gcc 4.3 will not handle an overflow in the expected way but will warn instead. -Werro...
[obnox/wireshark/wip.git] / epan / dissectors / 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$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
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 <epan/emem.h>
42 #include <epan/dissectors/packet-smb.h>
43 #include <epan/strutil.h>
44 #include <epan/prefs.h>
45 #include <epan/reassemble.h>
46 #include <epan/tap.h>
47 #include "packet-ipx.h"
48 #include "packet-idp.h"
49
50 #include "packet-windows-common.h"
51 #include "packet-smb-common.h"
52 #include "packet-smb-mailslot.h"
53 #include "packet-smb-pipe.h"
54 #include "packet-dcerpc.h"
55 #include "packet-ntlmssp.h"
56 #include "packet-smb2.h"
57
58 /*
59  * Various specifications and documents about SMB can be found in
60  *
61  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
62  *
63  * and a CIFS specification from the Storage Networking Industry Association
64  * can be found on a link from the page at
65  *
66  *      http://www.snia.org/tech_activities/CIFS
67  *
68  * (it supercedes the document at
69  *
70  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
71  *
72  * ).
73  *
74  * There are also some Open Group publications documenting CIFS available
75  * for download; catalog entries for them are at:
76  *
77  *      http://www.opengroup.org/products/publications/catalog/c209.htm
78  *
79  *      http://www.opengroup.org/products/publications/catalog/c195.htm
80  *
81  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
82  * can be found at
83  *
84  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
85  *
86  * (or, presumably a similar path under the Samba mirrors).  As the
87  * ".doc" indicates, it's a Word document.  Some of the specs from the
88  * Microsoft FTP site can be found in the
89  *
90  *      http://www.samba.org/samba/ftp/specs/
91  *
92  * directory as well.
93  *
94  * Beware - these specs may have errors.
95  */
96 static int proto_smb = -1;
97 static int hf_smb_cmd = -1;
98 static int hf_smb_mapped_in = -1;
99 static int hf_smb_unmapped_in = -1;
100 static int hf_smb_opened_in = -1;
101 static int hf_smb_closed_in = -1;
102 static int hf_smb_key = -1;
103 static int hf_smb_session_id = -1;
104 static int hf_smb_sequence_num = -1;
105 static int hf_smb_group_id = -1;
106 static int hf_smb_pid = -1;
107 static int hf_smb_tid = -1;
108 static int hf_smb_uid = -1;
109 static int hf_smb_mid = -1;
110 static int hf_smb_pid_high = -1;
111 static int hf_smb_sig = -1;
112 static int hf_smb_response_to = -1;
113 static int hf_smb_time = -1;
114 static int hf_smb_response_in = -1;
115 static int hf_smb_continuation_to = -1;
116 static int hf_smb_nt_status = -1;
117 static int hf_smb_error_class = -1;
118 static int hf_smb_error_code = -1;
119 static int hf_smb_reserved = -1;
120 static int hf_smb_create_flags = -1;
121 static int hf_smb_create_options = -1;
122 static int hf_smb_share_access = -1;
123 static int hf_smb_access_mask = -1;
124 static int hf_smb_flags_lock = -1;
125 static int hf_smb_flags_receive_buffer = -1;
126 static int hf_smb_flags_caseless = -1;
127 static int hf_smb_flags_canon = -1;
128 static int hf_smb_flags_oplock = -1;
129 static int hf_smb_flags_notify = -1;
130 static int hf_smb_flags_response = -1;
131 static int hf_smb_flags2_long_names_allowed = -1;
132 static int hf_smb_flags2_ea = -1;
133 static int hf_smb_flags2_sec_sig = -1;
134 static int hf_smb_flags2_long_names_used = -1;
135 static int hf_smb_flags2_esn = -1;
136 static int hf_smb_flags2_dfs = -1;
137 static int hf_smb_flags2_roe = -1;
138 static int hf_smb_flags2_nt_error = -1;
139 static int hf_smb_flags2_string = -1;
140 static int hf_smb_word_count = -1;
141 static int hf_smb_byte_count = -1;
142 static int hf_smb_buffer_format = -1;
143 static int hf_smb_dialect_name = -1;
144 static int hf_smb_dialect_index = -1;
145 static int hf_smb_max_trans_buf_size = -1;
146 static int hf_smb_max_mpx_count = -1;
147 static int hf_smb_max_vcs_num = -1;
148 static int hf_smb_session_key = -1;
149 static int hf_smb_server_timezone = -1;
150 static int hf_smb_encryption_key_length = -1;
151 static int hf_smb_encryption_key = -1;
152 static int hf_smb_primary_domain = -1;
153 static int hf_smb_server = -1;
154 static int hf_smb_max_raw_buf_size = -1;
155 static int hf_smb_server_guid = -1;
156 static int hf_smb_security_blob_len = -1;
157 static int hf_smb_security_blob = -1;
158 static int hf_smb_sm_mode16 = -1;
159 static int hf_smb_sm_password16 = -1;
160 static int hf_smb_sm_mode = -1;
161 static int hf_smb_sm_password = -1;
162 static int hf_smb_sm_signatures = -1;
163 static int hf_smb_sm_sig_required = -1;
164 static int hf_smb_rm_read = -1;
165 static int hf_smb_rm_write = -1;
166 static int hf_smb_server_date_time = -1;
167 static int hf_smb_server_smb_date = -1;
168 static int hf_smb_server_smb_time = -1;
169 static int hf_smb_server_cap_raw_mode = -1;
170 static int hf_smb_server_cap_mpx_mode = -1;
171 static int hf_smb_server_cap_unicode = -1;
172 static int hf_smb_server_cap_large_files = -1;
173 static int hf_smb_server_cap_nt_smbs = -1;
174 static int hf_smb_server_cap_rpc_remote_apis = -1;
175 static int hf_smb_server_cap_nt_status = -1;
176 static int hf_smb_server_cap_level_ii_oplocks = -1;
177 static int hf_smb_server_cap_lock_and_read = -1;
178 static int hf_smb_server_cap_nt_find = -1;
179 static int hf_smb_server_cap_dfs = -1;
180 static int hf_smb_server_cap_infolevel_passthru = -1;
181 static int hf_smb_server_cap_large_readx = -1;
182 static int hf_smb_server_cap_large_writex = -1;
183 static int hf_smb_server_cap_unix = -1;
184 static int hf_smb_server_cap_reserved = -1;
185 static int hf_smb_server_cap_bulk_transfer = -1;
186 static int hf_smb_server_cap_compressed_data = -1;
187 static int hf_smb_server_cap_extended_security = -1;
188 static int hf_smb_system_time = -1;
189 static int hf_smb_unknown = -1;
190 static int hf_smb_dir_name = -1;
191 static int hf_smb_echo_count = -1;
192 static int hf_smb_echo_data = -1;
193 static int hf_smb_echo_seq_num = -1;
194 static int hf_smb_max_buf_size = -1;
195 static int hf_smb_password = -1;
196 static int hf_smb_password_len = -1;
197 static int hf_smb_ansi_password = -1;
198 static int hf_smb_ansi_password_len = -1;
199 static int hf_smb_unicode_password = -1;
200 static int hf_smb_unicode_password_len = -1;
201 static int hf_smb_path = -1;
202 static int hf_smb_service = -1;
203 static int hf_smb_move_flags_file = -1;
204 static int hf_smb_move_flags_dir = -1;
205 static int hf_smb_move_flags_verify = -1;
206 static int hf_smb_files_moved = -1;
207 static int hf_smb_file_access_mask_read_data = -1;
208 static int hf_smb_file_access_mask_write_data = -1;
209 static int hf_smb_file_access_mask_append_data = -1;
210 static int hf_smb_file_access_mask_read_ea = -1;
211 static int hf_smb_file_access_mask_write_ea = -1;
212 static int hf_smb_file_access_mask_execute = -1;
213 static int hf_smb_file_access_mask_read_attribute = -1;
214 static int hf_smb_file_access_mask_write_attribute = -1;
215 static int hf_smb_dir_access_mask_list = -1;
216 static int hf_smb_dir_access_mask_add_file = -1;
217 static int hf_smb_dir_access_mask_add_subdir = -1;
218 static int hf_smb_dir_access_mask_read_ea = -1;
219 static int hf_smb_dir_access_mask_write_ea = -1;
220 static int hf_smb_dir_access_mask_traverse = -1;
221 static int hf_smb_dir_access_mask_delete_child = -1;
222 static int hf_smb_dir_access_mask_read_attribute = -1;
223 static int hf_smb_dir_access_mask_write_attribute = -1;
224 static int hf_smb_copy_flags_file = -1;
225 static int hf_smb_copy_flags_dir = -1;
226 static int hf_smb_copy_flags_dest_mode = -1;
227 static int hf_smb_copy_flags_source_mode = -1;
228 static int hf_smb_copy_flags_verify = -1;
229 static int hf_smb_copy_flags_tree_copy = -1;
230 static int hf_smb_copy_flags_ea_action = -1;
231 static int hf_smb_count = -1;
232 static int hf_smb_count_low = -1;
233 static int hf_smb_count_high = -1;
234 static int hf_smb_file_name = -1;
235 static int hf_smb_open_function_open = -1;
236 static int hf_smb_open_function_create = -1;
237 static int hf_smb_fid = -1;
238 static int hf_smb_file_attr_read_only_16bit = -1;
239 static int hf_smb_file_attr_read_only_8bit = -1;
240 static int hf_smb_file_attr_hidden_16bit = -1;
241 static int hf_smb_file_attr_hidden_8bit = -1;
242 static int hf_smb_file_attr_system_16bit = -1;
243 static int hf_smb_file_attr_system_8bit = -1;
244 static int hf_smb_file_attr_volume_16bit = -1;
245 static int hf_smb_file_attr_volume_8bit = -1;
246 static int hf_smb_file_attr_directory_16bit = -1;
247 static int hf_smb_file_attr_directory_8bit = -1;
248 static int hf_smb_file_attr_archive_16bit = -1;
249 static int hf_smb_file_attr_archive_8bit = -1;
250 static int hf_smb_file_attr_device = -1;
251 static int hf_smb_file_attr_normal = -1;
252 static int hf_smb_file_attr_temporary = -1;
253 static int hf_smb_file_attr_sparse = -1;
254 static int hf_smb_file_attr_reparse = -1;
255 static int hf_smb_file_attr_compressed = -1;
256 static int hf_smb_file_attr_offline = -1;
257 static int hf_smb_file_attr_not_content_indexed = -1;
258 static int hf_smb_file_attr_encrypted = -1;
259 static int hf_smb_file_size = -1;
260 static int hf_smb_search_attribute_read_only = -1;
261 static int hf_smb_search_attribute_hidden = -1;
262 static int hf_smb_search_attribute_system = -1;
263 static int hf_smb_search_attribute_volume = -1;
264 static int hf_smb_search_attribute_directory = -1;
265 static int hf_smb_search_attribute_archive = -1;
266 static int hf_smb_access_mode = -1;
267 static int hf_smb_access_sharing = -1;
268 static int hf_smb_access_locality = -1;
269 static int hf_smb_access_caching = -1;
270 static int hf_smb_access_writetru = -1;
271 static int hf_smb_create_time = -1;
272 static int hf_smb_modify_time = -1;
273 static int hf_smb_backup_time = -1;
274 static int hf_smb_mac_alloc_block_count = -1;
275 static int hf_smb_mac_alloc_block_size = -1;
276 static int hf_smb_mac_free_block_count = -1;
277 static int hf_smb_mac_fndrinfo = -1;
278 static int hf_smb_mac_root_file_count = -1;
279 static int hf_smb_mac_root_dir_count = -1;
280 static int hf_smb_mac_file_count = -1;
281 static int hf_smb_mac_dir_count = -1;
282 static int hf_smb_mac_support_flags = -1;
283 static int hf_smb_mac_sup_access_ctrl = -1;
284 static int hf_smb_mac_sup_getset_comments = -1;
285 static int hf_smb_mac_sup_desktopdb_calls = -1;
286 static int hf_smb_mac_sup_unique_ids = -1;
287 static int hf_smb_mac_sup_streams = -1;
288 static int hf_smb_create_dos_date = -1;
289 static int hf_smb_create_dos_time = -1;
290 static int hf_smb_last_write_time = -1;
291 static int hf_smb_last_write_dos_date = -1;
292 static int hf_smb_last_write_dos_time = -1;
293 static int hf_smb_access_time = -1;
294 static int hf_smb_access_dos_date = -1;
295 static int hf_smb_access_dos_time = -1;
296 static int hf_smb_old_file_name = -1;
297 static int hf_smb_offset = -1;
298 static int hf_smb_remaining = -1;
299 static int hf_smb_padding = -1;
300 static int hf_smb_file_data = -1;
301 static int hf_smb_total_data_len = -1;
302 static int hf_smb_data_len = -1;
303 static int hf_smb_data_len_low = -1;
304 static int hf_smb_data_len_high = -1;
305 static int hf_smb_seek_mode = -1;
306 static int hf_smb_data_size = -1;
307 static int hf_smb_alloc_size = -1;
308 static int hf_smb_alloc_size64 = -1;
309 static int hf_smb_max_count = -1;
310 static int hf_smb_max_count_low = -1;
311 static int hf_smb_max_count_high = -1;
312 static int hf_smb_min_count = -1;
313 static int hf_smb_timeout = -1;
314 static int hf_smb_high_offset = -1;
315 static int hf_smb_units = -1;
316 static int hf_smb_bpu = -1;
317 static int hf_smb_blocksize = -1;
318 static int hf_smb_freeunits = -1;
319 static int hf_smb_data_offset = -1;
320 static int hf_smb_dcm = -1;
321 static int hf_smb_request_mask = -1;
322 static int hf_smb_response_mask = -1;
323 static int hf_smb_search_id = -1;
324 static int hf_smb_write_mode_write_through = -1;
325 static int hf_smb_write_mode_return_remaining = -1;
326 static int hf_smb_write_mode_raw = -1;
327 static int hf_smb_write_mode_message_start = -1;
328 static int hf_smb_write_mode_connectionless = -1;
329 static int hf_smb_resume_key_len = -1;
330 static int hf_smb_resume_find_id = -1;
331 static int hf_smb_resume_server_cookie = -1;
332 static int hf_smb_resume_client_cookie = -1;
333 static int hf_smb_andxoffset = -1;
334 static int hf_smb_lock_type_large = -1;
335 static int hf_smb_lock_type_cancel = -1;
336 static int hf_smb_lock_type_change = -1;
337 static int hf_smb_lock_type_oplock = -1;
338 static int hf_smb_lock_type_shared = -1;
339 static int hf_smb_locking_ol = -1;
340 static int hf_smb_number_of_locks = -1;
341 static int hf_smb_number_of_unlocks = -1;
342 static int hf_smb_lock_long_offset = -1;
343 static int hf_smb_lock_long_length = -1;
344 static int hf_smb_file_type = -1;
345 static int hf_smb_ipc_state_nonblocking = -1;
346 static int hf_smb_ipc_state_endpoint = -1;
347 static int hf_smb_ipc_state_pipe_type = -1;
348 static int hf_smb_ipc_state_read_mode = -1;
349 static int hf_smb_ipc_state_icount = -1;
350 static int hf_smb_server_fid = -1;
351 static int hf_smb_open_flags_add_info = -1;
352 static int hf_smb_open_flags_ex_oplock = -1;
353 static int hf_smb_open_flags_batch_oplock = -1;
354 static int hf_smb_open_flags_ealen = -1;
355 static int hf_smb_open_action_open = -1;
356 static int hf_smb_open_action_lock = -1;
357 static int hf_smb_vc_num = -1;
358 static int hf_smb_account = -1;
359 static int hf_smb_os = -1;
360 static int hf_smb_lanman = -1;
361 static int hf_smb_setup_action_guest = -1;
362 static int hf_smb_fs = -1;
363 static int hf_smb_connect_flags_dtid = -1;
364 static int hf_smb_connect_support_search = -1;
365 static int hf_smb_connect_support_in_dfs = -1;
366 static int hf_smb_max_setup_count = -1;
367 static int hf_smb_total_param_count = -1;
368 static int hf_smb_total_data_count = -1;
369 static int hf_smb_max_param_count = -1;
370 static int hf_smb_max_data_count = -1;
371 static int hf_smb_param_disp16 = -1;
372 static int hf_smb_param_count16 = -1;
373 static int hf_smb_param_offset16 = -1;
374 static int hf_smb_param_disp32 = -1;
375 static int hf_smb_param_count32 = -1;
376 static int hf_smb_param_offset32 = -1;
377 static int hf_smb_data_disp16 = -1;
378 static int hf_smb_data_count16 = -1;
379 static int hf_smb_data_offset16 = -1;
380 static int hf_smb_data_disp32 = -1;
381 static int hf_smb_data_count32 = -1;
382 static int hf_smb_data_offset32 = -1;
383 static int hf_smb_setup_count = -1;
384 static int hf_smb_nt_trans_subcmd = -1;
385 static int hf_smb_nt_ioctl_isfsctl = -1;
386 static int hf_smb_nt_ioctl_flags_root_handle = -1;
387 #ifdef SMB_UNUSED_HANDLES
388 static int hf_smb_nt_security_information = -1;
389 #endif
390 static int hf_smb_nt_notify_action = -1;
391 static int hf_smb_nt_notify_watch_tree = -1;
392 static int hf_smb_nt_notify_stream_write = -1;
393 static int hf_smb_nt_notify_stream_size = -1;
394 static int hf_smb_nt_notify_stream_name = -1;
395 static int hf_smb_nt_notify_security = -1;
396 static int hf_smb_nt_notify_ea = -1;
397 static int hf_smb_nt_notify_creation = -1;
398 static int hf_smb_nt_notify_last_access = -1;
399 static int hf_smb_nt_notify_last_write = -1;
400 static int hf_smb_nt_notify_size = -1;
401 static int hf_smb_nt_notify_attributes = -1;
402 static int hf_smb_nt_notify_dir_name = -1;
403 static int hf_smb_nt_notify_file_name = -1;
404 static int hf_smb_root_dir_fid = -1;
405 static int hf_smb_nt_create_disposition = -1;
406 static int hf_smb_sd_length = -1;
407 static int hf_smb_ea_list_length = -1;
408 static int hf_smb_ea_flags = -1;
409 static int hf_smb_ea_name_length = -1;
410 static int hf_smb_ea_data_length = -1;
411 static int hf_smb_ea_name = -1;
412 static int hf_smb_ea_data = -1;
413 static int hf_smb_file_name_len = -1;
414 static int hf_smb_nt_impersonation_level = -1;
415 static int hf_smb_nt_security_flags_context_tracking = -1;
416 static int hf_smb_nt_security_flags_effective_only = -1;
417 static int hf_smb_nt_access_mask_generic_read = -1;
418 static int hf_smb_nt_access_mask_generic_write = -1;
419 static int hf_smb_nt_access_mask_generic_execute = -1;
420 static int hf_smb_nt_access_mask_generic_all = -1;
421 static int hf_smb_nt_access_mask_maximum_allowed = -1;
422 static int hf_smb_nt_access_mask_system_security = -1;
423 static int hf_smb_nt_access_mask_synchronize = -1;
424 static int hf_smb_nt_access_mask_write_owner = -1;
425 static int hf_smb_nt_access_mask_write_dac = -1;
426 static int hf_smb_nt_access_mask_read_control = -1;
427 static int hf_smb_nt_access_mask_delete = -1;
428 static int hf_smb_nt_access_mask_write_attributes = -1;
429 static int hf_smb_nt_access_mask_read_attributes = -1;
430 static int hf_smb_nt_access_mask_delete_child = -1;
431 static int hf_smb_nt_access_mask_execute = -1;
432 static int hf_smb_nt_access_mask_write_ea = -1;
433 static int hf_smb_nt_access_mask_read_ea = -1;
434 static int hf_smb_nt_access_mask_append = -1;
435 static int hf_smb_nt_access_mask_write = -1;
436 static int hf_smb_nt_access_mask_read = -1;
437 static int hf_smb_nt_create_bits_oplock = -1;
438 static int hf_smb_nt_create_bits_boplock = -1;
439 static int hf_smb_nt_create_bits_dir = -1;
440 static int hf_smb_nt_create_bits_ext_resp = -1;
441 static int hf_smb_nt_create_options_directory_file = -1;
442 static int hf_smb_nt_create_options_write_through = -1;
443 static int hf_smb_nt_create_options_sequential_only = -1;
444 static int hf_smb_nt_create_options_no_intermediate_buffering = -1;
445 static int hf_smb_nt_create_options_sync_io_alert = -1;
446 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
447 static int hf_smb_nt_create_options_non_directory_file = -1;
448 static int hf_smb_nt_create_options_create_tree_connection = -1;
449 static int hf_smb_nt_create_options_complete_if_oplocked = -1;
450 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
451 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
452 static int hf_smb_nt_create_options_random_access = -1;
453 static int hf_smb_nt_create_options_delete_on_close = -1;
454 static int hf_smb_nt_create_options_open_by_fileid = -1;
455 static int hf_smb_nt_create_options_backup_intent = -1;
456 static int hf_smb_nt_create_options_no_compression = -1;
457 static int hf_smb_nt_create_options_reserve_opfilter = -1;
458 static int hf_smb_nt_create_options_open_reparse_point = -1;
459 static int hf_smb_nt_create_options_open_no_recall = -1;
460 static int hf_smb_nt_create_options_open_for_free_space_query = -1;
461 static int hf_smb_nt_share_access_read = -1;
462 static int hf_smb_nt_share_access_write = -1;
463 static int hf_smb_nt_share_access_delete = -1;
464 static int hf_smb_file_eattr_read_only = -1;
465 static int hf_smb_file_eattr_hidden = -1;
466 static int hf_smb_file_eattr_system = -1;
467 static int hf_smb_file_eattr_volume = -1;
468 static int hf_smb_file_eattr_directory = -1;
469 static int hf_smb_file_eattr_archive = -1;
470 static int hf_smb_file_eattr_device = -1;
471 static int hf_smb_file_eattr_normal = -1;
472 static int hf_smb_file_eattr_temporary = -1;
473 static int hf_smb_file_eattr_sparse = -1;
474 static int hf_smb_file_eattr_reparse = -1;
475 static int hf_smb_file_eattr_compressed = -1;
476 static int hf_smb_file_eattr_offline = -1;
477 static int hf_smb_file_eattr_not_content_indexed = -1;
478 static int hf_smb_file_eattr_encrypted = -1;
479 static int hf_smb_sec_desc_len = -1;
480 static int hf_smb_nt_qsd_owner = -1;
481 static int hf_smb_nt_qsd_group = -1;
482 static int hf_smb_nt_qsd_dacl = -1;
483 static int hf_smb_nt_qsd_sacl = -1;
484 static int hf_smb_extended_attributes = -1;
485 static int hf_smb_oplock_level = -1;
486 static int hf_smb_create_action = -1;
487 static int hf_smb_file_id = -1;
488 static int hf_smb_ea_error_offset = -1;
489 static int hf_smb_end_of_file = -1;
490 static int hf_smb_replace = -1;
491 static int hf_smb_root_dir_handle = -1;
492 static int hf_smb_target_name_len = -1;
493 static int hf_smb_target_name = -1;
494 static int hf_smb_device_type = -1;
495 static int hf_smb_is_directory = -1;
496 static int hf_smb_next_entry_offset = -1;
497 static int hf_smb_change_time = -1;
498 static int hf_smb_setup_len = -1;
499 static int hf_smb_print_mode = -1;
500 static int hf_smb_print_identifier = -1;
501 static int hf_smb_restart_index = -1;
502 static int hf_smb_print_queue_date = -1;
503 static int hf_smb_print_queue_dos_date = -1;
504 static int hf_smb_print_queue_dos_time = -1;
505 static int hf_smb_print_status = -1;
506 static int hf_smb_print_spool_file_number = -1;
507 static int hf_smb_print_spool_file_size = -1;
508 static int hf_smb_print_spool_file_name = -1;
509 static int hf_smb_start_index = -1;
510 static int hf_smb_originator_name = -1;
511 static int hf_smb_destination_name = -1;
512 static int hf_smb_message_len = -1;
513 static int hf_smb_message = -1;
514 static int hf_smb_mgid = -1;
515 static int hf_smb_forwarded_name = -1;
516 static int hf_smb_machine_name = -1;
517 static int hf_smb_cancel_to = -1;
518 static int hf_smb_trans2_subcmd = -1;
519 static int hf_smb_trans_name = -1;
520 static int hf_smb_transaction_flags_dtid = -1;
521 static int hf_smb_transaction_flags_owt = -1;
522 static int hf_smb_search_count = -1;
523 static int hf_smb_search_pattern = -1;
524 static int hf_smb_ff2_backup = -1;
525 static int hf_smb_ff2_continue = -1;
526 static int hf_smb_ff2_resume = -1;
527 static int hf_smb_ff2_close_eos = -1;
528 static int hf_smb_ff2_close = -1;
529 static int hf_smb_ff2_information_level = -1;
530 static int hf_smb_qpi_loi = -1;
531 static int hf_smb_spi_loi = -1;
532 #if 0
533 static int hf_smb_sfi_writetru = -1;
534 static int hf_smb_sfi_caching = -1;
535 #endif
536 static int hf_smb_storage_type = -1;
537 static int hf_smb_resume = -1;
538 static int hf_smb_max_referral_level = -1;
539 static int hf_smb_qfsi_information_level = -1;
540 static int hf_smb_number_of_links = -1;
541 static int hf_smb_delete_pending = -1;
542 static int hf_smb_index_number = -1;
543 static int hf_smb_position = -1;
544 static int hf_smb_current_offset = -1;
545 static int hf_smb_t2_alignment = -1;
546 static int hf_smb_t2_stream_name_length = -1;
547 static int hf_smb_t2_stream_size = -1;
548 static int hf_smb_t2_stream_name = -1;
549 static int hf_smb_t2_compressed_file_size = -1;
550 static int hf_smb_t2_compressed_format = -1;
551 static int hf_smb_t2_compressed_unit_shift = -1;
552 static int hf_smb_t2_compressed_chunk_shift = -1;
553 static int hf_smb_t2_compressed_cluster_shift = -1;
554 static int hf_smb_t2_marked_for_deletion = -1;
555 static int hf_smb_dfs_path_consumed = -1;
556 static int hf_smb_dfs_num_referrals = -1;
557 static int hf_smb_get_dfs_server_hold_storage = -1;
558 static int hf_smb_get_dfs_fielding = -1;
559 static int hf_smb_dfs_referral_version = -1;
560 static int hf_smb_dfs_referral_size = -1;
561 static int hf_smb_dfs_referral_server_type = -1;
562 static int hf_smb_dfs_referral_flags_strip = -1;
563 static int hf_smb_dfs_referral_node_offset = -1;
564 static int hf_smb_dfs_referral_node = -1;
565 static int hf_smb_dfs_referral_proximity = -1;
566 static int hf_smb_dfs_referral_ttl = -1;
567 static int hf_smb_dfs_referral_path_offset = -1;
568 static int hf_smb_dfs_referral_path = -1;
569 static int hf_smb_dfs_referral_alt_path_offset = -1;
570 static int hf_smb_dfs_referral_alt_path = -1;
571 static int hf_smb_end_of_search = -1;
572 static int hf_smb_last_name_offset = -1;
573 static int hf_smb_fn_information_level = -1;
574 static int hf_smb_monitor_handle = -1;
575 static int hf_smb_change_count = -1;
576 static int hf_smb_file_index = -1;
577 static int hf_smb_short_file_name = -1;
578 static int hf_smb_short_file_name_len = -1;
579 static int hf_smb_fs_id = -1;
580 static int hf_smb_sector_unit = -1;
581 static int hf_smb_fs_units = -1;
582 static int hf_smb_fs_sector = -1;
583 static int hf_smb_avail_units = -1;
584 static int hf_smb_volume_serial_num = -1;
585 static int hf_smb_volume_label_len = -1;
586 static int hf_smb_volume_label = -1;
587 static int hf_smb_free_alloc_units64 = -1;
588 static int hf_smb_caller_free_alloc_units64 = -1;
589 static int hf_smb_actual_free_alloc_units64 = -1;
590 static int hf_smb_max_name_len = -1;
591 static int hf_smb_fs_name_len = -1;
592 static int hf_smb_fs_name = -1;
593 static int hf_smb_device_char_removable = -1;
594 static int hf_smb_device_char_read_only = -1;
595 static int hf_smb_device_char_floppy = -1;
596 static int hf_smb_device_char_write_once = -1;
597 static int hf_smb_device_char_remote = -1;
598 static int hf_smb_device_char_mounted = -1;
599 static int hf_smb_device_char_virtual = -1;
600 static int hf_smb_fs_attr_css = -1;
601 static int hf_smb_fs_attr_cpn = -1;
602 static int hf_smb_fs_attr_uod = -1;
603 static int hf_smb_fs_attr_pacls = -1;
604 static int hf_smb_fs_attr_fc = -1;
605 static int hf_smb_fs_attr_vq = -1;
606 static int hf_smb_fs_attr_ssf = -1;
607 static int hf_smb_fs_attr_srp = -1;
608 static int hf_smb_fs_attr_srs = -1;
609 static int hf_smb_fs_attr_sla = -1;
610 static int hf_smb_fs_attr_vic = -1;
611 static int hf_smb_fs_attr_soids = -1;
612 static int hf_smb_fs_attr_se = -1;
613 static int hf_smb_fs_attr_ns = -1;
614 static int hf_smb_fs_attr_rov = -1;
615 static int hf_smb_quota_flags_enabled = -1;
616 static int hf_smb_quota_flags_deny_disk = -1;
617 static int hf_smb_quota_flags_log_limit = -1;
618 static int hf_smb_quota_flags_log_warning = -1;
619 static int hf_smb_soft_quota_limit = -1;
620 static int hf_smb_hard_quota_limit = -1;
621 static int hf_smb_user_quota_used = -1;
622 static int hf_smb_user_quota_offset = -1;
623 static int hf_smb_nt_rename_level = -1;
624 static int hf_smb_cluster_count = -1;
625 static int hf_smb_segments = -1;
626 static int hf_smb_segment = -1;
627 static int hf_smb_segment_overlap = -1;
628 static int hf_smb_segment_overlap_conflict = -1;
629 static int hf_smb_segment_multiple_tails = -1;
630 static int hf_smb_segment_too_long_fragment = -1;
631 static int hf_smb_segment_error = -1;
632 static int hf_smb_pipe_write_len = -1;
633 static int hf_smb_unix_major_version = -1;
634 static int hf_smb_unix_minor_version = -1;
635 static int hf_smb_unix_capability_fcntl = -1;
636 static int hf_smb_unix_capability_posix_acl = -1;
637 static int hf_smb_unix_file_size = -1;
638 static int hf_smb_unix_file_num_bytes = -1;
639 static int hf_smb_unix_file_last_status = -1;
640 static int hf_smb_unix_file_last_access = -1;
641 static int hf_smb_unix_file_last_change = -1;
642 static int hf_smb_unix_file_uid = -1;
643 static int hf_smb_unix_file_gid = -1;
644 static int hf_smb_unix_file_type = -1;
645 static int hf_smb_unix_file_dev_major = -1;
646 static int hf_smb_unix_file_dev_minor = -1;
647 static int hf_smb_unix_file_unique_id = -1;
648 static int hf_smb_unix_file_permissions = -1;
649 static int hf_smb_unix_file_nlinks = -1;
650 static int hf_smb_unix_file_link_dest = -1;
651 static int hf_smb_unix_find_file_nextoffset = -1;
652 static int hf_smb_unix_find_file_resumekey = -1;
653 static int hf_smb_network_unknown = -1;
654 static int hf_smb_disposition_delete_on_close = -1;
655 static int hf_smb_pipe_info_flag = -1;
656 static int hf_smb_mode = -1;
657 static int hf_smb_attribute = -1;
658 static int hf_smb_reparse_tag = -1;
659 static int hf_smb_logged_in = -1;
660 static int hf_smb_logged_out = -1;
661 static int hf_smb_file_rw_offset = -1;
662 static int hf_smb_file_rw_length = -1;
663 static int hf_smb_posix_acl_version = -1;
664 static int hf_smb_posix_num_file_aces = -1;
665 static int hf_smb_posix_num_def_aces = -1;
666 static int hf_smb_posix_ace_type = -1;
667 static int hf_smb_posix_ace_flags = -1;
668 static int hf_smb_posix_ace_perm_read = -1;
669 static int hf_smb_posix_ace_perm_write = -1;
670 static int hf_smb_posix_ace_perm_execute = -1;
671 static int hf_smb_posix_ace_perm_owner_uid = -1;
672 static int hf_smb_posix_ace_perm_owner_gid = -1;
673 static int hf_smb_posix_ace_perm_uid = -1;
674 static int hf_smb_posix_ace_perm_gid = -1;
675
676 static gint ett_smb = -1;
677 static gint ett_smb_fid = -1;
678 static gint ett_smb_tid = -1;
679 static gint ett_smb_uid = -1;
680 static gint ett_smb_hdr = -1;
681 static gint ett_smb_command = -1;
682 static gint ett_smb_fileattributes = -1;
683 static gint ett_smb_capabilities = -1;
684 static gint ett_smb_aflags = -1;
685 static gint ett_smb_dialect = -1;
686 static gint ett_smb_dialects = -1;
687 static gint ett_smb_mode = -1;
688 static gint ett_smb_rawmode = -1;
689 static gint ett_smb_flags = -1;
690 static gint ett_smb_flags2 = -1;
691 static gint ett_smb_desiredaccess = -1;
692 static gint ett_smb_search = -1;
693 static gint ett_smb_file = -1;
694 static gint ett_smb_openfunction = -1;
695 static gint ett_smb_filetype = -1;
696 static gint ett_smb_openaction = -1;
697 static gint ett_smb_writemode = -1;
698 static gint ett_smb_lock_type = -1;
699 static gint ett_smb_ssetupandxaction = -1;
700 static gint ett_smb_optionsup = -1;
701 static gint ett_smb_time_date = -1;
702 static gint ett_smb_move_copy_flags = -1;
703 static gint ett_smb_file_attributes = -1;
704 static gint ett_smb_search_resume_key = -1;
705 static gint ett_smb_search_dir_info = -1;
706 static gint ett_smb_unlocks = -1;
707 static gint ett_smb_unlock = -1;
708 static gint ett_smb_locks = -1;
709 static gint ett_smb_lock = -1;
710 static gint ett_smb_open_flags = -1;
711 static gint ett_smb_ipc_state = -1;
712 static gint ett_smb_open_action = -1;
713 static gint ett_smb_setup_action = -1;
714 static gint ett_smb_connect_flags = -1;
715 static gint ett_smb_connect_support_bits = -1;
716 static gint ett_smb_nt_access_mask = -1;
717 static gint ett_smb_nt_create_bits = -1;
718 static gint ett_smb_nt_create_options = -1;
719 static gint ett_smb_nt_share_access = -1;
720 static gint ett_smb_nt_security_flags = -1;
721 static gint ett_smb_nt_trans_setup = -1;
722 static gint ett_smb_nt_trans_data = -1;
723 static gint ett_smb_nt_trans_param = -1;
724 static gint ett_smb_nt_notify_completion_filter = -1;
725 static gint ett_smb_nt_ioctl_flags = -1;
726 static gint ett_smb_security_information_mask = -1;
727 static gint ett_smb_print_queue_entry = -1;
728 static gint ett_smb_transaction_flags = -1;
729 static gint ett_smb_transaction_params = -1;
730 static gint ett_smb_find_first2_flags = -1;
731 static gint ett_smb_mac_support_flags = -1;
732 #if 0
733 static gint ett_smb_ioflag = -1;
734 #endif
735 static gint ett_smb_transaction_data = -1;
736 static gint ett_smb_stream_info = -1;
737 static gint ett_smb_dfs_referrals = -1;
738 static gint ett_smb_dfs_referral = -1;
739 static gint ett_smb_dfs_referral_flags = -1;
740 static gint ett_smb_get_dfs_flags = -1;
741 static gint ett_smb_ff2_data = -1;
742 static gint ett_smb_device_characteristics = -1;
743 static gint ett_smb_fs_attributes = -1;
744 static gint ett_smb_segments = -1;
745 static gint ett_smb_segment = -1;
746 static gint ett_smb_quotaflags = -1;
747 static gint ett_smb_secblob = -1;
748 static gint ett_smb_unicode_password = -1;
749 static gint ett_smb_ea = -1;
750 static gint ett_smb_unix_capabilities = -1;
751 static gint ett_smb_posic_ace = -1;
752 static gint ett_smb_posix_ace_perms = -1;
753
754 static int smb_tap = -1;
755
756 static dissector_handle_t gssapi_handle = NULL;
757 static dissector_handle_t ntlmssp_handle = NULL;
758
759 static const fragment_items smb_frag_items = {
760         &ett_smb_segment,
761         &ett_smb_segments,
762
763         &hf_smb_segments,
764         &hf_smb_segment,
765         &hf_smb_segment_overlap,
766         &hf_smb_segment_overlap_conflict,
767         &hf_smb_segment_multiple_tails,
768         &hf_smb_segment_too_long_fragment,
769         &hf_smb_segment_error,
770         NULL,
771
772         "segments"
773 };
774
775 static proto_tree *top_tree=NULL;     /* ugly */
776
777 static const char *decode_smb_name(guint8);
778 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
779
780 /*
781  * Macros for use in the main dissector routines for an SMB.
782  */
783
784 #define WORD_COUNT      \
785         /* Word Count */                                \
786         wc = tvb_get_guint8(tvb, offset);               \
787         proto_tree_add_uint(tree, hf_smb_word_count,    \
788                 tvb, offset, 1, wc);                    \
789         offset += 1;                                    \
790         if(wc==0) goto bytecount;
791
792 #define BYTE_COUNT      \
793         bytecount:                                      \
794         bc = tvb_get_letohs(tvb, offset);               \
795         proto_tree_add_uint(tree, hf_smb_byte_count,    \
796                         tvb, offset, 2, bc);            \
797         offset += 2;                                    \
798         if(bc==0) goto endofcommand;
799
800 #define CHECK_BYTE_COUNT(len)   \
801         if (bc < len) goto endofcommand;
802
803 #define COUNT_BYTES(len)   {\
804         int tmp;            \
805         tmp=len;            \
806         offset += tmp;      \
807         bc -= tmp;          \
808         }
809
810 #define END_OF_SMB      \
811         if (bc != 0) { \
812                 gint bc_remaining; \
813                 bc_remaining=tvb_length_remaining(tvb, offset); \
814                 if( ((gint)bc) > bc_remaining){ \
815                         bc=bc_remaining; \
816                 } \
817                 if(bc){ \
818                         tvb_ensure_bytes_exist(tvb, offset, bc); \
819                         proto_tree_add_text(tree, tvb, offset, bc, \
820                             "Extra byte parameters");           \
821                 } \
822                 offset += bc;                           \
823         }                                               \
824         endofcommand:
825
826 /*
827  * Macros for use in routines called by them.
828  */
829 #define CHECK_BYTE_COUNT_SUBR(len)      \
830         if (*bcp < len) {               \
831                 *trunc = TRUE;          \
832                 return offset;          \
833         }
834
835 #define CHECK_STRING_SUBR(fn)   \
836         if (fn == NULL) {       \
837                 *trunc = TRUE;  \
838                 return offset;  \
839         }
840
841 #define COUNT_BYTES_SUBR(len)   \
842         offset += len;          \
843         *bcp -= len;
844
845 /*
846  * Macros for use when dissecting transaction parameters and data
847  */
848 #define CHECK_BYTE_COUNT_TRANS(len)     \
849         if (bc < len) return offset;
850
851 #define CHECK_STRING_TRANS(fn)  \
852         if (fn == NULL) return offset;
853
854 #define COUNT_BYTES_TRANS(len)  \
855         offset += len;          \
856         bc -= len;
857
858 /*
859  * Macros for use in subrroutines dissecting transaction parameters or data
860  */
861 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
862         if (*bcp < len) return offset;
863
864 #define CHECK_STRING_TRANS_SUBR(fn)     \
865         if (fn == NULL) return offset;
866
867 #define COUNT_BYTES_TRANS_SUBR(len)     \
868         offset += len;                  \
869         *bcp -= len;
870
871
872 gboolean sid_name_snooping = FALSE;
873
874 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
875    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
876    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
877 static gboolean smb_trans_reassembly = TRUE;
878 gboolean smb_dcerpc_reassembly = TRUE;
879
880 static GHashTable *smb_trans_fragment_table = NULL;
881
882 static void
883 smb_trans_reassembly_init(void)
884 {
885         fragment_table_init(&smb_trans_fragment_table);
886 }
887
888 /*
889  * XXX - This keeps us from allocating huge amounts of memory as shown in
890  * bug 421.  It may need to be increased.
891  */
892 #define MAX_FRAGMENT_SIZE 65536
893 static fragment_data *
894 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
895                      int offset, int count, int pos, int totlen)
896 {
897         fragment_data *fd_head=NULL;
898         smb_info_t *si;
899         int more_frags;
900
901         if (count > MAX_FRAGMENT_SIZE || count < 0) {
902                 THROW(ReportedBoundsError);
903         }
904
905         more_frags=totlen>(pos+count);
906
907         si = (smb_info_t *)pinfo->private_data;
908         DISSECTOR_ASSERT(si);
909
910         if (si->sip == NULL) {
911                 /*
912                  * We don't have the frame number of the request.
913                  */
914                 return NULL;
915         }
916
917         if(!pinfo->fd->flags.visited){
918                 fd_head = fragment_add(tvb, offset, pinfo,
919                                        si->sip->frame_req, smb_trans_fragment_table,
920                                        pos, count, more_frags);
921         } else {
922                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
923         }
924
925         if (!fd_head || !(fd_head->flags&FD_DEFRAGMENTED)){
926                 /* This is continued - mark it as such, so we recognize
927                    continuation responses.
928                 */
929                 si->sip->flags |= SMB_SIF_IS_CONTINUED;
930         } else {
931                 /* We've finished reassembling, so there are no more
932                    continuation responses.
933                 */
934                 si->sip->flags &= ~SMB_SIF_IS_CONTINUED;
935         }
936
937         /* we only show the defragmented packet for the first fragment,
938            or else we might end up with dissecting one HUGE transaction PDU
939            a LOT of times. (first fragment is the only one containing the setup
940            bytes)
941            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
942            SMBs. Takes a LOT of time dissecting and is not fun.
943         */
944         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
945                 return fd_head;
946         } else {
947                 return NULL;
948         }
949 }
950
951
952
953
954
955 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
956    These variables and functions are used to match
957    responses with calls
958    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
959 /*
960  * The information we need to save about a request in order to show the
961  * frame number of the request in the dissection of the reply.
962  */
963 typedef struct  {
964         guint32 frame;
965         guint32 pid_mid;
966 } smb_saved_info_key_t;
967
968 /* unmatched smb_saved_info structures.
969    For unmatched smb_saved_info structures we store the smb_saved_info
970    structure using the MID and the PID as the key.
971
972    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
973    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
974    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
975 */
976 static gint
977 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
978 {
979         register guint32 key1 = GPOINTER_TO_UINT(k1);
980         register guint32 key2 = GPOINTER_TO_UINT(k2);
981         return key1==key2;
982 }
983 static guint
984 smb_saved_info_hash_unmatched(gconstpointer k)
985 {
986         register guint32 key = GPOINTER_TO_UINT(k);
987         return key;
988 }
989
990 /* matched smb_saved_info structures.
991    For matched smb_saved_info structures we store the smb_saved_info
992    structure twice in the table using the frame number, and a combination
993    of the MID and the PID, as the key.
994    The frame number is guaranteed to be unique but if ever someone makes
995    some change that will renumber the frames in a capture we are in BIG trouble.
996    This is not likely though since that would break (among other things) all the
997    reassembly routines as well.
998
999    We also need the MID as there may be more than one SMB request or reply
1000    in a single frame, and we also need the PID as there may be more than
1001    one outstanding request with the same MID and different PIDs.
1002 */
1003 static gint
1004 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
1005 {
1006         const smb_saved_info_key_t *key1 = k1;
1007         const smb_saved_info_key_t *key2 = k2;
1008         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
1009 }
1010 static guint
1011 smb_saved_info_hash_matched(gconstpointer k)
1012 {
1013         const smb_saved_info_key_t *key = k;
1014         return key->frame + key->pid_mid;
1015 }
1016
1017 static GSList *conv_tables = NULL;
1018
1019
1020 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1021    End of request/response matching functions
1022    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1023
1024
1025
1026 typedef struct _smb_uid_t {
1027         char *domain;
1028         char *account;
1029         int logged_in;
1030         int logged_out;
1031 } smb_uid_t;
1032
1033 static void
1034 smb_file_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1035 {
1036         mask&=0x0000ffff;
1037         if(mask==0x000001ff){
1038                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1039         }
1040
1041
1042         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_attribute, tvb, offset, 4, mask);
1043         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_attribute, tvb, offset, 4, mask);
1044         proto_tree_add_boolean(tree, hf_smb_file_access_mask_execute, tvb, offset, 4, mask);
1045         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_ea, tvb, offset, 4, mask);
1046         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_ea, tvb, offset, 4, mask);
1047         proto_tree_add_boolean(tree, hf_smb_file_access_mask_append_data, tvb, offset, 4, mask);
1048         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_data, tvb, offset, 4, mask);
1049         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_data, tvb, offset, 4, mask);
1050 }
1051 struct access_mask_info smb_file_access_mask_info = {
1052         "FILE",                         /* Name of specific rights */
1053         smb_file_specific_rights,       /* Dissection function */
1054         NULL,                           /* Generic mapping table */
1055         NULL                            /* Standard mapping table */
1056 };
1057
1058
1059 static void
1060 smb_dir_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1061 {
1062         mask&=0x0000ffff;
1063         if(mask==0x000001ff){
1064                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1065         }
1066
1067
1068         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_attribute, tvb, offset, 4, mask);
1069         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_attribute, tvb, offset, 4, mask);
1070         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_delete_child, tvb, offset, 4, mask);
1071         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_traverse, tvb, offset, 4, mask);
1072         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_ea, tvb, offset, 4, mask);
1073         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_ea, tvb, offset, 4, mask);
1074         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_subdir, tvb, offset, 4, mask);
1075         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_file, tvb, offset, 4, mask);
1076         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_list, tvb, offset, 4, mask);
1077 }
1078 struct access_mask_info smb_dir_access_mask_info = {
1079         "DIR",                          /* Name of specific rights */
1080         smb_dir_specific_rights,        /* Dissection function */
1081         NULL,                           /* Generic mapping table */
1082         NULL                            /* Standard mapping table */
1083 };
1084
1085
1086
1087 static const value_string buffer_format_vals[] = {
1088         {1,     "Data Block"},
1089         {2,     "Dialect"},
1090         {3,     "Pathname"},
1091         {4,     "ASCII"},
1092         {5,     "Variable Block"},
1093         {0,     NULL}
1094 };
1095
1096 #define POSIX_ACE_TYPE_USER_OBJ         0x01
1097 #define POSIX_ACE_TYPE_USER             0x02
1098 #define POSIX_ACE_TYPE_GROUP_OBJ        0x04
1099 #define POSIX_ACE_TYPE_GROUP            0x08
1100 #define POSIX_ACE_TYPE_MASK             0x10
1101 #define POSIX_ACE_TYPE_OTHER            0x20
1102 static const value_string ace_type_vals[] = {
1103         {POSIX_ACE_TYPE_USER_OBJ,       "User Obj"},
1104         {POSIX_ACE_TYPE_USER,           "User"},
1105         {POSIX_ACE_TYPE_GROUP_OBJ,      "Group Obj"},
1106         {POSIX_ACE_TYPE_GROUP,          "Group"},
1107         {POSIX_ACE_TYPE_MASK,           "Mask"},
1108         {POSIX_ACE_TYPE_OTHER,          "Other"},
1109         {0,     NULL}
1110 };
1111
1112 /*
1113  * UTIME - this is *almost* like a UNIX time stamp, except that it's
1114  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
1115  * January 1, 1970, 00:00:00 GMT.
1116  *
1117  * This means we have to do some extra work to convert it.  This code is
1118  * based on the Samba code:
1119  *
1120  *      Unix SMB/Netbios implementation.
1121  *      Version 1.9.
1122  *      time handling functions
1123  *      Copyright (C) Andrew Tridgell 1992-1998
1124  */
1125
1126 /*
1127  * Yield the difference between *A and *B, in seconds, ignoring leap
1128  * seconds.
1129  */
1130 #define TM_YEAR_BASE 1900
1131
1132 static int
1133 tm_diff(struct tm *a, struct tm *b)
1134 {
1135         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1136         int by = b->tm_year + (TM_YEAR_BASE - 1);
1137         int intervening_leap_days =
1138             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1139         int years = ay - by;
1140         int days =
1141             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1142         int hours = 24*days + (a->tm_hour - b->tm_hour);
1143         int minutes = 60*hours + (a->tm_min - b->tm_min);
1144         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1145
1146         return seconds;
1147 }
1148
1149 /*
1150  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1151  * determined.
1152  */
1153 static int
1154 TimeZone(time_t t)
1155 {
1156         struct tm *tm = gmtime(&t);
1157         struct tm tm_utc;
1158
1159         if (tm == NULL)
1160                 return 0;
1161         tm_utc = *tm;
1162         tm = localtime(&t);
1163         if (tm == NULL)
1164                 return 0;
1165         return tm_diff(&tm_utc,tm);
1166 }
1167
1168 /*
1169  * Return the same value as TimeZone, but it should be more efficient.
1170  *
1171  * We keep a table of DST offsets to prevent calling localtime() on each
1172  * call of this function. This saves a LOT of time on many unixes.
1173  *
1174  * Updated by Paul Eggert <eggert@twinsun.com>
1175  */
1176 #ifndef CHAR_BIT
1177 #define CHAR_BIT 8
1178 #endif
1179
1180 #ifndef TIME_T_MIN
1181 #define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1182                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
1183 #endif
1184 #ifndef TIME_T_MAX
1185 #define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
1186 #endif
1187
1188 static int
1189 TimeZoneFaster(time_t t)
1190 {
1191         static struct dst_table {time_t start,end; int zone;} *tdt;
1192         static struct dst_table *dst_table = NULL;
1193         static int table_size = 0;
1194         int i;
1195         int zone = 0;
1196
1197         if (t == 0)
1198                 t = time(NULL);
1199
1200         /* Tunis has a 8 day DST region, we need to be careful ... */
1201 #define MAX_DST_WIDTH (365*24*60*60)
1202 #define MAX_DST_SKIP (7*24*60*60)
1203
1204         for (i = 0; i < table_size; i++) {
1205                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1206                         break;
1207         }
1208
1209         if (i < table_size) {
1210                 zone = dst_table[i].zone;
1211         } else {
1212                 time_t low,high;
1213
1214                 zone = TimeZone(t);
1215                 if (dst_table == NULL)
1216                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1217                 else
1218                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1219                 if (tdt == NULL) {
1220                         if (dst_table)
1221                                 g_free(dst_table);
1222                         table_size = 0;
1223                 } else {
1224                         dst_table = tdt;
1225                         table_size++;
1226
1227                         dst_table[i].zone = zone;
1228                         dst_table[i].start = dst_table[i].end = t;
1229
1230                         /* no entry will cover more than 6 months */
1231                         low = t - MAX_DST_WIDTH/2;
1232
1233                         high = t + MAX_DST_WIDTH/2;
1234
1235                         /*
1236                          * Widen the new entry using two bisection searches.
1237                          */
1238                         while (low+60*60 < dst_table[i].start) {
1239                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1240                                         t = dst_table[i].start - MAX_DST_SKIP;
1241                                 else
1242                                         t = low + (dst_table[i].start-low)/2;
1243                                 if (TimeZone(t) == zone)
1244                                         dst_table[i].start = t;
1245                                 else
1246                                         low = t;
1247                         }
1248
1249                         while (high-60*60 > dst_table[i].end) {
1250                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1251                                         t = dst_table[i].end + MAX_DST_SKIP;
1252                                 else
1253                                         t = high - (high-dst_table[i].end)/2;
1254                                 if (TimeZone(t) == zone)
1255                                         dst_table[i].end = t;
1256                                 else
1257                                         high = t;
1258                         }
1259                 }
1260         }
1261         return zone;
1262 }
1263
1264 /*
1265  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1266  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1267  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1268  * daylight savings transitions because some local times are ambiguous.
1269  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1270  */
1271 static int
1272 LocTimeDiff(time_t lt)
1273 {
1274         int d = TimeZoneFaster(lt);
1275         time_t t = lt + d;
1276
1277         /* if overflow occurred, ignore all the adjustments so far */
1278         if (((t < lt) ^ (d < 0)))
1279                 t = lt;
1280
1281         /*
1282          * Now t should be close enough to the true UTC to yield the
1283          * right answer.
1284          */
1285         return TimeZoneFaster(t);
1286 }
1287
1288 static int
1289 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1290 {
1291         guint32 timeval;
1292         nstime_t ts;
1293
1294         timeval = tvb_get_letohl(tvb, offset);
1295         if (timeval == 0xffffffff) {
1296                 proto_tree_add_text(tree, tvb, offset, 4,
1297                     "%s: No time specified (0xffffffff)",
1298                     proto_registrar_get_name(hf_date));
1299                 offset += 4;
1300                 return offset;
1301         }
1302
1303         /*
1304          * We add the local time offset.
1305          */
1306         ts.secs = timeval + LocTimeDiff(timeval);
1307         ts.nsecs = 0;
1308
1309         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1310         offset += 4;
1311
1312         return offset;
1313 }
1314
1315 static int
1316 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1317     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1318 {
1319         guint16 dos_time, dos_date;
1320         proto_item *item = NULL;
1321         proto_tree *tree = NULL;
1322         struct tm tm;
1323         time_t t;
1324         static const int mday_noleap[12] = {
1325                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1326         };
1327         static const int mday_leap[12] = {
1328                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1329         };
1330 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1331         nstime_t tv;
1332
1333         if (time_first) {
1334                 dos_time = tvb_get_letohs(tvb, offset);
1335                 dos_date = tvb_get_letohs(tvb, offset+2);
1336         } else {
1337                 dos_date = tvb_get_letohs(tvb, offset);
1338                 dos_time = tvb_get_letohs(tvb, offset+2);
1339         }
1340
1341         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1342             (dos_date == 0 && dos_time == 0)) {
1343                 /*
1344                  * No date/time specified.
1345                  */
1346                 if(parent_tree){
1347                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1348                             "%s: No time specified (0x%08x)",
1349                             proto_registrar_get_name(hf_date),
1350                             (dos_date << 16) | dos_time);
1351                 }
1352                 offset += 4;
1353                 return offset;
1354         }
1355
1356         tm.tm_sec = (dos_time&0x1f)*2;
1357         tm.tm_min = (dos_time>>5)&0x3f;
1358         tm.tm_hour = (dos_time>>11)&0x1f;
1359         tm.tm_mday = dos_date&0x1f;
1360         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1361         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1362         tm.tm_isdst = -1;
1363
1364         /*
1365          * Do some sanity checks before calling "mktime()";
1366          * "mktime()" doesn't do them, it "normalizes" out-of-range
1367          * values.
1368          */
1369         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1370            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1371            (ISLEAP(tm.tm_year + 1900) ?
1372              tm.tm_mday > mday_leap[tm.tm_mon] :
1373              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1374              (t = mktime(&tm)) == -1) {
1375                 /*
1376                  * Invalid date/time.
1377                  */
1378                 if (parent_tree) {
1379                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1380                             "%s: Invalid time",
1381                             proto_registrar_get_name(hf_date));
1382                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1383                         if (time_first) {
1384                                 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);
1385                                 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);
1386                         } else {
1387                                 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);
1388                                 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);
1389                         }
1390                 }
1391                 offset += 4;
1392                 return offset;
1393         }
1394
1395         tv.secs = t;
1396         tv.nsecs = 0;
1397
1398         if(parent_tree){
1399                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1400                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1401                 if (time_first) {
1402                         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);
1403                         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);
1404                 } else {
1405                         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);
1406                         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);
1407                 }
1408         }
1409
1410         offset += 4;
1411
1412         return offset;
1413 }
1414
1415 static const true_false_string tfs_disposition_delete_on_close = {
1416         "DELETE this file when closed",
1417         "Normal access, do not delete on close"
1418 };
1419
1420 static const true_false_string tfs_pipe_info_flag = {
1421         "SET NAMED PIPE mode",
1422         "Clear NAMED PIPE mode"
1423 };
1424
1425
1426 static const value_string da_access_vals[] = {
1427         { 0,            "Open for reading"},
1428         { 1,            "Open for writing"},
1429         { 2,            "Open for reading and writing"},
1430         { 3,            "Open for execute"},
1431         {0, NULL}
1432 };
1433 static const value_string da_sharing_vals[] = {
1434         { 0,            "Compatibility mode"},
1435         { 1,            "Deny read/write/execute (exclusive)"},
1436         { 2,            "Deny write"},
1437         { 3,            "Deny read/execute"},
1438         { 4,            "Deny none"},
1439         {0, NULL}
1440 };
1441 static const value_string da_locality_vals[] = {
1442         { 0,            "Locality of reference unknown"},
1443         { 1,            "Mainly sequential access"},
1444         { 2,            "Mainly random access"},
1445         { 3,            "Random access with some locality"},
1446         {0, NULL}
1447 };
1448 static const true_false_string tfs_da_caching = {
1449         "Do not cache this file",
1450         "Caching permitted on this file"
1451 };
1452 static const true_false_string tfs_da_writetru = {
1453         "Write through enabled",
1454         "Write through disabled"
1455 };
1456 static int
1457 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *type)
1458 {
1459         guint16 mask;
1460         proto_item *item;
1461         proto_tree *tree;
1462
1463         mask = tvb_get_letohs(tvb, offset);
1464
1465         if(parent_tree){
1466                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1467                         "%s Access: 0x%04x", type, mask);
1468                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1469
1470                 proto_tree_add_boolean(tree, hf_smb_access_writetru,
1471                         tvb, offset, 2, mask);
1472                 proto_tree_add_boolean(tree, hf_smb_access_caching,
1473                         tvb, offset, 2, mask);
1474                 proto_tree_add_uint(tree, hf_smb_access_locality,
1475                         tvb, offset, 2, mask);
1476                 proto_tree_add_uint(tree, hf_smb_access_sharing,
1477                         tvb, offset, 2, mask);
1478                 proto_tree_add_uint(tree, hf_smb_access_mode,
1479                         tvb, offset, 2, mask);
1480         }
1481
1482         offset += 2;
1483
1484         return offset;
1485 }
1486
1487 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1488 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1489 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1490 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1491 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1492 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1493 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1494 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1495 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1496 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1497 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1498 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1499 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1500 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1501 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1502
1503 static const true_false_string tfs_file_attribute_read_only = {
1504         "This file is READ ONLY",
1505         "This file is NOT read only",
1506 };
1507 static const true_false_string tfs_file_attribute_hidden = {
1508         "This is a HIDDEN file",
1509         "This is NOT a hidden file"
1510 };
1511 static const true_false_string tfs_file_attribute_system = {
1512         "This is a SYSTEM file",
1513         "This is NOT a system file"
1514 };
1515 static const true_false_string tfs_file_attribute_volume = {
1516         "This is a VOLUME ID",
1517         "This is NOT a volume ID"
1518 };
1519 static const true_false_string tfs_file_attribute_directory = {
1520         "This is a DIRECTORY",
1521         "This is NOT a directory"
1522 };
1523 static const true_false_string tfs_file_attribute_archive = {
1524         "This file has been modified since last ARCHIVE",
1525         "This file has NOT been modified since last archive"
1526 };
1527 static const true_false_string tfs_file_attribute_device = {
1528         "This is a DEVICE",
1529         "This is NOT a device"
1530 };
1531 static const true_false_string tfs_file_attribute_normal = {
1532         "This file is an ordinary file",
1533         "This file has some attribute set"
1534 };
1535 static const true_false_string tfs_file_attribute_temporary = {
1536         "This is a TEMPORARY file",
1537         "This is NOT a temporary file"
1538 };
1539 static const true_false_string tfs_file_attribute_sparse = {
1540         "This is a SPARSE file",
1541         "This is NOT a sparse file"
1542 };
1543 static const true_false_string tfs_file_attribute_reparse = {
1544         "This file has an associated REPARSE POINT",
1545         "This file does NOT have an associated reparse point"
1546 };
1547 static const true_false_string tfs_file_attribute_compressed = {
1548         "This is a COMPRESSED file",
1549         "This is NOT a compressed file"
1550 };
1551 static const true_false_string tfs_file_attribute_offline = {
1552         "This file is OFFLINE",
1553         "This file is NOT offline"
1554 };
1555 static const true_false_string tfs_file_attribute_not_content_indexed = {
1556         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1557         "This file MAY be indexed by the content indexing service"
1558 };
1559 static const true_false_string tfs_file_attribute_encrypted = {
1560         "This is an ENCRYPTED file",
1561         "This is NOT an encrypted file"
1562 };
1563
1564 /*
1565  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are
1566  * listed as USHORT, and seem to be in packets in the wild, while in other
1567  * places they are listed as ULONG, and also seem to be.
1568  *
1569  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1570  * bytes to consume.
1571  */
1572
1573 int
1574 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1575                         int bytes)
1576 {
1577         guint16 mask;
1578         proto_item *item;
1579         proto_tree *tree;
1580
1581         if (bytes != 2 && bytes != 4) {
1582                 THROW(ReportedBoundsError);
1583         }
1584
1585         /*
1586          * The actual bits of interest appear to only be a USHORT
1587          */
1588         /* FIXME if this ever changes! */
1589         mask = tvb_get_letohs(tvb, offset);
1590
1591         if(parent_tree){
1592                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1593                         "File Attributes: 0x%08x", mask);
1594                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1595
1596                 proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1597                                        tvb, offset, bytes, mask);
1598                 proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1599                                        tvb, offset, bytes, mask);
1600                 proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1601                                        tvb, offset, bytes, mask);
1602                 proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1603                                        tvb, offset, bytes, mask);
1604                 proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1605                                        tvb, offset, bytes, mask);
1606                 proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1607                                        tvb, offset, bytes, mask);
1608                 proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1609                                        tvb, offset, bytes, mask);
1610                 proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1611                                        tvb, offset, bytes, mask);
1612                 proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1613                                        tvb, offset, bytes, mask);
1614                 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1615                                 tvb, offset, bytes, mask);
1616                 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1617                                 tvb, offset, bytes, mask);
1618                 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1619                                 tvb, offset, bytes, mask);
1620                 proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1621                                 tvb, offset, bytes, mask);
1622                 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1623                                 tvb, offset, bytes, mask);
1624                 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1625                                 tvb, offset, bytes, mask);
1626         }
1627
1628         offset += bytes;
1629
1630         return offset;
1631 }
1632
1633 /* 3.11 */
1634 static int
1635 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1636     int len, guint32 mask)
1637 {
1638         proto_item *item;
1639         proto_tree *tree;
1640
1641         if(parent_tree){
1642                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
1643                         "File Attributes: 0x%08x", mask);
1644                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1645
1646                 /*
1647                  * XXX - Network Monitor disagrees on some of the
1648                  * bits, e.g. the bits above temporary are "atomic write"
1649                  * and "transaction write", and it says nothing about the
1650                  * bits above that.
1651                  *
1652                  * Does the Win32 API documentation, or the NT Native API book,
1653                  * suggest anything?
1654                  */
1655                 proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1656                         tvb, offset, len, mask);
1657                 proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1658                         tvb, offset, len, mask);
1659                 proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1660                         tvb, offset, len, mask);
1661                 proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1662                         tvb, offset, len, mask);
1663                 proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1664                         tvb, offset, len, mask);
1665                 proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1666                         tvb, offset, len, mask);
1667                 proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1668                         tvb, offset, len, mask);
1669                 proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1670                         tvb, offset, len, mask);
1671                 proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1672                         tvb, offset, len, mask);
1673                 proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1674                         tvb, offset, len, mask);
1675                 proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1676                         tvb, offset, len, mask);
1677                 proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1678                         tvb, offset, len, mask);
1679                 proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1680                         tvb, offset, len, mask);
1681                 proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1682                         tvb, offset, len, mask);
1683                 proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1684                         tvb, offset, len, mask);
1685         }
1686
1687         offset += len;
1688
1689         return offset;
1690 }
1691
1692 /* 3.11 */
1693 static int
1694 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1695 {
1696         guint32 mask;
1697
1698         mask = tvb_get_letohl(tvb, offset);
1699
1700         offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, 4, mask);
1701
1702         return offset;
1703 }
1704
1705 static int
1706 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1707 {
1708         guint8 mask;
1709         proto_item *item;
1710         proto_tree *tree;
1711
1712         mask = tvb_get_guint8(tvb, offset);
1713
1714         if(parent_tree){
1715                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1716                         "File Attributes: 0x%02x", mask);
1717                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1718
1719                 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1720                         tvb, offset, 1, mask);
1721                 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1722                         tvb, offset, 1, mask);
1723                 proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1724                         tvb, offset, 1, mask);
1725                 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1726                         tvb, offset, 1, mask);
1727                 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1728                         tvb, offset, 1, mask);
1729                 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1730                         tvb, offset, 1, mask);
1731         }
1732
1733         offset += 1;
1734
1735         return offset;
1736 }
1737
1738 static const true_false_string tfs_search_attribute_read_only = {
1739         "Include READ ONLY files in search results",
1740         "Do NOT include read only files in search results",
1741 };
1742 static const true_false_string tfs_search_attribute_hidden = {
1743         "Include HIDDEN files in search results",
1744         "Do NOT include hidden files in search results"
1745 };
1746 static const true_false_string tfs_search_attribute_system = {
1747         "Include SYSTEM files in search results",
1748         "Do NOT include system files in search results"
1749 };
1750 static const true_false_string tfs_search_attribute_volume = {
1751         "Include VOLUME IDs in search results",
1752         "Do NOT include volume IDs in search results"
1753 };
1754 static const true_false_string tfs_search_attribute_directory = {
1755         "Include DIRECTORIES in search results",
1756         "Do NOT include directories in search results"
1757 };
1758 static const true_false_string tfs_search_attribute_archive = {
1759         "Include ARCHIVE files in search results",
1760         "Do NOT include archive files in search results"
1761 };
1762
1763 static int
1764 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1765 {
1766         guint16 mask;
1767         proto_item *item;
1768         proto_tree *tree;
1769
1770         mask = tvb_get_letohs(tvb, offset);
1771
1772         if(parent_tree){
1773                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1774                         "Search Attributes: 0x%04x", mask);
1775                 tree = proto_item_add_subtree(item, ett_smb_search);
1776
1777                 proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1778                         tvb, offset, 2, mask);
1779                 proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1780                         tvb, offset, 2, mask);
1781                 proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1782                         tvb, offset, 2, mask);
1783                 proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1784                         tvb, offset, 2, mask);
1785                 proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1786                         tvb, offset, 2, mask);
1787                 proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1788                         tvb, offset, 2, mask);
1789         }
1790
1791         offset += 2;
1792         return offset;
1793 }
1794
1795 #if 0
1796 /*
1797  * XXX - this isn't used.
1798  * Is this used for anything?  NT Create AndX doesn't use it.
1799  * Is there some 16-bit attribute field with more bits than Read Only,
1800  * Hidden, System, Volume ID, Directory, and Archive?
1801  */
1802 static int
1803 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1804 {
1805         guint32 mask;
1806         proto_item *item;
1807         proto_tree *tree;
1808
1809         mask = tvb_get_letohl(tvb, offset);
1810
1811         if(parent_tree){
1812                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1813                         "File Attributes: 0x%08x", mask);
1814                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1815         }
1816         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1817                 tvb, offset, 2, mask);
1818         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1819                 tvb, offset, 2, mask);
1820         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1821                 tvb, offset, 2, mask);
1822         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1823                 tvb, offset, 2, mask);
1824         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1825                 tvb, offset, 2, mask);
1826         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1827                 tvb, offset, 2, mask);
1828         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1829                 tvb, offset, 2, mask);
1830         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1831                 tvb, offset, 2, mask);
1832         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1833                 tvb, offset, 2, mask);
1834         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1835                 tvb, offset, 2, mask);
1836         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1837                 tvb, offset, 2, mask);
1838         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1839                 tvb, offset, 2, mask);
1840         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1841                 tvb, offset, 2, mask);
1842         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1843                 tvb, offset, 2, mask);
1844         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1845                 tvb, offset, 2, mask);
1846
1847         offset += 2;
1848
1849         return offset;
1850 }
1851 #endif
1852
1853
1854 #define SERVER_CAP_RAW_MODE            0x00000001
1855 #define SERVER_CAP_MPX_MODE            0x00000002
1856 #define SERVER_CAP_UNICODE             0x00000004
1857 #define SERVER_CAP_LARGE_FILES         0x00000008
1858 #define SERVER_CAP_NT_SMBS             0x00000010
1859 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1860 #define SERVER_CAP_STATUS32            0x00000040
1861 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1862 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1863 #define SERVER_CAP_NT_FIND             0x00000200
1864 #define SERVER_CAP_DFS                 0x00001000
1865 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1866 #define SERVER_CAP_LARGE_READX         0x00004000
1867 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1868 #define SERVER_CAP_UNIX                0x00800000
1869 #define SERVER_CAP_RESERVED            0x02000000
1870 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1871 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1872 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1873 static const true_false_string tfs_server_cap_raw_mode = {
1874         "Read Raw and Write Raw are supported",
1875         "Read Raw and Write Raw are not supported"
1876 };
1877 static const true_false_string tfs_server_cap_mpx_mode = {
1878         "Read Mpx and Write Mpx are supported",
1879         "Read Mpx and Write Mpx are not supported"
1880 };
1881 static const true_false_string tfs_server_cap_unicode = {
1882         "Unicode strings are supported",
1883         "Unicode strings are not supported"
1884 };
1885 static const true_false_string tfs_server_cap_large_files = {
1886         "Large files are supported",
1887         "Large files are not supported",
1888 };
1889 static const true_false_string tfs_server_cap_nt_smbs = {
1890         "NT SMBs are supported",
1891         "NT SMBs are not supported"
1892 };
1893 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1894         "RPC remote APIs are supported",
1895         "RPC remote APIs are not supported"
1896 };
1897 static const true_false_string tfs_server_cap_nt_status = {
1898         "NT status codes are supported",
1899         "NT status codes are not supported"
1900 };
1901 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1902         "Level 2 oplocks are supported",
1903         "Level 2 oplocks are not supported"
1904 };
1905 static const true_false_string tfs_server_cap_lock_and_read = {
1906         "Lock and Read is supported",
1907         "Lock and Read is not supported"
1908 };
1909 static const true_false_string tfs_server_cap_nt_find = {
1910         "NT Find is supported",
1911         "NT Find is not supported"
1912 };
1913 static const true_false_string tfs_server_cap_dfs = {
1914         "Dfs is supported",
1915         "Dfs is not supported"
1916 };
1917 static const true_false_string tfs_server_cap_infolevel_passthru = {
1918         "NT information level request passthrough is supported",
1919         "NT information level request passthrough is not supported"
1920 };
1921 static const true_false_string tfs_server_cap_large_readx = {
1922         "Large Read andX is supported",
1923         "Large Read andX is not supported"
1924 };
1925 static const true_false_string tfs_server_cap_large_writex = {
1926         "Large Write andX is supported",
1927         "Large Write andX is not supported"
1928 };
1929 static const true_false_string tfs_server_cap_unix = {
1930         "UNIX extensions are supported",
1931         "UNIX extensions are not supported"
1932 };
1933 static const true_false_string tfs_server_cap_reserved = {
1934         "Reserved",
1935         "Reserved"
1936 };
1937 static const true_false_string tfs_server_cap_bulk_transfer = {
1938         "Bulk Read and Bulk Write are supported",
1939         "Bulk Read and Bulk Write are not supported"
1940 };
1941 static const true_false_string tfs_server_cap_compressed_data = {
1942         "Compressed data transfer is supported",
1943         "Compressed data transfer is not supported"
1944 };
1945 static const true_false_string tfs_server_cap_extended_security = {
1946         "Extended security exchanges are supported",
1947         "Extended security exchanges are not supported"
1948 };
1949 static int
1950 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1951 {
1952         guint32 mask;
1953         proto_item *item;
1954         proto_tree *tree;
1955
1956         mask = tvb_get_letohl(tvb, offset);
1957
1958         if(parent_tree){
1959                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1960                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1961
1962                 proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1963                         tvb, offset, 4, mask);
1964                 proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1965                         tvb, offset, 4, mask);
1966                 proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1967                         tvb, offset, 4, mask);
1968                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1969                         tvb, offset, 4, mask);
1970                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1971                         tvb, offset, 4, mask);
1972                 proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1973                         tvb, offset, 4, mask);
1974                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1975                         tvb, offset, 4, mask);
1976                 proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1977                         tvb, offset, 4, mask);
1978                 proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1979                         tvb, offset, 4, mask);
1980                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1981                         tvb, offset, 4, mask);
1982                 proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1983                         tvb, offset, 4, mask);
1984                 proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1985                         tvb, offset, 4, mask);
1986                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1987                         tvb, offset, 4, mask);
1988                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1989                         tvb, offset, 4, mask);
1990                 proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1991                         tvb, offset, 4, mask);
1992                 proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1993                         tvb, offset, 4, mask);
1994                 proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1995                         tvb, offset, 4, mask);
1996                 proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1997                         tvb, offset, 4, mask);
1998                 proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1999                         tvb, offset, 4, mask);
2000         }
2001
2002         return mask;
2003 }
2004
2005 #define RAWMODE_READ   0x01
2006 #define RAWMODE_WRITE  0x02
2007 static const true_false_string tfs_rm_read = {
2008         "Read Raw is supported",
2009         "Read Raw is not supported"
2010 };
2011 static const true_false_string tfs_rm_write = {
2012         "Write Raw is supported",
2013         "Write Raw is not supported"
2014 };
2015
2016 static int
2017 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2018 {
2019         guint16 mask;
2020         proto_item *item;
2021         proto_tree *tree;
2022
2023         mask = tvb_get_letohs(tvb, offset);
2024
2025         if(parent_tree){
2026                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
2027                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
2028
2029                 proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
2030                 proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
2031         }
2032
2033         offset += 2;
2034
2035         return offset;
2036 }
2037
2038 #define SECURITY_MODE_MODE             0x01
2039 #define SECURITY_MODE_PASSWORD         0x02
2040 #define SECURITY_MODE_SIGNATURES       0x04
2041 #define SECURITY_MODE_SIG_REQUIRED     0x08
2042 static const true_false_string tfs_sm_mode = {
2043         "USER security mode",
2044         "SHARE security mode"
2045 };
2046 static const true_false_string tfs_sm_password = {
2047         "ENCRYPTED password. Use challenge/response",
2048         "PLAINTEXT password"
2049 };
2050 static const true_false_string tfs_sm_signatures = {
2051         "Security signatures ENABLED",
2052         "Security signatures NOT enabled"
2053 };
2054 static const true_false_string tfs_sm_sig_required = {
2055         "Security signatures REQUIRED",
2056         "Security signatures NOT required"
2057 };
2058
2059 static int
2060 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2061 {
2062         guint16 mask = 0;
2063         proto_item *item = NULL;
2064         proto_tree *tree = NULL;
2065
2066         switch(wc){
2067         case 13:
2068                 mask = tvb_get_letohs(tvb, offset);
2069                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2070                                 "Security Mode: 0x%04x", mask);
2071                 tree = proto_item_add_subtree(item, ett_smb_mode);
2072                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2073                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2074                 offset += 2;
2075                 break;
2076
2077         case 17:
2078                 mask = tvb_get_guint8(tvb, offset);
2079                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2080                                 "Security Mode: 0x%02x", mask);
2081                 tree = proto_item_add_subtree(item, ett_smb_mode);
2082                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2083                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2084                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2085                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2086                 offset += 1;
2087                 break;
2088         }
2089
2090         return offset;
2091 }
2092
2093 static int
2094 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2095 {
2096         proto_item *it = NULL;
2097         proto_tree *tr = NULL;
2098         guint16 bc;
2099         guint8 wc;
2100
2101         WORD_COUNT;
2102
2103         BYTE_COUNT;
2104
2105         if(tree){
2106                 tvb_ensure_bytes_exist(tvb, offset, bc);
2107                 it = proto_tree_add_text(tree, tvb, offset, bc,
2108                                 "Requested Dialects");
2109                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2110         }
2111
2112         while(bc){
2113                 int len;
2114                 const guint8 *str;
2115                 proto_item *dit = NULL;
2116                 proto_tree *dtr = NULL;
2117
2118                 /* XXX - what if this runs past bc? */
2119                 tvb_ensure_bytes_exist(tvb, offset+1, 1);
2120                 len = tvb_strsize(tvb, offset+1);
2121                 str = tvb_get_ptr(tvb, offset+1, len);
2122
2123                 if(tr){
2124                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2125                                         "Dialect: %s", str);
2126                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2127                 }
2128
2129                 /* Buffer Format */
2130                 CHECK_BYTE_COUNT(1);
2131                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2132                         TRUE);
2133                 COUNT_BYTES(1);
2134
2135                 /*Dialect Name */
2136                 CHECK_BYTE_COUNT(len);
2137                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2138                         len, str);
2139                 COUNT_BYTES(len);
2140         }
2141
2142         END_OF_SMB
2143
2144         return offset;
2145 }
2146
2147 static int
2148 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2149 {
2150         smb_info_t *si = pinfo->private_data;
2151         guint8 wc;
2152         guint16 dialect;
2153         const char *dn;
2154         int dn_len;
2155         guint16 bc;
2156         guint16 ekl=0;
2157         guint32 caps=0;
2158         gint16 tz;
2159
2160         DISSECTOR_ASSERT(si);
2161
2162         WORD_COUNT;
2163
2164         /* Dialect Index */
2165         dialect = tvb_get_letohs(tvb, offset);
2166         switch(wc){
2167         case 1:
2168                 if(dialect==0xffff){
2169                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2170                                 tvb, offset, 2, dialect,
2171                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2172                 } else {
2173                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2174                                 tvb, offset, 2, dialect);
2175                 }
2176                 break;
2177         case 13:
2178                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2179                         tvb, offset, 2, dialect,
2180                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2181                 break;
2182         case 17:
2183                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2184                         tvb, offset, 2, dialect,
2185                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2186                 break;
2187         default:
2188                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
2189                 proto_tree_add_text(tree, tvb, offset, wc*2,
2190                         "Words for unknown response format");
2191                 offset += wc*2;
2192                 goto bytecount;
2193         }
2194         offset += 2;
2195
2196         switch(wc){
2197         case 13:
2198                 /* Security Mode */
2199                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2200
2201                 /* Maximum Transmit Buffer Size */
2202                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2203                         tvb, offset, 2, TRUE);
2204                 offset += 2;
2205
2206                 /* Maximum Multiplex Count */
2207                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2208                         tvb, offset, 2, TRUE);
2209                 offset += 2;
2210
2211                 /* Maximum Vcs Number */
2212                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2213                         tvb, offset, 2, TRUE);
2214                 offset += 2;
2215
2216                 /* raw mode */
2217                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2218
2219                 /* session key */
2220                 proto_tree_add_item(tree, hf_smb_session_key,
2221                         tvb, offset, 4, TRUE);
2222                 offset += 4;
2223
2224                 /* current time and date at server */
2225                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2226                     TRUE);
2227
2228                 /* time zone */
2229                 tz = tvb_get_letohs(tvb, offset);
2230                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2231                 offset += 2;
2232
2233                 /* encryption key length */
2234                 ekl = tvb_get_letohs(tvb, offset);
2235                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2236                 offset += 2;
2237
2238                 /* 2 reserved bytes */
2239                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2240                 offset += 2;
2241
2242                 break;
2243
2244         case 17:
2245                 /* Security Mode */
2246                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2247
2248                 /* Maximum Multiplex Count */
2249                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2250                         tvb, offset, 2, TRUE);
2251                 offset += 2;
2252
2253                 /* Maximum Vcs Number */
2254                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2255                         tvb, offset, 2, TRUE);
2256                 offset += 2;
2257
2258                 /* Maximum Transmit Buffer Size */
2259                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2260                         tvb, offset, 4, TRUE);
2261                 offset += 4;
2262
2263                 /* maximum raw buffer size */
2264                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2265                         tvb, offset, 4, TRUE);
2266                 offset += 4;
2267
2268                 /* session key */
2269                 proto_tree_add_item(tree, hf_smb_session_key,
2270                         tvb, offset, 4, TRUE);
2271                 offset += 4;
2272
2273                 /* server capabilities */
2274                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2275                 offset += 4;
2276
2277                 /* system time */
2278                 offset = dissect_nt_64bit_time(tvb, tree, offset,
2279                                 hf_smb_system_time);
2280
2281                 /* time zone */
2282                 tz = tvb_get_letohs(tvb, offset);
2283                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2284                         tvb, offset, 2, tz,
2285                         "Server Time Zone: %d min from UTC", tz);
2286                 offset += 2;
2287
2288                 /* encryption key length */
2289                 ekl = tvb_get_guint8(tvb, offset);
2290                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2291                         tvb, offset, 1, ekl);
2292                 offset += 1;
2293
2294                 break;
2295         }
2296
2297         BYTE_COUNT;
2298
2299         switch(wc){
2300         case 13:
2301                 /* challenge/response encryption key */
2302                 if(ekl){
2303                         CHECK_BYTE_COUNT(ekl);
2304                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2305                         COUNT_BYTES(ekl);
2306                 }
2307
2308                 /*
2309                  * Primary domain.
2310                  *
2311                  * XXX - not present if negotiated dialect isn't
2312                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2313                  * have to see the request, or assume what dialect strings
2314                  * were sent, to determine that.
2315                  *
2316                  * Is this something other than a primary domain if the
2317                  * negotiated dialect is Windows for Workgroups 3.1a?
2318                  * It appears to be 8 bytes of binary data in at least
2319                  * one capture - is that an encryption key or something
2320                  * such as that?
2321                  */
2322                 dn = get_unicode_or_ascii_string(tvb, &offset,
2323                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2324                 if (dn == NULL)
2325                         goto endofcommand;
2326                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2327                         offset, dn_len,dn);
2328                 COUNT_BYTES(dn_len);
2329                 break;
2330
2331         case 17:
2332                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2333                         /* challenge/response encryption key */
2334                         /* XXX - is this aligned on an even boundary? */
2335                         if(ekl){
2336                                 CHECK_BYTE_COUNT(ekl);
2337                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2338                                         tvb, offset, ekl, TRUE);
2339                                 COUNT_BYTES(ekl);
2340                         }
2341
2342                         /* domain */
2343                         /* this string is special, unicode is flagged in caps */
2344                         /* This string is NOT padded to be 16bit aligned.
2345                            (seen in actual capture)
2346                            XXX - I've seen a capture where it appears to be
2347                            so aligned, but I've also seen captures where
2348                            it is.  The captures where it appeared to be
2349                            aligned may have been from buggy servers. */
2350                         /* However, don't get rid of existing setting */
2351                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2352                           si->unicode;
2353
2354                         dn = get_unicode_or_ascii_string(tvb,
2355                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2356                                 &bc);
2357                         if (dn == NULL)
2358                                 goto endofcommand;
2359                         proto_tree_add_string(tree, hf_smb_primary_domain,
2360                                 tvb, offset, dn_len, dn);
2361                         COUNT_BYTES(dn_len);
2362
2363                         /* server name, seen in w2k pro capture */
2364                         dn = get_unicode_or_ascii_string(tvb,
2365                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2366                                 &bc);
2367                         if (dn == NULL)
2368                                 goto endofcommand;
2369                         proto_tree_add_string(tree, hf_smb_server,
2370                                 tvb, offset, dn_len, dn);
2371                         COUNT_BYTES(dn_len);
2372
2373                 } else {
2374                         proto_item *blob_item;
2375                         guint16 sbloblen;
2376
2377                         /* guid */
2378                         /* XXX - show it in the standard Microsoft format
2379                            for GUIDs? */
2380                         CHECK_BYTE_COUNT(16);
2381                         proto_tree_add_item(tree, hf_smb_server_guid,
2382                                 tvb, offset, 16, TRUE);
2383                         COUNT_BYTES(16);
2384
2385                         /* security blob */
2386                         /* If it runs past the end of the captured data, don't
2387                          * try to put all of it into the protocol tree as the
2388                          * raw security blob; we might get an exception on
2389                          * short frames and then we will not see anything at all
2390                          * of the security blob.
2391                          */
2392                         sbloblen=bc;
2393                         if(sbloblen>tvb_length_remaining(tvb, offset)){
2394                                 sbloblen=tvb_length_remaining(tvb,offset);
2395                         }
2396                         blob_item = proto_tree_add_item(
2397                                 tree, hf_smb_security_blob,
2398                                 tvb, offset, sbloblen, TRUE);
2399
2400                         /*
2401                          * If Extended security and BCC == 16, then raw
2402                          * NTLMSSP is in use. We need to save this info
2403                          */
2404
2405                         if(bc){
2406                                 tvbuff_t *gssapi_tvb;
2407                                 proto_tree *gssapi_tree;
2408
2409                                 gssapi_tree = proto_item_add_subtree(
2410                                         blob_item, ett_smb_secblob);
2411
2412                                 /*
2413                                  * Set the reported length of this to
2414                                  * the reported length of the blob,
2415                                  * rather than the amount of data
2416                                  * available from the blob, so that
2417                                  * we'll throw the right exception if
2418                                  * it's too short.
2419                                  */
2420                                 gssapi_tvb = tvb_new_subset(
2421                                         tvb, offset, sbloblen, bc);
2422
2423                                 call_dissector(
2424                                         gssapi_handle, gssapi_tvb, pinfo,
2425                                         gssapi_tree);
2426
2427                                 if (si->ct)
2428                                   si->ct->raw_ntlmssp = 0;
2429
2430                                 COUNT_BYTES(bc);
2431                         }
2432                         else {
2433
2434                           /*
2435                            * There is no blob. We just have to make sure
2436                            * that subsequent routines know to call the
2437                            * right things ...
2438                            */
2439
2440                           if (si->ct)
2441                             si->ct->raw_ntlmssp = 1;
2442
2443                         }
2444                 }
2445                 break;
2446         }
2447
2448         END_OF_SMB
2449
2450         return offset;
2451 }
2452
2453
2454 static int
2455 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2456 {
2457         smb_info_t *si = pinfo->private_data;
2458         int dn_len;
2459         const char *dn;
2460         guint8 wc;
2461         guint16 bc;
2462
2463         DISSECTOR_ASSERT(si);
2464
2465         WORD_COUNT;
2466
2467         BYTE_COUNT;
2468
2469         /* buffer format */
2470         CHECK_BYTE_COUNT(1);
2471         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2472         COUNT_BYTES(1);
2473
2474         /* dir name */
2475         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2476                 FALSE, FALSE, &bc);
2477
2478         if(si->sip){
2479                 si->sip->extra_info_type=SMB_EI_FILENAME;
2480                 si->sip->extra_info=se_strdup(dn);
2481         }
2482
2483         if (dn == NULL)
2484                 goto endofcommand;
2485         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2486                 dn);
2487         COUNT_BYTES(dn_len);
2488
2489         if (check_col(pinfo->cinfo, COL_INFO)) {
2490                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
2491                     format_text(dn, strlen(dn)));
2492         }
2493
2494         END_OF_SMB
2495
2496         return offset;
2497 }
2498
2499 static int
2500 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2501 {
2502         guint8 wc;
2503         guint16 bc;
2504         smb_info_t *si = pinfo->private_data;
2505         proto_item *item=NULL;
2506
2507         DISSECTOR_ASSERT(si);
2508
2509         if(si->sip && si->sip->extra_info_type==SMB_EI_FILENAME){
2510                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, si->sip->extra_info);
2511                 PROTO_ITEM_SET_GENERATED(item);
2512         }
2513
2514
2515         WORD_COUNT;
2516
2517         BYTE_COUNT;
2518
2519         END_OF_SMB
2520
2521         return offset;
2522 }
2523
2524 static int
2525 dissect_rename_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2526 {
2527         guint8 wc;
2528         guint16 bc;
2529         smb_info_t *si = pinfo->private_data;
2530         proto_item *item=NULL;
2531
2532         DISSECTOR_ASSERT(si);
2533
2534         if(si->sip && si->sip->extra_info_type==SMB_EI_RENAMEDATA){
2535                 smb_rename_saved_info_t *rni=si->sip->extra_info;
2536
2537                 item=proto_tree_add_string(tree, hf_smb_old_file_name, tvb, 0, 0, rni->old_name);
2538                 PROTO_ITEM_SET_GENERATED(item);
2539                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, rni->new_name);
2540                 PROTO_ITEM_SET_GENERATED(item);
2541         }
2542
2543
2544         WORD_COUNT;
2545
2546         BYTE_COUNT;
2547
2548         END_OF_SMB
2549
2550         return offset;
2551 }
2552
2553 static int
2554 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2555 {
2556         guint16 ec, bc;
2557         guint8 wc;
2558
2559         WORD_COUNT;
2560
2561         /* echo count */
2562         ec = tvb_get_letohs(tvb, offset);
2563         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2564         offset += 2;
2565
2566         BYTE_COUNT;
2567
2568         if (bc != 0) {
2569                 /* echo data */
2570                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2571                 COUNT_BYTES(bc);
2572         }
2573
2574         END_OF_SMB
2575
2576         return offset;
2577 }
2578
2579 static int
2580 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2581 {
2582         guint16 bc;
2583         guint8 wc;
2584
2585         WORD_COUNT;
2586
2587         /* echo sequence number */
2588         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2589         offset += 2;
2590
2591         BYTE_COUNT;
2592
2593         if (bc != 0) {
2594                 /* echo data */
2595                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2596                 COUNT_BYTES(bc);
2597         }
2598
2599         END_OF_SMB
2600
2601         return offset;
2602 }
2603
2604 static int
2605 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2606 {
2607         smb_info_t *si = pinfo->private_data;
2608         int an_len, pwlen;
2609         const char *an;
2610         guint8 wc;
2611         guint16 bc;
2612
2613         DISSECTOR_ASSERT(si);
2614
2615         WORD_COUNT;
2616
2617         BYTE_COUNT;
2618
2619         /* buffer format */
2620         CHECK_BYTE_COUNT(1);
2621         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2622         COUNT_BYTES(1);
2623
2624         /* Path */
2625         an = get_unicode_or_ascii_string(tvb, &offset,
2626                 si->unicode, &an_len, FALSE, FALSE, &bc);
2627         if (an == NULL)
2628                 goto endofcommand;
2629         proto_tree_add_string(tree, hf_smb_path, tvb,
2630                 offset, an_len, an);
2631         COUNT_BYTES(an_len);
2632
2633         if (check_col(pinfo->cinfo, COL_INFO)) {
2634                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2635                     format_text(an, strlen(an)));
2636         }
2637
2638         /* buffer format */
2639         CHECK_BYTE_COUNT(1);
2640         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2641         COUNT_BYTES(1);
2642
2643         /* password, ANSI */
2644         /* XXX - what if this runs past bc? */
2645         pwlen = tvb_strsize(tvb, offset);
2646         CHECK_BYTE_COUNT(pwlen);
2647         proto_tree_add_item(tree, hf_smb_password,
2648                 tvb, offset, pwlen, TRUE);
2649         COUNT_BYTES(pwlen);
2650
2651         /* buffer format */
2652         CHECK_BYTE_COUNT(1);
2653         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2654         COUNT_BYTES(1);
2655
2656         /* Service */
2657         /*
2658          * XXX - the SNIA CIFS spec "Strings that are never passed in
2659          * Unicode are: ... The service name string in the
2660          * Tree_Connect_AndX SMB".  Is that claim false?
2661          */
2662         an = get_unicode_or_ascii_string(tvb, &offset,
2663                 si->unicode, &an_len, FALSE, FALSE, &bc);
2664         if (an == NULL)
2665                 goto endofcommand;
2666         proto_tree_add_string(tree, hf_smb_service, tvb,
2667                 offset, an_len, an);
2668         COUNT_BYTES(an_len);
2669
2670         END_OF_SMB
2671
2672         return offset;
2673 }
2674
2675 static int
2676 dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
2677 {
2678         proto_item *item, *subitem;
2679         proto_tree *tree;
2680         smb_uid_t *smb_uid=NULL;
2681
2682         item=proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
2683         tree=proto_item_add_subtree(item, ett_smb_uid);
2684
2685         smb_uid=se_tree_lookup32(si->ct->uid_tree, si->uid);
2686         if(smb_uid){
2687                 if(smb_uid->domain && smb_uid->account)
2688                         proto_item_append_text(item, "  (");
2689                 if(smb_uid->domain){
2690                         proto_item_append_text(item, "%s", smb_uid->domain);
2691                         subitem=proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
2692                         PROTO_ITEM_SET_GENERATED(subitem);
2693                 }
2694                 if(smb_uid->account){
2695                         proto_item_append_text(item, "\\%s", smb_uid->account);
2696                         subitem=proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
2697                         PROTO_ITEM_SET_GENERATED(subitem);
2698                 }
2699                 if(smb_uid->domain && smb_uid->account)
2700                         proto_item_append_text(item, ")");
2701                 if(smb_uid->logged_in>0){
2702                         subitem=proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
2703                         PROTO_ITEM_SET_GENERATED(subitem);
2704                 }
2705                 if(smb_uid->logged_out>0){
2706                         subitem=proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
2707                         PROTO_ITEM_SET_GENERATED(subitem);
2708                 }
2709         }
2710         offset += 2;
2711
2712         return offset;
2713 }
2714
2715 static int
2716 dissect_smb_tid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 tid, gboolean is_created, gboolean is_closed)
2717 {
2718         smb_info_t *si = pinfo->private_data;
2719         proto_item *it;
2720         proto_tree *tr;
2721         smb_tid_info_t *tid_info=NULL;
2722
2723         DISSECTOR_ASSERT(si);
2724
2725         /* tid */
2726         it=proto_tree_add_uint(tree, hf_smb_tid, tvb, offset, 2, tid);
2727         tr=proto_item_add_subtree(it, ett_smb_tid);
2728         offset += 2;
2729
2730         if((!pinfo->fd->flags.visited) && is_created){
2731                 tid_info=se_alloc(sizeof(smb_tid_info_t));
2732                 tid_info->opened_in=pinfo->fd->num;
2733                 tid_info->closed_in=0;
2734                 tid_info->type=SMB_FID_TYPE_UNKNOWN;
2735                 if(si->sip && (si->sip->extra_info_type==SMB_EI_TIDNAME)){
2736                         tid_info->filename=si->sip->extra_info;
2737                 } else {
2738                         tid_info->filename=NULL;
2739                 }
2740                 se_tree_insert32(si->ct->tid_tree, tid, tid_info);
2741         }
2742
2743         if(!tid_info){
2744                 tid_info=se_tree_lookup32_le(si->ct->tid_tree, tid);
2745         }
2746         if(!tid_info){
2747                 return offset;
2748         }
2749
2750         if((!pinfo->fd->flags.visited) && is_closed){
2751                 tid_info->closed_in=pinfo->fd->num;
2752         }
2753
2754         if(tid_info->opened_in){
2755                 if(tid_info->filename){
2756                         proto_item_append_text(it, "  (%s)", tid_info->filename);
2757
2758                         it=proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
2759                         PROTO_ITEM_SET_GENERATED(it);
2760                 }
2761
2762                 it=proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
2763                 PROTO_ITEM_SET_GENERATED(it);
2764         }
2765         if(tid_info->closed_in){
2766                 it=proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
2767                 PROTO_ITEM_SET_GENERATED(it);
2768         }
2769
2770
2771         return offset;
2772 }
2773
2774 static int
2775 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2776 {
2777         guint8 wc;
2778         guint16 bc;
2779
2780         WORD_COUNT;
2781
2782         /* Maximum Buffer Size */
2783         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2784         offset += 2;
2785
2786         /* tid */
2787         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tvb_get_letohs(tvb, offset), TRUE, FALSE);
2788
2789         BYTE_COUNT;
2790
2791         END_OF_SMB
2792
2793         return offset;
2794 }
2795
2796
2797 static const true_false_string tfs_of_create = {
2798         "Create file if it does not exist",
2799         "Fail if file does not exist"
2800 };
2801 static const value_string of_open[] = {
2802         { 0,            "Fail if file exists"},
2803         { 1,            "Open file if it exists"},
2804         { 2,            "Truncate file if it exists"},
2805         {0, NULL}
2806 };
2807 static int
2808 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2809 {
2810         guint16 mask;
2811         proto_item *item = NULL;
2812         proto_tree *tree = NULL;
2813
2814         mask = tvb_get_letohs(tvb, offset);
2815
2816         if(parent_tree){
2817                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2818                         "Open Function: 0x%04x", mask);
2819                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2820         }
2821
2822         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2823                 tvb, offset, 2, mask);
2824         proto_tree_add_uint(tree, hf_smb_open_function_open,
2825                 tvb, offset, 2, mask);
2826
2827         offset += 2;
2828
2829         return offset;
2830 }
2831
2832
2833 static const true_false_string tfs_mf_file = {
2834         "Target must be a file",
2835         "Target needn't be a file"
2836 };
2837 static const true_false_string tfs_mf_dir = {
2838         "Target must be a directory",
2839         "Target needn't be a directory"
2840 };
2841 static const true_false_string tfs_mf_verify = {
2842         "MUST verify all writes",
2843         "Don't have to verify writes"
2844 };
2845 static int
2846 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2847 {
2848         guint16 mask;
2849         proto_item *item = NULL;
2850         proto_tree *tree = NULL;
2851
2852         mask = tvb_get_letohs(tvb, offset);
2853
2854         if(parent_tree){
2855                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2856                         "Flags: 0x%04x", mask);
2857                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2858         }
2859
2860         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2861                 tvb, offset, 2, mask);
2862         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2863                 tvb, offset, 2, mask);
2864         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2865                 tvb, offset, 2, mask);
2866
2867         offset += 2;
2868
2869         return offset;
2870 }
2871
2872 static const true_false_string tfs_cf_mode = {
2873         "ASCII",
2874         "Binary"
2875 };
2876 static const true_false_string tfs_cf_tree_copy = {
2877         "Copy is a tree copy",
2878         "Copy is a file copy"
2879 };
2880 static const true_false_string tfs_cf_ea_action = {
2881         "Fail copy",
2882         "Discard EAs"
2883 };
2884 static int
2885 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2886 {
2887         guint16 mask;
2888         proto_item *item = NULL;
2889         proto_tree *tree = NULL;
2890
2891         mask = tvb_get_letohs(tvb, offset);
2892
2893         if(parent_tree){
2894                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2895                         "Flags: 0x%04x", mask);
2896                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2897         }
2898
2899         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2900                 tvb, offset, 2, mask);
2901         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2902                 tvb, offset, 2, mask);
2903         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2904                 tvb, offset, 2, mask);
2905         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2906                 tvb, offset, 2, mask);
2907         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2908                 tvb, offset, 2, mask);
2909         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2910                 tvb, offset, 2, mask);
2911         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2912                 tvb, offset, 2, mask);
2913
2914         offset += 2;
2915
2916         return offset;
2917 }
2918
2919 static int
2920 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2921 {
2922         smb_info_t *si = pinfo->private_data;
2923         int fn_len;
2924         guint16 tid;
2925         guint16 bc;
2926         guint8 wc;
2927         const char *fn;
2928
2929         DISSECTOR_ASSERT(si);
2930
2931         WORD_COUNT;
2932
2933         /* tid */
2934         tid = tvb_get_letohs(tvb, offset);
2935         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
2936
2937         /* open function */
2938         offset = dissect_open_function(tvb, tree, offset);
2939
2940         /* move flags */
2941         offset = dissect_move_flags(tvb, tree, offset);
2942
2943         BYTE_COUNT;
2944
2945         /* buffer format */
2946         CHECK_BYTE_COUNT(1);
2947         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2948         COUNT_BYTES(1);
2949
2950         /* file name */
2951         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2952                 FALSE, FALSE, &bc);
2953         if (fn == NULL)
2954                 goto endofcommand;
2955         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2956                 fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
2957         COUNT_BYTES(fn_len);
2958
2959         if (check_col(pinfo->cinfo, COL_INFO)) {
2960                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
2961                     format_text(fn, strlen(fn)));
2962         }
2963
2964         /* buffer format */
2965         CHECK_BYTE_COUNT(1);
2966         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2967         COUNT_BYTES(1);
2968
2969         /* file name */
2970         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2971                 FALSE, FALSE, &bc);
2972         if (fn == NULL)
2973                 goto endofcommand;
2974         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2975                 fn_len, fn, "New File Name: %s", format_text(fn, strlen(fn)));
2976         COUNT_BYTES(fn_len);
2977
2978         if (check_col(pinfo->cinfo, COL_INFO)) {
2979                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
2980                     format_text(fn, strlen(fn)));
2981         }
2982
2983         END_OF_SMB
2984
2985         return offset;
2986 }
2987
2988 static int
2989 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2990 {
2991         smb_info_t *si = pinfo->private_data;
2992         int fn_len;
2993         guint16 tid;
2994         guint16 bc;
2995         guint8 wc;
2996         const char *fn;
2997
2998         DISSECTOR_ASSERT(si);
2999
3000         WORD_COUNT;
3001
3002         /* tid */
3003         tid = tvb_get_letohs(tvb, offset);
3004         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
3005
3006         /* open function */
3007         offset = dissect_open_function(tvb, tree, offset);
3008
3009         /* copy flags */
3010         offset = dissect_copy_flags(tvb, tree, offset);
3011
3012         BYTE_COUNT;
3013
3014         /* buffer format */
3015         CHECK_BYTE_COUNT(1);
3016         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3017         COUNT_BYTES(1);
3018
3019         /* file name */
3020         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3021                 FALSE, FALSE, &bc);
3022         if (fn == NULL)
3023                 goto endofcommand;
3024         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3025                 fn_len, fn, "Source File Name: %s", format_text(fn, strlen(fn)));
3026         COUNT_BYTES(fn_len);
3027
3028         if (check_col(pinfo->cinfo, COL_INFO)) {
3029                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
3030                     format_text(fn, strlen(fn)));
3031         }
3032
3033         /* buffer format */
3034         CHECK_BYTE_COUNT(1);
3035         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3036         COUNT_BYTES(1);
3037
3038         /* file name */
3039         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3040                 FALSE, FALSE, &bc);
3041         if (fn == NULL)
3042                 goto endofcommand;
3043         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3044                 fn_len, fn, "Destination File Name: %s",
3045                 format_text(fn, strlen(fn)));
3046         COUNT_BYTES(fn_len);
3047
3048         if (check_col(pinfo->cinfo, COL_INFO)) {
3049                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(fn, strlen(fn)));
3050         }
3051
3052         END_OF_SMB
3053
3054         return offset;
3055 }
3056
3057 static int
3058 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3059 {
3060         smb_info_t *si = pinfo->private_data;
3061         int fn_len;
3062         const char *fn;
3063         guint8 wc;
3064         guint16 bc;
3065
3066         DISSECTOR_ASSERT(si);
3067
3068         WORD_COUNT;
3069
3070         /* # of files moved */
3071         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
3072         offset += 2;
3073
3074         BYTE_COUNT;
3075
3076         /* buffer format */
3077         CHECK_BYTE_COUNT(1);
3078         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3079         COUNT_BYTES(1);
3080
3081         /* file name */
3082         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3083                 FALSE, FALSE, &bc);
3084         if (fn == NULL)
3085                 goto endofcommand;
3086         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3087                 fn);
3088         COUNT_BYTES(fn_len);
3089
3090         END_OF_SMB
3091
3092         return offset;
3093 }
3094
3095 static int
3096 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3097 {
3098         smb_info_t *si = pinfo->private_data;
3099         int fn_len;
3100         const char *fn;
3101         guint8 wc;
3102         guint16 bc;
3103
3104         DISSECTOR_ASSERT(si);
3105
3106         WORD_COUNT;
3107
3108         /* desired access */
3109         offset = dissect_access(tvb, tree, offset, "Desired");
3110
3111         /* Search Attributes */
3112         offset = dissect_search_attributes(tvb, tree, offset);
3113
3114         BYTE_COUNT;
3115
3116         /* buffer format */
3117         CHECK_BYTE_COUNT(1);
3118         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3119         COUNT_BYTES(1);
3120
3121         /* file name */
3122         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3123                 FALSE, FALSE, &bc);
3124         if (fn == NULL)
3125                 goto endofcommand;
3126         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3127                 fn);
3128         COUNT_BYTES(fn_len);
3129
3130         if (check_col(pinfo->cinfo, COL_INFO)) {
3131                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3132                     format_text(fn, strlen(fn)));
3133         }
3134
3135         END_OF_SMB
3136
3137         return offset;
3138 }
3139
3140
3141
3142 static int
3143 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
3144     int len, guint32 mask)
3145 {
3146         proto_item *item = NULL;
3147         proto_tree *tree = NULL;
3148
3149         if(parent_tree){
3150                 item = proto_tree_add_uint(parent_tree, hf_smb_create_flags, tvb, offset, len, mask);
3151
3152                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
3153         }
3154
3155         /*
3156          * XXX - it's 0x00000016 in at least one capture, but
3157          * Network Monitor doesn't say what the 0x00000010 bit is.
3158          * Does the Win32 API documentation, or NT Native API book,
3159          * suggest anything?
3160          *
3161          * That is the extended response desired bit ... RJS, from Samba
3162          * Well, maybe. Samba thinks it is, and uses it to encode
3163          * OpLock granted as the high order bit of the Action field
3164          * in the response. However, Windows does not do that. Or at least
3165          * Win2K doesn't.
3166          */
3167         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
3168                                tvb, offset, len, mask);
3169         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
3170                 tvb, offset, len, mask);
3171         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
3172                 tvb, offset, len, mask);
3173         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
3174                 tvb, offset, len, mask);
3175
3176         offset += len;
3177
3178         return offset;
3179 }
3180
3181 /* FIXME: need to call dissect_nt_access_mask() instead */
3182 static int
3183 dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3184     int offset, int len, guint32 mask)
3185 {
3186         proto_item *item;
3187         proto_tree *tree;
3188
3189         if(parent_tree){
3190                 item = proto_tree_add_uint(parent_tree, hf_smb_access_mask, tvb, offset, len, mask);
3191                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
3192
3193                 /*
3194                  * Some of these bits come from
3195                  *
3196                  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3197                  *
3198                  * and others come from the section on ZwOpenFile in "Windows(R)
3199                  * NT(R)/2000 Native API Reference".
3200                  */
3201                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
3202                         tvb, offset, len, mask);
3203                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
3204                         tvb, offset, len, mask);
3205                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
3206                         tvb, offset, len, mask);
3207                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
3208                         tvb, offset, len, mask);
3209                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
3210                         tvb, offset, len, mask);
3211                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
3212                         tvb, offset, len, mask);
3213                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
3214                         tvb, offset, len, mask);
3215                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
3216                         tvb, offset, len, mask);
3217                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
3218                         tvb, offset, len, mask);
3219                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
3220                         tvb, offset, len, mask);
3221                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
3222                         tvb, offset, len, mask);
3223                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
3224                         tvb, offset, len, mask);
3225                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
3226                         tvb, offset, len, mask);
3227                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
3228                         tvb, offset, len, mask);
3229                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
3230                         tvb, offset, len, mask);
3231                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
3232                         tvb, offset, len, mask);
3233                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
3234                         tvb, offset, len, mask);
3235                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
3236                         tvb, offset, len, mask);
3237                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
3238                         tvb, offset, len, mask);
3239                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
3240                         tvb, offset, len, mask);
3241         }
3242         offset += len;
3243
3244         return offset;
3245 }
3246
3247 int
3248 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3249 {
3250         guint32 mask;
3251
3252         mask = tvb_get_letohl(tvb, offset);
3253
3254         offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, 4, mask);
3255
3256         return offset;
3257 }
3258
3259
3260 #define SHARE_ACCESS_DELETE     0x00000004
3261 #define SHARE_ACCESS_WRITE      0x00000002
3262 #define SHARE_ACCESS_READ       0x00000001
3263
3264 static int
3265 dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3266     int offset, int len, guint32 mask)
3267 {
3268         proto_item *item;
3269         proto_tree *tree;
3270
3271         if(parent_tree){
3272                 item = proto_tree_add_uint(parent_tree, hf_smb_share_access, tvb, offset, len, mask);
3273                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
3274
3275                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
3276                         tvb, offset, len, mask);
3277                 if(mask&SHARE_ACCESS_DELETE){
3278                         proto_item_append_text(item, " SHARE_DELETE");
3279                 }
3280
3281                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
3282                         tvb, offset, len, mask);
3283                 if(mask&SHARE_ACCESS_WRITE){
3284                         proto_item_append_text(item, " SHARE_WRITE");
3285                 }
3286
3287                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
3288                         tvb, offset, len, mask);
3289                 if(mask&SHARE_ACCESS_READ){
3290                         proto_item_append_text(item, " SHARE_READ");
3291                 }
3292         }
3293
3294         offset += len;
3295
3296         return offset;
3297 }
3298
3299 int
3300 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3301 {
3302         guint32 mask;
3303
3304         mask = tvb_get_letohl(tvb, offset);
3305
3306         offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, 4, mask);
3307
3308         return offset;
3309 }
3310
3311
3312 static int
3313 dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3314     int offset, int len, guint32 mask)
3315 {
3316         proto_item *item;
3317         proto_tree *tree;
3318
3319         if(parent_tree){
3320                 item = proto_tree_add_uint(parent_tree, hf_smb_create_options, tvb, offset, len, mask);
3321                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
3322
3323                 /*
3324                  * From
3325                  *
3326                  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3327                  */
3328                  proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
3329                         tvb, offset, len, mask);
3330                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
3331                         tvb, offset, len, mask);
3332                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
3333                         tvb, offset, len, mask);
3334                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
3335                         tvb, offset, len, mask);
3336                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
3337                         tvb, offset, len, mask);
3338                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
3339                         tvb, offset, len, mask);
3340                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
3341                         tvb, offset, len, mask);
3342                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
3343                         tvb, offset, len, mask);
3344                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
3345                         tvb, offset, len, mask);
3346                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
3347                         tvb, offset, len, mask);
3348                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
3349                         tvb, offset, len, mask);
3350                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
3351                         tvb, offset, len, mask);
3352                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
3353                         tvb, offset, len, mask);
3354                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
3355                         tvb, offset, len, mask);
3356                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
3357                         tvb, offset, len, mask);
3358                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
3359                         tvb, offset, len, mask);
3360                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
3361                         tvb, offset, len, mask);
3362                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
3363                         tvb, offset, len, mask);
3364                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
3365                         tvb, offset, len, mask);
3366                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
3367                         tvb, offset, len, mask);
3368         }
3369         offset += len;
3370
3371         return offset;
3372 }
3373
3374 int
3375 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3376 {
3377         guint32 mask;
3378
3379         mask = tvb_get_letohl(tvb, offset);
3380
3381         offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, 4, mask);
3382
3383         return offset;
3384 }
3385
3386
3387 /* fids are scoped by tcp session */
3388 smb_fid_info_t *
3389 dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3390     int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated)
3391 {
3392         smb_info_t *si = pinfo->private_data;
3393         smb_saved_info_t *sip = si->sip;
3394         proto_item *it;
3395         proto_tree *tr;
3396         smb_fid_info_t *fid_info=NULL;
3397
3398         DISSECTOR_ASSERT(si);
3399
3400         it=proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
3401         if(is_generated){
3402                 PROTO_ITEM_SET_GENERATED(it);
3403         }
3404         tr=proto_item_add_subtree(it, ett_smb_fid);
3405         if (check_col(pinfo->cinfo, COL_INFO))
3406                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
3407
3408         if((!pinfo->fd->flags.visited) && is_created){
3409                 fid_info=se_alloc(sizeof(smb_fid_info_t));
3410                 fid_info->opened_in=pinfo->fd->num;
3411                 fid_info->closed_in=0;
3412                 fid_info->type=SMB_FID_TYPE_UNKNOWN;
3413                 if(si->sip && (si->sip->extra_info_type==SMB_EI_FILEDATA)){
3414                         fid_info->fsi=si->sip->extra_info;
3415                 } else {
3416                         fid_info->fsi=NULL;
3417                 }
3418
3419                 se_tree_insert32(si->ct->fid_tree, fid, fid_info);
3420         }
3421
3422         if(!fid_info){
3423                 fid_info=se_tree_lookup32(si->ct->fid_tree, fid);
3424         }
3425         if(!fid_info){
3426                 return NULL;
3427         }
3428
3429         /* Store the fid in the transaction structure and remember if
3430            it was in the request or in the reply we saw it
3431          */
3432         if(sip && (!is_generated) && (!pinfo->fd->flags.visited)) {
3433                 sip->fid=fid;
3434                 if(si->request){
3435                         sip->fid_seen_in_request=TRUE;
3436                 } else {
3437                         sip->fid_seen_in_request=FALSE;
3438                 }
3439         }
3440
3441         if((!pinfo->fd->flags.visited) && is_closed){
3442                 fid_info->closed_in=pinfo->fd->num;
3443         }
3444
3445         if(fid_info->opened_in){
3446                 it=proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
3447                 PROTO_ITEM_SET_GENERATED(it);
3448         }
3449
3450         if(fid_info->closed_in){
3451                 it=proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
3452                 PROTO_ITEM_SET_GENERATED(it);
3453         }
3454
3455
3456         if(fid_info->opened_in){
3457                 if(fid_info->fsi && fid_info->fsi->filename){
3458                         it=proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
3459                         PROTO_ITEM_SET_GENERATED(it);
3460                         proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
3461                         dissect_nt_create_bits(tvb, tr, 0, 0, fid_info->fsi->create_flags);
3462                         dissect_smb_access_mask_bits(tvb, tr, 0, 0, fid_info->fsi->access_mask);
3463                         dissect_file_ext_attr_bits(tvb, tr, 0, 0, fid_info->fsi->file_attributes);
3464                         dissect_nt_share_access_bits(tvb, tr, 0, 0, fid_info->fsi->share_access);
3465                         dissect_nt_create_options_bits(tvb, tr, 0, 0, fid_info->fsi->create_options);
3466                         it=proto_tree_add_uint(tr, hf_smb_nt_create_disposition, tvb, 0, 0, fid_info->fsi->create_disposition);
3467                         PROTO_ITEM_SET_GENERATED(it);
3468                 }
3469         }
3470
3471         return fid_info;
3472 }
3473
3474 static int
3475 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3476 {
3477         guint8 wc;
3478         guint16 bc;
3479         guint16 fid;
3480
3481         WORD_COUNT;
3482
3483         /* fid */
3484         fid = tvb_get_letohs(tvb, offset);
3485         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3486         offset += 2;
3487
3488         /* File Attributes */
3489         offset = dissect_file_attributes(tvb, tree, offset, 2);
3490
3491         /* last write time */
3492         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3493
3494         /* File Size */
3495         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3496         offset += 4;
3497
3498         /* granted access */
3499         offset = dissect_access(tvb, tree, offset, "Granted");
3500
3501         BYTE_COUNT;
3502
3503         END_OF_SMB
3504
3505         return offset;
3506 }
3507
3508 static int
3509 dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3510 {
3511         guint8 wc;
3512         guint16 bc;
3513         guint16 fid;
3514
3515         WORD_COUNT;
3516
3517         /* fid */
3518         fid = tvb_get_letohs(tvb, offset);
3519         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3520         offset += 2;
3521
3522         BYTE_COUNT;
3523
3524         END_OF_SMB
3525
3526         return offset;
3527 }
3528
3529 static int
3530 dissect_close_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3531 {
3532         guint8 wc;
3533         guint16 bc;
3534         guint16 fid;
3535
3536         WORD_COUNT;
3537
3538         /* fid */
3539         fid = tvb_get_letohs(tvb, offset);
3540         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3541         offset += 2;
3542
3543         BYTE_COUNT;
3544
3545         END_OF_SMB
3546
3547         return offset;
3548 }
3549
3550 static int
3551 dissect_open_print_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3552 {
3553         guint8 wc;
3554         guint16 bc;
3555         guint16 fid;
3556
3557         WORD_COUNT;
3558
3559         /* fid */
3560         fid = tvb_get_letohs(tvb, offset);
3561         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3562         offset += 2;
3563
3564         BYTE_COUNT;
3565
3566         END_OF_SMB
3567
3568         return offset;
3569 }
3570
3571 static int
3572 dissect_create_new_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;
3576         guint16 fid;
3577
3578         WORD_COUNT;
3579
3580         /* fid */
3581         fid = tvb_get_letohs(tvb, offset);
3582         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3583         offset += 2;
3584
3585         BYTE_COUNT;
3586
3587         END_OF_SMB
3588
3589         return offset;
3590 }
3591
3592 static int
3593 dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3594 {
3595         guint8 wc;
3596         guint16 bc;
3597         guint16 fid;
3598
3599         WORD_COUNT;
3600
3601         /* fid */
3602         fid = tvb_get_letohs(tvb, offset);
3603         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3604         offset += 2;
3605
3606         BYTE_COUNT;
3607
3608         END_OF_SMB
3609
3610         return offset;
3611 }
3612
3613 static int
3614 dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3615 {
3616         guint8 wc;
3617         guint16 bc;
3618         guint16 fid;
3619
3620         WORD_COUNT;
3621
3622         /* fid */
3623         fid = tvb_get_letohs(tvb, offset);
3624         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3625         offset += 2;
3626
3627         BYTE_COUNT;
3628
3629         END_OF_SMB
3630
3631         return offset;
3632 }
3633
3634 static int
3635 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3636 {
3637         smb_info_t *si = pinfo->private_data;
3638         int fn_len;
3639         const char *fn;
3640         guint8 wc;
3641         guint16 bc;
3642
3643         DISSECTOR_ASSERT(si);
3644
3645         WORD_COUNT;
3646
3647         /* file attributes */
3648         offset = dissect_file_attributes(tvb, tree, offset, 2);
3649
3650         /* creation time */
3651         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3652
3653         BYTE_COUNT;
3654
3655         /* buffer format */
3656         CHECK_BYTE_COUNT(1);
3657         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3658         COUNT_BYTES(1);
3659
3660         /* File Name */
3661         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3662                 FALSE, FALSE, &bc);
3663         if (fn == NULL)
3664                 goto endofcommand;
3665         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3666                 fn);
3667         COUNT_BYTES(fn_len);
3668
3669         if (check_col(pinfo->cinfo, COL_INFO)) {
3670                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3671                     format_text(fn, strlen(fn)));
3672         }
3673
3674         END_OF_SMB
3675
3676         return offset;
3677 }
3678
3679 static int
3680 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3681 {
3682         guint8 wc;
3683         guint16 bc, fid;
3684
3685         WORD_COUNT;
3686
3687         /* fid */
3688         fid = tvb_get_letohs(tvb, offset);
3689         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3690         offset += 2;
3691
3692         /* last write time */
3693         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3694
3695         BYTE_COUNT;
3696
3697         END_OF_SMB
3698
3699         return offset;
3700 }
3701
3702 static int
3703 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3704 {
3705         smb_info_t *si = pinfo->private_data;
3706         int fn_len;
3707         const char *fn;
3708         guint8 wc;
3709         guint16 bc;
3710
3711         DISSECTOR_ASSERT(si);
3712
3713         WORD_COUNT;
3714
3715         /* search attributes */
3716         offset = dissect_search_attributes(tvb, tree, offset);
3717
3718         BYTE_COUNT;
3719
3720         /* buffer format */
3721         CHECK_BYTE_COUNT(1);
3722         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3723         COUNT_BYTES(1);
3724
3725         /* file name */
3726         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3727                 FALSE, FALSE, &bc);
3728
3729         if(si->sip){
3730                 si->sip->extra_info_type=SMB_EI_FILENAME;
3731                 si->sip->extra_info=se_strdup(fn);
3732         }
3733
3734         if (fn == NULL)
3735                 goto endofcommand;
3736         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3737                 fn);
3738         COUNT_BYTES(fn_len);
3739
3740         if (check_col(pinfo->cinfo, COL_INFO)) {
3741                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3742                     format_text(fn, strlen(fn)));
3743         }
3744
3745         END_OF_SMB
3746
3747         return offset;
3748 }
3749
3750 static int
3751 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3752 {
3753         smb_info_t *si = pinfo->private_data;
3754         int fn_len;
3755         const char *fn, *old_name=NULL, *new_name=NULL;
3756         guint8 wc;
3757         guint16 bc;
3758         smb_rename_saved_info_t *rni=NULL;
3759
3760         DISSECTOR_ASSERT(si);
3761
3762         WORD_COUNT;
3763
3764         /* search attributes */
3765         offset = dissect_search_attributes(tvb, tree, offset);
3766
3767         BYTE_COUNT;
3768
3769         /* buffer format */
3770         CHECK_BYTE_COUNT(1);
3771         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3772         COUNT_BYTES(1);
3773
3774         /* old file name */
3775         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3776                 FALSE, FALSE, &bc);
3777         if (fn == NULL)
3778                 goto endofcommand;
3779         old_name=fn;
3780         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3781                 fn);
3782         COUNT_BYTES(fn_len);
3783
3784         if (check_col(pinfo->cinfo, COL_INFO)) {
3785                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3786                     format_text(fn, strlen(fn)));
3787         }
3788
3789         /* buffer format */
3790         CHECK_BYTE_COUNT(1);
3791         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3792         COUNT_BYTES(1);
3793
3794         /* file name */
3795         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3796                 FALSE, FALSE, &bc);
3797         if (fn == NULL)
3798                 goto endofcommand;
3799         new_name=fn;
3800         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3801                 fn);
3802         COUNT_BYTES(fn_len);
3803
3804         if (check_col(pinfo->cinfo, COL_INFO)) {
3805                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3806                     format_text(fn, strlen(fn)));
3807         }
3808
3809         END_OF_SMB
3810
3811         /* save the offset/len for this transaction */
3812         if(si->sip && !pinfo->fd->flags.visited){
3813                 rni=se_alloc(sizeof(smb_rename_saved_info_t));
3814                 rni->old_name=se_strdup(old_name);
3815                 rni->new_name=se_strdup(new_name);
3816
3817                 si->sip->extra_info_type=SMB_EI_RENAMEDATA;
3818                 si->sip->extra_info=rni;
3819         }
3820
3821         return offset;
3822 }
3823
3824 static int
3825 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3826 {
3827         smb_info_t *si = pinfo->private_data;
3828         int fn_len;
3829         const char *fn;
3830         guint8 wc;
3831         guint16 bc;
3832
3833         DISSECTOR_ASSERT(si);
3834
3835         WORD_COUNT;
3836
3837         /* search attributes */
3838         offset = dissect_search_attributes(tvb, tree, offset);
3839
3840         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3841         offset += 2;
3842
3843         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3844         offset += 4;
3845
3846         BYTE_COUNT;
3847
3848         /* buffer format */
3849         CHECK_BYTE_COUNT(1);
3850         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3851         COUNT_BYTES(1);
3852
3853         /* old file name */
3854         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3855                 FALSE, FALSE, &bc);
3856         if (fn == NULL)
3857                 goto endofcommand;
3858         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3859                 fn);
3860         COUNT_BYTES(fn_len);
3861
3862         if (check_col(pinfo->cinfo, COL_INFO)) {
3863                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3864                     format_text(fn, strlen(fn)));
3865         }
3866
3867         /* buffer format */
3868         CHECK_BYTE_COUNT(1);
3869         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3870         COUNT_BYTES(1);
3871
3872         /* file name */
3873         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3874                 FALSE, FALSE, &bc);
3875         if (fn == NULL)
3876                 goto endofcommand;
3877         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3878                 fn);
3879         COUNT_BYTES(fn_len);
3880
3881         if (check_col(pinfo->cinfo, COL_INFO)) {
3882                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3883                     format_text(fn, strlen(fn)));
3884         }
3885
3886         END_OF_SMB
3887
3888         return offset;
3889 }
3890
3891
3892 static int
3893 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3894 {
3895         smb_info_t *si = pinfo->private_data;
3896         guint16 bc;
3897         guint8 wc;
3898         const char *fn;
3899         int fn_len;
3900
3901         DISSECTOR_ASSERT(si);
3902
3903         WORD_COUNT;
3904
3905         BYTE_COUNT;
3906
3907         /* Buffer Format */
3908         CHECK_BYTE_COUNT(1);
3909         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3910         COUNT_BYTES(1);
3911
3912         /* File Name */
3913         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3914                 FALSE, FALSE, &bc);
3915         if (fn == NULL)
3916                 goto endofcommand;
3917         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3918                 fn);
3919         COUNT_BYTES(fn_len);
3920
3921         if (check_col(pinfo->cinfo, COL_INFO)) {
3922                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3923                     format_text(fn, strlen(fn)));
3924         }
3925
3926         END_OF_SMB
3927
3928         return offset;
3929 }
3930
3931 static int
3932 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3933 {
3934         guint16 bc;
3935         guint8 wc;
3936
3937         WORD_COUNT;
3938
3939         /* File Attributes */
3940         offset = dissect_file_attributes(tvb, tree, offset, 2);
3941
3942         /* Last Write Time */
3943         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3944
3945         /* File Size */
3946         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3947         offset += 4;
3948
3949         /* 10 reserved bytes */
3950         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3951         offset += 10;
3952
3953         BYTE_COUNT;
3954
3955         END_OF_SMB
3956
3957         return offset;
3958 }
3959
3960 static int
3961 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3962 {
3963         smb_info_t *si = pinfo->private_data;
3964         int fn_len;
3965         const char *fn;
3966         guint8 wc;
3967         guint16 bc;
3968
3969         DISSECTOR_ASSERT(si);
3970
3971         WORD_COUNT;
3972
3973         /* file attributes */
3974         offset = dissect_file_attributes(tvb, tree, offset, 2);
3975
3976         /* last write time */
3977         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3978
3979         /* 10 reserved bytes */
3980         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3981         offset += 10;
3982
3983         BYTE_COUNT;
3984
3985         /* buffer format */
3986         CHECK_BYTE_COUNT(1);
3987         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3988         COUNT_BYTES(1);
3989
3990         /* file name */
3991         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3992                 FALSE, FALSE, &bc);
3993         if (fn == NULL)
3994                 goto endofcommand;
3995         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3996                 fn);
3997         COUNT_BYTES(fn_len);
3998
3999         if (check_col(pinfo->cinfo, COL_INFO)) {
4000                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4001                     format_text(fn, strlen(fn)));
4002         }
4003
4004         END_OF_SMB
4005
4006         return offset;
4007 }
4008
4009 static int
4010 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4011 {
4012         guint8 wc;
4013         guint16 cnt=0, bc;
4014         guint32 ofs=0;
4015         unsigned int fid;
4016
4017         WORD_COUNT;
4018
4019         /* fid */
4020         fid = tvb_get_letohs(tvb, offset);
4021         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
4022         offset += 2;
4023
4024         /* read count */
4025         cnt = tvb_get_letohs(tvb, offset);
4026         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4027         offset += 2;
4028
4029         /* offset */
4030         ofs = tvb_get_letohl(tvb, offset);
4031         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4032         offset += 4;
4033
4034         if (check_col(pinfo->cinfo, COL_INFO))
4035                 col_append_fstr(pinfo->cinfo, COL_INFO,
4036                                 ", %u byte%s at offset %u", cnt,
4037                                 (cnt == 1) ? "" : "s", ofs);
4038
4039         /* remaining */
4040         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4041         offset += 2;
4042
4043         BYTE_COUNT;
4044
4045         END_OF_SMB
4046
4047         return offset;
4048 }
4049
4050 int
4051 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
4052 {
4053         int tvblen;
4054
4055         if(bc>datalen){
4056                 /* We have some initial padding bytes. */
4057                 /* XXX - use the data offset here instead? */
4058                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4059                         TRUE);
4060                 offset += bc-datalen;
4061                 bc = datalen;
4062         }
4063         tvblen = tvb_length_remaining(tvb, offset);
4064         if(bc>tvblen){
4065                 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);
4066                 offset += tvblen;
4067         } else {
4068                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
4069                 offset += bc;
4070         }
4071         return offset;
4072 }
4073
4074 static int
4075 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4076     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
4077 {
4078         int tvblen;
4079         tvbuff_t *dcerpc_tvb;
4080
4081         if(bc>datalen){
4082                 /* We have some initial padding bytes. */
4083                 /* XXX - use the data offset here instead? */
4084                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4085                         TRUE);
4086                 offset += bc-datalen;
4087                 bc = datalen;
4088         }
4089         tvblen = tvb_length_remaining(tvb, offset);
4090         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
4091         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
4092         if(bc>tvblen)
4093                 offset += tvblen;
4094         else
4095                 offset += bc;
4096         return offset;
4097 }
4098
4099 /*
4100  * transporting DCERPC over SMB seems to be implemented in various
4101  * ways. We might just assume it can be done by an almost random
4102  * mix of Trans/Read/Write calls
4103  *
4104  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
4105  * and let him sort them out
4106  */
4107 static int
4108 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
4109     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
4110     guint16 datalen, guint32 ofs, guint16 fid)
4111 {
4112         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4113
4114         DISSECTOR_ASSERT(si);
4115
4116         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
4117                 /* dcerpc call */
4118                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
4119                     top_tree, offset, bc, datalen, fid);
4120         } else {
4121                 /* ordinary file data */
4122                 return dissect_file_data(tvb, tree, offset, bc, datalen);
4123         }
4124 }
4125
4126 static int
4127 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4128 {
4129         guint16 cnt=0, bc;
4130         guint8 wc;
4131         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4132         int fid=0;
4133
4134         DISSECTOR_ASSERT(si);
4135
4136         WORD_COUNT;
4137
4138         /* read count */
4139         cnt = tvb_get_letohs(tvb, offset);
4140         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4141         offset += 2;
4142
4143         /* 8 reserved bytes */
4144         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4145         offset += 8;
4146         BYTE_COUNT;
4147
4148         /* buffer format */
4149         CHECK_BYTE_COUNT(1);
4150         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4151         COUNT_BYTES(1);
4152
4153         /* data len */
4154         CHECK_BYTE_COUNT(2);
4155         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4156         COUNT_BYTES(2);
4157
4158         /* file data, might be DCERPC on a pipe */
4159         if(bc){
4160                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4161                     top_tree, offset, bc, bc, 0, (guint16) fid);
4162                 bc = 0;
4163         }
4164
4165         END_OF_SMB
4166
4167         return offset;
4168 }
4169
4170 static int
4171 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4172 {
4173         guint16 cnt, bc;
4174         guint8 wc;
4175
4176         WORD_COUNT;
4177
4178         /* read count */
4179         cnt = tvb_get_letohs(tvb, offset);
4180         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4181         offset += 2;
4182
4183         /* 8 reserved bytes */
4184         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4185         offset += 8;
4186
4187         BYTE_COUNT;
4188
4189         /* buffer format */
4190         CHECK_BYTE_COUNT(1);
4191         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4192         COUNT_BYTES(1);
4193
4194         /* data len */
4195         CHECK_BYTE_COUNT(2);
4196         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4197         COUNT_BYTES(2);
4198
4199         END_OF_SMB
4200
4201         return offset;
4202 }
4203
4204 typedef struct _rw_info_t {
4205         guint32 offset;
4206         guint32 len;
4207         guint16 fid;
4208 } rw_info_t;
4209
4210
4211 static int
4212 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4213 {
4214         guint32 ofs=0;
4215         guint16 cnt=0, bc, fid=0;
4216         guint8 wc;
4217         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4218         rw_info_t *rwi=NULL;
4219
4220         DISSECTOR_ASSERT(si);
4221
4222         WORD_COUNT;
4223
4224         /* fid */
4225         fid = tvb_get_letohs(tvb, offset);
4226         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4227         offset += 2;
4228
4229         /* write count */
4230         cnt = tvb_get_letohs(tvb, offset);
4231         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4232         offset += 2;
4233
4234         /* offset */
4235         ofs = tvb_get_letohl(tvb, offset);
4236         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4237         offset += 4;
4238
4239         if (check_col(pinfo->cinfo, COL_INFO))
4240                 col_append_fstr(pinfo->cinfo, COL_INFO,
4241                                 ", %u byte%s at offset %u", cnt,
4242                                 (cnt == 1) ? "" : "s", ofs);
4243
4244         /* save the offset/len for this transaction */
4245         if(si->sip && !pinfo->fd->flags.visited){
4246                 rwi=se_alloc(sizeof(rw_info_t));
4247                 rwi->offset=ofs;
4248                 rwi->len=cnt;
4249                 rwi->fid=fid;
4250
4251                 si->sip->extra_info_type=SMB_EI_RWINFO;
4252                 si->sip->extra_info=rwi;
4253         }
4254         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
4255                 rwi=si->sip->extra_info;
4256         }
4257         if(rwi){
4258                 proto_item *it;
4259
4260                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4261
4262                 PROTO_ITEM_SET_GENERATED(it);
4263                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4264                 PROTO_ITEM_SET_GENERATED(it);
4265         }
4266
4267         /* remaining */
4268         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4269         offset += 2;
4270
4271         BYTE_COUNT;
4272
4273         /* buffer format */
4274         CHECK_BYTE_COUNT(1);
4275         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4276         COUNT_BYTES(1);
4277
4278         /* data len */
4279         CHECK_BYTE_COUNT(2);
4280         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4281         COUNT_BYTES(2);
4282
4283         /* file data, might be DCERPC on a pipe */
4284         if (bc != 0) {
4285                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4286                     top_tree, offset, bc, bc, ofs, fid);
4287                 bc = 0;
4288         }
4289
4290         END_OF_SMB
4291
4292         return offset;
4293 }
4294
4295 static int
4296 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4297 {
4298         guint8 wc;
4299         guint16 bc, cnt;
4300         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4301         rw_info_t *rwi=NULL;
4302
4303         DISSECTOR_ASSERT(si);
4304
4305         WORD_COUNT;
4306
4307         /* write count */
4308         cnt = tvb_get_letohs(tvb, offset);
4309         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4310         offset += 2;
4311
4312         if (check_col(pinfo->cinfo, COL_INFO))
4313                 col_append_fstr(pinfo->cinfo, COL_INFO,
4314                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
4315
4316         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
4317                 rwi=si->sip->extra_info;
4318         }
4319         if(rwi){
4320                 proto_item *it;
4321
4322                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4323
4324                 PROTO_ITEM_SET_GENERATED(it);
4325                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4326                 PROTO_ITEM_SET_GENERATED(it);
4327         }
4328
4329         BYTE_COUNT;
4330
4331         END_OF_SMB
4332
4333         return offset;
4334 }
4335
4336 static int
4337 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4338 {
4339         guint8 wc;
4340         guint16 bc, fid;
4341
4342         WORD_COUNT;
4343
4344         /* fid */
4345         fid = tvb_get_letohs(tvb, offset);
4346         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4347         offset += 2;
4348
4349         /* lock count */
4350         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
4351         offset += 4;
4352
4353         /* offset */
4354         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4355         offset += 4;
4356
4357         BYTE_COUNT;
4358
4359         END_OF_SMB
4360
4361         return offset;
4362 }
4363
4364 static int
4365 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4366 {
4367         smb_info_t *si = pinfo->private_data;
4368         int fn_len;
4369         const char *fn;
4370         guint8 wc;
4371         guint16 bc;
4372
4373         DISSECTOR_ASSERT(si);
4374
4375         WORD_COUNT;
4376
4377         /* 2 reserved bytes */
4378         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4379         offset += 2;
4380
4381         /* Creation time */
4382         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4383
4384         BYTE_COUNT;
4385
4386         /* buffer format */
4387         CHECK_BYTE_COUNT(1);
4388         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4389         COUNT_BYTES(1);
4390
4391         /* directory name */
4392         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4393                 FALSE, FALSE, &bc);
4394         if (fn == NULL)
4395                 goto endofcommand;
4396         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
4397                 fn);
4398         COUNT_BYTES(fn_len);
4399
4400         if (check_col(pinfo->cinfo, COL_INFO)) {
4401                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4402                     format_text(fn, strlen(fn)));
4403         }
4404
4405         END_OF_SMB
4406
4407         return offset;
4408 }
4409
4410 static int
4411 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4412 {
4413         smb_info_t *si = pinfo->private_data;
4414         int fn_len;
4415         const char *fn;
4416         guint8 wc;
4417         guint16 bc, fid;
4418
4419         DISSECTOR_ASSERT(si);
4420
4421         WORD_COUNT;
4422
4423         /* fid */
4424         fid = tvb_get_letohs(tvb, offset);
4425         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
4426         offset += 2;
4427
4428         BYTE_COUNT;
4429
4430         /* buffer format */
4431         CHECK_BYTE_COUNT(1);
4432         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4433         COUNT_BYTES(1);
4434
4435         /* file name */
4436         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4437                 FALSE, FALSE, &bc);
4438         if (fn == NULL)
4439                 goto endofcommand;
4440         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4441                 fn);
4442         COUNT_BYTES(fn_len);
4443
4444         END_OF_SMB
4445
4446         return offset;
4447 }
4448
4449 static const value_string seek_mode_vals[] = {
4450         {0,     "From Start Of File"},
4451         {1,     "From Current Position"},
4452         {2,     "From End Of File"},
4453         {0,     NULL}
4454 };
4455
4456 static int
4457 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4458 {
4459         guint8 wc;
4460         guint16 bc, fid;
4461
4462         WORD_COUNT;
4463
4464         /* fid */
4465         fid = tvb_get_letohs(tvb, offset);
4466         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4467         offset += 2;
4468
4469         /* Seek Mode */
4470         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
4471         offset += 2;
4472
4473         /* offset */
4474         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4475         offset += 4;
4476
4477         BYTE_COUNT;
4478
4479         END_OF_SMB
4480
4481         return offset;
4482 }
4483
4484 static int
4485 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4486 {
4487         guint8 wc;
4488         guint16 bc;
4489
4490         WORD_COUNT;
4491
4492         /* offset */
4493         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4494         offset += 4;
4495
4496         BYTE_COUNT;
4497
4498         END_OF_SMB
4499
4500         return offset;
4501 }
4502
4503 static int
4504 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4505 {
4506         guint8 wc;
4507         guint16 bc, fid;
4508
4509         WORD_COUNT;
4510
4511         /* fid */
4512         fid = tvb_get_letohs(tvb, offset);
4513         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4514         offset += 2;
4515
4516         /* create time */
4517         offset = dissect_smb_datetime(tvb, tree, offset,
4518                 hf_smb_create_time,
4519                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4520
4521         /* access time */
4522         offset = dissect_smb_datetime(tvb, tree, offset,
4523                 hf_smb_access_time,
4524                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4525
4526         /* last write time */
4527         offset = dissect_smb_datetime(tvb, tree, offset,
4528                 hf_smb_last_write_time,
4529                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4530
4531         BYTE_COUNT;
4532
4533         END_OF_SMB
4534
4535         return offset;
4536 }
4537
4538 static int
4539 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4540 {
4541         guint8 wc;
4542         guint16 bc;
4543
4544         WORD_COUNT;
4545
4546         /* create time */
4547         offset = dissect_smb_datetime(tvb, tree, offset,
4548                 hf_smb_create_time,
4549                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4550
4551         /* access time */
4552         offset = dissect_smb_datetime(tvb, tree, offset,
4553                 hf_smb_access_time,
4554                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4555
4556         /* last write time */
4557         offset = dissect_smb_datetime(tvb, tree, offset,
4558                 hf_smb_last_write_time,
4559                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4560
4561         /* data size */
4562         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
4563         offset += 4;
4564
4565         /* allocation size */
4566         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4567         offset += 4;
4568
4569         /* File Attributes */
4570         offset = dissect_file_attributes(tvb, tree, offset, 2);
4571
4572         BYTE_COUNT;
4573
4574         END_OF_SMB
4575
4576         return offset;
4577 }
4578
4579 static int
4580 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4581 {
4582         guint8 wc;
4583         guint16 cnt=0;
4584         guint16 bc, fid;
4585
4586         WORD_COUNT;
4587
4588         /* fid */
4589         fid = tvb_get_letohs(tvb, offset);
4590         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
4591         offset += 2;
4592
4593         /* write count */
4594         cnt = tvb_get_letohs(tvb, offset);
4595         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4596         offset += 2;
4597
4598         /* offset */
4599         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4600         offset += 4;
4601
4602         /* last write time */
4603         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4604
4605         if(wc==12){
4606                 /* 12 reserved bytes */
4607                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
4608                 offset += 12;
4609         }
4610
4611         BYTE_COUNT;
4612
4613         /* 1 pad byte */
4614         CHECK_BYTE_COUNT(1);
4615         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
4616         COUNT_BYTES(1);
4617
4618         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
4619         bc = 0; /* XXX */
4620
4621         END_OF_SMB
4622
4623         return offset;
4624 }
4625
4626 static int
4627 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4628 {
4629         guint8 wc;
4630         guint16 bc;
4631
4632         WORD_COUNT;
4633
4634         /* write count */
4635         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4636         offset += 2;
4637
4638         BYTE_COUNT;
4639
4640         END_OF_SMB
4641
4642         return offset;
4643 }
4644
4645 /* Timeout is defined on page 117 of SMB Protocol Extensions version 2.0
4646    available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
4647 */
4648 static gchar *
4649 smbext20_timeout_msecs_to_str(gint32 time)
4650 {
4651         gchar *buf;
4652 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
4653
4654         if (time <= 0) {
4655                 buf=ep_alloc(SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
4656                 if (time == 0) {
4657                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
4658                 } else if (time == -1) {
4659                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
4660                 } else if (time == -2) {
4661                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
4662                 } else {
4663                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", time);
4664                 }
4665                 return buf;
4666         }
4667
4668         return time_msecs_to_str(time);
4669 }
4670
4671 static int
4672 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4673 {
4674         guint8 wc;
4675         guint16 bc, fid;
4676         guint32 to;
4677
4678         WORD_COUNT;
4679
4680         /* fid */
4681         fid = tvb_get_letohs(tvb, offset);
4682         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4683         offset += 2;
4684
4685         /* offset */
4686         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4687         offset += 4;
4688
4689         /* max count */
4690         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4691         offset += 2;
4692
4693         /* min count */
4694         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4695         offset += 2;
4696
4697         /* timeout */
4698         to = tvb_get_letohl(tvb, offset);
4699         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4700         offset += 4;
4701
4702         /* 2 reserved bytes */
4703         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4704         offset += 2;
4705
4706         if(wc==10){
4707                 /* high offset */
4708                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4709                 offset += 4;
4710         }
4711
4712         BYTE_COUNT;
4713
4714         END_OF_SMB
4715
4716         return offset;
4717 }
4718
4719 static int
4720 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4721 {
4722         guint8 wc;
4723         guint16 bc;
4724
4725         WORD_COUNT;
4726
4727         /* units */
4728         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
4729         offset += 2;
4730
4731         /* bpu */
4732         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
4733         offset += 2;
4734
4735         /* block size */
4736         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
4737         offset += 2;
4738
4739         /* free units */
4740         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
4741         offset += 2;
4742
4743         /* 2 reserved bytes */
4744         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4745         offset += 2;
4746
4747         BYTE_COUNT;
4748
4749         END_OF_SMB
4750
4751         return offset;
4752 }
4753
4754 static int
4755 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4756 {
4757         guint8 wc;
4758         guint16 bc, fid;
4759
4760         WORD_COUNT;
4761
4762         /* fid */
4763         fid = tvb_get_letohs(tvb, offset);
4764         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4765         offset += 2;
4766
4767         /* offset */
4768         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4769         offset += 4;
4770
4771         /* max count */
4772         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4773         offset += 2;
4774
4775         /* min count */
4776         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4777         offset += 2;
4778
4779         /* 6 reserved bytes */
4780         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4781         offset += 6;
4782
4783         BYTE_COUNT;
4784
4785         END_OF_SMB
4786
4787         return offset;
4788 }
4789
4790 static int
4791 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4792 {
4793         guint16 datalen=0, bc;
4794         guint8 wc;
4795
4796         WORD_COUNT;
4797
4798         /* offset */
4799         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4800         offset += 4;
4801
4802         /* count */
4803         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4804         offset += 2;
4805
4806         /* 2 reserved bytes */
4807         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4808         offset += 2;
4809
4810         /* data compaction mode */
4811         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4812         offset += 2;
4813
4814         /* 2 reserved bytes */
4815         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4816         offset += 2;
4817
4818         /* data len */
4819         datalen = tvb_get_letohs(tvb, offset);
4820         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4821         offset += 2;
4822
4823         /* data offset */
4824         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4825         offset += 2;
4826
4827         BYTE_COUNT;
4828
4829         /* file data */
4830         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4831         bc = 0;
4832
4833         END_OF_SMB
4834
4835         return offset;
4836 }
4837
4838
4839 static const true_false_string tfs_write_mode_write_through = {
4840         "WRITE THROUGH requested",
4841         "Write through not requested"
4842 };
4843 static const true_false_string tfs_write_mode_return_remaining = {
4844         "RETURN REMAINING (pipe/dev) requested",
4845         "DON'T return remaining (pipe/dev)"
4846 };
4847 static const true_false_string tfs_write_mode_raw = {
4848         "Use WriteRawNamedPipe (pipe)",
4849         "DON'T use WriteRawNamedPipe (pipe)"
4850 };
4851 static const true_false_string tfs_write_mode_message_start = {
4852         "This is the START of a MESSAGE (pipe)",
4853         "This is NOT the start of a message (pipe)"
4854 };
4855 static const true_false_string tfs_write_mode_connectionless = {
4856         "CONNECTIONLESS mode requested",
4857         "Connectionless mode NOT requested"
4858 };
4859
4860 #define WRITE_MODE_CONNECTIONLESS       0x0080
4861 #define WRITE_MODE_MESSAGE_START        0x0008
4862 #define WRITE_MODE_RAW                  0x0004
4863 #define WRITE_MODE_RETURN_REMAINING     0x0002
4864 #define WRITE_MODE_WRITE_THROUGH        0x0001
4865
4866 static int
4867 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4868 {
4869         guint16 mask;
4870         proto_item *item;
4871         proto_tree *tree;
4872
4873         mask = tvb_get_letohs(tvb, offset);
4874
4875         if(parent_tree){
4876                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4877                         "Write Mode: 0x%04x", mask);
4878                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4879
4880                 if(bm&WRITE_MODE_CONNECTIONLESS){
4881                         proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4882                                 tvb, offset, 2, mask);
4883                 }
4884                 if(bm&WRITE_MODE_MESSAGE_START){
4885                         proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4886                                 tvb, offset, 2, mask);
4887                                 }
4888                 if(bm&WRITE_MODE_RAW){
4889                         proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4890                                 tvb, offset, 2, mask);
4891                 }
4892                 if(bm&WRITE_MODE_RETURN_REMAINING){
4893                         proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4894                                 tvb, offset, 2, mask);
4895                 }
4896                 if(bm&WRITE_MODE_WRITE_THROUGH){
4897                         proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4898                                 tvb, offset, 2, mask);
4899                 }
4900         }
4901
4902         offset += 2;
4903         return offset;
4904 }
4905
4906 static int
4907 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4908 {
4909         guint32 to;
4910         guint16 datalen=0, bc, fid;
4911         guint8 wc;
4912
4913         WORD_COUNT;
4914
4915         /* fid */
4916         fid = tvb_get_letohs(tvb, offset);
4917         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4918         offset += 2;
4919
4920         /* total data length */
4921         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4922         offset += 2;
4923
4924         /* 2 reserved bytes */
4925         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4926         offset += 2;
4927
4928         /* offset */
4929         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4930         offset += 4;
4931
4932         /* timeout */
4933         to = tvb_get_letohl(tvb, offset);
4934         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4935         offset += 4;
4936
4937         /* mode */
4938         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4939
4940         /* 4 reserved bytes */
4941         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4942         offset += 4;
4943
4944         /* data len */
4945         datalen = tvb_get_letohs(tvb, offset);
4946         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4947         offset += 2;
4948
4949         /* data offset */
4950         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4951         offset += 2;
4952
4953         BYTE_COUNT;
4954
4955         /* file data */
4956         /* XXX - use the data offset to determine where the data starts? */
4957         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4958         bc = 0;
4959
4960         END_OF_SMB
4961
4962         return offset;
4963 }
4964
4965 static int
4966 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4967 {
4968         guint8 wc;
4969         guint16 bc;
4970
4971         WORD_COUNT;
4972
4973         /* remaining */
4974         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4975         offset += 2;
4976
4977         BYTE_COUNT;
4978
4979         END_OF_SMB
4980
4981         return offset;
4982 }
4983
4984 static int
4985 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4986 {
4987         guint32 to;
4988         guint16 datalen=0, bc, fid;
4989         guint8 wc;
4990
4991         WORD_COUNT;
4992
4993         /* fid */
4994         fid = tvb_get_letohs(tvb, offset);
4995         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4996         offset += 2;
4997
4998         /* total data length */
4999         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
5000         offset += 2;
5001
5002         /* 2 reserved bytes */
5003         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5004         offset += 2;
5005
5006         /* offset */
5007         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5008         offset += 4;
5009
5010         /* timeout */
5011         to = tvb_get_letohl(tvb, offset);
5012         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5013         offset += 4;
5014
5015         /* mode */
5016         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
5017
5018         /* request mask */
5019         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
5020         offset += 4;
5021
5022         /* data len */
5023         datalen = tvb_get_letohs(tvb, offset);
5024         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5025         offset += 2;
5026
5027         /* data offset */
5028         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
5029         offset += 2;
5030
5031         BYTE_COUNT;
5032
5033         /* file data */
5034         /* XXX - use the data offset to determine where the data starts? */
5035         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5036         bc = 0;
5037
5038         END_OF_SMB
5039
5040         return offset;
5041 }
5042
5043 static int
5044 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5045 {
5046         guint8 wc;
5047         guint16 bc;
5048
5049         WORD_COUNT;
5050
5051         /* response mask */
5052         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
5053         offset += 4;
5054
5055         BYTE_COUNT;
5056
5057         END_OF_SMB
5058
5059         return offset;
5060 }
5061
5062 static int
5063 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5064 {
5065         guint8 wc;
5066         guint16 bc;
5067
5068         WORD_COUNT;
5069
5070         /* sid */
5071         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
5072         offset += 2;
5073
5074         BYTE_COUNT;
5075
5076         END_OF_SMB
5077
5078         return offset;
5079 }
5080
5081 static int
5082 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
5083     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5084     gboolean has_find_id)
5085 {
5086         proto_item *item = NULL;
5087         proto_tree *tree = NULL;
5088         smb_info_t *si = pinfo->private_data;
5089         int fn_len;
5090         const char *fn;
5091         char fname[11+1];
5092
5093         DISSECTOR_ASSERT(si);
5094
5095         if(parent_tree){
5096                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
5097                         "Resume Key");
5098                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
5099         }
5100
5101         /* reserved byte */
5102         CHECK_BYTE_COUNT_SUBR(1);
5103         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5104         COUNT_BYTES_SUBR(1);
5105
5106         /* file name */
5107         fn_len = 11;
5108         fn = get_unicode_or_ascii_string(tvb, &offset, FALSE/*never Unicode*/, &fn_len,
5109                 TRUE, TRUE, bcp);
5110         CHECK_STRING_SUBR(fn);
5111         /* ensure that it's null-terminated */
5112         g_strlcpy(fname, fn, 11+1);
5113         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
5114                 fname);
5115         COUNT_BYTES_SUBR(fn_len);
5116
5117         if (has_find_id) {
5118                 CHECK_BYTE_COUNT_SUBR(1);
5119                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
5120                 COUNT_BYTES_SUBR(1);
5121
5122                 /* server cookie */
5123                 CHECK_BYTE_COUNT_SUBR(4);
5124                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
5125                 COUNT_BYTES_SUBR(4);
5126         } else {
5127                 /* server cookie */
5128                 CHECK_BYTE_COUNT_SUBR(5);
5129                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
5130                 COUNT_BYTES_SUBR(5);
5131         }
5132
5133         /* client cookie */
5134         CHECK_BYTE_COUNT_SUBR(4);
5135         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
5136         COUNT_BYTES_SUBR(4);
5137
5138         *trunc = FALSE;
5139         return offset;
5140 }
5141
5142 static int
5143 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
5144     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5145     gboolean has_find_id)
5146 {
5147         proto_item *item = NULL;
5148         proto_tree *tree = NULL;
5149         smb_info_t *si = pinfo->private_data;
5150         int fn_len;
5151         const char *fn;
5152         char fname[13+1];
5153
5154         DISSECTOR_ASSERT(si);
5155
5156         if(parent_tree){
5157                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
5158                         "Directory Information");
5159                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
5160         }
5161
5162         /* resume key */
5163         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
5164             trunc, has_find_id);
5165         if (*trunc)
5166                 return offset;
5167
5168         /* File Attributes */
5169         CHECK_BYTE_COUNT_SUBR(1);
5170         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
5171         *bcp -= 1;
5172
5173         /* last write time */
5174         CHECK_BYTE_COUNT_SUBR(4);
5175         offset = dissect_smb_datetime(tvb, tree, offset,
5176                 hf_smb_last_write_time,
5177                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
5178                 TRUE);
5179         *bcp -= 4;
5180
5181         /* File Size */
5182         CHECK_BYTE_COUNT_SUBR(4);
5183         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5184         COUNT_BYTES_SUBR(4);
5185
5186         /* file name */
5187         fn_len = 13;
5188         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5189                 TRUE, TRUE, bcp);
5190         CHECK_STRING_SUBR(fn);
5191         /* ensure that it's null-terminated */
5192         g_strlcpy(fname, fn, 13+1);
5193         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5194                 fname);
5195         COUNT_BYTES_SUBR(fn_len);
5196
5197         *trunc = FALSE;
5198         return offset;
5199 }
5200
5201
5202 static int
5203 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
5204     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5205     gboolean has_find_id)
5206 {
5207         smb_info_t *si = pinfo->private_data;
5208         int fn_len;
5209         const char *fn;
5210         guint16 rkl;
5211         guint8 wc;
5212         guint16 bc;
5213         gboolean trunc;
5214
5215         DISSECTOR_ASSERT(si);
5216
5217         WORD_COUNT;
5218
5219         /* max count */
5220         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5221         offset += 2;
5222
5223         /* Search Attributes */
5224         offset = dissect_search_attributes(tvb, tree, offset);
5225
5226         BYTE_COUNT;
5227
5228         /* buffer format */
5229         CHECK_BYTE_COUNT(1);
5230         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5231         COUNT_BYTES(1);
5232
5233         /* file name */
5234         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5235                 TRUE, FALSE, &bc);
5236         if (fn == NULL)
5237                 goto endofcommand;
5238         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5239                 fn);
5240         COUNT_BYTES(fn_len);
5241
5242         if (check_col(pinfo->cinfo, COL_INFO)) {
5243                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
5244                     format_text(fn, strlen(fn)));
5245         }
5246
5247         /* buffer format */
5248         CHECK_BYTE_COUNT(1);
5249         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5250         COUNT_BYTES(1);
5251
5252         /* resume key length */
5253         CHECK_BYTE_COUNT(2);
5254         rkl = tvb_get_letohs(tvb, offset);
5255         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
5256         COUNT_BYTES(2);
5257
5258         /* resume key */
5259         if(rkl){
5260                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
5261                     &bc, &trunc, has_find_id);
5262                 if (trunc)
5263                         goto endofcommand;
5264         }
5265
5266         END_OF_SMB
5267
5268         return offset;
5269 }
5270
5271 static int
5272 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5273     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5274 {
5275         return dissect_search_find_request(tvb, pinfo, tree, offset,
5276             smb_tree, FALSE);
5277 }
5278
5279 static int
5280 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5281     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5282 {
5283         return dissect_search_find_request(tvb, pinfo, tree, offset,
5284             smb_tree, TRUE);
5285 }
5286
5287 static int
5288 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5289     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5290 {
5291         return dissect_search_find_request(tvb, pinfo, tree, offset,
5292             smb_tree, TRUE);
5293 }
5294
5295 static int
5296 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5297     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5298     gboolean has_find_id)
5299 {
5300         guint16 count=0;
5301         guint8 wc;
5302         guint16 bc;
5303         gboolean trunc;
5304
5305         WORD_COUNT;
5306
5307         /* count */
5308         count = tvb_get_letohs(tvb, offset);
5309         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
5310         offset += 2;
5311
5312         BYTE_COUNT;
5313
5314         /* buffer format */
5315         CHECK_BYTE_COUNT(1);
5316         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5317         COUNT_BYTES(1);
5318
5319         /* data len */
5320         CHECK_BYTE_COUNT(2);
5321         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
5322         COUNT_BYTES(2);
5323
5324         while(count--){
5325                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
5326                     &bc, &trunc, has_find_id);
5327                 if (trunc)
5328                         goto endofcommand;
5329         }
5330
5331         END_OF_SMB
5332
5333         return offset;
5334 }
5335
5336 static int
5337 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5338 {
5339         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5340             FALSE);
5341 }
5342
5343 static int
5344 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5345 {
5346         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5347             TRUE);
5348 }
5349
5350 static int
5351 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5352     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5353 {
5354         guint8 wc;
5355         guint16 bc;
5356         guint16 data_len;
5357
5358         WORD_COUNT;
5359
5360         /* reserved */
5361         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5362         offset += 2;
5363
5364         BYTE_COUNT;
5365
5366         /* buffer format */
5367         CHECK_BYTE_COUNT(1);
5368         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5369         COUNT_BYTES(1);
5370
5371         /* data len */
5372         CHECK_BYTE_COUNT(2);
5373         data_len = tvb_get_ntohs(tvb, offset);
5374         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
5375         COUNT_BYTES(2);
5376
5377         if (data_len != 0) {
5378                 CHECK_BYTE_COUNT(data_len);
5379                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
5380                     data_len, TRUE);
5381                 COUNT_BYTES(data_len);
5382         }
5383
5384         END_OF_SMB
5385
5386         return offset;
5387 }
5388
5389 static const value_string locking_ol_vals[] = {
5390         {0,     "Client is not holding oplock on this file"},
5391         {1,     "Level 2 oplock currently held by client"},
5392         {0, NULL}
5393 };
5394
5395 static const true_false_string tfs_lock_type_large = {
5396         "Large file locking format requested",
5397         "Large file locking format not requested"
5398 };
5399 static const true_false_string tfs_lock_type_cancel = {
5400         "Cancel outstanding lock request",
5401         "Don't cancel outstanding lock request"
5402 };
5403 static const true_false_string tfs_lock_type_change = {
5404         "Change lock type",
5405         "Don't change lock type"
5406 };
5407 static const true_false_string tfs_lock_type_oplock = {
5408         "This is an oplock break notification/response",
5409         "This is not an oplock break notification/response"
5410 };
5411 static const true_false_string tfs_lock_type_shared = {
5412         "This is a shared lock",
5413         "This is an exclusive lock"
5414 };
5415 static int
5416 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5417 {
5418         guint8  wc, cmd=0xff, lt=0, ol=0;
5419         guint16 andxoffset=0, un=0, ln=0, bc, fid, num_lock=0, num_unlock=0;
5420         guint32 to;
5421         proto_item *litem = NULL;
5422         proto_tree *ltree = NULL;
5423         proto_item *it = NULL;
5424         proto_tree *tr = NULL;
5425         int old_offset = offset;
5426         smb_info_t *si = pinfo->private_data;
5427         smb_locking_saved_info_t *ld=NULL;
5428
5429
5430         DISSECTOR_ASSERT(si);
5431
5432         WORD_COUNT;
5433
5434         /* next smb command */
5435         cmd = tvb_get_guint8(tvb, offset);
5436         if(cmd!=0xff){
5437                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5438         } else {
5439                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5440         }
5441         offset += 1;
5442
5443         /* reserved byte */
5444         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5445         offset += 1;
5446
5447         /* andxoffset */
5448         andxoffset = tvb_get_letohs(tvb, offset);
5449         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5450         offset += 2;
5451
5452         /* fid */
5453         fid = tvb_get_letohs(tvb, offset);
5454         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
5455         offset += 2;
5456
5457         /* lock type */
5458         lt = tvb_get_guint8(tvb, offset);
5459         if(tree){
5460                 litem = proto_tree_add_text(tree, tvb, offset, 1,
5461                         "Lock Type: 0x%02x", lt);
5462                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5463
5464                 proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
5465                         tvb, offset, 1, lt);
5466                 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
5467                         tvb, offset, 1, lt);
5468                 proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
5469                         tvb, offset, 1, lt);
5470                 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
5471                         tvb, offset, 1, lt);
5472                 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
5473                         tvb, offset, 1, lt);
5474         }
5475         offset += 1;
5476
5477         /* oplock level */
5478         ol = tvb_get_guint8(tvb, offset);
5479         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
5480         offset += 1;
5481
5482         /* timeout */
5483         to = tvb_get_letohl(tvb, offset);
5484         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5485         offset += 4;
5486
5487         /* number of unlocks */
5488         un = tvb_get_letohs(tvb, offset);
5489         num_unlock=un;
5490         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
5491         offset += 2;
5492
5493         /* number of locks */
5494         ln = tvb_get_letohs(tvb, offset);
5495         num_lock=ln;
5496         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
5497         offset += 2;
5498
5499         BYTE_COUNT;
5500
5501         /* store the locking data for the response */
5502         if((!pinfo->fd->flags.visited) && si->sip){
5503                 ld=se_alloc(sizeof(smb_locking_saved_info_t));
5504                 ld->type=lt;
5505                 ld->oplock_level= ol;
5506                 ld->num_lock=num_lock;
5507                 ld->num_unlock=num_unlock;
5508                 ld->locks=NULL;
5509                 ld->unlocks=NULL;
5510                 si->sip->extra_info_type=SMB_EI_LOCKDATA;
5511                 si->sip->extra_info=ld;
5512         }
5513
5514         /* unlocks */
5515         if(un){
5516                 old_offset = offset;
5517
5518                 it = proto_tree_add_text(tree, tvb, offset, -1,
5519                         "Unlocks");
5520                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
5521                 while(un--){
5522                         proto_item *litem = NULL;
5523                         proto_tree *ltree = NULL;
5524                         if(lt&0x10){
5525                                 guint64 val;
5526                                 guint16 lock_pid;
5527                                 guint64 lock_offset;
5528                                 guint64 lock_length;
5529
5530                                 /* large lock format */
5531                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5532                                         "Unlock");
5533                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5534
5535                                 /* PID */
5536                                 CHECK_BYTE_COUNT(2);
5537                                 lock_pid=tvb_get_letohs(tvb, offset);
5538                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5539                                 COUNT_BYTES(2);
5540
5541                                 /* 2 reserved bytes */
5542                                 CHECK_BYTE_COUNT(2);
5543                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5544                                 COUNT_BYTES(2);
5545
5546                                 /* offset */
5547                                 CHECK_BYTE_COUNT(8);
5548                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5549                                     | tvb_get_letohl(tvb, offset+4);
5550                                 lock_offset=val;
5551                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5552                                 COUNT_BYTES(8);
5553
5554                                 /* length */
5555                                 CHECK_BYTE_COUNT(8);
5556                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5557                                     | tvb_get_letohl(tvb, offset+4);
5558                                 lock_length=val;
5559                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5560                                 COUNT_BYTES(8);
5561
5562                                 /* remember the unlock for the reply */
5563                                 if(ld){
5564                                         smb_lock_info_t *li;
5565                                         li=se_alloc(sizeof(smb_lock_info_t));
5566                                         li->next=ld->unlocks;
5567                                         ld->unlocks=li;
5568                                         li->pid=lock_pid;
5569                                         li->offset=lock_offset;
5570                                         li->length=lock_length;
5571                                 }
5572                         } else {
5573                                 /* normal lock format */
5574                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5575                                         "Unlock");
5576                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5577
5578                                 /* PID */
5579                                 CHECK_BYTE_COUNT(2);
5580                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5581                                 COUNT_BYTES(2);
5582
5583                                 /* offset */
5584                                 CHECK_BYTE_COUNT(4);
5585                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5586                                 COUNT_BYTES(4);
5587
5588                                 /* lock count */
5589                                 CHECK_BYTE_COUNT(4);
5590                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5591                                 COUNT_BYTES(4);
5592                         }
5593                 }
5594                 proto_item_set_len(it, offset-old_offset);
5595                 it = NULL;
5596         }
5597
5598         /* locks */
5599         if(ln){
5600                 old_offset = offset;
5601
5602                 it = proto_tree_add_text(tree, tvb, offset, -1,
5603                         "Locks");
5604                 tr = proto_item_add_subtree(it, ett_smb_locks);
5605                 while(ln--){
5606                         proto_item *litem = NULL;
5607                         proto_tree *ltree = NULL;
5608                         if(lt&0x10){
5609                                 guint64 val;
5610                                 guint16 lock_pid;
5611                                 guint64 lock_offset;
5612                                 guint64 lock_length;
5613
5614                                 /* large lock format */
5615                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5616                                         "Lock");
5617                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5618
5619                                 /* PID */
5620                                 CHECK_BYTE_COUNT(2);
5621                                 lock_pid=tvb_get_letohs(tvb, offset);
5622                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5623                                 COUNT_BYTES(2);
5624
5625                                 /* 2 reserved bytes */
5626                                 CHECK_BYTE_COUNT(2);
5627                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5628                                 COUNT_BYTES(2);
5629
5630                                 /* offset */
5631                                 CHECK_BYTE_COUNT(8);
5632                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5633                                     | tvb_get_letohl(tvb, offset+4);
5634                                 lock_offset=val;
5635                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5636                                 COUNT_BYTES(8);
5637
5638                                 /* length */
5639                                 CHECK_BYTE_COUNT(8);
5640                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5641                                     | tvb_get_letohl(tvb, offset+4);
5642                                 lock_length=val;
5643                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5644                                 COUNT_BYTES(8);
5645
5646                                 /* remember the lock for the reply */
5647                                 if(ld){
5648                                         smb_lock_info_t *li;
5649                                         li=se_alloc(sizeof(smb_lock_info_t));
5650                                         li->next=ld->locks;
5651                                         ld->locks=li;
5652                                         li->pid=lock_pid;
5653                                         li->offset=lock_offset;
5654                                         li->length=lock_length;
5655                                 }
5656                         } else {
5657                                 /* normal lock format */
5658                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5659                                         "Lock");
5660                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5661
5662                                 /* PID */
5663                                 CHECK_BYTE_COUNT(2);
5664                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5665                                 COUNT_BYTES(2);
5666
5667                                 /* offset */
5668                                 CHECK_BYTE_COUNT(4);
5669                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5670                                 COUNT_BYTES(4);
5671
5672                                 /* lock count */
5673                                 CHECK_BYTE_COUNT(4);
5674                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5675                                 COUNT_BYTES(4);
5676                         }
5677                 }
5678                 proto_item_set_len(it, offset-old_offset);
5679                 it = NULL;
5680         }
5681
5682         END_OF_SMB
5683
5684         if (it != NULL) {
5685                 /*
5686                  * We ran out of byte count in the middle of dissecting
5687                  * the locks or the unlocks; set the site of the item
5688                  * we were dissecting.
5689                  */
5690                 proto_item_set_len(it, offset-old_offset);
5691         }
5692
5693         if (cmd != 0xff) {      /* there is an andX command */
5694                 if (andxoffset < offset)
5695                         THROW(ReportedBoundsError);
5696                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5697         }
5698
5699         return offset;
5700 }
5701
5702 static int
5703 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5704 {
5705         guint8  wc, cmd=0xff;
5706         guint16 andxoffset=0;
5707         guint16 bc;
5708         smb_info_t *si;
5709
5710         si = (smb_info_t *)pinfo->private_data;
5711         DISSECTOR_ASSERT(si);
5712
5713         /* print the lock info from the request */
5714         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_LOCKDATA) {
5715                 smb_locking_saved_info_t *ld;
5716                 proto_item *litem = NULL;
5717                 proto_tree *ltree = NULL;
5718
5719                 ld = si->sip->extra_info;
5720                 if (ld != NULL) {
5721                         proto_item *lit;
5722                         proto_tree *ltr;
5723                         smb_lock_info_t *li;
5724                         if(tree){
5725                                 litem = proto_tree_add_text(tree, tvb, 0, 0,
5726                                         "Lock Type: 0x%02x", ld->type);
5727                                 PROTO_ITEM_SET_GENERATED(litem);
5728                                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5729
5730                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_large, tvb, 0, 0, ld->type);
5731                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel, tvb, 0, 0, ld->type);
5732                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_change, tvb, 0, 0, ld->type);
5733                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock, tvb, 0, 0, ld->type);
5734                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared, tvb, 0, 0, ld->type);
5735                                 proto_tree_add_uint(ltree, hf_smb_locking_ol, tvb, 0, 0, ld->oplock_level);
5736                                 proto_tree_add_uint(ltree, hf_smb_number_of_unlocks, tvb, 0, 0, ld->num_unlock);
5737                                 proto_tree_add_uint(ltree, hf_smb_number_of_locks, tvb, 0, 0, ld->num_lock);
5738
5739                                 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Locks");
5740                                 ltr = proto_item_add_subtree(lit, ett_smb_lock);
5741                                 li=ld->locks;
5742                                 while(li){
5743                                         proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
5744                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
5745                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
5746                                         li=li->next;
5747                                 }
5748                                 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Unlocks");
5749                                 ltr = proto_item_add_subtree(lit, ett_smb_unlock);
5750                                 li=ld->unlocks;
5751                                 while(li){
5752                                         proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
5753                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
5754                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
5755                                         li=li->next;
5756                                 }
5757                         }
5758                 }
5759         }
5760
5761         WORD_COUNT;
5762
5763         /* next smb command */
5764         cmd = tvb_get_guint8(tvb, offset);
5765         if(cmd!=0xff){
5766                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5767         } else {
5768                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5769         }
5770         offset += 1;
5771
5772         /* reserved byte */
5773         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5774         offset += 1;
5775
5776         /* andxoffset */
5777         andxoffset = tvb_get_letohs(tvb, offset);
5778         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5779         offset += 2;
5780
5781         BYTE_COUNT;
5782
5783         END_OF_SMB
5784
5785         if (cmd != 0xff) {      /* there is an andX command */
5786                 if (andxoffset < offset)
5787                         THROW(ReportedBoundsError);
5788                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5789         }
5790
5791         return offset;
5792 }
5793
5794
5795 const value_string oa_open_vals[] = {
5796         { 0,            "No action taken?"},
5797         { 1,            "The file existed and was opened"},
5798         { 2,            "The file did not exist but was created"},
5799         { 3,            "The file existed and was truncated"},
5800         { 0x8001,       "The file existed and was opened, and an OpLock was granted"},
5801         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
5802         { 0x8003,       "The file existed and was truncated, and an OpLock was granted"},
5803         {0,     NULL}
5804 };
5805 static const true_false_string tfs_oa_lock = {
5806         "File is currently opened only by this user",
5807         "File is opened by another user (or mode not supported by server)"
5808 };
5809 static int
5810 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5811 {
5812         guint16 mask;
5813         proto_item *item;
5814         proto_tree *tree;
5815
5816         mask = tvb_get_letohs(tvb, offset);
5817
5818         if(parent_tree){
5819                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5820                         "Action: 0x%04x", mask);
5821                 tree = proto_item_add_subtree(item, ett_smb_open_action);
5822
5823                 proto_tree_add_boolean(tree, hf_smb_open_action_lock,
5824                         tvb, offset, 2, mask);
5825                 proto_tree_add_uint(tree, hf_smb_open_action_open,
5826                         tvb, offset, 2, mask);
5827         }
5828         offset += 2;
5829
5830         return offset;
5831 }
5832
5833 static const true_false_string tfs_open_flags_add_info = {
5834         "Additional information requested",
5835         "Additional information not requested"
5836 };
5837 static const true_false_string tfs_open_flags_ex_oplock = {
5838         "Exclusive oplock requested",
5839         "Exclusive oplock not requested"
5840 };
5841 static const true_false_string tfs_open_flags_batch_oplock = {
5842         "Batch oplock requested",
5843         "Batch oplock not requested"
5844 };
5845 static const true_false_string tfs_open_flags_ealen = {
5846         "Total length of EAs requested",
5847         "Total length of EAs not requested"
5848 };
5849 static int
5850 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5851 {
5852         guint16 mask;
5853         proto_item *item;
5854         proto_tree *tree;
5855
5856         mask = tvb_get_letohs(tvb, offset);
5857
5858         if(parent_tree){
5859                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5860                         "Flags: 0x%04x", mask);
5861                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5862
5863                 if(bm&0x0001){
5864                         proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5865                                 tvb, offset, 2, mask);
5866                 }
5867                 if(bm&0x0002){
5868                         proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5869                                 tvb, offset, 2, mask);
5870                 }
5871                 if(bm&0x0004){
5872                         proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5873                                 tvb, offset, 2, mask);
5874                 }
5875                 if(bm&0x0008){
5876                         proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5877                                 tvb, offset, 2, mask);
5878                 }
5879         }
5880
5881         offset += 2;
5882
5883         return offset;
5884 }
5885
5886 static const value_string filetype_vals[] = {
5887         { 0,            "Disk file or directory"},
5888         { 1,            "Named pipe in byte mode"},
5889         { 2,            "Named pipe in message mode"},
5890         { 3,            "Spooled printer"},
5891         {0, NULL}
5892 };
5893 static int
5894 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5895 {
5896         guint8  wc, cmd=0xff;
5897         guint16 andxoffset=0, bc;
5898         guint32 to;
5899         smb_info_t *si = pinfo->private_data;
5900         int fn_len;
5901         const char *fn;
5902
5903         DISSECTOR_ASSERT(si);
5904
5905         WORD_COUNT;
5906
5907         /* next smb command */
5908         cmd = tvb_get_guint8(tvb, offset);
5909         if(cmd!=0xff){
5910                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5911         } else {
5912                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5913         }
5914         offset += 1;
5915
5916         /* reserved byte */
5917         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5918         offset += 1;
5919
5920         /* andxoffset */
5921         andxoffset = tvb_get_letohs(tvb, offset);
5922         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5923         offset += 2;
5924
5925         /* open flags */
5926         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5927
5928         /* desired access */
5929         offset = dissect_access(tvb, tree, offset, "Desired");
5930
5931         /* Search Attributes */
5932         offset = dissect_search_attributes(tvb, tree, offset);
5933
5934         /* File Attributes */
5935         offset = dissect_file_attributes(tvb, tree, offset, 2);
5936
5937         /* creation time */
5938         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5939
5940         /* open function */
5941         offset = dissect_open_function(tvb, tree, offset);
5942
5943         /* allocation size */
5944         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5945         offset += 4;
5946
5947         /* timeout, described at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT */
5948         to = tvb_get_letohl(tvb, offset);
5949         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5950         offset += 4;
5951
5952         /* 4 reserved bytes */
5953         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5954         offset += 4;
5955
5956         BYTE_COUNT;
5957
5958         /* file name */
5959         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5960                 FALSE, FALSE, &bc);
5961         if (fn == NULL)
5962                 goto endofcommand;
5963         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5964                 fn);
5965         COUNT_BYTES(fn_len);
5966
5967         if (check_col(pinfo->cinfo, COL_INFO)) {
5968                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
5969                     format_text(fn, strlen(fn)));
5970         }
5971
5972         END_OF_SMB
5973
5974         if (cmd != 0xff) {      /* there is an andX command */
5975                 if (andxoffset < offset)
5976                         THROW(ReportedBoundsError);
5977                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5978         }
5979
5980         return offset;
5981 }
5982
5983 static const true_false_string tfs_ipc_state_nonblocking = {
5984         "Reads/writes return immediately if no data available",
5985         "Reads/writes block if no data available"
5986 };
5987 static const value_string ipc_state_endpoint_vals[] = {
5988         { 0,            "Consumer end of pipe"},
5989         { 1,            "Server end of pipe"},
5990         {0,     NULL}
5991 };
5992 static const value_string ipc_state_pipe_type_vals[] = {
5993         { 0,            "Byte stream pipe"},
5994         { 1,            "Message pipe"},
5995         {0,     NULL}
5996 };
5997 static const value_string ipc_state_read_mode_vals[] = {
5998         { 0,            "Read pipe as a byte stream"},
5999         { 1,            "Read messages from pipe"},
6000         {0,     NULL}
6001 };
6002
6003 int
6004 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
6005     gboolean setstate)
6006 {
6007         guint16 mask;
6008         proto_item *item;
6009         proto_tree *tree;
6010
6011         mask = tvb_get_letohs(tvb, offset);
6012
6013         if(parent_tree){
6014                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6015                         "IPC State: 0x%04x", mask);
6016                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
6017
6018                 proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
6019                         tvb, offset, 2, mask);
6020                 if (!setstate) {
6021                         proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
6022                                 tvb, offset, 2, mask);
6023                         proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
6024                                 tvb, offset, 2, mask);
6025                 }
6026                 proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
6027                         tvb, offset, 2, mask);
6028                 if (!setstate) {
6029                         proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
6030                                 tvb, offset, 2, mask);
6031                 }
6032         }
6033
6034         offset += 2;
6035
6036         return offset;
6037 }
6038
6039 static int
6040 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6041 {
6042         guint8  wc, cmd=0xff;
6043         guint16 andxoffset=0, bc;
6044         guint16 fid;
6045
6046         WORD_COUNT;
6047
6048         /* next smb command */
6049         cmd = tvb_get_guint8(tvb, offset);
6050         if(cmd!=0xff){
6051                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6052         } else {
6053                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6054         }
6055         offset += 1;
6056
6057         /* reserved byte */
6058         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6059         offset += 1;
6060
6061         /* andxoffset */
6062         andxoffset = tvb_get_letohs(tvb, offset);
6063         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6064         offset += 2;
6065
6066         /* fid */
6067         fid = tvb_get_letohs(tvb, offset);
6068         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
6069         offset += 2;
6070
6071         /* File Attributes */
6072         offset = dissect_file_attributes(tvb, tree, offset, 2);
6073
6074         /* last write time */
6075         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
6076
6077         /* File Size */
6078         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
6079         offset += 4;
6080
6081         /* granted access */
6082         offset = dissect_access(tvb, tree, offset, "Granted");
6083
6084         /* File Type */
6085         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
6086         offset += 2;
6087
6088         /* IPC State */
6089         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
6090
6091         /* open_action */
6092         offset = dissect_open_action(tvb, tree, offset);
6093
6094         /* server fid */
6095         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
6096         offset += 4;
6097
6098         /* 2 reserved bytes */
6099         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6100         offset += 2;
6101
6102         BYTE_COUNT;
6103
6104         END_OF_SMB
6105
6106         if (cmd != 0xff) {      /* there is an andX command */
6107                 if (andxoffset < offset)
6108                         THROW(ReportedBoundsError);
6109                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6110         }
6111
6112         return offset;
6113 }
6114
6115 static int
6116 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6117 {
6118         guint8  wc, cmd=0xff;
6119         guint16 andxoffset=0, bc, maxcnt_low;
6120         guint32 maxcnt_high;
6121         guint32 maxcnt=0;
6122         guint32 ofs = 0;
6123         smb_info_t *si= (smb_info_t *)pinfo->private_data;
6124         unsigned int fid;
6125         rw_info_t *rwi=NULL;
6126
6127
6128         DISSECTOR_ASSERT(si);
6129
6130         WORD_COUNT;
6131
6132         /* next smb command */
6133         cmd = tvb_get_guint8(tvb, offset);
6134         if(cmd!=0xff){
6135                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6136         } else {
6137                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6138         }
6139         offset += 1;
6140
6141         /* reserved byte */
6142         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6143         offset += 1;
6144
6145         /* andxoffset */
6146         andxoffset = tvb_get_letohs(tvb, offset);
6147         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6148         offset += 2;
6149
6150         /* fid */
6151         fid = tvb_get_letohs(tvb, offset);
6152         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6153         offset += 2;
6154
6155         /* offset */
6156         ofs = tvb_get_letohl(tvb, offset);
6157         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6158         offset += 4;
6159
6160         /* max count low */
6161         maxcnt_low = tvb_get_letohs(tvb, offset);
6162         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
6163         offset += 2;
6164
6165         /* min count */
6166         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
6167         offset += 2;
6168
6169         /*
6170          * max count high
6171          *
6172          * XXX - we should really only do this in case we have seen
6173          * LARGE FILE being negotiated.  Unfortunately, we might not
6174          * have seen the negotiation phase in the capture....
6175          *
6176          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
6177          * it's 32 bits, but the description says "High 16 bits of
6178          * MaxCount if CAP_LARGE_READX".
6179          *
6180          * The SMB File Sharing Protocol Extensions Version 2.0,
6181          * Document Version 3.3 spec doesn't speak of an extra 16
6182          * bits in max count, but it does show a 32-bit timeout
6183          * after the min count field.
6184          *
6185          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
6186          * high count and a 16-bit reserved field.
6187          *
6188          * We fetch and display it as 32 bits.
6189          *
6190          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
6191          * bytes and we just ignore it.
6192          */
6193         maxcnt_high = tvb_get_letohl(tvb, offset);
6194         if(maxcnt_high==0xffffffff){
6195                 maxcnt_high=0;
6196         } else {
6197                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
6198         }
6199
6200         offset += 4;
6201
6202         maxcnt=maxcnt_high;
6203         maxcnt=(maxcnt<<16)|maxcnt_low;
6204
6205         if (check_col(pinfo->cinfo, COL_INFO))
6206                 col_append_fstr(pinfo->cinfo, COL_INFO,
6207                                 ", %u byte%s at offset %u", maxcnt,
6208                                 (maxcnt == 1) ? "" : "s", ofs);
6209
6210         /* save the offset/len for this transaction */
6211         if(si->sip && !pinfo->fd->flags.visited){
6212                 rwi=se_alloc(sizeof(rw_info_t));
6213                 rwi->offset=ofs;
6214                 rwi->len=maxcnt;
6215                 rwi->fid=fid;
6216
6217                 si->sip->extra_info_type=SMB_EI_RWINFO;
6218                 si->sip->extra_info=rwi;
6219         }
6220         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6221                 rwi=si->sip->extra_info;
6222         }
6223         if(rwi){
6224                 proto_item *it;
6225
6226                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6227
6228                 PROTO_ITEM_SET_GENERATED(it);
6229                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6230                 PROTO_ITEM_SET_GENERATED(it);
6231         }
6232
6233         /* remaining */
6234         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6235         offset += 2;
6236
6237         if(wc==12){
6238                 /* high offset */
6239                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6240                 offset += 4;
6241         }
6242
6243         BYTE_COUNT;
6244
6245         END_OF_SMB
6246
6247         if (cmd != 0xff) {      /* there is an andX command */
6248                 if (andxoffset < offset)
6249                         THROW(ReportedBoundsError);
6250                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6251         }
6252
6253         return offset;
6254 }
6255
6256 static int
6257 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6258 {
6259         guint8  wc, cmd=0xff;
6260         guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
6261         guint32 datalen=0, datalen_high;
6262         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6263         int fid=0;
6264         rw_info_t *rwi=NULL;
6265
6266         DISSECTOR_ASSERT(si);
6267
6268         WORD_COUNT;
6269
6270         /* next smb command */
6271         cmd = tvb_get_guint8(tvb, offset);
6272         if(cmd!=0xff){
6273                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6274         } else {
6275                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6276         }
6277         offset += 1;
6278
6279         /* reserved byte */
6280         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6281         offset += 1;
6282
6283         /* andxoffset */
6284         andxoffset = tvb_get_letohs(tvb, offset);
6285         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6286         offset += 2;
6287
6288         /* If we have seen the request, then print which FID this refers to */
6289         /* first check if we have seen the request */
6290         if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type==SMB_EI_FID){
6291                 fid=GPOINTER_TO_INT(si->sip->extra_info);
6292                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE);
6293         }
6294
6295         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6296                 rwi=si->sip->extra_info;
6297         }
6298         if(rwi){
6299                 proto_item *it;
6300
6301                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6302
6303                 PROTO_ITEM_SET_GENERATED(it);
6304                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6305                 PROTO_ITEM_SET_GENERATED(it);
6306
6307                 /* we need the fid for the call to dcerpc below */
6308                 fid=rwi->fid;
6309         }
6310
6311         /* remaining */
6312         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6313         offset += 2;
6314
6315         /* data compaction mode */
6316         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
6317         offset += 2;
6318
6319         /* 2 reserved bytes */
6320         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6321         offset += 2;
6322
6323         /* data len low */
6324         datalen_low = tvb_get_letohs(tvb, offset);
6325         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6326         offset += 2;
6327
6328         /* data offset */
6329         dataoffset=tvb_get_letohs(tvb, offset);
6330         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6331         offset += 2;
6332
6333         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6334         /* data length high */
6335         datalen_high = tvb_get_letohl(tvb, offset);
6336         if(datalen_high==0xffffffff){
6337                 datalen_high=0;
6338         } else {
6339                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
6340         }
6341         offset += 4;
6342
6343         datalen=datalen_high;
6344         datalen=(datalen<<16)|datalen_low;
6345
6346
6347         if (check_col(pinfo->cinfo, COL_INFO))
6348                 col_append_fstr(pinfo->cinfo, COL_INFO,
6349                                 ", %u byte%s", datalen,
6350                                 (datalen == 1) ? "" : "s");
6351
6352
6353         /* 6 reserved bytes */
6354         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
6355         offset += 6;
6356
6357         BYTE_COUNT;
6358
6359         /* file data, might be DCERPC on a pipe */
6360         if(bc){
6361                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6362                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6363                 bc = 0;
6364         }
6365
6366         END_OF_SMB
6367
6368         if (cmd != 0xff) {      /* there is an andX command */
6369                 if (andxoffset < offset)
6370                         THROW(ReportedBoundsError);
6371                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6372         }
6373
6374         return offset;
6375 }
6376
6377 static int
6378 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6379 {
6380         guint32 ofs=0;
6381         guint8  wc, cmd=0xff;
6382         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
6383         guint32 datalen=0;
6384         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6385         unsigned int fid=0;
6386         guint16 mode = 0;
6387         rw_info_t *rwi=NULL;
6388
6389
6390         DISSECTOR_ASSERT(si);
6391
6392         WORD_COUNT;
6393
6394         /* next smb command */
6395         cmd = tvb_get_guint8(tvb, offset);
6396         if(cmd!=0xff){
6397                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6398         } else {
6399                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6400         }
6401         offset += 1;
6402
6403         /* reserved byte */
6404         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6405         offset += 1;
6406
6407         /* andxoffset */
6408         andxoffset = tvb_get_letohs(tvb, offset);
6409         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6410         offset += 2;
6411
6412         /* fid */
6413         fid = tvb_get_letohs(tvb, offset);
6414         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6415         offset += 2;
6416
6417         /* offset */
6418         ofs = tvb_get_letohl(tvb, offset);
6419         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6420         offset += 4;
6421
6422         /* reserved */
6423         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6424         offset += 4;
6425
6426         /* mode */
6427         mode = tvb_get_letohs(tvb, offset);
6428         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
6429
6430         /* remaining */
6431         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6432         offset += 2;
6433
6434         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6435         /* data length high */
6436         datalen_high = tvb_get_letohs(tvb, offset);
6437         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
6438         offset += 2;
6439
6440         /* data len low */
6441         datalen_low = tvb_get_letohs(tvb, offset);
6442         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6443         offset += 2;
6444
6445         datalen=datalen_high;
6446         datalen=(datalen<<16)|datalen_low;
6447
6448         /* data offset */
6449         dataoffset=tvb_get_letohs(tvb, offset);
6450         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6451         offset += 2;
6452
6453         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
6454         if (check_col(pinfo->cinfo, COL_INFO))
6455                 col_append_fstr(pinfo->cinfo, COL_INFO,
6456                                 ", %u byte%s at offset %u", datalen,
6457                                 (datalen == 1) ? "" : "s", ofs);
6458
6459         /* save the offset/len for this transaction */
6460         if(si->sip && !pinfo->fd->flags.visited){
6461                 rwi=se_alloc(sizeof(rw_info_t));
6462                 rwi->offset=ofs;
6463                 rwi->len=datalen;
6464                 rwi->fid=fid;
6465
6466                 si->sip->extra_info_type=SMB_EI_RWINFO;
6467                 si->sip->extra_info=rwi;
6468         }
6469         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6470                 rwi=si->sip->extra_info;
6471         }
6472         if(rwi){
6473                 proto_item *it;
6474
6475                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6476
6477                 PROTO_ITEM_SET_GENERATED(it);
6478                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6479                 PROTO_ITEM_SET_GENERATED(it);
6480         }
6481
6482
6483         if(wc==14){
6484                 /* high offset */
6485                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6486                 offset += 4;
6487         }
6488
6489         BYTE_COUNT;
6490
6491         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
6492            the first two bytes of the payload is the length of the data.
6493            Assume that all WriteAndX PDUs that have MESSAGE_START set to
6494            be over the IPC$ share and thus they all transport DCERPC.
6495            (if we didnt already know that from the TreeConnect call)
6496         */
6497         if(mode&WRITE_MODE_MESSAGE_START){
6498                 if(mode&WRITE_MODE_RAW){
6499                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
6500                         offset += 2;
6501                         dataoffset += 2;
6502                         bc -= 2;
6503                         datalen -= 2;
6504                 }
6505                 if(!pinfo->fd->flags.visited){
6506                         /* In case we did not see the TreeConnect call,
6507                            store this TID here as well as a IPC TID
6508                            so we know that future Read/Writes to this
6509                            TID is (probably) DCERPC.
6510                         */
6511                         if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
6512                                 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
6513                         }
6514                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
6515                 }
6516                 if(si->sip){
6517                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
6518                 }
6519         }
6520
6521         /* file data, might be DCERPC on a pipe */
6522         if (bc != 0) {
6523                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6524                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6525                 bc = 0;
6526         }
6527
6528         END_OF_SMB
6529
6530         if (cmd != 0xff) {      /* there is an andX command */
6531                 if (andxoffset < offset)
6532                         THROW(ReportedBoundsError);
6533                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6534         }
6535
6536         return offset;
6537 }
6538
6539 static int
6540 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6541 {
6542         guint8  wc, cmd=0xff;
6543         guint16 andxoffset=0, bc, count_low, count_high;
6544         guint32 count=0;
6545         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6546         rw_info_t *rwi=NULL;
6547
6548         DISSECTOR_ASSERT(si);
6549
6550         WORD_COUNT;
6551
6552         /* next smb command */
6553         cmd = tvb_get_guint8(tvb, offset);
6554         if(cmd!=0xff){
6555                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6556         } else {
6557                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6558         }
6559         offset += 1;
6560
6561         /* reserved byte */
6562         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6563         offset += 1;
6564
6565         /* andxoffset */
6566         andxoffset = tvb_get_letohs(tvb, offset);
6567         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6568         offset += 2;
6569
6570
6571         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6572                 rwi=si->sip->extra_info;
6573         }
6574         if(rwi){
6575                 proto_item *it;
6576
6577                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6578
6579                 PROTO_ITEM_SET_GENERATED(it);
6580                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6581                 PROTO_ITEM_SET_GENERATED(it);
6582         }
6583
6584
6585         /* write count low */
6586         count_low = tvb_get_letohs(tvb, offset);
6587         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
6588         offset += 2;
6589
6590         /* remaining */
6591         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6592         offset += 2;
6593
6594         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6595         /* write count high */
6596         count_high = tvb_get_letohs(tvb, offset);
6597         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
6598         offset += 2;
6599
6600         count=count_high;
6601         count=(count<<16)|count_low;
6602
6603         if (check_col(pinfo->cinfo, COL_INFO))
6604                 col_append_fstr(pinfo->cinfo, COL_INFO,
6605                                 ", %u byte%s", count,
6606                                 (count == 1) ? "" : "s");
6607
6608         /* 2 reserved bytes */
6609         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6610         offset += 2;
6611
6612         BYTE_COUNT;
6613
6614         END_OF_SMB
6615
6616         if (cmd != 0xff) {      /* there is an andX command */
6617                 if (andxoffset < offset)
6618                         THROW(ReportedBoundsError);
6619                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6620         }
6621
6622         return offset;
6623 }
6624
6625
6626 static const true_false_string tfs_setup_action_guest = {
6627         "Logged in as GUEST",
6628         "Not logged in as GUEST"
6629 };
6630 static int
6631 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6632 {
6633         guint16 mask;
6634         proto_item *item;
6635         proto_tree *tree;
6636
6637         mask = tvb_get_letohs(tvb, offset);
6638
6639         if(parent_tree){
6640                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6641                         "Action: 0x%04x", mask);
6642                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
6643
6644                 proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
6645                         tvb, offset, 2, mask);
6646         }
6647         offset += 2;
6648
6649         return offset;
6650 }
6651
6652
6653 static int
6654 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6655 {
6656         guint8  wc, cmd=0xff;
6657         guint16 bc;
6658         guint16 andxoffset=0;
6659         smb_info_t *si = pinfo->private_data;
6660         int an_len;
6661         const char *an;
6662         int dn_len;
6663         const char *dn;
6664         guint16 pwlen=0;
6665         guint16 sbloblen=0, sbloblen_short;
6666         guint16 apwlen=0, upwlen=0;
6667         gboolean unicodeflag;
6668         static int ntlmssp_tap_id = 0;
6669         const ntlmssp_header_t *ntlmssph;
6670
6671         if(!ntlmssp_tap_id){
6672                 GString *error_string;
6673                 /* We dont specify any callbacks at all.
6674                  * Instead we manually fetch the tapped data after the
6675                  * security blob has been fully dissected and before
6676                  * we exit from this dissector.
6677                  */
6678                 error_string=register_tap_listener("ntlmssp", NULL, NULL, NULL, NULL, NULL);
6679                 if(!error_string){
6680                         ntlmssp_tap_id=find_tap_id("ntlmssp");
6681                 }
6682         }
6683
6684         DISSECTOR_ASSERT(si);
6685
6686         WORD_COUNT;
6687
6688         /* next smb command */
6689         cmd = tvb_get_guint8(tvb, offset);
6690         if(cmd!=0xff){
6691                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6692         } else {
6693                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6694         }
6695         offset += 1;
6696
6697         /* reserved byte */
6698         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6699         offset += 1;
6700
6701         /* andxoffset */
6702         andxoffset = tvb_get_letohs(tvb, offset);
6703         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6704         offset += 2;
6705
6706         /* Maximum Buffer Size */
6707         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
6708         offset += 2;
6709
6710         /* Maximum Multiplex Count */
6711         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
6712         offset += 2;
6713
6714         /* VC Number */
6715         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
6716         offset += 2;
6717
6718         /* session key */
6719         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
6720         offset += 4;
6721
6722         switch (wc) {
6723         case 10:
6724                 /* password length, ASCII*/
6725                 pwlen = tvb_get_letohs(tvb, offset);
6726                 proto_tree_add_uint(tree, hf_smb_password_len,
6727                         tvb, offset, 2, pwlen);
6728                 offset += 2;
6729
6730                 /* 4 reserved bytes */
6731                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6732                 offset += 4;
6733
6734                 break;
6735
6736         case 12:
6737                 /* security blob length */
6738                 sbloblen = tvb_get_letohs(tvb, offset);
6739                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6740                 offset += 2;
6741
6742                 /* 4 reserved bytes */
6743                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6744                 offset += 4;
6745
6746                 /* capabilities */
6747                 dissect_negprot_capabilities(tvb, tree, offset);
6748                 offset += 4;
6749
6750                 break;
6751
6752         case 13:
6753                 /* password length, ANSI*/
6754                 apwlen = tvb_get_letohs(tvb, offset);
6755                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
6756                         tvb, offset, 2, apwlen);
6757                 offset += 2;
6758
6759                 /* password length, Unicode*/
6760                 upwlen = tvb_get_letohs(tvb, offset);
6761                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
6762                         tvb, offset, 2, upwlen);
6763                 offset += 2;
6764
6765                 /* 4 reserved bytes */
6766                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6767                 offset += 4;
6768
6769                 /* capabilities */
6770                 dissect_negprot_capabilities(tvb, tree, offset);
6771                 offset += 4;
6772
6773                 break;
6774         }
6775
6776         BYTE_COUNT;
6777
6778         if (wc==12) {
6779                 proto_item *blob_item;
6780
6781                 /* security blob */
6782                 /* If it runs past the end of the captured data, don't
6783                  * try to put all of it into the protocol tree as the
6784                  * raw security blob; we might get an exception on
6785                  * short frames and then we will not see anything at all
6786                  * of the security blob.
6787                  */
6788                 sbloblen_short = sbloblen;
6789                 if(sbloblen_short>tvb_length_remaining(tvb,offset)){
6790                         sbloblen_short=tvb_length_remaining(tvb,offset);
6791                 }
6792                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6793                                                 tvb, offset, sbloblen_short,
6794                                                 TRUE);
6795
6796                 /* As an optimization, because Windows is perverse,
6797                    we check to see if NTLMSSP is the first part of the
6798                    blob, and if so, call the NTLMSSP dissector,
6799                    otherwise we call the GSS-API dissector. This is because
6800                    Windows can request RAW NTLMSSP, but will happily handle
6801                    a client that wraps NTLMSSP in SPNEGO
6802                 */
6803
6804                 if(sbloblen){
6805                         tvbuff_t *blob_tvb;
6806                         proto_tree *blob_tree;
6807
6808                         blob_tree = proto_item_add_subtree(blob_item,
6809                                                            ett_smb_secblob);
6810                         CHECK_BYTE_COUNT(sbloblen);
6811
6812                         /*
6813                          * Set the reported length of this to the reported
6814                          * length of the blob, rather than the amount of
6815                          * data available from the blob, so that we'll
6816                          * throw the right exception if it's too short.
6817                          */
6818                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
6819                                                   sbloblen);
6820
6821                         if (si && si->ct && si->ct->raw_ntlmssp &&
6822                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
6823                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6824                                          blob_tree);
6825
6826                         }
6827                         else {
6828                           call_dissector(gssapi_handle, blob_tvb,
6829                                          pinfo, blob_tree);
6830                         }
6831
6832                         /* If we have found a uid->acct_name mapping, store it */
6833                         if(!pinfo->fd->flags.visited && si->sip){
6834                                 int idx=0;
6835                                 if((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
6836                                         if(ntlmssph && ntlmssph->type==3){
6837                                                 smb_uid_t *smb_uid;
6838
6839                                                 smb_uid=se_alloc(sizeof(smb_uid_t));
6840                                                 smb_uid->logged_in=-1;
6841                                                 smb_uid->logged_out=-1;
6842                                                 smb_uid->domain=se_strdup(ntlmssph->domain_name);
6843                                                 smb_uid->account=se_strdup(ntlmssph->acct_name);
6844
6845                                                 si->sip->extra_info=smb_uid;
6846                                                 si->sip->extra_info_type=SMB_EI_UID;
6847                                         }
6848                                 }
6849                         }
6850
6851                         COUNT_BYTES(sbloblen);
6852                 }
6853
6854                 /* OS
6855                  * Eventhough this field should honour the unicode flag
6856                  * some ms clients gets this wrong.
6857                  * At least XP SP1 sends this in ASCII
6858                  * even when the unicode flag is on.
6859                  * Test if the first three bytes are "Win"
6860                  * and if so just override the flag.
6861                  */
6862                 unicodeflag=si->unicode;
6863                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6864                         unicodeflag=FALSE;
6865                 }
6866                 an = get_unicode_or_ascii_string(tvb, &offset,
6867                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6868                 if (an == NULL)
6869                         goto endofcommand;
6870                 proto_tree_add_string(tree, hf_smb_os, tvb,
6871                         offset, an_len, an);
6872                 COUNT_BYTES(an_len);
6873
6874                 /* LANMAN */
6875                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
6876                  * padding/null string/whatever in front of this. W2K doesn't
6877                  * appear to. I suspect that's a bug that got fixed; I also
6878                  * suspect that, in practice, nobody ever looks at that field
6879                  * because the bug didn't appear to get fixed until NT 5.0....
6880                  *
6881                  * Eventhough this field should honour the unicode flag
6882                  * some ms clients gets this wrong.
6883                  * At least XP SP1 sends this in ASCII
6884                  * even when the unicode flag is on.
6885                  * Test if the first three bytes are "Win"
6886                  * and if so just override the flag.
6887                  */
6888                 unicodeflag=si->unicode;
6889                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6890                         unicodeflag=FALSE;
6891                 }
6892                 an = get_unicode_or_ascii_string(tvb, &offset,
6893                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6894                 if (an == NULL)
6895                         goto endofcommand;
6896                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6897                         offset, an_len, an);
6898                 COUNT_BYTES(an_len);
6899
6900                 /* Primary domain */
6901                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6902                  * byte in front of this, at least if all the strings are
6903                  * ASCII and the account name is empty. Another bug?
6904                  */
6905                 dn = get_unicode_or_ascii_string(tvb, &offset,
6906                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6907                 if (dn == NULL)
6908                         goto endofcommand;
6909                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6910                         offset, dn_len, dn);
6911                 COUNT_BYTES(dn_len);
6912         } else {
6913                 switch (wc) {
6914
6915                 case 10:
6916                         if(pwlen){
6917                                 /* password, ASCII */
6918                                 CHECK_BYTE_COUNT(pwlen);
6919                                 proto_tree_add_item(tree, hf_smb_password,
6920                                         tvb, offset, pwlen, TRUE);
6921                                 COUNT_BYTES(pwlen);
6922                         }
6923
6924                         break;
6925
6926                 case 13:
6927                         if(apwlen){
6928                                 /* password, ANSI */
6929                                 CHECK_BYTE_COUNT(apwlen);
6930                                 proto_tree_add_item(tree, hf_smb_ansi_password,
6931                                         tvb, offset, apwlen, TRUE);
6932                                 COUNT_BYTES(apwlen);
6933                         }
6934
6935                         if(upwlen){
6936                                 proto_item *item;
6937
6938                                 /* password, Unicode */
6939                                 CHECK_BYTE_COUNT(upwlen);
6940                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
6941                                         tvb, offset, upwlen, TRUE);
6942
6943                                 if (upwlen > 24) {
6944                                         proto_tree *subtree;
6945
6946                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
6947
6948                                         dissect_ntlmv2_response(
6949                                                 tvb, subtree, offset, upwlen);
6950                                 }
6951
6952                                 COUNT_BYTES(upwlen);
6953                         }
6954
6955                         break;
6956                 }
6957
6958                 /* Account Name */
6959                 an = get_unicode_or_ascii_string(tvb, &offset,
6960                         si->unicode, &an_len, FALSE, FALSE, &bc);
6961                 if (an == NULL)
6962                         goto endofcommand;
6963                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
6964                         an);
6965                 COUNT_BYTES(an_len);
6966
6967                 /* Primary domain */
6968                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6969                  * byte in front of this, at least if all the strings are
6970                  * ASCII and the account name is empty. Another bug?
6971                  */
6972                 dn = get_unicode_or_ascii_string(tvb, &offset,
6973                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6974                 if (dn == NULL)
6975                         goto endofcommand;
6976                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6977                         offset, dn_len, dn);
6978                 COUNT_BYTES(dn_len);
6979
6980                 if (check_col(pinfo->cinfo, COL_INFO)) {
6981                         col_append_str(pinfo->cinfo, COL_INFO, ", User: ");
6982
6983                         if (!dn[0] && !an[0])
6984                                 col_append_str(pinfo->cinfo, COL_INFO,
6985                                                 "anonymous");
6986                         else
6987                                 col_append_fstr(pinfo->cinfo, COL_INFO,
6988                                                 "%s\\%s",
6989                                                 format_text(dn, strlen(dn)),
6990                                                 format_text(an, strlen(an)));
6991                 }
6992
6993                 /* OS */
6994                 an = get_unicode_or_ascii_string(tvb, &offset,
6995                         si->unicode, &an_len, FALSE, FALSE, &bc);
6996                 if (an == NULL)
6997                         goto endofcommand;
6998                 proto_tree_add_string(tree, hf_smb_os, tvb,
6999                         offset, an_len, an);
7000                 COUNT_BYTES(an_len);
7001
7002                 /* LANMAN */
7003                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7004                  * padding/null string/whatever in front of this. W2K doesn't
7005                  * appear to. I suspect that's a bug that got fixed; I also
7006                  * suspect that, in practice, nobody ever looks at that field
7007                  * because the bug didn't appear to get fixed until NT 5.0....
7008                  */
7009                 an = get_unicode_or_ascii_string(tvb, &offset,
7010                         si->unicode, &an_len, FALSE, FALSE, &bc);
7011                 if (an == NULL)
7012                         goto endofcommand;
7013                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
7014                         offset, an_len, an);
7015                 COUNT_BYTES(an_len);
7016         }
7017
7018         END_OF_SMB
7019
7020         if (cmd != 0xff) {      /* there is an andX command */
7021                 if (andxoffset < offset)
7022                         THROW(ReportedBoundsError);
7023                 pinfo->private_data = si;
7024                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7025         }
7026
7027         return offset;
7028 }
7029
7030 static int
7031 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7032 {
7033         guint8  wc, cmd=0xff;
7034         guint16 andxoffset=0, bc;
7035         guint16 sbloblen=0;
7036         smb_info_t *si = pinfo->private_data;
7037         int an_len;
7038         const char *an;
7039
7040         DISSECTOR_ASSERT(si);
7041
7042         WORD_COUNT;
7043
7044         if(!pinfo->fd->flags.visited && si->sip && si->sip->extra_info &&
7045             si->sip->extra_info_type==SMB_EI_UID){
7046                 smb_uid_t *smb_uid;
7047
7048                 smb_uid=si->sip->extra_info;
7049                 smb_uid->logged_in=pinfo->fd->num;
7050                 se_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
7051         }
7052
7053         /* next smb command */
7054         cmd = tvb_get_guint8(tvb, offset);
7055         if(cmd!=0xff){
7056                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7057         } else {
7058                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7059         }
7060         offset += 1;
7061
7062         /* reserved byte */
7063         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7064         offset += 1;
7065
7066         /* andxoffset */
7067         andxoffset = tvb_get_letohs(tvb, offset);
7068         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7069         offset += 2;
7070
7071         /* flags */
7072         offset = dissect_setup_action(tvb, tree, offset);
7073
7074         if(wc==4){
7075                 /* security blob length */
7076                 sbloblen = tvb_get_letohs(tvb, offset);
7077                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7078                 offset += 2;
7079         }
7080
7081         BYTE_COUNT;
7082
7083         if(wc==4) {
7084                 proto_item *blob_item;
7085
7086                 /* security blob */
7087                 /* dont try to eat too much of we might get an exception on
7088                  * short frames and then we will not see anything at all
7089                  * of the security blob.
7090                  */
7091                 if(sbloblen>tvb_length_remaining(tvb,offset)){
7092                         sbloblen=tvb_length_remaining(tvb,offset);
7093                 }
7094                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7095                                                 tvb, offset, sbloblen, TRUE);
7096
7097                 if(sbloblen){
7098                         tvbuff_t *blob_tvb;
7099                         proto_tree *blob_tree;
7100
7101                         blob_tree = proto_item_add_subtree(blob_item,
7102                                                            ett_smb_secblob);
7103                         CHECK_BYTE_COUNT(sbloblen);
7104
7105                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen,
7106                                                     sbloblen);
7107
7108                         if (si && si->ct && si->ct->raw_ntlmssp &&
7109                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
7110                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7111                                          blob_tree);
7112
7113                         }
7114                         else {
7115                           call_dissector(gssapi_handle, blob_tvb, pinfo,
7116                                          blob_tree);
7117
7118                         }
7119
7120                         COUNT_BYTES(sbloblen);
7121                 }
7122         }
7123
7124         /* OS */
7125         an = get_unicode_or_ascii_string(tvb, &offset,
7126                 si->unicode, &an_len, FALSE, FALSE, &bc);
7127         if (an == NULL)
7128                 goto endofcommand;
7129         proto_tree_add_string(tree, hf_smb_os, tvb,
7130                 offset, an_len, an);
7131         COUNT_BYTES(an_len);
7132
7133         /* LANMAN */
7134         an = get_unicode_or_ascii_string(tvb, &offset,
7135                 si->unicode, &an_len, FALSE, FALSE, &bc);
7136         if (an == NULL)
7137                 goto endofcommand;
7138         proto_tree_add_string(tree, hf_smb_lanman, tvb,
7139                 offset, an_len, an);
7140         COUNT_BYTES(an_len);
7141
7142         if((wc==3)||(wc==4)) {
7143                 /* Primary domain */
7144                 an = get_unicode_or_ascii_string(tvb, &offset,
7145                         si->unicode, &an_len, FALSE, FALSE, &bc);
7146                 if (an == NULL)
7147                         goto endofcommand;
7148                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7149                         offset, an_len, an);
7150                 COUNT_BYTES(an_len);
7151         }
7152
7153         END_OF_SMB
7154
7155         if (cmd != 0xff) {      /* there is an andX command */
7156                 if (andxoffset < offset)
7157                         THROW(ReportedBoundsError);
7158                 pinfo->private_data = si;
7159                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7160         }
7161
7162         return offset;
7163 }
7164
7165
7166 static int
7167 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7168 {
7169         guint8  wc, cmd=0xff;
7170         guint16 andxoffset=0;
7171         guint16 bc;
7172
7173         WORD_COUNT;
7174
7175         /* next smb command */
7176         cmd = tvb_get_guint8(tvb, offset);
7177         if(cmd!=0xff){
7178                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7179         } else {
7180                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7181         }
7182         offset += 1;
7183
7184         /* reserved byte */
7185         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7186         offset += 1;
7187
7188         /* andxoffset */
7189         andxoffset = tvb_get_letohs(tvb, offset);
7190         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7191         offset += 2;
7192
7193         BYTE_COUNT;
7194
7195         END_OF_SMB
7196
7197         if (cmd != 0xff) {      /* there is an andX command */
7198                 if (andxoffset < offset)
7199                         THROW(ReportedBoundsError);
7200                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7201         }
7202
7203         return offset;
7204 }
7205
7206
7207 static const true_false_string tfs_connect_support_search = {
7208         "Exclusive search bits supported",
7209         "Exclusive search bits not supported"
7210 };
7211 static const true_false_string tfs_connect_support_in_dfs = {
7212         "Share is in Dfs",
7213         "Share isn't in Dfs"
7214 };
7215
7216 static int
7217 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7218 {
7219         guint16 mask;
7220         proto_item *item;
7221         proto_tree *tree;
7222
7223         mask = tvb_get_letohs(tvb, offset);
7224
7225         if(parent_tree){
7226                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7227                         "Optional Support: 0x%04x", mask);
7228                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
7229
7230                 proto_tree_add_boolean(tree, hf_smb_connect_support_search,
7231                         tvb, offset, 2, mask);
7232                 proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
7233                         tvb, offset, 2, mask);
7234         }
7235
7236         offset += 2;
7237
7238         return offset;
7239 }
7240
7241 static const true_false_string tfs_disconnect_tid = {
7242         "DISCONNECT TID",
7243         "Do NOT disconnect TID"
7244 };
7245
7246 static int
7247 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7248 {
7249         guint16 mask;
7250         proto_item *item;
7251         proto_tree *tree;
7252
7253         mask = tvb_get_letohs(tvb, offset);
7254
7255         if(parent_tree){
7256                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7257                         "Flags: 0x%04x", mask);
7258                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
7259
7260                 proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
7261                         tvb, offset, 2, mask);
7262         }
7263
7264         offset += 2;
7265
7266         return offset;
7267 }
7268
7269 static int
7270 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7271 {
7272         guint8  wc, cmd=0xff;
7273         guint16 bc;
7274         guint16 andxoffset=0, pwlen=0;
7275         smb_info_t *si = pinfo->private_data;
7276         int an_len;
7277         const char *an;
7278
7279         DISSECTOR_ASSERT(si);
7280
7281         WORD_COUNT;
7282
7283         /* next smb command */
7284         cmd = tvb_get_guint8(tvb, offset);
7285         if(cmd!=0xff){
7286                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7287         } else {
7288                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7289         }
7290         offset += 1;
7291
7292         /* reserved byte */
7293         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7294         offset += 1;
7295
7296         /* andxoffset */
7297         andxoffset = tvb_get_letohs(tvb, offset);
7298         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7299         offset += 2;
7300
7301         /* flags */
7302         offset = dissect_connect_flags(tvb, tree, offset);
7303
7304         /* password length*/
7305         pwlen = tvb_get_letohs(tvb, offset);
7306         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
7307         offset += 2;
7308
7309         BYTE_COUNT;
7310
7311         /* password */
7312         CHECK_BYTE_COUNT(pwlen);
7313         proto_tree_add_item(tree, hf_smb_password,
7314                 tvb, offset, pwlen, TRUE);
7315         COUNT_BYTES(pwlen);
7316
7317         /* Path */
7318         an = get_unicode_or_ascii_string(tvb, &offset,
7319                 si->unicode, &an_len, FALSE, FALSE, &bc);
7320         if (an == NULL)
7321                 goto endofcommand;
7322         proto_tree_add_string(tree, hf_smb_path, tvb,
7323                 offset, an_len, an);
7324         COUNT_BYTES(an_len);
7325
7326         /* store it for the tid->name/openframe/closeframe matching in
7327          * dissect_smb_tid()   called from the response.
7328          */
7329         if((!pinfo->fd->flags.visited) && si->sip && an){
7330                 si->sip->extra_info_type=SMB_EI_TIDNAME;
7331                 si->sip->extra_info=se_strdup(an);
7332         }
7333
7334         if (check_col(pinfo->cinfo, COL_INFO)) {
7335                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
7336                     format_text(an, strlen(an)));
7337         }
7338
7339         /*
7340          * NOTE: the Service string is always ASCII, even if the
7341          * "strings are Unicode" bit is set in the flags2 field
7342          * of the SMB.
7343          */
7344
7345         /* Service */
7346         /* XXX - what if this runs past bc? */
7347         an_len = tvb_strsize(tvb, offset);
7348         CHECK_BYTE_COUNT(an_len);
7349         an = tvb_get_ptr(tvb, offset, an_len);
7350         proto_tree_add_string(tree, hf_smb_service, tvb,
7351                 offset, an_len, an);
7352         COUNT_BYTES(an_len);
7353
7354         END_OF_SMB
7355
7356         if (cmd != 0xff) {      /* there is an andX command */
7357                 if (andxoffset < offset)
7358                         THROW(ReportedBoundsError);
7359                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7360         }
7361
7362         return offset;
7363 }
7364
7365
7366 static int
7367 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7368 {
7369         guint8  wc, wleft, cmd=0xff;
7370         guint16 andxoffset=0;
7371         guint16 bc;
7372         int an_len;
7373         const char *an;
7374         smb_info_t *si = pinfo->private_data;
7375
7376         DISSECTOR_ASSERT(si);
7377
7378         WORD_COUNT;
7379
7380         wleft = wc;     /* this is at least 1 */
7381
7382         /* next smb command */
7383         cmd = tvb_get_guint8(tvb, offset);
7384         if(cmd!=0xff){
7385                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7386         } else {
7387                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7388         }
7389         offset += 1;
7390
7391         /* reserved byte */
7392         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7393         offset += 1;
7394
7395         wleft--;
7396         if (wleft == 0)
7397                 goto bytecount;
7398
7399         /* andxoffset */
7400         andxoffset = tvb_get_letohs(tvb, offset);
7401         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7402         offset += 2;
7403         wleft--;
7404         if (wleft == 0)
7405                 goto bytecount;
7406
7407         /* flags */
7408         offset = dissect_connect_support_bits(tvb, tree, offset);
7409         wleft--;
7410
7411         /* XXX - I've seen captures where this is 7, but I have no
7412            idea how to dissect it.  I'm guessing the third word
7413            contains connect support bits, which looks plausible
7414            from the values I've seen. */
7415
7416         while (wleft != 0) {
7417                 proto_tree_add_text(tree, tvb, offset, 2,
7418                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
7419                 offset += 2;
7420                 wleft--;
7421         }
7422
7423         BYTE_COUNT;
7424
7425         /*
7426          * NOTE: even though the SNIA CIFS spec doesn't say there's
7427          * a "Service" string if there's a word count of 2, the
7428          * document at
7429          *
7430          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
7431          *
7432          * (it's in an ugly format - text intended to be sent to a
7433          * printer, with backspaces and overstrikes used for boldfacing
7434          * and underlining; UNIX "col -b" can be used to strip the
7435          * overstrikes out) says there's a "Service" string there, and
7436          * some network traffic has it.
7437          */
7438
7439         /*
7440          * NOTE: the Service string is always ASCII, even if the
7441          * "strings are Unicode" bit is set in the flags2 field
7442          * of the SMB.
7443          */
7444
7445         /* Service */
7446         /* XXX - what if this runs past bc? */
7447         an_len = tvb_strsize(tvb, offset);
7448         CHECK_BYTE_COUNT(an_len);
7449         an = tvb_get_ptr(tvb, offset, an_len);
7450         proto_tree_add_string(tree, hf_smb_service, tvb,
7451                 offset, an_len, an);
7452         COUNT_BYTES(an_len);
7453
7454         /* Now when we know the service type, store it so that we know it for later commands down
7455            this tree */
7456         if(!pinfo->fd->flags.visited){
7457                 /* Remove any previous entry for this TID */
7458                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
7459                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
7460                 }
7461                 if(strcmp(an,"IPC") == 0){
7462                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
7463                 } else {
7464                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_NORMAL);
7465                 }
7466         }
7467
7468
7469         if(wc==3){
7470                 if (bc != 0) {
7471                         /*
7472                          * Sometimes this isn't present.
7473                          */
7474
7475                         /* Native FS */
7476                         an = get_unicode_or_ascii_string(tvb, &offset,
7477                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
7478                                 &bc);
7479                         if (an == NULL)
7480                                 goto endofcommand;
7481                         proto_tree_add_string(tree, hf_smb_fs, tvb,
7482                                 offset, an_len, an);
7483                         COUNT_BYTES(an_len);
7484                 }
7485         }
7486
7487         END_OF_SMB
7488
7489         if (cmd != 0xff) {      /* there is an andX command */
7490                 if (andxoffset < offset)
7491                         THROW(ReportedBoundsError);
7492                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7493         }
7494
7495         return offset;
7496 }
7497
7498
7499
7500 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7501    NT Transaction command  begins here
7502    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7503 #define NT_TRANS_CREATE         1
7504 #define NT_TRANS_IOCTL          2
7505 #define NT_TRANS_SSD            3
7506 #define NT_TRANS_NOTIFY         4
7507 #define NT_TRANS_RENAME         5
7508 #define NT_TRANS_QSD            6
7509 #define NT_TRANS_GET_USER_QUOTA 7
7510 #define NT_TRANS_SET_USER_QUOTA 8
7511 const value_string nt_cmd_vals[] = {
7512         {NT_TRANS_CREATE,               "NT CREATE"},
7513         {NT_TRANS_IOCTL,                "NT IOCTL"},
7514         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
7515         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
7516         {NT_TRANS_RENAME,               "NT RENAME"},
7517         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
7518         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
7519         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
7520         {0, NULL}
7521 };
7522
7523 static const value_string nt_ioctl_isfsctl_vals[] = {
7524         {0,     "Device IOCTL"},
7525         {1,     "FS control : FSCTL"},
7526         {0, NULL}
7527 };
7528
7529 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
7530 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
7531         "Apply the command to share root handle (MUST BE Dfs)",
7532         "Apply to this share",
7533 };
7534
7535 static const value_string nt_notify_action_vals[] = {
7536         {1,     "ADDED (object was added"},
7537         {2,     "REMOVED (object was removed)"},
7538         {3,     "MODIFIED (object was modified)"},
7539         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
7540         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
7541         {6,     "ADDED_STREAM (a stream was added)"},
7542         {7,     "REMOVED_STREAM (a stream was removed)"},
7543         {8,     "MODIFIED_STREAM (a stream was modified)"},
7544         {0, NULL}
7545 };
7546
7547 static const value_string watch_tree_vals[] = {
7548         {0,     "Current directory only"},
7549         {1,     "Subdirectories also"},
7550         {0, NULL}
7551 };
7552
7553 #define NT_NOTIFY_STREAM_WRITE  0x00000800
7554 #define NT_NOTIFY_STREAM_SIZE   0x00000400
7555 #define NT_NOTIFY_STREAM_NAME   0x00000200
7556 #define NT_NOTIFY_SECURITY      0x00000100
7557 #define NT_NOTIFY_EA            0x00000080
7558 #define NT_NOTIFY_CREATION      0x00000040
7559 #define NT_NOTIFY_LAST_ACCESS   0x00000020
7560 #define NT_NOTIFY_LAST_WRITE    0x00000010
7561 #define NT_NOTIFY_SIZE          0x00000008
7562 #define NT_NOTIFY_ATTRIBUTES    0x00000004
7563 #define NT_NOTIFY_DIR_NAME      0x00000002
7564 #define NT_NOTIFY_FILE_NAME     0x00000001
7565 static const true_false_string tfs_nt_notify_stream_write = {
7566         "Notify on changes to STREAM WRITE",
7567         "Do NOT notify on changes to stream write",
7568 };
7569 static const true_false_string tfs_nt_notify_stream_size = {
7570         "Notify on changes to STREAM SIZE",
7571         "Do NOT notify on changes to stream size",
7572 };
7573 static const true_false_string tfs_nt_notify_stream_name = {
7574         "Notify on changes to STREAM NAME",
7575         "Do NOT notify on changes to stream name",
7576 };
7577 static const true_false_string tfs_nt_notify_security = {
7578         "Notify on changes to SECURITY",
7579         "Do NOT notify on changes to security",
7580 };
7581 static const true_false_string tfs_nt_notify_ea = {
7582         "Notify on changes to EA",
7583         "Do NOT notify on changes to EA",
7584 };
7585 static const true_false_string tfs_nt_notify_creation = {
7586         "Notify on changes to CREATION TIME",
7587         "Do NOT notify on changes to creation time",
7588 };
7589 static const true_false_string tfs_nt_notify_last_access = {
7590         "Notify on changes to LAST ACCESS TIME",
7591         "Do NOT notify on changes to last access time",
7592 };
7593 static const true_false_string tfs_nt_notify_last_write = {
7594         "Notify on changes to LAST WRITE TIME",
7595         "Do NOT notify on changes to last write time",
7596 };
7597 static const true_false_string tfs_nt_notify_size = {
7598         "Notify on changes to SIZE",
7599         "Do NOT notify on changes to size",
7600 };
7601 static const true_false_string tfs_nt_notify_attributes = {
7602         "Notify on changes to ATTRIBUTES",
7603         "Do NOT notify on changes to attributes",
7604 };
7605 static const true_false_string tfs_nt_notify_dir_name = {
7606         "Notify on changes to DIR NAME",
7607         "Do NOT notify on changes to dir name",
7608 };
7609 static const true_false_string tfs_nt_notify_file_name = {
7610         "Notify on changes to FILE NAME",
7611         "Do NOT notify on changes to file name",
7612 };
7613
7614 const value_string create_disposition_vals[] = {
7615         {0,     "Supersede (supersede existing file (if it exists))"},
7616         {1,     "Open (if file exists open it, else fail)"},
7617         {2,     "Create (if file exists fail, else create it)"},
7618         {3,     "Open If (if file exists open it, else create it)"},
7619         {4,     "Overwrite (if file exists overwrite, else fail)"},
7620         {5,     "Overwrite If (if file exists overwrite, else create it)"},
7621         {0, NULL}
7622 };
7623
7624 const value_string impersonation_level_vals[] = {
7625         {0,     "Anonymous"},
7626         {1,     "Identification"},
7627         {2,     "Impersonation"},
7628         {3,     "Delegation"},
7629         {0, NULL}
7630 };
7631
7632 static const true_false_string tfs_nt_security_flags_context_tracking = {
7633         "Security tracking mode is DYNAMIC",
7634         "Security tracking mode is STATIC",
7635 };
7636
7637 static const true_false_string tfs_nt_security_flags_effective_only = {
7638         "ONLY ENABLED aspects of the client's security context are available",
7639         "ALL aspects of the client's security context are available",
7640 };
7641
7642 static const true_false_string tfs_nt_create_bits_oplock = {
7643         "Requesting OPLOCK",
7644         "Does NOT request oplock"
7645 };
7646
7647 static const true_false_string tfs_nt_create_bits_boplock = {
7648         "Requesting BATCH OPLOCK",
7649         "Does NOT request batch oplock"
7650 };
7651
7652 /*
7653  * XXX - must be a directory, and can be a file, or can be a directory,
7654  * and must be a file?
7655  */
7656 static const true_false_string tfs_nt_create_bits_dir = {
7657         "Target of open MUST be a DIRECTORY",
7658         "Target of open can be a file"
7659 };
7660
7661 static const true_false_string tfs_nt_create_bits_ext_resp = {
7662   "Extended responses required",
7663   "Extended responses NOT required"
7664 };
7665
7666 static const true_false_string tfs_nt_access_mask_generic_read = {
7667         "GENERIC READ is set",
7668         "Generic read is NOT set"
7669 };
7670 static const true_false_string tfs_nt_access_mask_generic_write = {
7671         "GENERIC WRITE is set",
7672         "Generic write is NOT set"
7673 };
7674 static const true_false_string tfs_nt_access_mask_generic_execute = {
7675         "GENERIC EXECUTE is set",
7676         "Generic execute is NOT set"
7677 };
7678 static const true_false_string tfs_nt_access_mask_generic_all = {
7679         "GENERIC ALL is set",
7680         "Generic all is NOT set"
7681 };
7682 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
7683         "MAXIMUM ALLOWED is set",
7684         "Maximum allowed is NOT set"
7685 };
7686 static const true_false_string tfs_nt_access_mask_system_security = {
7687         "SYSTEM SECURITY is set",
7688         "System security is NOT set"
7689 };
7690 static const true_false_string tfs_nt_access_mask_synchronize = {
7691         "Can wait on handle to SYNCHRONIZE on completion of I/O",
7692         "Can NOT wait on handle to synchronize on completion of I/O"
7693 };
7694 static const true_false_string tfs_nt_access_mask_write_owner = {
7695         "Can WRITE OWNER (take ownership)",
7696         "Can NOT write owner (take ownership)"
7697 };
7698 static const true_false_string tfs_nt_access_mask_write_dac = {
7699         "OWNER may WRITE the DAC",
7700         "Owner may NOT write to the DAC"
7701 };
7702 static const true_false_string tfs_nt_access_mask_read_control = {
7703         "READ ACCESS to owner, group and ACL of the SID",
7704         "Read access is NOT granted to owner, group and ACL of the SID"
7705 };
7706 static const true_false_string tfs_nt_access_mask_delete = {
7707         "DELETE access",
7708         "NO delete access"
7709 };
7710 static const true_false_string tfs_nt_access_mask_write_attributes = {
7711         "WRITE ATTRIBUTES access",
7712         "NO write attributes access"
7713 };
7714 static const true_false_string tfs_nt_access_mask_read_attributes = {
7715         "READ ATTRIBUTES access",
7716         "NO read attributes access"
7717 };
7718 static const true_false_string tfs_nt_access_mask_delete_child = {
7719         "DELETE CHILD access",
7720         "NO delete child access"
7721 };
7722 static const true_false_string tfs_nt_access_mask_execute = {
7723         "EXECUTE access",
7724         "NO execute access"
7725 };
7726 static const true_false_string tfs_nt_access_mask_write_ea = {
7727         "WRITE EXTENDED ATTRIBUTES access",
7728         "NO write extended attributes access"
7729 };
7730 static const true_false_string tfs_nt_access_mask_read_ea = {
7731         "READ EXTENDED ATTRIBUTES access",
7732         "NO read extended attributes access"
7733 };
7734 static const true_false_string tfs_nt_access_mask_append = {
7735         "APPEND access",
7736         "NO append access"
7737 };
7738 static const true_false_string tfs_nt_access_mask_write = {
7739         "WRITE access",
7740         "NO write access"
7741 };
7742 static const true_false_string tfs_nt_access_mask_read = {
7743         "READ access",
7744         "NO read access"
7745 };
7746
7747 static const true_false_string tfs_nt_share_access_delete = {
7748         "Object can be shared for DELETE",
7749         "Object can NOT be shared for delete"
7750 };
7751 static const true_false_string tfs_nt_share_access_write = {
7752         "Object can be shared for WRITE",
7753         "Object can NOT be shared for write"
7754 };
7755 static const true_false_string tfs_nt_share_access_read = {
7756         "Object can be shared for READ",
7757         "Object can NOT be shared for read"
7758 };
7759
7760 static const value_string oplock_level_vals[] = {
7761         {0,     "No oplock granted"},
7762         {1,     "Exclusive oplock granted"},
7763         {2,     "Batch oplock granted"},
7764         {3,     "Level II oplock granted"},
7765         {0, NULL}
7766 };
7767
7768 static const value_string device_type_vals[] = {
7769         {0x00000001,    "Beep"},
7770         {0x00000002,    "CDROM"},
7771         {0x00000003,    "CDROM Filesystem"},
7772         {0x00000004,    "Controller"},
7773         {0x00000005,    "Datalink"},
7774         {0x00000006,    "Dfs"},
7775         {0x00000007,    "Disk"},
7776         {0x00000008,    "Disk Filesystem"},
7777         {0x00000009,    "Filesystem"},
7778         {0x0000000a,    "Inport Port"},
7779         {0x0000000b,    "Keyboard"},
7780         {0x0000000c,    "Mailslot"},
7781         {0x0000000d,    "MIDI-In"},
7782         {0x0000000e,    "MIDI-Out"},
7783         {0x0000000f,    "Mouse"},
7784         {0x00000010,    "Multi UNC Provider"},
7785         {0x00000011,    "Named Pipe"},
7786         {0x00000012,    "Network"},
7787         {0x00000013,    "Network Browser"},
7788         {0x00000014,    "Network Filesystem"},
7789         {0x00000015,    "NULL"},
7790         {0x00000016,    "Parallel Port"},
7791         {0x00000017,    "Physical card"},
7792         {0x00000018,    "Printer"},
7793         {0x00000019,    "Scanner"},
7794         {0x0000001a,    "Serial Mouse port"},
7795         {0x0000001b,    "Serial port"},
7796         {0x0000001c,    "Screen"},
7797         {0x0000001d,    "Sound"},
7798         {0x0000001e,    "Streams"},
7799         {0x0000001f,    "Tape"},
7800         {0x00000020,    "Tape Filesystem"},
7801         {0x00000021,    "Transport"},
7802         {0x00000022,    "Unknown"},
7803         {0x00000023,    "Video"},
7804         {0x00000024,    "Virtual Disk"},
7805         {0x00000025,    "WAVE-In"},
7806         {0x00000026,    "WAVE-Out"},
7807         {0x00000027,    "8042 Port"},
7808         {0x00000028,    "Network Redirector"},
7809         {0x00000029,    "Battery"},
7810         {0x0000002a,    "Bus Extender"},
7811         {0x0000002b,    "Modem"},
7812         {0x0000002c,    "VDM"},
7813         {0,     NULL}
7814 };
7815
7816 static const value_string is_directory_vals[] = {
7817         {0,     "This is NOT a directory"},
7818         {1,     "This is a DIRECTORY"},
7819         {0, NULL}
7820 };
7821
7822 typedef struct _nt_trans_data {
7823         int subcmd;
7824         guint32 sd_len;
7825         guint32 ea_len;
7826 } nt_trans_data;
7827
7828
7829
7830 static int
7831 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7832 {
7833         guint8 mask;
7834         proto_item *item;
7835         proto_tree *tree;
7836
7837         mask = tvb_get_guint8(tvb, offset);
7838
7839         if(parent_tree){
7840                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7841                         "Security Flags: 0x%02x", mask);
7842                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
7843
7844                 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
7845                         tvb, offset, 1, mask);
7846                 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
7847                         tvb, offset, 1, mask);
7848         }
7849
7850         offset += 1;
7851
7852         return offset;
7853 }
7854
7855 /*
7856  * XXX - there are some more flags in the description of "ZwOpenFile()"
7857  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
7858  * the wire as well?  (The spec at
7859  *
7860  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
7861  *
7862  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
7863  * via the SMB protocol.  The NT redirector should convert this option
7864  * to FILE_WRITE_THROUGH."
7865  *
7866  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
7867  * values one would infer from their position in the list of flags for
7868  * "ZwOpenFile()".  Most of the others probably have those values
7869  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
7870  * which might go over the wire (for the benefit of backup/restore software).
7871  */
7872 static const true_false_string tfs_nt_create_options_directory = {
7873         "File being created/opened must be a directory",
7874         "File being created/opened must not be a directory"
7875 };
7876 static const true_false_string tfs_nt_create_options_write_through = {
7877         "Writes should flush buffered data before completing",
7878         "Writes need not flush buffered data before completing"
7879 };
7880 static const true_false_string tfs_nt_create_options_sequential_only = {
7881         "The file will only be accessed sequentially",
7882         "The file might not only be accessed sequentially"
7883 };
7884 static const true_false_string tfs_nt_create_options_no_intermediate_buffering = {
7885         "NO intermediate buffering is allowed",
7886         "Intermediate buffering is allowed"
7887 };
7888 static const true_false_string tfs_nt_create_options_sync_io_alert = {
7889         "All operations SYNCHRONOUS, waits subject to termination from alert",
7890         "Operations NOT necessarily synchronous"
7891 };
7892 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
7893         "All operations SYNCHRONOUS, waits not subject to alert",
7894         "Operations NOT necessarily synchronous"
7895 };
7896 static const true_false_string tfs_nt_create_options_non_directory = {
7897         "File being created/opened must not be a directory",
7898         "File being created/opened must be a directory"
7899 };
7900 static const true_false_string tfs_nt_create_options_create_tree_connection = {
7901         "Create Tree Connections is SET",
7902         "Create Tree Connections is NOT set"
7903 };
7904 static const true_false_string tfs_nt_create_options_complete_if_oplocked = {
7905         "Complete if oplocked is SET",
7906         "Complete if oplocked is NOT set"
7907 };
7908 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
7909         "The client does not understand extended attributes",
7910         "The client understands extended attributes"
7911 };
7912 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
7913         "The client understands only 8.3 file names",
7914         "The client understands long file names"
7915 };
7916 static const true_false_string tfs_nt_create_options_random_access = {
7917         "The file will be accessed randomly",
7918         "The file will not be accessed randomly"
7919 };
7920 static const true_false_string tfs_nt_create_options_delete_on_close = {
7921         "The file should be deleted when it is closed",
7922         "The file should not be deleted when it is closed"
7923 };
7924 static const true_false_string tfs_nt_create_options_open_by_fileid = {
7925         "OpenByFileID bit is SET",
7926         "OpenByFileID is NOT set"
7927 };
7928 static const true_false_string tfs_nt_create_options_backup_intent = {
7929         "This is a create with BACKUP INTENT",
7930         "This is a normal create"
7931 };
7932 static const true_false_string tfs_nt_create_options_no_compression = {
7933         "Open/Create with NO Compression",
7934         "Compression is allowed for Open/Create"
7935 };
7936 static const true_false_string tfs_nt_create_options_reserve_opfilter = {
7937         "Reserve Opfilter is SET",
7938         "Reserve Opfilter is NOT set"
7939 };
7940 static const true_false_string tfs_nt_create_options_open_reparse_point = {
7941         "Open a Reparse Point",
7942         "Normal open"
7943 };
7944 static const true_false_string tfs_nt_create_options_open_no_recall = {
7945         "Open No Recall is SET",
7946         "Open no recall is NOT set"
7947 };
7948 static const true_false_string tfs_nt_create_options_open_for_free_space_query = {
7949         "This is an OPEN FOR FREE SPACE QUERY",
7950         "This is NOT an open for free space query"
7951 };
7952
7953 int
7954 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7955 {
7956         guint32 mask;
7957         proto_item *item;
7958         proto_tree *tree;
7959
7960         mask = tvb_get_letohl(tvb, offset);
7961
7962         if(parent_tree){
7963                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7964                         "Completion Filter: 0x%08x", mask);
7965                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7966
7967                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7968                         tvb, offset, 4, mask);
7969                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7970                         tvb, offset, 4, mask);
7971                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7972                         tvb, offset, 4, mask);
7973                 proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7974                         tvb, offset, 4, mask);
7975                 proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7976                         tvb, offset, 4, mask);
7977                 proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7978                         tvb, offset, 4, mask);
7979                 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7980                         tvb, offset, 4, mask);
7981                 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7982                         tvb, offset, 4, mask);
7983                 proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7984                         tvb, offset, 4, mask);
7985                 proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7986                         tvb, offset, 4, mask);
7987                 proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7988                         tvb, offset, 4, mask);
7989                 proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7990                         tvb, offset, 4, mask);
7991         }
7992
7993         offset += 4;
7994         return offset;
7995 }
7996
7997 static int
7998 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7999 {
8000         guint8 mask;
8001         proto_item *item;
8002         proto_tree *tree;
8003
8004         mask = tvb_get_guint8(tvb, offset);
8005
8006         if(parent_tree){
8007                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
8008                         "Completion Filter: 0x%02x", mask);
8009                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
8010
8011                 proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
8012                         tvb, offset, 1, mask);
8013         }
8014
8015         offset += 1;
8016         return offset;
8017 }
8018
8019 /*
8020  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
8021  * Native API Reference".
8022  */
8023 static const true_false_string tfs_nt_qsd_owner = {
8024         "Requesting OWNER security information",
8025         "NOT requesting owner security information",
8026 };
8027
8028 static const true_false_string tfs_nt_qsd_group = {
8029         "Requesting GROUP security information",
8030         "NOT requesting group security information",
8031 };
8032
8033 static const true_false_string tfs_nt_qsd_dacl = {
8034         "Requesting DACL security information",
8035         "NOT requesting DACL security information",
8036 };
8037
8038 static const true_false_string tfs_nt_qsd_sacl = {
8039         "Requesting SACL security information",
8040         "NOT requesting SACL security information",
8041 };
8042
8043 #define NT_QSD_OWNER    0x00000001
8044 #define NT_QSD_GROUP    0x00000002
8045 #define NT_QSD_DACL     0x00000004
8046 #define NT_QSD_SACL     0x00000008
8047
8048 int
8049 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8050 {
8051         guint32 mask;
8052         proto_item *item;
8053         proto_tree *tree;
8054
8055         mask = tvb_get_letohl(tvb, offset);
8056
8057         if(parent_tree){
8058                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
8059                         "Security Information: 0x%08x", mask);
8060                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
8061
8062                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
8063                         tvb, offset, 4, mask);
8064                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
8065                         tvb, offset, 4, mask);
8066                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
8067                         tvb, offset, 4, mask);
8068                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
8069                         tvb, offset, 4, mask);
8070         }
8071
8072         offset += 4;
8073
8074         return offset;
8075 }
8076
8077 static int
8078 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
8079 {
8080         int old_offset, old_sid_offset;
8081         guint32 qsize;
8082
8083         do {
8084                 old_offset=offset;
8085
8086                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8087                 qsize=tvb_get_letohl(tvb, offset);
8088                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8089                 COUNT_BYTES_TRANS_SUBR(4);
8090
8091                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8092                 /* length of SID */
8093                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8094                 COUNT_BYTES_TRANS_SUBR(4);
8095
8096                 /* 16 unknown bytes */
8097                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8098                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8099                             offset, 8, TRUE);
8100                 COUNT_BYTES_TRANS_SUBR(8);
8101
8102                 /* number of bytes for used quota */
8103                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8104                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
8105                 COUNT_BYTES_TRANS_SUBR(8);
8106
8107                 /* number of bytes for quota warning */
8108                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8109                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
8110                 COUNT_BYTES_TRANS_SUBR(8);
8111
8112                 /* number of bytes for quota limit */
8113                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8114                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
8115                 COUNT_BYTES_TRANS_SUBR(8);
8116
8117                 /* SID of the user */
8118                 old_sid_offset=offset;
8119                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8120                 *bcp -= (offset-old_sid_offset);
8121
8122                 if(qsize){
8123                         offset = old_offset+qsize;
8124                 }
8125         }while(qsize);
8126
8127
8128         return offset;
8129 }
8130
8131
8132 static int
8133 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd, smb_nt_transact_info_t *nti)
8134 {
8135         proto_item *item = NULL;
8136         proto_tree *tree = NULL;
8137         smb_info_t *si;
8138         int old_offset = offset;
8139         guint16 bcp=bc; /* XXX fixme */
8140         struct access_mask_info *ami=NULL;
8141         tvbuff_t *ioctl_tvb;
8142
8143         si = (smb_info_t *)pinfo->private_data;
8144
8145         DISSECTOR_ASSERT(si);
8146
8147         if(parent_tree){
8148                 tvb_ensure_bytes_exist(tvb, offset, bc);
8149                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8150                                 "%s Data",
8151                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8152                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8153         }
8154
8155         switch(ntd->subcmd){
8156         case NT_TRANS_CREATE:
8157                 /* security descriptor */
8158                 if(ntd->sd_len){
8159                         offset = dissect_nt_sec_desc(
8160                                 tvb, offset, pinfo, tree, NULL, TRUE,
8161                                 ntd->sd_len, NULL);
8162                 }
8163
8164                 /* extended attributes */
8165                 if(ntd->ea_len){
8166                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8167                         offset += ntd->ea_len;
8168                 }
8169
8170                 break;
8171         case NT_TRANS_IOCTL:
8172                 /* ioctl data */
8173                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
8174                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, TRUE);
8175
8176
8177                 offset += bc;
8178
8179                 break;
8180         case NT_TRANS_SSD:
8181                 if(nti){
8182                         switch(nti->fid_type){
8183                         case SMB_FID_TYPE_FILE:
8184                                 ami= &smb_file_access_mask_info;
8185                                 break;
8186                         case SMB_FID_TYPE_DIR:
8187                                 ami= &smb_dir_access_mask_info;
8188                                 break;
8189                         }
8190                 }
8191
8192                 offset = dissect_nt_sec_desc(
8193                         tvb, offset, pinfo, tree, NULL, TRUE, bc, ami);
8194                 break;
8195         case NT_TRANS_NOTIFY:
8196                 break;
8197         case NT_TRANS_RENAME:
8198                 /* XXX not documented */
8199                 break;
8200         case NT_TRANS_QSD:
8201                 break;
8202         case NT_TRANS_GET_USER_QUOTA:
8203                 /* unknown 4 bytes */
8204                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8205                             offset, 4, TRUE);
8206                 offset += 4;
8207
8208                 /* length of SID */
8209                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8210                 offset +=4;
8211
8212                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8213                 break;
8214         case NT_TRANS_SET_USER_QUOTA:
8215                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8216                 break;
8217         }
8218
8219         /* ooops there were data we didnt know how to process */
8220         if((offset-old_offset) < bc){
8221                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8222                     bc - (offset-old_offset), TRUE);
8223                 offset += bc - (offset-old_offset);
8224         }
8225
8226         return offset;
8227 }
8228
8229 static int
8230 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, smb_nt_transact_info_t *nti)
8231 {
8232         proto_item *item = NULL;
8233         proto_tree *tree = NULL;
8234         smb_info_t *si;
8235         guint32 fn_len, create_flags, access_mask, file_attributes, share_access, create_options, create_disposition;
8236         const char *fn;
8237
8238         si = (smb_info_t *)pinfo->private_data;
8239
8240         DISSECTOR_ASSERT(si);
8241
8242         if(parent_tree){
8243                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8244                                 "%s Parameters",
8245                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8246                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8247         }
8248
8249         switch(ntd->subcmd){
8250         case NT_TRANS_CREATE:
8251                 /* Create flags */
8252                 create_flags=tvb_get_letohl(tvb, offset);
8253                 offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
8254                 bc -= 4;
8255
8256                 /* root directory fid */
8257                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8258                 COUNT_BYTES(4);
8259
8260                 /* nt access mask */
8261                 access_mask=tvb_get_letohl(tvb, offset);
8262                 offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
8263                 bc -= 4;
8264
8265                 /* allocation size */
8266                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8267                 COUNT_BYTES(8);
8268
8269                 /* Extended File Attributes */
8270                 file_attributes=tvb_get_letohl(tvb, offset);
8271                 offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
8272                 bc -= 4;
8273
8274                 /* share access */
8275                 share_access=tvb_get_letohl(tvb, offset);
8276                 offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
8277                 bc -= 4;
8278
8279                 /* create disposition */
8280                 create_disposition=tvb_get_letohl(tvb, offset);
8281                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8282                 COUNT_BYTES(4);
8283
8284                 /* create options */
8285                 create_options=tvb_get_letohl(tvb, offset);
8286                 offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
8287                 bc -= 4;
8288
8289                 /* sd length */
8290                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8291                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8292                 COUNT_BYTES(4);
8293
8294                 /* ea length */
8295                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8296                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8297                 COUNT_BYTES(4);
8298
8299                 /* file name len */
8300                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8301                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8302                 COUNT_BYTES(4);
8303
8304                 /* impersonation level */
8305                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8306                 COUNT_BYTES(4);
8307
8308                 /* security flags */
8309                 offset = dissect_nt_security_flags(tvb, tree, offset);
8310                 bc -= 1;
8311
8312                 /* file name */
8313                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8314                 if (fn != NULL) {
8315                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8316                                 fn);
8317                         COUNT_BYTES(fn_len);
8318                 }
8319
8320                 break;
8321         case NT_TRANS_IOCTL:
8322                 break;
8323         case NT_TRANS_SSD: {
8324                 guint16 fid;
8325                 smb_fid_info_t *fid_info;
8326
8327                 /* fid */
8328                 fid = tvb_get_letohs(tvb, offset);
8329                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8330                 offset += 2;
8331                 if(nti){
8332                         if(fid_info){
8333                                 nti->fid_type=fid_info->type;
8334                         } else {
8335                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8336                         }
8337                 }
8338
8339                 /* 2 reserved bytes */
8340                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8341                 offset += 2;
8342
8343                 /* security information */
8344                 offset = dissect_security_information_mask(tvb, tree, offset);
8345                 break;
8346         }
8347         case NT_TRANS_NOTIFY:
8348                 break;
8349         case NT_TRANS_RENAME:
8350                 /* XXX not documented */
8351                 break;
8352         case NT_TRANS_QSD: {
8353                 guint16 fid;
8354                 smb_fid_info_t *fid_info;
8355
8356                 /* fid */
8357                 fid = tvb_get_letohs(tvb, offset);
8358                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8359                 offset += 2;
8360                 if(nti){
8361                         if(fid_info){
8362                                 nti->fid_type=fid_info->type;
8363                         } else {
8364                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8365                         }
8366                 }
8367
8368                 /* 2 reserved bytes */
8369                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8370                 offset += 2;
8371
8372                 /* security information */
8373                 offset = dissect_security_information_mask(tvb, tree, offset);
8374                 break;
8375         }
8376         case NT_TRANS_GET_USER_QUOTA:
8377                 /* not decoded yet */
8378                 break;
8379         case NT_TRANS_SET_USER_QUOTA:
8380                 /* not decoded yet */
8381                 break;
8382         }
8383
8384         return offset;
8385 }
8386
8387 static int
8388 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8389 {
8390         proto_item *item = NULL;
8391         proto_tree *tree = NULL;
8392         int old_offset = offset;
8393         smb_info_t *si;
8394         smb_nt_transact_info_t *nti;
8395         smb_saved_info_t *sip;
8396
8397
8398         si = (smb_info_t *)pinfo->private_data;
8399         DISSECTOR_ASSERT(si);
8400         sip = si->sip;
8401         DISSECTOR_ASSERT(sip);
8402         nti=sip->extra_info;
8403
8404
8405         if(parent_tree){
8406                 tvb_ensure_bytes_exist(tvb, offset, len);
8407                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8408                                 "%s Setup",
8409                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8410                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8411         }
8412
8413         switch(ntd->subcmd){
8414         case NT_TRANS_CREATE:
8415                 break;
8416         case NT_TRANS_IOCTL: {
8417                 guint16 fid;
8418
8419                 /* function code */
8420                 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &nti->ioctl_function);
8421
8422                 /* fid */
8423                 fid = tvb_get_letohs(tvb, offset);
8424                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8425                 offset += 2;
8426
8427                 /* isfsctl */
8428                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8429                 offset += 1;
8430
8431                 /* isflags */
8432                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8433
8434                 break;
8435         }
8436         case NT_TRANS_SSD:
8437                 break;
8438         case NT_TRANS_NOTIFY: {
8439                 guint16 fid;
8440
8441                 /* completion filter */
8442                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8443
8444                 /* fid */
8445                 fid = tvb_get_letohs(tvb, offset);
8446                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8447                 offset += 2;
8448
8449                 /* watch tree */
8450                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8451                 offset += 1;
8452
8453                 /* reserved byte */
8454                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8455                 offset += 1;
8456
8457                 break;
8458         }
8459         case NT_TRANS_RENAME:
8460                 /* XXX not documented */
8461                 break;
8462         case NT_TRANS_QSD:
8463                 break;
8464         case NT_TRANS_GET_USER_QUOTA:
8465                 /* not decoded yet */
8466                 break;
8467         case NT_TRANS_SET_USER_QUOTA:
8468                 /* not decoded yet */
8469                 break;
8470         }
8471
8472         return old_offset+len;
8473 }
8474
8475
8476 static int
8477 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8478 {
8479         guint8 wc, sc;
8480         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8481         smb_info_t *si;
8482         smb_saved_info_t *sip;
8483         int subcmd;
8484         nt_trans_data ntd;
8485         guint16 bc;
8486         guint32 padcnt;
8487         smb_nt_transact_info_t *nti=NULL;
8488
8489         ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
8490
8491         si = (smb_info_t *)pinfo->private_data;
8492         DISSECTOR_ASSERT(si);
8493         sip = si->sip;
8494
8495         WORD_COUNT;
8496
8497         if(wc>=19){
8498                 /* primary request */
8499                 /* max setup count */
8500                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8501                 offset += 1;
8502
8503                 /* 2 reserved bytes */
8504                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8505                 offset += 2;
8506         } else {
8507                 /* secondary request */
8508                 /* 3 reserved bytes */
8509                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8510                 offset += 3;
8511         }
8512
8513
8514         /* total param count */
8515         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8516         offset += 4;
8517
8518         /* total data count */
8519         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8520         offset += 4;
8521
8522         if(wc>=19){
8523                 /* primary request */
8524                 /* max param count */
8525                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8526                 offset += 4;
8527
8528                 /* max data count */
8529                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8530                 offset += 4;
8531         }
8532
8533         /* param count */
8534         pc = tvb_get_letohl(tvb, offset);
8535         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8536         offset += 4;
8537
8538         /* param offset */
8539         po = tvb_get_letohl(tvb, offset);
8540         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8541         offset += 4;
8542
8543         /* param displacement */
8544         if(wc>=19){
8545                 /* primary request*/
8546                 pd = 0;
8547         } else {
8548                 /* secondary request */
8549                 pd = tvb_get_letohl(tvb, offset);
8550                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8551                 offset += 4;
8552         }
8553
8554         /* data count */
8555         dc = tvb_get_letohl(tvb, offset);
8556         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8557         offset += 4;
8558
8559         /* data offset */
8560         od = tvb_get_letohl(tvb, offset);
8561         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8562         offset += 4;
8563
8564         /* data displacement */
8565         if(wc>=19){
8566                 /* primary request */
8567                 dd = 0;
8568         } else {
8569                 /* secondary request */
8570                 dd = tvb_get_letohl(tvb, offset);
8571                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8572                 offset += 4;
8573         }
8574
8575         /* setup count */
8576         if(wc>=19){
8577                 /* primary request */
8578                 sc = tvb_get_guint8(tvb, offset);
8579                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8580                 offset += 1;
8581         } else {
8582                 /* secondary request */
8583                 sc = 0;
8584         }
8585
8586         /* function */
8587         if(wc>=19){
8588                 /* primary request */
8589                 subcmd = tvb_get_letohs(tvb, offset);
8590                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8591                 if(check_col(pinfo->cinfo, COL_INFO)){
8592                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8593                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8594                 }
8595                 ntd.subcmd = subcmd;
8596                 if (!si->unidir && sip) {
8597                         if(!pinfo->fd->flags.visited){
8598                                 /*
8599                                  * Allocate a new smb_nt_transact_info_t
8600                                  * structure.
8601                                  */
8602                                 nti = se_alloc(sizeof(smb_nt_transact_info_t));
8603                                 nti->subcmd = subcmd;
8604                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8605                                 sip->extra_info = nti;
8606                                 sip->extra_info_type = SMB_EI_NTI;
8607                         } else {
8608                                 if(sip->extra_info_type == SMB_EI_NTI){
8609                                         nti=sip->extra_info;
8610                                 }
8611                         }
8612                 }
8613         } else {
8614                 /* secondary request */
8615                 if(check_col(pinfo->cinfo, COL_INFO)){
8616                         col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
8617                 }
8618         }
8619         offset += 2;
8620
8621         /* this is a padding byte */
8622         if(offset%1){
8623                 /* pad byte */
8624                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8625                 offset += 1;
8626         }
8627
8628         /* if there were any setup bytes, decode them */
8629         if(sc){
8630                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8631                 offset += sc*2;
8632         }
8633
8634         BYTE_COUNT;
8635
8636         /* parameters */
8637         if(po>(guint32)offset){
8638                 /* We have some initial padding bytes.
8639                 */
8640                 padcnt = po-offset;
8641                 if (padcnt > bc)
8642                         padcnt = bc;
8643                 CHECK_BYTE_COUNT(padcnt);
8644                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8645                 COUNT_BYTES(padcnt);
8646         }
8647         if(pc){
8648                 CHECK_BYTE_COUNT(pc);
8649                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc, nti);
8650                 COUNT_BYTES(pc);
8651         }
8652
8653         /* data */
8654         if(od>(guint32)offset){
8655                 /* We have some initial padding bytes.
8656                 */
8657                 padcnt = od-offset;
8658                 if (padcnt > bc)
8659                         padcnt = bc;
8660                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8661                 COUNT_BYTES(padcnt);
8662         }
8663         if(dc){
8664                 CHECK_BYTE_COUNT(dc);
8665                 dissect_nt_trans_data_request(
8666                         tvb, pinfo, offset, tree, dc, &ntd, nti);
8667                 COUNT_BYTES(dc);
8668         }
8669
8670         END_OF_SMB
8671
8672         return offset;
8673 }
8674
8675
8676
8677 static int
8678 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8679                                int offset, proto_tree *parent_tree, int len,
8680                                nt_trans_data *ntd _U_,
8681                                smb_nt_transact_info_t *nti)
8682 {
8683         proto_item *item = NULL;
8684         proto_tree *tree = NULL;
8685         smb_info_t *si;
8686         guint16 bcp;
8687         struct access_mask_info *ami=NULL;
8688         tvbuff_t *ioctl_tvb;
8689
8690         si = (smb_info_t *)pinfo->private_data;
8691         DISSECTOR_ASSERT(si);
8692
8693         if(parent_tree){
8694                 tvb_ensure_bytes_exist(tvb, offset, len);
8695                 if(nti != NULL){
8696                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8697                                 "%s Data",
8698                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8699                 } else {
8700                         /*
8701                          * We never saw the request to which this is a
8702                          * response.
8703                          */
8704                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8705                                 "Unknown NT Transaction Data (matching request not seen)");
8706                 }
8707                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8708         }
8709
8710         if (nti == NULL) {
8711                 offset += len;
8712                 return offset;
8713         }
8714         switch(nti->subcmd){
8715         case NT_TRANS_CREATE:
8716                 break;
8717         case NT_TRANS_IOCTL:
8718                 /* ioctl data */
8719                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)len, tvb_length_remaining(tvb, offset)), len);
8720                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, FALSE);
8721
8722                 offset += len;
8723
8724                 break;
8725         case NT_TRANS_SSD:
8726                 break;
8727         case NT_TRANS_NOTIFY:
8728                 break;
8729         case NT_TRANS_RENAME:
8730                 /* XXX not documented */
8731                 break;
8732         case NT_TRANS_QSD:
8733                 if(nti){
8734                         switch(nti->fid_type){
8735                         case SMB_FID_TYPE_FILE:
8736                                 ami= &smb_file_access_mask_info;
8737                                 break;
8738                         case SMB_FID_TYPE_DIR:
8739                                 ami= &smb_dir_access_mask_info;
8740                                 break;
8741                         }
8742                 }
8743                 offset = dissect_nt_sec_desc(
8744                         tvb, offset, pinfo, tree, NULL, TRUE, len, ami);
8745                 break;
8746         case NT_TRANS_GET_USER_QUOTA:
8747                 bcp=len;
8748                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8749                 break;
8750         case NT_TRANS_SET_USER_QUOTA:
8751                 /* not decoded yet */
8752                 break;
8753         }
8754
8755         return offset;
8756 }
8757
8758 static int
8759 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8760                                 int offset, proto_tree *parent_tree,
8761                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8762 {
8763         proto_item *item = NULL;
8764         proto_tree *tree = NULL;
8765         guint32 fn_len;
8766         const char *fn;
8767         smb_info_t *si;
8768         smb_nt_transact_info_t *nti;
8769         guint16 fid;
8770         int old_offset;
8771         guint32 neo;
8772         int padcnt;
8773         smb_fid_info_t *fid_info=NULL;
8774         guint16 ftype;
8775         guint8  isdir;
8776
8777         si = (smb_info_t *)pinfo->private_data;
8778         DISSECTOR_ASSERT(si);
8779
8780         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8781                 nti = si->sip->extra_info;
8782         else
8783                 nti = NULL;
8784
8785         if(parent_tree){
8786                 tvb_ensure_bytes_exist(tvb, offset, len);
8787                 if(nti != NULL){
8788                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8789                                 "%s Parameters",
8790                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8791                 } else {
8792                         /*
8793                          * We never saw the request to which this is a
8794                          * response.
8795                          */
8796                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8797                                 "Unknown NT Transaction Parameters (matching request not seen)");
8798                 }
8799                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8800         }
8801
8802         if (nti == NULL) {
8803                 offset += len;
8804                 return offset;
8805         }
8806         switch(nti->subcmd){
8807         case NT_TRANS_CREATE:
8808                 /* oplock level */
8809                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8810                 offset += 1;
8811
8812                 /* reserved byte */
8813                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8814                 offset += 1;
8815
8816                 /* fid */
8817                 fid = tvb_get_letohs(tvb, offset);
8818                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
8819                 offset += 2;
8820
8821                 /* create action */
8822                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8823                 offset += 4;
8824
8825                 /* ea error offset */
8826                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8827                 offset += 4;
8828
8829                 /* create time */
8830                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8831                         hf_smb_create_time);
8832
8833                 /* access time */
8834                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8835                         hf_smb_access_time);
8836
8837                 /* last write time */
8838                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8839                         hf_smb_last_write_time);
8840
8841                 /* last change time */
8842                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8843                         hf_smb_change_time);
8844
8845                 /* Extended File Attributes */
8846                 offset = dissect_file_ext_attr(tvb, tree, offset);
8847
8848                 /* allocation size */
8849                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8850                 offset += 8;
8851
8852                 /* end of file */
8853                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8854                 offset += 8;
8855
8856                 /* File Type */
8857                 ftype=tvb_get_letohs(tvb, offset);
8858                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8859                 offset += 2;
8860
8861                 /* device state */
8862                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8863
8864                 /* is directory */
8865                 isdir=tvb_get_guint8(tvb, offset);
8866                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8867                 offset += 1;
8868
8869                 /* Try to remember the type of this fid so that we can dissect
8870                  * any future security descriptor (access mask) properly
8871                  */
8872                 if(ftype==0){
8873                         if(isdir==0){
8874                                 if(fid_info){
8875                                         fid_info->type=SMB_FID_TYPE_FILE;
8876                                 }
8877                         } else {
8878                                 if(fid_info){
8879                                         fid_info->type=SMB_FID_TYPE_DIR;
8880                                 }
8881                         }
8882                 }
8883                 if(ftype==2){
8884                         if(fid_info){
8885                                 fid_info->type=SMB_FID_TYPE_PIPE;
8886                         }
8887                 }
8888                 break;
8889         case NT_TRANS_IOCTL:
8890                 break;
8891         case NT_TRANS_SSD:
8892                 break;
8893         case NT_TRANS_NOTIFY:
8894                 while(len){
8895                         old_offset = offset;
8896
8897                         /* next entry offset */
8898                         neo = tvb_get_letohl(tvb, offset);
8899                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8900                         COUNT_BYTES(4);
8901                         len -= 4;
8902                         /* broken implementations */
8903                         if(len<0)break;
8904
8905                         /* action */
8906                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8907                         COUNT_BYTES(4);
8908                         len -= 4;
8909                         /* broken implementations */
8910                         if(len<0)break;
8911
8912                         /* file name len */
8913                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8914                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8915                         COUNT_BYTES(4);
8916                         len -= 4;
8917                         /* broken implementations */
8918                         if(len<0)break;
8919
8920                         /* file name */
8921                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8922                         if (fn == NULL)
8923                                 break;
8924                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8925                                 fn);
8926                         COUNT_BYTES(fn_len);
8927                         len -= fn_len;
8928                         /* broken implementations */
8929                         if(len<0)break;
8930
8931                         if (neo == 0)
8932                                 break;  /* no more structures */
8933
8934                         /* skip to next structure */
8935                         padcnt = (old_offset + neo) - offset;
8936                         if (padcnt < 0) {
8937                                 /*
8938                                  * XXX - this is bogus; flag it?
8939                                  */
8940                                 padcnt = 0;
8941                         }
8942                         if (padcnt != 0) {
8943                                 COUNT_BYTES(padcnt);
8944                                 len -= padcnt;
8945                                 /* broken implementations */
8946                                 if(len<0)break;
8947                         }
8948                 }
8949                 break;
8950         case NT_TRANS_RENAME:
8951                 /* XXX not documented */
8952                 break;
8953         case NT_TRANS_QSD:
8954                 /*
8955                  * This appears to be the size of the security
8956                  * descriptor; the calling sequence of
8957                  * "ZwQuerySecurityObject()" suggests that it would
8958                  * be.  The actual security descriptor wouldn't
8959                  * follow if the max data count in the request
8960                  * was smaller; this lets the client know how
8961                  * big a buffer it needs to provide.
8962                  */
8963                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8964                 offset += 4;
8965                 break;
8966         case NT_TRANS_GET_USER_QUOTA:
8967                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8968                         tvb_get_letohl(tvb, offset));
8969                 offset += 4;
8970                 break;
8971         case NT_TRANS_SET_USER_QUOTA:
8972                 /* not decoded yet */
8973                 break;
8974         }
8975
8976         return offset;
8977 }
8978
8979 static int
8980 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8981                                 int offset, proto_tree *parent_tree,
8982                                 int len, nt_trans_data *ntd _U_)
8983 {
8984         proto_item *item = NULL;
8985         proto_tree *tree = NULL;
8986         smb_info_t *si;
8987         smb_nt_transact_info_t *nti;
8988
8989         si = (smb_info_t *)pinfo->private_data;
8990         DISSECTOR_ASSERT(si);
8991
8992         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8993                 nti = si->sip->extra_info;
8994         else
8995                 nti = NULL;
8996
8997         if(parent_tree){
8998                 tvb_ensure_bytes_exist(tvb, offset, len);
8999                 if(nti != NULL){
9000                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9001                                 "%s Setup",
9002                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
9003                 } else {
9004                         /*
9005                          * We never saw the request to which this is a
9006                          * response.
9007                          */
9008                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9009                                 "Unknown NT Transaction Setup (matching request not seen)");
9010                 }
9011                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
9012         }
9013
9014         if (nti == NULL) {
9015                 offset += len;
9016                 return offset;
9017         }
9018         switch(nti->subcmd){
9019         case NT_TRANS_CREATE:
9020                 break;
9021         case NT_TRANS_IOCTL:
9022                 break;
9023         case NT_TRANS_SSD:
9024                 break;
9025         case NT_TRANS_NOTIFY:
9026                 break;
9027         case NT_TRANS_RENAME:
9028                 /* XXX not documented */
9029                 break;
9030         case NT_TRANS_QSD:
9031                 break;
9032         case NT_TRANS_GET_USER_QUOTA:
9033                 /* not decoded yet */
9034                 break;
9035         case NT_TRANS_SET_USER_QUOTA:
9036                 /* not decoded yet */
9037                 break;
9038         }
9039
9040         return offset;
9041 }
9042
9043 static int
9044 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9045 {
9046         guint8 wc, sc;
9047         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
9048         guint32 td=0, tp=0;
9049         smb_info_t *si;
9050         smb_nt_transact_info_t *nti=NULL;
9051         static nt_trans_data ntd;
9052         guint16 bc;
9053         gint32 padcnt;
9054         fragment_data *r_fd = NULL;
9055         tvbuff_t *pd_tvb=NULL;
9056         gboolean save_fragmented;
9057
9058         si = (smb_info_t *)pinfo->private_data;
9059         DISSECTOR_ASSERT(si);
9060
9061         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
9062                 nti = si->sip->extra_info;
9063         else
9064                 nti = NULL;
9065
9066         /* primary request */
9067         if(nti != NULL){
9068                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
9069                 if(check_col(pinfo->cinfo, COL_INFO)){
9070                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9071                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
9072                 }
9073         } else {
9074                 proto_tree_add_text(tree, tvb, offset, 0,
9075                         "Function: <unknown function - could not find matching request>");
9076                 if(check_col(pinfo->cinfo, COL_INFO)){
9077                         col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
9078                 }
9079         }
9080
9081         WORD_COUNT;
9082
9083         /* 3 reserved bytes */
9084         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
9085         offset += 3;
9086
9087         /* total param count */
9088         tp = tvb_get_letohl(tvb, offset);
9089         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
9090         offset += 4;
9091
9092         /* total data count */
9093         td = tvb_get_letohl(tvb, offset);
9094         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
9095         offset += 4;
9096
9097         /* param count */
9098         pc = tvb_get_letohl(tvb, offset);
9099         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
9100         offset += 4;
9101
9102         /* param offset */
9103         po = tvb_get_letohl(tvb, offset);
9104         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
9105         offset += 4;
9106
9107         /* param displacement */
9108         pd = tvb_get_letohl(tvb, offset);
9109         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
9110         offset += 4;
9111
9112         /* data count */
9113         dc = tvb_get_letohl(tvb, offset);
9114         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
9115         offset += 4;
9116
9117         /* data offset */
9118         od = tvb_get_letohl(tvb, offset);
9119         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9120         offset += 4;
9121
9122         /* data displacement */
9123         dd = tvb_get_letohl(tvb, offset);
9124         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9125         offset += 4;
9126
9127         /* setup count */
9128         sc = tvb_get_guint8(tvb, offset);
9129         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9130         offset += 1;
9131
9132         /* setup data */
9133         if(sc){
9134                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
9135                 offset += sc*2;
9136         }
9137
9138         BYTE_COUNT;
9139
9140         /* reassembly of SMB NT Transaction data payload.
9141            In this section we do reassembly of both the data and parameters
9142            blocks of the SMB transaction command.
9143         */
9144         save_fragmented = pinfo->fragmented;
9145         /* do we need reassembly? */
9146         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
9147                 /* oh yeah, either data or parameter section needs
9148                    reassembly...
9149                 */
9150                 pinfo->fragmented = TRUE;
9151                 if(smb_trans_reassembly){
9152                         /* ...and we were told to do reassembly */
9153                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
9154                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9155                                                              po, pc, pd, td+tp);
9156
9157                         }
9158                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
9159                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9160                                                              od, dc, dd+tp, td+tp);
9161                         }
9162                 }
9163         }
9164
9165         /* if we got a reassembled fd structure from the reassembly routine we
9166            must create pd_tvb from it
9167         */
9168         if(r_fd){
9169         proto_item *frag_tree_item;
9170
9171                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
9172                                              r_fd->datalen);
9173                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
9174                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9175
9176                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9177         }
9178
9179
9180         if(pd_tvb){
9181           /* we have reassembled data, grab param and data from there */
9182           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
9183                                           &ntd, (guint16) tvb_length(pd_tvb));
9184           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd, nti);
9185         } else {
9186           /* we do not have reassembled data, just use what we have in the
9187              packet as well as we can */
9188           /* parameters */
9189           if(po>(guint32)offset){
9190             /* We have some initial padding bytes.
9191              */
9192             padcnt = po-offset;
9193             if (padcnt > bc)
9194               padcnt = bc;
9195             CHECK_BYTE_COUNT(padcnt);
9196             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9197             COUNT_BYTES(padcnt);
9198           }
9199           if(pc){
9200             CHECK_BYTE_COUNT(pc);
9201             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
9202             COUNT_BYTES(pc);
9203           }
9204
9205           /* data */
9206           if(od>(guint32)offset){
9207             /* We have some initial padding bytes.
9208              */
9209             padcnt = od-offset;
9210             if (padcnt > bc)
9211               padcnt = bc;
9212             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9213             COUNT_BYTES(padcnt);
9214           }
9215           if(dc){
9216             CHECK_BYTE_COUNT(dc);
9217             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd, nti);
9218             COUNT_BYTES(dc);
9219           }
9220         }
9221         pinfo->fragmented = save_fragmented;
9222
9223         END_OF_SMB
9224
9225         return offset;
9226 }
9227
9228 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9229    NT Transaction command  ends here
9230    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9231
9232 static const value_string print_mode_vals[] = {
9233         {0,     "Text Mode"},
9234         {1,     "Graphics Mode"},
9235         {0, NULL}
9236 };
9237
9238 static int
9239 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9240 {
9241         smb_info_t *si = pinfo->private_data;
9242         int fn_len;
9243         const char *fn;
9244         guint8 wc;
9245         guint16 bc;
9246
9247         DISSECTOR_ASSERT(si);
9248
9249         WORD_COUNT;
9250
9251         /* setup len */
9252         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9253         offset += 2;
9254
9255         /* print mode */
9256         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9257         offset += 2;
9258
9259         BYTE_COUNT;
9260
9261         /* buffer format */
9262         CHECK_BYTE_COUNT(1);
9263         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9264         COUNT_BYTES(1);
9265
9266         /* print identifier */
9267         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9268         if (fn == NULL)
9269                 goto endofcommand;
9270         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9271                 fn);
9272         COUNT_BYTES(fn_len);
9273
9274         END_OF_SMB
9275
9276         return offset;
9277 }
9278
9279
9280 static int
9281 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9282 {
9283         int cnt;
9284         guint8 wc;
9285         guint16 bc, fid;
9286
9287         WORD_COUNT;
9288
9289         /* fid */
9290         fid = tvb_get_letohs(tvb, offset);
9291         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
9292         offset += 2;
9293
9294         BYTE_COUNT;
9295
9296         /* buffer format */
9297         CHECK_BYTE_COUNT(1);
9298         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9299         COUNT_BYTES(1);
9300
9301         /* data len */
9302         CHECK_BYTE_COUNT(2);
9303         cnt = tvb_get_letohs(tvb, offset);
9304         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9305         COUNT_BYTES(2);
9306
9307         /* file data */
9308         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9309
9310         END_OF_SMB
9311
9312         return offset;
9313 }
9314
9315
9316 static const value_string print_status_vals[] = {
9317         {1,     "Held or Stopped"},
9318         {2,     "Printing"},
9319         {3,     "Awaiting print"},
9320         {4,     "In intercept"},
9321         {5,     "File had error"},
9322         {6,     "Printer error"},
9323         {0, NULL}
9324 };
9325
9326 static int
9327 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9328 {
9329         guint8 wc;
9330         guint16 bc;
9331
9332         WORD_COUNT;
9333
9334         /* max count */
9335         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9336         offset += 2;
9337
9338         /* start index */
9339         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9340         offset += 2;
9341
9342         BYTE_COUNT;
9343
9344         END_OF_SMB
9345
9346         return offset;
9347 }
9348
9349 static int
9350 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9351     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9352 {
9353         proto_item *item = NULL;
9354         proto_tree *tree = NULL;
9355         smb_info_t *si = pinfo->private_data;
9356         int fn_len;
9357         const char *fn;
9358
9359         DISSECTOR_ASSERT(si);
9360
9361         if(parent_tree){
9362                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9363                         "Queue entry");
9364                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9365         }
9366
9367         /* queued time */
9368         CHECK_BYTE_COUNT_SUBR(4);
9369         offset = dissect_smb_datetime(tvb, tree, offset,
9370                 hf_smb_print_queue_date,
9371                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9372         *bcp -= 4;
9373
9374         /* status */
9375         CHECK_BYTE_COUNT_SUBR(1);
9376         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9377         COUNT_BYTES_SUBR(1);
9378
9379         /* spool file number */
9380         CHECK_BYTE_COUNT_SUBR(2);
9381         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9382         COUNT_BYTES_SUBR(2);
9383
9384         /* spool file size */
9385         CHECK_BYTE_COUNT_SUBR(4);
9386         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9387         COUNT_BYTES_SUBR(4);
9388
9389         /* reserved byte */
9390         CHECK_BYTE_COUNT_SUBR(1);
9391         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9392         COUNT_BYTES_SUBR(1);
9393
9394         /* file name */
9395         fn_len = 16;
9396         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9397         CHECK_STRING_SUBR(fn);
9398         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9399                 fn);
9400         COUNT_BYTES_SUBR(fn_len);
9401
9402         *trunc = FALSE;
9403         return offset;
9404 }
9405
9406 static int
9407 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9408 {
9409         guint16 cnt=0, len;
9410         guint8 wc;
9411         guint16 bc;
9412         gboolean trunc;
9413
9414         WORD_COUNT;
9415
9416         /* count */
9417         cnt = tvb_get_letohs(tvb, offset);
9418         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9419         offset += 2;
9420
9421         /* restart index */
9422         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9423         offset += 2;
9424
9425         BYTE_COUNT;
9426
9427         /* buffer format */
9428         CHECK_BYTE_COUNT(1);
9429         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9430         COUNT_BYTES(1);
9431
9432         /* data len */
9433         CHECK_BYTE_COUNT(2);
9434         len = tvb_get_letohs(tvb, offset);
9435         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9436         COUNT_BYTES(2);
9437
9438         /* queue elements */
9439         while(cnt--){
9440                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9441                     &bc, &trunc);
9442                 if (trunc)
9443                         goto endofcommand;
9444         }
9445
9446         END_OF_SMB
9447
9448         return offset;
9449 }
9450
9451
9452 static int
9453 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9454 {
9455         int name_len;
9456         guint16 bc;
9457         guint8 wc;
9458         guint16 message_len;
9459
9460         WORD_COUNT;
9461
9462         BYTE_COUNT;
9463
9464         /* buffer format */
9465         CHECK_BYTE_COUNT(1);
9466         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9467         COUNT_BYTES(1);
9468
9469         /* originator name */
9470         /* XXX - what if this runs past bc? */
9471         name_len = tvb_strsize(tvb, offset);
9472         CHECK_BYTE_COUNT(name_len);
9473         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9474             name_len, TRUE);
9475         COUNT_BYTES(name_len);
9476
9477         /* buffer format */
9478         CHECK_BYTE_COUNT(1);
9479         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9480         COUNT_BYTES(1);
9481
9482         /* destination name */
9483         /* XXX - what if this runs past bc? */
9484         name_len = tvb_strsize(tvb, offset);
9485         CHECK_BYTE_COUNT(name_len);
9486         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9487             name_len, TRUE);
9488         COUNT_BYTES(name_len);
9489
9490         /* buffer format */
9491         CHECK_BYTE_COUNT(1);
9492         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9493         COUNT_BYTES(1);
9494
9495         /* message len */
9496         CHECK_BYTE_COUNT(2);
9497         message_len = tvb_get_letohs(tvb, offset);
9498         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9499             message_len);
9500         COUNT_BYTES(2);
9501
9502         /* message */
9503         CHECK_BYTE_COUNT(message_len);
9504         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9505             TRUE);
9506         COUNT_BYTES(message_len);
9507
9508         END_OF_SMB
9509
9510         return offset;
9511 }
9512
9513 static int
9514 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9515 {
9516         int name_len;
9517         guint16 bc;
9518         guint8 wc;
9519
9520         WORD_COUNT;
9521
9522         BYTE_COUNT;
9523
9524         /* buffer format */
9525         CHECK_BYTE_COUNT(1);
9526         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9527         COUNT_BYTES(1);
9528
9529         /* originator name */
9530         /* XXX - what if this runs past bc? */
9531         name_len = tvb_strsize(tvb, offset);
9532         CHECK_BYTE_COUNT(name_len);
9533         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9534             name_len, TRUE);
9535         COUNT_BYTES(name_len);
9536
9537         /* buffer format */
9538         CHECK_BYTE_COUNT(1);
9539         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9540         COUNT_BYTES(1);
9541
9542         /* destination name */
9543         /* XXX - what if this runs past bc? */
9544         name_len = tvb_strsize(tvb, offset);
9545         CHECK_BYTE_COUNT(name_len);
9546         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9547             name_len, TRUE);
9548         COUNT_BYTES(name_len);
9549
9550         END_OF_SMB
9551
9552         return offset;
9553 }
9554
9555 static int
9556 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9557 {
9558         guint16 bc;
9559         guint8 wc;
9560
9561         WORD_COUNT;
9562
9563         /* message group ID */
9564         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9565         offset += 2;
9566
9567         BYTE_COUNT;
9568
9569         END_OF_SMB
9570
9571         return offset;
9572 }
9573
9574 static int
9575 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9576 {
9577         guint16 bc;
9578         guint8 wc;
9579         guint16 message_len;
9580
9581         WORD_COUNT;
9582
9583         BYTE_COUNT;
9584
9585         /* buffer format */
9586         CHECK_BYTE_COUNT(1);
9587         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9588         COUNT_BYTES(1);
9589
9590         /* message len */
9591         CHECK_BYTE_COUNT(2);
9592         message_len = tvb_get_letohs(tvb, offset);
9593         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9594             message_len);
9595         COUNT_BYTES(2);
9596
9597         /* message */
9598         CHECK_BYTE_COUNT(message_len);
9599         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9600             TRUE);
9601         COUNT_BYTES(message_len);
9602
9603         END_OF_SMB
9604
9605         return offset;
9606 }
9607
9608 static int
9609 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9610 {
9611         int name_len;
9612         guint16 bc;
9613         guint8 wc;
9614
9615         WORD_COUNT;
9616
9617         BYTE_COUNT;
9618
9619         /* buffer format */
9620         CHECK_BYTE_COUNT(1);
9621         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9622         COUNT_BYTES(1);
9623
9624         /* forwarded name */
9625         /* XXX - what if this runs past bc? */
9626         name_len = tvb_strsize(tvb, offset);
9627         CHECK_BYTE_COUNT(name_len);
9628         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9629             name_len, TRUE);
9630         COUNT_BYTES(name_len);
9631
9632         END_OF_SMB
9633
9634         return offset;
9635 }
9636
9637 static int
9638 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9639 {
9640         int name_len;
9641         guint16 bc;
9642         guint8 wc;
9643
9644         WORD_COUNT;
9645
9646         BYTE_COUNT;
9647
9648         /* buffer format */
9649         CHECK_BYTE_COUNT(1);
9650         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9651         COUNT_BYTES(1);
9652
9653         /* machine name */
9654         /* XXX - what if this runs past bc? */
9655         name_len = tvb_strsize(tvb, offset);
9656         CHECK_BYTE_COUNT(name_len);
9657         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9658             name_len, TRUE);
9659         COUNT_BYTES(name_len);
9660
9661         END_OF_SMB
9662
9663         return offset;
9664 }
9665
9666
9667 static int
9668 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9669 {
9670         guint8  wc, cmd=0xff;
9671         guint16 andxoffset=0;
9672         guint16 bc;
9673         smb_info_t *si = pinfo->private_data;
9674         int fn_len;
9675         const char *fn;
9676         guint32 create_flags=0, access_mask=0, file_attributes=0, share_access=0, create_options=0, create_disposition=0;
9677
9678         DISSECTOR_ASSERT(si);
9679
9680         WORD_COUNT;
9681
9682         /* next smb command */
9683         cmd = tvb_get_guint8(tvb, offset);
9684         if(cmd!=0xff){
9685                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9686         } else {
9687                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9688         }
9689         offset += 1;
9690
9691         /* reserved byte */
9692         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9693         offset += 1;
9694
9695         /* andxoffset */
9696         andxoffset = tvb_get_letohs(tvb, offset);
9697         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9698         offset += 2;
9699
9700         /* reserved byte */
9701         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9702         offset += 1;
9703
9704         /* file name len */
9705         fn_len = tvb_get_letohs(tvb, offset);
9706         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9707         offset += 2;
9708
9709         /* Create flags */
9710         create_flags=tvb_get_letohl(tvb, offset);
9711         offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
9712
9713         /* root directory fid */
9714         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9715         offset += 4;
9716
9717         /* nt access mask */
9718         access_mask=tvb_get_letohl(tvb, offset);
9719         offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
9720
9721         /* allocation size */
9722         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9723         offset += 8;
9724
9725         /* Extended File Attributes */
9726         file_attributes=tvb_get_letohl(tvb, offset);
9727         offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
9728
9729         /* share access */
9730         share_access=tvb_get_letohl(tvb, offset);
9731         offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
9732
9733         /* create disposition */
9734         create_disposition=tvb_get_letohl(tvb, offset);
9735         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9736         offset += 4;
9737
9738         /* create options */
9739         create_options=tvb_get_letohl(tvb, offset);
9740         offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
9741
9742         /* impersonation level */
9743         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9744         offset += 4;
9745
9746         /* security flags */
9747         offset = dissect_nt_security_flags(tvb, tree, offset);
9748
9749         BYTE_COUNT;
9750
9751         /* file name */
9752         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9753         if (fn == NULL)
9754                 goto endofcommand;
9755         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9756                 fn);
9757         COUNT_BYTES(fn_len);
9758
9759         /* store it for the fid->name/openframe/closeframe matching in
9760          * dissect_smb_fid()   called from the response.
9761          */
9762         if((!pinfo->fd->flags.visited) && si->sip && fn){
9763                 smb_fid_saved_info_t *fsi;
9764
9765                 fsi=se_alloc(sizeof(smb_fid_saved_info_t));
9766                 fsi->filename=se_strdup(fn);
9767                 fsi->create_flags=create_flags;
9768                 fsi->access_mask=access_mask;
9769                 fsi->file_attributes=file_attributes;
9770                 fsi->share_access=share_access;
9771                 fsi->create_options=create_options;
9772                 fsi->create_disposition=create_disposition;
9773
9774                 si->sip->extra_info_type=SMB_EI_FILEDATA;
9775                 si->sip->extra_info=fsi;
9776         }
9777
9778         if (check_col(pinfo->cinfo, COL_INFO)) {
9779                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9780                     format_text(fn, strlen(fn)));
9781         }
9782
9783         END_OF_SMB
9784
9785         if (cmd != 0xff) {      /* there is an andX command */
9786                 if (andxoffset < offset)
9787                         THROW(ReportedBoundsError);
9788                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9789         }
9790
9791         return offset;
9792 }
9793
9794
9795 static int
9796 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9797 {
9798         guint8  wc, cmd=0xff;
9799         guint16 andxoffset=0;
9800         guint16 bc;
9801         guint16 fid=0;
9802         guint16 ftype;
9803         guint8  isdir;
9804         smb_fid_info_t *fid_info=NULL;
9805         smb_info_t              *si;
9806
9807         si = pinfo->private_data;
9808
9809         WORD_COUNT;
9810
9811         /* next smb command */
9812         cmd = tvb_get_guint8(tvb, offset);
9813         if(cmd!=0xff){
9814                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9815         } else {
9816                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9817         }
9818         offset += 1;
9819
9820         /* reserved byte */
9821         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9822         offset += 1;
9823
9824         /* andxoffset */
9825         andxoffset = tvb_get_letohs(tvb, offset);
9826         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9827         offset += 2;
9828
9829         /* oplock level */
9830         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9831         offset += 1;
9832
9833         /* fid */
9834         fid = tvb_get_letohs(tvb, offset);
9835         fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
9836         offset += 2;
9837
9838         /* create action */
9839         /*XXX is this really the same as create disposition in the request? it looks so*/
9840         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9841         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9842         offset += 4;
9843
9844         /* create time */
9845         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
9846
9847         /* access time */
9848         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
9849
9850         /* last write time */
9851         offset = dissect_nt_64bit_time(tvb, tree, offset,
9852                 hf_smb_last_write_time);
9853
9854         /* last change time */
9855         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
9856
9857         /* Extended File Attributes */
9858         offset = dissect_file_ext_attr(tvb, tree, offset);
9859
9860         /* allocation size */
9861         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9862         offset += 8;
9863
9864         /* end of file */
9865         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9866         offset += 8;
9867
9868         /* File Type */
9869         ftype=tvb_get_letohs(tvb, offset);
9870         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9871         offset += 2;
9872
9873         /* IPC State */
9874         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9875
9876         /* is directory */
9877         isdir=tvb_get_guint8(tvb, offset);
9878         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9879         offset += 1;
9880
9881         /* Try to remember the type of this fid so that we can dissect
9882          * any future security descriptor (access mask) properly
9883          */
9884         if(ftype==0){
9885                 if(isdir==0){
9886                         if(fid_info){
9887                                 fid_info->type=SMB_FID_TYPE_FILE;
9888                         }
9889                 } else {
9890                         if(fid_info){
9891                                 fid_info->type=SMB_FID_TYPE_DIR;
9892                         }
9893                 }
9894         }
9895         if(ftype==2){
9896                 if(fid_info){
9897                         fid_info->type=SMB_FID_TYPE_PIPE;
9898                 }
9899         }
9900
9901         BYTE_COUNT;
9902
9903         END_OF_SMB
9904
9905         if (cmd != 0xff) {      /* there is an andX command */
9906                 if (andxoffset < offset)
9907                         THROW(ReportedBoundsError);
9908                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9909         }
9910
9911         /* if there was an error, add a generated filename to the tree */
9912         if(si->nt_status){
9913                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE);
9914         }
9915
9916         return offset;
9917 }
9918
9919
9920 static int
9921 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9922 {
9923         guint8 wc;
9924         guint16 bc;
9925
9926         WORD_COUNT;
9927
9928         BYTE_COUNT;
9929
9930         END_OF_SMB
9931
9932         return offset;
9933 }
9934
9935 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9936    BEGIN Transaction/Transaction2 Primary and secondary requests
9937    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9938
9939
9940 const value_string trans2_cmd_vals[] = {
9941         { 0x00,         "OPEN2" },
9942         { 0x01,         "FIND_FIRST2" },
9943         { 0x02,         "FIND_NEXT2" },
9944         { 0x03,         "QUERY_FS_INFO" },
9945         { 0x04,         "SET_FS_QUOTA" },
9946         { 0x05,         "QUERY_PATH_INFO" },
9947         { 0x06,         "SET_PATH_INFO" },
9948         { 0x07,         "QUERY_FILE_INFO" },
9949         { 0x08,         "SET_FILE_INFO" },
9950         { 0x09,         "FSCTL" },
9951         { 0x0A,         "IOCTL2" },
9952         { 0x0B,         "FIND_NOTIFY_FIRST" },
9953         { 0x0C,         "FIND_NOTIFY_NEXT" },
9954         { 0x0D,         "CREATE_DIRECTORY" },
9955         { 0x0E,         "SESSION_SETUP" },
9956         { 0x10,         "GET_DFS_REFERRAL" },
9957         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9958         { 0,    NULL }
9959 };
9960
9961 static const true_false_string tfs_tf_dtid = {
9962         "Also DISCONNECT TID",
9963         "Do NOT disconnect TID"
9964 };
9965 static const true_false_string tfs_tf_owt = {
9966         "One Way Transaction (NO RESPONSE)",
9967         "Two way transaction"
9968 };
9969
9970 static const true_false_string tfs_ff2_backup = {
9971         "Find WITH backup intent",
9972         "No backup intent"
9973 };
9974 static const true_false_string tfs_ff2_continue = {
9975         "CONTINUE search from previous position",
9976         "New search, do NOT continue from previous position"
9977 };
9978 static const true_false_string tfs_ff2_resume = {
9979         "Return RESUME keys",
9980         "Do NOT return resume keys"
9981 };
9982 static const true_false_string tfs_ff2_close_eos = {
9983         "CLOSE search if END OF SEARCH is reached",
9984         "Do NOT close search if end of search reached"
9985 };
9986 static const true_false_string tfs_ff2_close = {
9987         "CLOSE search after this request",
9988         "Do NOT close search after this request"
9989 };
9990
9991 /* used by
9992    TRANS2_FIND_FIRST2
9993 */
9994 static const value_string ff2_il_vals[] = {
9995         { 1,            "Info Standard"},
9996         { 2,            "Info Query EA Size"},
9997         { 3,            "Info Query EAs From List"},
9998         { 0x0101,       "Find File Directory Info"},
9999         { 0x0102,       "Find File Full Directory Info"},
10000         { 0x0103,       "Find File Names Info"},
10001         { 0x0104,       "Find File Both Directory Info"},
10002         { 0x0202,       "Find File UNIX"},
10003         {0, NULL}
10004 };
10005
10006 /* values used by :
10007         TRANS2_QUERY_PATH_INFORMATION
10008         TRANS2_QUERY_FILE_INFORMATION
10009 */
10010 static const value_string qpi_loi_vals[] = {
10011         { 1,            "Info Standard"},
10012         { 2,            "Info Query EA Size"},
10013         { 3,            "Info Query EAs From List"},
10014         { 4,            "Info Query All EAs"},
10015         { 6,            "Info Is Name Valid"},
10016         { 0x0101,       "Query File Basic Info"},
10017         { 0x0102,       "Query File Standard Info"},
10018         { 0x0103,       "Query File EA Info"},
10019         { 0x0104,       "Query File Name Info"},
10020         { 0x0107,       "Query File All Info"},
10021         { 0x0108,       "Query File Alt Name Info"},
10022         { 0x0109,       "Query File Stream Info"},
10023         { 0x010b,       "Query File Compression Info"},
10024         { 0x0200,       "Query File Unix Basic"},
10025         { 0x0201,       "Query File Unix Link"},
10026         { 0x0202,       "Query File Unix Hardlink"},
10027         { 0x0204,       "Query File Posix ACL"},
10028         { 0x0205,       "Query File Posix XATTR"},
10029         { 0x0206,       "Query File Posix Attr Flags"},
10030         { 0x0207,       "Query File Posix Permissions"},
10031         { 0x0208,       "Query File Posix Lock"},
10032         { 1004,         "Query File Basic Info"},
10033         { 1005,         "Query File Standard Info"},
10034         { 1006,         "Query File Internal Info"},
10035         { 1007,         "Query File EA Info"},
10036         { 1009,         "Query File Name Info"},
10037         { 1010,         "Query File Rename Info"},
10038         { 1011,         "Query File Link Info"},
10039         { 1012,         "Query File Names Info"},
10040         { 1013,         "Query File Disposition Info"},
10041         { 1014,         "Query File Position Info"},
10042         { 1015,         "Query File Full EA Info"},
10043         { 1016,         "Query File Mode Info"},
10044         { 1017,         "Query File Alignment Info"},
10045         { 1018,         "Query File All Info"},
10046         { 1019,         "Query File Allocation Info"},
10047         { 1020,         "Query File End of File Info"},
10048         { 1021,         "Query File Alt Name Info"},
10049         { 1022,         "Query File Stream Info"},
10050         { 1023,         "Query File Pipe Info"},
10051         { 1024,         "Query File Pipe Local Info"},
10052         { 1025,         "Query File Pipe Remote Info"},
10053         { 1026,         "Query File Mailslot Query Info"},
10054         { 1027,         "Query File Mailslot Set Info"},
10055         { 1028,         "Query File Compression Info"},
10056         { 1029,         "Query File ObjectID Info"},
10057         { 1030,         "Query File Completion Info"},
10058         { 1031,         "Query File Move Cluster Info"},
10059         { 1032,         "Query File Quota Info"},
10060         { 1033,         "Query File Reparsepoint Info"},
10061         { 1034,         "Query File Network Open Info"},
10062         { 1035,         "Query File Attribute Tag Info"},
10063         { 1036,         "Query File Tracking Info"},
10064         { 1037,         "Query File Maximum Info"},
10065         {0, NULL}
10066 };
10067
10068 /* values used by :
10069         TRANS2_SET_PATH_INFORMATION
10070         TRANS2_SET_FILE_INFORMATION
10071         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
10072         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
10073         well; note that they're different from the QUERY_PATH_INFORMATION
10074         and QUERY_FILE_INFORMATION values!)
10075 */
10076 static const value_string spi_loi_vals[] = {
10077         { 1,            "Info Standard"},
10078         { 2,            "Info Query EA Size"},
10079         { 4,            "Info Query All EAs"},
10080         { 0x0101,       "Set File Basic Info"},
10081         { 0x0102,       "Set File Disposition Info"},
10082         { 0x0103,       "Set File Allocation Info"},
10083         { 0x0104,       "Set File End Of File Info"},
10084         { 0x0200,       "Set File Unix Basic"},
10085         { 0x0201,       "Set File Unix Link"},
10086         { 0x0202,       "Set File Unix HardLink"},
10087         { 0x0204,       "Set File Unix ACL"},
10088         { 0x0205,       "Set File Unix XATTR"},
10089         { 0x0206,       "Set File Unix Attr Flags"},
10090         { 0x0208,       "Set File Posix Lock"},
10091         { 0x0209,       "Set File Posix Open"},
10092         { 0x020a,       "Set File Posix Unlink"},
10093         { 1004,         "Set File Basic Info"},
10094         { 1010,         "Set Rename Information"},
10095         { 1013,         "Set Disposition Information"},
10096         { 1014,         "Set Position Information"},
10097         { 1016,         "Set Mode Information"},
10098         { 1019,         "Set Allocation Information"},
10099         { 1020,         "Set EOF Information"},
10100         { 1023,         "Set File Pipe Information"},
10101         { 1025,         "Set File Pipe Remote Information"},
10102         { 1029,         "Set Copy On Write Information"},
10103         { 1032,         "Set OLE Class ID Information"},
10104         { 1039,         "Set Inherit Context Index Information"},
10105         { 1040,         "Set OLE Information (?)"},
10106         {0, NULL}
10107 };
10108
10109 static const value_string qfsi_vals[] = {
10110         { 1,            "Info Allocation"},
10111         { 2,            "Info Volume"},
10112         { 0x0101,       "Query FS Label Info"},
10113         { 0x0102,       "Query FS Volume Info"},
10114         { 0x0103,       "Query FS Size Info"},
10115         { 0x0104,       "Query FS Device Info"},
10116         { 0x0105,       "Query FS Attribute Info"},
10117         { 0x0200,       "Unix Query FS Info"},
10118         { 0x0301,       "Mac Query FS Info"},
10119         { 1001,         "Query FS Label Info"},
10120         { 1002,         "Query FS Volume Info"},
10121         { 1003,         "Query FS Size Info"},
10122         { 1004,         "Query FS Device Info"},
10123         { 1005,         "Query FS Attribute Info"},
10124         { 1006,         "Query FS Quota Info"},
10125         { 1007,         "Query Full FS Size Info"},
10126         { 1008,         "Object ID Information"},
10127         {0, NULL}
10128 };
10129
10130 static const value_string nt_rename_vals[] = {
10131         { 0x0103,       "Create Hard Link"},
10132         {0, NULL}
10133 };
10134
10135
10136 static const value_string delete_pending_vals[] = {
10137         {0,     "Normal, no pending delete"},
10138         {1,     "This object has DELETE PENDING"},
10139         {0, NULL}
10140 };
10141
10142 static const value_string alignment_vals[] = {
10143         {0,     "Byte alignment"},
10144         {1,     "Word (16bit) alignment"},
10145         {3,     "Long (32bit) alignment"},
10146         {7,     "8 byte boundary alignment"},
10147         {0x0f,  "16 byte boundary alignment"},
10148         {0x1f,  "32 byte boundary alignment"},
10149         {0x3f,  "64 byte boundary alignment"},
10150         {0x7f,  "128 byte boundary alignment"},
10151         {0xff,  "256 byte boundary alignment"},
10152         {0x1ff, "512 byte boundary alignment"},
10153         {0, NULL}
10154 };
10155
10156 static const true_false_string tfs_marked_for_deletion = {
10157         "File is MARKED FOR DELETION",
10158         "File is NOT marked for deletion"
10159 };
10160
10161 static const true_false_string tfs_get_dfs_server_hold_storage = {
10162         "Referral SERVER HOLDS STORAGE for the file",
10163         "Referral server does NOT hold storage for the file"
10164 };
10165 static const true_false_string tfs_get_dfs_fielding = {
10166         "The server in referral is FIELDING CAPABLE",
10167         "The server in referrals is NOT fielding capable"
10168 };
10169
10170 static const true_false_string tfs_dfs_referral_flags_strip = {
10171         "STRIP off pathconsumed characters before submitting",
10172         "Do NOT strip off any characters"
10173 };
10174
10175 static const value_string dfs_referral_server_type_vals[] = {
10176         {0,     "Don't know"},
10177         {1,     "SMB Server"},
10178         {2,     "Netware Server"},
10179         {3,     "Domain Server"},
10180         {0, NULL}
10181 };
10182
10183
10184 static const true_false_string tfs_device_char_removable = {
10185         "This is a REMOVABLE device",
10186         "This is NOT a removable device"
10187 };
10188 static const true_false_string tfs_device_char_read_only = {
10189         "This is a READ-ONLY device",
10190         "This is NOT a read-only device"
10191 };
10192 static const true_false_string tfs_device_char_floppy = {
10193         "This is a FLOPPY DISK device",
10194         "This is NOT a floppy disk device"
10195 };
10196 static const true_false_string tfs_device_char_write_once = {
10197         "This is a WRITE-ONCE device",
10198         "This is NOT a write-once device"
10199 };
10200 static const true_false_string tfs_device_char_remote = {
10201         "This is a REMOTE device",
10202         "This is NOT a remote device"
10203 };
10204 static const true_false_string tfs_device_char_mounted = {
10205         "This device is MOUNTED",
10206         "This device is NOT mounted"
10207 };
10208 static const true_false_string tfs_device_char_virtual = {
10209         "This is a VIRTUAL device",
10210         "This is NOT a virtual device"
10211 };
10212
10213
10214 static const true_false_string tfs_fs_attr_css = {
10215         "This FS supports CASE SENSITIVE SEARCHes",
10216         "This FS does NOT support case sensitive searches"
10217 };
10218 static const true_false_string tfs_fs_attr_cpn = {
10219         "This FS supports CASE PRESERVED NAMES",
10220         "This FS does NOT support case preserved names"
10221 };
10222 static const true_false_string tfs_fs_attr_uod = {
10223         "This FS supports UNICODE NAMES",
10224         "This FS does NOT support unicode names"
10225 };
10226 static const true_false_string tfs_fs_attr_pacls = {
10227         "This FS supports PERSISTENT ACLs",
10228         "This FS does NOT support persistent acls"
10229 };
10230 static const true_false_string tfs_fs_attr_fc = {
10231         "This FS supports COMPRESSED FILES",
10232         "This FS does NOT support compressed files"
10233 };
10234 static const true_false_string tfs_fs_attr_vq = {
10235         "This FS supports VOLUME QUOTAS",
10236         "This FS does NOT support volume quotas"
10237 };
10238 static const true_false_string tfs_fs_attr_srp = {
10239         "This FS supports REPARSE POINTS",
10240         "This FS does NOT support reparse points"
10241 };
10242 static const true_false_string tfs_fs_attr_srs = {
10243         "This FS supports REMOTE STORAGE",
10244         "This FS does NOT support remote storage"
10245 };
10246 static const true_false_string tfs_fs_attr_ssf = {
10247         "This FS supports SPARSE FILES",
10248         "This FS does NOT support sparse files"
10249 };
10250 static const true_false_string tfs_fs_attr_sla = {
10251         "This FS supports LFN APIs",
10252         "This FS does NOT support lfn apis"
10253 };
10254 static const true_false_string tfs_fs_attr_vic = {
10255         "This FS VOLUME IS COMPRESSED",
10256         "This FS volume is NOT compressed"
10257 };
10258 static const true_false_string tfs_fs_attr_soids = {
10259         "This FS supports OIDs",
10260         "This FS does NOT support OIDs"
10261 };
10262 static const true_false_string tfs_fs_attr_se = {
10263         "This FS supports ENCRYPTION",
10264         "This FS does NOT support encryption"
10265 };
10266 static const true_false_string tfs_fs_attr_ns = {
10267         "This FS supports NAMED STREAMS",
10268         "This FS does NOT support named streams"
10269 };
10270 static const true_false_string tfs_fs_attr_rov = {
10271         "This is a READ ONLY VOLUME",
10272         "This is a read/write volume"
10273 };
10274
10275 #define FF2_RESUME      0x0004
10276
10277 static int
10278 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10279 {
10280         guint16 mask;
10281         proto_item *item = NULL;
10282         proto_tree *tree = NULL;
10283         smb_info_t *si;
10284         smb_transact2_info_t *t2i;
10285
10286         mask = tvb_get_letohs(tvb, offset);
10287
10288         si = (smb_info_t *)pinfo->private_data;
10289         DISSECTOR_ASSERT(si);
10290
10291         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
10292                 t2i = si->sip->extra_info;
10293                 if (t2i != NULL) {
10294                         if (!pinfo->fd->flags.visited)
10295                                 t2i->resume_keys = (mask & FF2_RESUME);
10296                 }
10297         }
10298
10299         if(parent_tree){
10300                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10301                         "Flags: 0x%04x", mask);
10302                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
10303
10304                 proto_tree_add_boolean(tree, hf_smb_ff2_backup,
10305                         tvb, offset, 2, mask);
10306                 proto_tree_add_boolean(tree, hf_smb_ff2_continue,
10307                         tvb, offset, 2, mask);
10308                 proto_tree_add_boolean(tree, hf_smb_ff2_resume,
10309                         tvb, offset, 2, mask);
10310                 proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
10311                         tvb, offset, 2, mask);
10312                 proto_tree_add_boolean(tree, hf_smb_ff2_close,
10313                         tvb, offset, 2, mask);
10314         }
10315
10316         offset += 2;
10317
10318         return offset;
10319 }
10320
10321 #if 0
10322 static int
10323 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10324 {
10325         guint16 mask;
10326         proto_item *item;
10327         proto_tree *tree;
10328
10329         mask = tvb_get_letohs(tvb, offset);
10330
10331         if(parent_tree){
10332                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10333                         "IO Flag: 0x%04x", mask);
10334                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10335
10336                 proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10337                         tvb, offset, 2, mask);
10338                 proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10339                         tvb, offset, 2, mask);
10340         }
10341
10342         offset += 2;
10343
10344         return offset;
10345 }
10346 #endif
10347
10348 static int
10349 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10350     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
10351 {
10352         proto_item *item = NULL;
10353         proto_tree *tree = NULL;
10354         smb_info_t *si;
10355         smb_transact2_info_t *t2i;
10356         int fn_len;
10357         const char *fn;
10358
10359         si = (smb_info_t *)pinfo->private_data;
10360         DISSECTOR_ASSERT(si);
10361
10362         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
10363                 t2i = si->sip->extra_info;
10364         else
10365                 t2i = NULL;
10366
10367         if(parent_tree){
10368                 tvb_ensure_bytes_exist(tvb, offset, bc);
10369                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10370                                 "%s Parameters",
10371                                 val_to_str(subcmd, trans2_cmd_vals,
10372                                            "Unknown (0x%02x)"));
10373                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10374         }
10375
10376         switch(subcmd){
10377         case 0x00:      /*TRANS2_OPEN2*/
10378                 /* open flags */
10379                 CHECK_BYTE_COUNT_TRANS(2);
10380                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10381                 bc -= 2;
10382
10383                 /* desired access */
10384                 CHECK_BYTE_COUNT_TRANS(2);
10385                 offset = dissect_access(tvb, tree, offset, "Desired");
10386                 bc -= 2;
10387
10388                 /* Search Attributes */
10389                 CHECK_BYTE_COUNT_TRANS(2);
10390                 offset = dissect_search_attributes(tvb, tree, offset);
10391                 bc -= 2;
10392
10393                 /* File Attributes */
10394                 CHECK_BYTE_COUNT_TRANS(2);
10395                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10396                 bc -= 2;
10397
10398                 /* create time */
10399                 CHECK_BYTE_COUNT_TRANS(4);
10400                 offset = dissect_smb_datetime(tvb, tree, offset,
10401                         hf_smb_create_time,
10402                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10403                         TRUE);
10404                 bc -= 4;
10405
10406                 /* open function */
10407                 CHECK_BYTE_COUNT_TRANS(2);
10408                 offset = dissect_open_function(tvb, tree, offset);
10409                 bc -= 2;
10410
10411                 /* allocation size */
10412                 CHECK_BYTE_COUNT_TRANS(4);
10413                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10414                 COUNT_BYTES_TRANS(4);
10415
10416                 /* 10 reserved bytes */
10417                 CHECK_BYTE_COUNT_TRANS(10);
10418                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10419                 COUNT_BYTES_TRANS(10);
10420
10421                 /* file name */
10422                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10423                 CHECK_STRING_TRANS(fn);
10424                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10425                         fn);
10426                 COUNT_BYTES_TRANS(fn_len);
10427
10428                 if (check_col(pinfo->cinfo, COL_INFO)) {
10429                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10430                             format_text(fn, strlen(fn)));
10431                 }
10432                 break;
10433         case 0x01:      /*TRANS2_FIND_FIRST2*/
10434                 /* Search Attributes */
10435                 CHECK_BYTE_COUNT_TRANS(2);
10436                 offset = dissect_search_attributes(tvb, tree, offset);
10437                 bc -= 2;
10438
10439                 /* search count */
10440                 CHECK_BYTE_COUNT_TRANS(2);
10441                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10442                 COUNT_BYTES_TRANS(2);
10443
10444                 /* Find First2 flags */
10445                 CHECK_BYTE_COUNT_TRANS(2);
10446                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10447                 bc -= 2;
10448
10449                 /* Find First2 information level */
10450                 CHECK_BYTE_COUNT_TRANS(2);
10451                 si->info_level = tvb_get_letohs(tvb, offset);
10452                 if (t2i != NULL && !pinfo->fd->flags.visited)
10453                         t2i->info_level = si->info_level;
10454                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10455                 COUNT_BYTES_TRANS(2);
10456
10457                 /* storage type */
10458                 CHECK_BYTE_COUNT_TRANS(4);
10459                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10460                 COUNT_BYTES_TRANS(4);
10461
10462                 /* search pattern */
10463                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10464                 CHECK_STRING_TRANS(fn);
10465                 if(t2i && !t2i->name){
10466                         t2i->name = se_strdup(fn);
10467                 }
10468                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10469                         fn);
10470                 COUNT_BYTES_TRANS(fn_len);
10471
10472                 if (check_col(pinfo->cinfo, COL_INFO)) {
10473                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10474                             format_text(fn, strlen(fn)));
10475                 }
10476
10477                 break;
10478         case 0x02:      /*TRANS2_FIND_NEXT2*/
10479                 /* sid */
10480                 CHECK_BYTE_COUNT_TRANS(2);
10481                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10482                 COUNT_BYTES_TRANS(2);
10483
10484                 /* search count */
10485                 CHECK_BYTE_COUNT_TRANS(2);
10486                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10487                 COUNT_BYTES_TRANS(2);
10488
10489                 /* Find First2 information level */
10490                 CHECK_BYTE_COUNT_TRANS(2);
10491                 si->info_level = tvb_get_letohs(tvb, offset);
10492                 if (t2i != NULL && !pinfo->fd->flags.visited)
10493                         t2i->info_level = si->info_level;
10494                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10495                 COUNT_BYTES_TRANS(2);
10496
10497                 /* resume key */
10498                 CHECK_BYTE_COUNT_TRANS(4);
10499                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10500                 COUNT_BYTES_TRANS(4);
10501
10502                 /* Find First2 flags */
10503                 CHECK_BYTE_COUNT_TRANS(2);
10504                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10505                 bc -= 2;
10506
10507                 /* file name */
10508                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10509                 CHECK_STRING_TRANS(fn);
10510                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10511                         fn);
10512                 COUNT_BYTES_TRANS(fn_len);
10513
10514                 if (check_col(pinfo->cinfo, COL_INFO)) {
10515                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10516                             format_text(fn, strlen(fn)));
10517                 }
10518
10519                 break;
10520         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10521                 /* level of interest */
10522                 CHECK_BYTE_COUNT_TRANS(2);
10523                 si->info_level = tvb_get_letohs(tvb, offset);
10524                 if (t2i != NULL && !pinfo->fd->flags.visited)
10525                         t2i->info_level = si->info_level;
10526                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10527                 COUNT_BYTES_TRANS(2);
10528
10529                 if (check_col(pinfo->cinfo, COL_INFO))
10530                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10531                                         val_to_str(si->info_level, qfsi_vals,
10532                                                    "Unknown (0x%02x)"));
10533
10534                 break;
10535         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10536                 /* level of interest */
10537                 CHECK_BYTE_COUNT_TRANS(2);
10538                 si->info_level = tvb_get_letohs(tvb, offset);
10539                 if (t2i != NULL && !pinfo->fd->flags.visited)
10540                         t2i->info_level = si->info_level;
10541                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10542                 COUNT_BYTES_TRANS(2);
10543
10544                 if (check_col(pinfo->cinfo, COL_INFO)) {
10545                         col_append_fstr(
10546                                 pinfo->cinfo, COL_INFO, ", %s",
10547                                 val_to_str(si->info_level, qpi_loi_vals,
10548                                            "Unknown (%u)"));
10549                 }
10550
10551                 /* 4 reserved bytes */
10552                 CHECK_BYTE_COUNT_TRANS(4);
10553                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10554                 COUNT_BYTES_TRANS(4);
10555
10556                 /* file name */
10557                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10558                 CHECK_STRING_TRANS(fn);
10559                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10560                         fn);
10561                 COUNT_BYTES_TRANS(fn_len);
10562                 if(t2i && !t2i->name){
10563                         t2i->name = se_strdup(fn);
10564                 }
10565
10566                 if (check_col(pinfo->cinfo, COL_INFO)) {
10567                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10568                             format_text(fn, strlen(fn)));
10569                 }
10570
10571                 break;
10572         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10573                 /* level of interest */
10574                 CHECK_BYTE_COUNT_TRANS(2);
10575                 si->info_level = tvb_get_letohs(tvb, offset);
10576                 if (t2i != NULL && !pinfo->fd->flags.visited)
10577                         t2i->info_level = si->info_level;
10578                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10579                 COUNT_BYTES_TRANS(2);
10580
10581                 /* 4 reserved bytes */
10582                 CHECK_BYTE_COUNT_TRANS(4);
10583                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10584                 COUNT_BYTES_TRANS(4);
10585
10586                 /* file name */
10587                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10588                 CHECK_STRING_TRANS(fn);
10589                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10590                         fn);
10591                 COUNT_BYTES_TRANS(fn_len);
10592
10593                 if (check_col(pinfo->cinfo, COL_INFO)) {
10594                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10595                             format_text(fn, strlen(fn)));
10596                 }
10597
10598                 break;
10599         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10600                 guint16 fid;
10601
10602                 /* fid */
10603                 CHECK_BYTE_COUNT_TRANS(2);
10604                 fid = tvb_get_letohs(tvb, offset);
10605                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10606                 COUNT_BYTES_TRANS(2);
10607
10608                 /* level of interest */
10609                 CHECK_BYTE_COUNT_TRANS(2);
10610                 si->info_level = tvb_get_letohs(tvb, offset);
10611                 if (t2i != NULL && !pinfo->fd->flags.visited)
10612                         t2i->info_level = si->info_level;
10613                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10614                 COUNT_BYTES_TRANS(2);
10615
10616                 if (check_col(pinfo->cinfo, COL_INFO)) {
10617                         col_append_fstr(
10618                                 pinfo->cinfo, COL_INFO, ", %s",
10619                                 val_to_str(si->info_level, qpi_loi_vals,
10620                                            "Unknown (%u)"));
10621                 }
10622
10623                 break;
10624         }
10625         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10626                 guint16 fid;
10627
10628                 /* fid */
10629                 CHECK_BYTE_COUNT_TRANS(2);
10630                 fid = tvb_get_letohs(tvb, offset);
10631                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10632                 COUNT_BYTES_TRANS(2);
10633
10634                 /* level of interest */
10635                 CHECK_BYTE_COUNT_TRANS(2);
10636                 si->info_level = tvb_get_letohs(tvb, offset);
10637                 if (t2i != NULL && !pinfo->fd->flags.visited)
10638                         t2i->info_level = si->info_level;
10639                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10640                 COUNT_BYTES_TRANS(2);
10641
10642 #if 0
10643                 /*
10644                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10645                  * Extensions Version 3.0, Document Version 1.11,
10646                  * July 19, 1990" says this is I/O flags, but it's
10647                  * reserved in the SNIA spec, and some clients appear
10648                  * to leave junk in it.
10649                  *
10650                  * Is this some field used only if a particular
10651                  * dialect was negotiated, so that clients can feel
10652                  * safe not setting it if they haven't negotiated that
10653                  * dialect?  Or do the (non-OS/2) clients simply not care
10654                  * about that particular OS/2-oriented dialect?
10655                  */
10656
10657                 /* IO Flag */
10658                 CHECK_BYTE_COUNT_TRANS(2);
10659                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10660                 bc -= 2;
10661 #else
10662                 /* 2 reserved bytes */
10663                 CHECK_BYTE_COUNT_TRANS(2);
10664                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10665                 COUNT_BYTES_TRANS(2);
10666 #endif
10667
10668                 break;
10669         }
10670         case 0x09:      /*TRANS2_FSCTL*/
10671                 /* this call has no parameter block in the request */
10672
10673                 /*
10674                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10675                  * Extensions Version 3.0, Document Version 1.11,
10676                  * July 19, 1990" says this this contains a
10677                  * "File system specific parameter block".  (That means
10678                  * we may not be able to dissect it in any case.)
10679                  */
10680                 break;
10681         case 0x0a:      /*TRANS2_IOCTL2*/
10682                 /* this call has no parameter block in the request */
10683
10684                 /*
10685                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10686                  * Extensions Version 3.0, Document Version 1.11,
10687                  * July 19, 1990" says this this contains a
10688                  * "Device/function specific parameter block".  (That
10689                  * means we may not be able to dissect it in any case.)
10690                  */
10691                 break;
10692         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10693                 /* Search Attributes */
10694                 CHECK_BYTE_COUNT_TRANS(2);
10695                 offset = dissect_search_attributes(tvb, tree, offset);
10696                 bc -= 2;
10697
10698                 /* Number of changes to wait for */
10699                 CHECK_BYTE_COUNT_TRANS(2);
10700                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10701                 COUNT_BYTES_TRANS(2);
10702
10703                 /* Find Notify information level */
10704                 CHECK_BYTE_COUNT_TRANS(2);
10705                 si->info_level = tvb_get_letohs(tvb, offset);
10706                 if (t2i != NULL && !pinfo->fd->flags.visited)
10707                         t2i->info_level = si->info_level;
10708                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10709                 COUNT_BYTES_TRANS(2);
10710
10711                 /* 4 reserved bytes */
10712                 CHECK_BYTE_COUNT_TRANS(4);
10713                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10714                 COUNT_BYTES_TRANS(4);
10715
10716                 /* file name */
10717                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10718                 CHECK_STRING_TRANS(fn);
10719                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10720                         fn);
10721                 COUNT_BYTES_TRANS(fn_len);
10722
10723                 if (check_col(pinfo->cinfo, COL_INFO)) {
10724                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10725                             format_text(fn, strlen(fn)));
10726                 }
10727
10728                 break;
10729         }
10730         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10731                 /* Monitor handle */
10732                 CHECK_BYTE_COUNT_TRANS(2);
10733                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10734                 COUNT_BYTES_TRANS(2);
10735
10736                 /* Number of changes to wait for */
10737                 CHECK_BYTE_COUNT_TRANS(2);
10738                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10739                 COUNT_BYTES_TRANS(2);
10740
10741                 break;
10742         }
10743         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10744                 /* 4 reserved bytes */
10745                 CHECK_BYTE_COUNT_TRANS(4);
10746                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10747                 COUNT_BYTES_TRANS(4);
10748
10749                 /* dir name */
10750                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10751                         FALSE, FALSE, &bc);
10752                 CHECK_STRING_TRANS(fn);
10753                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10754                         fn);
10755                 COUNT_BYTES_TRANS(fn_len);
10756
10757                 if (check_col(pinfo->cinfo, COL_INFO)) {
10758                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10759                             format_text(fn, strlen(fn)));
10760                 }
10761                 break;
10762         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10763                 /* XXX unknown structure*/
10764                 break;
10765         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10766                 /* referral level */
10767                 CHECK_BYTE_COUNT_TRANS(2);
10768                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10769                 COUNT_BYTES_TRANS(2);
10770
10771                 /* file name */
10772                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10773                 CHECK_STRING_TRANS(fn);
10774                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10775                         fn);
10776                 COUNT_BYTES_TRANS(fn_len);
10777
10778                 if (check_col(pinfo->cinfo, COL_INFO)) {
10779                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10780                             format_text(fn, strlen(fn)));
10781                 }
10782
10783                 break;
10784         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10785                 /* file name */
10786                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10787                 CHECK_STRING_TRANS(fn);
10788                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10789                         fn);
10790                 COUNT_BYTES_TRANS(fn_len);
10791
10792                 if (check_col(pinfo->cinfo, COL_INFO)) {
10793                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10794                             format_text(fn, strlen(fn)));
10795                 }
10796
10797                 break;
10798         }
10799
10800         /* ooops there were data we didnt know how to process */
10801         if(bc != 0){
10802                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10803                 offset += bc;
10804         }
10805
10806         return offset;
10807 }
10808
10809 /*
10810  * XXX - just use "dissect_connect_flags()" here?
10811  */
10812 static guint16
10813 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10814 {
10815         guint16 mask;
10816         proto_item *item;
10817         proto_tree *tree;
10818
10819         mask = tvb_get_letohs(tvb, offset);
10820
10821         if(parent_tree){
10822                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10823                         "Flags: 0x%04x", mask);
10824                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10825
10826                 proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10827                         tvb, offset, 2, mask);
10828                 proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10829                         tvb, offset, 2, mask);
10830         }
10831
10832         return mask;
10833 }
10834
10835
10836 static int
10837 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10838 {
10839         guint16 mask;
10840         proto_item *item;
10841         proto_tree *tree;
10842
10843         mask = tvb_get_letohs(tvb, offset);
10844
10845         if(parent_tree){
10846                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10847                         "Flags: 0x%04x", mask);
10848                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10849
10850                 proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10851                         tvb, offset, 2, mask);
10852                 proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10853                         tvb, offset, 2, mask);
10854         }
10855
10856         offset += 2;
10857         return offset;
10858 }
10859
10860 static int
10861 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10862 {
10863         guint16 mask;
10864         proto_item *item;
10865         proto_tree *tree;
10866
10867         mask = tvb_get_letohs(tvb, offset);
10868
10869         if(parent_tree){
10870                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10871                         "Flags: 0x%04x", mask);
10872                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10873
10874                 proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10875                         tvb, offset, 2, mask);
10876         }
10877
10878         offset += 2;
10879
10880         return offset;
10881 }
10882
10883
10884 /* dfs inconsistency data  (4.4.2)
10885 */
10886 static int
10887 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10888     proto_tree *tree, int offset, guint16 *bcp)
10889 {
10890         smb_info_t *si = pinfo->private_data;
10891         int fn_len;
10892         const char *fn;
10893
10894         DISSECTOR_ASSERT(si);
10895
10896         /*XXX shouldn this data hold version and size? unclear from doc*/
10897         /* referral version */
10898         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10899         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10900         COUNT_BYTES_TRANS_SUBR(2);
10901
10902         /* referral size */
10903         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10904         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10905         COUNT_BYTES_TRANS_SUBR(2);
10906
10907         /* referral server type */
10908         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10909         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10910         COUNT_BYTES_TRANS_SUBR(2);
10911
10912         /* referral flags */
10913         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10914         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10915         *bcp -= 2;
10916
10917         /* node name */
10918         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10919         CHECK_STRING_TRANS_SUBR(fn);
10920         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10921                 fn);
10922         COUNT_BYTES_TRANS_SUBR(fn_len);
10923
10924         return offset;
10925 }
10926
10927 /* get dfs referral data  (4.4.1)
10928 */
10929 static int
10930 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10931     proto_tree *tree, int offset, guint16 *bcp)
10932 {
10933         smb_info_t *si = pinfo->private_data;
10934         guint16 numref;
10935         guint16 refsize;
10936         guint16 pathoffset;
10937         guint16 altpathoffset;
10938         guint16 nodeoffset;
10939         int fn_len;
10940         int stroffset;
10941         int offsetoffset;
10942         guint16 save_bc;
10943         const char *fn;
10944         int unklen;
10945         int ucstring_end;
10946         int ucstring_len;
10947
10948         DISSECTOR_ASSERT(si);
10949
10950         /* path consumed */
10951         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10952         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10953         COUNT_BYTES_TRANS_SUBR(2);
10954
10955         /* num referrals */
10956         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10957         numref = tvb_get_letohs(tvb, offset);
10958         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10959         COUNT_BYTES_TRANS_SUBR(2);
10960
10961         /* get dfs flags */
10962         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10963         offset = dissect_get_dfs_flags(tvb, tree, offset);
10964         *bcp -= 2;
10965
10966         /* XXX - in at least one capture there appears to be 2 bytes
10967            of stuff after the Dfs flags, perhaps so that the header
10968            in front of the referral list is a multiple of 4 bytes long. */
10969         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10970         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10971         COUNT_BYTES_TRANS_SUBR(2);
10972
10973         /* if there are any referrals */
10974         if(numref){
10975                 proto_item *ref_item = NULL;
10976                 proto_tree *ref_tree = NULL;
10977                 int old_offset=offset;
10978
10979                 if(tree){
10980                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
10981                         ref_item = proto_tree_add_text(tree,
10982                                 tvb, offset, *bcp, "Referrals");
10983                         ref_tree = proto_item_add_subtree(ref_item,
10984                                 ett_smb_dfs_referrals);
10985                 }
10986                 ucstring_end = -1;
10987
10988                 while(numref--){
10989                         proto_item *ri = NULL;
10990                         proto_tree *rt = NULL;
10991                         int old_offset=offset;
10992                         guint16 version;
10993
10994                         if(tree){
10995                                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
10996                                 ri = proto_tree_add_text(ref_tree,
10997                                         tvb, offset, *bcp, "Referral");
10998                                 rt = proto_item_add_subtree(ri,
10999                                         ett_smb_dfs_referral);
11000                         }
11001
11002                         /* referral version */
11003                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11004                         version = tvb_get_letohs(tvb, offset);
11005                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
11006                                 tvb, offset, 2, version);
11007                         COUNT_BYTES_TRANS_SUBR(2);
11008
11009                         /* referral size */
11010                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11011                         refsize = tvb_get_letohs(tvb, offset);
11012                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
11013                         COUNT_BYTES_TRANS_SUBR(2);
11014
11015                         /* referral server type */
11016                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11017                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
11018                         COUNT_BYTES_TRANS_SUBR(2);
11019
11020                         /* referral flags */
11021                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11022                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
11023                         *bcp -= 2;
11024
11025                         switch(version){
11026
11027                         case 1:
11028                                 /* node name */
11029                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11030                                 CHECK_STRING_TRANS_SUBR(fn);
11031                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
11032                                         fn);
11033                                 COUNT_BYTES_TRANS_SUBR(fn_len);
11034                                 break;
11035
11036                         case 2:
11037                         case 3: /* XXX - like version 2, but not identical;
11038                                    seen in a capture, but the format isn't
11039                                    documented */
11040                                 /* proximity */
11041                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11042                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
11043                                 COUNT_BYTES_TRANS_SUBR(2);
11044
11045                                 /* ttl */
11046                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11047                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
11048                                 COUNT_BYTES_TRANS_SUBR(2);
11049
11050                                 /* path offset */
11051                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11052                                 pathoffset = tvb_get_letohs(tvb, offset);
11053                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11054                                 COUNT_BYTES_TRANS_SUBR(2);
11055
11056                                 /* alt path offset */
11057                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11058                                 altpathoffset = tvb_get_letohs(tvb, offset);
11059                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11060                                 COUNT_BYTES_TRANS_SUBR(2);
11061
11062                                 /* node offset */
11063                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11064                                 nodeoffset = tvb_get_letohs(tvb, offset);
11065                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11066                                 COUNT_BYTES_TRANS_SUBR(2);
11067
11068                                 /* path */
11069                                 if (pathoffset != 0) {
11070                                         stroffset = old_offset + pathoffset;
11071                                         offsetoffset = stroffset - offset;
11072                                         if (offsetoffset > 0 &&
11073                                             *bcp > offsetoffset) {
11074                                                 save_bc = *bcp;
11075                                                 *bcp -= offsetoffset;
11076                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11077                                                 CHECK_STRING_TRANS_SUBR(fn);
11078                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
11079                                                         fn);
11080                                                 stroffset += fn_len;
11081                                                 if (ucstring_end < stroffset)
11082                                                         ucstring_end = stroffset;
11083                                                 *bcp = save_bc;
11084                                         }
11085                                 }
11086
11087                                 /* alt path */
11088                                 if (altpathoffset != 0) {
11089                                         stroffset = old_offset + altpathoffset;
11090                                         offsetoffset = stroffset - offset;
11091                                         if (offsetoffset > 0 &&
11092                                             *bcp > offsetoffset) {
11093                                                 save_bc = *bcp;
11094                                                 *bcp -= offsetoffset;
11095                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11096                                                 CHECK_STRING_TRANS_SUBR(fn);
11097                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
11098                                                         fn);
11099                                                 stroffset += fn_len;
11100                                                 if (ucstring_end < stroffset)
11101                                                         ucstring_end = stroffset;
11102                                                 *bcp = save_bc;
11103                                         }
11104                                 }
11105
11106                                 /* node */
11107                                 if (nodeoffset != 0) {
11108                                         stroffset = old_offset + nodeoffset;
11109                                         offsetoffset = stroffset - offset;
11110                                         if (offsetoffset > 0 &&
11111                                             *bcp > offsetoffset) {
11112                                                 save_bc = *bcp;
11113                                                 *bcp -= offsetoffset;
11114                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11115                                                 CHECK_STRING_TRANS_SUBR(fn);
11116                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
11117                                                         fn);
11118                                                 stroffset += fn_len;
11119                                                 if (ucstring_end < stroffset)
11120                                                         ucstring_end = stroffset;
11121                                                 *bcp = save_bc;
11122                                         }
11123                                 }
11124                                 break;
11125                         }
11126
11127                         /*
11128                          * Show anything beyond the length of the referral
11129                          * as unknown data.
11130                          */
11131                         unklen = (old_offset + refsize) - offset;
11132                         if (unklen < 0) {
11133                                 /*
11134                                  * XXX - the length is bogus.
11135                                  */
11136                                 unklen = 0;
11137                         }
11138                         if (unklen != 0) {
11139                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
11140                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
11141                                     offset, unklen, TRUE);
11142                                 COUNT_BYTES_TRANS_SUBR(unklen);
11143                         }
11144
11145                         proto_item_set_len(ri, offset-old_offset);
11146                 }
11147
11148                 /*
11149                  * Treat the offset past the end of the last Unicode
11150                  * string after the referrals (if any) as the last
11151                  * offset.
11152                  */
11153                 if (ucstring_end > offset) {
11154                         ucstring_len = ucstring_end - offset;
11155                         if (*bcp < ucstring_len)
11156                                 ucstring_len = *bcp;
11157                         offset += ucstring_len;
11158                         *bcp -= ucstring_len;
11159                 }
11160                 proto_item_set_len(ref_item, offset-old_offset);
11161         }
11162
11163         return offset;
11164 }
11165
11166 /* This dissects the standard four 8-byte Windows timestamps ...
11167  */
11168 static int
11169 dissect_smb_standard_8byte_timestamps(tvbuff_t *tvb,
11170     packet_info *pinfo _U_, proto_tree *tree,
11171     int offset, guint16 *bcp, gboolean *trunc)
11172 {
11173         /* create time */
11174         CHECK_BYTE_COUNT_SUBR(8);
11175         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11176         *bcp -= 8;
11177
11178         /* access time */
11179         CHECK_BYTE_COUNT_SUBR(8);
11180         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
11181         *bcp -= 8;
11182
11183         /* last write time */
11184         CHECK_BYTE_COUNT_SUBR(8);
11185         offset = dissect_nt_64bit_time(tvb, tree, offset,
11186                 hf_smb_last_write_time);
11187         *bcp -= 8;
11188
11189         /* last change time */
11190         CHECK_BYTE_COUNT_SUBR(8);
11191         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
11192         *bcp -= 8;
11193
11194         *trunc = FALSE;
11195         return offset;
11196 }
11197
11198 /* this dissects the SMB_INFO_STANDARD
11199    as described in 4.2.16.1
11200 */
11201 static int
11202 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11203     int offset, guint16 *bcp, gboolean *trunc)
11204 {
11205         /* create time */
11206         CHECK_BYTE_COUNT_SUBR(4);
11207         offset = dissect_smb_datetime(tvb, tree, offset,
11208                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
11209                 FALSE);
11210         *bcp -= 4;
11211
11212         /* access time */
11213         CHECK_BYTE_COUNT_SUBR(4);
11214         offset = dissect_smb_datetime(tvb, tree, offset,
11215                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
11216                 FALSE);
11217         *bcp -= 4;
11218
11219         /* last write time */
11220         CHECK_BYTE_COUNT_SUBR(4);
11221         offset = dissect_smb_datetime(tvb, tree, offset,
11222                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
11223                 FALSE);
11224         *bcp -= 4;
11225
11226         /* data size */
11227         CHECK_BYTE_COUNT_SUBR(4);
11228         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11229         COUNT_BYTES_SUBR(4);
11230
11231         /* allocation size */
11232         CHECK_BYTE_COUNT_SUBR(4);
11233         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11234         COUNT_BYTES_SUBR(4);
11235
11236         /* File Attributes */
11237         CHECK_BYTE_COUNT_SUBR(2);
11238         offset = dissect_file_attributes(tvb, tree, offset, 2);
11239         *bcp -= 2;
11240
11241         /* ea length */
11242         CHECK_BYTE_COUNT_SUBR(4);
11243         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11244         COUNT_BYTES_SUBR(4);
11245
11246         *trunc = FALSE;
11247         return offset;
11248 }
11249
11250 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
11251    as described in 4.2.16.2
11252 */
11253 static int
11254 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11255     int offset, guint16 *bcp, gboolean *trunc)
11256 {
11257         guint8 name_len;
11258         guint16 data_len;
11259         /* EA size */
11260
11261         CHECK_BYTE_COUNT_SUBR(4);
11262         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11263         COUNT_BYTES_SUBR(4);
11264
11265         while (*bcp > 0) {
11266                 proto_item *item;
11267                 proto_tree *subtree;
11268                 int start_offset = offset;
11269                 guint8 *name;
11270
11271                 item = proto_tree_add_text(
11272                         tree, tvb, offset, 0, "Extended Attribute");
11273                 subtree = proto_item_add_subtree(item, ett_smb_ea);
11274
11275                 /* EA flags */
11276
11277                 CHECK_BYTE_COUNT_SUBR(1);
11278                 proto_tree_add_item(
11279                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
11280                 COUNT_BYTES_SUBR(1);
11281
11282                 /* EA name length */
11283
11284                 name_len = tvb_get_guint8(tvb, offset);
11285
11286                 CHECK_BYTE_COUNT_SUBR(1);
11287                 proto_tree_add_item(
11288                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
11289                 COUNT_BYTES_SUBR(1);
11290
11291                 /* EA data length */
11292
11293                 data_len = tvb_get_letohs(tvb, offset);
11294
11295                 CHECK_BYTE_COUNT_SUBR(2);
11296                 proto_tree_add_item(
11297                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
11298                 COUNT_BYTES_SUBR(2);
11299
11300                 /* EA name */
11301
11302                 name = tvb_get_ephemeral_string(tvb, offset, name_len);
11303                 proto_item_append_text(item, ": %s", format_text(name, strlen(name)));
11304
11305                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
11306                 proto_tree_add_item(
11307                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1,
11308                         TRUE);
11309                 COUNT_BYTES_SUBR(name_len + 1);
11310
11311                 /* EA data */
11312
11313                 CHECK_BYTE_COUNT_SUBR(data_len);
11314                 proto_tree_add_item(
11315                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
11316                 COUNT_BYTES_SUBR(data_len);
11317
11318                 proto_item_set_len(item, offset - start_offset);
11319         }
11320
11321         *trunc = FALSE;
11322         return offset;
11323 }
11324
11325 /* this dissects the SMB_INFO_IS_NAME_VALID
11326    as described in 4.2.16.3
11327 */
11328 static int
11329 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11330     int offset, guint16 *bcp, gboolean *trunc)
11331 {
11332         smb_info_t *si = pinfo->private_data;
11333         int fn_len;
11334         const char *fn;
11335
11336         DISSECTOR_ASSERT(si);
11337
11338         /* file name */
11339         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11340         CHECK_STRING_SUBR(fn);
11341         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11342                 fn);
11343         COUNT_BYTES_SUBR(fn_len);
11344
11345         *trunc = FALSE;
11346         return offset;
11347 }
11348
11349 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
11350    as described in 4.2.16.4
11351 */
11352 static int
11353 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11354     int offset, guint16 *bcp, gboolean *trunc)
11355 {
11356
11357         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11358         if (*trunc) {
11359           return offset;
11360         }
11361
11362         /* File Attributes */
11363         CHECK_BYTE_COUNT_SUBR(4);
11364         offset = dissect_file_attributes(tvb, tree, offset, 4);
11365         *bcp -= 4;
11366
11367         *trunc = FALSE;
11368         return offset;
11369 }
11370
11371 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
11372    as described in 4.2.16.5
11373 */
11374 int
11375 dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11376     int offset, guint16 *bcp, gboolean *trunc)
11377 {
11378         /* allocation size */
11379         CHECK_BYTE_COUNT_SUBR(8);
11380         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11381         COUNT_BYTES_SUBR(8);
11382
11383         /* end of file */
11384         CHECK_BYTE_COUNT_SUBR(8);
11385         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11386         COUNT_BYTES_SUBR(8);
11387
11388         /* number of links */
11389         CHECK_BYTE_COUNT_SUBR(4);
11390         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11391         COUNT_BYTES_SUBR(4);
11392
11393         /* delete pending */
11394         CHECK_BYTE_COUNT_SUBR(1);
11395         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11396         COUNT_BYTES_SUBR(1);
11397
11398         /* is directory */
11399         CHECK_BYTE_COUNT_SUBR(1);
11400         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11401         COUNT_BYTES_SUBR(1);
11402
11403         *trunc = FALSE;
11404         return offset;
11405 }
11406
11407 /* this dissects the SMB_QUERY_FILE_INTERNAL_INFO
11408 */
11409 int
11410 dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11411     int offset, guint16 *bcp, gboolean *trunc)
11412 {
11413         /* file id */
11414         CHECK_BYTE_COUNT_SUBR(8);
11415         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11416         COUNT_BYTES_SUBR(8);
11417
11418         *trunc = FALSE;
11419         return offset;
11420 }
11421
11422 /* this dissects the SMB_QUERY_FILE_POSITION_INFO
11423 */
11424 int
11425 dissect_qfi_SMB_FILE_POSITION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11426     int offset, guint16 *bcp, gboolean *trunc)
11427 {
11428         /* file id */
11429         CHECK_BYTE_COUNT_SUBR(8);
11430         proto_tree_add_item(tree, hf_smb_position, tvb, offset, 8, TRUE);
11431         COUNT_BYTES_SUBR(8);
11432
11433         *trunc = FALSE;
11434         return offset;
11435 }
11436
11437 /* this dissects the SMB_QUERY_FILE_MODE_INFO
11438 */
11439 int
11440 dissect_qfi_SMB_FILE_MODE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11441     int offset, guint16 *bcp, gboolean *trunc)
11442 {
11443         /* mode */
11444         CHECK_BYTE_COUNT_SUBR(4);
11445         proto_tree_add_item(tree, hf_smb_mode, tvb, offset, 4, TRUE);
11446         COUNT_BYTES_SUBR(4);
11447
11448         *trunc = FALSE;
11449         return offset;
11450 }
11451
11452 /* this dissects the SMB_QUERY_FILE_ALIGNMENT_INFO
11453 */
11454 int
11455 dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11456     int offset, guint16 *bcp, gboolean *trunc)
11457 {
11458         /* alignment */
11459         CHECK_BYTE_COUNT_SUBR(4);
11460         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11461         COUNT_BYTES_SUBR(4);
11462
11463         *trunc = FALSE;
11464         return offset;
11465 }
11466
11467 /* this dissects the SMB_QUERY_FILE_EA_INFO
11468    as described in 4.2.16.6
11469 */
11470 int
11471 dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11472     int offset, guint16 *bcp, gboolean *trunc)
11473 {
11474         /* ea length */
11475         CHECK_BYTE_COUNT_SUBR(4);
11476         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11477         COUNT_BYTES_SUBR(4);
11478
11479         *trunc = FALSE;
11480         return offset;
11481 }
11482
11483 /* this dissects the SMB_QUERY_FILE_ALLOCATION_INFO
11484 */
11485 int
11486 dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11487     int offset, guint16 *bcp, gboolean *trunc)
11488 {
11489         /* allocation size */
11490         CHECK_BYTE_COUNT_SUBR(8);
11491         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11492         COUNT_BYTES_SUBR(8);
11493
11494         *trunc = FALSE;
11495         return offset;
11496 }
11497
11498 /* this dissects the SMB_QUERY_FILE_ENDOFFILE_INFO
11499 */
11500 int
11501 dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11502     int offset, guint16 *bcp, gboolean *trunc)
11503 {
11504         /* end of file */
11505         CHECK_BYTE_COUNT_SUBR(8);
11506         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11507         COUNT_BYTES_SUBR(8);
11508
11509         *trunc = FALSE;
11510         return offset;
11511 }
11512
11513 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11514    as described in 4.2.16.7
11515    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11516    as described in 4.2.16.9
11517 */
11518 int
11519 dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11520     int offset, guint16 *bcp, gboolean *trunc)
11521 {
11522         smb_info_t *si = pinfo->private_data;
11523         int fn_len;
11524         const char *fn;
11525
11526         DISSECTOR_ASSERT(si);
11527
11528         /* file name len */
11529         CHECK_BYTE_COUNT_SUBR(4);
11530         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11531         COUNT_BYTES_SUBR(4);
11532
11533         /* file name */
11534         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11535         CHECK_STRING_SUBR(fn);
11536         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11537                 fn);
11538         COUNT_BYTES_SUBR(fn_len);
11539
11540         *trunc = FALSE;
11541         return offset;
11542 }
11543
11544 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11545    but not as described in 4.2.16.8 since CNIA spec is wrong
11546 */
11547 static int
11548 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11549     int offset, guint16 *bcp, gboolean *trunc)
11550 {
11551         smb_info_t *si;
11552         guint32 fn_len;
11553         const char *fn;
11554
11555         si = (smb_info_t *)pinfo->private_data;
11556
11557         DISSECTOR_ASSERT(si);
11558
11559         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11560         if (*trunc) {
11561           return offset;
11562         }
11563
11564         /* File Attributes */
11565         CHECK_BYTE_COUNT_SUBR(4);
11566         offset = dissect_file_attributes(tvb, tree, offset, 4);
11567         *bcp -= 4;
11568
11569         /* 4 pad bytes */
11570         offset+=4;
11571         *bcp -= 4;
11572
11573         /* allocation size */
11574         CHECK_BYTE_COUNT_SUBR(8);
11575         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11576         COUNT_BYTES_SUBR(8);
11577
11578         /* end of file */
11579         CHECK_BYTE_COUNT_SUBR(8);
11580         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11581         COUNT_BYTES_SUBR(8);
11582
11583         /* number of links */
11584         CHECK_BYTE_COUNT_SUBR(4);
11585         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11586         COUNT_BYTES_SUBR(4);
11587
11588         /* delete pending */
11589         CHECK_BYTE_COUNT_SUBR(1);
11590         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11591         COUNT_BYTES_SUBR(1);
11592
11593         /* is directory */
11594         CHECK_BYTE_COUNT_SUBR(1);
11595         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11596         COUNT_BYTES_SUBR(1);
11597
11598         /* 2 pad bytes */
11599         offset+=2;
11600         *bcp -= 2;
11601
11602         /* ea length */
11603         CHECK_BYTE_COUNT_SUBR(4);
11604         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11605         COUNT_BYTES_SUBR(4);
11606
11607         /* file name len */
11608         CHECK_BYTE_COUNT_SUBR(4);
11609         fn_len = (guint32)tvb_get_letohl(tvb, offset);
11610         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11611         COUNT_BYTES_SUBR(4);
11612
11613
11614         /* file name */
11615         CHECK_BYTE_COUNT_SUBR(fn_len);
11616         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
11617         if (fn != NULL) {
11618                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11619                         fn);
11620                 COUNT_BYTES_SUBR(fn_len);
11621         }
11622
11623
11624         if (*trunc)
11625                 return offset;
11626
11627         return offset;
11628 }
11629
11630 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11631    as described in 4.2.16.10
11632 */
11633 int
11634 dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
11635     int offset, guint16 *bcp, gboolean *trunc, int unicode)
11636 {
11637         proto_item *item;
11638         proto_tree *tree;
11639         int old_offset;
11640         guint32 neo;
11641         int fn_len;
11642         const char *fn;
11643         int padcnt;
11644
11645
11646         for (;;) {
11647                 old_offset = offset;
11648
11649                 /* next entry offset */
11650                 CHECK_BYTE_COUNT_SUBR(4);
11651                 if(parent_tree){
11652                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
11653                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11654                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11655                 } else {
11656                         item = NULL;
11657                         tree = NULL;
11658                 }
11659
11660                 neo = tvb_get_letohl(tvb, offset);
11661                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11662                 COUNT_BYTES_SUBR(4);
11663
11664                 /* stream name len */
11665                 CHECK_BYTE_COUNT_SUBR(4);
11666                 fn_len = tvb_get_letohl(tvb, offset);
11667                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11668                 COUNT_BYTES_SUBR(4);
11669
11670                 /* stream size */
11671                 CHECK_BYTE_COUNT_SUBR(8);
11672                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11673                 COUNT_BYTES_SUBR(8);
11674
11675                 /* allocation size */
11676                 CHECK_BYTE_COUNT_SUBR(8);
11677                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11678                 COUNT_BYTES_SUBR(8);
11679
11680                 /* stream name */
11681                 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
11682                 CHECK_STRING_SUBR(fn);
11683                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11684                         fn);
11685                 COUNT_BYTES_SUBR(fn_len);
11686
11687                 proto_item_append_text(item, ": %s", format_text(fn, strlen(fn)));
11688                 proto_item_set_len(item, offset-old_offset);
11689
11690                 if (neo == 0)
11691                         break;  /* no more structures */
11692
11693                 /* skip to next structure */
11694                 padcnt = (old_offset + neo) - offset;
11695                 if (padcnt < 0) {
11696                         /*
11697                          * XXX - this is bogus; flag it?
11698                          */
11699                         padcnt = 0;
11700                 }
11701                 if (padcnt != 0) {
11702                         CHECK_BYTE_COUNT_SUBR(padcnt);
11703                         COUNT_BYTES_SUBR(padcnt);
11704                 }
11705         }
11706
11707         *trunc = FALSE;
11708         return offset;
11709 }
11710
11711 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11712    as described in 4.2.16.11
11713 */
11714 int
11715 dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11716     int offset, guint16 *bcp, gboolean *trunc)
11717 {
11718         /* compressed file size */
11719         CHECK_BYTE_COUNT_SUBR(8);
11720         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11721         COUNT_BYTES_SUBR(8);
11722
11723         /* compression format */
11724         CHECK_BYTE_COUNT_SUBR(2);
11725         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11726         COUNT_BYTES_SUBR(2);
11727
11728         /* compression unit shift */
11729         CHECK_BYTE_COUNT_SUBR(1);
11730         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11731         COUNT_BYTES_SUBR(1);
11732
11733         /* compression chunk shift */
11734         CHECK_BYTE_COUNT_SUBR(1);
11735         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11736         COUNT_BYTES_SUBR(1);
11737
11738         /* compression cluster shift */
11739         CHECK_BYTE_COUNT_SUBR(1);
11740         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11741         COUNT_BYTES_SUBR(1);
11742
11743         /* 3 reserved bytes */
11744         CHECK_BYTE_COUNT_SUBR(3);
11745         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11746         COUNT_BYTES_SUBR(3);
11747
11748         *trunc = FALSE;
11749         return offset;
11750 }
11751
11752 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11753
11754 static const value_string unix_file_type_vals[] = {
11755         { 0, "File" },
11756         { 1, "Directory" },
11757         { 2, "Symbolic link" },
11758         { 3, "Character device" },
11759         { 4, "Block device" },
11760         { 5, "FIFO" },
11761         { 6, "Socket" },
11762         { 0, NULL }
11763 };
11764
11765 static int
11766 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11767                   int offset, guint16 *bcp, gboolean *trunc)
11768 {
11769         /* End of file (file size) */
11770         CHECK_BYTE_COUNT_SUBR(8);
11771         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11772         COUNT_BYTES_SUBR(8);
11773
11774         /* Number of bytes */
11775         CHECK_BYTE_COUNT_SUBR(8);
11776         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11777         COUNT_BYTES_SUBR(8);
11778
11779         /* Last status change */
11780         CHECK_BYTE_COUNT_SUBR(8);
11781         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11782         *bcp -= 8;              /* dissect_nt_64bit_time() increments offset */
11783
11784         /* Last access time */
11785         CHECK_BYTE_COUNT_SUBR(8);
11786         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11787         *bcp -= 8;
11788
11789         /* Last modification time */
11790         CHECK_BYTE_COUNT_SUBR(8);
11791         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11792         *bcp -= 8;
11793
11794         /* File owner uid */
11795         CHECK_BYTE_COUNT_SUBR(8);
11796         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11797         COUNT_BYTES_SUBR(8);
11798
11799         /* File group gid */
11800         CHECK_BYTE_COUNT_SUBR(8);
11801         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11802         COUNT_BYTES_SUBR(8);
11803
11804         /* File type */
11805         CHECK_BYTE_COUNT_SUBR(4);
11806         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11807         COUNT_BYTES_SUBR(4);
11808
11809         /* Major device number */
11810         CHECK_BYTE_COUNT_SUBR(8);
11811         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11812         COUNT_BYTES_SUBR(8);
11813
11814         /* Minor device number */
11815         CHECK_BYTE_COUNT_SUBR(8);
11816         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11817         COUNT_BYTES_SUBR(8);
11818
11819         /* Unique id */
11820         CHECK_BYTE_COUNT_SUBR(8);
11821         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11822         COUNT_BYTES_SUBR(8);
11823
11824         /* Permissions */
11825         CHECK_BYTE_COUNT_SUBR(8);
11826         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11827         COUNT_BYTES_SUBR(8);
11828
11829         /* Nlinks */
11830         CHECK_BYTE_COUNT_SUBR(8);
11831         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11832         COUNT_BYTES_SUBR(8);
11833
11834         /* Sometimes there is one extra byte in the data field which I
11835            guess could be padding, but we are only using 4 or 8 byte
11836            data types so this is a bit confusing. -tpot */
11837
11838         *trunc = FALSE;
11839         return offset;
11840 }
11841
11842 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11843
11844 static int
11845 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11846                   int offset, guint16 *bcp, gboolean *trunc)
11847 {
11848         smb_info_t *si = pinfo->private_data;
11849         const char *fn;
11850         int fn_len;
11851
11852         DISSECTOR_ASSERT(si);
11853
11854         /* Link destination */
11855
11856         fn = get_unicode_or_ascii_string(
11857                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11858
11859         CHECK_STRING_SUBR(fn);
11860         proto_tree_add_string(
11861                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11862         COUNT_BYTES_SUBR(fn_len);
11863
11864         *trunc = FALSE;
11865         return offset;
11866 }
11867
11868 /* unix ACL
11869 */
11870 static int
11871 dissect_qpi_unix_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11872                   int offset, guint16 *bcp, gboolean *trunc)
11873 {
11874         guint16 version, num_file_aces, num_def_aces;
11875         static const int *perm_fields[] = {
11876                 &hf_smb_posix_ace_perm_read,
11877                 &hf_smb_posix_ace_perm_write,
11878                 &hf_smb_posix_ace_perm_execute,
11879                 NULL
11880         };
11881
11882         /* version */
11883         CHECK_BYTE_COUNT_SUBR(2);
11884         version = tvb_get_letohs(tvb, offset);
11885         proto_tree_add_item(tree, hf_smb_posix_acl_version, tvb, offset, 2, TRUE);
11886         COUNT_BYTES_SUBR(2);
11887
11888         /* num file acls */
11889         CHECK_BYTE_COUNT_SUBR(2);
11890         num_file_aces = tvb_get_letohs(tvb, offset);
11891         proto_tree_add_item(tree, hf_smb_posix_num_file_aces, tvb, offset, 2, TRUE);
11892         COUNT_BYTES_SUBR(2);
11893
11894         /* num default acls */
11895         CHECK_BYTE_COUNT_SUBR(2);
11896         num_def_aces = tvb_get_letohs(tvb, offset);
11897         proto_tree_add_item(tree, hf_smb_posix_num_def_aces, tvb, offset, 2, TRUE);
11898         COUNT_BYTES_SUBR(2);
11899
11900         while(num_file_aces--){
11901                 proto_item *it;
11902                 proto_tree *tr;
11903                 int old_offset = offset;
11904                 guint8 ace_type;
11905
11906                 it = proto_tree_add_text(tree, tvb, offset, 0, "ACE");
11907                 tr = proto_item_add_subtree(it, ett_smb_posic_ace);
11908
11909                 /* ace type */
11910                 CHECK_BYTE_COUNT_SUBR(1);
11911                 ace_type = tvb_get_guint8(tvb, offset);
11912                 proto_tree_add_item(tr, hf_smb_posix_ace_type, tvb, offset, 1, TRUE);
11913                 COUNT_BYTES_SUBR(1);
11914
11915                 CHECK_BYTE_COUNT_SUBR(1);
11916                 proto_tree_add_bitmask(tr, tvb, offset, hf_smb_posix_ace_flags, ett_smb_posix_ace_perms, perm_fields, FALSE);
11917                 COUNT_BYTES_SUBR(1);
11918
11919                 switch(ace_type){
11920                 case POSIX_ACE_TYPE_USER_OBJ:
11921                         CHECK_BYTE_COUNT_SUBR(4);
11922                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_uid, tvb, offset, 4, TRUE);
11923                         COUNT_BYTES_SUBR(4);
11924
11925                         CHECK_BYTE_COUNT_SUBR(4);
11926                         /* 4 reserved bytes */
11927                         COUNT_BYTES_SUBR(4);
11928                         break;
11929                 case POSIX_ACE_TYPE_GROUP_OBJ:
11930                         CHECK_BYTE_COUNT_SUBR(4);
11931                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_gid, tvb, offset, 4, TRUE);
11932                         COUNT_BYTES_SUBR(4);
11933
11934                         CHECK_BYTE_COUNT_SUBR(4);
11935                         /* 4 reserved bytes */
11936                         COUNT_BYTES_SUBR(4);
11937                         break;
11938
11939                 case POSIX_ACE_TYPE_MASK:
11940                 case POSIX_ACE_TYPE_OTHER:
11941                         CHECK_BYTE_COUNT_SUBR(8);
11942                         /* 8 reserved bytes */
11943                         COUNT_BYTES_SUBR(8);
11944                         break;
11945
11946                 case POSIX_ACE_TYPE_USER:
11947                         CHECK_BYTE_COUNT_SUBR(4);
11948                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_uid, tvb, offset, 4, TRUE);
11949                         COUNT_BYTES_SUBR(4);
11950
11951                         CHECK_BYTE_COUNT_SUBR(4);
11952                         /* 4 reserved bytes */
11953                         COUNT_BYTES_SUBR(4);
11954                         break;
11955
11956                 case POSIX_ACE_TYPE_GROUP:
11957                         CHECK_BYTE_COUNT_SUBR(4);
11958                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_gid, tvb, offset, 4, TRUE);
11959                         COUNT_BYTES_SUBR(4);
11960
11961                         CHECK_BYTE_COUNT_SUBR(4);
11962                         /* 4 reserved bytes */
11963                         COUNT_BYTES_SUBR(4);
11964                         break;
11965                 default:
11966                         proto_tree_add_text(tr, tvb, offset, 0, "Unknown posix ace type");
11967                         CHECK_BYTE_COUNT_SUBR(8);
11968                         /* skip 8 bytes */
11969                         COUNT_BYTES_SUBR(8);
11970                 }
11971
11972                 proto_item_set_len(it, offset-old_offset);
11973         }
11974
11975         return offset;
11976 }
11977
11978 static int
11979 dissect_qpi_unix_xattr(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
11980                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
11981 {
11982         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
11983
11984         return offset;
11985 }
11986
11987 static int
11988 dissect_qpi_unix_attr_flags(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
11989                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
11990 {
11991         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
11992
11993         return offset;
11994 }
11995
11996 static int
11997 dissect_qpi_unix_permissions(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
11998                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
11999 {
12000         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12001
12002         return offset;
12003 }
12004
12005 static int
12006 dissect_qpi_unix_lock(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12007                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12008 {
12009         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12010
12011         return offset;
12012 }
12013
12014 static int
12015 dissect_qpi_unix_open(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12016                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12017 {
12018         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12019
12020         return offset;
12021 }
12022
12023 static int
12024 dissect_qpi_unix_unlink(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12025                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12026 {
12027         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12028
12029         return offset;
12030 }
12031
12032 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
12033 */
12034 int
12035 dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
12036     packet_info *pinfo, proto_tree *tree,
12037     int offset, guint16 *bcp, gboolean *trunc)
12038 {
12039
12040         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12041         if (*trunc) {
12042           return offset;
12043         }
12044
12045         /* allocation size */
12046         CHECK_BYTE_COUNT_SUBR(8);
12047         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12048         COUNT_BYTES_SUBR(8);
12049
12050         /* end of file */
12051         CHECK_BYTE_COUNT_SUBR(8);
12052         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12053         COUNT_BYTES_SUBR(8);
12054
12055         /* File Attributes */
12056         CHECK_BYTE_COUNT_SUBR(4);
12057         offset = dissect_file_attributes(tvb, tree, offset, 4);
12058         *bcp -= 4;
12059
12060         /* Unknown, possibly count of network accessors ... */
12061         CHECK_BYTE_COUNT_SUBR(4);
12062         proto_tree_add_item(tree, hf_smb_network_unknown, tvb, offset, 4, TRUE);
12063         COUNT_BYTES_SUBR(4);
12064
12065         *trunc = FALSE;
12066         return offset;
12067 }
12068
12069 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
12070 */
12071 int
12072 dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb,
12073     packet_info *pinfo _U_, proto_tree *tree,
12074     int offset, guint16 *bcp, gboolean *trunc)
12075 {
12076         /* attribute */
12077         CHECK_BYTE_COUNT_SUBR(4);
12078         proto_tree_add_item(tree, hf_smb_attribute, tvb, offset, 4, TRUE);
12079         COUNT_BYTES_SUBR(4);
12080
12081         /* reparse tag */
12082         CHECK_BYTE_COUNT_SUBR(4);
12083         proto_tree_add_item(tree, hf_smb_reparse_tag, tvb, offset, 4, TRUE);
12084         COUNT_BYTES_SUBR(4);
12085
12086         *trunc = FALSE;
12087         return offset;
12088 }
12089
12090 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
12091    as described in 4.2.19.2
12092 */
12093 static int
12094 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12095     int offset, guint16 *bcp, gboolean *trunc)
12096 {
12097         /* marked for deletion? */
12098         CHECK_BYTE_COUNT_SUBR(1);
12099         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
12100         COUNT_BYTES_SUBR(1);
12101
12102         *trunc = FALSE;
12103         return offset;
12104 }
12105
12106 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
12107    as described in 4.2.19.3
12108 */
12109 static int
12110 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12111     int offset, guint16 *bcp, gboolean *trunc)
12112 {
12113         /* file allocation size */
12114         CHECK_BYTE_COUNT_SUBR(8);
12115         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12116         COUNT_BYTES_SUBR(8);
12117
12118         *trunc = FALSE;
12119         return offset;
12120 }
12121
12122 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
12123    as described in 4.2.19.4
12124 */
12125 static int
12126 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12127     int offset, guint16 *bcp, gboolean *trunc)
12128 {
12129         /* file end of file offset */
12130         CHECK_BYTE_COUNT_SUBR(8);
12131         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12132         COUNT_BYTES_SUBR(8);
12133
12134         *trunc = FALSE;
12135         return offset;
12136 }
12137
12138 /* Set File Rename Info */
12139
12140 static const true_false_string tfs_smb_replace = {
12141         "Remove target file if it exists",
12142         "Do NOT remove target file if it exists",
12143 };
12144
12145 static int
12146 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12147                     int offset, guint16 *bcp, gboolean *trunc)
12148 {
12149         smb_info_t *si = pinfo->private_data;
12150         const char *fn;
12151         guint32 target_name_len;
12152         int fn_len;
12153
12154         DISSECTOR_ASSERT(si);
12155
12156         /* Replace flag */
12157         CHECK_BYTE_COUNT_SUBR(4);
12158         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, TRUE);
12159         COUNT_BYTES_SUBR(4);
12160
12161         /* Root directory handle */
12162         CHECK_BYTE_COUNT_SUBR(4);
12163         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, TRUE);
12164         COUNT_BYTES_SUBR(4);
12165
12166         /* Target name length */
12167         CHECK_BYTE_COUNT_SUBR(4);
12168         target_name_len = tvb_get_letohl(tvb, offset);
12169         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
12170         COUNT_BYTES_SUBR(4);
12171
12172         /* Target name */
12173         fn_len = target_name_len;
12174         fn = get_unicode_or_ascii_string(
12175                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12176
12177         CHECK_STRING_SUBR(fn);
12178         proto_tree_add_string(
12179                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
12180         COUNT_BYTES_SUBR(fn_len);
12181
12182         *trunc = FALSE;
12183         return offset;
12184 }
12185
12186 static int
12187 dissect_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12188                     int offset, guint16 *bcp, gboolean *trunc)
12189 {
12190         smb_info_t *si = pinfo->private_data;
12191 /*      const char *fn;*/
12192 /*      guint32 target_name_len;*/
12193 /*      int fn_len;*/
12194
12195         DISSECTOR_ASSERT(si);
12196
12197         /* Disposition flags */
12198         CHECK_BYTE_COUNT_SUBR(1);
12199         proto_tree_add_item(tree, hf_smb_disposition_delete_on_close, tvb, offset, 1, TRUE);
12200         COUNT_BYTES_SUBR(1);
12201
12202         *trunc = FALSE;
12203         return offset;
12204 }
12205
12206 int
12207 dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12208                     int offset, guint16 *bcp, gboolean *trunc)
12209 {
12210         smb_info_t *si = pinfo->private_data;
12211
12212         DISSECTOR_ASSERT(si);
12213
12214         /* pipe info flag */
12215         CHECK_BYTE_COUNT_SUBR(1);
12216         proto_tree_add_item(tree, hf_smb_pipe_info_flag, tvb, offset, 1, TRUE);
12217         COUNT_BYTES_SUBR(1);
12218
12219         *trunc = FALSE;
12220         return offset;
12221 }
12222
12223 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
12224   TRANS2_QUERY_FILE_INFORMATION*/
12225 static int
12226 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12227     int offset, guint16 *bcp)
12228 {
12229         smb_info_t *si;
12230         gboolean trunc;
12231
12232         if(!*bcp){
12233                 return offset;
12234         }
12235
12236         si = (smb_info_t *)pinfo->private_data;
12237         DISSECTOR_ASSERT(si);
12238
12239         switch(si->info_level){
12240         case 1:         /*Info Standard*/
12241                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
12242                     &trunc);
12243                 break;
12244
12245         case 2:         /*Info Query EA Size*/
12246                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12247                     &trunc);
12248                 break;
12249         case 3:         /*Info Query EAs From List*/
12250         case 4:         /*Info Query All EAs*/
12251                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12252                     &trunc);
12253                 break;
12254         case 6:         /*Info Is Name Valid*/
12255                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
12256                     &trunc);
12257                 break;
12258         case 0x0101:    /*Query File Basic Info*/
12259         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
12260                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
12261                     &trunc);
12262                 break;
12263         case 0x0102:    /*Query File Standard Info*/
12264         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
12265                 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, bcp,
12266                     &trunc);
12267                 break;
12268         case 1006:      /* SMB_FILE_INTERNAL_INFORMATION */
12269                 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, bcp,
12270                     &trunc);
12271                 break;
12272         case 0x0103:    /*Query File EA Info*/
12273         case 1007:      /* SMB_FILE_EA_INFORMATION */
12274                 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, bcp,
12275                     &trunc);
12276                 break;
12277         case 0x0104:    /*Query File Name Info*/
12278         case 1009:      /* SMB_FILE_NAME_INFORMATION */
12279                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
12280                     &trunc);
12281                 break;
12282         case 1014:      /* SMB_FILE_POSITION_INFORMATION */
12283                 offset = dissect_qfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
12284                     &trunc);
12285                 break;
12286         case 1016:      /* SMB_FILE_MODE_INFORMATION */
12287                 offset = dissect_qfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
12288                     &trunc);
12289                 break;
12290         case 1017:      /* SMB_FILE_ALIGNMENT_INFORMATION */
12291                 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, bcp,
12292                     &trunc);
12293                 break;
12294         case 0x0107:    /*Query File All Info*/
12295         case 1018:      /* SMB_FILE_ALL_INFORMATION */
12296                 offset = dissect_qfi_SMB_FILE_ALL_INFO(tvb, pinfo, tree, offset, bcp,
12297                     &trunc);
12298                 break;
12299         case 1019:      /* SMB_FILE_ALLOCATION_INFORMATION */
12300                 offset = dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
12301                     &trunc);
12302                 break;
12303         case 1020:      /* SMB_FILE_ENDOFFILE_INFORMATION */
12304                 offset = dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
12305                     &trunc);
12306                 break;
12307         case 0x0108:    /*Query File Alt File Info*/
12308         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
12309                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
12310                     &trunc);
12311                 break;
12312         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
12313                 si->unicode = TRUE;
12314         case 0x0109:    /*Query File Stream Info*/
12315                 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, bcp,
12316                     &trunc, si->unicode);
12317                 break;
12318         case 0x010b:    /*Query File Compression Info*/
12319         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
12320                 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, bcp,
12321                     &trunc);
12322                 break;
12323         case 1034:     /* SMB_FILE_NETWORK_OPEN_INFO */
12324                 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
12325                 break;
12326         case 1035:     /* SMB_FILE_ATTRIBUTE_TAG_INFO */
12327                 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
12328                 break;
12329         case 0x0200:    /* Query File Unix Basic*/
12330                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
12331                                            &trunc);
12332                 break;
12333         case 0x0201:    /* Query File Unix Link*/
12334                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12335                                            &trunc);
12336                 break;
12337         case 0x0202:    /* Query File Unix HardLink*/
12338                 /* XXX add this from the SNIA doc */
12339                 break;
12340         case 0x0204:    /* Query File Unix ACL*/
12341                 offset = dissect_qpi_unix_acl(tvb, pinfo, tree, offset, bcp,
12342                                            &trunc);
12343                 break;
12344         case 0x0205:    /* Query File Unix XATTR*/
12345                 offset = dissect_qpi_unix_xattr(tvb, pinfo, tree, offset, bcp,
12346                                            &trunc);
12347                 break;
12348         case 0x0206:    /* Query File Unix Attr Flags*/
12349                 offset = dissect_qpi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
12350                                            &trunc);
12351                 break;
12352         case 0x0207:    /* Query File Unix Permissions*/
12353                 offset = dissect_qpi_unix_permissions(tvb, pinfo, tree, offset, bcp,
12354                                            &trunc);
12355                 break;
12356         case 0x0208:    /* Query File Unix Lock*/
12357                 offset = dissect_qpi_unix_lock(tvb, pinfo, tree, offset, bcp,
12358                                            &trunc);
12359                 break;
12360         }
12361
12362         return offset;
12363 }
12364
12365 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
12366   TRANS2_SET_FILE_INFORMATION*/
12367 static int
12368 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12369     int offset, guint16 *bcp)
12370 {
12371         smb_info_t *si;
12372         gboolean trunc;
12373
12374         if(!*bcp){
12375                 return offset;
12376         }
12377
12378         si = (smb_info_t *)pinfo->private_data;
12379         DISSECTOR_ASSERT(si);
12380
12381         switch(si->info_level){
12382         case 1:         /*Info Standard*/
12383                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
12384                     &trunc);
12385                 break;
12386         case 2:         /*Info Query EA Size*/
12387                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12388                     &trunc);
12389                 break;
12390         case 4:         /*Info Query All EAs*/
12391                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12392                     &trunc);
12393                 break;
12394         case 0x0101:    /*Set File Basic Info*/
12395         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
12396                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
12397                     &trunc);
12398                 break;
12399         case 0x0102:    /*Set File Disposition Info*/
12400                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
12401                     &trunc);
12402                 break;
12403         case 0x0103:    /*Set File Allocation Info*/
12404                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
12405                     &trunc);
12406                 break;
12407         case 0x0104:    /*Set End Of File Info*/
12408                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
12409                     &trunc);
12410                 break;
12411         case 0x0200:    /*Set File Unix Basic.  Same as query. */
12412                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
12413                     &trunc);
12414                 break;
12415         case 0x0201:    /*Set File Unix Link.  Same as query. */
12416                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12417                     &trunc);
12418                 break;
12419         case 0x0202:    /*Set File Unix HardLink.  Same as link query. */
12420                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12421                     &trunc);
12422                 break;
12423         case 0x0204:    /* Set File Unix ACL*/
12424                 offset = dissect_qpi_unix_acl(tvb, pinfo, tree, offset, bcp,
12425                                            &trunc);
12426                 break;
12427         case 0x0205:    /* Set File Unix XATTR*/
12428                 offset = dissect_qpi_unix_xattr(tvb, pinfo, tree, offset, bcp,
12429                                            &trunc);
12430                 break;
12431         case 0x0206:    /* Set File Unix Attr Flags*/
12432                 offset = dissect_qpi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
12433                                            &trunc);
12434                 break;
12435         case 0x0208:    /* Set File Unix Lock*/
12436                 offset = dissect_qpi_unix_lock(tvb, pinfo, tree, offset, bcp,
12437                                            &trunc);
12438                 break;
12439         case 0x0209:    /* Set File Unix Open*/
12440                 offset = dissect_qpi_unix_open(tvb, pinfo, tree, offset, bcp,
12441                                            &trunc);
12442                 break;
12443         case 0x020a:    /* Set File Unix Unlink*/
12444                 offset = dissect_qpi_unix_unlink(tvb, pinfo, tree, offset, bcp,
12445                                            &trunc);
12446                 break;
12447         case 1010:      /* Set File Rename */
12448                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
12449                     &trunc);
12450                 break;
12451         case 1013: /* Set Disposition Information */
12452                 offset = dissect_disposition_info(tvb, pinfo, tree, offset, bcp,
12453                     &trunc);
12454                 break;
12455         case 1023: /* Set Pipe Info */
12456                 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, bcp,
12457                     &trunc);
12458                 break;
12459         case 1014:
12460         case 1016:
12461         case 1019:
12462         case 1020:
12463         case 1025:
12464         case 1029:
12465         case 1032:
12466         case 1039:
12467         case 1040:
12468                 /* XXX: TODO, extra levels discovered by tridge */
12469                 break;
12470         }
12471
12472         return offset;
12473 }
12474
12475
12476 static const true_false_string tfs_quota_flags_deny_disk = {
12477         "DENY DISK SPACE for users exceeding quota limit",
12478         "Do NOT deny disk space for users exceeding quota limit"
12479 };
12480 static const true_false_string tfs_quota_flags_log_limit = {
12481         "LOG EVENT when a user exceeds their QUOTA LIMIT",
12482         "Do NOT log event when a user exceeds their quota limit"
12483 };
12484 static const true_false_string tfs_quota_flags_log_warning = {
12485         "LOG EVENT when a user exceeds their WARNING LEVEL",
12486         "Do NOT log event when a user exceeds their warning level"
12487 };
12488 static const true_false_string tfs_quota_flags_enabled = {
12489         "Quotas are ENABLED of this fs",
12490         "Quotas are NOT enabled on this fs"
12491 };
12492 static void
12493 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12494 {
12495         guint8 mask;
12496         proto_item *item;
12497         proto_tree *tree;
12498
12499         mask = tvb_get_guint8(tvb, offset);
12500
12501         if(parent_tree){
12502                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
12503                         "Quota Flags: 0x%02x %s", mask,
12504                         mask?"Enabled":"Disabled");
12505                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
12506
12507                 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
12508                         tvb, offset, 1, mask);
12509                 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
12510                         tvb, offset, 1, mask);
12511                 proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
12512                         tvb, offset, 1, mask);
12513
12514                 if(mask && (!(mask&0x01))){
12515                         proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
12516                                 tvb, offset, 1, 0x01);
12517                 } else {
12518                         proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
12519                                 tvb, offset, 1, mask);
12520                 }
12521         }
12522
12523 }
12524
12525 int
12526 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
12527 {
12528         /* first 24 bytes are unknown */
12529         CHECK_BYTE_COUNT_TRANS_SUBR(24);
12530         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12531                     offset, 24, TRUE);
12532         COUNT_BYTES_TRANS_SUBR(24);
12533
12534         /* number of bytes for quota warning */
12535         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12536         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
12537         COUNT_BYTES_TRANS_SUBR(8);
12538
12539         /* number of bytes for quota limit */
12540         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12541         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
12542         COUNT_BYTES_TRANS_SUBR(8);
12543
12544         /* one byte of quota flags */
12545         CHECK_BYTE_COUNT_TRANS_SUBR(1);
12546         dissect_quota_flags(tvb, tree, offset);
12547         COUNT_BYTES_TRANS_SUBR(1);
12548
12549         /* these 7 bytes are unknown */
12550         CHECK_BYTE_COUNT_TRANS_SUBR(7);
12551         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12552                     offset, 7, TRUE);
12553         COUNT_BYTES_TRANS_SUBR(7);
12554
12555         return offset;
12556 }
12557
12558 static int
12559 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
12560     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
12561 {
12562         proto_item *item = NULL;
12563         proto_tree *tree = NULL;
12564         smb_info_t *si;
12565
12566         si = (smb_info_t *)pinfo->private_data;
12567         DISSECTOR_ASSERT(si);
12568
12569         if(parent_tree){
12570                 tvb_ensure_bytes_exist(tvb, offset, dc);
12571                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12572                                 "%s Data",
12573                                 val_to_str(subcmd, trans2_cmd_vals,
12574                                                 "Unknown (0x%02x)"));
12575                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12576         }
12577
12578         switch(subcmd){
12579         case 0x00:      /*TRANS2_OPEN2*/
12580                 /* XXX dont know how to decode FEAList */
12581                 break;
12582         case 0x01:      /*TRANS2_FIND_FIRST2*/
12583                 /* XXX dont know how to decode FEAList */
12584                 break;
12585         case 0x02:      /*TRANS2_FIND_NEXT2*/
12586                 /* XXX dont know how to decode FEAList */
12587                 break;
12588         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12589                 /* no data field in this request */
12590                 break;
12591         case 0x04:      /* TRANS2_SET_QUOTA */
12592                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
12593                 break;
12594         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12595                 /* no data field in this request */
12596                 /*
12597                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12598                  * Extensions Version 3.0, Document Version 1.11,
12599                  * July 19, 1990" says there may be "Additional
12600                  * FileInfoLevel dependent information" here.
12601                  *
12602                  * Was that just a cut-and-pasteo?
12603                  * TRANS2_SET_PATH_INFORMATION *does* have that information
12604                  * here.
12605                  */
12606                 break;
12607         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12608                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12609                 break;
12610         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12611                 /* no data field in this request */
12612                 /*
12613                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12614                  * Extensions Version 3.0, Document Version 1.11,
12615                  * July 19, 1990" says there may be "Additional
12616                  * FileInfoLevel dependent information" here.
12617                  *
12618                  * Was that just a cut-and-pasteo?
12619                  * TRANS2_SET_FILE_INFORMATION *does* have that information
12620                  * here.
12621                  */
12622                 break;
12623         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12624                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12625                 break;
12626         case 0x09:      /*TRANS2_FSCTL*/
12627                 /*XXX dont know how to decode this yet */
12628
12629                 /*
12630                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12631                  * Extensions Version 3.0, Document Version 1.11,
12632                  * July 19, 1990" says this this contains a
12633                  * "File system specific data block".  (That means we
12634                  * may not be able to dissect it in any case.)
12635                  */
12636                 break;
12637         case 0x0a:      /*TRANS2_IOCTL2*/
12638                 /*XXX dont know how to decode this yet */
12639
12640                 /*
12641                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12642                  * Extensions Version 3.0, Document Version 1.11,
12643                  * July 19, 1990" says this this contains a
12644                  * "Device/function specific data block".  (That
12645                  * means we may not be able to dissect it in any case.)
12646                  */
12647                 break;
12648         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12649                 /*XXX dont know how to decode this yet */
12650
12651                 /*
12652                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12653                  * Extensions Version 3.0, Document Version 1.11,
12654                  * July 19, 1990" says this this contains "additional
12655                  * level dependent match data".
12656                  */
12657                 break;
12658         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12659                 /*XXX dont know how to decode this yet */
12660
12661                 /*
12662                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12663                  * Extensions Version 3.0, Document Version 1.11,
12664                  * July 19, 1990" says this this contains "additional
12665                  * level dependent monitor information".
12666                  */
12667                 break;
12668         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12669                 /* XXX optional FEAList, unknown what FEAList looks like*/
12670                 break;
12671         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12672                 /*XXX dont know how to decode this yet */
12673                 break;
12674         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12675                 /* no data field in this request */
12676                 break;
12677         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12678                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
12679                 break;
12680         }
12681
12682         /* ooops there were data we didnt know how to process */
12683         if(dc != 0){
12684                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12685                 offset += dc;
12686         }
12687
12688         return offset;
12689 }
12690
12691
12692 static void
12693 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
12694     proto_tree *tree)
12695 {
12696         int i;
12697         int offset;
12698         guint length;
12699
12700         /*
12701          * Show the setup words.
12702          */
12703         if (s_tvb != NULL) {
12704                 length = tvb_reported_length(s_tvb);
12705                 for (i = 0, offset = 0; length >= 2;
12706                     i++, offset += 2, length -= 2) {
12707                         /*
12708                          * XXX - add a setup word filterable field?
12709                          */
12710                         proto_tree_add_text(tree, s_tvb, offset, 2,
12711                             "Setup Word %d: 0x%04x", i,
12712                             tvb_get_letohs(s_tvb, offset));
12713                 }
12714         }
12715
12716         /*
12717          * Show the parameters, if any.
12718          */
12719         if (p_tvb != NULL) {
12720                 length = tvb_reported_length(p_tvb);
12721                 if (length != 0) {
12722                         proto_tree_add_text(tree, p_tvb, 0, length,
12723                             "Parameters: %s",
12724                             tvb_bytes_to_str(p_tvb, 0, length));
12725                 }
12726         }
12727
12728         /*
12729          * Show the data, if any.
12730          */
12731         if (d_tvb != NULL) {
12732                 length = tvb_reported_length(d_tvb);
12733                 if (length != 0) {
12734                         proto_tree_add_text(tree, d_tvb, 0, length,
12735                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
12736                 }
12737         }
12738 }
12739
12740 /* This routine handles the following 4 calls
12741    Transaction  0x25
12742    Transaction Secondary 0x26
12743    Transaction2 0x32
12744    Transaction2 Secondary 0x33
12745 */
12746 static int
12747 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
12748 {
12749         guint8 wc, sc=0;
12750         int so=offset;
12751         int sl=0;
12752         int spo=offset;
12753         int spc=0;
12754         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
12755         int subcmd = -1;
12756         guint32 to;
12757         int an_len;
12758         const char *an = NULL;
12759         smb_info_t *si;
12760         smb_transact2_info_t *t2i;
12761         smb_transact_info_t *tri;
12762         guint16 bc;
12763         int padcnt;
12764         gboolean dissected_trans;
12765
12766         si = (smb_info_t *)pinfo->private_data;
12767         DISSECTOR_ASSERT(si);
12768
12769         WORD_COUNT;
12770
12771         if(wc==8){
12772                 /*secondary client request*/
12773
12774                 /* total param count, only a 16bit integer here*/
12775                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12776                 offset += 2;
12777
12778                 /* total data count , only 16bit integer here*/
12779                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12780                 offset += 2;
12781
12782                 /* param count */
12783                 pc = tvb_get_letohs(tvb, offset);
12784                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12785                 offset += 2;
12786
12787                 /* param offset */
12788                 po = tvb_get_letohs(tvb, offset);
12789                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12790                 offset += 2;
12791
12792                 /* param disp */
12793                 pd = tvb_get_letohs(tvb, offset);
12794                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12795                 offset += 2;
12796
12797                 /* data count */
12798                 dc = tvb_get_letohs(tvb, offset);
12799                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12800                 offset += 2;
12801
12802                 /* data offset */
12803                 od = tvb_get_letohs(tvb, offset);
12804                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12805                 offset += 2;
12806
12807                 /* data disp */
12808                 dd = tvb_get_letohs(tvb, offset);
12809                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12810                 offset += 2;
12811
12812                 if(si->cmd==SMB_COM_TRANSACTION2){
12813                         guint16 fid;
12814
12815                         /* fid */
12816                         fid = tvb_get_letohs(tvb, offset);
12817                         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
12818
12819                         offset += 2;
12820                 }
12821
12822                 /* There are no setup words. */
12823                 so = offset;
12824                 sc = 0;
12825                 sl = 0;
12826         } else {
12827                 /* it is not a secondary request */
12828
12829                 /* total param count , only a 16 bit integer here*/
12830                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12831                 offset += 2;
12832
12833                 /* total data count , only 16bit integer here*/
12834                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12835                 offset += 2;
12836
12837                 /* max param count , only 16bit integer here*/
12838                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12839                 offset += 2;
12840
12841                 /* max data count, only 16bit integer here*/
12842                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12843                 offset += 2;
12844
12845                 /* max setup count, only 16bit integer here*/
12846                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12847                 offset += 1;
12848
12849                 /* reserved byte */
12850                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12851                 offset += 1;
12852
12853                 /* transaction flags */
12854                 tf = dissect_transaction_flags(tvb, tree, offset);
12855                 offset += 2;
12856
12857                 /* timeout */
12858                 to = tvb_get_letohl(tvb, offset);
12859                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
12860                 offset += 4;
12861
12862                 /* 2 reserved bytes */
12863                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12864                 offset += 2;
12865
12866                 /* param count */
12867                 pc = tvb_get_letohs(tvb, offset);
12868                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12869                 offset += 2;
12870
12871                 /* param offset */
12872                 po = tvb_get_letohs(tvb, offset);
12873                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12874                 offset += 2;
12875
12876                 /* param displacement is zero here */
12877                 pd = 0;
12878
12879                 /* data count */
12880                 dc = tvb_get_letohs(tvb, offset);
12881                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12882                 offset += 2;
12883
12884                 /* data offset */
12885                 od = tvb_get_letohs(tvb, offset);
12886                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12887                 offset += 2;
12888
12889                 /* data displacement is zero here */
12890                 dd = 0;
12891
12892                 /* setup count */
12893                 sc = tvb_get_guint8(tvb, offset);
12894                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12895                 offset += 1;
12896
12897                 /* reserved byte */
12898                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12899                 offset += 1;
12900
12901                 /* this is where the setup bytes, if any start */
12902                 so = offset;
12903                 sl = sc*2;
12904
12905                 /* if there were any setup bytes, decode them */
12906                 if(sc){
12907                         switch(si->cmd){
12908
12909                         case SMB_COM_TRANSACTION2:
12910                                 /* TRANSACTION2 only has one setup word and
12911                                    that is the subcommand code.
12912
12913                                    XXX - except for TRANS2_FSCTL
12914                                    and TRANS2_IOCTL. */
12915                                 subcmd = tvb_get_letohs(tvb, offset);
12916                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12917                                     tvb, offset, 2, subcmd);
12918                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12919                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12920                                             val_to_str(subcmd, trans2_cmd_vals,
12921                                                 "Unknown (0x%02x)"));
12922                                 }
12923                                 if (!si->unidir) {
12924                                         if(!pinfo->fd->flags.visited && si->sip){
12925                                                 /*
12926                                                  * Allocate a new
12927                                                  * smb_transact2_info_t
12928                                                  * structure.
12929                                                  */
12930                                                 t2i = se_alloc(sizeof(smb_transact2_info_t));
12931                                                 t2i->subcmd = subcmd;
12932                                                 t2i->info_level = -1;
12933                                                 t2i->resume_keys = FALSE;
12934                                                 t2i->name = NULL;
12935                                                 si->sip->extra_info = t2i;
12936                                                 si->sip->extra_info_type = SMB_EI_T2I;
12937                                         }
12938                                 }
12939
12940                                 /*
12941                                  * XXX - process TRANS2_FSCTL and
12942                                  * TRANS2_IOCTL setup words here.
12943                                  */
12944                                 break;
12945
12946                         case SMB_COM_TRANSACTION:
12947                                 /* TRANSACTION setup words processed below */
12948                                 break;
12949                         }
12950
12951                         offset += sl;
12952                 }
12953         }
12954
12955         BYTE_COUNT;
12956
12957         if(wc!=8){
12958                 /* primary request */
12959                 /* name is NULL if transaction2 */
12960                 if(si->cmd == SMB_COM_TRANSACTION){
12961                         /* Transaction Name */
12962                         an = get_unicode_or_ascii_string(tvb, &offset,
12963                                 si->unicode, &an_len, FALSE, FALSE, &bc);
12964                         if (an == NULL)
12965                                 goto endofcommand;
12966                         tvb_ensure_bytes_exist(tvb, offset, an_len);
12967                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
12968                                 offset, an_len, an);
12969                         COUNT_BYTES(an_len);
12970                 }
12971         }
12972
12973         /*
12974          * The pipe or mailslot arguments for Transaction start with
12975          * the first setup word (or where the first setup word would
12976          * be if there were any setup words), and run to the current
12977          * offset (which could mean that there aren't any).
12978          */
12979         spo = so;
12980         spc = offset - spo;
12981
12982         /* parameters */
12983         if(po>offset){
12984                 /* We have some initial padding bytes.
12985                 */
12986                 padcnt = po-offset;
12987                 if (padcnt > bc)
12988                         padcnt = bc;
12989                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
12990                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12991                 COUNT_BYTES(padcnt);
12992         }
12993         if(pc){
12994                 CHECK_BYTE_COUNT(pc);
12995                 switch(si->cmd) {
12996
12997                 case SMB_COM_TRANSACTION2:
12998                         /* TRANSACTION2 parameters*/
12999                         offset = dissect_transaction2_request_parameters(tvb,
13000                             pinfo, tree, offset, subcmd, pc);
13001                         bc -= pc;
13002                         break;
13003
13004                 case SMB_COM_TRANSACTION:
13005                         /* TRANSACTION parameters processed below */
13006                         COUNT_BYTES(pc);
13007                         break;
13008                 }
13009         }
13010
13011         /* data */
13012         if(od>offset){
13013                 /* We have some initial padding bytes.
13014                 */
13015                 padcnt = od-offset;
13016                 if (padcnt > bc)
13017                         padcnt = bc;
13018                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
13019                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13020                 COUNT_BYTES(padcnt);
13021         }
13022         if(dc){
13023                 CHECK_BYTE_COUNT(dc);
13024                 switch(si->cmd){
13025
13026                 case SMB_COM_TRANSACTION2:
13027                         /* TRANSACTION2 data*/
13028                         offset = dissect_transaction2_request_data(tvb, pinfo,
13029                             tree, offset, subcmd, dc);
13030                         bc -= dc;
13031                         break;
13032
13033                 case SMB_COM_TRANSACTION:
13034                         /* TRANSACTION data processed below */
13035                         COUNT_BYTES(dc);
13036                         break;
13037                 }
13038         }
13039
13040         /*TRANSACTION request parameters */
13041         if(si->cmd==SMB_COM_TRANSACTION){
13042                 /*XXX replace this block with a function and use that one
13043                      for both requests/responses*/
13044                 if(dd==0){
13045                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
13046                         tvbuff_t *sp_tvb, *pd_tvb;
13047
13048                         if(pc>0){
13049                                 if(pc>tvb_length_remaining(tvb, po)){
13050                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
13051                                 } else {
13052                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
13053                                 }
13054                         } else {
13055                                 p_tvb = NULL;
13056                         }
13057                         if(dc>0){
13058                                 if(dc>tvb_length_remaining(tvb, od)){
13059                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
13060                                 } else {
13061                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
13062                                 }
13063                         } else {
13064                                 d_tvb = NULL;
13065                         }
13066                         if(sl){
13067                                 if(sl>tvb_length_remaining(tvb, so)){
13068                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
13069                                 } else {
13070                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
13071                                 }
13072                         } else {
13073                                 s_tvb = NULL;
13074                         }
13075
13076                         if (!si->unidir) {
13077                                 if(!pinfo->fd->flags.visited && si->sip){
13078                                         /*
13079                                          * Allocate a new smb_transact_info_t
13080                                          * structure.
13081                                          */
13082                                         tri = se_alloc(sizeof(smb_transact_info_t));
13083                                         tri->subcmd = -1;
13084                                         tri->trans_subcmd = -1;
13085                                         tri->function = -1;
13086                                         tri->fid = -1;
13087                                         tri->lanman_cmd = 0;
13088                                         tri->param_descrip = NULL;
13089                                         tri->data_descrip = NULL;
13090                                         tri->aux_data_descrip = NULL;
13091                                         tri->info_level = -1;
13092                                         si->sip->extra_info = tri;
13093                                         si->sip->extra_info_type = SMB_EI_TRI;
13094                                 } else {
13095                                         /*
13096                                          * We already filled the structure
13097                                          * in; don't bother doing so again.
13098                                          */
13099                                         tri = NULL;
13100                                 }
13101                         } else {
13102                                 /*
13103                                  * This is a unidirectional message, for
13104                                  * which there will be no reply; don't
13105                                  * bother allocating an "smb_transact_info_t"
13106                                  * structure for it.
13107                                  */
13108                                 tri = NULL;
13109                         }
13110                         dissected_trans = FALSE;
13111                         if (an == NULL)
13112                                 goto endofcommand;
13113                         if(strncmp("\\PIPE\\", an, 6) == 0){
13114                                 if (tri != NULL)
13115                                         tri->subcmd=TRANSACTION_PIPE;
13116
13117                                 /*
13118                                  * A tvbuff containing the setup words and
13119                                  * the pipe path.
13120                                  */
13121                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
13122
13123                                 /*
13124                                  * A tvbuff containing the parameters and the
13125                                  * data.
13126                                  */
13127                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
13128
13129                                 dissected_trans = dissect_pipe_smb(sp_tvb,
13130                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
13131                                     top_tree);
13132
13133                                 /* In case we did not see the TreeConnect call,
13134                                    store this TID here as well as a IPC TID
13135                                    so we know that future Read/Writes to this
13136                                    TID is (probably) DCERPC.
13137                                 */
13138                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
13139                                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
13140                                 }
13141                                 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
13142                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
13143                                 if (tri != NULL)
13144                                         tri->subcmd=TRANSACTION_MAILSLOT;
13145
13146                                 /*
13147                                  * A tvbuff containing the setup words and
13148                                  * the mailslot path.
13149                                  */
13150                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
13151                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
13152                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
13153                         }
13154                         if (!dissected_trans)
13155                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
13156                 } else {
13157                         if(check_col(pinfo->cinfo, COL_INFO)){
13158                                 col_append_str(pinfo->cinfo, COL_INFO,
13159                                         "[transact continuation]");
13160                         }
13161                 }
13162         }
13163
13164         END_OF_SMB
13165
13166         return offset;
13167 }
13168
13169
13170
13171 static int
13172 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13173     int offset, guint16 *bcp, gboolean *trunc)
13174 {
13175         int fn_len;
13176         const char *fn;
13177         int old_offset = offset;
13178         proto_item *item = NULL;
13179         proto_tree *tree = NULL;
13180         smb_info_t *si;
13181         smb_transact2_info_t *t2i;
13182         gboolean resume_keys = FALSE;
13183
13184         si = (smb_info_t *)pinfo->private_data;
13185         DISSECTOR_ASSERT(si);
13186
13187         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
13188                 t2i = si->sip->extra_info;
13189                 if (t2i != NULL)
13190                         resume_keys = t2i->resume_keys;
13191         }
13192
13193         if(parent_tree){
13194                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13195                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13196                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13197                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13198         }
13199
13200         if (resume_keys) {
13201                 /* resume key */
13202                 CHECK_BYTE_COUNT_SUBR(4);
13203                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
13204                 COUNT_BYTES_SUBR(4);
13205         }
13206
13207         /* create time */
13208         CHECK_BYTE_COUNT_SUBR(4);
13209         offset = dissect_smb_datetime(tvb, tree, offset,
13210                 hf_smb_create_time,
13211                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
13212         *bcp -= 4;
13213
13214         /* access time */
13215         CHECK_BYTE_COUNT_SUBR(4);
13216         offset = dissect_smb_datetime(tvb, tree, offset,
13217                 hf_smb_access_time,
13218                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
13219         *bcp -= 4;
13220
13221         /* last write time */
13222         CHECK_BYTE_COUNT_SUBR(4);
13223         offset = dissect_smb_datetime(tvb, tree, offset,
13224                 hf_smb_last_write_time,
13225                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
13226         *bcp -= 4;
13227
13228         /* data size */
13229         CHECK_BYTE_COUNT_SUBR(4);
13230         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13231         COUNT_BYTES_SUBR(4);
13232
13233         /* allocation size */
13234         CHECK_BYTE_COUNT_SUBR(4);
13235         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
13236         COUNT_BYTES_SUBR(4);
13237
13238         /* File Attributes */
13239         CHECK_BYTE_COUNT_SUBR(2);
13240         offset = dissect_file_attributes(tvb, tree, offset, 2);
13241         *bcp -= 2;
13242
13243         /* file name len */
13244         CHECK_BYTE_COUNT_SUBR(1);
13245         fn_len = tvb_get_guint8(tvb, offset);
13246         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
13247         COUNT_BYTES_SUBR(1);
13248         if (si->unicode)
13249                 fn_len += 2;    /* include terminating '\0' */
13250         else
13251                 fn_len++;       /* include terminating '\0' */
13252
13253         /* file name */
13254         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13255         CHECK_STRING_SUBR(fn);
13256         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13257                 fn);
13258         COUNT_BYTES_SUBR(fn_len);
13259
13260         if (check_col(pinfo->cinfo, COL_INFO)) {
13261                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13262                     format_text(fn, strlen(fn)));
13263         }
13264
13265         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13266         proto_item_set_len(item, offset-old_offset);
13267
13268         *trunc = FALSE;
13269         return offset;
13270 }
13271
13272 static int
13273 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13274     int offset, guint16 *bcp, gboolean *trunc)
13275 {
13276         int fn_len;
13277         const char *fn;
13278         int old_offset = offset;
13279         proto_item *item = NULL;
13280         proto_tree *tree = NULL;
13281         smb_info_t *si;
13282         smb_transact2_info_t *t2i;
13283         gboolean resume_keys = FALSE;
13284
13285         si = (smb_info_t *)pinfo->private_data;
13286         DISSECTOR_ASSERT(si);
13287
13288         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
13289                 t2i = si->sip->extra_info;
13290                 if (t2i != NULL)
13291                         resume_keys = t2i->resume_keys;
13292         }
13293
13294         if(parent_tree){
13295                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13296                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13297                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13298                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13299         }
13300
13301         if (resume_keys) {
13302                 /* resume key */
13303                 CHECK_BYTE_COUNT_SUBR(4);
13304                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
13305                 COUNT_BYTES_SUBR(4);
13306         }
13307
13308         /* create time */
13309         CHECK_BYTE_COUNT_SUBR(4);
13310         offset = dissect_smb_datetime(tvb, tree, offset,
13311                 hf_smb_create_time,
13312                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
13313         *bcp -= 4;
13314
13315         /* access time */
13316         CHECK_BYTE_COUNT_SUBR(4);
13317         offset = dissect_smb_datetime(tvb, tree, offset,
13318                 hf_smb_access_time,
13319                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
13320         *bcp -= 4;
13321
13322         /* last write time */
13323         CHECK_BYTE_COUNT_SUBR(4);
13324         offset = dissect_smb_datetime(tvb, tree, offset,
13325                 hf_smb_last_write_time,
13326                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
13327         *bcp -= 4;
13328
13329         /* data size */
13330         CHECK_BYTE_COUNT_SUBR(4);
13331         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13332         COUNT_BYTES_SUBR(4);
13333
13334         /* allocation size */
13335         CHECK_BYTE_COUNT_SUBR(4);
13336         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
13337         COUNT_BYTES_SUBR(4);
13338
13339         /* File Attributes */
13340         CHECK_BYTE_COUNT_SUBR(2);
13341         offset = dissect_file_attributes(tvb, tree, offset, 2);
13342         *bcp -= 2;
13343
13344         /* ea length */
13345         CHECK_BYTE_COUNT_SUBR(4);
13346         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13347         COUNT_BYTES_SUBR(4);
13348
13349         /* file name len */
13350         CHECK_BYTE_COUNT_SUBR(1);
13351         fn_len = tvb_get_guint8(tvb, offset);
13352         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
13353         COUNT_BYTES_SUBR(1);
13354         if (si->unicode)
13355                 fn_len += 2;    /* include terminating '\0' */
13356         else
13357                 fn_len++;       /* include terminating '\0' */
13358
13359         /* file name */
13360         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13361         CHECK_STRING_SUBR(fn);
13362         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13363                 fn);
13364         COUNT_BYTES_SUBR(fn_len);
13365
13366         if (check_col(pinfo->cinfo, COL_INFO)) {
13367                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13368                     format_text(fn, strlen(fn)));
13369         }
13370
13371         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13372         proto_item_set_len(item, offset-old_offset);
13373
13374         *trunc = FALSE;
13375         return offset;
13376 }
13377
13378 static int
13379 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13380     int offset, guint16 *bcp, gboolean *trunc)
13381 {
13382         int fn_len;
13383         const char *fn;
13384         int old_offset = offset;
13385         proto_item *item = NULL;
13386         proto_tree *tree = NULL;
13387         smb_info_t *si;
13388         guint32 neo;
13389         int padcnt;
13390
13391         si = (smb_info_t *)pinfo->private_data;
13392         DISSECTOR_ASSERT(si);
13393
13394         if(parent_tree){
13395                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13396                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13397                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13398                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13399         }
13400
13401         /*
13402          * We assume that the presence of a next entry offset implies the
13403          * absence of a resume key, as appears to be the case for 4.3.4.6.
13404          */
13405
13406         /* next entry offset */
13407         CHECK_BYTE_COUNT_SUBR(4);
13408         neo = tvb_get_letohl(tvb, offset);
13409         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13410         COUNT_BYTES_SUBR(4);
13411
13412         /* file index */
13413         CHECK_BYTE_COUNT_SUBR(4);
13414         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13415         COUNT_BYTES_SUBR(4);
13416
13417         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13418         if (*trunc) {
13419           return offset;
13420         }
13421
13422         /* end of file */
13423         CHECK_BYTE_COUNT_SUBR(8);
13424         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13425         COUNT_BYTES_SUBR(8);
13426
13427         /* allocation size */
13428         CHECK_BYTE_COUNT_SUBR(8);
13429         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13430         COUNT_BYTES_SUBR(8);
13431
13432         /* Extended File Attributes */
13433         CHECK_BYTE_COUNT_SUBR(4);
13434         offset = dissect_file_ext_attr(tvb, tree, offset);
13435         *bcp -= 4;
13436
13437         /* file name len */
13438         CHECK_BYTE_COUNT_SUBR(4);
13439         fn_len = tvb_get_letohl(tvb, offset);
13440         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13441         COUNT_BYTES_SUBR(4);
13442
13443         /* file name */
13444         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13445         CHECK_STRING_SUBR(fn);
13446         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13447                 fn);
13448         COUNT_BYTES_SUBR(fn_len);
13449
13450         if (check_col(pinfo->cinfo, COL_INFO)) {
13451                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13452                     format_text(fn, strlen(fn)));
13453         }
13454
13455         /* skip to next structure */
13456         if(neo){
13457                 padcnt = (old_offset + neo) - offset;
13458                 if (padcnt < 0) {
13459                         /*
13460                          * XXX - this is bogus; flag it?
13461                          */
13462                         padcnt = 0;
13463                 }
13464                 if (padcnt != 0) {
13465                         CHECK_BYTE_COUNT_SUBR(padcnt);
13466                         COUNT_BYTES_SUBR(padcnt);
13467                 }
13468         }
13469
13470         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13471         proto_item_set_len(item, offset-old_offset);
13472
13473         *trunc = FALSE;
13474         return offset;
13475 }
13476
13477 static int
13478 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13479     int offset, guint16 *bcp, gboolean *trunc)
13480 {
13481         int fn_len;
13482         const char *fn;
13483         int old_offset = offset;
13484         proto_item *item = NULL;
13485         proto_tree *tree = NULL;
13486         smb_info_t *si;
13487         guint32 neo;
13488         int padcnt;
13489
13490         si = (smb_info_t *)pinfo->private_data;
13491         DISSECTOR_ASSERT(si);
13492
13493         if(parent_tree){
13494                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13495                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13496                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13497                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13498         }
13499
13500         /*
13501          * We assume that the presence of a next entry offset implies the
13502          * absence of a resume key, as appears to be the case for 4.3.4.6.
13503          */
13504
13505         /* next entry offset */
13506         CHECK_BYTE_COUNT_SUBR(4);
13507         neo = tvb_get_letohl(tvb, offset);
13508         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13509         COUNT_BYTES_SUBR(4);
13510
13511         /* file index */
13512         CHECK_BYTE_COUNT_SUBR(4);
13513         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13514         COUNT_BYTES_SUBR(4);
13515
13516         /* standard 8-byte timestamps */
13517         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13518         if (*trunc) {
13519           return offset;
13520         }
13521
13522         /* end of file */
13523         CHECK_BYTE_COUNT_SUBR(8);
13524         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13525         COUNT_BYTES_SUBR(8);
13526
13527         /* allocation size */
13528         CHECK_BYTE_COUNT_SUBR(8);
13529         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13530         COUNT_BYTES_SUBR(8);
13531
13532         /* Extended File Attributes */
13533         CHECK_BYTE_COUNT_SUBR(4);
13534         offset = dissect_file_ext_attr(tvb, tree, offset);
13535         *bcp -= 4;
13536
13537         /* file name len */
13538         CHECK_BYTE_COUNT_SUBR(4);
13539         fn_len = tvb_get_letohl(tvb, offset);
13540         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13541         COUNT_BYTES_SUBR(4);
13542
13543         /* ea length */
13544         CHECK_BYTE_COUNT_SUBR(4);
13545         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13546         COUNT_BYTES_SUBR(4);
13547
13548         /* file name */
13549         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13550         CHECK_STRING_SUBR(fn);
13551         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13552                 fn);
13553         COUNT_BYTES_SUBR(fn_len);
13554
13555         if (check_col(pinfo->cinfo, COL_INFO)) {
13556                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13557                     format_text(fn, strlen(fn)));
13558         }
13559
13560         /* skip to next structure */
13561         if(neo){
13562                 padcnt = (old_offset + neo) - offset;
13563                 if (padcnt < 0) {
13564                         /*
13565                          * XXX - this is bogus; flag it?
13566                          */
13567                         padcnt = 0;
13568                 }
13569                 if (padcnt != 0) {
13570                         CHECK_BYTE_COUNT_SUBR(padcnt);
13571                         COUNT_BYTES_SUBR(padcnt);
13572                 }
13573         }
13574
13575         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13576         proto_item_set_len(item, offset-old_offset);
13577
13578         *trunc = FALSE;
13579         return offset;
13580 }
13581
13582 static int
13583 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13584     int offset, guint16 *bcp, gboolean *trunc)
13585 {
13586         int fn_len, sfn_len;
13587         const char *fn, *sfn;
13588         int old_offset = offset;
13589         proto_item *item = NULL;
13590         proto_tree *tree = NULL;
13591         smb_info_t *si;
13592         guint32 neo;
13593         int padcnt;
13594
13595         si = (smb_info_t *)pinfo->private_data;
13596         DISSECTOR_ASSERT(si);
13597
13598         if(parent_tree){
13599                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13600                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13601                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13602                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13603         }
13604
13605         /*
13606          * XXX - I have not seen any of these that contain a resume
13607          * key, even though some of the requests had the "return resume
13608          * key" flag set.
13609          */
13610
13611         /* next entry offset */
13612         CHECK_BYTE_COUNT_SUBR(4);
13613         neo = tvb_get_letohl(tvb, offset);
13614         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13615         COUNT_BYTES_SUBR(4);
13616
13617         /* file index */
13618         CHECK_BYTE_COUNT_SUBR(4);
13619         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13620         COUNT_BYTES_SUBR(4);
13621
13622         /* dissect standard 8-byte timestamps */
13623         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13624         if (*trunc) {
13625           return offset;
13626         }
13627
13628         /* end of file */
13629         CHECK_BYTE_COUNT_SUBR(8);
13630         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13631         COUNT_BYTES_SUBR(8);
13632
13633         /* allocation size */
13634         CHECK_BYTE_COUNT_SUBR(8);
13635         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13636         COUNT_BYTES_SUBR(8);
13637
13638         /* Extended File Attributes */
13639         CHECK_BYTE_COUNT_SUBR(4);
13640         offset = dissect_file_ext_attr(tvb, tree, offset);
13641         *bcp -= 4;
13642
13643         /* file name len */
13644         CHECK_BYTE_COUNT_SUBR(4);
13645         fn_len = tvb_get_letohl(tvb, offset);
13646         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13647         COUNT_BYTES_SUBR(4);
13648
13649         /*
13650          * EA length.
13651          *
13652          * XXX - in one captures, this has the topmost bit set, and the
13653          * rest of the bits have the value 7.  Is the topmost bit being
13654          * set some indication that the value *isn't* the length of
13655          * the EAs?
13656          */
13657         CHECK_BYTE_COUNT_SUBR(4);
13658         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13659         COUNT_BYTES_SUBR(4);
13660
13661         /* short file name len */
13662         CHECK_BYTE_COUNT_SUBR(1);
13663         sfn_len = tvb_get_guint8(tvb, offset);
13664         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
13665         COUNT_BYTES_SUBR(1);
13666
13667         /* reserved byte */
13668         CHECK_BYTE_COUNT_SUBR(1);
13669         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13670         COUNT_BYTES_SUBR(1);
13671
13672         /* short file name - it's not always in Unicode */
13673         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
13674         CHECK_STRING_SUBR(sfn);
13675         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
13676                 sfn);
13677         COUNT_BYTES_SUBR(24);
13678
13679         /* file name */
13680         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13681         CHECK_STRING_SUBR(fn);
13682         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13683                 fn);
13684         COUNT_BYTES_SUBR(fn_len);
13685
13686         if (check_col(pinfo->cinfo, COL_INFO)) {
13687                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13688                     format_text(fn, strlen(fn)));
13689         }
13690
13691         /* skip to next structure */
13692         if(neo){
13693                 padcnt = (old_offset + neo) - offset;
13694                 if (padcnt < 0) {
13695                         /*
13696                          * XXX - this is bogus; flag it?
13697                          */
13698                         padcnt = 0;
13699                 }
13700                 if (padcnt != 0) {
13701                         CHECK_BYTE_COUNT_SUBR(padcnt);
13702                         COUNT_BYTES_SUBR(padcnt);
13703                 }
13704         }
13705
13706         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13707         proto_item_set_len(item, offset-old_offset);
13708
13709         *trunc = FALSE;
13710         return offset;
13711 }
13712
13713 static int
13714 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13715     int offset, guint16 *bcp, gboolean *trunc)
13716 {
13717         int fn_len;
13718         const char *fn;
13719         int old_offset = offset;
13720         proto_item *item = NULL;
13721         proto_tree *tree = NULL;
13722         smb_info_t *si;
13723         guint32 neo;
13724         int padcnt;
13725
13726         si = (smb_info_t *)pinfo->private_data;
13727         DISSECTOR_ASSERT(si);
13728
13729         if(parent_tree){
13730                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13731                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13732                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13733                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13734         }
13735
13736         /*
13737          * We assume that the presence of a next entry offset implies the
13738          * absence of a resume key, as appears to be the case for 4.3.4.6.
13739          */
13740
13741         /* next entry offset */
13742         CHECK_BYTE_COUNT_SUBR(4);
13743         neo = tvb_get_letohl(tvb, offset);
13744         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13745         COUNT_BYTES_SUBR(4);
13746
13747         /* file index */
13748         CHECK_BYTE_COUNT_SUBR(4);
13749         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13750         COUNT_BYTES_SUBR(4);
13751
13752         /* file name len */
13753         CHECK_BYTE_COUNT_SUBR(4);
13754         fn_len = tvb_get_letohl(tvb, offset);
13755         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13756         COUNT_BYTES_SUBR(4);
13757
13758         /* file name */
13759         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13760         CHECK_STRING_SUBR(fn);
13761         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13762                 fn);
13763         COUNT_BYTES_SUBR(fn_len);
13764
13765         if (check_col(pinfo->cinfo, COL_INFO)) {
13766                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13767                     format_text(fn, strlen(fn)));
13768         }
13769
13770         /* skip to next structure */
13771         if(neo){
13772                 padcnt = (old_offset + neo) - offset;
13773                 if (padcnt < 0) {
13774                         /*
13775                          * XXX - this is bogus; flag it?
13776                          */
13777                         padcnt = 0;
13778                 }
13779                 if (padcnt != 0) {
13780                         CHECK_BYTE_COUNT_SUBR(padcnt);
13781                         COUNT_BYTES_SUBR(padcnt);
13782                 }
13783         }
13784
13785         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13786         proto_item_set_len(item, offset-old_offset);
13787
13788         *trunc = FALSE;
13789         return offset;
13790 }
13791
13792 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
13793
13794 static int
13795 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
13796                 proto_tree *tree, int offset, guint16 *bcp,
13797                 gboolean *trunc)
13798 {
13799         smb_info_t *si = pinfo->private_data;
13800         const char *fn;
13801         int fn_len;
13802
13803         DISSECTOR_ASSERT(si);
13804
13805         /* NextEntryOffset */
13806         CHECK_BYTE_COUNT_SUBR(4);
13807         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
13808         COUNT_BYTES_SUBR(4);
13809
13810         /* ResumeKey */
13811         CHECK_BYTE_COUNT_SUBR(4);
13812         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
13813         COUNT_BYTES_SUBR(4);
13814
13815         /* End of file (file size) */
13816         CHECK_BYTE_COUNT_SUBR(8);
13817         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
13818         COUNT_BYTES_SUBR(8);
13819
13820         /* Number of bytes */
13821         CHECK_BYTE_COUNT_SUBR(8);
13822         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
13823         COUNT_BYTES_SUBR(8);
13824
13825         /* Last status change */
13826         CHECK_BYTE_COUNT_SUBR(8);
13827         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
13828         *bcp -= 8;
13829
13830         /* Last access time */
13831         CHECK_BYTE_COUNT_SUBR(8);
13832         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
13833         *bcp -= 8;
13834
13835         /* Last modification time */
13836         CHECK_BYTE_COUNT_SUBR(8);
13837         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
13838         *bcp -= 8;
13839
13840         /* File owner uid */
13841         CHECK_BYTE_COUNT_SUBR(8);
13842         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
13843         COUNT_BYTES_SUBR(8);
13844
13845         /* File group gid */
13846         CHECK_BYTE_COUNT_SUBR(8);
13847         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
13848         COUNT_BYTES_SUBR(8);
13849
13850         /* File type */
13851         CHECK_BYTE_COUNT_SUBR(4);
13852         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
13853         COUNT_BYTES_SUBR(4);
13854
13855         /* Major device number */
13856         CHECK_BYTE_COUNT_SUBR(8);
13857         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
13858         COUNT_BYTES_SUBR(8);
13859
13860         /* Minor device number */
13861         CHECK_BYTE_COUNT_SUBR(8);
13862         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
13863         COUNT_BYTES_SUBR(8);
13864
13865         /* Unique id */
13866         CHECK_BYTE_COUNT_SUBR(8);
13867         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
13868         COUNT_BYTES_SUBR(8);
13869
13870         /* Permissions */
13871         CHECK_BYTE_COUNT_SUBR(8);
13872         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
13873         COUNT_BYTES_SUBR(8);
13874
13875         /* Nlinks */
13876         CHECK_BYTE_COUNT_SUBR(8);
13877         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
13878         COUNT_BYTES_SUBR(8);
13879
13880         /* Name */
13881
13882         fn = get_unicode_or_ascii_string(
13883                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13884
13885         CHECK_STRING_SUBR(fn);
13886         proto_tree_add_string(
13887                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13888         COUNT_BYTES_SUBR(fn_len);
13889
13890         /* Pad to 4 bytes */
13891
13892         if (offset % 4)
13893                 offset += 4 - (offset % 4);
13894
13895         *trunc = FALSE;
13896         return offset;
13897 }
13898
13899 /*dissect the data block for TRANS2_FIND_FIRST2*/
13900 static int
13901 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13902     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13903 {
13904         smb_info_t *si;
13905
13906         if(!*bcp){
13907                 return offset;
13908         }
13909
13910         si = (smb_info_t *)pinfo->private_data;
13911         DISSECTOR_ASSERT(si);
13912
13913         switch(si->info_level){
13914         case 1:         /*Info Standard*/
13915                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13916                     trunc);
13917                 break;
13918         case 2:         /*Info Query EA Size*/
13919                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13920                     trunc);
13921                 break;
13922         case 3:         /*Info Query EAs From List same as
13923                                 InfoQueryEASize*/
13924                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13925                     trunc);
13926                 break;
13927         case 0x0101:    /*Find File Directory Info*/
13928                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13929                     trunc);
13930                 break;
13931         case 0x0102:    /*Find File Full Directory Info*/
13932                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13933                     trunc);
13934                 break;
13935         case 0x0103:    /*Find File Names Info*/
13936                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13937                     trunc);
13938                 break;
13939         case 0x0104:    /*Find File Both Directory Info*/
13940                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13941                     trunc);
13942                 break;
13943         case 0x0202:    /*Find File UNIX*/
13944                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13945                     trunc);
13946                 break;
13947         default:        /* unknown info level */
13948                 *trunc = FALSE;
13949                 break;
13950         }
13951         return offset;
13952 }
13953
13954
13955 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
13956 static int
13957 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13958 {
13959         guint32 mask;
13960         proto_item *item;
13961         proto_tree *tree;
13962
13963         mask = tvb_get_letohl(tvb, offset);
13964
13965         if(parent_tree){
13966                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13967                         "FS Attributes: 0x%08x", mask);
13968                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
13969
13970                 /* case sensitive search */
13971                 proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
13972                         tvb, offset, 4, mask);
13973                 /* case preserved names */
13974                 proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
13975                         tvb, offset, 4, mask);
13976                 /* unicode on disk */
13977                 proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
13978                         tvb, offset, 4, mask);
13979                 /* persistent acls */
13980                 proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
13981                         tvb, offset, 4, mask);
13982                 /* file compression */
13983                 proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
13984                         tvb, offset, 4, mask);
13985                 /* volume quotas */
13986                 proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
13987                         tvb, offset, 4, mask);
13988                 /* sparse files */
13989                 proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
13990                         tvb, offset, 4, mask);
13991                 /* reparse points */
13992                 proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
13993                         tvb, offset, 4, mask);
13994                 /* remote storage */
13995                 proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
13996                         tvb, offset, 4, mask);
13997                 /* lfn apis */
13998                 proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
13999                         tvb, offset, 4, mask);
14000                 /* volume is compressed */
14001                 proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
14002                         tvb, offset, 4, mask);
14003                 /* support oids */
14004                 proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
14005                         tvb, offset, 4, mask);
14006                 /* encryption */
14007                 proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
14008                         tvb, offset, 4, mask);
14009                 /* named streams */
14010                 proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
14011                         tvb, offset, 4, mask);
14012                 /* read only volume */
14013                 proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
14014                         tvb, offset, 4, mask);
14015         }
14016
14017         offset += 4;
14018         return offset;
14019 }
14020
14021
14022 static int
14023 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
14024 {
14025         guint32 mask;
14026         proto_item *item;
14027         proto_tree *tree;
14028
14029         mask = tvb_get_letohl(tvb, offset);
14030
14031         if(parent_tree){
14032                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
14033                         "Device Characteristics: 0x%08x", mask);
14034                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
14035
14036                 proto_tree_add_boolean(tree, hf_smb_device_char_removable,
14037                         tvb, offset, 4, mask);
14038                 proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
14039                         tvb, offset, 4, mask);
14040                 proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
14041                         tvb, offset, 4, mask);
14042                 proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
14043                         tvb, offset, 4, mask);
14044                 proto_tree_add_boolean(tree, hf_smb_device_char_remote,
14045                         tvb, offset, 4, mask);
14046                 proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
14047                         tvb, offset, 4, mask);
14048                 proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
14049                         tvb, offset, 4, mask);
14050         }
14051
14052         offset += 4;
14053         return offset;
14054 }
14055
14056 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
14057
14058 static const true_false_string tfs_smb_mac_access_ctrl = {
14059   "Macintosh Access Control Supported",
14060   "Macintosh Access Control Not Supported"
14061 };
14062
14063 static const true_false_string tfs_smb_mac_getset_comments = {
14064   "Macintosh Get & Set Comments Supported",
14065   "Macintosh Get & Set Comments Not Supported"
14066 };
14067
14068 static const true_false_string tfs_smb_mac_desktopdb_calls = {
14069   "Macintosh Get & Set Desktop Database Info Supported",
14070   "Macintosh Get & Set Desktop Database Info Supported"
14071 };
14072
14073 static const true_false_string tfs_smb_mac_unique_ids = {
14074   "Macintosh Unique IDs Supported",
14075   "Macintosh Unique IDs Not Supported"
14076 };
14077
14078 static const true_false_string tfs_smb_mac_streams = {
14079   "Macintosh and Streams Extensions Not Supported",
14080   "Macintosh and Streams Extensions Supported"
14081 };
14082
14083 int
14084 dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
14085 {
14086         int fn_len, vll;
14087         const char *fn;
14088
14089         /* create time */
14090         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14091         offset = dissect_nt_64bit_time(tvb, tree, offset,
14092                 hf_smb_create_time);
14093         *bcp -= 8;
14094
14095         /* volume serial number */
14096         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14097         proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
14098         COUNT_BYTES_TRANS_SUBR(4);
14099
14100         /* volume label length */
14101         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14102         vll = tvb_get_letohl(tvb, offset);
14103         proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
14104         COUNT_BYTES_TRANS_SUBR(4);
14105
14106         /* 2 reserved bytes */
14107         CHECK_BYTE_COUNT_TRANS_SUBR(2);
14108         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14109         COUNT_BYTES_TRANS_SUBR(2);
14110
14111         /* label */
14112         fn_len = vll;
14113         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
14114         CHECK_STRING_TRANS_SUBR(fn);
14115         proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14116                 fn);
14117         COUNT_BYTES_TRANS_SUBR(fn_len);
14118
14119         return offset;
14120 }
14121
14122 int
14123 dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14124 {
14125         /* allocation size */
14126         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14127         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
14128         COUNT_BYTES_TRANS_SUBR(8);
14129
14130         /* free allocation units */
14131         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14132         proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
14133         COUNT_BYTES_TRANS_SUBR(8);
14134
14135         /* sectors per unit */
14136         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14137         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14138         COUNT_BYTES_TRANS_SUBR(4);
14139
14140         /* bytes per sector */
14141         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14142         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
14143         COUNT_BYTES_TRANS_SUBR(4);
14144
14145         return offset;
14146 }
14147
14148 int
14149 dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14150 {
14151         /* device type */
14152         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14153         proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
14154         COUNT_BYTES_TRANS_SUBR(4);
14155
14156         /* device characteristics */
14157         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14158         offset = dissect_device_characteristics(tvb, tree, offset);
14159         *bcp -= 4;
14160
14161         return offset;
14162 }
14163
14164 int
14165 dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
14166 {
14167         int fn_len, fnl;
14168         const char *fn;
14169
14170         /* FS attributes */
14171         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14172         offset = dissect_fs_attributes(tvb, tree, offset);
14173         *bcp -= 4;
14174
14175         /* max name len */
14176         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14177         proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
14178         COUNT_BYTES_TRANS_SUBR(4);
14179
14180         /* fs name length */
14181         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14182         fnl = tvb_get_letohl(tvb, offset);
14183         proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
14184         COUNT_BYTES_TRANS_SUBR(4);
14185
14186         /* label */
14187         fn_len = fnl;
14188         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
14189         CHECK_STRING_TRANS_SUBR(fn);
14190         proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
14191                 fn);
14192         COUNT_BYTES_TRANS_SUBR(fn_len);
14193
14194         return offset;
14195 }
14196
14197 int
14198 dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
14199 {
14200         CHECK_BYTE_COUNT_TRANS_SUBR(64);
14201
14202         dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
14203
14204         COUNT_BYTES_TRANS_SUBR(64);
14205
14206         return offset;
14207 }
14208
14209 int
14210 dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14211 {
14212         /* allocation size */
14213         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14214         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
14215         COUNT_BYTES_TRANS_SUBR(8);
14216
14217         /* caller free allocation units */
14218         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14219         proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
14220         COUNT_BYTES_TRANS_SUBR(8);
14221
14222         /* actual free allocation units */
14223         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14224         proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
14225         COUNT_BYTES_TRANS_SUBR(8);
14226
14227         /* sectors per unit */
14228         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14229         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14230         COUNT_BYTES_TRANS_SUBR(4);
14231
14232         /* bytes per sector */
14233         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14234         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
14235         COUNT_BYTES_TRANS_SUBR(4);
14236
14237         return offset;
14238 }
14239
14240 static int
14241 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
14242     int offset, guint16 *bcp)
14243 {
14244         smb_info_t *si;
14245         int fn_len, vll;
14246         const char *fn;
14247         guint support = 0;
14248         proto_item *item = NULL;
14249         proto_tree *ti = NULL;
14250
14251         if(!*bcp){
14252                 return offset;
14253         }
14254
14255         si = (smb_info_t *)pinfo->private_data;
14256         DISSECTOR_ASSERT(si);
14257
14258         switch(si->info_level){
14259         case 1:         /* SMB_INFO_ALLOCATION */
14260                 /* filesystem id */
14261                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14262                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
14263                 COUNT_BYTES_TRANS_SUBR(4);
14264
14265                 /* sectors per unit */
14266                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14267                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14268                 COUNT_BYTES_TRANS_SUBR(4);
14269
14270                 /* units */
14271                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14272                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
14273                 COUNT_BYTES_TRANS_SUBR(4);
14274
14275                 /* avail units */
14276                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14277                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
14278                 COUNT_BYTES_TRANS_SUBR(4);
14279
14280                 /* bytes per sector, only 16bit integer here */
14281                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14282                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14283                 COUNT_BYTES_TRANS_SUBR(2);
14284
14285                 break;
14286         case 2:         /* SMB_INFO_VOLUME */
14287                 /* volume serial number */
14288                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14289                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
14290                 COUNT_BYTES_TRANS_SUBR(4);
14291
14292                 /* volume label length, only one byte here */
14293                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
14294                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
14295                 COUNT_BYTES_TRANS_SUBR(1);
14296
14297                 /* label */
14298                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
14299                 CHECK_STRING_TRANS_SUBR(fn);
14300                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14301                         fn);
14302                 COUNT_BYTES_TRANS_SUBR(fn_len);
14303
14304                 break;
14305         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
14306         case 1002:      /* SMB_FS_LABEL_INFORMATION */
14307                 /* volume label length */
14308                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14309                 vll = tvb_get_letohl(tvb, offset);
14310                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
14311                 COUNT_BYTES_TRANS_SUBR(4);
14312
14313                 /* label */
14314                 fn_len = vll;
14315                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14316                 CHECK_STRING_TRANS_SUBR(fn);
14317                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14318                         fn);
14319                 COUNT_BYTES_TRANS_SUBR(fn_len);
14320
14321                 break;
14322         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
14323         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
14324                 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
14325                 break;
14326         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
14327         case 1003:      /* SMB_FS_SIZE_INFORMATION */
14328                 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
14329                 break;
14330         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
14331         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
14332                 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, bcp);
14333                 break;
14334         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
14335         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
14336                 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
14337                 break;
14338         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
14339                 proto_item *item = NULL;
14340                 proto_tree *subtree = NULL;
14341                 guint32 caps_lo, caps_hi;
14342
14343                 /* MajorVersionNumber */
14344                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14345                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
14346                 COUNT_BYTES_TRANS_SUBR(2);
14347
14348                 /* MinorVersionNumber */
14349                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14350                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
14351                 COUNT_BYTES_TRANS_SUBR(2);
14352
14353                 /* Capability */
14354
14355                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14356
14357                 caps_lo = tvb_get_letohl(tvb, offset);
14358                 caps_hi = tvb_get_letohl(tvb, offset + 4);
14359
14360                 if (tree) {
14361                         item = proto_tree_add_text(
14362                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x",
14363                                 caps_hi, caps_lo);
14364                         subtree = proto_item_add_subtree(
14365                                 item, ett_smb_unix_capabilities);
14366                 }
14367
14368                 proto_tree_add_boolean(
14369                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8,
14370                         caps_lo);
14371
14372                 proto_tree_add_boolean(
14373                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8,
14374                         caps_lo);
14375
14376                 COUNT_BYTES_TRANS_SUBR(8);
14377
14378                 break;
14379         }
14380         case 0x301:     /* MAC_QUERY_FS_INFO */
14381                 /* Create time */
14382                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14383                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
14384                 *bcp -= 8;
14385                 /* Modify Time */
14386                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14387                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
14388                 *bcp -= 8;
14389                 /* Backup Time */
14390                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14391                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
14392                 *bcp -= 8;
14393                 /* Allocation blocks */
14394                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14395                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
14396                                     offset,
14397                                     4, TRUE);
14398                 COUNT_BYTES_TRANS_SUBR(4);
14399                 /* Allocation Block Size */
14400                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14401                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
14402                                     offset, 4, TRUE);
14403                 COUNT_BYTES_TRANS_SUBR(4);
14404                 /* Free Block Count */
14405                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14406                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
14407                                     offset, 4, TRUE);
14408                 COUNT_BYTES_TRANS_SUBR(4);
14409                 /* Finder Info ... */
14410                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
14411                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
14412                                             offset, 32,
14413                                             tvb_get_ptr(tvb, offset,32),
14414                                             "Finder Info: %s",
14415                                             tvb_format_text(tvb, offset, 32));
14416                 COUNT_BYTES_TRANS_SUBR(32);
14417                 /* Number Files */
14418                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14419                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
14420                                     offset, 4, TRUE);
14421                 COUNT_BYTES_TRANS_SUBR(4);
14422                 /* Number of Root Directories */
14423                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14424                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
14425                                     offset, 4, TRUE);
14426                 COUNT_BYTES_TRANS_SUBR(4);
14427                 /* Number of files */
14428                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14429                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
14430                                     offset, 4, TRUE);
14431                 COUNT_BYTES_TRANS_SUBR(4);
14432                 /* Dir Count */
14433                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14434                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
14435                                     offset, 4, TRUE);
14436                 COUNT_BYTES_TRANS_SUBR(4);
14437                 /* Mac Support Flags */
14438                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14439                 support = tvb_get_ntohl(tvb, offset);
14440                 item = proto_tree_add_text(tree, tvb, offset, 4,
14441                                            "Mac Support Flags: 0x%08x", support);
14442                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
14443                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
14444                                        tvb, offset, 4, support);
14445                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
14446                                        tvb, offset, 4, support);
14447                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
14448                                        tvb, offset, 4, support);
14449                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
14450                                        tvb, offset, 4, support);
14451                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
14452                                        tvb, offset, 4, support);
14453                 COUNT_BYTES_TRANS_SUBR(4);
14454                 break;
14455         case 1006:      /* QUERY_FS_QUOTA_INFO */
14456                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
14457                 break;
14458         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
14459                 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
14460                 break;
14461         case 1008: /* Query Object ID */ {
14462                 offset = dissect_qfsi_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, bcp);
14463                 break;
14464             }
14465         }
14466
14467         return offset;
14468 }
14469
14470 static int
14471 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
14472     proto_tree *parent_tree)
14473 {
14474         proto_item *item = NULL;
14475         proto_tree *tree = NULL;
14476         smb_info_t *si;
14477         smb_transact2_info_t *t2i;
14478         int count;
14479         gboolean trunc;
14480         int offset = 0;
14481         guint16 dc;
14482
14483         dc = tvb_reported_length(tvb);
14484
14485         si = (smb_info_t *)pinfo->private_data;
14486         DISSECTOR_ASSERT(si);
14487
14488         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14489                 t2i = si->sip->extra_info;
14490         else
14491                 t2i = NULL;
14492
14493         if(parent_tree){
14494                 if (t2i != NULL && t2i->subcmd != -1) {
14495                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
14496                                 "%s Data",
14497                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14498                                         "Unknown (0x%02x)"));
14499                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
14500                 } else {
14501                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
14502                                 "Unknown Transaction2 Data");
14503                 }
14504         }
14505
14506         if (t2i == NULL) {
14507                 offset += dc;
14508                 return offset;
14509         }
14510         switch(t2i->subcmd){
14511         case 0x00:      /*TRANS2_OPEN2*/
14512                 /* XXX not implemented yet. See SNIA doc */
14513                 break;
14514         case 0x01:      /*TRANS2_FIND_FIRST2*/
14515                 /* returned data */
14516                 count = si->info_count;
14517
14518         if(count == -1) {
14519             break;
14520         }
14521                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14522                         col_append_str(pinfo->cinfo, COL_INFO,
14523                         ", Files:");
14524                 }
14525
14526                 while(count--){
14527                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14528                                 offset, &dc, &trunc);
14529                         if (trunc)
14530                                 break;
14531                 }
14532                 break;
14533         case 0x02:      /*TRANS2_FIND_NEXT2*/
14534                 /* returned data */
14535                 count = si->info_count;
14536
14537         if(count == -1) {
14538             break;
14539         }
14540                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14541                         col_append_str(pinfo->cinfo, COL_INFO,
14542                         ", Files:");
14543                 }
14544
14545                 while(count--){
14546                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14547                                 offset, &dc, &trunc);
14548                         if (trunc)
14549                                 break;
14550                 }
14551                 break;
14552         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14553                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
14554                 break;
14555         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14556                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14557                 break;
14558         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14559                 /* no data in this response */
14560                 break;
14561         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14562                 /* identical to QUERY_PATH_INFO */
14563                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14564                 break;
14565         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14566                 /* no data in this response */
14567                 break;
14568         case 0x09:      /*TRANS2_FSCTL*/
14569                 /* XXX dont know how to dissect this one (yet)*/
14570
14571                 /*
14572                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14573                  * Extensions Version 3.0, Document Version 1.11,
14574                  * July 19, 1990" says this this contains a
14575                  * "File system specific return data block".
14576                  * (That means we may not be able to dissect it in any
14577                  * case.)
14578                  */
14579                 break;
14580         case 0x0a:      /*TRANS2_IOCTL2*/
14581                 /* XXX dont know how to dissect this one (yet)*/
14582
14583                 /*
14584                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14585                  * Extensions Version 3.0, Document Version 1.11,
14586                  * July 19, 1990" says this this contains a
14587                  * "Device/function specific return data block".
14588                  * (That means we may not be able to dissect it in any
14589                  * case.)
14590                  */
14591                 break;
14592         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14593                 /* XXX dont know how to dissect this one (yet)*/
14594
14595                 /*
14596                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14597                  * Extensions Version 3.0, Document Version 1.11,
14598                  * July 19, 1990" says this this contains "the level
14599                  * dependent information about the changes which
14600                  * occurred".
14601                  */
14602                 break;
14603         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14604                 /* XXX dont know how to dissect this one (yet)*/
14605
14606                 /*
14607                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14608                  * Extensions Version 3.0, Document Version 1.11,
14609                  * July 19, 1990" says this this contains "the level
14610                  * dependent information about the changes which
14611                  * occurred".
14612                  */
14613                 break;
14614         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14615                 /* no data in this response */
14616                 break;
14617         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14618                 /* XXX dont know how to dissect this one (yet)*/
14619                 break;
14620         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14621                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
14622                 break;
14623         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14624                 /* the SNIA spec appears to say the response has no data */
14625                 break;
14626         case -1:
14627                 /*
14628                  * We don't know what the matching request was; don't
14629                  * bother putting anything else into the tree for the data.
14630                  */
14631                 offset += dc;
14632                 dc = 0;
14633                 break;
14634         }
14635
14636         /* ooops there were data we didnt know how to process */
14637         if(dc != 0){
14638                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
14639                 offset += dc;
14640         }
14641
14642         return offset;
14643 }
14644
14645
14646 static void
14647 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14648 {
14649         proto_item *item = NULL;
14650         proto_tree *tree = NULL;
14651         smb_info_t *si;
14652         smb_transact2_info_t *t2i;
14653         guint16 fid;
14654         int lno;
14655         int offset = 0;
14656         int pc;
14657
14658         pc = tvb_reported_length(tvb);
14659
14660         si = (smb_info_t *)pinfo->private_data;
14661         DISSECTOR_ASSERT(si);
14662
14663         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14664                 t2i = si->sip->extra_info;
14665         else
14666                 t2i = NULL;
14667
14668         if(parent_tree){
14669                 if (t2i != NULL && t2i->subcmd != -1) {
14670                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14671                                 "%s Parameters",
14672                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14673                                                 "Unknown (0x%02x)"));
14674                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
14675                 } else {
14676                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14677                                 "Unknown Transaction2 Parameters");
14678                 }
14679         }
14680
14681         if (t2i == NULL) {
14682                 offset += pc;
14683                 return;
14684         }
14685         switch(t2i->subcmd){
14686         case 0x00:      /*TRANS2_OPEN2*/
14687                 /* fid */
14688                 fid = tvb_get_letohs(tvb, offset);
14689                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
14690                 offset += 2;
14691
14692                 /*
14693                  * XXX - Microsoft Networks SMB File Sharing Protocol
14694                  * Extensions Version 3.0, Document Version 1.11,
14695                  * July 19, 1990 says that the file attributes, create
14696                  * time (which it says is the last modification time),
14697                  * data size, granted access, file type, and IPC state
14698                  * are returned only if bit 0 is set in the open flags,
14699                  * and that the EA length is returned only if bit 3
14700                  * is set in the open flags.  Does that mean that,
14701                  * at least in that SMB dialect, those fields are not
14702                  * present in the reply parameters if the bits in
14703                  * question aren't set?
14704                  */
14705
14706                 /* File Attributes */
14707                 offset = dissect_file_attributes(tvb, tree, offset, 2);
14708
14709                 /* create time */
14710                 offset = dissect_smb_datetime(tvb, tree, offset,
14711                         hf_smb_create_time,
14712                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
14713
14714                 /* data size */
14715                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
14716                 offset += 4;
14717
14718                 /* granted access */
14719                 offset = dissect_access(tvb, tree, offset, "Granted");
14720
14721                 /* File Type */
14722                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
14723                 offset += 2;
14724
14725                 /* IPC State */
14726                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
14727
14728                 /* open_action */
14729                 offset = dissect_open_action(tvb, tree, offset);
14730
14731                 /* server unique file ID */
14732                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
14733                 offset += 4;
14734
14735                 /* ea error offset, only a 16 bit integer here */
14736                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14737                 offset += 2;
14738
14739                 /* ea length */
14740                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
14741                 offset += 4;
14742
14743                 break;
14744         case 0x01:      /*TRANS2_FIND_FIRST2*/
14745                 /* Find First2 information level */
14746                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
14747
14748                 /* sid */
14749                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
14750                 offset += 2;
14751
14752                 /* search count */
14753                 si->info_count = tvb_get_letohs(tvb, offset);
14754                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14755                 offset += 2;
14756
14757                 /* end of search */
14758                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14759                 offset += 2;
14760
14761                 /* ea error offset, only a 16 bit integer here */
14762                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14763                 offset += 2;
14764
14765                 /* last name offset */
14766                 lno = tvb_get_letohs(tvb, offset);
14767                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14768                 offset += 2;
14769
14770                 break;
14771         case 0x02:      /*TRANS2_FIND_NEXT2*/
14772                 /* search count */
14773                 si->info_count = tvb_get_letohs(tvb, offset);
14774                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14775                 offset += 2;
14776
14777                 /* end of search */
14778                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14779                 offset += 2;
14780
14781                 /* ea_error_offset, only a 16 bit integer here*/
14782                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14783                 offset += 2;
14784
14785                 /* last name offset */
14786                 lno = tvb_get_letohs(tvb, offset);
14787                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14788                 offset += 2;
14789
14790                 break;
14791         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14792                 /* no parameter block here */
14793                 break;
14794         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14795                 /* ea_error_offset, only a 16 bit integer here*/
14796                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14797                 offset += 2;
14798
14799                 break;
14800         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14801                 /* ea_error_offset, only a 16 bit integer here*/
14802                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14803                 offset += 2;
14804
14805                 break;
14806         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14807                 /* ea_error_offset, only a 16 bit integer here*/
14808                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14809                 offset += 2;
14810
14811                 break;
14812         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14813                 /* ea_error_offset, only a 16 bit integer here*/
14814                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14815                 offset += 2;
14816
14817                 break;
14818         case 0x09:      /*TRANS2_FSCTL*/
14819                 /* XXX dont know how to dissect this one (yet)*/
14820
14821                 /*
14822                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14823                  * Extensions Version 3.0, Document Version 1.11,
14824                  * July 19, 1990" says this this contains a
14825                  * "File system specific return parameter block".
14826                  * (That means we may not be able to dissect it in any
14827                  * case.)
14828                  */
14829                 break;
14830         case 0x0a:      /*TRANS2_IOCTL2*/
14831                 /* XXX dont know how to dissect this one (yet)*/
14832
14833                 /*
14834                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14835                  * Extensions Version 3.0, Document Version 1.11,
14836                  * July 19, 1990" says this this contains a
14837                  * "Device/function specific return parameter block".
14838                  * (That means we may not be able to dissect it in any
14839                  * case.)
14840                  */
14841                 break;
14842         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14843                 /* Find Notify information level */
14844                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14845
14846                 /* Monitor handle */
14847                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14848                 offset += 2;
14849
14850                 /* Change count */
14851                 si->info_count = tvb_get_letohs(tvb, offset);
14852                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14853                 offset += 2;
14854
14855                 /* ea_error_offset, only a 16 bit integer here*/
14856                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14857                 offset += 2;
14858
14859                 break;
14860         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14861                 /* Find Notify information level */
14862                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14863
14864                 /* Change count */
14865                 si->info_count = tvb_get_letohs(tvb, offset);
14866                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14867                 offset += 2;
14868
14869                 /* ea_error_offset, only a 16 bit integer here*/
14870                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14871                 offset += 2;
14872
14873                 break;
14874         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14875                 /* ea error offset, only a 16 bit integer here */
14876                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14877                 offset += 2;
14878
14879                 break;
14880         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14881                 /* XXX dont know how to dissect this one (yet)*/
14882                 break;
14883         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14884                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14885                 break;
14886         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14887                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14888                 break;
14889         case -1:
14890                 /*
14891                  * We don't know what the matching request was; don't
14892                  * bother putting anything else into the tree for the data.
14893                  */
14894                 offset += pc;
14895                 break;
14896         }
14897
14898         /* ooops there were data we didnt know how to process */
14899         if(offset<pc){
14900                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
14901                 offset += pc-offset;
14902         }
14903 }
14904
14905
14906 static int
14907 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14908 {
14909         guint8 sc, wc;
14910         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
14911         smb_info_t *si;
14912         smb_transact2_info_t *t2i = NULL;
14913         guint16 bc;
14914         int padcnt;
14915         gboolean dissected_trans;
14916         fragment_data *r_fd = NULL;
14917         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
14918         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
14919         gboolean save_fragmented;
14920         proto_item *item;
14921
14922         si = (smb_info_t *)pinfo->private_data;
14923         DISSECTOR_ASSERT(si);
14924
14925         switch(si->cmd){
14926         case SMB_COM_TRANSACTION2:
14927                 /* transaction2 */
14928                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
14929                         t2i = si->sip->extra_info;
14930                 } else
14931                         t2i = NULL;
14932                 if (t2i == NULL) {
14933                         /*
14934                          * We didn't see the matching request, so we don't
14935                          * know what type of transaction this is.
14936                          */
14937                         proto_tree_add_text(tree, tvb, 0, 0,
14938                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
14939                         if (check_col(pinfo->cinfo, COL_INFO)) {
14940                                 col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
14941                         }
14942                 } else {
14943                         si->info_level = t2i->info_level;
14944                         if (t2i->subcmd == -1) {
14945                                 /*
14946                                  * We didn't manage to extract the subcommand
14947                                  * from the matching request (perhaps because
14948                                  * the frame was short), so we don't know what
14949                                  * type of transaction this is.
14950                                  */
14951                                 proto_tree_add_text(tree, tvb, 0, 0,
14952                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
14953                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14954                                         col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
14955                                 }
14956                         } else {
14957                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
14958                                 /* FIND_FIRST2 */
14959                                 if(t2i && t2i->subcmd==0x0001){
14960                                         item=proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
14961                                         PROTO_ITEM_SET_GENERATED(item);
14962                                         if(t2i->name){
14963                                                 item=proto_tree_add_string(tree, hf_smb_search_pattern, tvb, 0, 0, t2i->name);
14964                                                 PROTO_ITEM_SET_GENERATED(item);
14965                                         }
14966                                 }
14967
14968                                 /* QUERY_PATH_INFORMATION */
14969                                 if(t2i && t2i->subcmd==0x0005){
14970                                         item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
14971                                         PROTO_ITEM_SET_GENERATED(item);
14972                                         if(t2i->name){
14973                                                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, t2i->name);
14974                                                 PROTO_ITEM_SET_GENERATED(item);
14975                                         }
14976                                 }
14977                                 /* QUERY_FILE_INFORMATION */
14978                                 if(t2i && t2i->subcmd==0x0007){
14979                                         item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
14980                                         PROTO_ITEM_SET_GENERATED(item);
14981                                 }
14982                                 /* QUERY_FS_INFORMATION */
14983                                 if(t2i && t2i->subcmd==0x0003){
14984                                         item=proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level);
14985                                         PROTO_ITEM_SET_GENERATED(item);
14986                                 }
14987
14988                                 if (t2i && check_col(pinfo->cinfo, COL_INFO)) {
14989                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
14990                                                 val_to_str(t2i->subcmd,
14991                                                         trans2_cmd_vals,
14992                                                         "<unknown (0x%02x)>"));
14993                                 }
14994                         }
14995                 }
14996                 break;
14997         }
14998
14999         WORD_COUNT;
15000
15001         /* total param count, only a 16bit integer here */
15002         tp = tvb_get_letohs(tvb, offset);
15003         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
15004         offset += 2;
15005
15006         /* total data count, only a 16 bit integer here */
15007         td = tvb_get_letohs(tvb, offset);
15008         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
15009         offset += 2;
15010
15011         /* 2 reserved bytes */
15012         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
15013         offset += 2;
15014
15015         /* param count */
15016         pc = tvb_get_letohs(tvb, offset);
15017         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
15018         offset += 2;
15019
15020         /* param offset */
15021         po = tvb_get_letohs(tvb, offset);
15022         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
15023         offset += 2;
15024
15025         /* param disp */
15026         pd = tvb_get_letohs(tvb, offset);
15027         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
15028         offset += 2;
15029
15030         /* data count */
15031         dc = tvb_get_letohs(tvb, offset);
15032         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
15033         offset += 2;
15034
15035         /* data offset */
15036         od = tvb_get_letohs(tvb, offset);
15037         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
15038         offset += 2;
15039
15040         /* data disp */
15041         dd = tvb_get_letohs(tvb, offset);
15042         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
15043         offset += 2;
15044
15045         /* setup count */
15046         sc = tvb_get_guint8(tvb, offset);
15047         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
15048         offset += 1;
15049
15050         /* reserved byte */
15051         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
15052         offset += 1;
15053
15054
15055         /* if there were any setup bytes, put them in a tvb for later */
15056         if(sc){
15057                 if((2*sc)>tvb_length_remaining(tvb, offset)){
15058                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
15059                 } else {
15060                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
15061                 }
15062                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
15063         } else {
15064                 s_tvb = NULL;
15065                 sp_tvb=NULL;
15066         }
15067         offset += 2*sc;
15068
15069
15070         BYTE_COUNT;
15071
15072
15073         /* reassembly of SMB Transaction data payload.
15074            In this section we do reassembly of both the data and parameters
15075            blocks of the SMB transaction command.
15076         */
15077         save_fragmented = pinfo->fragmented;
15078         /* do we need reassembly? */
15079         if( (td!=dc) || (tp!=pc) ){
15080                 /* oh yeah, either data or parameter section needs
15081                    reassembly
15082                 */
15083                 pinfo->fragmented = TRUE;
15084                 if(smb_trans_reassembly){
15085                         /* ...and we were told to do reassembly */
15086                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
15087                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
15088                                                              po, pc, pd, td+tp);
15089
15090                         }
15091                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
15092                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
15093                                                              od, dc, dd+tp, td+tp);
15094                         }
15095                 }
15096         }
15097
15098         /* if we got a reassembled fd structure from the reassembly routine we must
15099            create pd_tvb from it
15100         */
15101         if(r_fd){
15102         proto_item *frag_tree_item;
15103
15104                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
15105                                              r_fd->datalen);
15106                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
15107                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
15108                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
15109         }
15110
15111
15112         if(pd_tvb){
15113                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
15114                 if(tp){
15115                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
15116                 }
15117                 if(td){
15118                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
15119                 }
15120         } else {
15121                 /* It was not reassembled. Do as best as we can.
15122                  * in this case we always try to dissect the stuff if
15123                  * data and param displacement is 0. i.e. for the first
15124                  * (and maybe only) packet.
15125                  */
15126                 if( (pd==0) && (dd==0) ){
15127                         int min;
15128                         int reported_min;
15129                         min = MIN(pc,tvb_length_remaining(tvb,po));
15130                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
15131                         if(min && reported_min) {
15132                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
15133                         }
15134                         min = MIN(dc,tvb_length_remaining(tvb,od));
15135                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
15136                         if(min && reported_min) {
15137                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
15138                         }
15139                         /*
15140                          * A tvbuff containing the parameters
15141                          * and the data.
15142                          * XXX - check pc and dc as well?
15143                          */
15144                         if (tvb_length_remaining(tvb, po)){
15145                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
15146                         }
15147                 }
15148         }
15149
15150
15151
15152         /* parameters */
15153         if(po>offset){
15154                 /* We have some padding bytes.
15155                 */
15156                 padcnt = po-offset;
15157                 if (padcnt > bc)
15158                         padcnt = bc;
15159                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
15160                 COUNT_BYTES(padcnt);
15161         }
15162         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
15163                 /* TRANSACTION2 parameters*/
15164                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
15165         }
15166         COUNT_BYTES(pc);
15167
15168
15169         /* data */
15170         if(od>offset){
15171                 /* We have some initial padding bytes.
15172                 */
15173                 padcnt = od-offset;
15174                 if (padcnt > bc)
15175                         padcnt = bc;
15176                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
15177                 COUNT_BYTES(padcnt);
15178         }
15179         /*
15180          * If the data count is bigger than the count of bytes
15181          * remaining, clamp it so that the count of bytes remaining
15182          * doesn't go negative.
15183          */
15184         if (dc > bc)
15185                 dc = bc;
15186         COUNT_BYTES(dc);
15187
15188
15189
15190         /* from now on, everything is in separate tvbuffs so we dont count
15191            the bytes with COUNT_BYTES any more.
15192            neither do we reference offset any more (which by now points to the
15193            first byte AFTER this PDU */
15194
15195
15196         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
15197                 /* TRANSACTION2 parameters*/
15198                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
15199         }
15200
15201
15202         if(si->cmd==SMB_COM_TRANSACTION){
15203                 smb_transact_info_t *tri;
15204
15205                 dissected_trans = FALSE;
15206                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_TRI)
15207                         tri = si->sip->extra_info;
15208                 else
15209                         tri = NULL;
15210                 if (tri != NULL) {
15211                         switch(tri->subcmd){
15212
15213                         case TRANSACTION_PIPE:
15214                                 /* This function is safe to call for
15215                                    s_tvb==sp_tvb==NULL, i.e. if we don't
15216                                    know them at this point.
15217                                    It's also safe to call if "p_tvb"
15218                                    or "d_tvb" are null.
15219                                 */
15220                                 if( pd_tvb) {
15221                                         dissected_trans = dissect_pipe_smb(
15222                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
15223                                                 d_tvb, NULL, pinfo, top_tree);
15224                                 }
15225                                 break;
15226
15227                         case TRANSACTION_MAILSLOT:
15228                                 /* This one should be safe to call
15229                                    even if s_tvb and sp_tvb is NULL
15230                                 */
15231                                 if(d_tvb){
15232                                         dissected_trans = dissect_mailslot_smb(
15233                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
15234                                                 top_tree);
15235                                 }
15236                                 break;
15237                         }
15238                 }
15239                 if (!dissected_trans) {
15240                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
15241                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
15242                 }
15243         }
15244
15245
15246         if( (p_tvb==0) && (d_tvb==0) ){
15247                 if(check_col(pinfo->cinfo, COL_INFO)){
15248                         col_append_str(pinfo->cinfo, COL_INFO,
15249                                        "[transact continuation]");
15250                 }
15251         }
15252
15253         pinfo->fragmented = save_fragmented;
15254         END_OF_SMB
15255
15256         return offset;
15257 }
15258
15259
15260 static int
15261 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15262 {
15263         guint8 wc;
15264         guint16 bc;
15265
15266         WORD_COUNT;
15267
15268         /* Monitor handle */
15269         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
15270         offset += 2;
15271
15272         BYTE_COUNT;
15273
15274         END_OF_SMB
15275
15276         return offset;
15277 }
15278
15279 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15280    END Transaction/Transaction2 Primary and secondary requests
15281    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15282
15283
15284 static int
15285 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15286 {
15287         guint8 wc;
15288         guint16 bc;
15289
15290         WORD_COUNT;
15291
15292         if (wc != 0) {
15293                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
15294                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
15295                 offset += wc*2;
15296         }
15297
15298         BYTE_COUNT;
15299
15300         if (bc != 0) {
15301                 tvb_ensure_bytes_exist(tvb, offset, bc);
15302                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
15303                 offset += bc;
15304                 bc = 0;
15305         }
15306
15307         END_OF_SMB
15308
15309         return offset;
15310 }
15311
15312 typedef struct _smb_function {
15313        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15314        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15315 } smb_function;
15316
15317 static smb_function smb_dissector[256] = {
15318   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
15319   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
15320   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
15321   /* 0x03 Create File*/  {dissect_create_file_request, dissect_create_file_response},
15322   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
15323   /* 0x05 Flush File*/  {dissect_flush_file_request, dissect_empty},
15324   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
15325   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_rename_file_response},
15326   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
15327   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
15328   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
15329   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
15330   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
15331   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
15332   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
15333   /* 0x0f Create New*/  {dissect_create_file_request, dissect_create_new_response},
15334
15335   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
15336   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
15337   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
15338   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
15339   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
15340   /* 0x15 */  {dissect_unknown, dissect_unknown},
15341   /* 0x16 */  {dissect_unknown, dissect_unknown},
15342   /* 0x17 */  {dissect_unknown, dissect_unknown},
15343   /* 0x18 */  {dissect_unknown, dissect_unknown},
15344   /* 0x19 */  {dissect_unknown, dissect_unknown},
15345   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
15346   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
15347   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
15348   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
15349   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
15350   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
15351
15352   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
15353   /* 0x21 */  {dissect_unknown, dissect_unknown},
15354   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
15355   /* 0x23 Query Info2*/  {dissect_query_information2_request, dissect_query_information2_response},
15356   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
15357   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
15358   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
15359   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
15360   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
15361   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
15362   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
15363   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
15364   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
15365   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
15366   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
15367   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
15368
15369   /* 0x30 */  {dissect_unknown, dissect_unknown},
15370   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
15371   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
15372   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
15373   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
15374   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
15375   /* 0x36 */  {dissect_unknown, dissect_unknown},
15376   /* 0x37 */  {dissect_unknown, dissect_unknown},
15377   /* 0x38 */  {dissect_unknown, dissect_unknown},
15378   /* 0x39 */  {dissect_unknown, dissect_unknown},
15379   /* 0x3a */  {dissect_unknown, dissect_unknown},
15380   /* 0x3b */  {dissect_unknown, dissect_unknown},
15381   /* 0x3c */  {dissect_unknown, dissect_unknown},
15382   /* 0x3d */  {dissect_unknown, dissect_unknown},
15383   /* 0x3e */  {dissect_unknown, dissect_unknown},
15384   /* 0x3f */  {dissect_unknown, dissect_unknown},
15385
15386   /* 0x40 */  {dissect_unknown, dissect_unknown},
15387   /* 0x41 */  {dissect_unknown, dissect_unknown},
15388   /* 0x42 */  {dissect_unknown, dissect_unknown},
15389   /* 0x43 */  {dissect_unknown, dissect_unknown},
15390   /* 0x44 */  {dissect_unknown, dissect_unknown},
15391   /* 0x45 */  {dissect_unknown, dissect_unknown},
15392   /* 0x46 */  {dissect_unknown, dissect_unknown},
15393   /* 0x47 */  {dissect_unknown, dissect_unknown},
15394   /* 0x48 */  {dissect_unknown, dissect_unknown},
15395   /* 0x49 */  {dissect_unknown, dissect_unknown},
15396   /* 0x4a */  {dissect_unknown, dissect_unknown},
15397   /* 0x4b */  {dissect_unknown, dissect_unknown},
15398   /* 0x4c */  {dissect_unknown, dissect_unknown},
15399   /* 0x4d */  {dissect_unknown, dissect_unknown},
15400   /* 0x4e */  {dissect_unknown, dissect_unknown},
15401   /* 0x4f */  {dissect_unknown, dissect_unknown},
15402
15403   /* 0x50 */  {dissect_unknown, dissect_unknown},
15404   /* 0x51 */  {dissect_unknown, dissect_unknown},
15405   /* 0x52 */  {dissect_unknown, dissect_unknown},
15406   /* 0x53 */  {dissect_unknown, dissect_unknown},
15407   /* 0x54 */  {dissect_unknown, dissect_unknown},
15408   /* 0x55 */  {dissect_unknown, dissect_unknown},
15409   /* 0x56 */  {dissect_unknown, dissect_unknown},
15410   /* 0x57 */  {dissect_unknown, dissect_unknown},
15411   /* 0x58 */  {dissect_unknown, dissect_unknown},
15412   /* 0x59 */  {dissect_unknown, dissect_unknown},
15413   /* 0x5a */  {dissect_unknown, dissect_unknown},
15414   /* 0x5b */  {dissect_unknown, dissect_unknown},
15415   /* 0x5c */  {dissect_unknown, dissect_unknown},
15416   /* 0x5d */  {dissect_unknown, dissect_unknown},
15417   /* 0x5e */  {dissect_unknown, dissect_unknown},
15418   /* 0x5f */  {dissect_unknown, dissect_unknown},
15419
15420   /* 0x60 */  {dissect_unknown, dissect_unknown},
15421   /* 0x61 */  {dissect_unknown, dissect_unknown},
15422   /* 0x62 */  {dissect_unknown, dissect_unknown},
15423   /* 0x63 */  {dissect_unknown, dissect_unknown},
15424   /* 0x64 */  {dissect_unknown, dissect_unknown},
15425   /* 0x65 */  {dissect_unknown, dissect_unknown},
15426   /* 0x66 */  {dissect_unknown, dissect_unknown},
15427   /* 0x67 */  {dissect_unknown, dissect_unknown},
15428   /* 0x68 */  {dissect_unknown, dissect_unknown},
15429   /* 0x69 */  {dissect_unknown, dissect_unknown},
15430   /* 0x6a */  {dissect_unknown, dissect_unknown},
15431   /* 0x6b */  {dissect_unknown, dissect_unknown},
15432   /* 0x6c */  {dissect_unknown, dissect_unknown},
15433   /* 0x6d */  {dissect_unknown, dissect_unknown},
15434   /* 0x6e */  {dissect_unknown, dissect_unknown},
15435   /* 0x6f */  {dissect_unknown, dissect_unknown},
15436
15437   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
15438   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
15439   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
15440   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
15441   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
15442   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
15443   /* 0x76 */  {dissect_unknown, dissect_unknown},
15444   /* 0x77 */  {dissect_unknown, dissect_unknown},
15445   /* 0x78 */  {dissect_unknown, dissect_unknown},
15446   /* 0x79 */  {dissect_unknown, dissect_unknown},
15447   /* 0x7a */  {dissect_unknown, dissect_unknown},
15448   /* 0x7b */  {dissect_unknown, dissect_unknown},
15449   /* 0x7c */  {dissect_unknown, dissect_unknown},
15450   /* 0x7d */  {dissect_unknown, dissect_unknown},
15451   /* 0x7e */  {dissect_unknown, dissect_unknown},
15452   /* 0x7f */  {dissect_unknown, dissect_unknown},
15453
15454   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
15455   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
15456   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
15457   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
15458   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
15459   /* 0x85 */  {dissect_unknown, dissect_unknown},
15460   /* 0x86 */  {dissect_unknown, dissect_unknown},
15461   /* 0x87 */  {dissect_unknown, dissect_unknown},
15462   /* 0x88 */  {dissect_unknown, dissect_unknown},
15463   /* 0x89 */  {dissect_unknown, dissect_unknown},
15464   /* 0x8a */  {dissect_unknown, dissect_unknown},
15465   /* 0x8b */  {dissect_unknown, dissect_unknown},
15466   /* 0x8c */  {dissect_unknown, dissect_unknown},
15467   /* 0x8d */  {dissect_unknown, dissect_unknown},
15468   /* 0x8e */  {dissect_unknown, dissect_unknown},
15469   /* 0x8f */  {dissect_unknown, dissect_unknown},
15470
15471   /* 0x90 */  {dissect_unknown, dissect_unknown},
15472   /* 0x91 */  {dissect_unknown, dissect_unknown},
15473   /* 0x92 */  {dissect_unknown, dissect_unknown},
15474   /* 0x93 */  {dissect_unknown, dissect_unknown},
15475   /* 0x94 */  {dissect_unknown, dissect_unknown},
15476   /* 0x95 */  {dissect_unknown, dissect_unknown},
15477   /* 0x96 */  {dissect_unknown, dissect_unknown},
15478   /* 0x97 */  {dissect_unknown, dissect_unknown},
15479   /* 0x98 */  {dissect_unknown, dissect_unknown},
15480   /* 0x99 */  {dissect_unknown, dissect_unknown},
15481   /* 0x9a */  {dissect_unknown, dissect_unknown},
15482   /* 0x9b */  {dissect_unknown, dissect_unknown},
15483   /* 0x9c */  {dissect_unknown, dissect_unknown},
15484   /* 0x9d */  {dissect_unknown, dissect_unknown},
15485   /* 0x9e */  {dissect_unknown, dissect_unknown},
15486   /* 0x9f */  {dissect_unknown, dissect_unknown},
15487
15488   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
15489   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
15490   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
15491   /* 0xa3 */  {dissect_unknown, dissect_unknown},
15492   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
15493   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
15494   /* 0xa6 */  {dissect_unknown, dissect_unknown},
15495   /* 0xa7 */  {dissect_unknown, dissect_unknown},
15496   /* 0xa8 */  {dissect_unknown, dissect_unknown},
15497   /* 0xa9 */  {dissect_unknown, dissect_unknown},
15498   /* 0xaa */  {dissect_unknown, dissect_unknown},
15499   /* 0xab */  {dissect_unknown, dissect_unknown},
15500   /* 0xac */  {dissect_unknown, dissect_unknown},
15501   /* 0xad */  {dissect_unknown, dissect_unknown},
15502   /* 0xae */  {dissect_unknown, dissect_unknown},
15503   /* 0xaf */  {dissect_unknown, dissect_unknown},
15504
15505   /* 0xb0 */  {dissect_unknown, dissect_unknown},
15506   /* 0xb1 */  {dissect_unknown, dissect_unknown},
15507   /* 0xb2 */  {dissect_unknown, dissect_unknown},
15508   /* 0xb3 */  {dissect_unknown, dissect_unknown},
15509   /* 0xb4 */  {dissect_unknown, dissect_unknown},
15510   /* 0xb5 */  {dissect_unknown, dissect_unknown},
15511   /* 0xb6 */  {dissect_unknown, dissect_unknown},
15512   /* 0xb7 */  {dissect_unknown, dissect_unknown},
15513   /* 0xb8 */  {dissect_unknown, dissect_unknown},
15514   /* 0xb9 */  {dissect_unknown, dissect_unknown},
15515   /* 0xba */  {dissect_unknown, dissect_unknown},
15516   /* 0xbb */  {dissect_unknown, dissect_unknown},
15517   /* 0xbc */  {dissect_unknown, dissect_unknown},
15518   /* 0xbd */  {dissect_unknown, dissect_unknown},
15519   /* 0xbe */  {dissect_unknown, dissect_unknown},
15520   /* 0xbf */  {dissect_unknown, dissect_unknown},
15521
15522   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_open_print_file_response},
15523   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
15524   /* 0xc2 Close Print File*/  {dissect_close_print_file_request, dissect_empty},
15525   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
15526   /* 0xc4 */  {dissect_unknown, dissect_unknown},
15527   /* 0xc5 */  {dissect_unknown, dissect_unknown},
15528   /* 0xc6 */  {dissect_unknown, dissect_unknown},
15529   /* 0xc7 */  {dissect_unknown, dissect_unknown},
15530   /* 0xc8 */  {dissect_unknown, dissect_unknown},
15531   /* 0xc9 */  {dissect_unknown, dissect_unknown},
15532   /* 0xca */  {dissect_unknown, dissect_unknown},
15533   /* 0xcb */  {dissect_unknown, dissect_unknown},
15534   /* 0xcc */  {dissect_unknown, dissect_unknown},
15535   /* 0xcd */  {dissect_unknown, dissect_unknown},
15536   /* 0xce */  {dissect_unknown, dissect_unknown},
15537   /* 0xcf */  {dissect_unknown, dissect_unknown},
15538
15539   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
15540   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
15541   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
15542   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
15543   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
15544   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
15545   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
15546   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
15547   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
15548   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
15549   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
15550   /* 0xdb */  {dissect_unknown, dissect_unknown},
15551   /* 0xdc */  {dissect_unknown, dissect_unknown},
15552   /* 0xdd */  {dissect_unknown, dissect_unknown},
15553   /* 0xde */  {dissect_unknown, dissect_unknown},
15554   /* 0xdf */  {dissect_unknown, dissect_unknown},
15555
15556   /* 0xe0 */  {dissect_unknown, dissect_unknown},
15557   /* 0xe1 */  {dissect_unknown, dissect_unknown},
15558   /* 0xe2 */  {dissect_unknown, dissect_unknown},
15559   /* 0xe3 */  {dissect_unknown, dissect_unknown},
15560   /* 0xe4 */  {dissect_unknown, dissect_unknown},
15561   /* 0xe5 */  {dissect_unknown, dissect_unknown},
15562   /* 0xe6 */  {dissect_unknown, dissect_unknown},
15563   /* 0xe7 */  {dissect_unknown, dissect_unknown},
15564   /* 0xe8 */  {dissect_unknown, dissect_unknown},
15565   /* 0xe9 */  {dissect_unknown, dissect_unknown},
15566   /* 0xea */  {dissect_unknown, dissect_unknown},
15567   /* 0xeb */  {dissect_unknown, dissect_unknown},
15568   /* 0xec */  {dissect_unknown, dissect_unknown},
15569   /* 0xed */  {dissect_unknown, dissect_unknown},
15570   /* 0xee */  {dissect_unknown, dissect_unknown},
15571   /* 0xef */  {dissect_unknown, dissect_unknown},
15572
15573   /* 0xf0 */  {dissect_unknown, dissect_unknown},
15574   /* 0xf1 */  {dissect_unknown, dissect_unknown},
15575   /* 0xf2 */  {dissect_unknown, dissect_unknown},
15576   /* 0xf3 */  {dissect_unknown, dissect_unknown},
15577   /* 0xf4 */  {dissect_unknown, dissect_unknown},
15578   /* 0xf5 */  {dissect_unknown, dissect_unknown},
15579   /* 0xf6 */  {dissect_unknown, dissect_unknown},
15580   /* 0xf7 */  {dissect_unknown, dissect_unknown},
15581   /* 0xf8 */  {dissect_unknown, dissect_unknown},
15582   /* 0xf9 */  {dissect_unknown, dissect_unknown},
15583   /* 0xfa */  {dissect_unknown, dissect_unknown},
15584   /* 0xfb */  {dissect_unknown, dissect_unknown},
15585   /* 0xfc */  {dissect_unknown, dissect_unknown},
15586   /* 0xfd */  {dissect_unknown, dissect_unknown},
15587   /* 0xfe */  {dissect_unknown, dissect_unknown},
15588   /* 0xff */  {dissect_unknown, dissect_unknown},
15589 };
15590
15591 static int
15592 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
15593 {
15594         smb_info_t *si;
15595         smb_saved_info_t *sip;
15596
15597         si = pinfo->private_data;
15598         DISSECTOR_ASSERT(si);
15599
15600         if(cmd!=0xff){
15601                 proto_item *cmd_item;
15602                 proto_tree *cmd_tree;
15603                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15604
15605                 if (check_col(pinfo->cinfo, COL_INFO)) {
15606                         if(first_pdu){
15607                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15608                                         "%s %s",
15609                                         decode_smb_name(cmd),
15610                                         (si->request)? "Request" : "Response");
15611                         } else {
15612                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15613                                         "; %s",
15614                                         decode_smb_name(cmd));
15615                         }
15616
15617                 }
15618
15619                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
15620                         "%s %s (0x%02x)",
15621                         decode_smb_name(cmd),
15622                         (si->request)?"Request":"Response",
15623                         cmd);
15624
15625                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
15626
15627                 /* we track FIDs on a per transaction basis.
15628                    if this was a request and the fid was seen in a reply
15629                    we add a "generated" fid tree for this pdu and v.v.
15630                  */
15631                 sip = si->sip;
15632                 if (sip && sip->fid) {
15633                         if( (si->request && (!sip->fid_seen_in_request))
15634                           ||((!si->request) && sip->fid_seen_in_request) ){
15635                                 dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE);
15636                         }
15637                 }
15638
15639                 dissector = (si->request)?
15640                         smb_dissector[cmd].request:smb_dissector[cmd].response;
15641
15642                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
15643                 proto_item_set_end(cmd_item, tvb, offset);
15644         }
15645         return offset;
15646 }
15647
15648
15649 /* NOTE: this value_string array will also be used to access data directly by
15650  * index instead of val_to_str() since
15651  * 1, the array will always span every value from 0x00 to 0xff and
15652  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
15653  * This means that this value_string array MUST always
15654  * 1, contain all entries 0x00 to 0xff
15655  * 2, all entries must be in order.
15656  */
15657 const value_string smb_cmd_vals[] = {
15658   { 0x00, "Create Directory" },
15659   { 0x01, "Delete Directory" },
15660   { 0x02, "Open" },
15661   { 0x03, "Create" },
15662   { 0x04, "Close" },
15663   { 0x05, "Flush" },
15664   { 0x06, "Delete" },
15665   { 0x07, "Rename" },
15666   { 0x08, "Query Information" },
15667   { 0x09, "Set Information" },
15668   { 0x0A, "Read" },
15669   { 0x0B, "Write" },
15670   { 0x0C, "Lock Byte Range" },
15671   { 0x0D, "Unlock Byte Range" },
15672   { 0x0E, "Create Temp" },
15673   { 0x0F, "Create New" },
15674   { 0x10, "Check Directory" },
15675   { 0x11, "Process Exit" },
15676   { 0x12, "Seek" },
15677   { 0x13, "Lock And Read" },
15678   { 0x14, "Write And Unlock" },
15679   { 0x15, "unknown-0x15" },
15680   { 0x16, "unknown-0x16" },
15681   { 0x17, "unknown-0x17" },
15682   { 0x18, "unknown-0x18" },
15683   { 0x19, "unknown-0x19" },
15684   { 0x1A, "Read Raw" },
15685   { 0x1B, "Read MPX" },
15686   { 0x1C, "Read MPX Secondary" },
15687   { 0x1D, "Write Raw" },
15688   { 0x1E, "Write MPX" },
15689   { 0x1F, "Write MPX Secondary" },
15690   { 0x20, "Write Complete" },
15691   { 0x21, "unknown-0x21" },
15692   { 0x22, "Set Information2" },
15693   { 0x23, "Query Information2" },
15694   { 0x24, "Locking AndX" },
15695   { 0x25, "Trans" },
15696   { 0x26, "Trans Secondary" },
15697   { 0x27, "IOCTL" },
15698   { 0x28, "IOCTL Secondary" },
15699   { 0x29, "Copy" },
15700   { 0x2A, "Move" },
15701   { 0x2B, "Echo" },
15702   { 0x2C, "Write And Close" },
15703   { 0x2D, "Open AndX" },
15704   { 0x2E, "Read AndX" },
15705   { 0x2F, "Write AndX" },
15706   { 0x30, "unknown-0x30" },
15707   { 0x31, "Close And Tree Disconnect" },
15708   { 0x32, "Trans2" },
15709   { 0x33, "Trans2 Secondary" },
15710   { 0x34, "Find Close2" },
15711   { 0x35, "Find Notify Close" },
15712   { 0x36, "unknown-0x36" },
15713   { 0x37, "unknown-0x37" },
15714   { 0x38, "unknown-0x38" },
15715   { 0x39, "unknown-0x39" },
15716   { 0x3A, "unknown-0x3A" },
15717   { 0x3B, "unknown-0x3B" },
15718   { 0x3C, "unknown-0x3C" },
15719   { 0x3D, "unknown-0x3D" },
15720   { 0x3E, "unknown-0x3E" },
15721   { 0x3F, "unknown-0x3F" },
15722   { 0x40, "unknown-0x40" },
15723   { 0x41, "unknown-0x41" },
15724   { 0x42, "unknown-0x42" },
15725   { 0x43, "unknown-0x43" },
15726   { 0x44, "unknown-0x44" },
15727   { 0x45, "unknown-0x45" },
15728   { 0x46, "unknown-0x46" },
15729   { 0x47, "unknown-0x47" },
15730   { 0x48, "unknown-0x48" },
15731   { 0x49, "unknown-0x49" },
15732   { 0x4A, "unknown-0x4A" },
15733   { 0x4B, "unknown-0x4B" },
15734   { 0x4C, "unknown-0x4C" },
15735   { 0x4D, "unknown-0x4D" },
15736   { 0x4E, "unknown-0x4E" },
15737   { 0x4F, "unknown-0x4F" },
15738   { 0x50, "unknown-0x50" },
15739   { 0x51, "unknown-0x51" },
15740   { 0x52, "unknown-0x52" },
15741   { 0x53, "unknown-0x53" },
15742   { 0x54, "unknown-0x54" },
15743   { 0x55, "unknown-0x55" },
15744   { 0x56, "unknown-0x56" },
15745   { 0x57, "unknown-0x57" },
15746   { 0x58, "unknown-0x58" },
15747   { 0x59, "unknown-0x59" },
15748   { 0x5A, "unknown-0x5A" },
15749   { 0x5B, "unknown-0x5B" },
15750   { 0x5C, "unknown-0x5C" },
15751   { 0x5D, "unknown-0x5D" },
15752   { 0x5E, "unknown-0x5E" },
15753   { 0x5F, "unknown-0x5F" },
15754   { 0x60, "unknown-0x60" },
15755   { 0x61, "unknown-0x61" },
15756   { 0x62, "unknown-0x62" },
15757   { 0x63, "unknown-0x63" },
15758   { 0x64, "unknown-0x64" },
15759   { 0x65, "unknown-0x65" },
15760   { 0x66, "unknown-0x66" },
15761   { 0x67, "unknown-0x67" },
15762   { 0x68, "unknown-0x68" },
15763   { 0x69, "unknown-0x69" },
15764   { 0x6A, "unknown-0x6A" },
15765   { 0x6B, "unknown-0x6B" },
15766   { 0x6C, "unknown-0x6C" },
15767   { 0x6D, "unknown-0x6D" },
15768   { 0x6E, "unknown-0x6E" },
15769   { 0x6F, "unknown-0x6F" },
15770   { 0x70, "Tree Connect" },
15771   { 0x71, "Tree Disconnect" },
15772   { 0x72, "Negotiate Protocol" },
15773   { 0x73, "Session Setup AndX" },
15774   { 0x74, "Logoff AndX" },
15775   { 0x75, "Tree Connect AndX" },
15776   { 0x76, "unknown-0x76" },
15777   { 0x77, "unknown-0x77" },
15778   { 0x78, "unknown-0x78" },
15779   { 0x79, "unknown-0x79" },
15780   { 0x7A, "unknown-0x7A" },
15781   { 0x7B, "unknown-0x7B" },
15782   { 0x7C, "unknown-0x7C" },
15783   { 0x7D, "unknown-0x7D" },
15784   { 0x7E, "unknown-0x7E" },
15785   { 0x7F, "unknown-0x7F" },
15786   { 0x80, "Query Information Disk" },
15787   { 0x81, "Search" },
15788   { 0x82, "Find" },
15789   { 0x83, "Find Unique" },
15790   { 0x84, "Find Close" },
15791   { 0x85, "unknown-0x85" },
15792   { 0x86, "unknown-0x86" },
15793   { 0x87, "unknown-0x87" },
15794   { 0x88, "unknown-0x88" },
15795   { 0x89, "unknown-0x89" },
15796   { 0x8A, "unknown-0x8A" },
15797   { 0x8B, "unknown-0x8B" },
15798   { 0x8C, "unknown-0x8C" },
15799   { 0x8D, "unknown-0x8D" },
15800   { 0x8E, "unknown-0x8E" },
15801   { 0x8F, "unknown-0x8F" },
15802   { 0x90, "unknown-0x90" },
15803   { 0x91, "unknown-0x91" },
15804   { 0x92, "unknown-0x92" },
15805   { 0x93, "unknown-0x93" },
15806   { 0x94, "unknown-0x94" },
15807   { 0x95, "unknown-0x95" },
15808   { 0x96, "unknown-0x96" },
15809   { 0x97, "unknown-0x97" },
15810   { 0x98, "unknown-0x98" },
15811   { 0x99, "unknown-0x99" },
15812   { 0x9A, "unknown-0x9A" },
15813   { 0x9B, "unknown-0x9B" },
15814   { 0x9C, "unknown-0x9C" },
15815   { 0x9D, "unknown-0x9D" },
15816   { 0x9E, "unknown-0x9E" },
15817   { 0x9F, "unknown-0x9F" },
15818   { 0xA0, "NT Trans" },
15819   { 0xA1, "NT Trans Secondary" },
15820   { 0xA2, "NT Create AndX" },
15821   { 0xA3, "unknown-0xA3" },
15822   { 0xA4, "NT Cancel" },
15823   { 0xA5, "NT Rename" },
15824   { 0xA6, "unknown-0xA6" },
15825   { 0xA7, "unknown-0xA7" },
15826   { 0xA8, "unknown-0xA8" },
15827   { 0xA9, "unknown-0xA9" },
15828   { 0xAA, "unknown-0xAA" },
15829   { 0xAB, "unknown-0xAB" },
15830   { 0xAC, "unknown-0xAC" },
15831   { 0xAD, "unknown-0xAD" },
15832   { 0xAE, "unknown-0xAE" },
15833   { 0xAF, "unknown-0xAF" },
15834   { 0xB0, "unknown-0xB0" },
15835   { 0xB1, "unknown-0xB1" },
15836   { 0xB2, "unknown-0xB2" },
15837   { 0xB3, "unknown-0xB3" },
15838   { 0xB4, "unknown-0xB4" },
15839   { 0xB5, "unknown-0xB5" },
15840   { 0xB6, "unknown-0xB6" },
15841   { 0xB7, "unknown-0xB7" },
15842   { 0xB8, "unknown-0xB8" },
15843   { 0xB9, "unknown-0xB9" },
15844   { 0xBA, "unknown-0xBA" },
15845   { 0xBB, "unknown-0xBB" },
15846   { 0xBC, "unknown-0xBC" },
15847   { 0xBD, "unknown-0xBD" },
15848   { 0xBE, "unknown-0xBE" },
15849   { 0xBF, "unknown-0xBF" },
15850   { 0xC0, "Open Print File" },
15851   { 0xC1, "Write Print File" },
15852   { 0xC2, "Close Print File" },
15853   { 0xC3, "Get Print Queue" },
15854   { 0xC4, "unknown-0xC4" },
15855   { 0xC5, "unknown-0xC5" },
15856   { 0xC6, "unknown-0xC6" },
15857   { 0xC7, "unknown-0xC7" },
15858   { 0xC8, "unknown-0xC8" },
15859   { 0xC9, "unknown-0xC9" },
15860   { 0xCA, "unknown-0xCA" },
15861   { 0xCB, "unknown-0xCB" },
15862   { 0xCC, "unknown-0xCC" },
15863   { 0xCD, "unknown-0xCD" },
15864   { 0xCE, "unknown-0xCE" },
15865   { 0xCF, "unknown-0xCF" },
15866   { 0xD0, "Send Single Block Message" },
15867   { 0xD1, "Send Broadcast Message" },
15868   { 0xD2, "Forward User Name" },
15869   { 0xD3, "Cancel Forward" },
15870   { 0xD4, "Get Machine Name" },
15871   { 0xD5, "Send Start of Multi-block Message" },
15872   { 0xD6, "Send End of Multi-block Message" },
15873   { 0xD7, "Send Text of Multi-block Message" },
15874   { 0xD8, "SMBreadbulk" },
15875   { 0xD9, "SMBwritebulk" },
15876   { 0xDA, "SMBwritebulkdata" },
15877   { 0xDB, "unknown-0xDB" },
15878   { 0xDC, "unknown-0xDC" },
15879   { 0xDD, "unknown-0xDD" },
15880   { 0xDE, "unknown-0xDE" },
15881   { 0xDF, "unknown-0xDF" },
15882   { 0xE0, "unknown-0xE0" },
15883   { 0xE1, "unknown-0xE1" },
15884   { 0xE2, "unknown-0xE2" },
15885   { 0xE3, "unknown-0xE3" },
15886   { 0xE4, "unknown-0xE4" },
15887   { 0xE5, "unknown-0xE5" },
15888   { 0xE6, "unknown-0xE6" },
15889   { 0xE7, "unknown-0xE7" },
15890   { 0xE8, "unknown-0xE8" },
15891   { 0xE9, "unknown-0xE9" },
15892   { 0xEA, "unknown-0xEA" },
15893   { 0xEB, "unknown-0xEB" },
15894   { 0xEC, "unknown-0xEC" },
15895   { 0xED, "unknown-0xED" },
15896   { 0xEE, "unknown-0xEE" },
15897   { 0xEF, "unknown-0xEF" },
15898   { 0xF0, "unknown-0xF0" },
15899   { 0xF1, "unknown-0xF1" },
15900   { 0xF2, "unknown-0xF2" },
15901   { 0xF3, "unknown-0xF3" },
15902   { 0xF4, "unknown-0xF4" },
15903   { 0xF5, "unknown-0xF5" },
15904   { 0xF6, "unknown-0xF6" },
15905   { 0xF7, "unknown-0xF7" },
15906   { 0xF8, "unknown-0xF8" },
15907   { 0xF9, "unknown-0xF9" },
15908   { 0xFA, "unknown-0xFA" },
15909   { 0xFB, "unknown-0xFB" },
15910   { 0xFC, "unknown-0xFC" },
15911   { 0xFD, "unknown-0xFD" },
15912   { 0xFE, "SMBinvalid" },
15913   { 0xFF, "unknown-0xFF" },
15914   { 0x00, NULL },
15915 };
15916
15917 static const char *decode_smb_name(guint8 cmd)
15918 {
15919   return(smb_cmd_vals[cmd].strptr);
15920 }
15921
15922
15923
15924 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15925  * Everything TVBUFFIFIED above this line
15926  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15927
15928
15929 static void
15930 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
15931 {
15932         conv_tables_t *ct = ctarg;
15933
15934         if (ct->unmatched)
15935                 g_hash_table_destroy(ct->unmatched);
15936         if (ct->matched)
15937                 g_hash_table_destroy(ct->matched);
15938         if (ct->tid_service)
15939                 g_hash_table_destroy(ct->tid_service);
15940         g_free(ct);
15941 }
15942
15943 static void
15944 smb_init_protocol(void)
15945 {
15946         /*
15947          * Free the hash tables attached to the conversation table
15948          * structures, and then free the list of conversation table
15949          * data structures.
15950          */
15951         if (conv_tables) {
15952                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
15953                 g_slist_free(conv_tables);
15954                 conv_tables = NULL;
15955         }
15956 }
15957
15958 static const value_string errcls_types[] = {
15959   { SMB_SUCCESS, "Success"},
15960   { SMB_ERRDOS, "DOS Error"},
15961   { SMB_ERRSRV, "Server Error"},
15962   { SMB_ERRHRD, "Hardware Error"},
15963   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
15964   { 0, NULL }
15965 };
15966
15967 /* Error codes for the ERRSRV class */
15968
15969 static const value_string SRV_errors[] = {
15970   {SMBE_error, "Non specific error code"},
15971   {SMBE_badpw, "Bad password"},
15972   {SMBE_badtype, "Reserved"},
15973   {SMBE_access, "No permissions to perform the requested operation"},
15974   {SMBE_invnid, "TID invalid"},
15975   {SMBE_invnetname, "Invalid network name. Service not found"},
15976   {SMBE_invdevice, "Invalid device"},
15977   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
15978   {SMBE_qfull, "Print queue full"},
15979   {SMBE_qtoobig, "Queued item too big"},
15980   {SMBE_qeof, "EOF on print queue dump"},
15981   {SMBE_invpfid, "Invalid print file in smb_fid"},
15982   {SMBE_smbcmd, "Unrecognised command"},
15983   {SMBE_srverror, "SMB server internal error"},
15984   {SMBE_filespecs, "Fid and pathname invalid combination"},
15985   {SMBE_badlink, "Bad link in request ???"},
15986   {SMBE_badpermits, "Access specified for a file is not valid"},
15987   {SMBE_badpid, "Bad process id in request"},
15988   {SMBE_setattrmode, "Attribute mode invalid"},
15989   {SMBE_paused, "Message server paused"},
15990   {SMBE_msgoff, "Not receiving messages"},
15991   {SMBE_noroom, "No room for message"},
15992   {SMBE_rmuns, "Too many remote usernames"},
15993   {SMBE_timeout, "Operation timed out"},
15994   {SMBE_noresource, "No resources currently available for request."},
15995   {SMBE_toomanyuids, "Too many userids"},
15996   {SMBE_baduid, "Bad userid"},
15997   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
15998   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
15999   {SMBE_contMPX, "Resume MPX mode"},
16000   {SMBE_badPW, "Bad Password???"},
16001   {SMBE_nosupport, "Operation not supported"},
16002   { 0, NULL}
16003 };
16004
16005 /* Error codes for the ERRHRD class */
16006
16007 static const value_string HRD_errors[] = {
16008   {SMBE_nowrite, "Read only media"},
16009   {SMBE_badunit, "Unknown device"},
16010   {SMBE_notready, "Drive not ready"},
16011   {SMBE_badcmd, "Unknown command"},
16012   {SMBE_data, "Data (CRC) error"},
16013   {SMBE_badreq, "Bad request structure length"},
16014   {SMBE_seek, "Seek error"},
16015   {SMBE_badmedia, "Unknown media type"},
16016   {SMBE_badsector, "Sector not found"},
16017   {SMBE_nopaper, "Printer out of paper"},
16018   {SMBE_write, "Write fault"},
16019   {SMBE_read, "Read fault"},
16020   {SMBE_general, "General failure"},
16021   {SMBE_badshare, "A open conflicts with an existing open"},
16022   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
16023   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
16024   {SMBE_FCBunavail, "No FCBs are available to process request"},
16025   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
16026   {SMBE_diskfull, "Disk full???"},
16027   {0, NULL}
16028 };
16029
16030 static const char *decode_smb_error(guint8 errcls, guint16 errcode)
16031 {
16032
16033   switch (errcls) {
16034
16035   case SMB_SUCCESS:
16036
16037     return("No Error");   /* No error ??? */
16038
16039   case SMB_ERRDOS:
16040
16041     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
16042
16043   case SMB_ERRSRV:
16044
16045     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
16046
16047   case SMB_ERRHRD:
16048
16049     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
16050
16051   default:
16052
16053     return("Unknown error class!");
16054
16055   }
16056
16057 }
16058
16059 static const true_false_string tfs_smb_flags_lock = {
16060         "Lock&Read, Write&Unlock are supported",
16061         "Lock&Read, Write&Unlock are not supported"
16062 };
16063 static const true_false_string tfs_smb_flags_receive_buffer = {
16064         "Receive buffer has been posted",
16065         "Receive buffer has not been posted"
16066 };
16067 static const true_false_string tfs_smb_flags_caseless = {
16068         "Path names are caseless",
16069         "Path names are case sensitive"
16070 };
16071 static const true_false_string tfs_smb_flags_canon = {
16072         "Pathnames are canonicalized",
16073         "Pathnames are not canonicalized"
16074 };
16075 static const true_false_string tfs_smb_flags_oplock = {
16076         "OpLock requested/granted",
16077         "OpLock not requested/granted"
16078 };
16079 static const true_false_string tfs_smb_flags_notify = {
16080         "Notify client on all modifications",
16081         "Notify client only on open"
16082 };
16083 static const true_false_string tfs_smb_flags_response = {
16084         "Message is a response to the client/redirector",
16085         "Message is a request to the server"
16086 };
16087
16088 static int
16089 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16090 {
16091         guint8 mask;
16092         proto_item *item;
16093         proto_tree *tree;
16094
16095         mask = tvb_get_guint8(tvb, offset);
16096
16097         if(parent_tree){
16098                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16099                         "Flags: 0x%02x", mask);
16100                 tree = proto_item_add_subtree(item, ett_smb_flags);
16101
16102                 proto_tree_add_boolean(tree, hf_smb_flags_response,
16103                         tvb, offset, 1, mask);
16104                 proto_tree_add_boolean(tree, hf_smb_flags_notify,
16105                         tvb, offset, 1, mask);
16106                 proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16107                         tvb, offset, 1, mask);
16108                 proto_tree_add_boolean(tree, hf_smb_flags_canon,
16109                         tvb, offset, 1, mask);
16110                 proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16111                         tvb, offset, 1, mask);
16112                 proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16113                         tvb, offset, 1, mask);
16114                 proto_tree_add_boolean(tree, hf_smb_flags_lock,
16115                         tvb, offset, 1, mask);
16116         }
16117
16118         offset += 1;
16119         return offset;
16120 }
16121
16122
16123
16124 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16125         "Long file names are allowed in the response",
16126         "Long file names are not allowed in the response"
16127 };
16128 static const true_false_string tfs_smb_flags2_ea = {
16129         "Extended attributes are supported",
16130         "Extended attributes are not supported"
16131 };
16132 static const true_false_string tfs_smb_flags2_sec_sig = {
16133         "Security signatures are supported",
16134         "Security signatures are not supported"
16135 };
16136 static const true_false_string tfs_smb_flags2_long_names_used = {
16137         "Path names in request are long file names",
16138         "Path names in request are not long file names"
16139 };
16140 static const true_false_string tfs_smb_flags2_esn = {
16141         "Extended security negotiation is supported",
16142         "Extended security negotiation is not supported"
16143 };
16144 static const true_false_string tfs_smb_flags2_dfs = {
16145         "Resolve pathnames with Dfs",
16146         "Don't resolve pathnames with Dfs"
16147 };
16148 static const true_false_string tfs_smb_flags2_roe = {
16149         "Permit reads if execute-only",
16150         "Don't permit reads if execute-only"
16151 };
16152 static const true_false_string tfs_smb_flags2_nt_error = {
16153         "Error codes are NT error codes",
16154         "Error codes are DOS error codes"
16155 };
16156 static const true_false_string tfs_smb_flags2_string = {
16157         "Strings are Unicode",
16158         "Strings are ASCII"
16159 };
16160 static int
16161 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16162 {
16163         guint16 mask;
16164         proto_item *item;
16165         proto_tree *tree;
16166
16167         mask = tvb_get_letohs(tvb, offset);
16168
16169         if(parent_tree){
16170                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16171                         "Flags2: 0x%04x", mask);
16172                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16173
16174                 proto_tree_add_boolean(tree, hf_smb_flags2_string,
16175                         tvb, offset, 2, mask);
16176                 proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16177                         tvb, offset, 2, mask);
16178                 proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16179                         tvb, offset, 2, mask);
16180                 proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16181                         tvb, offset, 2, mask);
16182                 proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16183                         tvb, offset, 2, mask);
16184                 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16185                         tvb, offset, 2, mask);
16186                 proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16187                         tvb, offset, 2, mask);
16188                 proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16189                         tvb, offset, 2, mask);
16190                 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16191                         tvb, offset, 2, mask);
16192         }
16193         offset += 2;
16194         return offset;
16195 }
16196
16197
16198
16199 #define SMB_FLAGS_DIRN 0x80
16200
16201
16202 static void
16203 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16204 {
16205         int offset = 0;
16206         proto_item *item = NULL, *hitem = NULL;
16207         proto_tree *tree = NULL, *htree = NULL;
16208         proto_item *tmp_item=NULL;
16209         guint8          flags;
16210         guint16         flags2;
16211         smb_info_t              *si;
16212         smb_saved_info_t *sip = NULL;
16213         smb_saved_info_key_t key;
16214         smb_saved_info_key_t *new_key;
16215         guint8 errclass = 0;
16216         guint16 errcode = 0;
16217         guint32 pid_mid;
16218         conversation_t *conversation;
16219         nstime_t t, deltat;
16220
16221         si=ep_alloc(sizeof(smb_info_t));
16222
16223         top_tree=parent_tree;
16224
16225         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
16226                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16227         }
16228         if (check_col(pinfo->cinfo, COL_INFO)){
16229                 col_clear(pinfo->cinfo, COL_INFO);
16230         }
16231
16232         /* start off using the local variable, we will allocate a new one if we
16233            need to*/
16234         si->cmd = tvb_get_guint8(tvb, offset+4);
16235         flags = tvb_get_guint8(tvb, offset+9);
16236         /*
16237          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16238          * the direction flag appears never to be set, even for what appear
16239          * to be replies.  Do some SMB servers fail to set that flag,
16240          * under the assumption that the client knows it's a reply because
16241          * it received it?
16242          */
16243         si->request = !(flags&SMB_FLAGS_DIRN);
16244         flags2 = tvb_get_letohs(tvb, offset+10);
16245         if(flags2 & 0x8000){
16246                 si->unicode = TRUE; /* Mark them as Unicode */
16247         } else {
16248                 si->unicode = FALSE;
16249         }
16250         si->tid = tvb_get_letohs(tvb, offset+24);
16251         si->pid = tvb_get_letohs(tvb, offset+26);
16252         si->uid = tvb_get_letohs(tvb, offset+28);
16253         si->mid = tvb_get_letohs(tvb, offset+30);
16254         pid_mid = (si->pid << 16) | si->mid;
16255         si->info_level = -1;
16256         si->info_count = -1;
16257
16258         if (parent_tree) {
16259                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16260                         -1, FALSE);
16261                 tree = proto_item_add_subtree(item, ett_smb);
16262
16263                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16264                         "SMB Header");
16265
16266                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16267         }
16268
16269         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16270         offset += 4;  /* Skip the marker */
16271
16272         /* find which conversation we are part of and get the tables for that
16273            conversation*/
16274         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
16275                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16276         if(!conversation){
16277                 /* OK this is a new conversation so lets create it */
16278                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
16279                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16280         }
16281         /* see if we already have the smb data for this conversation */
16282         si->ct=conversation_get_proto_data(conversation, proto_smb);
16283         if(!si->ct){
16284                 /* No, not yet. create it and attach it to the conversation */
16285                 si->ct = g_malloc(sizeof(conv_tables_t));
16286
16287                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16288                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16289                         smb_saved_info_equal_matched);
16290                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16291                         smb_saved_info_equal_unmatched);
16292                 si->ct->tid_service=g_hash_table_new(
16293                         smb_saved_info_hash_unmatched,
16294                         smb_saved_info_equal_unmatched);
16295                 si->ct->raw_ntlmssp = 0;
16296
16297                 si->ct->fid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB fid_tree");
16298                 si->ct->tid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB tid_tree");
16299                 si->ct->uid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB uid_tree");
16300                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16301         }
16302
16303         if( (si->request)
16304             &&  (si->mid==0)
16305             &&  (si->uid==0)
16306             &&  (si->pid==0)
16307             &&  (si->tid==0) ){
16308                 /* this is a broadcast SMB packet, there will not be a reply.
16309                    We dont need to do anything
16310                 */
16311                 si->unidir = TRUE;
16312         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16313                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16314                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16315                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16316                 /* Ok, we got a special request type. This request is either
16317                    an NT Cancel or a continuation relative to a real request
16318                    in an earlier packet.  In either case, we don't expect any
16319                    responses to this packet.  For continuations, any later
16320                    responses we see really just belong to the original request.
16321                    Anyway, we want to remember this packet somehow and
16322                    remember which original request it is associated with so
16323                    we can say nice things such as "This is a Cancellation to
16324                    the request in frame x", but we don't want the
16325                    request/response matching to get messed up.
16326
16327                    The only thing we do in this case is trying to find which original
16328                    request we match with and insert an entry for this "special"
16329                    request for later reference. We continue to reference the original
16330                    requests smb_saved_info_t but we dont touch it or change anything
16331                    in it.
16332                 */
16333
16334                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16335
16336                 if(!pinfo->fd->flags.visited){
16337                         /* try to find which original call we match and if we
16338                            find it add us to the matched table. Dont touch
16339                            anything else since we dont want this one to mess
16340                            up the request/response matching. We still consider
16341                            the initial call the real request and this is only
16342                            some sort of continuation.
16343                         */
16344                         /* we only check the unmatched table and assume that the
16345                            last seen MID matching ours is the right one.
16346                            This can fail but is better than nothing
16347                         */
16348                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16349                         if(sip!=NULL){
16350                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16351                                 new_key->frame = pinfo->fd->num;
16352                                 new_key->pid_mid = pid_mid;
16353                                 g_hash_table_insert(si->ct->matched, new_key,
16354                                     sip);
16355                         }
16356                 } else {
16357                         /* we have seen this packet before; check the
16358                            matching table
16359                         */
16360                         key.frame = pinfo->fd->num;
16361                         key.pid_mid = pid_mid;
16362                         sip=g_hash_table_lookup(si->ct->matched, &key);
16363                         if(sip==NULL){
16364                         /*
16365                           We didn't find it.
16366                           Too bad, unfortunately there is not really much we can
16367                           do now since this means that we never saw the initial
16368                           request.
16369                          */
16370                         }
16371                 }
16372
16373
16374                 if(sip && sip->frame_req){
16375                         switch(si->cmd){
16376                         case SMB_COM_NT_CANCEL:
16377                                 tmp_item=proto_tree_add_uint(htree, hf_smb_cancel_to,
16378                                                     tvb, 0, 0, sip->frame_req);
16379                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16380                                 break;
16381                         case SMB_COM_TRANSACTION_SECONDARY:
16382                         case SMB_COM_TRANSACTION2_SECONDARY:
16383                         case SMB_COM_NT_TRANSACT_SECONDARY:
16384                                 tmp_item=proto_tree_add_uint(htree, hf_smb_continuation_to,
16385                                                     tvb, 0, 0, sip->frame_req);
16386                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16387                                 break;
16388                         }
16389                 } else {
16390                         switch(si->cmd){
16391                         case SMB_COM_NT_CANCEL:
16392                                 proto_tree_add_text(htree, tvb, 0, 0,
16393                                                     "Cancellation to: <unknown frame>");
16394                                 break;
16395                         case SMB_COM_TRANSACTION_SECONDARY:
16396                         case SMB_COM_TRANSACTION2_SECONDARY:
16397                         case SMB_COM_NT_TRANSACT_SECONDARY:
16398                                 proto_tree_add_text(htree, tvb, 0, 0,
16399                                                     "Continuation to: <unknown frame>");
16400                                 break;
16401                         }
16402                 }
16403         } else { /* normal bidirectional request or response */
16404                 si->unidir = FALSE;
16405
16406                 if(!pinfo->fd->flags.visited){
16407                         /* first see if we find an unmatched smb "equal" to
16408                            the current one
16409                         */
16410                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16411                         if(sip!=NULL){
16412                                 gboolean cmd_match=FALSE;
16413
16414                                 /*
16415                                  * Make sure the SMB we found was the
16416                                  * same command, or a different command
16417                                  * that's another valid type of reply
16418                                  * to that command.
16419                                  */
16420                                 if(si->cmd==sip->cmd){
16421                                         cmd_match=TRUE;
16422                                 }
16423                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16424                                         cmd_match=TRUE;
16425                                 }
16426                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16427                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16428                                         cmd_match=TRUE;
16429                                 }
16430                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16431                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16432                                         cmd_match=TRUE;
16433                                 }
16434                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16435                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16436                                         cmd_match=TRUE;
16437                                 }
16438
16439                                 if( (si->request) || (!cmd_match) ) {
16440                                         /* We are processing an SMB request but there was already
16441                                            another "identical" smb request we had not matched yet.
16442                                            This must mean that either we have a retransmission or that the
16443                                            response to the previous one was lost and the client has reused
16444                                            the MID for this conversation. In either case it's not much more
16445                                            we can do than forget the old request and concentrate on the
16446                                            present one instead.
16447
16448                                            We also do this cleanup if we see that the cmd in the original
16449                                            request in sip->cmd is not compatible with the current cmd.
16450                                            This is to prevent matching errors such as if there were two
16451                                            SMBs of different cmds but with identical MID and PID values and
16452                                            if wireshark lost the first reply and the second request.
16453                                         */
16454                                         g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16455                                         sip=NULL; /* XXX should free it as well */
16456                                 } else {
16457                                         /* we have found a response to some
16458                                            request we have seen earlier.
16459                                            What we do now depends on whether
16460                                            this is the first response to that
16461                                            request we see (id frame_res==0) or
16462                                            if it's a response to a request
16463                                            for which we've seen an earlier
16464                                            response that's continued.
16465                                         */
16466                                         if(sip->frame_res==0 ||
16467                                            sip->flags & SMB_SIF_IS_CONTINUED){
16468                                                 /* OK, it is the first response
16469                                                    we have seen to this packet,
16470                                                    or it's a continuation of
16471                                                    a response we've seen. */
16472                                                 sip->frame_res = pinfo->fd->num;
16473                                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16474                                                 new_key->frame = sip->frame_res;
16475                                                 new_key->pid_mid = pid_mid;
16476                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16477                                                 /* We remove the entry for unmatched since we have found a match.
16478                                                  * We have to do this since the MID value wraps so quickly (effective only 10 bits)
16479                                                  * and if there is packetloss in the trace (maybe due to large holes
16480                                                  * created by a sniffer device not being able to keep up
16481                                                  * with the line rate.
16482                                                  * There is a real possibility that the following would occur which is painful :
16483                                                  * 1, -> Request  MID:5
16484                                                  * 2, <- Response MID:5
16485                                                  *   3, ->Request  MID:5 (missing from capture)
16486                                                  * 4, <- Response MID:5
16487                                                  * We DONT want #4 to be presented as a response to #1
16488                                                  */
16489                                                 g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16490                                         } else {
16491                                                 /* We have already seen another response to this MID.
16492                                                    Since the MID in reality is only something like 10 bits
16493                                                    this probably means that we just have a MID that is being
16494                                                    reused due to the small MID space and that this is a new
16495                                                    command we did not see the original request for.
16496                                                 */
16497                                                 sip=NULL;
16498                                         }
16499                                 }
16500                         }
16501                         if(si->request){
16502                                 sip = se_alloc(sizeof(smb_saved_info_t));
16503                                 sip->frame_req = pinfo->fd->num;
16504                                 sip->frame_res = 0;
16505                                 sip->req_time = pinfo->fd->abs_ts;
16506                                 sip->flags = 0;
16507                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))
16508                                     == (void *)TID_IPC) {
16509                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16510                                 }
16511                                 sip->cmd = si->cmd;
16512                                 sip->extra_info = NULL;
16513                                 sip->extra_info_type = SMB_EI_NONE;
16514                                 sip->fid=0;
16515                                 sip->fid_seen_in_request=0;
16516                                 g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
16517                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16518                                 new_key->frame = sip->frame_req;
16519                                 new_key->pid_mid = pid_mid;
16520                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16521                         }
16522                 } else {
16523                         /* we have seen this packet before; check the
16524                            matching table.
16525                            If we haven't yet seen the reply, we won't
16526                            find the info for it; we don't need it, as
16527                            we only use it to save information, and, as
16528                            we've seen this packet before, we've already
16529                            saved the information.
16530                         */
16531                         key.frame = pinfo->fd->num;
16532                         key.pid_mid = pid_mid;
16533                         sip=g_hash_table_lookup(si->ct->matched, &key);
16534                 }
16535         }
16536
16537         /*
16538          * Pass the "sip" on to subdissectors through "si".
16539          */
16540         si->sip = sip;
16541
16542         if (sip != NULL) {
16543                 /*
16544                  * Put in fields for the frame number of the frame to which
16545                  * this is a response or the frame with the response to this
16546                  * frame - if we know the frame number (i.e., it's not 0).
16547                  */
16548                 if(si->request){
16549                         if (sip->frame_res != 0) {
16550                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16551                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16552                         }
16553                 } else {
16554                         if (sip->frame_req != 0) {
16555                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16556                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16557                                 t = pinfo->fd->abs_ts;
16558                                 nstime_delta(&deltat, &t, &sip->req_time);
16559                                 tmp_item=proto_tree_add_time(htree, hf_smb_time, tvb,
16560                                     0, 0, &deltat);
16561                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16562                         }
16563                 }
16564         }
16565
16566         /* smb command */
16567         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);
16568         offset += 1;
16569
16570         if(flags2 & 0x4000){
16571                 /* handle NT 32 bit error code */
16572
16573                 si->nt_status = tvb_get_letohl(tvb, offset);
16574
16575                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16576                         TRUE);
16577                 offset += 4;
16578
16579         } else {
16580                 /* handle DOS error code & class */
16581                 errclass = tvb_get_guint8(tvb, offset);
16582                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16583                         errclass);
16584                 offset += 1;
16585
16586                 /* reserved byte */
16587                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16588                 offset += 1;
16589
16590                 /* error code */
16591                 /* XXX - the type of this field depends on the value of
16592                  * "errcls", so there is isn't a single value_string array
16593                  * fo it, so there can't be a single field for it.
16594                  */
16595                 errcode = tvb_get_letohs(tvb, offset);
16596                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16597                         offset, 2, errcode, "Error Code: %s",
16598                         decode_smb_error(errclass, errcode));
16599                 offset += 2;
16600         }
16601
16602         /* flags */
16603         offset = dissect_smb_flags(tvb, htree, offset);
16604
16605         /* flags2 */
16606         offset = dissect_smb_flags2(tvb, htree, offset);
16607
16608         /*
16609          * The document at
16610          *
16611          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16612          *
16613          * (a text version of "Microsoft Networks SMB FILE SHARING
16614          * PROTOCOL, Document Version 6.0p") says that:
16615          *
16616          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16617          *      the "High Part of PID";
16618          *
16619          *      the next four bytes are reserved;
16620          *
16621          *      the next four bytes are, for SMB-over-IPX (with no
16622          *      NetBIOS involved) two bytes of Session ID and two bytes
16623          *      of SequenceNumber.
16624          *
16625          * Network Monitor 2.x dissects the four bytes before the Session ID
16626          * as a "Key", and the two bytes after the SequenceNumber as
16627          * a "Group ID".
16628          *
16629          * The "High Part of PID" has been seen in calls other than NT
16630          * Create and X, although most of them appear to be I/O on DCE RPC
16631          * pipes opened with the NT Create and X in question.
16632          */
16633         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16634         offset += 2;
16635
16636         if (pinfo->ptype == PT_IPX &&
16637             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16638              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16639              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16640                 /*
16641                  * This is SMB-over-IPX.
16642                  * XXX - do we have to worry about "sequenced commands",
16643                  * as per the Samba document?  They say that for
16644                  * "unsequenced commands" (with a sequence number of 0),
16645                  * the Mid must be unique, but perhaps the Mid doesn't
16646                  * have to be unique for sequenced commands.  In at least
16647                  * one capture with SMB-over-IPX, however, the Mids
16648                  * are unique even for sequenced commands.
16649                  */
16650                 /* Key */
16651                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16652                     TRUE);
16653                 offset += 4;
16654
16655                 /* Session ID */
16656                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16657                     TRUE);
16658                 offset += 2;
16659
16660                 /* Sequence number */
16661                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16662                     TRUE);
16663                 offset += 2;
16664
16665                 /* Group ID */
16666                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16667                     TRUE);
16668                 offset += 2;
16669         } else {
16670                 /*
16671                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16672                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16673                  * bytes after the "High part of PID" are an 8-byte
16674                  * signature ...
16675                  */
16676                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16677                 offset += 8;
16678
16679                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16680                 offset += 2;
16681         }
16682
16683         pinfo->private_data = si;
16684
16685         /* TID
16686          * TreeConnectAndX(0x75) is special, here it is the mere fact of
16687          * having a response that means that the share was mapped and we
16688          * need to track it
16689          */
16690         if(!pinfo->fd->flags.visited && si->cmd==0x75 && !si->request){
16691                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE);
16692         } else {
16693                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE);
16694         }
16695
16696         /* PID */
16697         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16698         offset += 2;
16699
16700         /* UID */
16701         offset=dissect_smb_uid(tvb, htree, offset, si);
16702
16703         /* MID */
16704         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16705         offset += 2;
16706
16707         /* tap the packet before the dissectors are called so we still get
16708            the tap listener called even if there is an exception.
16709         */
16710         tap_queue_packet(smb_tap, pinfo, si);
16711         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16712
16713         /* Append error info from this packet to info string. */
16714         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16715                 if (flags2 & 0x4000) {
16716                         /*
16717                          * The status is an NT status code; was there
16718                          * an error?
16719                          */
16720                         if ((si->nt_status & 0xC0000000) == 0xC0000000) {
16721                                 /*
16722                                  * Yes.
16723                                  */
16724                                 col_append_fstr(
16725                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16726                                         val_to_str(si->nt_status, NT_errors,
16727                                             "Unknown (0x%08X)"));
16728                         }
16729                 } else {
16730                         /*
16731                          * The status is a DOS error class and code; was
16732                          * there an error?
16733                          */
16734                         if (errclass != SMB_SUCCESS) {
16735                                 /*
16736                                  * Yes.
16737                                  */
16738                                 col_append_fstr(
16739                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16740                                         decode_smb_error(errclass, errcode));
16741                         }
16742                 }
16743         }
16744 }
16745
16746 static gboolean
16747 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16748 {
16749         /* must check that this really is a smb packet */
16750         if (tvb_length(tvb) < 4)
16751                 return FALSE;
16752
16753         if( (tvb_get_guint8(tvb, 0) != 0xff)
16754             || (tvb_get_guint8(tvb, 1) != 'S')
16755             || (tvb_get_guint8(tvb, 2) != 'M')
16756             || (tvb_get_guint8(tvb, 3) != 'B') ){
16757                 return FALSE;
16758         }
16759
16760         dissect_smb(tvb, pinfo, parent_tree);
16761         return TRUE;
16762 }
16763
16764 void
16765 proto_register_smb(void)
16766 {
16767         static hf_register_info hf[] = {
16768         { &hf_smb_cmd,
16769                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16770                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16771
16772         { &hf_smb_trans2_subcmd,
16773                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16774                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16775
16776         { &hf_smb_nt_trans_subcmd,
16777                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16778                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16779
16780         { &hf_smb_word_count,
16781                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16782                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16783
16784         { &hf_smb_byte_count,
16785                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16786                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16787
16788         { &hf_smb_response_to,
16789                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16790                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16791
16792         { &hf_smb_time,
16793                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16794                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16795
16796         { &hf_smb_response_in,
16797                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16798                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16799
16800         { &hf_smb_continuation_to,
16801                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16802                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16803
16804         { &hf_smb_nt_status,
16805                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16806                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16807
16808         { &hf_smb_error_class,
16809                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16810                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16811
16812         { &hf_smb_error_code,
16813                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16814                 NULL, 0, "DOS Error Code", HFILL }},
16815
16816         { &hf_smb_reserved,
16817                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16818                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16819
16820         { &hf_smb_sig,
16821                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16822                 NULL, 0, "Signature bytes", HFILL }},
16823
16824         { &hf_smb_key,
16825                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16826                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16827
16828         { &hf_smb_session_id,
16829                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16830                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16831
16832         { &hf_smb_sequence_num,
16833                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16834                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16835
16836         { &hf_smb_group_id,
16837                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16838                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16839
16840         { &hf_smb_pid,
16841                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16842                 NULL, 0, "Process ID", HFILL }},
16843
16844         { &hf_smb_pid_high,
16845                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16846                 NULL, 0, "Process ID High Bytes", HFILL }},
16847
16848         { &hf_smb_tid,
16849                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16850                 NULL, 0, "Tree ID", HFILL }},
16851
16852         { &hf_smb_uid,
16853                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16854                 NULL, 0, "User ID", HFILL }},
16855
16856         { &hf_smb_mid,
16857                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16858                 NULL, 0, "Multiplex ID", HFILL }},
16859
16860         { &hf_smb_flags_lock,
16861                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16862                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16863
16864         { &hf_smb_flags_receive_buffer,
16865                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16866                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16867
16868         { &hf_smb_flags_caseless,
16869                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16870                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16871
16872         { &hf_smb_flags_canon,
16873                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16874                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16875
16876         { &hf_smb_flags_oplock,
16877                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16878                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16879
16880         { &hf_smb_flags_notify,
16881                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16882                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16883
16884         { &hf_smb_flags_response,
16885                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16886                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16887
16888         { &hf_smb_flags2_long_names_allowed,
16889                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16890                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16891
16892         { &hf_smb_flags2_ea,
16893                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16894                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16895
16896         { &hf_smb_flags2_sec_sig,
16897                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16898                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16899
16900         { &hf_smb_flags2_long_names_used,
16901                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16902                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16903
16904         { &hf_smb_flags2_esn,
16905                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16906                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16907
16908         { &hf_smb_flags2_dfs,
16909                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16910                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16911
16912         { &hf_smb_flags2_roe,
16913                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16914                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16915
16916         { &hf_smb_flags2_nt_error,
16917                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16918                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16919
16920         { &hf_smb_flags2_string,
16921                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16922                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16923
16924         { &hf_smb_buffer_format,
16925                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16926                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16927
16928         { &hf_smb_dialect_name,
16929                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16930                 NULL, 0, "Name of dialect", HFILL }},
16931
16932         { &hf_smb_dialect_index,
16933                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16934                 NULL, 0, "Index of selected dialect", HFILL }},
16935
16936         { &hf_smb_max_trans_buf_size,
16937                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16938                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16939
16940         { &hf_smb_max_mpx_count,
16941                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16942                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16943
16944         { &hf_smb_max_vcs_num,
16945                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16946                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16947
16948         { &hf_smb_session_key,
16949                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16950                 NULL, 0, "Unique token identifying this session", HFILL }},
16951
16952         { &hf_smb_server_timezone,
16953                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16954                 NULL, 0, "Current timezone at server.", HFILL }},
16955
16956         { &hf_smb_encryption_key_length,
16957                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16958                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16959
16960         { &hf_smb_encryption_key,
16961                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16962                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
16963
16964         { &hf_smb_primary_domain,
16965                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
16966                 NULL, 0, "The server's primary domain", HFILL }},
16967
16968         { &hf_smb_server,
16969                 { "Server", "smb.server", FT_STRING, BASE_NONE,
16970                 NULL, 0, "The name of the DC/server", HFILL }},
16971
16972         { &hf_smb_max_raw_buf_size,
16973                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
16974                 NULL, 0, "Maximum raw buffer size", HFILL }},
16975
16976         { &hf_smb_server_guid,
16977                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
16978                 NULL, 0, "Globally unique identifier for this server", HFILL }},
16979
16980         { &hf_smb_security_blob_len,
16981                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
16982                 NULL, 0, "Security blob length", HFILL }},
16983
16984         { &hf_smb_security_blob,
16985                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
16986                 NULL, 0, "Security blob", HFILL }},
16987
16988         { &hf_smb_sm_mode16,
16989                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
16990                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16991
16992         { &hf_smb_sm_password16,
16993                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
16994                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16995
16996         { &hf_smb_sm_mode,
16997                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
16998                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16999
17000         { &hf_smb_sm_password,
17001                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
17002                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17003
17004         { &hf_smb_sm_signatures,
17005                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
17006                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
17007
17008         { &hf_smb_sm_sig_required,
17009                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
17010                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
17011
17012         { &hf_smb_rm_read,
17013                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
17014                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
17015
17016         { &hf_smb_rm_write,
17017                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
17018                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
17019
17020         { &hf_smb_server_date_time,
17021                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
17022                 NULL, 0, "Current date and time at server", HFILL }},
17023
17024         { &hf_smb_server_smb_date,
17025                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
17026                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
17027
17028         { &hf_smb_server_smb_time,
17029                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
17030                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
17031
17032         { &hf_smb_server_cap_raw_mode,
17033                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
17034                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
17035
17036         { &hf_smb_server_cap_mpx_mode,
17037                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
17038                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
17039
17040         { &hf_smb_server_cap_unicode,
17041                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
17042                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
17043
17044         { &hf_smb_server_cap_large_files,
17045                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
17046                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
17047
17048         { &hf_smb_server_cap_nt_smbs,
17049                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
17050                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
17051
17052         { &hf_smb_server_cap_rpc_remote_apis,
17053                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
17054                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
17055
17056         { &hf_smb_server_cap_nt_status,
17057                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
17058                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
17059
17060         { &hf_smb_server_cap_level_ii_oplocks,
17061                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
17062                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
17063
17064         { &hf_smb_server_cap_lock_and_read,
17065                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
17066                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
17067
17068         { &hf_smb_server_cap_nt_find,
17069                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
17070                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
17071
17072         { &hf_smb_server_cap_dfs,
17073                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
17074                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
17075
17076         { &hf_smb_server_cap_infolevel_passthru,
17077                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
17078                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
17079
17080         { &hf_smb_server_cap_large_readx,
17081                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
17082                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
17083
17084         { &hf_smb_server_cap_large_writex,
17085                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
17086                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
17087
17088         { &hf_smb_server_cap_unix,
17089                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
17090                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
17091
17092         { &hf_smb_server_cap_reserved,
17093                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
17094                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
17095
17096         { &hf_smb_server_cap_bulk_transfer,
17097                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
17098                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
17099
17100         { &hf_smb_server_cap_compressed_data,
17101                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
17102                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
17103
17104         { &hf_smb_server_cap_extended_security,
17105                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
17106                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
17107
17108         { &hf_smb_system_time,
17109                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
17110                 NULL, 0, "System Time", HFILL }},
17111
17112         { &hf_smb_unknown,
17113                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
17114                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
17115
17116         { &hf_smb_dir_name,
17117                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17118                 NULL, 0, "SMB Directory Name", HFILL }},
17119
17120         { &hf_smb_echo_count,
17121                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17122                 NULL, 0, "Number of times to echo data back", HFILL }},
17123
17124         { &hf_smb_echo_data,
17125                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
17126                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17127
17128         { &hf_smb_echo_seq_num,
17129                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17130                 NULL, 0, "Sequence number for this echo response", HFILL }},
17131
17132         { &hf_smb_max_buf_size,
17133                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17134                 NULL, 0, "Max client buffer size", HFILL }},
17135
17136         { &hf_smb_path,
17137                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17138                 NULL, 0, "Path. Server name and share name", HFILL }},
17139
17140         { &hf_smb_service,
17141                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17142                 NULL, 0, "Service name", HFILL }},
17143
17144         { &hf_smb_password,
17145                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17146                 NULL, 0, "Password", HFILL }},
17147
17148         { &hf_smb_ansi_password,
17149                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17150                 NULL, 0, "ANSI Password", HFILL }},
17151
17152         { &hf_smb_unicode_password,
17153                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17154                 NULL, 0, "Unicode Password", HFILL }},
17155
17156         { &hf_smb_move_flags_file,
17157                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17158                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17159
17160         { &hf_smb_move_flags_dir,
17161                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17162                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17163
17164         { &hf_smb_move_flags_verify,
17165                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17166                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17167
17168         { &hf_smb_files_moved,
17169                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17170                 NULL, 0, "Number of files moved", HFILL }},
17171
17172         { &hf_smb_copy_flags_file,
17173                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17174                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17175
17176         { &hf_smb_copy_flags_dir,
17177                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17178                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17179
17180         { &hf_smb_copy_flags_dest_mode,
17181                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17182                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17183
17184         { &hf_smb_copy_flags_source_mode,
17185                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17186                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17187
17188         { &hf_smb_copy_flags_verify,
17189                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17190                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17191
17192         { &hf_smb_copy_flags_tree_copy,
17193                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17194                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17195
17196         { &hf_smb_copy_flags_ea_action,
17197                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17198                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17199
17200         { &hf_smb_count,
17201                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17202                 NULL, 0, "Count number of items/bytes", HFILL }},
17203
17204         { &hf_smb_count_low,
17205                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
17206                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
17207
17208         { &hf_smb_count_high,
17209                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
17210                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
17211
17212         { &hf_smb_file_name,
17213                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17214                 NULL, 0, "File Name", HFILL }},
17215
17216         { &hf_smb_open_function_create,
17217                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17218                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17219
17220         { &hf_smb_open_function_open,
17221                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17222                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17223
17224         { &hf_smb_fid,
17225                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17226                 NULL, 0, "FID: File ID", HFILL }},
17227
17228         { &hf_smb_file_attr_read_only_16bit,
17229                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17230                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17231
17232         { &hf_smb_file_attr_read_only_8bit,
17233                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17234                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17235
17236         { &hf_smb_file_attr_hidden_16bit,
17237                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17238                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17239
17240         { &hf_smb_file_attr_hidden_8bit,
17241                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17242                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17243
17244         { &hf_smb_file_attr_system_16bit,
17245                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17246                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17247
17248         { &hf_smb_file_attr_system_8bit,
17249                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17250                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17251
17252         { &hf_smb_file_attr_volume_16bit,
17253                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17254                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17255
17256         { &hf_smb_file_attr_volume_8bit,
17257                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17258                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17259
17260         { &hf_smb_file_attr_directory_16bit,
17261                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17262                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17263
17264         { &hf_smb_file_attr_directory_8bit,
17265                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17266                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17267
17268         { &hf_smb_file_attr_archive_16bit,
17269                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17270                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17271
17272         { &hf_smb_file_attr_archive_8bit,
17273                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17274                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17275
17276         { &hf_smb_file_attr_device,
17277                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17278                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17279
17280         { &hf_smb_file_attr_normal,
17281                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17282                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17283
17284         { &hf_smb_file_attr_temporary,
17285                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17286                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17287
17288         { &hf_smb_file_attr_sparse,
17289                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17290                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17291
17292         { &hf_smb_file_attr_reparse,
17293                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17294                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17295
17296         { &hf_smb_file_attr_compressed,
17297                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17298                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17299
17300         { &hf_smb_file_attr_offline,
17301                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17302                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17303
17304         { &hf_smb_file_attr_not_content_indexed,
17305                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17306                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17307
17308         { &hf_smb_file_attr_encrypted,
17309                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17310                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17311
17312         { &hf_smb_file_size,
17313                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17314                 NULL, 0, "File Size", HFILL }},
17315
17316         { &hf_smb_search_attribute_read_only,
17317                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17318                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17319
17320         { &hf_smb_search_attribute_hidden,
17321                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17322                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17323
17324         { &hf_smb_search_attribute_system,
17325                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17326                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17327
17328         { &hf_smb_search_attribute_volume,
17329                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17330                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17331
17332         { &hf_smb_search_attribute_directory,
17333                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17334                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17335
17336         { &hf_smb_search_attribute_archive,
17337                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17338                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17339
17340         { &hf_smb_access_mode,
17341                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17342                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17343
17344         { &hf_smb_access_sharing,
17345                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17346                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17347
17348         { &hf_smb_access_locality,
17349                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17350                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17351
17352         { &hf_smb_access_caching,
17353                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17354                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17355
17356         { &hf_smb_access_writetru,
17357                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17358                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17359
17360         { &hf_smb_create_time,
17361                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17362                 NULL, 0, "Creation Time", HFILL }},
17363
17364         { &hf_smb_modify_time,
17365                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17366                   NULL, 0, "Modification Time", HFILL }},
17367
17368         { &hf_smb_backup_time,
17369                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17370                   NULL, 0, "Backup time", HFILL}},
17371
17372         { &hf_smb_mac_alloc_block_count,
17373                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17374                   NULL, 0, "Allocation Block Count", HFILL}},
17375
17376         { &hf_smb_mac_alloc_block_size,
17377                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17378                   NULL, 0, "Allocation Block Size", HFILL}},
17379
17380         { &hf_smb_mac_free_block_count,
17381                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17382                   NULL, 0, "Free Block Count", HFILL}},
17383
17384         { &hf_smb_mac_root_file_count,
17385                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17386                 NULL, 0, "Root File Count", HFILL}},
17387
17388         { &hf_smb_mac_root_dir_count,
17389           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17390             NULL, 0, "Root Directory Count", HFILL}},
17391
17392         { &hf_smb_mac_file_count,
17393           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17394             NULL, 0, "File Count", HFILL}},
17395
17396         { &hf_smb_mac_dir_count,
17397           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17398             NULL, 0, "Directory Count", HFILL}},
17399
17400         { &hf_smb_mac_support_flags,
17401           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17402             NULL, 0, "Mac Support Flags", HFILL}},
17403
17404         { &hf_smb_mac_sup_access_ctrl,
17405           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17406             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17407
17408         { &hf_smb_mac_sup_getset_comments,
17409           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17410             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17411
17412         { &hf_smb_mac_sup_desktopdb_calls,
17413           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17414             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17415
17416         { &hf_smb_mac_sup_unique_ids,
17417           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17418             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17419
17420         { &hf_smb_mac_sup_streams,
17421           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17422             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17423
17424         { &hf_smb_create_dos_date,
17425                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17426                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17427
17428         { &hf_smb_create_dos_time,
17429                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17430                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17431
17432         { &hf_smb_last_write_time,
17433                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17434                 NULL, 0, "Time this file was last written to", HFILL }},
17435
17436         { &hf_smb_last_write_dos_date,
17437                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17438                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17439
17440         { &hf_smb_last_write_dos_time,
17441                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17442                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17443
17444         { &hf_smb_old_file_name,
17445                 { "Old File Name", "smb.old_file", FT_STRING, BASE_NONE,
17446                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17447
17448         { &hf_smb_offset,
17449                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17450                 NULL, 0, "Offset in file", HFILL }},
17451
17452         { &hf_smb_remaining,
17453                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17454                 NULL, 0, "Remaining number of bytes", HFILL }},
17455
17456         { &hf_smb_padding,
17457                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17458                 NULL, 0, "Padding or unknown data", HFILL }},
17459
17460         { &hf_smb_file_data,
17461                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17462                 NULL, 0, "Data read/written to the file", HFILL }},
17463
17464         { &hf_smb_mac_fndrinfo,
17465                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17466                   NULL, 0, "Finder Info", HFILL}},
17467
17468         { &hf_smb_total_data_len,
17469                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17470                 NULL, 0, "Total length of data", HFILL }},
17471
17472         { &hf_smb_data_len,
17473                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17474                 NULL, 0, "Length of data", HFILL }},
17475
17476         { &hf_smb_data_len_low,
17477                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17478                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17479
17480         { &hf_smb_data_len_high,
17481                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17482                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17483
17484         { &hf_smb_seek_mode,
17485                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17486                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17487
17488         { &hf_smb_access_time,
17489                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17490                 NULL, 0, "Last Access Time", HFILL }},
17491
17492         { &hf_smb_access_dos_date,
17493                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17494                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17495
17496         { &hf_smb_access_dos_time,
17497                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17498                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17499
17500         { &hf_smb_data_size,
17501                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17502                 NULL, 0, "Data Size", HFILL }},
17503
17504         { &hf_smb_alloc_size,
17505                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17506                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17507
17508         { &hf_smb_max_count,
17509                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17510                 NULL, 0, "Maximum Count", HFILL }},
17511
17512         { &hf_smb_max_count_low,
17513                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17514                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17515
17516         { &hf_smb_max_count_high,
17517                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17518                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17519
17520         { &hf_smb_min_count,
17521                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17522                 NULL, 0, "Minimum Count", HFILL }},
17523
17524         { &hf_smb_timeout,
17525                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17526                 NULL, 0, "Timeout in miliseconds", HFILL }},
17527
17528         { &hf_smb_high_offset,
17529                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17530                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17531
17532         { &hf_smb_units,
17533                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17534                 NULL, 0, "Total number of units at server", HFILL }},
17535
17536         { &hf_smb_bpu,
17537                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17538                 NULL, 0, "Blocks per unit at server", HFILL }},
17539
17540         { &hf_smb_blocksize,
17541                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17542                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17543
17544         { &hf_smb_freeunits,
17545                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17546                 NULL, 0, "Number of free units at server", HFILL }},
17547
17548         { &hf_smb_data_offset,
17549                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17550                 NULL, 0, "Data Offset", HFILL }},
17551
17552         { &hf_smb_dcm,
17553                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17554                 NULL, 0, "Data Compaction Mode", HFILL }},
17555
17556         { &hf_smb_request_mask,
17557                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17558                 NULL, 0, "Connectionless mode mask", HFILL }},
17559
17560         { &hf_smb_response_mask,
17561                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17562                 NULL, 0, "Connectionless mode mask", HFILL }},
17563
17564         { &hf_smb_search_id,
17565                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17566                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17567
17568         { &hf_smb_write_mode_write_through,
17569                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17570                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17571
17572         { &hf_smb_write_mode_return_remaining,
17573                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17574                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17575
17576         { &hf_smb_write_mode_raw,
17577                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17578                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17579
17580         { &hf_smb_write_mode_message_start,
17581                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17582                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17583
17584         { &hf_smb_write_mode_connectionless,
17585                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17586                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17587
17588         { &hf_smb_resume_key_len,
17589                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17590                 NULL, 0, "Resume Key length", HFILL }},
17591
17592         { &hf_smb_resume_find_id,
17593                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17594                 NULL, 0, "Handle for Find operation", HFILL }},
17595
17596         { &hf_smb_resume_server_cookie,
17597                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17598                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17599
17600         { &hf_smb_resume_client_cookie,
17601                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17602                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17603
17604         { &hf_smb_andxoffset,
17605                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17606                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17607
17608         { &hf_smb_lock_type_large,
17609                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17610                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17611
17612         { &hf_smb_lock_type_cancel,
17613                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17614                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17615
17616         { &hf_smb_lock_type_change,
17617                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17618                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17619
17620         { &hf_smb_lock_type_oplock,
17621                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17622                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17623
17624         { &hf_smb_lock_type_shared,
17625                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17626                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17627
17628         { &hf_smb_locking_ol,
17629                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17630                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17631
17632         { &hf_smb_number_of_locks,
17633                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17634                 NULL, 0, "Number of lock requests in this request", HFILL }},
17635
17636         { &hf_smb_number_of_unlocks,
17637                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17638                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17639
17640         { &hf_smb_lock_long_length,
17641                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
17642                 NULL, 0, "Length of lock/unlock region", HFILL }},
17643
17644         { &hf_smb_lock_long_offset,
17645                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
17646                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17647
17648         { &hf_smb_file_type,
17649                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17650                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17651
17652         { &hf_smb_ipc_state_nonblocking,
17653                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17654                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17655
17656         { &hf_smb_ipc_state_endpoint,
17657                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17658                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17659
17660         { &hf_smb_ipc_state_pipe_type,
17661                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17662                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17663
17664         { &hf_smb_ipc_state_read_mode,
17665                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17666                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17667
17668         { &hf_smb_ipc_state_icount,
17669                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17670                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17671
17672         { &hf_smb_server_fid,
17673                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17674                 NULL, 0, "Server unique File ID", HFILL }},
17675
17676         { &hf_smb_open_flags_add_info,
17677                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17678                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17679
17680         { &hf_smb_open_flags_ex_oplock,
17681                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17682                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17683
17684         { &hf_smb_open_flags_batch_oplock,
17685                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17686                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17687
17688         { &hf_smb_open_flags_ealen,
17689                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17690                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17691
17692         { &hf_smb_open_action_open,
17693                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17694                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17695
17696         { &hf_smb_open_action_lock,
17697                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17698                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17699
17700         { &hf_smb_vc_num,
17701                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17702                 NULL, 0, "VC Number", HFILL }},
17703
17704         { &hf_smb_password_len,
17705                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17706                 NULL, 0, "Length of password", HFILL }},
17707
17708         { &hf_smb_ansi_password_len,
17709                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17710                 NULL, 0, "Length of ANSI password", HFILL }},
17711
17712         { &hf_smb_unicode_password_len,
17713                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17714                 NULL, 0, "Length of Unicode password", HFILL }},
17715
17716         { &hf_smb_account,
17717                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17718                 NULL, 0, "Account, username", HFILL }},
17719
17720         { &hf_smb_os,
17721                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17722                 NULL, 0, "Which OS we are running", HFILL }},
17723
17724         { &hf_smb_lanman,
17725                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17726                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17727
17728         { &hf_smb_setup_action_guest,
17729                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17730                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17731
17732         { &hf_smb_fs,
17733                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17734                 NULL, 0, "Native File System", HFILL }},
17735
17736         { &hf_smb_connect_flags_dtid,
17737                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17738                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17739
17740         { &hf_smb_connect_support_search,
17741                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17742                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17743
17744         { &hf_smb_connect_support_in_dfs,
17745                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17746                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17747
17748         { &hf_smb_max_setup_count,
17749                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17750                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17751
17752         { &hf_smb_total_param_count,
17753                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17754                 NULL, 0, "Total number of parameter bytes", HFILL }},
17755
17756         { &hf_smb_total_data_count,
17757                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17758                 NULL, 0, "Total number of data bytes", HFILL }},
17759
17760         { &hf_smb_max_param_count,
17761                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17762                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17763
17764         { &hf_smb_max_data_count,
17765                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17766                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17767
17768         { &hf_smb_param_disp16,
17769                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17770                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17771
17772         { &hf_smb_param_count16,
17773                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17774                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17775
17776         { &hf_smb_param_offset16,
17777                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17778                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17779
17780         { &hf_smb_param_disp32,
17781                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17782                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17783
17784         { &hf_smb_param_count32,
17785                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17786                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17787
17788         { &hf_smb_param_offset32,
17789                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17790                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17791
17792         { &hf_smb_data_count16,
17793                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17794                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17795
17796         { &hf_smb_data_disp16,
17797                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17798                 NULL, 0, "Data Displacement", HFILL }},
17799
17800         { &hf_smb_data_offset16,
17801                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17802                 NULL, 0, "Data Offset", HFILL }},
17803
17804         { &hf_smb_data_count32,
17805                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17806                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17807
17808         { &hf_smb_data_disp32,
17809                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17810                 NULL, 0, "Data Displacement", HFILL }},
17811
17812         { &hf_smb_data_offset32,
17813                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17814                 NULL, 0, "Data Offset", HFILL }},
17815
17816         { &hf_smb_setup_count,
17817                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17818                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17819
17820         { &hf_smb_nt_ioctl_isfsctl,
17821                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17822                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17823
17824         { &hf_smb_nt_ioctl_flags_root_handle,
17825                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17826                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17827
17828         { &hf_smb_nt_notify_action,
17829                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17830                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17831
17832         { &hf_smb_nt_notify_watch_tree,
17833                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17834                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17835
17836         { &hf_smb_nt_notify_stream_write,
17837                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17838                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17839
17840         { &hf_smb_nt_notify_stream_size,
17841                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17842                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17843
17844         { &hf_smb_nt_notify_stream_name,
17845                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17846                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17847
17848         { &hf_smb_nt_notify_security,
17849                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17850                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17851
17852         { &hf_smb_nt_notify_ea,
17853                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17854                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17855
17856         { &hf_smb_nt_notify_creation,
17857                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17858                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17859
17860         { &hf_smb_nt_notify_last_access,
17861                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17862                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17863
17864         { &hf_smb_nt_notify_last_write,
17865                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17866                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17867
17868         { &hf_smb_nt_notify_size,
17869                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17870                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17871
17872         { &hf_smb_nt_notify_attributes,
17873                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17874                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17875
17876         { &hf_smb_nt_notify_dir_name,
17877                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17878                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17879
17880         { &hf_smb_nt_notify_file_name,
17881                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17882                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17883
17884         { &hf_smb_root_dir_fid,
17885                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17886                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17887
17888         { &hf_smb_alloc_size64,
17889                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17890                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17891
17892         { &hf_smb_nt_create_disposition,
17893                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17894                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17895
17896         { &hf_smb_sd_length,
17897                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17898                 NULL, 0, "Total length of security descriptor", HFILL }},
17899
17900         { &hf_smb_ea_list_length,
17901                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17902                 NULL, 0, "Total length of extended attributes", HFILL }},
17903
17904         { &hf_smb_ea_flags,
17905                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17906                 NULL, 0, "EA Flags", HFILL }},
17907
17908         { &hf_smb_ea_name_length,
17909                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17910                 NULL, 0, "EA Name Length", HFILL }},
17911
17912         { &hf_smb_ea_data_length,
17913                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17914                 NULL, 0, "EA Data Length", HFILL }},
17915
17916         { &hf_smb_ea_name,
17917                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17918                 NULL, 0, "EA Name", HFILL }},
17919
17920         { &hf_smb_ea_data,
17921                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17922                 NULL, 0, "EA Data", HFILL }},
17923
17924         { &hf_smb_file_name_len,
17925                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17926                 NULL, 0, "Length of File Name", HFILL }},
17927
17928         { &hf_smb_nt_impersonation_level,
17929                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17930                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17931
17932         { &hf_smb_nt_security_flags_context_tracking,
17933                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17934                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17935
17936         { &hf_smb_nt_security_flags_effective_only,
17937                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17938                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17939
17940         { &hf_smb_nt_access_mask_generic_read,
17941                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17942                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17943
17944         { &hf_smb_nt_access_mask_generic_write,
17945                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17946                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17947
17948         { &hf_smb_nt_access_mask_generic_execute,
17949                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17950                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17951
17952         { &hf_smb_nt_access_mask_generic_all,
17953                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17954                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17955
17956         { &hf_smb_nt_access_mask_maximum_allowed,
17957                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17958                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
17959
17960         { &hf_smb_nt_access_mask_system_security,
17961                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
17962                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
17963
17964         { &hf_smb_nt_access_mask_synchronize,
17965                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
17966                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
17967
17968         { &hf_smb_nt_access_mask_write_owner,
17969                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
17970                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
17971
17972         { &hf_smb_nt_access_mask_write_dac,
17973                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
17974                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
17975
17976         { &hf_smb_nt_access_mask_read_control,
17977                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
17978                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
17979
17980         { &hf_smb_nt_access_mask_delete,
17981                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
17982                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
17983
17984         { &hf_smb_nt_access_mask_write_attributes,
17985                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
17986                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
17987
17988         { &hf_smb_nt_access_mask_read_attributes,
17989                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
17990                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
17991
17992         { &hf_smb_nt_access_mask_delete_child,
17993                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
17994                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
17995
17996         /*
17997          * "Execute" for files, "traverse" for directories.
17998          */
17999         { &hf_smb_nt_access_mask_execute,
18000                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
18001                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
18002
18003         { &hf_smb_nt_access_mask_write_ea,
18004                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
18005                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
18006
18007         { &hf_smb_nt_access_mask_read_ea,
18008                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
18009                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
18010
18011         /*
18012          * "Append data" for files, "add subdirectory" for directories,
18013          * "create pipe instance" for named pipes.
18014          */
18015         { &hf_smb_nt_access_mask_append,
18016                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
18017                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
18018
18019         /*
18020          * "Write data" for files and pipes, "add file" for directory.
18021          */
18022         { &hf_smb_nt_access_mask_write,
18023                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
18024                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
18025
18026         /*
18027          * "Read data" for files and pipes, "list directory" for directory.
18028          */
18029         { &hf_smb_nt_access_mask_read,
18030                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
18031                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
18032
18033         { &hf_smb_nt_create_bits_oplock,
18034                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
18035                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
18036
18037         { &hf_smb_nt_create_bits_boplock,
18038                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
18039                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
18040
18041         { &hf_smb_nt_create_bits_dir,
18042                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
18043                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
18044
18045         { &hf_smb_nt_create_bits_ext_resp,
18046           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32,
18047             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
18048
18049         { &hf_smb_nt_create_options_directory_file,
18050                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
18051                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
18052
18053         { &hf_smb_nt_create_options_write_through,
18054                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
18055                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
18056
18057         { &hf_smb_nt_create_options_sequential_only,
18058                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
18059                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
18060
18061         { &hf_smb_nt_create_options_no_intermediate_buffering,
18062                 { "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
18063                 TFS(&tfs_nt_create_options_no_intermediate_buffering), 0x00000008, "Is intermediate buffering allowed?", HFILL }},
18064
18065         { &hf_smb_nt_create_options_sync_io_alert,
18066                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
18067                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
18068
18069         { &hf_smb_nt_create_options_sync_io_nonalert,
18070                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
18071                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
18072
18073         { &hf_smb_nt_create_options_non_directory_file,
18074                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
18075                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
18076
18077         { &hf_smb_nt_create_options_create_tree_connection,
18078                 { "Create Tree Connection", "smb.nt.create_options.create_tree_connection", FT_BOOLEAN, 32,
18079                 TFS(&tfs_nt_create_options_create_tree_connection), 0x00000080, "Create Tree Connection flag", HFILL }},
18080
18081         { &hf_smb_nt_create_options_complete_if_oplocked,
18082                 { "Complete If Oplocked", "smb.nt.create_options.complete_if_oplocked", FT_BOOLEAN, 32,
18083                 TFS(&tfs_nt_create_options_complete_if_oplocked), 0x00000100, "Complete if oplocked flag", HFILL }},
18084
18085         { &hf_smb_nt_create_options_no_ea_knowledge,
18086                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
18087                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
18088
18089         { &hf_smb_nt_create_options_eight_dot_three_only,
18090                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
18091                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
18092
18093         { &hf_smb_nt_create_options_random_access,
18094                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
18095                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
18096
18097         { &hf_smb_nt_create_options_delete_on_close,
18098                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
18099                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
18100         { &hf_smb_nt_create_options_open_by_fileid,
18101                 { "Open By FileID", "smb.nt.create_options.open_by_fileid", FT_BOOLEAN, 32,
18102                 TFS(&tfs_nt_create_options_open_by_fileid), 0x00002000, "Open file by inode", HFILL }},
18103
18104         { &hf_smb_nt_create_options_backup_intent,
18105                 { "Backup Intent", "smb.nt.create_options.backup_intent", FT_BOOLEAN, 32,
18106                 TFS(&tfs_nt_create_options_backup_intent), 0x00004000, "Is this opened by BACKUP ADMIN for backup intent?", HFILL }},
18107
18108         { &hf_smb_nt_create_options_no_compression,
18109                 { "No Compression", "smb.nt.create_options.no_compression", FT_BOOLEAN, 32,
18110                 TFS(&tfs_nt_create_options_no_compression), 0x00008000, "Is compression allowed?", HFILL }},
18111
18112         { &hf_smb_nt_create_options_reserve_opfilter,
18113                 { "Reserve Opfilter", "smb.nt.create_options.reserve_opfilter", FT_BOOLEAN, 32,
18114                 TFS(&tfs_nt_create_options_reserve_opfilter), 0x00100000, "Reserve Opfilter flag", HFILL }},
18115
18116         { &hf_smb_nt_create_options_open_reparse_point,
18117                 { "Open Reparse Point", "smb.nt.create_options.open_reparse_point", FT_BOOLEAN, 32,
18118                 TFS(&tfs_nt_create_options_open_reparse_point), 0x00200000, "Is this an open of a reparse point or of the normal file?", HFILL }},
18119
18120         { &hf_smb_nt_create_options_open_no_recall,
18121                 { "Open No Recall", "smb.nt.create_options.open_no_recall", FT_BOOLEAN, 32,
18122                 TFS(&tfs_nt_create_options_open_no_recall), 0x00400000, "Open no recall flag", HFILL }},
18123
18124         { &hf_smb_nt_create_options_open_for_free_space_query,
18125                 { "Open For Free Space query", "smb.nt.create_options.open_for_free_space_query", FT_BOOLEAN, 32,
18126                 TFS(&tfs_nt_create_options_open_for_free_space_query), 0x00800000, "Open For Free Space Query flag", HFILL }},
18127
18128         { &hf_smb_nt_share_access_read,
18129                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
18130                 TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
18131
18132         { &hf_smb_nt_share_access_write,
18133                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
18134                 TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
18135
18136         { &hf_smb_nt_share_access_delete,
18137                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
18138                 TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, "", HFILL }},
18139
18140         { &hf_smb_file_eattr_read_only,
18141                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
18142                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18143
18144         { &hf_smb_file_eattr_hidden,
18145                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
18146                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18147
18148         { &hf_smb_file_eattr_system,
18149                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
18150                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18151
18152         { &hf_smb_file_eattr_volume,
18153                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18154                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18155
18156         { &hf_smb_file_eattr_directory,
18157                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18158                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18159
18160         { &hf_smb_file_eattr_archive,
18161                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18162                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18163
18164         { &hf_smb_file_eattr_device,
18165                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18166                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18167
18168         { &hf_smb_file_eattr_normal,
18169                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18170                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18171
18172         { &hf_smb_file_eattr_temporary,
18173                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18174                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18175
18176         { &hf_smb_file_eattr_sparse,
18177                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18178                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18179
18180         { &hf_smb_file_eattr_reparse,
18181                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18182                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18183
18184         { &hf_smb_file_eattr_compressed,
18185                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18186                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18187
18188         { &hf_smb_file_eattr_offline,
18189                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18190                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18191
18192         { &hf_smb_file_eattr_not_content_indexed,
18193                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18194                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18195
18196         { &hf_smb_file_eattr_encrypted,
18197                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18198                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18199
18200         { &hf_smb_sec_desc_len,
18201                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18202                 NULL, 0, "Security Descriptor Length", HFILL }},
18203
18204         { &hf_smb_nt_qsd_owner,
18205                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18206                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18207
18208         { &hf_smb_nt_qsd_group,
18209                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18210                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18211
18212         { &hf_smb_nt_qsd_dacl,
18213                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18214                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18215
18216         { &hf_smb_nt_qsd_sacl,
18217                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18218                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18219
18220         { &hf_smb_extended_attributes,
18221                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
18222                 NULL, 0, "Extended Attributes", HFILL }},
18223
18224         { &hf_smb_oplock_level,
18225                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18226                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18227
18228         { &hf_smb_create_action,
18229                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18230                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18231
18232         { &hf_smb_file_id,
18233                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18234                 NULL, 0, "Server unique file ID", HFILL }},
18235
18236         { &hf_smb_ea_error_offset,
18237                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18238                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18239
18240         { &hf_smb_end_of_file,
18241                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18242                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18243
18244         { &hf_smb_replace,
18245                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
18246                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
18247
18248         { &hf_smb_root_dir_handle,
18249                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
18250                 NULL, 0, "Root directory handle", HFILL }},
18251
18252         { &hf_smb_target_name_len,
18253                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
18254                 NULL, 0, "Length of target file name", HFILL }},
18255
18256         { &hf_smb_target_name,
18257                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
18258                 NULL, 0, "Target file name", HFILL }},
18259
18260         { &hf_smb_device_type,
18261                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18262                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18263
18264         { &hf_smb_is_directory,
18265                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18266                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18267
18268         { &hf_smb_next_entry_offset,
18269                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18270                 NULL, 0, "Offset to next entry", HFILL }},
18271
18272         { &hf_smb_change_time,
18273                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18274                 NULL, 0, "Last Change Time", HFILL }},
18275
18276         { &hf_smb_setup_len,
18277                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18278                 NULL, 0, "Length of printer setup data", HFILL }},
18279
18280         { &hf_smb_print_mode,
18281                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18282                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18283
18284         { &hf_smb_print_identifier,
18285                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18286                 NULL, 0, "Identifier string for this print job", HFILL }},
18287
18288         { &hf_smb_restart_index,
18289                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18290                 NULL, 0, "Index of entry after last returned", HFILL }},
18291
18292         { &hf_smb_print_queue_date,
18293                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18294                 NULL, 0, "Date when this entry was queued", HFILL }},
18295
18296         { &hf_smb_print_queue_dos_date,
18297                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18298                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18299
18300         { &hf_smb_print_queue_dos_time,
18301                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18302                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18303
18304         { &hf_smb_print_status,
18305                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18306                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18307
18308         { &hf_smb_print_spool_file_number,
18309                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18310                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18311
18312         { &hf_smb_print_spool_file_size,
18313                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18314                 NULL, 0, "Number of bytes in spool file", HFILL }},
18315
18316         { &hf_smb_print_spool_file_name,
18317                 { "Name", "smb.print.spool.name", FT_STRINGZ, BASE_NONE,
18318                 NULL, 0, "Name of client that submitted this job", HFILL }},
18319
18320         { &hf_smb_start_index,
18321                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18322                 NULL, 0, "First queue entry to return", HFILL }},
18323
18324         { &hf_smb_originator_name,
18325                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18326                 NULL, 0, "Name of sender of message", HFILL }},
18327
18328         { &hf_smb_destination_name,
18329                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18330                 NULL, 0, "Name of recipient of message", HFILL }},
18331
18332         { &hf_smb_message_len,
18333                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18334                 NULL, 0, "Length of message", HFILL }},
18335
18336         { &hf_smb_message,
18337                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18338                 NULL, 0, "Message text", HFILL }},
18339
18340         { &hf_smb_mgid,
18341                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18342                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18343
18344         { &hf_smb_forwarded_name,
18345                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18346                 NULL, 0, "Recipient name being forwarded", HFILL }},
18347
18348         { &hf_smb_machine_name,
18349                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18350                 NULL, 0, "Name of target machine", HFILL }},
18351
18352         { &hf_smb_cancel_to,
18353                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18354                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18355
18356         { &hf_smb_trans_name,
18357                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18358                 NULL, 0, "Name of transaction", HFILL }},
18359
18360         { &hf_smb_transaction_flags_dtid,
18361                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18362                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18363
18364         { &hf_smb_transaction_flags_owt,
18365                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18366                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18367
18368         { &hf_smb_search_count,
18369                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18370                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18371
18372         { &hf_smb_search_pattern,
18373                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18374                 NULL, 0, "Search Pattern", HFILL }},
18375
18376         { &hf_smb_ff2_backup,
18377                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18378                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18379
18380         { &hf_smb_ff2_continue,
18381                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18382                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18383
18384         { &hf_smb_ff2_resume,
18385                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18386                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18387
18388         { &hf_smb_ff2_close_eos,
18389                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18390                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18391
18392         { &hf_smb_ff2_close,
18393                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18394                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18395
18396         { &hf_smb_ff2_information_level,
18397                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18398                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18399
18400         { &hf_smb_qpi_loi,
18401                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18402                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18403
18404         { &hf_smb_spi_loi,
18405                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18406                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18407
18408 #if 0
18409         { &hf_smb_sfi_writetru,
18410                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18411                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18412
18413         { &hf_smb_sfi_caching,
18414                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18415                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18416 #endif
18417
18418         { &hf_smb_storage_type,
18419                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18420                 NULL, 0, "Type of storage", HFILL }},
18421
18422         { &hf_smb_resume,
18423                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18424                 NULL, 0, "Resume Key", HFILL }},
18425
18426         { &hf_smb_max_referral_level,
18427                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18428                 NULL, 0, "Latest referral version number understood", HFILL }},
18429
18430         { &hf_smb_qfsi_information_level,
18431                 { "Level of Interest", "smb.qfsi_loi", FT_UINT16, BASE_HEX,
18432                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18433
18434         { &hf_smb_nt_rename_level,
18435                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18436                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18437
18438         { &hf_smb_cluster_count,
18439                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18440                 NULL, 0, "Number of clusters", HFILL }},
18441
18442         { &hf_smb_number_of_links,
18443                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18444                 NULL, 0, "Number of hard links to the file", HFILL }},
18445
18446         { &hf_smb_delete_pending,
18447                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18448                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18449
18450         { &hf_smb_index_number,
18451                 { "Index Number", "smb.index_number", FT_UINT64, BASE_HEX,
18452                 NULL, 0, "File system unique identifier", HFILL }},
18453
18454         { &hf_smb_position,
18455                 { "Position", "smb.position", FT_UINT64, BASE_DEC,
18456                 NULL, 0, "File position", HFILL }},
18457
18458         { &hf_smb_current_offset,
18459                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18460                 NULL, 0, "Current offset in the file", HFILL }},
18461
18462         { &hf_smb_t2_alignment,
18463                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18464                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18465
18466         { &hf_smb_t2_stream_name_length,
18467                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18468                 NULL, 0, "Length of stream name", HFILL }},
18469
18470         { &hf_smb_t2_stream_size,
18471                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18472                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18473
18474         { &hf_smb_t2_stream_name,
18475                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18476                 NULL, 0, "Name of the stream", HFILL }},
18477
18478         { &hf_smb_t2_compressed_file_size,
18479                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18480                 NULL, 0, "Size of the compressed file", HFILL }},
18481
18482         { &hf_smb_t2_compressed_format,
18483                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18484                 NULL, 0, "Compression algorithm used", HFILL }},
18485
18486         { &hf_smb_t2_compressed_unit_shift,
18487                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18488                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18489
18490         { &hf_smb_t2_compressed_chunk_shift,
18491                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18492                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18493
18494         { &hf_smb_t2_compressed_cluster_shift,
18495                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18496                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18497
18498         { &hf_smb_t2_marked_for_deletion,
18499                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18500                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18501
18502         { &hf_smb_dfs_path_consumed,
18503                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18504                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18505
18506         { &hf_smb_dfs_num_referrals,
18507                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18508                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18509
18510         { &hf_smb_get_dfs_server_hold_storage,
18511                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18512                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18513
18514         { &hf_smb_get_dfs_fielding,
18515                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18516                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18517
18518         { &hf_smb_dfs_referral_version,
18519                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18520                 NULL, 0, "Version of referral element", HFILL }},
18521
18522         { &hf_smb_dfs_referral_size,
18523                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18524                 NULL, 0, "Size of referral element", HFILL }},
18525
18526         { &hf_smb_dfs_referral_server_type,
18527                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18528                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18529
18530         { &hf_smb_dfs_referral_flags_strip,
18531                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18532                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18533
18534         { &hf_smb_dfs_referral_node_offset,
18535                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18536                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18537
18538         { &hf_smb_dfs_referral_node,
18539                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18540                 NULL, 0, "Name of entity to visit next", HFILL }},
18541
18542         { &hf_smb_dfs_referral_proximity,
18543                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18544                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18545
18546         { &hf_smb_dfs_referral_ttl,
18547                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18548                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18549
18550         { &hf_smb_dfs_referral_path_offset,
18551                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18552                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18553
18554         { &hf_smb_dfs_referral_path,
18555                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18556                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18557
18558         { &hf_smb_dfs_referral_alt_path_offset,
18559                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18560                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18561
18562         { &hf_smb_dfs_referral_alt_path,
18563                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18564                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18565
18566         { &hf_smb_end_of_search,
18567                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18568                 NULL, 0, "Was last entry returned?", HFILL }},
18569
18570         { &hf_smb_last_name_offset,
18571                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18572                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18573
18574         { &hf_smb_fn_information_level,
18575                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18576                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18577
18578         { &hf_smb_monitor_handle,
18579                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18580                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18581
18582         { &hf_smb_change_count,
18583                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18584                 NULL, 0, "Number of changes to wait for", HFILL }},
18585
18586         { &hf_smb_file_index,
18587                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18588                 NULL, 0, "File index", HFILL }},
18589
18590         { &hf_smb_short_file_name,
18591                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18592                 NULL, 0, "Short (8.3) File Name", HFILL }},
18593
18594         { &hf_smb_short_file_name_len,
18595                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18596                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18597
18598         { &hf_smb_fs_id,
18599                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18600                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18601
18602         { &hf_smb_sector_unit,
18603                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18604                 NULL, 0, "Sectors per allocation unit", HFILL }},
18605
18606         { &hf_smb_fs_units,
18607                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18608                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18609
18610         { &hf_smb_fs_sector,
18611                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18612                 NULL, 0, "Bytes per sector", HFILL }},
18613
18614         { &hf_smb_avail_units,
18615                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18616                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18617
18618         { &hf_smb_volume_serial_num,
18619                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18620                 NULL, 0, "Volume serial number", HFILL }},
18621
18622         { &hf_smb_volume_label_len,
18623                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18624                 NULL, 0, "Length of volume label", HFILL }},
18625
18626         { &hf_smb_volume_label,
18627                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18628                 NULL, 0, "Volume label", HFILL }},
18629
18630         { &hf_smb_free_alloc_units64,
18631                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18632                 NULL, 0, "Number of free allocation units", HFILL }},
18633
18634         { &hf_smb_caller_free_alloc_units64,
18635                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18636                 NULL, 0, "Number of caller free allocation units", HFILL }},
18637
18638         { &hf_smb_actual_free_alloc_units64,
18639                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18640                 NULL, 0, "Number of actual free allocation units", HFILL }},
18641
18642         { &hf_smb_soft_quota_limit,
18643                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18644                 NULL, 0, "Soft Quota treshold", HFILL }},
18645
18646         { &hf_smb_hard_quota_limit,
18647                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18648                 NULL, 0, "Hard Quota limit", HFILL }},
18649
18650         { &hf_smb_user_quota_used,
18651                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18652                 NULL, 0, "How much Quota is used by this user", HFILL }},
18653
18654         { &hf_smb_max_name_len,
18655                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18656                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18657
18658         { &hf_smb_fs_name_len,
18659                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18660                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18661
18662         { &hf_smb_fs_name,
18663                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18664                 NULL, 0, "Name of filesystem", HFILL }},
18665
18666         { &hf_smb_device_char_removable,
18667                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18668                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18669
18670         { &hf_smb_device_char_read_only,
18671                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18672                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18673
18674         { &hf_smb_device_char_floppy,
18675                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18676                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18677
18678         { &hf_smb_device_char_write_once,
18679                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18680                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18681
18682         { &hf_smb_device_char_remote,
18683                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18684                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18685
18686         { &hf_smb_device_char_mounted,
18687                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18688                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18689
18690         { &hf_smb_device_char_virtual,
18691                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18692                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18693
18694         { &hf_smb_fs_attr_css,
18695                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18696                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18697
18698         { &hf_smb_fs_attr_cpn,
18699                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18700                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18701
18702         { &hf_smb_fs_attr_uod,
18703                 { "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
18704                 TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
18705
18706         { &hf_smb_fs_attr_pacls,
18707                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18708                 TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
18709
18710         { &hf_smb_fs_attr_fc,
18711                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18712                 TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
18713
18714         { &hf_smb_fs_attr_vq,
18715                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18716                 TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
18717
18718         { &hf_smb_fs_attr_ssf,
18719                 { "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
18720                 TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
18721
18722         { &hf_smb_fs_attr_srp,
18723                 { "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
18724                 TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
18725
18726         { &hf_smb_fs_attr_srs,
18727                 { "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
18728                 TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
18729
18730         { &hf_smb_fs_attr_sla,
18731                 { "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
18732                 TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
18733
18734         { &hf_smb_fs_attr_vic,
18735                 { "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
18736                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
18737
18738         { &hf_smb_fs_attr_soids,
18739                 { "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
18740                 TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
18741
18742         { &hf_smb_fs_attr_se,
18743                 { "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
18744                 TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
18745
18746         { &hf_smb_fs_attr_ns,
18747                 { "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
18748                 TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
18749
18750         { &hf_smb_fs_attr_rov,
18751                 { "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
18752                 TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
18753
18754         { &hf_smb_user_quota_offset,
18755                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18756                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18757
18758         { &hf_smb_pipe_write_len,
18759                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18760                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18761
18762         { &hf_smb_quota_flags_deny_disk,
18763                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18764                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18765
18766         { &hf_smb_quota_flags_log_limit,
18767                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18768                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18769
18770         { &hf_smb_quota_flags_log_warning,
18771                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18772                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18773
18774         { &hf_smb_quota_flags_enabled,
18775                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18776                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18777
18778         { &hf_smb_segment_overlap,
18779                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18780                         "Fragment overlaps with other fragments", HFILL }},
18781
18782         { &hf_smb_segment_overlap_conflict,
18783                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18784                         "Overlapping fragments contained conflicting data", HFILL }},
18785
18786         { &hf_smb_segment_multiple_tails,
18787                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18788                         "Several tails were found when defragmenting the packet", HFILL }},
18789
18790         { &hf_smb_segment_too_long_fragment,
18791                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18792                         "Fragment contained data past end of packet", HFILL }},
18793
18794         { &hf_smb_segment_error,
18795                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18796                         "Defragmentation error due to illegal fragments", HFILL }},
18797
18798         { &hf_smb_opened_in,
18799                 { "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18800                         "The frame this fid was opened", HFILL }},
18801
18802         { &hf_smb_closed_in,
18803                 { "Closed in", "smb.fid.closed_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18804                         "The frame this fid was closed", HFILL }},
18805
18806         { &hf_smb_mapped_in,
18807                 { "Mapped in", "smb.fid.mapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18808                         "The frame this share was mapped", HFILL }},
18809
18810         { &hf_smb_unmapped_in,
18811                 { "Unmapped in", "smb.fid.unmapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18812                         "The frame this share was unmapped", HFILL }},
18813
18814         { &hf_smb_segment,
18815                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18816                         "SMB Segment", HFILL }},
18817
18818         { &hf_smb_segments,
18819                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18820                         "SMB Segments", HFILL }},
18821
18822         { &hf_smb_unix_major_version,
18823           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
18824             NULL, 0, "UNIX Major Version", HFILL }},
18825
18826         { &hf_smb_unix_minor_version,
18827           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
18828             NULL, 0, "UNIX Minor Version", HFILL }},
18829
18830         { &hf_smb_unix_capability_fcntl,
18831           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
18832                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18833
18834         { &hf_smb_unix_capability_posix_acl,
18835           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
18836                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18837
18838         { &hf_smb_file_access_mask_read_data,
18839           { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
18840                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18841
18842         { &hf_smb_file_access_mask_write_data,
18843           { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
18844                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18845
18846         { &hf_smb_file_access_mask_append_data,
18847           { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
18848                 TFS(&flags_set_truth), 0x00000004, "", HFILL }},
18849
18850         { &hf_smb_file_access_mask_read_ea,
18851           { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
18852                 TFS(&flags_set_truth), 0x00000008, "", HFILL }},
18853
18854         { &hf_smb_file_access_mask_write_ea,
18855           { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
18856                 TFS(&flags_set_truth), 0x00000010, "", HFILL }},
18857
18858         { &hf_smb_file_access_mask_execute,
18859           { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
18860                 TFS(&flags_set_truth), 0x00000020, "", HFILL }},
18861
18862         { &hf_smb_file_access_mask_read_attribute,
18863           { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
18864                 TFS(&flags_set_truth), 0x00000080, "", HFILL }},
18865
18866         { &hf_smb_file_access_mask_write_attribute,
18867           { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
18868                 TFS(&flags_set_truth), 0x00000100, "", HFILL }},
18869
18870         { &hf_smb_dir_access_mask_list,
18871           { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
18872                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18873
18874         { &hf_smb_dir_access_mask_add_file,
18875           { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
18876                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18877
18878         { &hf_smb_dir_access_mask_add_subdir,
18879           { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
18880                 TFS(&flags_set_truth), 0x00000004, "", HFILL }},
18881
18882         { &hf_smb_dir_access_mask_read_ea,
18883           { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
18884                 TFS(&flags_set_truth), 0x00000008, "", HFILL }},
18885
18886         { &hf_smb_dir_access_mask_write_ea,
18887           { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
18888                 TFS(&flags_set_truth), 0x00000010, "", HFILL }},
18889
18890         { &hf_smb_dir_access_mask_traverse,
18891           { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
18892                 TFS(&flags_set_truth), 0x00000020, "", HFILL }},
18893
18894         { &hf_smb_dir_access_mask_delete_child,
18895           { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
18896                 TFS(&flags_set_truth), 0x00000040, "", HFILL }},
18897
18898         { &hf_smb_dir_access_mask_read_attribute,
18899           { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
18900                 TFS(&flags_set_truth), 0x00000080, "", HFILL }},
18901
18902         { &hf_smb_dir_access_mask_write_attribute,
18903           { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
18904                 TFS(&flags_set_truth), 0x00000100, "", HFILL }},
18905
18906         { &hf_smb_unix_file_size,
18907           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
18908             NULL, 0, "", HFILL }},
18909
18910         { &hf_smb_unix_file_num_bytes,
18911           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
18912             NULL, 0, "Number of bytes used to store the file", HFILL }},
18913
18914         { &hf_smb_unix_file_last_status,
18915           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
18916             NULL, 0, "", HFILL }},
18917
18918         { &hf_smb_unix_file_last_access,
18919           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
18920             NULL, 0, "", HFILL }},
18921
18922         { &hf_smb_unix_file_last_change,
18923           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
18924             NULL, 0, "", HFILL }},
18925
18926         { &hf_smb_unix_file_uid,
18927           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
18928             NULL, 0, "", HFILL }},
18929
18930         { &hf_smb_unix_file_gid,
18931           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
18932             NULL, 0, "", HFILL }},
18933
18934         { &hf_smb_unix_file_type,
18935           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
18936             VALS(unix_file_type_vals), 0, "", HFILL }},
18937
18938         { &hf_smb_unix_file_dev_major,
18939           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
18940             NULL, 0, "", HFILL }},
18941
18942         { &hf_smb_unix_file_dev_minor,
18943           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
18944             NULL, 0, "", HFILL }},
18945
18946         { &hf_smb_unix_file_unique_id,
18947           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
18948             NULL, 0, "", HFILL }},
18949
18950         { &hf_smb_unix_file_permissions,
18951           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
18952             NULL, 0, "", HFILL }},
18953
18954         { &hf_smb_unix_file_nlinks,
18955           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
18956             NULL, 0, "", HFILL }},
18957
18958         { &hf_smb_unix_file_link_dest,
18959           { "Link destination", "smb.unix.file.link_dest", FT_STRING,
18960             BASE_NONE, NULL, 0, "", HFILL }},
18961
18962         { &hf_smb_unix_find_file_nextoffset,
18963           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
18964             NULL, 0, "", HFILL }},
18965
18966         { &hf_smb_unix_find_file_resumekey,
18967           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
18968             NULL, 0, "", HFILL }},
18969
18970         { &hf_smb_network_unknown,
18971           { "Unknown field", "smb.unknown", FT_UINT32, BASE_HEX,
18972             NULL, 0, "", HFILL }},
18973
18974         { &hf_smb_create_flags,
18975           { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
18976             NULL, 0, "", HFILL }},
18977
18978         { &hf_smb_create_options,
18979           { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
18980             NULL, 0, "", HFILL }},
18981
18982         { &hf_smb_share_access,
18983           { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
18984             NULL, 0, "", HFILL }},
18985
18986         { &hf_smb_access_mask,
18987           { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
18988             NULL, 0, "", HFILL }},
18989
18990         { &hf_smb_mode,
18991           { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
18992             NULL, 0, "", HFILL }},
18993
18994         { &hf_smb_attribute,
18995           { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
18996             NULL, 0, "", HFILL }},
18997
18998         { &hf_smb_reparse_tag,
18999           { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
19000             NULL, 0, "", HFILL }},
19001
19002         { &hf_smb_disposition_delete_on_close,
19003           { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
19004                 TFS(&tfs_disposition_delete_on_close), 0x01, "", HFILL }},
19005
19006         { &hf_smb_pipe_info_flag,
19007           { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
19008                 TFS(&tfs_pipe_info_flag), 0x01, "", HFILL }},
19009
19010         { &hf_smb_logged_in,
19011           { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_DEC,
19012                 NULL, 0, "", HFILL }},
19013
19014         { &hf_smb_logged_out,
19015           { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_DEC,
19016                 NULL, 0, "", HFILL }},
19017
19018         { &hf_smb_file_rw_offset,
19019           { "File Offset", "smb.file.rw.offset", FT_UINT32, BASE_DEC,
19020                 NULL, 0, "", HFILL }},
19021
19022         { &hf_smb_file_rw_length,
19023           { "File RW Length", "smb.file.rw.length", FT_UINT32, BASE_DEC,
19024                 NULL, 0, "", HFILL }},
19025
19026         { &hf_smb_posix_acl_version,
19027           { "Posix ACL version", "smb.posix_acl.version", FT_UINT16, BASE_DEC,
19028                 NULL, 0, "", HFILL }},
19029
19030         { &hf_smb_posix_num_file_aces,
19031           { "Number of file ACEs", "smb.posix_acl.num_file_aces", FT_UINT16, BASE_DEC,
19032                 NULL, 0, "", HFILL }},
19033
19034         { &hf_smb_posix_num_def_aces,
19035           { "Number of default ACEs", "smb.posix_acl.num_def_aces", FT_UINT16, BASE_DEC,
19036                 NULL, 0, "", HFILL }},
19037
19038         { &hf_smb_posix_ace_type,
19039           { "ACE Type", "smb.posix_acl.ace_type", FT_UINT8, BASE_DEC,
19040                 VALS(&ace_type_vals), 0, "", HFILL }},
19041
19042         { &hf_smb_posix_ace_flags,
19043           { "Permissions", "smb.posix_acl.ace_perms", FT_UINT8, BASE_HEX,
19044                 NULL, 0, "", HFILL }},
19045
19046         { &hf_smb_posix_ace_perm_read,
19047           {"READ", "smb.posix_acl.ace_perms.read", FT_BOOLEAN, 8,
19048                 NULL, 0x04, "", HFILL}},
19049
19050         { &hf_smb_posix_ace_perm_write,
19051           {"WRITE", "smb.posix_acl.ace_perms.write", FT_BOOLEAN, 8,
19052                 NULL, 0x02, "", HFILL}},
19053
19054         { &hf_smb_posix_ace_perm_execute,
19055           {"EXECUTE", "smb.posix_acl.ace_perms.execute", FT_BOOLEAN, 8,
19056                 NULL, 0x01, "", HFILL}},
19057
19058         { &hf_smb_posix_ace_perm_owner_uid,
19059           { "Owner UID", "smb.posix_acl.ace_perms.owner_uid", FT_UINT32, BASE_DEC,
19060                 NULL, 0, "", HFILL }},
19061
19062         { &hf_smb_posix_ace_perm_owner_gid,
19063           { "Owner GID", "smb.posix_acl.ace_perms.owner_gid", FT_UINT32, BASE_DEC,
19064                 NULL, 0, "", HFILL }},
19065
19066         { &hf_smb_posix_ace_perm_uid,
19067           { "UID", "smb.posix_acl.ace_perms.uid", FT_UINT32, BASE_DEC,
19068                 NULL, 0, "", HFILL }},
19069
19070         { &hf_smb_posix_ace_perm_gid,
19071           { "GID", "smb.posix_acl.ace_perms.gid", FT_UINT32, BASE_DEC,
19072                 NULL, 0, "", HFILL }},
19073
19074         };
19075
19076         static gint *ett[] = {
19077                 &ett_smb,
19078                 &ett_smb_fid,
19079                 &ett_smb_tid,
19080                 &ett_smb_uid,
19081                 &ett_smb_hdr,
19082                 &ett_smb_command,
19083                 &ett_smb_fileattributes,
19084                 &ett_smb_capabilities,
19085                 &ett_smb_aflags,
19086                 &ett_smb_dialect,
19087                 &ett_smb_dialects,
19088                 &ett_smb_mode,
19089                 &ett_smb_rawmode,
19090                 &ett_smb_flags,
19091                 &ett_smb_flags2,
19092                 &ett_smb_desiredaccess,
19093                 &ett_smb_search,
19094                 &ett_smb_file,
19095                 &ett_smb_openfunction,
19096                 &ett_smb_filetype,
19097                 &ett_smb_openaction,
19098                 &ett_smb_writemode,
19099                 &ett_smb_lock_type,
19100                 &ett_smb_ssetupandxaction,
19101                 &ett_smb_optionsup,
19102                 &ett_smb_time_date,
19103                 &ett_smb_move_copy_flags,
19104                 &ett_smb_file_attributes,
19105                 &ett_smb_search_resume_key,
19106                 &ett_smb_search_dir_info,
19107                 &ett_smb_unlocks,
19108                 &ett_smb_unlock,
19109                 &ett_smb_locks,
19110                 &ett_smb_lock,
19111                 &ett_smb_open_flags,
19112                 &ett_smb_ipc_state,
19113                 &ett_smb_open_action,
19114                 &ett_smb_setup_action,
19115                 &ett_smb_connect_flags,
19116                 &ett_smb_connect_support_bits,
19117                 &ett_smb_nt_access_mask,
19118                 &ett_smb_nt_create_bits,
19119                 &ett_smb_nt_create_options,
19120                 &ett_smb_nt_share_access,
19121                 &ett_smb_nt_security_flags,
19122                 &ett_smb_nt_trans_setup,
19123                 &ett_smb_nt_trans_data,
19124                 &ett_smb_nt_trans_param,
19125                 &ett_smb_nt_notify_completion_filter,
19126                 &ett_smb_nt_ioctl_flags,
19127                 &ett_smb_security_information_mask,
19128                 &ett_smb_print_queue_entry,
19129                 &ett_smb_transaction_flags,
19130                 &ett_smb_transaction_params,
19131                 &ett_smb_find_first2_flags,
19132 #if 0
19133                 &ett_smb_ioflag,
19134 #endif
19135                 &ett_smb_transaction_data,
19136                 &ett_smb_stream_info,
19137                 &ett_smb_dfs_referrals,
19138                 &ett_smb_dfs_referral,
19139                 &ett_smb_dfs_referral_flags,
19140                 &ett_smb_get_dfs_flags,
19141                 &ett_smb_ff2_data,
19142                 &ett_smb_device_characteristics,
19143                 &ett_smb_fs_attributes,
19144                 &ett_smb_segments,
19145                 &ett_smb_segment,
19146                 &ett_smb_quotaflags,
19147                 &ett_smb_secblob,
19148                 &ett_smb_mac_support_flags,
19149                 &ett_smb_unicode_password,
19150                 &ett_smb_ea,
19151                 &ett_smb_unix_capabilities,
19152                 &ett_smb_posic_ace,
19153                 &ett_smb_posix_ace_perms
19154         };
19155         module_t *smb_module;
19156
19157         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19158             "SMB", "smb");
19159         proto_register_subtree_array(ett, array_length(ett));
19160         proto_register_field_array(proto_smb, hf, array_length(hf));
19161
19162         proto_do_register_windows_common(proto_smb);
19163
19164         register_init_routine(&smb_init_protocol);
19165         smb_module = prefs_register_protocol(proto_smb, NULL);
19166         prefs_register_bool_preference(smb_module, "trans_reassembly",
19167                 "Reassemble SMB Transaction payload",
19168                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19169                 &smb_trans_reassembly);
19170         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19171                 "Reassemble DCERPC over SMB",
19172                 "Whether the dissector should reassemble DCERPC over SMB commands",
19173                 &smb_dcerpc_reassembly);
19174         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19175                 "Snoop SID to Name mappings",
19176                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19177                 &sid_name_snooping);
19178
19179         register_init_routine(smb_trans_reassembly_init);
19180         smb_tap = register_tap("smb");
19181 }
19182
19183 void
19184 proto_reg_handoff_smb(void)
19185 {
19186         dissector_handle_t smb_handle;
19187
19188         gssapi_handle = find_dissector("gssapi");
19189         ntlmssp_handle = find_dissector("ntlmssp");
19190
19191         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19192         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19193         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19194         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
19195         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19196         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19197         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
19198             smb_handle);
19199         dissector_add("spp.socket", IDP_SOCKET_SMB, smb_handle);
19200 }