Enable Lua tcp tap userdata.
[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;
757 static dissector_handle_t ntlmssp_handle;
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                         g_free(dst_table);
1221                         table_size = 0;
1222                 } else {
1223                         dst_table = tdt;
1224                         table_size++;
1225
1226                         dst_table[i].zone = zone;
1227                         dst_table[i].start = dst_table[i].end = t;
1228
1229                         /* no entry will cover more than 6 months */
1230                         low = t - MAX_DST_WIDTH/2;
1231                         /* XXX - what if t < MAX_DST_WIDTH/2? */
1232
1233                         high = t + MAX_DST_WIDTH/2;
1234                         /* XXX - what if this overflows? */
1235
1236                         /*
1237                          * Widen the new entry using two bisection searches.
1238                          */
1239                         while (low+60*60 < dst_table[i].start) {
1240                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1241                                         t = dst_table[i].start - MAX_DST_SKIP;
1242                                 else
1243                                         t = low + (dst_table[i].start-low)/2;
1244                                 if (TimeZone(t) == zone)
1245                                         dst_table[i].start = t;
1246                                 else
1247                                         low = t;
1248                         }
1249
1250                         while (high-60*60 > dst_table[i].end) {
1251                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1252                                         t = dst_table[i].end + MAX_DST_SKIP;
1253                                 else
1254                                         t = high - (high-dst_table[i].end)/2;
1255                                 if (TimeZone(t) == zone)
1256                                         dst_table[i].end = t;
1257                                 else
1258                                         high = t;
1259                         }
1260                 }
1261         }
1262         return zone;
1263 }
1264
1265 /*
1266  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1267  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1268  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1269  * daylight savings transitions because some local times are ambiguous.
1270  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1271  */
1272 static int
1273 LocTimeDiff(time_t lt)
1274 {
1275         int d = TimeZoneFaster(lt);
1276         time_t t = lt + d;
1277
1278         /* if overflow occurred, ignore all the adjustments so far */
1279         if (((t < lt) ^ (d < 0)))
1280                 t = lt;
1281
1282         /*
1283          * Now t should be close enough to the true UTC to yield the
1284          * right answer.
1285          */
1286         return TimeZoneFaster(t);
1287 }
1288
1289 static int
1290 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1291 {
1292         guint32 timeval;
1293         nstime_t ts;
1294
1295         timeval = tvb_get_letohl(tvb, offset);
1296         if (timeval == 0xffffffff) {
1297                 proto_tree_add_text(tree, tvb, offset, 4,
1298                     "%s: No time specified (0xffffffff)",
1299                     proto_registrar_get_name(hf_date));
1300                 offset += 4;
1301                 return offset;
1302         }
1303
1304         /*
1305          * We add the local time offset.
1306          */
1307         ts.secs = timeval + LocTimeDiff(timeval);
1308         ts.nsecs = 0;
1309
1310         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1311         offset += 4;
1312
1313         return offset;
1314 }
1315
1316 static int
1317 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1318     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1319 {
1320         guint16 dos_time, dos_date;
1321         proto_item *item = NULL;
1322         proto_tree *tree = NULL;
1323         struct tm tm;
1324         time_t t;
1325         static const int mday_noleap[12] = {
1326                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1327         };
1328         static const int mday_leap[12] = {
1329                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1330         };
1331 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1332         nstime_t tv;
1333
1334         if (time_first) {
1335                 dos_time = tvb_get_letohs(tvb, offset);
1336                 dos_date = tvb_get_letohs(tvb, offset+2);
1337         } else {
1338                 dos_date = tvb_get_letohs(tvb, offset);
1339                 dos_time = tvb_get_letohs(tvb, offset+2);
1340         }
1341
1342         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1343             (dos_date == 0 && dos_time == 0)) {
1344                 /*
1345                  * No date/time specified.
1346                  */
1347                 if(parent_tree){
1348                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1349                             "%s: No time specified (0x%08x)",
1350                             proto_registrar_get_name(hf_date),
1351                             (dos_date << 16) | dos_time);
1352                 }
1353                 offset += 4;
1354                 return offset;
1355         }
1356
1357         tm.tm_sec = (dos_time&0x1f)*2;
1358         tm.tm_min = (dos_time>>5)&0x3f;
1359         tm.tm_hour = (dos_time>>11)&0x1f;
1360         tm.tm_mday = dos_date&0x1f;
1361         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1362         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1363         tm.tm_isdst = -1;
1364
1365         /*
1366          * Do some sanity checks before calling "mktime()";
1367          * "mktime()" doesn't do them, it "normalizes" out-of-range
1368          * values.
1369          */
1370         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1371            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1372            (ISLEAP(tm.tm_year + 1900) ?
1373              tm.tm_mday > mday_leap[tm.tm_mon] :
1374              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1375              (t = mktime(&tm)) == -1) {
1376                 /*
1377                  * Invalid date/time.
1378                  */
1379                 if (parent_tree) {
1380                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1381                             "%s: Invalid time",
1382                             proto_registrar_get_name(hf_date));
1383                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1384                         if (time_first) {
1385                                 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);
1386                                 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);
1387                         } else {
1388                                 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);
1389                                 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);
1390                         }
1391                 }
1392                 offset += 4;
1393                 return offset;
1394         }
1395
1396         tv.secs = t;
1397         tv.nsecs = 0;
1398
1399         if(parent_tree){
1400                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1401                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1402                 if (time_first) {
1403                         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);
1404                         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);
1405                 } else {
1406                         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);
1407                         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);
1408                 }
1409         }
1410
1411         offset += 4;
1412
1413         return offset;
1414 }
1415
1416 static const true_false_string tfs_disposition_delete_on_close = {
1417         "DELETE this file when closed",
1418         "Normal access, do not delete on close"
1419 };
1420
1421 static const true_false_string tfs_pipe_info_flag = {
1422         "SET NAMED PIPE mode",
1423         "Clear NAMED PIPE mode"
1424 };
1425
1426
1427 static const value_string da_access_vals[] = {
1428         { 0,            "Open for reading"},
1429         { 1,            "Open for writing"},
1430         { 2,            "Open for reading and writing"},
1431         { 3,            "Open for execute"},
1432         {0, NULL}
1433 };
1434 static const value_string da_sharing_vals[] = {
1435         { 0,            "Compatibility mode"},
1436         { 1,            "Deny read/write/execute (exclusive)"},
1437         { 2,            "Deny write"},
1438         { 3,            "Deny read/execute"},
1439         { 4,            "Deny none"},
1440         {0, NULL}
1441 };
1442 static const value_string da_locality_vals[] = {
1443         { 0,            "Locality of reference unknown"},
1444         { 1,            "Mainly sequential access"},
1445         { 2,            "Mainly random access"},
1446         { 3,            "Random access with some locality"},
1447         {0, NULL}
1448 };
1449 static const true_false_string tfs_da_caching = {
1450         "Do not cache this file",
1451         "Caching permitted on this file"
1452 };
1453 static const true_false_string tfs_da_writetru = {
1454         "Write through enabled",
1455         "Write through disabled"
1456 };
1457 static int
1458 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *type)
1459 {
1460         guint16 mask;
1461         proto_item *item;
1462         proto_tree *tree;
1463
1464         mask = tvb_get_letohs(tvb, offset);
1465
1466         if(parent_tree){
1467                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1468                         "%s Access: 0x%04x", type, mask);
1469                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1470
1471                 proto_tree_add_boolean(tree, hf_smb_access_writetru,
1472                         tvb, offset, 2, mask);
1473                 proto_tree_add_boolean(tree, hf_smb_access_caching,
1474                         tvb, offset, 2, mask);
1475                 proto_tree_add_uint(tree, hf_smb_access_locality,
1476                         tvb, offset, 2, mask);
1477                 proto_tree_add_uint(tree, hf_smb_access_sharing,
1478                         tvb, offset, 2, mask);
1479                 proto_tree_add_uint(tree, hf_smb_access_mode,
1480                         tvb, offset, 2, mask);
1481         }
1482
1483         offset += 2;
1484
1485         return offset;
1486 }
1487
1488 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1489 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1490 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1491 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1492 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1493 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1494 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1495 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1496 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1497 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1498 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1499 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1500 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1501 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1502 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1503
1504 static const true_false_string tfs_file_attribute_read_only = {
1505         "This file is READ ONLY",
1506         "This file is NOT read only",
1507 };
1508 static const true_false_string tfs_file_attribute_hidden = {
1509         "This is a HIDDEN file",
1510         "This is NOT a hidden file"
1511 };
1512 static const true_false_string tfs_file_attribute_system = {
1513         "This is a SYSTEM file",
1514         "This is NOT a system file"
1515 };
1516 static const true_false_string tfs_file_attribute_volume = {
1517         "This is a VOLUME ID",
1518         "This is NOT a volume ID"
1519 };
1520 static const true_false_string tfs_file_attribute_directory = {
1521         "This is a DIRECTORY",
1522         "This is NOT a directory"
1523 };
1524 static const true_false_string tfs_file_attribute_archive = {
1525         "This file has been modified since last ARCHIVE",
1526         "This file has NOT been modified since last archive"
1527 };
1528 static const true_false_string tfs_file_attribute_device = {
1529         "This is a DEVICE",
1530         "This is NOT a device"
1531 };
1532 static const true_false_string tfs_file_attribute_normal = {
1533         "This file is an ordinary file",
1534         "This file has some attribute set"
1535 };
1536 static const true_false_string tfs_file_attribute_temporary = {
1537         "This is a TEMPORARY file",
1538         "This is NOT a temporary file"
1539 };
1540 static const true_false_string tfs_file_attribute_sparse = {
1541         "This is a SPARSE file",
1542         "This is NOT a sparse file"
1543 };
1544 static const true_false_string tfs_file_attribute_reparse = {
1545         "This file has an associated REPARSE POINT",
1546         "This file does NOT have an associated reparse point"
1547 };
1548 static const true_false_string tfs_file_attribute_compressed = {
1549         "This is a COMPRESSED file",
1550         "This is NOT a compressed file"
1551 };
1552 static const true_false_string tfs_file_attribute_offline = {
1553         "This file is OFFLINE",
1554         "This file is NOT offline"
1555 };
1556 static const true_false_string tfs_file_attribute_not_content_indexed = {
1557         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1558         "This file MAY be indexed by the content indexing service"
1559 };
1560 static const true_false_string tfs_file_attribute_encrypted = {
1561         "This is an ENCRYPTED file",
1562         "This is NOT an encrypted file"
1563 };
1564
1565 /*
1566  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are
1567  * listed as USHORT, and seem to be in packets in the wild, while in other
1568  * places they are listed as ULONG, and also seem to be.
1569  *
1570  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1571  * bytes to consume.
1572  */
1573
1574 int
1575 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1576                         int bytes)
1577 {
1578         guint16 mask;
1579         proto_item *item;
1580         proto_tree *tree;
1581
1582         if (bytes != 2 && bytes != 4) {
1583                 THROW(ReportedBoundsError);
1584         }
1585
1586         /*
1587          * The actual bits of interest appear to only be a USHORT
1588          */
1589         /* FIXME if this ever changes! */
1590         mask = tvb_get_letohs(tvb, offset);
1591
1592         if(parent_tree){
1593                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1594                         "File Attributes: 0x%08x", mask);
1595                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1596
1597                 proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1598                                        tvb, offset, bytes, mask);
1599                 proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1600                                        tvb, offset, bytes, mask);
1601                 proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1602                                        tvb, offset, bytes, mask);
1603                 proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1604                                        tvb, offset, bytes, mask);
1605                 proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1606                                        tvb, offset, bytes, mask);
1607                 proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1608                                        tvb, offset, bytes, mask);
1609                 proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1610                                        tvb, offset, bytes, mask);
1611                 proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1612                                        tvb, offset, bytes, mask);
1613                 proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1614                                        tvb, offset, bytes, mask);
1615                 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1616                                 tvb, offset, bytes, mask);
1617                 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1618                                 tvb, offset, bytes, mask);
1619                 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1620                                 tvb, offset, bytes, mask);
1621                 proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1622                                 tvb, offset, bytes, mask);
1623                 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1624                                 tvb, offset, bytes, mask);
1625                 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1626                                 tvb, offset, bytes, mask);
1627         }
1628
1629         offset += bytes;
1630
1631         return offset;
1632 }
1633
1634 /* 3.11 */
1635 static int
1636 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1637     int len, guint32 mask)
1638 {
1639         proto_item *item;
1640         proto_tree *tree;
1641
1642         if(parent_tree){
1643                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
1644                         "File Attributes: 0x%08x", mask);
1645                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1646
1647                 /*
1648                  * XXX - Network Monitor disagrees on some of the
1649                  * bits, e.g. the bits above temporary are "atomic write"
1650                  * and "transaction write", and it says nothing about the
1651                  * bits above that.
1652                  *
1653                  * Does the Win32 API documentation, or the NT Native API book,
1654                  * suggest anything?
1655                  */
1656                 proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1657                         tvb, offset, len, mask);
1658                 proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1659                         tvb, offset, len, mask);
1660                 proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1661                         tvb, offset, len, mask);
1662                 proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1663                         tvb, offset, len, mask);
1664                 proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1665                         tvb, offset, len, mask);
1666                 proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1667                         tvb, offset, len, mask);
1668                 proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1669                         tvb, offset, len, mask);
1670                 proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1671                         tvb, offset, len, mask);
1672                 proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1673                         tvb, offset, len, mask);
1674                 proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1675                         tvb, offset, len, mask);
1676                 proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1677                         tvb, offset, len, mask);
1678                 proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1679                         tvb, offset, len, mask);
1680                 proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1681                         tvb, offset, len, mask);
1682                 proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1683                         tvb, offset, len, mask);
1684                 proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1685                         tvb, offset, len, mask);
1686         }
1687
1688         offset += len;
1689
1690         return offset;
1691 }
1692
1693 /* 3.11 */
1694 static int
1695 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1696 {
1697         guint32 mask;
1698
1699         mask = tvb_get_letohl(tvb, offset);
1700
1701         offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, 4, mask);
1702
1703         return offset;
1704 }
1705
1706 static int
1707 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1708 {
1709         guint8 mask;
1710         proto_item *item;
1711         proto_tree *tree;
1712
1713         mask = tvb_get_guint8(tvb, offset);
1714
1715         if(parent_tree){
1716                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1717                         "File Attributes: 0x%02x", mask);
1718                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1719
1720                 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1721                         tvb, offset, 1, mask);
1722                 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1723                         tvb, offset, 1, mask);
1724                 proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1725                         tvb, offset, 1, mask);
1726                 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1727                         tvb, offset, 1, mask);
1728                 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1729                         tvb, offset, 1, mask);
1730                 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1731                         tvb, offset, 1, mask);
1732         }
1733
1734         offset += 1;
1735
1736         return offset;
1737 }
1738
1739 static const true_false_string tfs_search_attribute_read_only = {
1740         "Include READ ONLY files in search results",
1741         "Do NOT include read only files in search results",
1742 };
1743 static const true_false_string tfs_search_attribute_hidden = {
1744         "Include HIDDEN files in search results",
1745         "Do NOT include hidden files in search results"
1746 };
1747 static const true_false_string tfs_search_attribute_system = {
1748         "Include SYSTEM files in search results",
1749         "Do NOT include system files in search results"
1750 };
1751 static const true_false_string tfs_search_attribute_volume = {
1752         "Include VOLUME IDs in search results",
1753         "Do NOT include volume IDs in search results"
1754 };
1755 static const true_false_string tfs_search_attribute_directory = {
1756         "Include DIRECTORIES in search results",
1757         "Do NOT include directories in search results"
1758 };
1759 static const true_false_string tfs_search_attribute_archive = {
1760         "Include ARCHIVE files in search results",
1761         "Do NOT include archive files in search results"
1762 };
1763
1764 static int
1765 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1766 {
1767         guint16 mask;
1768         proto_item *item;
1769         proto_tree *tree;
1770
1771         mask = tvb_get_letohs(tvb, offset);
1772
1773         if(parent_tree){
1774                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1775                         "Search Attributes: 0x%04x", mask);
1776                 tree = proto_item_add_subtree(item, ett_smb_search);
1777
1778                 proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1779                         tvb, offset, 2, mask);
1780                 proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1781                         tvb, offset, 2, mask);
1782                 proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1783                         tvb, offset, 2, mask);
1784                 proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1785                         tvb, offset, 2, mask);
1786                 proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1787                         tvb, offset, 2, mask);
1788                 proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1789                         tvb, offset, 2, mask);
1790         }
1791
1792         offset += 2;
1793         return offset;
1794 }
1795
1796 #if 0
1797 /*
1798  * XXX - this isn't used.
1799  * Is this used for anything?  NT Create AndX doesn't use it.
1800  * Is there some 16-bit attribute field with more bits than Read Only,
1801  * Hidden, System, Volume ID, Directory, and Archive?
1802  */
1803 static int
1804 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1805 {
1806         guint32 mask;
1807         proto_item *item;
1808         proto_tree *tree;
1809
1810         mask = tvb_get_letohl(tvb, offset);
1811
1812         if(parent_tree){
1813                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1814                         "File Attributes: 0x%08x", mask);
1815                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1816         }
1817         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1818                 tvb, offset, 2, mask);
1819         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1820                 tvb, offset, 2, mask);
1821         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1822                 tvb, offset, 2, mask);
1823         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1824                 tvb, offset, 2, mask);
1825         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1826                 tvb, offset, 2, mask);
1827         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1828                 tvb, offset, 2, mask);
1829         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1830                 tvb, offset, 2, mask);
1831         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1832                 tvb, offset, 2, mask);
1833         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1834                 tvb, offset, 2, mask);
1835         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1836                 tvb, offset, 2, mask);
1837         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1838                 tvb, offset, 2, mask);
1839         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1840                 tvb, offset, 2, mask);
1841         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1842                 tvb, offset, 2, mask);
1843         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1844                 tvb, offset, 2, mask);
1845         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1846                 tvb, offset, 2, mask);
1847
1848         offset += 2;
1849
1850         return offset;
1851 }
1852 #endif
1853
1854
1855 #define SERVER_CAP_RAW_MODE            0x00000001
1856 #define SERVER_CAP_MPX_MODE            0x00000002
1857 #define SERVER_CAP_UNICODE             0x00000004
1858 #define SERVER_CAP_LARGE_FILES         0x00000008
1859 #define SERVER_CAP_NT_SMBS             0x00000010
1860 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1861 #define SERVER_CAP_STATUS32            0x00000040
1862 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1863 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1864 #define SERVER_CAP_NT_FIND             0x00000200
1865 #define SERVER_CAP_DFS                 0x00001000
1866 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1867 #define SERVER_CAP_LARGE_READX         0x00004000
1868 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1869 #define SERVER_CAP_UNIX                0x00800000
1870 #define SERVER_CAP_RESERVED            0x02000000
1871 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1872 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1873 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1874 static const true_false_string tfs_server_cap_raw_mode = {
1875         "Read Raw and Write Raw are supported",
1876         "Read Raw and Write Raw are not supported"
1877 };
1878 static const true_false_string tfs_server_cap_mpx_mode = {
1879         "Read Mpx and Write Mpx are supported",
1880         "Read Mpx and Write Mpx are not supported"
1881 };
1882 static const true_false_string tfs_server_cap_unicode = {
1883         "Unicode strings are supported",
1884         "Unicode strings are not supported"
1885 };
1886 static const true_false_string tfs_server_cap_large_files = {
1887         "Large files are supported",
1888         "Large files are not supported",
1889 };
1890 static const true_false_string tfs_server_cap_nt_smbs = {
1891         "NT SMBs are supported",
1892         "NT SMBs are not supported"
1893 };
1894 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1895         "RPC remote APIs are supported",
1896         "RPC remote APIs are not supported"
1897 };
1898 static const true_false_string tfs_server_cap_nt_status = {
1899         "NT status codes are supported",
1900         "NT status codes are not supported"
1901 };
1902 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1903         "Level 2 oplocks are supported",
1904         "Level 2 oplocks are not supported"
1905 };
1906 static const true_false_string tfs_server_cap_lock_and_read = {
1907         "Lock and Read is supported",
1908         "Lock and Read is not supported"
1909 };
1910 static const true_false_string tfs_server_cap_nt_find = {
1911         "NT Find is supported",
1912         "NT Find is not supported"
1913 };
1914 static const true_false_string tfs_server_cap_dfs = {
1915         "Dfs is supported",
1916         "Dfs is not supported"
1917 };
1918 static const true_false_string tfs_server_cap_infolevel_passthru = {
1919         "NT information level request passthrough is supported",
1920         "NT information level request passthrough is not supported"
1921 };
1922 static const true_false_string tfs_server_cap_large_readx = {
1923         "Large Read andX is supported",
1924         "Large Read andX is not supported"
1925 };
1926 static const true_false_string tfs_server_cap_large_writex = {
1927         "Large Write andX is supported",
1928         "Large Write andX is not supported"
1929 };
1930 static const true_false_string tfs_server_cap_unix = {
1931         "UNIX extensions are supported",
1932         "UNIX extensions are not supported"
1933 };
1934 static const true_false_string tfs_server_cap_reserved = {
1935         "Reserved",
1936         "Reserved"
1937 };
1938 static const true_false_string tfs_server_cap_bulk_transfer = {
1939         "Bulk Read and Bulk Write are supported",
1940         "Bulk Read and Bulk Write are not supported"
1941 };
1942 static const true_false_string tfs_server_cap_compressed_data = {
1943         "Compressed data transfer is supported",
1944         "Compressed data transfer is not supported"
1945 };
1946 static const true_false_string tfs_server_cap_extended_security = {
1947         "Extended security exchanges are supported",
1948         "Extended security exchanges are not supported"
1949 };
1950 static int
1951 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1952 {
1953         guint32 mask;
1954         proto_item *item;
1955         proto_tree *tree;
1956
1957         mask = tvb_get_letohl(tvb, offset);
1958
1959         if(parent_tree){
1960                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1961                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1962
1963                 proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1964                         tvb, offset, 4, mask);
1965                 proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1966                         tvb, offset, 4, mask);
1967                 proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1968                         tvb, offset, 4, mask);
1969                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1970                         tvb, offset, 4, mask);
1971                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1972                         tvb, offset, 4, mask);
1973                 proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1974                         tvb, offset, 4, mask);
1975                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1976                         tvb, offset, 4, mask);
1977                 proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1978                         tvb, offset, 4, mask);
1979                 proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1980                         tvb, offset, 4, mask);
1981                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1982                         tvb, offset, 4, mask);
1983                 proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1984                         tvb, offset, 4, mask);
1985                 proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1986                         tvb, offset, 4, mask);
1987                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1988                         tvb, offset, 4, mask);
1989                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1990                         tvb, offset, 4, mask);
1991                 proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1992                         tvb, offset, 4, mask);
1993                 proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1994                         tvb, offset, 4, mask);
1995                 proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1996                         tvb, offset, 4, mask);
1997                 proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1998                         tvb, offset, 4, mask);
1999                 proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
2000                         tvb, offset, 4, mask);
2001         }
2002
2003         return mask;
2004 }
2005
2006 #define RAWMODE_READ   0x01
2007 #define RAWMODE_WRITE  0x02
2008 static const true_false_string tfs_rm_read = {
2009         "Read Raw is supported",
2010         "Read Raw is not supported"
2011 };
2012 static const true_false_string tfs_rm_write = {
2013         "Write Raw is supported",
2014         "Write Raw is not supported"
2015 };
2016
2017 static int
2018 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2019 {
2020         guint16 mask;
2021         proto_item *item;
2022         proto_tree *tree;
2023
2024         mask = tvb_get_letohs(tvb, offset);
2025
2026         if(parent_tree){
2027                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
2028                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
2029
2030                 proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
2031                 proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
2032         }
2033
2034         offset += 2;
2035
2036         return offset;
2037 }
2038
2039 #define SECURITY_MODE_MODE             0x01
2040 #define SECURITY_MODE_PASSWORD         0x02
2041 #define SECURITY_MODE_SIGNATURES       0x04
2042 #define SECURITY_MODE_SIG_REQUIRED     0x08
2043 static const true_false_string tfs_sm_mode = {
2044         "USER security mode",
2045         "SHARE security mode"
2046 };
2047 static const true_false_string tfs_sm_password = {
2048         "ENCRYPTED password. Use challenge/response",
2049         "PLAINTEXT password"
2050 };
2051 static const true_false_string tfs_sm_signatures = {
2052         "Security signatures ENABLED",
2053         "Security signatures NOT enabled"
2054 };
2055 static const true_false_string tfs_sm_sig_required = {
2056         "Security signatures REQUIRED",
2057         "Security signatures NOT required"
2058 };
2059
2060 static int
2061 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2062 {
2063         guint16 mask = 0;
2064         proto_item *item = NULL;
2065         proto_tree *tree = NULL;
2066
2067         switch(wc){
2068         case 13:
2069                 mask = tvb_get_letohs(tvb, offset);
2070                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2071                                 "Security Mode: 0x%04x", mask);
2072                 tree = proto_item_add_subtree(item, ett_smb_mode);
2073                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2074                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2075                 offset += 2;
2076                 break;
2077
2078         case 17:
2079                 mask = tvb_get_guint8(tvb, offset);
2080                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2081                                 "Security Mode: 0x%02x", mask);
2082                 tree = proto_item_add_subtree(item, ett_smb_mode);
2083                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2084                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2085                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2086                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2087                 offset += 1;
2088                 break;
2089         }
2090
2091         return offset;
2092 }
2093
2094 #define MAX_DIALECTS 20
2095 struct negprot_dialects {
2096        int num;
2097        char *name[MAX_DIALECTS+1];
2098 };
2099
2100 static int
2101 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2102 {
2103         proto_item *it = NULL;
2104         proto_tree *tr = NULL;
2105         guint16 bc;
2106         guint8 wc;
2107         struct negprot_dialects *dialects = NULL;
2108         smb_info_t *si;
2109
2110         si = (smb_info_t *)pinfo->private_data;
2111         DISSECTOR_ASSERT(si);
2112
2113         WORD_COUNT;
2114
2115         BYTE_COUNT;
2116
2117         if(tree){
2118                 tvb_ensure_bytes_exist(tvb, offset, bc);
2119                 it = proto_tree_add_text(tree, tvb, offset, bc,
2120                                 "Requested Dialects");
2121                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2122         }
2123
2124         if (!pinfo->fd->flags.visited && si->sip) {
2125                 dialects = se_alloc(sizeof(struct negprot_dialects));
2126                 dialects->num = 0;
2127                 si->sip->extra_info_type = SMB_EI_DIALECTS;
2128                 si->sip->extra_info = dialects;
2129         }
2130
2131         while(bc){
2132                 int len;
2133                 const guint8 *str;
2134                 proto_item *dit = NULL;
2135                 proto_tree *dtr = NULL;
2136
2137                 /* XXX - what if this runs past bc? */
2138                 tvb_ensure_bytes_exist(tvb, offset+1, 1);
2139                 len = tvb_strsize(tvb, offset+1);
2140                 str = tvb_get_ptr(tvb, offset+1, len);
2141
2142                 if(tr){
2143                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2144                                         "Dialect: %s", str);
2145                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2146                 }
2147
2148                 /* Buffer Format */
2149                 CHECK_BYTE_COUNT(1);
2150                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2151                         TRUE);
2152                 COUNT_BYTES(1);
2153
2154                 /*Dialect Name */
2155                 CHECK_BYTE_COUNT(len);
2156                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2157                         len, str);
2158                 COUNT_BYTES(len);
2159
2160                 if (!pinfo->fd->flags.visited && dialects && dialects->num<MAX_DIALECTS) {
2161                         dialects->name[dialects->num++] = se_strdup(str);
2162                 }
2163         }
2164
2165
2166         END_OF_SMB
2167
2168         return offset;
2169 }
2170
2171 static int
2172 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2173 {
2174         smb_info_t *si = pinfo->private_data;
2175         guint8 wc;
2176         guint16 dialect;
2177         const char *dn;
2178         int dn_len;
2179         guint16 bc;
2180         guint16 ekl=0;
2181         guint32 caps=0;
2182         gint16 tz;
2183         struct negprot_dialects *dialects = NULL;
2184         const char *dialect_name = NULL;
2185
2186         DISSECTOR_ASSERT(si);
2187
2188         WORD_COUNT;
2189
2190         /* Dialect Index */
2191         dialect = tvb_get_letohs(tvb, offset);
2192
2193         if (si->sip && si->sip->extra_info_type==SMB_EI_DIALECTS) {
2194                 dialects = si->sip->extra_info;
2195                 if (dialect <= dialects->num) {
2196                         dialect_name = dialects->name[dialect];
2197                 }
2198         }
2199         if (!dialect_name) {
2200                 dialect_name = "unknown";
2201         }
2202
2203         switch(wc){
2204         case 1:
2205                 if(dialect==0xffff){
2206                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2207                                 tvb, offset, 2, dialect,
2208                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2209                 } else {
2210                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2211                                 tvb, offset, 2, dialect);
2212                 }
2213                 break;
2214         case 13:
2215                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2216                         tvb, offset, 2, dialect,
2217                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2218                 break;
2219         case 17:
2220                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2221                         tvb, offset, 2, dialect,
2222                         "Dialect Index: %u: %s", dialect, dialect_name);
2223                 break;
2224         default:
2225                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
2226                 proto_tree_add_text(tree, tvb, offset, wc*2,
2227                         "Words for unknown response format");
2228                 offset += wc*2;
2229                 goto bytecount;
2230         }
2231         offset += 2;
2232
2233         switch(wc){
2234         case 13:
2235                 /* Security Mode */
2236                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2237
2238                 /* Maximum Transmit Buffer Size */
2239                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2240                         tvb, offset, 2, TRUE);
2241                 offset += 2;
2242
2243                 /* Maximum Multiplex Count */
2244                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2245                         tvb, offset, 2, TRUE);
2246                 offset += 2;
2247
2248                 /* Maximum Vcs Number */
2249                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2250                         tvb, offset, 2, TRUE);
2251                 offset += 2;
2252
2253                 /* raw mode */
2254                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2255
2256                 /* session key */
2257                 proto_tree_add_item(tree, hf_smb_session_key,
2258                         tvb, offset, 4, TRUE);
2259                 offset += 4;
2260
2261                 /* current time and date at server */
2262                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2263                     TRUE);
2264
2265                 /* time zone */
2266                 tz = tvb_get_letohs(tvb, offset);
2267                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2268                 offset += 2;
2269
2270                 /* encryption key length */
2271                 ekl = tvb_get_letohs(tvb, offset);
2272                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2273                 offset += 2;
2274
2275                 /* 2 reserved bytes */
2276                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2277                 offset += 2;
2278
2279                 break;
2280
2281         case 17:
2282                 /* Security Mode */
2283                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2284
2285                 /* Maximum Multiplex Count */
2286                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2287                         tvb, offset, 2, TRUE);
2288                 offset += 2;
2289
2290                 /* Maximum Vcs Number */
2291                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2292                         tvb, offset, 2, TRUE);
2293                 offset += 2;
2294
2295                 /* Maximum Transmit Buffer Size */
2296                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2297                         tvb, offset, 4, TRUE);
2298                 offset += 4;
2299
2300                 /* maximum raw buffer size */
2301                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2302                         tvb, offset, 4, TRUE);
2303                 offset += 4;
2304
2305                 /* session key */
2306                 proto_tree_add_item(tree, hf_smb_session_key,
2307                         tvb, offset, 4, TRUE);
2308                 offset += 4;
2309
2310                 /* server capabilities */
2311                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2312                 offset += 4;
2313
2314                 /* system time */
2315                 offset = dissect_nt_64bit_time(tvb, tree, offset,
2316                                 hf_smb_system_time);
2317
2318                 /* time zone */
2319                 tz = tvb_get_letohs(tvb, offset);
2320                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2321                         tvb, offset, 2, tz,
2322                         "Server Time Zone: %d min from UTC", tz);
2323                 offset += 2;
2324
2325                 /* encryption key length */
2326                 ekl = tvb_get_guint8(tvb, offset);
2327                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2328                         tvb, offset, 1, ekl);
2329                 offset += 1;
2330
2331                 break;
2332         }
2333
2334         BYTE_COUNT;
2335
2336         switch(wc){
2337         case 13:
2338                 /* challenge/response encryption key */
2339                 if(ekl){
2340                         CHECK_BYTE_COUNT(ekl);
2341                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2342                         COUNT_BYTES(ekl);
2343                 }
2344
2345                 /*
2346                  * Primary domain.
2347                  *
2348                  * XXX - not present if negotiated dialect isn't
2349                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2350                  * have to see the request, or assume what dialect strings
2351                  * were sent, to determine that.
2352                  *
2353                  * Is this something other than a primary domain if the
2354                  * negotiated dialect is Windows for Workgroups 3.1a?
2355                  * It appears to be 8 bytes of binary data in at least
2356                  * one capture - is that an encryption key or something
2357                  * such as that?
2358                  */
2359                 dn = get_unicode_or_ascii_string(tvb, &offset,
2360                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2361                 if (dn == NULL)
2362                         goto endofcommand;
2363                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2364                         offset, dn_len,dn);
2365                 COUNT_BYTES(dn_len);
2366                 break;
2367
2368         case 17:
2369                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2370                         /* challenge/response encryption key */
2371                         /* XXX - is this aligned on an even boundary? */
2372                         if(ekl){
2373                                 CHECK_BYTE_COUNT(ekl);
2374                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2375                                         tvb, offset, ekl, TRUE);
2376                                 COUNT_BYTES(ekl);
2377                         }
2378
2379                         /* domain */
2380                         /* this string is special, unicode is flagged in caps */
2381                         /* This string is NOT padded to be 16bit aligned.
2382                            (seen in actual capture)
2383                            XXX - I've seen a capture where it appears to be
2384                            so aligned, but I've also seen captures where
2385                            it is.  The captures where it appeared to be
2386                            aligned may have been from buggy servers. */
2387                         /* However, don't get rid of existing setting */
2388                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2389                           si->unicode;
2390
2391                         dn = get_unicode_or_ascii_string(tvb,
2392                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2393                                 &bc);
2394                         if (dn == NULL)
2395                                 goto endofcommand;
2396                         proto_tree_add_string(tree, hf_smb_primary_domain,
2397                                 tvb, offset, dn_len, dn);
2398                         COUNT_BYTES(dn_len);
2399
2400                         /* server name, seen in w2k pro capture */
2401                         dn = get_unicode_or_ascii_string(tvb,
2402                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2403                                 &bc);
2404                         if (dn == NULL)
2405                                 goto endofcommand;
2406                         proto_tree_add_string(tree, hf_smb_server,
2407                                 tvb, offset, dn_len, dn);
2408                         COUNT_BYTES(dn_len);
2409
2410                 } else {
2411                         proto_item *blob_item;
2412                         guint16 sbloblen;
2413
2414                         /* guid */
2415                         /* XXX - show it in the standard Microsoft format
2416                            for GUIDs? */
2417                         CHECK_BYTE_COUNT(16);
2418                         proto_tree_add_item(tree, hf_smb_server_guid,
2419                                 tvb, offset, 16, TRUE);
2420                         COUNT_BYTES(16);
2421
2422                         /* security blob */
2423                         /* If it runs past the end of the captured data, don't
2424                          * try to put all of it into the protocol tree as the
2425                          * raw security blob; we might get an exception on
2426                          * short frames and then we will not see anything at all
2427                          * of the security blob.
2428                          */
2429                         sbloblen=bc;
2430                         if(sbloblen>tvb_length_remaining(tvb, offset)){
2431                                 sbloblen=tvb_length_remaining(tvb,offset);
2432                         }
2433                         blob_item = proto_tree_add_item(
2434                                 tree, hf_smb_security_blob,
2435                                 tvb, offset, sbloblen, TRUE);
2436
2437                         /*
2438                          * If Extended security and BCC == 16, then raw
2439                          * NTLMSSP is in use. We need to save this info
2440                          */
2441
2442                         if(bc){
2443                                 tvbuff_t *gssapi_tvb;
2444                                 proto_tree *gssapi_tree;
2445
2446                                 gssapi_tree = proto_item_add_subtree(
2447                                         blob_item, ett_smb_secblob);
2448
2449                                 /*
2450                                  * Set the reported length of this to
2451                                  * the reported length of the blob,
2452                                  * rather than the amount of data
2453                                  * available from the blob, so that
2454                                  * we'll throw the right exception if
2455                                  * it's too short.
2456                                  */
2457                                 gssapi_tvb = tvb_new_subset(
2458                                         tvb, offset, sbloblen, bc);
2459
2460                                 call_dissector(
2461                                         gssapi_handle, gssapi_tvb, pinfo,
2462                                         gssapi_tree);
2463
2464                                 if (si->ct)
2465                                   si->ct->raw_ntlmssp = 0;
2466
2467                                 COUNT_BYTES(bc);
2468                         }
2469                         else {
2470
2471                           /*
2472                            * There is no blob. We just have to make sure
2473                            * that subsequent routines know to call the
2474                            * right things ...
2475                            */
2476
2477                           if (si->ct)
2478                             si->ct->raw_ntlmssp = 1;
2479
2480                         }
2481                 }
2482                 break;
2483         }
2484
2485         END_OF_SMB
2486
2487         return offset;
2488 }
2489
2490
2491 static int
2492 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2493 {
2494         smb_info_t *si = pinfo->private_data;
2495         int dn_len;
2496         const char *dn;
2497         guint8 wc;
2498         guint16 bc;
2499
2500         DISSECTOR_ASSERT(si);
2501
2502         WORD_COUNT;
2503
2504         BYTE_COUNT;
2505
2506         /* buffer format */
2507         CHECK_BYTE_COUNT(1);
2508         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2509         COUNT_BYTES(1);
2510
2511         /* dir name */
2512         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2513                 FALSE, FALSE, &bc);
2514
2515         if(si->sip){
2516                 si->sip->extra_info_type=SMB_EI_FILENAME;
2517                 si->sip->extra_info=se_strdup(dn);
2518         }
2519
2520         if (dn == NULL)
2521                 goto endofcommand;
2522         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2523                 dn);
2524         COUNT_BYTES(dn_len);
2525
2526         if (check_col(pinfo->cinfo, COL_INFO)) {
2527                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
2528                     format_text(dn, strlen(dn)));
2529         }
2530
2531         END_OF_SMB
2532
2533         return offset;
2534 }
2535
2536 static int
2537 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2538 {
2539         guint8 wc;
2540         guint16 bc;
2541         smb_info_t *si = pinfo->private_data;
2542         proto_item *item=NULL;
2543
2544         DISSECTOR_ASSERT(si);
2545
2546         if(si->sip && si->sip->extra_info_type==SMB_EI_FILENAME){
2547                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, si->sip->extra_info);
2548                 PROTO_ITEM_SET_GENERATED(item);
2549         }
2550
2551
2552         WORD_COUNT;
2553
2554         BYTE_COUNT;
2555
2556         END_OF_SMB
2557
2558         return offset;
2559 }
2560
2561 static int
2562 dissect_rename_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2563 {
2564         guint8 wc;
2565         guint16 bc;
2566         smb_info_t *si = pinfo->private_data;
2567         proto_item *item=NULL;
2568
2569         DISSECTOR_ASSERT(si);
2570
2571         if(si->sip && si->sip->extra_info_type==SMB_EI_RENAMEDATA){
2572                 smb_rename_saved_info_t *rni=si->sip->extra_info;
2573
2574                 item=proto_tree_add_string(tree, hf_smb_old_file_name, tvb, 0, 0, rni->old_name);
2575                 PROTO_ITEM_SET_GENERATED(item);
2576                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, rni->new_name);
2577                 PROTO_ITEM_SET_GENERATED(item);
2578         }
2579
2580
2581         WORD_COUNT;
2582
2583         BYTE_COUNT;
2584
2585         END_OF_SMB
2586
2587         return offset;
2588 }
2589
2590 static int
2591 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2592 {
2593         guint16 ec, bc;
2594         guint8 wc;
2595
2596         WORD_COUNT;
2597
2598         /* echo count */
2599         ec = tvb_get_letohs(tvb, offset);
2600         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2601         offset += 2;
2602
2603         BYTE_COUNT;
2604
2605         if (bc != 0) {
2606                 /* echo data */
2607                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2608                 COUNT_BYTES(bc);
2609         }
2610
2611         END_OF_SMB
2612
2613         return offset;
2614 }
2615
2616 static int
2617 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2618 {
2619         guint16 bc;
2620         guint8 wc;
2621
2622         WORD_COUNT;
2623
2624         /* echo sequence number */
2625         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2626         offset += 2;
2627
2628         BYTE_COUNT;
2629
2630         if (bc != 0) {
2631                 /* echo data */
2632                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2633                 COUNT_BYTES(bc);
2634         }
2635
2636         END_OF_SMB
2637
2638         return offset;
2639 }
2640
2641 static int
2642 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2643 {
2644         smb_info_t *si = pinfo->private_data;
2645         int an_len, pwlen;
2646         const char *an;
2647         guint8 wc;
2648         guint16 bc;
2649
2650         DISSECTOR_ASSERT(si);
2651
2652         WORD_COUNT;
2653
2654         BYTE_COUNT;
2655
2656         /* buffer format */
2657         CHECK_BYTE_COUNT(1);
2658         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2659         COUNT_BYTES(1);
2660
2661         /* Path */
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_path, tvb,
2667                 offset, an_len, an);
2668         COUNT_BYTES(an_len);
2669
2670         if (check_col(pinfo->cinfo, COL_INFO)) {
2671                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2672                     format_text(an, strlen(an)));
2673         }
2674
2675         /* buffer format */
2676         CHECK_BYTE_COUNT(1);
2677         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2678         COUNT_BYTES(1);
2679
2680         /* password, ANSI */
2681         /* XXX - what if this runs past bc? */
2682         pwlen = tvb_strsize(tvb, offset);
2683         CHECK_BYTE_COUNT(pwlen);
2684         proto_tree_add_item(tree, hf_smb_password,
2685                 tvb, offset, pwlen, TRUE);
2686         COUNT_BYTES(pwlen);
2687
2688         /* buffer format */
2689         CHECK_BYTE_COUNT(1);
2690         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2691         COUNT_BYTES(1);
2692
2693         /* Service */
2694         /*
2695          * XXX - the SNIA CIFS spec "Strings that are never passed in
2696          * Unicode are: ... The service name string in the
2697          * Tree_Connect_AndX SMB".  Is that claim false?
2698          */
2699         an = get_unicode_or_ascii_string(tvb, &offset,
2700                 si->unicode, &an_len, FALSE, FALSE, &bc);
2701         if (an == NULL)
2702                 goto endofcommand;
2703         proto_tree_add_string(tree, hf_smb_service, tvb,
2704                 offset, an_len, an);
2705         COUNT_BYTES(an_len);
2706
2707         END_OF_SMB
2708
2709         return offset;
2710 }
2711
2712 static int
2713 dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
2714 {
2715         proto_item *item, *subitem;
2716         proto_tree *tree;
2717         smb_uid_t *smb_uid=NULL;
2718
2719         item=proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
2720         tree=proto_item_add_subtree(item, ett_smb_uid);
2721
2722         smb_uid=se_tree_lookup32(si->ct->uid_tree, si->uid);
2723         if(smb_uid){
2724                 if(smb_uid->domain && smb_uid->account)
2725                         proto_item_append_text(item, "  (");
2726                 if(smb_uid->domain){
2727                         proto_item_append_text(item, "%s", smb_uid->domain);
2728                         subitem=proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
2729                         PROTO_ITEM_SET_GENERATED(subitem);
2730                 }
2731                 if(smb_uid->account){
2732                         proto_item_append_text(item, "\\%s", smb_uid->account);
2733                         subitem=proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
2734                         PROTO_ITEM_SET_GENERATED(subitem);
2735                 }
2736                 if(smb_uid->domain && smb_uid->account)
2737                         proto_item_append_text(item, ")");
2738                 if(smb_uid->logged_in>0){
2739                         subitem=proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
2740                         PROTO_ITEM_SET_GENERATED(subitem);
2741                 }
2742                 if(smb_uid->logged_out>0){
2743                         subitem=proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
2744                         PROTO_ITEM_SET_GENERATED(subitem);
2745                 }
2746         }
2747         offset += 2;
2748
2749         return offset;
2750 }
2751
2752 static int
2753 dissect_smb_tid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 tid, gboolean is_created, gboolean is_closed)
2754 {
2755         smb_info_t *si = pinfo->private_data;
2756         proto_item *it;
2757         proto_tree *tr;
2758         smb_tid_info_t *tid_info=NULL;
2759
2760         DISSECTOR_ASSERT(si);
2761
2762         /* tid */
2763         it=proto_tree_add_uint(tree, hf_smb_tid, tvb, offset, 2, tid);
2764         tr=proto_item_add_subtree(it, ett_smb_tid);
2765         offset += 2;
2766
2767         if((!pinfo->fd->flags.visited) && is_created){
2768                 tid_info=se_alloc(sizeof(smb_tid_info_t));
2769                 tid_info->opened_in=pinfo->fd->num;
2770                 tid_info->closed_in=0;
2771                 tid_info->type=SMB_FID_TYPE_UNKNOWN;
2772                 if(si->sip && (si->sip->extra_info_type==SMB_EI_TIDNAME)){
2773                         tid_info->filename=si->sip->extra_info;
2774                 } else {
2775                         tid_info->filename=NULL;
2776                 }
2777                 se_tree_insert32(si->ct->tid_tree, tid, tid_info);
2778         }
2779
2780         if(!tid_info){
2781                 tid_info=se_tree_lookup32_le(si->ct->tid_tree, tid);
2782         }
2783         if(!tid_info){
2784                 return offset;
2785         }
2786
2787         if((!pinfo->fd->flags.visited) && is_closed){
2788                 tid_info->closed_in=pinfo->fd->num;
2789         }
2790
2791         if(tid_info->opened_in){
2792                 if(tid_info->filename){
2793                         proto_item_append_text(it, "  (%s)", tid_info->filename);
2794
2795                         it=proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
2796                         PROTO_ITEM_SET_GENERATED(it);
2797                 }
2798
2799                 it=proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
2800                 PROTO_ITEM_SET_GENERATED(it);
2801         }
2802         if(tid_info->closed_in){
2803                 it=proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
2804                 PROTO_ITEM_SET_GENERATED(it);
2805         }
2806
2807
2808         return offset;
2809 }
2810
2811 static int
2812 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2813 {
2814         guint8 wc;
2815         guint16 bc;
2816
2817         WORD_COUNT;
2818
2819         /* Maximum Buffer Size */
2820         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2821         offset += 2;
2822
2823         /* tid */
2824         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tvb_get_letohs(tvb, offset), TRUE, FALSE);
2825
2826         BYTE_COUNT;
2827
2828         END_OF_SMB
2829
2830         return offset;
2831 }
2832
2833
2834 static const true_false_string tfs_of_create = {
2835         "Create file if it does not exist",
2836         "Fail if file does not exist"
2837 };
2838 static const value_string of_open[] = {
2839         { 0,            "Fail if file exists"},
2840         { 1,            "Open file if it exists"},
2841         { 2,            "Truncate file if it exists"},
2842         {0, NULL}
2843 };
2844 static int
2845 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2846 {
2847         guint16 mask;
2848         proto_item *item = NULL;
2849         proto_tree *tree = NULL;
2850
2851         mask = tvb_get_letohs(tvb, offset);
2852
2853         if(parent_tree){
2854                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2855                         "Open Function: 0x%04x", mask);
2856                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2857         }
2858
2859         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2860                 tvb, offset, 2, mask);
2861         proto_tree_add_uint(tree, hf_smb_open_function_open,
2862                 tvb, offset, 2, mask);
2863
2864         offset += 2;
2865
2866         return offset;
2867 }
2868
2869
2870 static const true_false_string tfs_mf_file = {
2871         "Target must be a file",
2872         "Target needn't be a file"
2873 };
2874 static const true_false_string tfs_mf_dir = {
2875         "Target must be a directory",
2876         "Target needn't be a directory"
2877 };
2878 static const true_false_string tfs_mf_verify = {
2879         "MUST verify all writes",
2880         "Don't have to verify writes"
2881 };
2882 static int
2883 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2884 {
2885         guint16 mask;
2886         proto_item *item = NULL;
2887         proto_tree *tree = NULL;
2888
2889         mask = tvb_get_letohs(tvb, offset);
2890
2891         if(parent_tree){
2892                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2893                         "Flags: 0x%04x", mask);
2894                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2895         }
2896
2897         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2898                 tvb, offset, 2, mask);
2899         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2900                 tvb, offset, 2, mask);
2901         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2902                 tvb, offset, 2, mask);
2903
2904         offset += 2;
2905
2906         return offset;
2907 }
2908
2909 static const true_false_string tfs_cf_mode = {
2910         "ASCII",
2911         "Binary"
2912 };
2913 static const true_false_string tfs_cf_tree_copy = {
2914         "Copy is a tree copy",
2915         "Copy is a file copy"
2916 };
2917 static const true_false_string tfs_cf_ea_action = {
2918         "Fail copy",
2919         "Discard EAs"
2920 };
2921 static int
2922 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2923 {
2924         guint16 mask;
2925         proto_item *item = NULL;
2926         proto_tree *tree = NULL;
2927
2928         mask = tvb_get_letohs(tvb, offset);
2929
2930         if(parent_tree){
2931                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2932                         "Flags: 0x%04x", mask);
2933                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2934         }
2935
2936         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2937                 tvb, offset, 2, mask);
2938         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2939                 tvb, offset, 2, mask);
2940         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2941                 tvb, offset, 2, mask);
2942         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2943                 tvb, offset, 2, mask);
2944         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2945                 tvb, offset, 2, mask);
2946         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2947                 tvb, offset, 2, mask);
2948         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2949                 tvb, offset, 2, mask);
2950
2951         offset += 2;
2952
2953         return offset;
2954 }
2955
2956 static int
2957 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2958 {
2959         smb_info_t *si = pinfo->private_data;
2960         int fn_len;
2961         guint16 tid;
2962         guint16 bc;
2963         guint8 wc;
2964         const char *fn;
2965
2966         DISSECTOR_ASSERT(si);
2967
2968         WORD_COUNT;
2969
2970         /* tid */
2971         tid = tvb_get_letohs(tvb, offset);
2972         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
2973
2974         /* open function */
2975         offset = dissect_open_function(tvb, tree, offset);
2976
2977         /* move flags */
2978         offset = dissect_move_flags(tvb, tree, offset);
2979
2980         BYTE_COUNT;
2981
2982         /* buffer format */
2983         CHECK_BYTE_COUNT(1);
2984         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2985         COUNT_BYTES(1);
2986
2987         /* file name */
2988         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2989                 FALSE, FALSE, &bc);
2990         if (fn == NULL)
2991                 goto endofcommand;
2992         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2993                 fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
2994         COUNT_BYTES(fn_len);
2995
2996         if (check_col(pinfo->cinfo, COL_INFO)) {
2997                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
2998                     format_text(fn, strlen(fn)));
2999         }
3000
3001         /* buffer format */
3002         CHECK_BYTE_COUNT(1);
3003         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3004         COUNT_BYTES(1);
3005
3006         /* file name */
3007         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3008                 FALSE, FALSE, &bc);
3009         if (fn == NULL)
3010                 goto endofcommand;
3011         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3012                 fn_len, fn, "New File Name: %s", format_text(fn, strlen(fn)));
3013         COUNT_BYTES(fn_len);
3014
3015         if (check_col(pinfo->cinfo, COL_INFO)) {
3016                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3017                     format_text(fn, strlen(fn)));
3018         }
3019
3020         END_OF_SMB
3021
3022         return offset;
3023 }
3024
3025 static int
3026 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3027 {
3028         smb_info_t *si = pinfo->private_data;
3029         int fn_len;
3030         guint16 tid;
3031         guint16 bc;
3032         guint8 wc;
3033         const char *fn;
3034
3035         DISSECTOR_ASSERT(si);
3036
3037         WORD_COUNT;
3038
3039         /* tid */
3040         tid = tvb_get_letohs(tvb, offset);
3041         offset=dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE);
3042
3043         /* open function */
3044         offset = dissect_open_function(tvb, tree, offset);
3045
3046         /* copy flags */
3047         offset = dissect_copy_flags(tvb, tree, offset);
3048
3049         BYTE_COUNT;
3050
3051         /* buffer format */
3052         CHECK_BYTE_COUNT(1);
3053         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3054         COUNT_BYTES(1);
3055
3056         /* file name */
3057         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3058                 FALSE, FALSE, &bc);
3059         if (fn == NULL)
3060                 goto endofcommand;
3061         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3062                 fn_len, fn, "Source File Name: %s", format_text(fn, strlen(fn)));
3063         COUNT_BYTES(fn_len);
3064
3065         if (check_col(pinfo->cinfo, COL_INFO)) {
3066                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
3067                     format_text(fn, strlen(fn)));
3068         }
3069
3070         /* buffer format */
3071         CHECK_BYTE_COUNT(1);
3072         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3073         COUNT_BYTES(1);
3074
3075         /* file name */
3076         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3077                 FALSE, FALSE, &bc);
3078         if (fn == NULL)
3079                 goto endofcommand;
3080         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3081                 fn_len, fn, "Destination File Name: %s",
3082                 format_text(fn, strlen(fn)));
3083         COUNT_BYTES(fn_len);
3084
3085         if (check_col(pinfo->cinfo, COL_INFO)) {
3086                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(fn, strlen(fn)));
3087         }
3088
3089         END_OF_SMB
3090
3091         return offset;
3092 }
3093
3094 static int
3095 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3096 {
3097         smb_info_t *si = pinfo->private_data;
3098         int fn_len;
3099         const char *fn;
3100         guint8 wc;
3101         guint16 bc;
3102
3103         DISSECTOR_ASSERT(si);
3104
3105         WORD_COUNT;
3106
3107         /* # of files moved */
3108         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
3109         offset += 2;
3110
3111         BYTE_COUNT;
3112
3113         /* buffer format */
3114         CHECK_BYTE_COUNT(1);
3115         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3116         COUNT_BYTES(1);
3117
3118         /* file name */
3119         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3120                 FALSE, FALSE, &bc);
3121         if (fn == NULL)
3122                 goto endofcommand;
3123         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3124                 fn);
3125         COUNT_BYTES(fn_len);
3126
3127         END_OF_SMB
3128
3129         return offset;
3130 }
3131
3132 static int
3133 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3134 {
3135         smb_info_t *si = pinfo->private_data;
3136         int fn_len;
3137         const char *fn;
3138         guint8 wc;
3139         guint16 bc;
3140
3141         DISSECTOR_ASSERT(si);
3142
3143         WORD_COUNT;
3144
3145         /* desired access */
3146         offset = dissect_access(tvb, tree, offset, "Desired");
3147
3148         /* Search Attributes */
3149         offset = dissect_search_attributes(tvb, tree, offset);
3150
3151         BYTE_COUNT;
3152
3153         /* buffer format */
3154         CHECK_BYTE_COUNT(1);
3155         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3156         COUNT_BYTES(1);
3157
3158         /* file name */
3159         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3160                 FALSE, FALSE, &bc);
3161         if (fn == NULL)
3162                 goto endofcommand;
3163         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3164                 fn);
3165         COUNT_BYTES(fn_len);
3166
3167         if (check_col(pinfo->cinfo, COL_INFO)) {
3168                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3169                     format_text(fn, strlen(fn)));
3170         }
3171
3172         END_OF_SMB
3173
3174         return offset;
3175 }
3176
3177
3178
3179 static int
3180 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
3181     int len, guint32 mask)
3182 {
3183         proto_item *item = NULL;
3184         proto_tree *tree = NULL;
3185
3186         if(parent_tree){
3187                 item = proto_tree_add_uint(parent_tree, hf_smb_create_flags, tvb, offset, len, mask);
3188
3189                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
3190         }
3191
3192         /*
3193          * XXX - it's 0x00000016 in at least one capture, but
3194          * Network Monitor doesn't say what the 0x00000010 bit is.
3195          * Does the Win32 API documentation, or NT Native API book,
3196          * suggest anything?
3197          *
3198          * That is the extended response desired bit ... RJS, from Samba
3199          * Well, maybe. Samba thinks it is, and uses it to encode
3200          * OpLock granted as the high order bit of the Action field
3201          * in the response. However, Windows does not do that. Or at least
3202          * Win2K doesn't.
3203          */
3204         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
3205                                tvb, offset, len, mask);
3206         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
3207                 tvb, offset, len, mask);
3208         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
3209                 tvb, offset, len, mask);
3210         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
3211                 tvb, offset, len, mask);
3212
3213         offset += len;
3214
3215         return offset;
3216 }
3217
3218 /* FIXME: need to call dissect_nt_access_mask() instead */
3219 static int
3220 dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3221     int offset, int len, guint32 mask)
3222 {
3223         proto_item *item;
3224         proto_tree *tree;
3225
3226         if(parent_tree){
3227                 item = proto_tree_add_uint(parent_tree, hf_smb_access_mask, tvb, offset, len, mask);
3228                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
3229
3230                 /*
3231                  * Some of these bits come from
3232                  *
3233                  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3234                  *
3235                  * and others come from the section on ZwOpenFile in "Windows(R)
3236                  * NT(R)/2000 Native API Reference".
3237                  */
3238                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
3239                         tvb, offset, len, mask);
3240                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
3241                         tvb, offset, len, mask);
3242                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
3243                         tvb, offset, len, mask);
3244                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
3245                         tvb, offset, len, mask);
3246                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
3247                         tvb, offset, len, mask);
3248                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
3249                         tvb, offset, len, mask);
3250                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
3251                         tvb, offset, len, mask);
3252                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
3253                         tvb, offset, len, mask);
3254                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
3255                         tvb, offset, len, mask);
3256                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
3257                         tvb, offset, len, mask);
3258                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
3259                         tvb, offset, len, mask);
3260                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
3261                         tvb, offset, len, mask);
3262                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
3263                         tvb, offset, len, mask);
3264                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
3265                         tvb, offset, len, mask);
3266                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
3267                         tvb, offset, len, mask);
3268                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
3269                         tvb, offset, len, mask);
3270                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
3271                         tvb, offset, len, mask);
3272                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
3273                         tvb, offset, len, mask);
3274                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
3275                         tvb, offset, len, mask);
3276                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
3277                         tvb, offset, len, mask);
3278         }
3279         offset += len;
3280
3281         return offset;
3282 }
3283
3284 int
3285 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3286 {
3287         guint32 mask;
3288
3289         mask = tvb_get_letohl(tvb, offset);
3290
3291         offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, 4, mask);
3292
3293         return offset;
3294 }
3295
3296
3297 #define SHARE_ACCESS_DELETE     0x00000004
3298 #define SHARE_ACCESS_WRITE      0x00000002
3299 #define SHARE_ACCESS_READ       0x00000001
3300
3301 static int
3302 dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3303     int offset, int len, guint32 mask)
3304 {
3305         proto_item *item;
3306         proto_tree *tree;
3307
3308         if(parent_tree){
3309                 item = proto_tree_add_uint(parent_tree, hf_smb_share_access, tvb, offset, len, mask);
3310                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
3311
3312                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
3313                         tvb, offset, len, mask);
3314                 if(mask&SHARE_ACCESS_DELETE){
3315                         proto_item_append_text(item, " SHARE_DELETE");
3316                 }
3317
3318                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
3319                         tvb, offset, len, mask);
3320                 if(mask&SHARE_ACCESS_WRITE){
3321                         proto_item_append_text(item, " SHARE_WRITE");
3322                 }
3323
3324                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
3325                         tvb, offset, len, mask);
3326                 if(mask&SHARE_ACCESS_READ){
3327                         proto_item_append_text(item, " SHARE_READ");
3328                 }
3329         }
3330
3331         offset += len;
3332
3333         return offset;
3334 }
3335
3336 int
3337 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3338 {
3339         guint32 mask;
3340
3341         mask = tvb_get_letohl(tvb, offset);
3342
3343         offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, 4, mask);
3344
3345         return offset;
3346 }
3347
3348
3349 static int
3350 dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3351     int offset, int len, guint32 mask)
3352 {
3353         proto_item *item;
3354         proto_tree *tree;
3355
3356         if(parent_tree){
3357                 item = proto_tree_add_uint(parent_tree, hf_smb_create_options, tvb, offset, len, mask);
3358                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
3359
3360                 /*
3361                  * From
3362                  *
3363                  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3364                  */
3365                  proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
3366                         tvb, offset, len, mask);
3367                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
3368                         tvb, offset, len, mask);
3369                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
3370                         tvb, offset, len, mask);
3371                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
3372                         tvb, offset, len, mask);
3373                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
3374                         tvb, offset, len, mask);
3375                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
3376                         tvb, offset, len, mask);
3377                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
3378                         tvb, offset, len, mask);
3379                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
3380                         tvb, offset, len, mask);
3381                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
3382                         tvb, offset, len, mask);
3383                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
3384                         tvb, offset, len, mask);
3385                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
3386                         tvb, offset, len, mask);
3387                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
3388                         tvb, offset, len, mask);
3389                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
3390                         tvb, offset, len, mask);
3391                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
3392                         tvb, offset, len, mask);
3393                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
3394                         tvb, offset, len, mask);
3395                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
3396                         tvb, offset, len, mask);
3397                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
3398                         tvb, offset, len, mask);
3399                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
3400                         tvb, offset, len, mask);
3401                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
3402                         tvb, offset, len, mask);
3403                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
3404                         tvb, offset, len, mask);
3405         }
3406         offset += len;
3407
3408         return offset;
3409 }
3410
3411 int
3412 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3413 {
3414         guint32 mask;
3415
3416         mask = tvb_get_letohl(tvb, offset);
3417
3418         offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, 4, mask);
3419
3420         return offset;
3421 }
3422
3423
3424 /* fids are scoped by tcp session */
3425 smb_fid_info_t *
3426 dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3427     int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated)
3428 {
3429         smb_info_t *si = pinfo->private_data;
3430         smb_saved_info_t *sip = si->sip;
3431         proto_item *it;
3432         proto_tree *tr;
3433         smb_fid_info_t *fid_info=NULL;
3434
3435         DISSECTOR_ASSERT(si);
3436
3437         it=proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
3438         if(is_generated){
3439                 PROTO_ITEM_SET_GENERATED(it);
3440         }
3441         tr=proto_item_add_subtree(it, ett_smb_fid);
3442         if (check_col(pinfo->cinfo, COL_INFO))
3443                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
3444
3445         if((!pinfo->fd->flags.visited) && is_created){
3446                 fid_info=se_alloc(sizeof(smb_fid_info_t));
3447                 fid_info->opened_in=pinfo->fd->num;
3448                 fid_info->closed_in=0;
3449                 fid_info->type=SMB_FID_TYPE_UNKNOWN;
3450                 if(si->sip && (si->sip->extra_info_type==SMB_EI_FILEDATA)){
3451                         fid_info->fsi=si->sip->extra_info;
3452                 } else {
3453                         fid_info->fsi=NULL;
3454                 }
3455
3456                 se_tree_insert32(si->ct->fid_tree, fid, fid_info);
3457         }
3458
3459         if(!fid_info){
3460                 fid_info=se_tree_lookup32(si->ct->fid_tree, fid);
3461         }
3462         if(!fid_info){
3463                 return NULL;
3464         }
3465
3466         /* Store the fid in the transaction structure and remember if
3467            it was in the request or in the reply we saw it
3468          */
3469         if(sip && (!is_generated) && (!pinfo->fd->flags.visited)) {
3470                 sip->fid=fid;
3471                 if(si->request){
3472                         sip->fid_seen_in_request=TRUE;
3473                 } else {
3474                         sip->fid_seen_in_request=FALSE;
3475                 }
3476         }
3477
3478         if((!pinfo->fd->flags.visited) && is_closed){
3479                 fid_info->closed_in=pinfo->fd->num;
3480         }
3481
3482         if(fid_info->opened_in){
3483                 it=proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
3484                 PROTO_ITEM_SET_GENERATED(it);
3485         }
3486
3487         if(fid_info->closed_in){
3488                 it=proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
3489                 PROTO_ITEM_SET_GENERATED(it);
3490         }
3491
3492
3493         if(fid_info->opened_in){
3494                 if(fid_info->fsi && fid_info->fsi->filename){
3495                         it=proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
3496                         PROTO_ITEM_SET_GENERATED(it);
3497                         proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
3498                         dissect_nt_create_bits(tvb, tr, 0, 0, fid_info->fsi->create_flags);
3499                         dissect_smb_access_mask_bits(tvb, tr, 0, 0, fid_info->fsi->access_mask);
3500                         dissect_file_ext_attr_bits(tvb, tr, 0, 0, fid_info->fsi->file_attributes);
3501                         dissect_nt_share_access_bits(tvb, tr, 0, 0, fid_info->fsi->share_access);
3502                         dissect_nt_create_options_bits(tvb, tr, 0, 0, fid_info->fsi->create_options);
3503                         it=proto_tree_add_uint(tr, hf_smb_nt_create_disposition, tvb, 0, 0, fid_info->fsi->create_disposition);
3504                         PROTO_ITEM_SET_GENERATED(it);
3505                 }
3506         }
3507
3508         return fid_info;
3509 }
3510
3511 static int
3512 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3513 {
3514         guint8 wc;
3515         guint16 bc;
3516         guint16 fid;
3517
3518         WORD_COUNT;
3519
3520         /* fid */
3521         fid = tvb_get_letohs(tvb, offset);
3522         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3523         offset += 2;
3524
3525         /* File Attributes */
3526         offset = dissect_file_attributes(tvb, tree, offset, 2);
3527
3528         /* last write time */
3529         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3530
3531         /* File Size */
3532         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3533         offset += 4;
3534
3535         /* granted access */
3536         offset = dissect_access(tvb, tree, offset, "Granted");
3537
3538         BYTE_COUNT;
3539
3540         END_OF_SMB
3541
3542         return offset;
3543 }
3544
3545 static int
3546 dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3547 {
3548         guint8 wc;
3549         guint16 bc;
3550         guint16 fid;
3551
3552         WORD_COUNT;
3553
3554         /* fid */
3555         fid = tvb_get_letohs(tvb, offset);
3556         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3557         offset += 2;
3558
3559         BYTE_COUNT;
3560
3561         END_OF_SMB
3562
3563         return offset;
3564 }
3565
3566 static int
3567 dissect_close_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3568 {
3569         guint8 wc;
3570         guint16 bc;
3571         guint16 fid;
3572
3573         WORD_COUNT;
3574
3575         /* fid */
3576         fid = tvb_get_letohs(tvb, offset);
3577         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3578         offset += 2;
3579
3580         BYTE_COUNT;
3581
3582         END_OF_SMB
3583
3584         return offset;
3585 }
3586
3587 static int
3588 dissect_open_print_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3589 {
3590         guint8 wc;
3591         guint16 bc;
3592         guint16 fid;
3593
3594         WORD_COUNT;
3595
3596         /* fid */
3597         fid = tvb_get_letohs(tvb, offset);
3598         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3599         offset += 2;
3600
3601         BYTE_COUNT;
3602
3603         END_OF_SMB
3604
3605         return offset;
3606 }
3607
3608 static int
3609 dissect_create_new_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3610 {
3611         guint8 wc;
3612         guint16 bc;
3613         guint16 fid;
3614
3615         WORD_COUNT;
3616
3617         /* fid */
3618         fid = tvb_get_letohs(tvb, offset);
3619         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3620         offset += 2;
3621
3622         BYTE_COUNT;
3623
3624         END_OF_SMB
3625
3626         return offset;
3627 }
3628
3629 static int
3630 dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3631 {
3632         guint8 wc;
3633         guint16 bc;
3634         guint16 fid;
3635
3636         WORD_COUNT;
3637
3638         /* fid */
3639         fid = tvb_get_letohs(tvb, offset);
3640         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
3641         offset += 2;
3642
3643         BYTE_COUNT;
3644
3645         END_OF_SMB
3646
3647         return offset;
3648 }
3649
3650 static int
3651 dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3652 {
3653         guint8 wc;
3654         guint16 bc;
3655         guint16 fid;
3656
3657         WORD_COUNT;
3658
3659         /* fid */
3660         fid = tvb_get_letohs(tvb, offset);
3661         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
3662         offset += 2;
3663
3664         BYTE_COUNT;
3665
3666         END_OF_SMB
3667
3668         return offset;
3669 }
3670
3671 static int
3672 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3673 {
3674         smb_info_t *si = pinfo->private_data;
3675         int fn_len;
3676         const char *fn;
3677         guint8 wc;
3678         guint16 bc;
3679
3680         DISSECTOR_ASSERT(si);
3681
3682         WORD_COUNT;
3683
3684         /* file attributes */
3685         offset = dissect_file_attributes(tvb, tree, offset, 2);
3686
3687         /* creation time */
3688         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3689
3690         BYTE_COUNT;
3691
3692         /* buffer format */
3693         CHECK_BYTE_COUNT(1);
3694         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3695         COUNT_BYTES(1);
3696
3697         /* File Name */
3698         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3699                 FALSE, FALSE, &bc);
3700         if (fn == NULL)
3701                 goto endofcommand;
3702         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3703                 fn);
3704         COUNT_BYTES(fn_len);
3705
3706         if (check_col(pinfo->cinfo, COL_INFO)) {
3707                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3708                     format_text(fn, strlen(fn)));
3709         }
3710
3711         END_OF_SMB
3712
3713         return offset;
3714 }
3715
3716 static int
3717 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3718 {
3719         guint8 wc;
3720         guint16 bc, fid;
3721
3722         WORD_COUNT;
3723
3724         /* fid */
3725         fid = tvb_get_letohs(tvb, offset);
3726         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
3727         offset += 2;
3728
3729         /* last write time */
3730         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3731
3732         BYTE_COUNT;
3733
3734         END_OF_SMB
3735
3736         return offset;
3737 }
3738
3739 static int
3740 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3741 {
3742         smb_info_t *si = pinfo->private_data;
3743         int fn_len;
3744         const char *fn;
3745         guint8 wc;
3746         guint16 bc;
3747
3748         DISSECTOR_ASSERT(si);
3749
3750         WORD_COUNT;
3751
3752         /* search attributes */
3753         offset = dissect_search_attributes(tvb, tree, offset);
3754
3755         BYTE_COUNT;
3756
3757         /* buffer format */
3758         CHECK_BYTE_COUNT(1);
3759         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3760         COUNT_BYTES(1);
3761
3762         /* file name */
3763         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3764                 FALSE, FALSE, &bc);
3765
3766         if(si->sip){
3767                 si->sip->extra_info_type=SMB_EI_FILENAME;
3768                 si->sip->extra_info=se_strdup(fn);
3769         }
3770
3771         if (fn == NULL)
3772                 goto endofcommand;
3773         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3774                 fn);
3775         COUNT_BYTES(fn_len);
3776
3777         if (check_col(pinfo->cinfo, COL_INFO)) {
3778                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3779                     format_text(fn, strlen(fn)));
3780         }
3781
3782         END_OF_SMB
3783
3784         return offset;
3785 }
3786
3787 static int
3788 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3789 {
3790         smb_info_t *si = pinfo->private_data;
3791         int fn_len;
3792         const char *fn, *old_name=NULL, *new_name=NULL;
3793         guint8 wc;
3794         guint16 bc;
3795         smb_rename_saved_info_t *rni=NULL;
3796
3797         DISSECTOR_ASSERT(si);
3798
3799         WORD_COUNT;
3800
3801         /* search attributes */
3802         offset = dissect_search_attributes(tvb, tree, offset);
3803
3804         BYTE_COUNT;
3805
3806         /* buffer format */
3807         CHECK_BYTE_COUNT(1);
3808         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3809         COUNT_BYTES(1);
3810
3811         /* old file name */
3812         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3813                 FALSE, FALSE, &bc);
3814         if (fn == NULL)
3815                 goto endofcommand;
3816         old_name=fn;
3817         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3818                 fn);
3819         COUNT_BYTES(fn_len);
3820
3821         if (check_col(pinfo->cinfo, COL_INFO)) {
3822                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3823                     format_text(fn, strlen(fn)));
3824         }
3825
3826         /* buffer format */
3827         CHECK_BYTE_COUNT(1);
3828         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3829         COUNT_BYTES(1);
3830
3831         /* file name */
3832         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3833                 FALSE, FALSE, &bc);
3834         if (fn == NULL)
3835                 goto endofcommand;
3836         new_name=fn;
3837         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3838                 fn);
3839         COUNT_BYTES(fn_len);
3840
3841         if (check_col(pinfo->cinfo, COL_INFO)) {
3842                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3843                     format_text(fn, strlen(fn)));
3844         }
3845
3846         END_OF_SMB
3847
3848         /* save the offset/len for this transaction */
3849         if(si->sip && !pinfo->fd->flags.visited){
3850                 rni=se_alloc(sizeof(smb_rename_saved_info_t));
3851                 rni->old_name=se_strdup(old_name);
3852                 rni->new_name=se_strdup(new_name);
3853
3854                 si->sip->extra_info_type=SMB_EI_RENAMEDATA;
3855                 si->sip->extra_info=rni;
3856         }
3857
3858         return offset;
3859 }
3860
3861 static int
3862 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3863 {
3864         smb_info_t *si = pinfo->private_data;
3865         int fn_len;
3866         const char *fn;
3867         guint8 wc;
3868         guint16 bc;
3869
3870         DISSECTOR_ASSERT(si);
3871
3872         WORD_COUNT;
3873
3874         /* search attributes */
3875         offset = dissect_search_attributes(tvb, tree, offset);
3876
3877         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3878         offset += 2;
3879
3880         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3881         offset += 4;
3882
3883         BYTE_COUNT;
3884
3885         /* buffer format */
3886         CHECK_BYTE_COUNT(1);
3887         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3888         COUNT_BYTES(1);
3889
3890         /* old file name */
3891         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3892                 FALSE, FALSE, &bc);
3893         if (fn == NULL)
3894                 goto endofcommand;
3895         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3896                 fn);
3897         COUNT_BYTES(fn_len);
3898
3899         if (check_col(pinfo->cinfo, COL_INFO)) {
3900                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3901                     format_text(fn, strlen(fn)));
3902         }
3903
3904         /* buffer format */
3905         CHECK_BYTE_COUNT(1);
3906         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3907         COUNT_BYTES(1);
3908
3909         /* file name */
3910         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3911                 FALSE, FALSE, &bc);
3912         if (fn == NULL)
3913                 goto endofcommand;
3914         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3915                 fn);
3916         COUNT_BYTES(fn_len);
3917
3918         if (check_col(pinfo->cinfo, COL_INFO)) {
3919                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3920                     format_text(fn, strlen(fn)));
3921         }
3922
3923         END_OF_SMB
3924
3925         return offset;
3926 }
3927
3928
3929 static int
3930 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3931 {
3932         smb_info_t *si = pinfo->private_data;
3933         guint16 bc;
3934         guint8 wc;
3935         const char *fn;
3936         int fn_len;
3937
3938         DISSECTOR_ASSERT(si);
3939
3940         WORD_COUNT;
3941
3942         BYTE_COUNT;
3943
3944         /* Buffer Format */
3945         CHECK_BYTE_COUNT(1);
3946         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3947         COUNT_BYTES(1);
3948
3949         /* File Name */
3950         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3951                 FALSE, FALSE, &bc);
3952         if (fn == NULL)
3953                 goto endofcommand;
3954         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3955                 fn);
3956         COUNT_BYTES(fn_len);
3957
3958         if (check_col(pinfo->cinfo, COL_INFO)) {
3959                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3960                     format_text(fn, strlen(fn)));
3961         }
3962
3963         END_OF_SMB
3964
3965         return offset;
3966 }
3967
3968 static int
3969 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3970 {
3971         guint16 bc;
3972         guint8 wc;
3973
3974         WORD_COUNT;
3975
3976         /* File Attributes */
3977         offset = dissect_file_attributes(tvb, tree, offset, 2);
3978
3979         /* Last Write Time */
3980         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3981
3982         /* File Size */
3983         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3984         offset += 4;
3985
3986         /* 10 reserved bytes */
3987         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3988         offset += 10;
3989
3990         BYTE_COUNT;
3991
3992         END_OF_SMB
3993
3994         return offset;
3995 }
3996
3997 static int
3998 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3999 {
4000         smb_info_t *si = pinfo->private_data;
4001         int fn_len;
4002         const char *fn;
4003         guint8 wc;
4004         guint16 bc;
4005
4006         DISSECTOR_ASSERT(si);
4007
4008         WORD_COUNT;
4009
4010         /* file attributes */
4011         offset = dissect_file_attributes(tvb, tree, offset, 2);
4012
4013         /* last write time */
4014         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4015
4016         /* 10 reserved bytes */
4017         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
4018         offset += 10;
4019
4020         BYTE_COUNT;
4021
4022         /* buffer format */
4023         CHECK_BYTE_COUNT(1);
4024         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4025         COUNT_BYTES(1);
4026
4027         /* file name */
4028         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4029                 FALSE, FALSE, &bc);
4030         if (fn == NULL)
4031                 goto endofcommand;
4032         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4033                 fn);
4034         COUNT_BYTES(fn_len);
4035
4036         if (check_col(pinfo->cinfo, COL_INFO)) {
4037                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4038                     format_text(fn, strlen(fn)));
4039         }
4040
4041         END_OF_SMB
4042
4043         return offset;
4044 }
4045
4046 static int
4047 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4048 {
4049         guint8 wc;
4050         guint16 cnt=0, bc;
4051         guint32 ofs=0;
4052         unsigned int fid;
4053
4054         WORD_COUNT;
4055
4056         /* fid */
4057         fid = tvb_get_letohs(tvb, offset);
4058         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
4059         offset += 2;
4060
4061         /* read count */
4062         cnt = tvb_get_letohs(tvb, offset);
4063         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4064         offset += 2;
4065
4066         /* offset */
4067         ofs = tvb_get_letohl(tvb, offset);
4068         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4069         offset += 4;
4070
4071         if (check_col(pinfo->cinfo, COL_INFO))
4072                 col_append_fstr(pinfo->cinfo, COL_INFO,
4073                                 ", %u byte%s at offset %u", cnt,
4074                                 (cnt == 1) ? "" : "s", ofs);
4075
4076         /* remaining */
4077         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4078         offset += 2;
4079
4080         BYTE_COUNT;
4081
4082         END_OF_SMB
4083
4084         return offset;
4085 }
4086
4087 int
4088 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
4089 {
4090         int tvblen;
4091
4092         if(bc>datalen){
4093                 /* We have some initial padding bytes. */
4094                 /* XXX - use the data offset here instead? */
4095                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4096                         TRUE);
4097                 offset += bc-datalen;
4098                 bc = datalen;
4099         }
4100         tvblen = tvb_length_remaining(tvb, offset);
4101         if(bc>tvblen){
4102                 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);
4103                 offset += tvblen;
4104         } else {
4105                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
4106                 offset += bc;
4107         }
4108         return offset;
4109 }
4110
4111 static int
4112 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4113     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
4114 {
4115         int tvblen;
4116         tvbuff_t *dcerpc_tvb;
4117
4118         if(bc>datalen){
4119                 /* We have some initial padding bytes. */
4120                 /* XXX - use the data offset here instead? */
4121                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4122                         TRUE);
4123                 offset += bc-datalen;
4124                 bc = datalen;
4125         }
4126         tvblen = tvb_length_remaining(tvb, offset);
4127         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
4128         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
4129         if(bc>tvblen)
4130                 offset += tvblen;
4131         else
4132                 offset += bc;
4133         return offset;
4134 }
4135
4136 /*
4137  * transporting DCERPC over SMB seems to be implemented in various
4138  * ways. We might just assume it can be done by an almost random
4139  * mix of Trans/Read/Write calls
4140  *
4141  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
4142  * and let him sort them out
4143  */
4144 static int
4145 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
4146     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
4147     guint16 datalen, guint32 ofs, guint16 fid)
4148 {
4149         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4150
4151         DISSECTOR_ASSERT(si);
4152
4153         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
4154                 /* dcerpc call */
4155                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
4156                     top_tree, offset, bc, datalen, fid);
4157         } else {
4158                 /* ordinary file data */
4159                 return dissect_file_data(tvb, tree, offset, bc, datalen);
4160         }
4161 }
4162
4163 static int
4164 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4165 {
4166         guint16 cnt=0, bc;
4167         guint8 wc;
4168         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4169         int fid=0;
4170
4171         DISSECTOR_ASSERT(si);
4172
4173         WORD_COUNT;
4174
4175         /* read count */
4176         cnt = tvb_get_letohs(tvb, offset);
4177         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4178         offset += 2;
4179
4180         /* 8 reserved bytes */
4181         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4182         offset += 8;
4183         BYTE_COUNT;
4184
4185         /* buffer format */
4186         CHECK_BYTE_COUNT(1);
4187         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4188         COUNT_BYTES(1);
4189
4190         /* data len */
4191         CHECK_BYTE_COUNT(2);
4192         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4193         COUNT_BYTES(2);
4194
4195         /* file data, might be DCERPC on a pipe */
4196         if(bc){
4197                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4198                     top_tree, offset, bc, bc, 0, (guint16) fid);
4199                 bc = 0;
4200         }
4201
4202         END_OF_SMB
4203
4204         return offset;
4205 }
4206
4207 static int
4208 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4209 {
4210         guint16 cnt, bc;
4211         guint8 wc;
4212
4213         WORD_COUNT;
4214
4215         /* read count */
4216         cnt = tvb_get_letohs(tvb, offset);
4217         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4218         offset += 2;
4219
4220         /* 8 reserved bytes */
4221         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4222         offset += 8;
4223
4224         BYTE_COUNT;
4225
4226         /* buffer format */
4227         CHECK_BYTE_COUNT(1);
4228         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4229         COUNT_BYTES(1);
4230
4231         /* data len */
4232         CHECK_BYTE_COUNT(2);
4233         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4234         COUNT_BYTES(2);
4235
4236         END_OF_SMB
4237
4238         return offset;
4239 }
4240
4241 typedef struct _rw_info_t {
4242         guint32 offset;
4243         guint32 len;
4244         guint16 fid;
4245 } rw_info_t;
4246
4247
4248 static int
4249 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4250 {
4251         guint32 ofs=0;
4252         guint16 cnt=0, bc, fid=0;
4253         guint8 wc;
4254         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4255         rw_info_t *rwi=NULL;
4256
4257         DISSECTOR_ASSERT(si);
4258
4259         WORD_COUNT;
4260
4261         /* fid */
4262         fid = tvb_get_letohs(tvb, offset);
4263         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4264         offset += 2;
4265
4266         /* write count */
4267         cnt = tvb_get_letohs(tvb, offset);
4268         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4269         offset += 2;
4270
4271         /* offset */
4272         ofs = tvb_get_letohl(tvb, offset);
4273         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4274         offset += 4;
4275
4276         if (check_col(pinfo->cinfo, COL_INFO))
4277                 col_append_fstr(pinfo->cinfo, COL_INFO,
4278                                 ", %u byte%s at offset %u", cnt,
4279                                 (cnt == 1) ? "" : "s", ofs);
4280
4281         /* save the offset/len for this transaction */
4282         if(si->sip && !pinfo->fd->flags.visited){
4283                 rwi=se_alloc(sizeof(rw_info_t));
4284                 rwi->offset=ofs;
4285                 rwi->len=cnt;
4286                 rwi->fid=fid;
4287
4288                 si->sip->extra_info_type=SMB_EI_RWINFO;
4289                 si->sip->extra_info=rwi;
4290         }
4291         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
4292                 rwi=si->sip->extra_info;
4293         }
4294         if(rwi){
4295                 proto_item *it;
4296
4297                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4298
4299                 PROTO_ITEM_SET_GENERATED(it);
4300                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4301                 PROTO_ITEM_SET_GENERATED(it);
4302         }
4303
4304         /* remaining */
4305         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4306         offset += 2;
4307
4308         BYTE_COUNT;
4309
4310         /* buffer format */
4311         CHECK_BYTE_COUNT(1);
4312         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4313         COUNT_BYTES(1);
4314
4315         /* data len */
4316         CHECK_BYTE_COUNT(2);
4317         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4318         COUNT_BYTES(2);
4319
4320         /* file data, might be DCERPC on a pipe */
4321         if (bc != 0) {
4322                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4323                     top_tree, offset, bc, bc, ofs, fid);
4324                 bc = 0;
4325         }
4326
4327         END_OF_SMB
4328
4329         return offset;
4330 }
4331
4332 static int
4333 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4334 {
4335         guint8 wc;
4336         guint16 bc, cnt;
4337         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4338         rw_info_t *rwi=NULL;
4339
4340         DISSECTOR_ASSERT(si);
4341
4342         WORD_COUNT;
4343
4344         /* write count */
4345         cnt = tvb_get_letohs(tvb, offset);
4346         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4347         offset += 2;
4348
4349         if (check_col(pinfo->cinfo, COL_INFO))
4350                 col_append_fstr(pinfo->cinfo, COL_INFO,
4351                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
4352
4353         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
4354                 rwi=si->sip->extra_info;
4355         }
4356         if(rwi){
4357                 proto_item *it;
4358
4359                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4360
4361                 PROTO_ITEM_SET_GENERATED(it);
4362                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4363                 PROTO_ITEM_SET_GENERATED(it);
4364         }
4365
4366         BYTE_COUNT;
4367
4368         END_OF_SMB
4369
4370         return offset;
4371 }
4372
4373 static int
4374 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4375 {
4376         guint8 wc;
4377         guint16 bc, fid;
4378
4379         WORD_COUNT;
4380
4381         /* fid */
4382         fid = tvb_get_letohs(tvb, offset);
4383         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4384         offset += 2;
4385
4386         /* lock count */
4387         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
4388         offset += 4;
4389
4390         /* offset */
4391         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4392         offset += 4;
4393
4394         BYTE_COUNT;
4395
4396         END_OF_SMB
4397
4398         return offset;
4399 }
4400
4401 static int
4402 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4403 {
4404         smb_info_t *si = pinfo->private_data;
4405         int fn_len;
4406         const char *fn;
4407         guint8 wc;
4408         guint16 bc;
4409
4410         DISSECTOR_ASSERT(si);
4411
4412         WORD_COUNT;
4413
4414         /* 2 reserved bytes */
4415         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4416         offset += 2;
4417
4418         /* Creation time */
4419         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4420
4421         BYTE_COUNT;
4422
4423         /* buffer format */
4424         CHECK_BYTE_COUNT(1);
4425         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4426         COUNT_BYTES(1);
4427
4428         /* directory name */
4429         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4430                 FALSE, FALSE, &bc);
4431         if (fn == NULL)
4432                 goto endofcommand;
4433         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
4434                 fn);
4435         COUNT_BYTES(fn_len);
4436
4437         if (check_col(pinfo->cinfo, COL_INFO)) {
4438                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4439                     format_text(fn, strlen(fn)));
4440         }
4441
4442         END_OF_SMB
4443
4444         return offset;
4445 }
4446
4447 static int
4448 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4449 {
4450         smb_info_t *si = pinfo->private_data;
4451         int fn_len;
4452         const char *fn;
4453         guint8 wc;
4454         guint16 bc, fid;
4455
4456         DISSECTOR_ASSERT(si);
4457
4458         WORD_COUNT;
4459
4460         /* fid */
4461         fid = tvb_get_letohs(tvb, offset);
4462         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
4463         offset += 2;
4464
4465         BYTE_COUNT;
4466
4467         /* buffer format */
4468         CHECK_BYTE_COUNT(1);
4469         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4470         COUNT_BYTES(1);
4471
4472         /* file name */
4473         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4474                 FALSE, FALSE, &bc);
4475         if (fn == NULL)
4476                 goto endofcommand;
4477         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4478                 fn);
4479         COUNT_BYTES(fn_len);
4480
4481         END_OF_SMB
4482
4483         return offset;
4484 }
4485
4486 static const value_string seek_mode_vals[] = {
4487         {0,     "From Start Of File"},
4488         {1,     "From Current Position"},
4489         {2,     "From End Of File"},
4490         {0,     NULL}
4491 };
4492
4493 static int
4494 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4495 {
4496         guint8 wc;
4497         guint16 bc, fid;
4498
4499         WORD_COUNT;
4500
4501         /* fid */
4502         fid = tvb_get_letohs(tvb, offset);
4503         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4504         offset += 2;
4505
4506         /* Seek Mode */
4507         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
4508         offset += 2;
4509
4510         /* offset */
4511         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4512         offset += 4;
4513
4514         BYTE_COUNT;
4515
4516         END_OF_SMB
4517
4518         return offset;
4519 }
4520
4521 static int
4522 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4523 {
4524         guint8 wc;
4525         guint16 bc;
4526
4527         WORD_COUNT;
4528
4529         /* offset */
4530         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4531         offset += 4;
4532
4533         BYTE_COUNT;
4534
4535         END_OF_SMB
4536
4537         return offset;
4538 }
4539
4540 static int
4541 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4542 {
4543         guint8 wc;
4544         guint16 bc, fid;
4545
4546         WORD_COUNT;
4547
4548         /* fid */
4549         fid = tvb_get_letohs(tvb, offset);
4550         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4551         offset += 2;
4552
4553         /* create time */
4554         offset = dissect_smb_datetime(tvb, tree, offset,
4555                 hf_smb_create_time,
4556                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4557
4558         /* access time */
4559         offset = dissect_smb_datetime(tvb, tree, offset,
4560                 hf_smb_access_time,
4561                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4562
4563         /* last write time */
4564         offset = dissect_smb_datetime(tvb, tree, offset,
4565                 hf_smb_last_write_time,
4566                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4567
4568         BYTE_COUNT;
4569
4570         END_OF_SMB
4571
4572         return offset;
4573 }
4574
4575 static int
4576 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4577 {
4578         guint8 wc;
4579         guint16 bc;
4580
4581         WORD_COUNT;
4582
4583         /* create time */
4584         offset = dissect_smb_datetime(tvb, tree, offset,
4585                 hf_smb_create_time,
4586                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4587
4588         /* access time */
4589         offset = dissect_smb_datetime(tvb, tree, offset,
4590                 hf_smb_access_time,
4591                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4592
4593         /* last write time */
4594         offset = dissect_smb_datetime(tvb, tree, offset,
4595                 hf_smb_last_write_time,
4596                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4597
4598         /* data size */
4599         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
4600         offset += 4;
4601
4602         /* allocation size */
4603         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4604         offset += 4;
4605
4606         /* File Attributes */
4607         offset = dissect_file_attributes(tvb, tree, offset, 2);
4608
4609         BYTE_COUNT;
4610
4611         END_OF_SMB
4612
4613         return offset;
4614 }
4615
4616 static int
4617 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4618 {
4619         guint8 wc;
4620         guint16 cnt=0;
4621         guint16 bc, fid;
4622
4623         WORD_COUNT;
4624
4625         /* fid */
4626         fid = tvb_get_letohs(tvb, offset);
4627         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
4628         offset += 2;
4629
4630         /* write count */
4631         cnt = tvb_get_letohs(tvb, offset);
4632         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4633         offset += 2;
4634
4635         /* offset */
4636         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4637         offset += 4;
4638
4639         /* last write time */
4640         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4641
4642         if(wc==12){
4643                 /* 12 reserved bytes */
4644                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
4645                 offset += 12;
4646         }
4647
4648         BYTE_COUNT;
4649
4650         /* 1 pad byte */
4651         CHECK_BYTE_COUNT(1);
4652         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
4653         COUNT_BYTES(1);
4654
4655         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
4656         bc = 0; /* XXX */
4657
4658         END_OF_SMB
4659
4660         return offset;
4661 }
4662
4663 static int
4664 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4665 {
4666         guint8 wc;
4667         guint16 bc;
4668
4669         WORD_COUNT;
4670
4671         /* write count */
4672         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4673         offset += 2;
4674
4675         BYTE_COUNT;
4676
4677         END_OF_SMB
4678
4679         return offset;
4680 }
4681
4682 /* Timeout is defined on page 117 of SMB Protocol Extensions version 2.0
4683    available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
4684 */
4685 static gchar *
4686 smbext20_timeout_msecs_to_str(gint32 time)
4687 {
4688         gchar *buf;
4689 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
4690
4691         if (time <= 0) {
4692                 buf=ep_alloc(SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
4693                 if (time == 0) {
4694                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
4695                 } else if (time == -1) {
4696                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
4697                 } else if (time == -2) {
4698                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
4699                 } else {
4700                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", time);
4701                 }
4702                 return buf;
4703         }
4704
4705         return time_msecs_to_str(time);
4706 }
4707
4708 static int
4709 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4710 {
4711         guint8 wc;
4712         guint16 bc, fid;
4713         guint32 to;
4714
4715         WORD_COUNT;
4716
4717         /* fid */
4718         fid = tvb_get_letohs(tvb, offset);
4719         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4720         offset += 2;
4721
4722         /* offset */
4723         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4724         offset += 4;
4725
4726         /* max count */
4727         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4728         offset += 2;
4729
4730         /* min count */
4731         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4732         offset += 2;
4733
4734         /* timeout */
4735         to = tvb_get_letohl(tvb, offset);
4736         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4737         offset += 4;
4738
4739         /* 2 reserved bytes */
4740         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4741         offset += 2;
4742
4743         if(wc==10){
4744                 /* high offset */
4745                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4746                 offset += 4;
4747         }
4748
4749         BYTE_COUNT;
4750
4751         END_OF_SMB
4752
4753         return offset;
4754 }
4755
4756 static int
4757 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4758 {
4759         guint8 wc;
4760         guint16 bc;
4761
4762         WORD_COUNT;
4763
4764         /* units */
4765         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
4766         offset += 2;
4767
4768         /* bpu */
4769         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
4770         offset += 2;
4771
4772         /* block size */
4773         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
4774         offset += 2;
4775
4776         /* free units */
4777         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
4778         offset += 2;
4779
4780         /* 2 reserved bytes */
4781         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4782         offset += 2;
4783
4784         BYTE_COUNT;
4785
4786         END_OF_SMB
4787
4788         return offset;
4789 }
4790
4791 static int
4792 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4793 {
4794         guint8 wc;
4795         guint16 bc, fid;
4796
4797         WORD_COUNT;
4798
4799         /* fid */
4800         fid = tvb_get_letohs(tvb, offset);
4801         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4802         offset += 2;
4803
4804         /* offset */
4805         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4806         offset += 4;
4807
4808         /* max count */
4809         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4810         offset += 2;
4811
4812         /* min count */
4813         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4814         offset += 2;
4815
4816         /* 6 reserved bytes */
4817         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4818         offset += 6;
4819
4820         BYTE_COUNT;
4821
4822         END_OF_SMB
4823
4824         return offset;
4825 }
4826
4827 static int
4828 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4829 {
4830         guint16 datalen=0, bc;
4831         guint8 wc;
4832
4833         WORD_COUNT;
4834
4835         /* offset */
4836         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4837         offset += 4;
4838
4839         /* count */
4840         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4841         offset += 2;
4842
4843         /* 2 reserved bytes */
4844         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4845         offset += 2;
4846
4847         /* data compaction mode */
4848         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4849         offset += 2;
4850
4851         /* 2 reserved bytes */
4852         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4853         offset += 2;
4854
4855         /* data len */
4856         datalen = tvb_get_letohs(tvb, offset);
4857         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4858         offset += 2;
4859
4860         /* data offset */
4861         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4862         offset += 2;
4863
4864         BYTE_COUNT;
4865
4866         /* file data */
4867         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4868         bc = 0;
4869
4870         END_OF_SMB
4871
4872         return offset;
4873 }
4874
4875
4876 static const true_false_string tfs_write_mode_write_through = {
4877         "WRITE THROUGH requested",
4878         "Write through not requested"
4879 };
4880 static const true_false_string tfs_write_mode_return_remaining = {
4881         "RETURN REMAINING (pipe/dev) requested",
4882         "DON'T return remaining (pipe/dev)"
4883 };
4884 static const true_false_string tfs_write_mode_raw = {
4885         "Use WriteRawNamedPipe (pipe)",
4886         "DON'T use WriteRawNamedPipe (pipe)"
4887 };
4888 static const true_false_string tfs_write_mode_message_start = {
4889         "This is the START of a MESSAGE (pipe)",
4890         "This is NOT the start of a message (pipe)"
4891 };
4892 static const true_false_string tfs_write_mode_connectionless = {
4893         "CONNECTIONLESS mode requested",
4894         "Connectionless mode NOT requested"
4895 };
4896
4897 #define WRITE_MODE_CONNECTIONLESS       0x0080
4898 #define WRITE_MODE_MESSAGE_START        0x0008
4899 #define WRITE_MODE_RAW                  0x0004
4900 #define WRITE_MODE_RETURN_REMAINING     0x0002
4901 #define WRITE_MODE_WRITE_THROUGH        0x0001
4902
4903 static int
4904 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4905 {
4906         guint16 mask;
4907         proto_item *item;
4908         proto_tree *tree;
4909
4910         mask = tvb_get_letohs(tvb, offset);
4911
4912         if(parent_tree){
4913                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4914                         "Write Mode: 0x%04x", mask);
4915                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4916
4917                 if(bm&WRITE_MODE_CONNECTIONLESS){
4918                         proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4919                                 tvb, offset, 2, mask);
4920                 }
4921                 if(bm&WRITE_MODE_MESSAGE_START){
4922                         proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4923                                 tvb, offset, 2, mask);
4924                                 }
4925                 if(bm&WRITE_MODE_RAW){
4926                         proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4927                                 tvb, offset, 2, mask);
4928                 }
4929                 if(bm&WRITE_MODE_RETURN_REMAINING){
4930                         proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4931                                 tvb, offset, 2, mask);
4932                 }
4933                 if(bm&WRITE_MODE_WRITE_THROUGH){
4934                         proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4935                                 tvb, offset, 2, mask);
4936                 }
4937         }
4938
4939         offset += 2;
4940         return offset;
4941 }
4942
4943 static int
4944 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4945 {
4946         guint32 to;
4947         guint16 datalen=0, bc, fid;
4948         guint8 wc;
4949
4950         WORD_COUNT;
4951
4952         /* fid */
4953         fid = tvb_get_letohs(tvb, offset);
4954         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
4955         offset += 2;
4956
4957         /* total data length */
4958         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4959         offset += 2;
4960
4961         /* 2 reserved bytes */
4962         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4963         offset += 2;
4964
4965         /* offset */
4966         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4967         offset += 4;
4968
4969         /* timeout */
4970         to = tvb_get_letohl(tvb, offset);
4971         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
4972         offset += 4;
4973
4974         /* mode */
4975         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4976
4977         /* 4 reserved bytes */
4978         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4979         offset += 4;
4980
4981         /* data len */
4982         datalen = tvb_get_letohs(tvb, offset);
4983         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4984         offset += 2;
4985
4986         /* data offset */
4987         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4988         offset += 2;
4989
4990         BYTE_COUNT;
4991
4992         /* file data */
4993         /* XXX - use the data offset to determine where the data starts? */
4994         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4995         bc = 0;
4996
4997         END_OF_SMB
4998
4999         return offset;
5000 }
5001
5002 static int
5003 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5004 {
5005         guint8 wc;
5006         guint16 bc;
5007
5008         WORD_COUNT;
5009
5010         /* remaining */
5011         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5012         offset += 2;
5013
5014         BYTE_COUNT;
5015
5016         END_OF_SMB
5017
5018         return offset;
5019 }
5020
5021 static int
5022 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5023 {
5024         guint32 to;
5025         guint16 datalen=0, bc, fid;
5026         guint8 wc;
5027
5028         WORD_COUNT;
5029
5030         /* fid */
5031         fid = tvb_get_letohs(tvb, offset);
5032         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
5033         offset += 2;
5034
5035         /* total data length */
5036         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
5037         offset += 2;
5038
5039         /* 2 reserved bytes */
5040         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5041         offset += 2;
5042
5043         /* offset */
5044         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5045         offset += 4;
5046
5047         /* timeout */
5048         to = tvb_get_letohl(tvb, offset);
5049         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5050         offset += 4;
5051
5052         /* mode */
5053         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
5054
5055         /* request mask */
5056         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
5057         offset += 4;
5058
5059         /* data len */
5060         datalen = tvb_get_letohs(tvb, offset);
5061         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5062         offset += 2;
5063
5064         /* data offset */
5065         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
5066         offset += 2;
5067
5068         BYTE_COUNT;
5069
5070         /* file data */
5071         /* XXX - use the data offset to determine where the data starts? */
5072         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5073         bc = 0;
5074
5075         END_OF_SMB
5076
5077         return offset;
5078 }
5079
5080 static int
5081 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5082 {
5083         guint8 wc;
5084         guint16 bc;
5085
5086         WORD_COUNT;
5087
5088         /* response mask */
5089         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
5090         offset += 4;
5091
5092         BYTE_COUNT;
5093
5094         END_OF_SMB
5095
5096         return offset;
5097 }
5098
5099 static int
5100 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5101 {
5102         guint8 wc;
5103         guint16 bc;
5104
5105         WORD_COUNT;
5106
5107         /* sid */
5108         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
5109         offset += 2;
5110
5111         BYTE_COUNT;
5112
5113         END_OF_SMB
5114
5115         return offset;
5116 }
5117
5118 static int
5119 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
5120     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5121     gboolean has_find_id)
5122 {
5123         proto_item *item = NULL;
5124         proto_tree *tree = NULL;
5125         smb_info_t *si = pinfo->private_data;
5126         int fn_len;
5127         const char *fn;
5128         char fname[11+1];
5129
5130         DISSECTOR_ASSERT(si);
5131
5132         if(parent_tree){
5133                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
5134                         "Resume Key");
5135                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
5136         }
5137
5138         /* reserved byte */
5139         CHECK_BYTE_COUNT_SUBR(1);
5140         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5141         COUNT_BYTES_SUBR(1);
5142
5143         /* file name */
5144         fn_len = 11;
5145         fn = get_unicode_or_ascii_string(tvb, &offset, FALSE/*never Unicode*/, &fn_len,
5146                 TRUE, TRUE, bcp);
5147         CHECK_STRING_SUBR(fn);
5148         /* ensure that it's null-terminated */
5149         g_strlcpy(fname, fn, 11+1);
5150         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
5151                 fname);
5152         COUNT_BYTES_SUBR(fn_len);
5153
5154         if (has_find_id) {
5155                 CHECK_BYTE_COUNT_SUBR(1);
5156                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
5157                 COUNT_BYTES_SUBR(1);
5158
5159                 /* server cookie */
5160                 CHECK_BYTE_COUNT_SUBR(4);
5161                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
5162                 COUNT_BYTES_SUBR(4);
5163         } else {
5164                 /* server cookie */
5165                 CHECK_BYTE_COUNT_SUBR(5);
5166                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
5167                 COUNT_BYTES_SUBR(5);
5168         }
5169
5170         /* client cookie */
5171         CHECK_BYTE_COUNT_SUBR(4);
5172         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
5173         COUNT_BYTES_SUBR(4);
5174
5175         *trunc = FALSE;
5176         return offset;
5177 }
5178
5179 static int
5180 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
5181     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5182     gboolean has_find_id)
5183 {
5184         proto_item *item = NULL;
5185         proto_tree *tree = NULL;
5186         smb_info_t *si = pinfo->private_data;
5187         int fn_len;
5188         const char *fn;
5189         char fname[13+1];
5190
5191         DISSECTOR_ASSERT(si);
5192
5193         if(parent_tree){
5194                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
5195                         "Directory Information");
5196                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
5197         }
5198
5199         /* resume key */
5200         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
5201             trunc, has_find_id);
5202         if (*trunc)
5203                 return offset;
5204
5205         /* File Attributes */
5206         CHECK_BYTE_COUNT_SUBR(1);
5207         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
5208         *bcp -= 1;
5209
5210         /* last write time */
5211         CHECK_BYTE_COUNT_SUBR(4);
5212         offset = dissect_smb_datetime(tvb, tree, offset,
5213                 hf_smb_last_write_time,
5214                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
5215                 TRUE);
5216         *bcp -= 4;
5217
5218         /* File Size */
5219         CHECK_BYTE_COUNT_SUBR(4);
5220         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5221         COUNT_BYTES_SUBR(4);
5222
5223         /* file name */
5224         fn_len = 13;
5225         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5226                 TRUE, TRUE, bcp);
5227         CHECK_STRING_SUBR(fn);
5228         /* ensure that it's null-terminated */
5229         g_strlcpy(fname, fn, 13+1);
5230         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5231                 fname);
5232         COUNT_BYTES_SUBR(fn_len);
5233
5234         *trunc = FALSE;
5235         return offset;
5236 }
5237
5238
5239 static int
5240 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
5241     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5242     gboolean has_find_id)
5243 {
5244         smb_info_t *si = pinfo->private_data;
5245         int fn_len;
5246         const char *fn;
5247         guint16 rkl;
5248         guint8 wc;
5249         guint16 bc;
5250         gboolean trunc;
5251
5252         DISSECTOR_ASSERT(si);
5253
5254         WORD_COUNT;
5255
5256         /* max count */
5257         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5258         offset += 2;
5259
5260         /* Search Attributes */
5261         offset = dissect_search_attributes(tvb, tree, offset);
5262
5263         BYTE_COUNT;
5264
5265         /* buffer format */
5266         CHECK_BYTE_COUNT(1);
5267         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5268         COUNT_BYTES(1);
5269
5270         /* file name */
5271         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5272                 TRUE, FALSE, &bc);
5273         if (fn == NULL)
5274                 goto endofcommand;
5275         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5276                 fn);
5277         COUNT_BYTES(fn_len);
5278
5279         if (check_col(pinfo->cinfo, COL_INFO)) {
5280                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
5281                     format_text(fn, strlen(fn)));
5282         }
5283
5284         /* buffer format */
5285         CHECK_BYTE_COUNT(1);
5286         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5287         COUNT_BYTES(1);
5288
5289         /* resume key length */
5290         CHECK_BYTE_COUNT(2);
5291         rkl = tvb_get_letohs(tvb, offset);
5292         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
5293         COUNT_BYTES(2);
5294
5295         /* resume key */
5296         if(rkl){
5297                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
5298                     &bc, &trunc, has_find_id);
5299                 if (trunc)
5300                         goto endofcommand;
5301         }
5302
5303         END_OF_SMB
5304
5305         return offset;
5306 }
5307
5308 static int
5309 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5310     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5311 {
5312         return dissect_search_find_request(tvb, pinfo, tree, offset,
5313             smb_tree, FALSE);
5314 }
5315
5316 static int
5317 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5318     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5319 {
5320         return dissect_search_find_request(tvb, pinfo, tree, offset,
5321             smb_tree, TRUE);
5322 }
5323
5324 static int
5325 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
5326     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5327 {
5328         return dissect_search_find_request(tvb, pinfo, tree, offset,
5329             smb_tree, TRUE);
5330 }
5331
5332 static int
5333 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5334     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5335     gboolean has_find_id)
5336 {
5337         guint16 count=0;
5338         guint8 wc;
5339         guint16 bc;
5340         gboolean trunc;
5341
5342         WORD_COUNT;
5343
5344         /* count */
5345         count = tvb_get_letohs(tvb, offset);
5346         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
5347         offset += 2;
5348
5349         BYTE_COUNT;
5350
5351         /* buffer format */
5352         CHECK_BYTE_COUNT(1);
5353         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5354         COUNT_BYTES(1);
5355
5356         /* data len */
5357         CHECK_BYTE_COUNT(2);
5358         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
5359         COUNT_BYTES(2);
5360
5361         while(count--){
5362                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
5363                     &bc, &trunc, has_find_id);
5364                 if (trunc)
5365                         goto endofcommand;
5366         }
5367
5368         END_OF_SMB
5369
5370         return offset;
5371 }
5372
5373 static int
5374 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5375 {
5376         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5377             FALSE);
5378 }
5379
5380 static int
5381 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5382 {
5383         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5384             TRUE);
5385 }
5386
5387 static int
5388 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5389     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
5390 {
5391         guint8 wc;
5392         guint16 bc;
5393         guint16 data_len;
5394
5395         WORD_COUNT;
5396
5397         /* reserved */
5398         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5399         offset += 2;
5400
5401         BYTE_COUNT;
5402
5403         /* buffer format */
5404         CHECK_BYTE_COUNT(1);
5405         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
5406         COUNT_BYTES(1);
5407
5408         /* data len */
5409         CHECK_BYTE_COUNT(2);
5410         data_len = tvb_get_ntohs(tvb, offset);
5411         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
5412         COUNT_BYTES(2);
5413
5414         if (data_len != 0) {
5415                 CHECK_BYTE_COUNT(data_len);
5416                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
5417                     data_len, TRUE);
5418                 COUNT_BYTES(data_len);
5419         }
5420
5421         END_OF_SMB
5422
5423         return offset;
5424 }
5425
5426 static const value_string locking_ol_vals[] = {
5427         {0,     "Client is not holding oplock on this file"},
5428         {1,     "Level 2 oplock currently held by client"},
5429         {0, NULL}
5430 };
5431
5432 static const true_false_string tfs_lock_type_large = {
5433         "Large file locking format requested",
5434         "Large file locking format not requested"
5435 };
5436 static const true_false_string tfs_lock_type_cancel = {
5437         "Cancel outstanding lock request",
5438         "Don't cancel outstanding lock request"
5439 };
5440 static const true_false_string tfs_lock_type_change = {
5441         "Change lock type",
5442         "Don't change lock type"
5443 };
5444 static const true_false_string tfs_lock_type_oplock = {
5445         "This is an oplock break notification/response",
5446         "This is not an oplock break notification/response"
5447 };
5448 static const true_false_string tfs_lock_type_shared = {
5449         "This is a shared lock",
5450         "This is an exclusive lock"
5451 };
5452 static int
5453 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5454 {
5455         guint8  wc, cmd=0xff, lt=0, ol=0;
5456         guint16 andxoffset=0, un=0, ln=0, bc, fid, num_lock=0, num_unlock=0;
5457         guint32 to;
5458         proto_item *litem = NULL;
5459         proto_tree *ltree = NULL;
5460         proto_item *it = NULL;
5461         proto_tree *tr = NULL;
5462         int old_offset = offset;
5463         smb_info_t *si = pinfo->private_data;
5464         smb_locking_saved_info_t *ld=NULL;
5465
5466
5467         DISSECTOR_ASSERT(si);
5468
5469         WORD_COUNT;
5470
5471         /* next smb command */
5472         cmd = tvb_get_guint8(tvb, offset);
5473         if(cmd!=0xff){
5474                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5475         } else {
5476                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5477         }
5478         offset += 1;
5479
5480         /* reserved byte */
5481         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5482         offset += 1;
5483
5484         /* andxoffset */
5485         andxoffset = tvb_get_letohs(tvb, offset);
5486         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5487         offset += 2;
5488
5489         /* fid */
5490         fid = tvb_get_letohs(tvb, offset);
5491         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
5492         offset += 2;
5493
5494         /* lock type */
5495         lt = tvb_get_guint8(tvb, offset);
5496         if(tree){
5497                 litem = proto_tree_add_text(tree, tvb, offset, 1,
5498                         "Lock Type: 0x%02x", lt);
5499                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5500
5501                 proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
5502                         tvb, offset, 1, lt);
5503                 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
5504                         tvb, offset, 1, lt);
5505                 proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
5506                         tvb, offset, 1, lt);
5507                 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
5508                         tvb, offset, 1, lt);
5509                 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
5510                         tvb, offset, 1, lt);
5511         }
5512         offset += 1;
5513
5514         /* oplock level */
5515         ol = tvb_get_guint8(tvb, offset);
5516         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
5517         offset += 1;
5518
5519         /* timeout */
5520         to = tvb_get_letohl(tvb, offset);
5521         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5522         offset += 4;
5523
5524         /* number of unlocks */
5525         un = tvb_get_letohs(tvb, offset);
5526         num_unlock=un;
5527         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
5528         offset += 2;
5529
5530         /* number of locks */
5531         ln = tvb_get_letohs(tvb, offset);
5532         num_lock=ln;
5533         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
5534         offset += 2;
5535
5536         BYTE_COUNT;
5537
5538         /* store the locking data for the response */
5539         if((!pinfo->fd->flags.visited) && si->sip){
5540                 ld=se_alloc(sizeof(smb_locking_saved_info_t));
5541                 ld->type=lt;
5542                 ld->oplock_level= ol;
5543                 ld->num_lock=num_lock;
5544                 ld->num_unlock=num_unlock;
5545                 ld->locks=NULL;
5546                 ld->unlocks=NULL;
5547                 si->sip->extra_info_type=SMB_EI_LOCKDATA;
5548                 si->sip->extra_info=ld;
5549         }
5550
5551         /* unlocks */
5552         if(un){
5553                 old_offset = offset;
5554
5555                 it = proto_tree_add_text(tree, tvb, offset, -1,
5556                         "Unlocks");
5557                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
5558                 while(un--){
5559                         proto_item *litem = NULL;
5560                         proto_tree *ltree = NULL;
5561                         if(lt&0x10){
5562                                 guint64 val;
5563                                 guint16 lock_pid;
5564                                 guint64 lock_offset;
5565                                 guint64 lock_length;
5566
5567                                 /* large lock format */
5568                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5569                                         "Unlock");
5570                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5571
5572                                 /* PID */
5573                                 CHECK_BYTE_COUNT(2);
5574                                 lock_pid=tvb_get_letohs(tvb, offset);
5575                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5576                                 COUNT_BYTES(2);
5577
5578                                 /* 2 reserved bytes */
5579                                 CHECK_BYTE_COUNT(2);
5580                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5581                                 COUNT_BYTES(2);
5582
5583                                 /* offset */
5584                                 CHECK_BYTE_COUNT(8);
5585                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5586                                     | tvb_get_letohl(tvb, offset+4);
5587                                 lock_offset=val;
5588                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5589                                 COUNT_BYTES(8);
5590
5591                                 /* length */
5592                                 CHECK_BYTE_COUNT(8);
5593                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5594                                     | tvb_get_letohl(tvb, offset+4);
5595                                 lock_length=val;
5596                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5597                                 COUNT_BYTES(8);
5598
5599                                 /* remember the unlock for the reply */
5600                                 if(ld){
5601                                         smb_lock_info_t *li;
5602                                         li=se_alloc(sizeof(smb_lock_info_t));
5603                                         li->next=ld->unlocks;
5604                                         ld->unlocks=li;
5605                                         li->pid=lock_pid;
5606                                         li->offset=lock_offset;
5607                                         li->length=lock_length;
5608                                 }
5609                         } else {
5610                                 /* normal lock format */
5611                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5612                                         "Unlock");
5613                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
5614
5615                                 /* PID */
5616                                 CHECK_BYTE_COUNT(2);
5617                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5618                                 COUNT_BYTES(2);
5619
5620                                 /* offset */
5621                                 CHECK_BYTE_COUNT(4);
5622                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5623                                 COUNT_BYTES(4);
5624
5625                                 /* lock count */
5626                                 CHECK_BYTE_COUNT(4);
5627                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5628                                 COUNT_BYTES(4);
5629                         }
5630                 }
5631                 proto_item_set_len(it, offset-old_offset);
5632                 it = NULL;
5633         }
5634
5635         /* locks */
5636         if(ln){
5637                 old_offset = offset;
5638
5639                 it = proto_tree_add_text(tree, tvb, offset, -1,
5640                         "Locks");
5641                 tr = proto_item_add_subtree(it, ett_smb_locks);
5642                 while(ln--){
5643                         proto_item *litem = NULL;
5644                         proto_tree *ltree = NULL;
5645                         if(lt&0x10){
5646                                 guint64 val;
5647                                 guint16 lock_pid;
5648                                 guint64 lock_offset;
5649                                 guint64 lock_length;
5650
5651                                 /* large lock format */
5652                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
5653                                         "Lock");
5654                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5655
5656                                 /* PID */
5657                                 CHECK_BYTE_COUNT(2);
5658                                 lock_pid=tvb_get_letohs(tvb, offset);
5659                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5660                                 COUNT_BYTES(2);
5661
5662                                 /* 2 reserved bytes */
5663                                 CHECK_BYTE_COUNT(2);
5664                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
5665                                 COUNT_BYTES(2);
5666
5667                                 /* offset */
5668                                 CHECK_BYTE_COUNT(8);
5669                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5670                                     | tvb_get_letohl(tvb, offset+4);
5671                                 lock_offset=val;
5672                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
5673                                 COUNT_BYTES(8);
5674
5675                                 /* length */
5676                                 CHECK_BYTE_COUNT(8);
5677                                 val=((guint64)tvb_get_letohl(tvb, offset)) << 32
5678                                     | tvb_get_letohl(tvb, offset+4);
5679                                 lock_length=val;
5680                                 proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
5681                                 COUNT_BYTES(8);
5682
5683                                 /* remember the lock for the reply */
5684                                 if(ld){
5685                                         smb_lock_info_t *li;
5686                                         li=se_alloc(sizeof(smb_lock_info_t));
5687                                         li->next=ld->locks;
5688                                         ld->locks=li;
5689                                         li->pid=lock_pid;
5690                                         li->offset=lock_offset;
5691                                         li->length=lock_length;
5692                                 }
5693                         } else {
5694                                 /* normal lock format */
5695                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
5696                                         "Lock");
5697                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
5698
5699                                 /* PID */
5700                                 CHECK_BYTE_COUNT(2);
5701                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
5702                                 COUNT_BYTES(2);
5703
5704                                 /* offset */
5705                                 CHECK_BYTE_COUNT(4);
5706                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
5707                                 COUNT_BYTES(4);
5708
5709                                 /* lock count */
5710                                 CHECK_BYTE_COUNT(4);
5711                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
5712                                 COUNT_BYTES(4);
5713                         }
5714                 }
5715                 proto_item_set_len(it, offset-old_offset);
5716                 it = NULL;
5717         }
5718
5719         END_OF_SMB
5720
5721         if (it != NULL) {
5722                 /*
5723                  * We ran out of byte count in the middle of dissecting
5724                  * the locks or the unlocks; set the site of the item
5725                  * we were dissecting.
5726                  */
5727                 proto_item_set_len(it, offset-old_offset);
5728         }
5729
5730         if (cmd != 0xff) {      /* there is an andX command */
5731                 if (andxoffset < offset)
5732                         THROW(ReportedBoundsError);
5733                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5734         }
5735
5736         return offset;
5737 }
5738
5739 static int
5740 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
5741 {
5742         guint8  wc, cmd=0xff;
5743         guint16 andxoffset=0;
5744         guint16 bc;
5745         smb_info_t *si;
5746
5747         si = (smb_info_t *)pinfo->private_data;
5748         DISSECTOR_ASSERT(si);
5749
5750         /* print the lock info from the request */
5751         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_LOCKDATA) {
5752                 smb_locking_saved_info_t *ld;
5753                 proto_item *litem = NULL;
5754                 proto_tree *ltree = NULL;
5755
5756                 ld = si->sip->extra_info;
5757                 if (ld != NULL) {
5758                         proto_item *lit;
5759                         proto_tree *ltr;
5760                         smb_lock_info_t *li;
5761                         if(tree){
5762                                 litem = proto_tree_add_text(tree, tvb, 0, 0,
5763                                         "Lock Type: 0x%02x", ld->type);
5764                                 PROTO_ITEM_SET_GENERATED(litem);
5765                                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5766
5767                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_large, tvb, 0, 0, ld->type);
5768                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel, tvb, 0, 0, ld->type);
5769                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_change, tvb, 0, 0, ld->type);
5770                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock, tvb, 0, 0, ld->type);
5771                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared, tvb, 0, 0, ld->type);
5772                                 proto_tree_add_uint(ltree, hf_smb_locking_ol, tvb, 0, 0, ld->oplock_level);
5773                                 proto_tree_add_uint(ltree, hf_smb_number_of_unlocks, tvb, 0, 0, ld->num_unlock);
5774                                 proto_tree_add_uint(ltree, hf_smb_number_of_locks, tvb, 0, 0, ld->num_lock);
5775
5776                                 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Locks");
5777                                 ltr = proto_item_add_subtree(lit, ett_smb_lock);
5778                                 li=ld->locks;
5779                                 while(li){
5780                                         proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
5781                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
5782                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
5783                                         li=li->next;
5784                                 }
5785                                 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Unlocks");
5786                                 ltr = proto_item_add_subtree(lit, ett_smb_unlock);
5787                                 li=ld->unlocks;
5788                                 while(li){
5789                                         proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
5790                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
5791                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
5792                                         li=li->next;
5793                                 }
5794                         }
5795                 }
5796         }
5797
5798         WORD_COUNT;
5799
5800         /* next smb command */
5801         cmd = tvb_get_guint8(tvb, offset);
5802         if(cmd!=0xff){
5803                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5804         } else {
5805                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5806         }
5807         offset += 1;
5808
5809         /* reserved byte */
5810         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5811         offset += 1;
5812
5813         /* andxoffset */
5814         andxoffset = tvb_get_letohs(tvb, offset);
5815         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5816         offset += 2;
5817
5818         BYTE_COUNT;
5819
5820         END_OF_SMB
5821
5822         if (cmd != 0xff) {      /* there is an andX command */
5823                 if (andxoffset < offset)
5824                         THROW(ReportedBoundsError);
5825                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5826         }
5827
5828         return offset;
5829 }
5830
5831
5832 const value_string oa_open_vals[] = {
5833         { 0,            "No action taken?"},
5834         { 1,            "The file existed and was opened"},
5835         { 2,            "The file did not exist but was created"},
5836         { 3,            "The file existed and was truncated"},
5837         { 0x8001,       "The file existed and was opened, and an OpLock was granted"},
5838         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
5839         { 0x8003,       "The file existed and was truncated, and an OpLock was granted"},
5840         {0,     NULL}
5841 };
5842 static const true_false_string tfs_oa_lock = {
5843         "File is currently opened only by this user",
5844         "File is opened by another user (or mode not supported by server)"
5845 };
5846 static int
5847 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5848 {
5849         guint16 mask;
5850         proto_item *item;
5851         proto_tree *tree;
5852
5853         mask = tvb_get_letohs(tvb, offset);
5854
5855         if(parent_tree){
5856                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5857                         "Action: 0x%04x", mask);
5858                 tree = proto_item_add_subtree(item, ett_smb_open_action);
5859
5860                 proto_tree_add_boolean(tree, hf_smb_open_action_lock,
5861                         tvb, offset, 2, mask);
5862                 proto_tree_add_uint(tree, hf_smb_open_action_open,
5863                         tvb, offset, 2, mask);
5864         }
5865         offset += 2;
5866
5867         return offset;
5868 }
5869
5870 static const true_false_string tfs_open_flags_add_info = {
5871         "Additional information requested",
5872         "Additional information not requested"
5873 };
5874 static const true_false_string tfs_open_flags_ex_oplock = {
5875         "Exclusive oplock requested",
5876         "Exclusive oplock not requested"
5877 };
5878 static const true_false_string tfs_open_flags_batch_oplock = {
5879         "Batch oplock requested",
5880         "Batch oplock not requested"
5881 };
5882 static const true_false_string tfs_open_flags_ealen = {
5883         "Total length of EAs requested",
5884         "Total length of EAs not requested"
5885 };
5886 static int
5887 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5888 {
5889         guint16 mask;
5890         proto_item *item;
5891         proto_tree *tree;
5892
5893         mask = tvb_get_letohs(tvb, offset);
5894
5895         if(parent_tree){
5896                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5897                         "Flags: 0x%04x", mask);
5898                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5899
5900                 if(bm&0x0001){
5901                         proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5902                                 tvb, offset, 2, mask);
5903                 }
5904                 if(bm&0x0002){
5905                         proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5906                                 tvb, offset, 2, mask);
5907                 }
5908                 if(bm&0x0004){
5909                         proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5910                                 tvb, offset, 2, mask);
5911                 }
5912                 if(bm&0x0008){
5913                         proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5914                                 tvb, offset, 2, mask);
5915                 }
5916         }
5917
5918         offset += 2;
5919
5920         return offset;
5921 }
5922
5923 static const value_string filetype_vals[] = {
5924         { 0,            "Disk file or directory"},
5925         { 1,            "Named pipe in byte mode"},
5926         { 2,            "Named pipe in message mode"},
5927         { 3,            "Spooled printer"},
5928         {0, NULL}
5929 };
5930 static int
5931 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5932 {
5933         guint8  wc, cmd=0xff;
5934         guint16 andxoffset=0, bc;
5935         guint32 to;
5936         smb_info_t *si = pinfo->private_data;
5937         int fn_len;
5938         const char *fn;
5939
5940         DISSECTOR_ASSERT(si);
5941
5942         WORD_COUNT;
5943
5944         /* next smb command */
5945         cmd = tvb_get_guint8(tvb, offset);
5946         if(cmd!=0xff){
5947                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5948         } else {
5949                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5950         }
5951         offset += 1;
5952
5953         /* reserved byte */
5954         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5955         offset += 1;
5956
5957         /* andxoffset */
5958         andxoffset = tvb_get_letohs(tvb, offset);
5959         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5960         offset += 2;
5961
5962         /* open flags */
5963         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5964
5965         /* desired access */
5966         offset = dissect_access(tvb, tree, offset, "Desired");
5967
5968         /* Search Attributes */
5969         offset = dissect_search_attributes(tvb, tree, offset);
5970
5971         /* File Attributes */
5972         offset = dissect_file_attributes(tvb, tree, offset, 2);
5973
5974         /* creation time */
5975         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5976
5977         /* open function */
5978         offset = dissect_open_function(tvb, tree, offset);
5979
5980         /* allocation size */
5981         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5982         offset += 4;
5983
5984         /* timeout, described at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT */
5985         to = tvb_get_letohl(tvb, offset);
5986         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
5987         offset += 4;
5988
5989         /* 4 reserved bytes */
5990         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5991         offset += 4;
5992
5993         BYTE_COUNT;
5994
5995         /* file name */
5996         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5997                 FALSE, FALSE, &bc);
5998         if (fn == NULL)
5999                 goto endofcommand;
6000         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6001                 fn);
6002         COUNT_BYTES(fn_len);
6003
6004         if (check_col(pinfo->cinfo, COL_INFO)) {
6005                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
6006                     format_text(fn, strlen(fn)));
6007         }
6008
6009         END_OF_SMB
6010
6011         if (cmd != 0xff) {      /* there is an andX command */
6012                 if (andxoffset < offset)
6013                         THROW(ReportedBoundsError);
6014                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6015         }
6016
6017         return offset;
6018 }
6019
6020 static const true_false_string tfs_ipc_state_nonblocking = {
6021         "Reads/writes return immediately if no data available",
6022         "Reads/writes block if no data available"
6023 };
6024 static const value_string ipc_state_endpoint_vals[] = {
6025         { 0,            "Consumer end of pipe"},
6026         { 1,            "Server end of pipe"},
6027         {0,     NULL}
6028 };
6029 static const value_string ipc_state_pipe_type_vals[] = {
6030         { 0,            "Byte stream pipe"},
6031         { 1,            "Message pipe"},
6032         {0,     NULL}
6033 };
6034 static const value_string ipc_state_read_mode_vals[] = {
6035         { 0,            "Read pipe as a byte stream"},
6036         { 1,            "Read messages from pipe"},
6037         {0,     NULL}
6038 };
6039
6040 int
6041 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
6042     gboolean setstate)
6043 {
6044         guint16 mask;
6045         proto_item *item;
6046         proto_tree *tree;
6047
6048         mask = tvb_get_letohs(tvb, offset);
6049
6050         if(parent_tree){
6051                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6052                         "IPC State: 0x%04x", mask);
6053                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
6054
6055                 proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
6056                         tvb, offset, 2, mask);
6057                 if (!setstate) {
6058                         proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
6059                                 tvb, offset, 2, mask);
6060                         proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
6061                                 tvb, offset, 2, mask);
6062                 }
6063                 proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
6064                         tvb, offset, 2, mask);
6065                 if (!setstate) {
6066                         proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
6067                                 tvb, offset, 2, mask);
6068                 }
6069         }
6070
6071         offset += 2;
6072
6073         return offset;
6074 }
6075
6076 static int
6077 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6078 {
6079         guint8  wc, cmd=0xff;
6080         guint16 andxoffset=0, bc;
6081         guint16 fid;
6082
6083         WORD_COUNT;
6084
6085         /* next smb command */
6086         cmd = tvb_get_guint8(tvb, offset);
6087         if(cmd!=0xff){
6088                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6089         } else {
6090                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6091         }
6092         offset += 1;
6093
6094         /* reserved byte */
6095         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6096         offset += 1;
6097
6098         /* andxoffset */
6099         andxoffset = tvb_get_letohs(tvb, offset);
6100         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6101         offset += 2;
6102
6103         /* fid */
6104         fid = tvb_get_letohs(tvb, offset);
6105         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
6106         offset += 2;
6107
6108         /* File Attributes */
6109         offset = dissect_file_attributes(tvb, tree, offset, 2);
6110
6111         /* last write time */
6112         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
6113
6114         /* File Size */
6115         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
6116         offset += 4;
6117
6118         /* granted access */
6119         offset = dissect_access(tvb, tree, offset, "Granted");
6120
6121         /* File Type */
6122         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
6123         offset += 2;
6124
6125         /* IPC State */
6126         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
6127
6128         /* open_action */
6129         offset = dissect_open_action(tvb, tree, offset);
6130
6131         /* server fid */
6132         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
6133         offset += 4;
6134
6135         /* 2 reserved bytes */
6136         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6137         offset += 2;
6138
6139         BYTE_COUNT;
6140
6141         END_OF_SMB
6142
6143         if (cmd != 0xff) {      /* there is an andX command */
6144                 if (andxoffset < offset)
6145                         THROW(ReportedBoundsError);
6146                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6147         }
6148
6149         return offset;
6150 }
6151
6152 static int
6153 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6154 {
6155         guint8  wc, cmd=0xff;
6156         guint16 andxoffset=0, bc, maxcnt_low;
6157         guint32 maxcnt_high;
6158         guint32 maxcnt=0;
6159         guint32 ofs = 0;
6160         smb_info_t *si= (smb_info_t *)pinfo->private_data;
6161         unsigned int fid;
6162         rw_info_t *rwi=NULL;
6163
6164
6165         DISSECTOR_ASSERT(si);
6166
6167         WORD_COUNT;
6168
6169         /* next smb command */
6170         cmd = tvb_get_guint8(tvb, offset);
6171         if(cmd!=0xff){
6172                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6173         } else {
6174                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6175         }
6176         offset += 1;
6177
6178         /* reserved byte */
6179         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6180         offset += 1;
6181
6182         /* andxoffset */
6183         andxoffset = tvb_get_letohs(tvb, offset);
6184         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6185         offset += 2;
6186
6187         /* fid */
6188         fid = tvb_get_letohs(tvb, offset);
6189         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6190         offset += 2;
6191
6192         /* offset */
6193         ofs = tvb_get_letohl(tvb, offset);
6194         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6195         offset += 4;
6196
6197         /* max count low */
6198         maxcnt_low = tvb_get_letohs(tvb, offset);
6199         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
6200         offset += 2;
6201
6202         /* min count */
6203         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
6204         offset += 2;
6205
6206         /*
6207          * max count high
6208          *
6209          * XXX - we should really only do this in case we have seen
6210          * LARGE FILE being negotiated.  Unfortunately, we might not
6211          * have seen the negotiation phase in the capture....
6212          *
6213          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
6214          * it's 32 bits, but the description says "High 16 bits of
6215          * MaxCount if CAP_LARGE_READX".
6216          *
6217          * The SMB File Sharing Protocol Extensions Version 2.0,
6218          * Document Version 3.3 spec doesn't speak of an extra 16
6219          * bits in max count, but it does show a 32-bit timeout
6220          * after the min count field.
6221          *
6222          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
6223          * high count and a 16-bit reserved field.
6224          *
6225          * We fetch and display it as 32 bits.
6226          *
6227          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
6228          * bytes and we just ignore it.
6229          */
6230         maxcnt_high = tvb_get_letohl(tvb, offset);
6231         if(maxcnt_high==0xffffffff){
6232                 maxcnt_high=0;
6233         } else {
6234                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
6235         }
6236
6237         offset += 4;
6238
6239         maxcnt=maxcnt_high;
6240         maxcnt=(maxcnt<<16)|maxcnt_low;
6241
6242         if (check_col(pinfo->cinfo, COL_INFO))
6243                 col_append_fstr(pinfo->cinfo, COL_INFO,
6244                                 ", %u byte%s at offset %u", maxcnt,
6245                                 (maxcnt == 1) ? "" : "s", ofs);
6246
6247         /* save the offset/len for this transaction */
6248         if(si->sip && !pinfo->fd->flags.visited){
6249                 rwi=se_alloc(sizeof(rw_info_t));
6250                 rwi->offset=ofs;
6251                 rwi->len=maxcnt;
6252                 rwi->fid=fid;
6253
6254                 si->sip->extra_info_type=SMB_EI_RWINFO;
6255                 si->sip->extra_info=rwi;
6256         }
6257         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6258                 rwi=si->sip->extra_info;
6259         }
6260         if(rwi){
6261                 proto_item *it;
6262
6263                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6264
6265                 PROTO_ITEM_SET_GENERATED(it);
6266                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6267                 PROTO_ITEM_SET_GENERATED(it);
6268         }
6269
6270         /* remaining */
6271         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6272         offset += 2;
6273
6274         if(wc==12){
6275                 /* high offset */
6276                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6277                 offset += 4;
6278         }
6279
6280         BYTE_COUNT;
6281
6282         END_OF_SMB
6283
6284         if (cmd != 0xff) {      /* there is an andX command */
6285                 if (andxoffset < offset)
6286                         THROW(ReportedBoundsError);
6287                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6288         }
6289
6290         return offset;
6291 }
6292
6293 static int
6294 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6295 {
6296         guint8  wc, cmd=0xff;
6297         guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
6298         guint32 datalen=0, datalen_high;
6299         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6300         int fid=0;
6301         rw_info_t *rwi=NULL;
6302
6303         DISSECTOR_ASSERT(si);
6304
6305         WORD_COUNT;
6306
6307         /* next smb command */
6308         cmd = tvb_get_guint8(tvb, offset);
6309         if(cmd!=0xff){
6310                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6311         } else {
6312                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6313         }
6314         offset += 1;
6315
6316         /* reserved byte */
6317         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6318         offset += 1;
6319
6320         /* andxoffset */
6321         andxoffset = tvb_get_letohs(tvb, offset);
6322         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6323         offset += 2;
6324
6325         /* If we have seen the request, then print which FID this refers to */
6326         /* first check if we have seen the request */
6327         if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type==SMB_EI_FID){
6328                 fid=GPOINTER_TO_INT(si->sip->extra_info);
6329                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE);
6330         }
6331
6332         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6333                 rwi=si->sip->extra_info;
6334         }
6335         if(rwi){
6336                 proto_item *it;
6337
6338                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6339
6340                 PROTO_ITEM_SET_GENERATED(it);
6341                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6342                 PROTO_ITEM_SET_GENERATED(it);
6343
6344                 /* we need the fid for the call to dcerpc below */
6345                 fid=rwi->fid;
6346         }
6347
6348         /* remaining */
6349         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6350         offset += 2;
6351
6352         /* data compaction mode */
6353         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
6354         offset += 2;
6355
6356         /* 2 reserved bytes */
6357         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6358         offset += 2;
6359
6360         /* data len low */
6361         datalen_low = tvb_get_letohs(tvb, offset);
6362         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6363         offset += 2;
6364
6365         /* data offset */
6366         dataoffset=tvb_get_letohs(tvb, offset);
6367         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6368         offset += 2;
6369
6370         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6371         /* data length high */
6372         datalen_high = tvb_get_letohl(tvb, offset);
6373         if(datalen_high==0xffffffff){
6374                 datalen_high=0;
6375         } else {
6376                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
6377         }
6378         offset += 4;
6379
6380         datalen=datalen_high;
6381         datalen=(datalen<<16)|datalen_low;
6382
6383
6384         if (check_col(pinfo->cinfo, COL_INFO))
6385                 col_append_fstr(pinfo->cinfo, COL_INFO,
6386                                 ", %u byte%s", datalen,
6387                                 (datalen == 1) ? "" : "s");
6388
6389
6390         /* 6 reserved bytes */
6391         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
6392         offset += 6;
6393
6394         BYTE_COUNT;
6395
6396         /* file data, might be DCERPC on a pipe */
6397         if(bc){
6398                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6399                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6400                 bc = 0;
6401         }
6402
6403         END_OF_SMB
6404
6405         if (cmd != 0xff) {      /* there is an andX command */
6406                 if (andxoffset < offset)
6407                         THROW(ReportedBoundsError);
6408                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6409         }
6410
6411         return offset;
6412 }
6413
6414 static int
6415 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6416 {
6417         guint32 ofs=0;
6418         guint8  wc, cmd=0xff;
6419         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
6420         guint32 datalen=0;
6421         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6422         unsigned int fid=0;
6423         guint16 mode = 0;
6424         rw_info_t *rwi=NULL;
6425
6426
6427         DISSECTOR_ASSERT(si);
6428
6429         WORD_COUNT;
6430
6431         /* next smb command */
6432         cmd = tvb_get_guint8(tvb, offset);
6433         if(cmd!=0xff){
6434                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6435         } else {
6436                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6437         }
6438         offset += 1;
6439
6440         /* reserved byte */
6441         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6442         offset += 1;
6443
6444         /* andxoffset */
6445         andxoffset = tvb_get_letohs(tvb, offset);
6446         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6447         offset += 2;
6448
6449         /* fid */
6450         fid = tvb_get_letohs(tvb, offset);
6451         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
6452         offset += 2;
6453
6454         /* offset */
6455         ofs = tvb_get_letohl(tvb, offset);
6456         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
6457         offset += 4;
6458
6459         /* reserved */
6460         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6461         offset += 4;
6462
6463         /* mode */
6464         mode = tvb_get_letohs(tvb, offset);
6465         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
6466
6467         /* remaining */
6468         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6469         offset += 2;
6470
6471         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6472         /* data length high */
6473         datalen_high = tvb_get_letohs(tvb, offset);
6474         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
6475         offset += 2;
6476
6477         /* data len low */
6478         datalen_low = tvb_get_letohs(tvb, offset);
6479         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6480         offset += 2;
6481
6482         datalen=datalen_high;
6483         datalen=(datalen<<16)|datalen_low;
6484
6485         /* data offset */
6486         dataoffset=tvb_get_letohs(tvb, offset);
6487         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6488         offset += 2;
6489
6490         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
6491         if (check_col(pinfo->cinfo, COL_INFO))
6492                 col_append_fstr(pinfo->cinfo, COL_INFO,
6493                                 ", %u byte%s at offset %u", datalen,
6494                                 (datalen == 1) ? "" : "s", ofs);
6495
6496         /* save the offset/len for this transaction */
6497         if(si->sip && !pinfo->fd->flags.visited){
6498                 rwi=se_alloc(sizeof(rw_info_t));
6499                 rwi->offset=ofs;
6500                 rwi->len=datalen;
6501                 rwi->fid=fid;
6502
6503                 si->sip->extra_info_type=SMB_EI_RWINFO;
6504                 si->sip->extra_info=rwi;
6505         }
6506         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6507                 rwi=si->sip->extra_info;
6508         }
6509         if(rwi){
6510                 proto_item *it;
6511
6512                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6513
6514                 PROTO_ITEM_SET_GENERATED(it);
6515                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6516                 PROTO_ITEM_SET_GENERATED(it);
6517         }
6518
6519
6520         if(wc==14){
6521                 /* high offset */
6522                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
6523                 offset += 4;
6524         }
6525
6526         BYTE_COUNT;
6527
6528         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
6529            the first two bytes of the payload is the length of the data.
6530            Assume that all WriteAndX PDUs that have MESSAGE_START set to
6531            be over the IPC$ share and thus they all transport DCERPC.
6532            (if we didnt already know that from the TreeConnect call)
6533         */
6534         if(mode&WRITE_MODE_MESSAGE_START){
6535                 if(mode&WRITE_MODE_RAW){
6536                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
6537                         offset += 2;
6538                         dataoffset += 2;
6539                         bc -= 2;
6540                         datalen -= 2;
6541                 }
6542                 if(!pinfo->fd->flags.visited){
6543                         /* In case we did not see the TreeConnect call,
6544                            store this TID here as well as a IPC TID
6545                            so we know that future Read/Writes to this
6546                            TID is (probably) DCERPC.
6547                         */
6548                         if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
6549                                 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
6550                         }
6551                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
6552                 }
6553                 if(si->sip){
6554                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
6555                 }
6556         }
6557
6558         /* file data, might be DCERPC on a pipe */
6559         if (bc != 0) {
6560                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6561                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
6562                 bc = 0;
6563         }
6564
6565         END_OF_SMB
6566
6567         if (cmd != 0xff) {      /* there is an andX command */
6568                 if (andxoffset < offset)
6569                         THROW(ReportedBoundsError);
6570                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6571         }
6572
6573         return offset;
6574 }
6575
6576 static int
6577 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6578 {
6579         guint8  wc, cmd=0xff;
6580         guint16 andxoffset=0, bc, count_low, count_high;
6581         guint32 count=0;
6582         smb_info_t *si = (smb_info_t *)pinfo->private_data;
6583         rw_info_t *rwi=NULL;
6584
6585         DISSECTOR_ASSERT(si);
6586
6587         WORD_COUNT;
6588
6589         /* next smb command */
6590         cmd = tvb_get_guint8(tvb, offset);
6591         if(cmd!=0xff){
6592                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6593         } else {
6594                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6595         }
6596         offset += 1;
6597
6598         /* reserved byte */
6599         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6600         offset += 1;
6601
6602         /* andxoffset */
6603         andxoffset = tvb_get_letohs(tvb, offset);
6604         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6605         offset += 2;
6606
6607
6608         if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
6609                 rwi=si->sip->extra_info;
6610         }
6611         if(rwi){
6612                 proto_item *it;
6613
6614                 it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6615
6616                 PROTO_ITEM_SET_GENERATED(it);
6617                 it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6618                 PROTO_ITEM_SET_GENERATED(it);
6619         }
6620
6621
6622         /* write count low */
6623         count_low = tvb_get_letohs(tvb, offset);
6624         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
6625         offset += 2;
6626
6627         /* remaining */
6628         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
6629         offset += 2;
6630
6631         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6632         /* write count high */
6633         count_high = tvb_get_letohs(tvb, offset);
6634         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
6635         offset += 2;
6636
6637         count=count_high;
6638         count=(count<<16)|count_low;
6639
6640         if (check_col(pinfo->cinfo, COL_INFO))
6641                 col_append_fstr(pinfo->cinfo, COL_INFO,
6642                                 ", %u byte%s", count,
6643                                 (count == 1) ? "" : "s");
6644
6645         /* 2 reserved bytes */
6646         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6647         offset += 2;
6648
6649         BYTE_COUNT;
6650
6651         END_OF_SMB
6652
6653         if (cmd != 0xff) {      /* there is an andX command */
6654                 if (andxoffset < offset)
6655                         THROW(ReportedBoundsError);
6656                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6657         }
6658
6659         return offset;
6660 }
6661
6662
6663 static const true_false_string tfs_setup_action_guest = {
6664         "Logged in as GUEST",
6665         "Not logged in as GUEST"
6666 };
6667 static int
6668 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6669 {
6670         guint16 mask;
6671         proto_item *item;
6672         proto_tree *tree;
6673
6674         mask = tvb_get_letohs(tvb, offset);
6675
6676         if(parent_tree){
6677                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6678                         "Action: 0x%04x", mask);
6679                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
6680
6681                 proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
6682                         tvb, offset, 2, mask);
6683         }
6684         offset += 2;
6685
6686         return offset;
6687 }
6688
6689
6690 static int
6691 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6692 {
6693         guint8  wc, cmd=0xff;
6694         guint16 bc;
6695         guint16 andxoffset=0;
6696         smb_info_t *si = pinfo->private_data;
6697         int an_len;
6698         const char *an;
6699         int dn_len;
6700         const char *dn;
6701         guint16 pwlen=0;
6702         guint16 sbloblen=0, sbloblen_short;
6703         guint16 apwlen=0, upwlen=0;
6704         gboolean unicodeflag;
6705         static int ntlmssp_tap_id = 0;
6706         const ntlmssp_header_t *ntlmssph;
6707
6708         if(!ntlmssp_tap_id){
6709                 GString *error_string;
6710                 /* We dont specify any callbacks at all.
6711                  * Instead we manually fetch the tapped data after the
6712                  * security blob has been fully dissected and before
6713                  * we exit from this dissector.
6714                  */
6715                 error_string=register_tap_listener("ntlmssp", NULL, NULL,
6716                     0, NULL, NULL, NULL);
6717                 if(!error_string){
6718                         ntlmssp_tap_id=find_tap_id("ntlmssp");
6719                 }
6720         }
6721
6722         DISSECTOR_ASSERT(si);
6723
6724         WORD_COUNT;
6725
6726         /* next smb command */
6727         cmd = tvb_get_guint8(tvb, offset);
6728         if(cmd!=0xff){
6729                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6730         } else {
6731                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6732         }
6733         offset += 1;
6734
6735         /* reserved byte */
6736         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6737         offset += 1;
6738
6739         /* andxoffset */
6740         andxoffset = tvb_get_letohs(tvb, offset);
6741         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6742         offset += 2;
6743
6744         /* Maximum Buffer Size */
6745         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
6746         offset += 2;
6747
6748         /* Maximum Multiplex Count */
6749         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
6750         offset += 2;
6751
6752         /* VC Number */
6753         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
6754         offset += 2;
6755
6756         /* session key */
6757         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
6758         offset += 4;
6759
6760         switch (wc) {
6761         case 10:
6762                 /* password length, ASCII*/
6763                 pwlen = tvb_get_letohs(tvb, offset);
6764                 proto_tree_add_uint(tree, hf_smb_password_len,
6765                         tvb, offset, 2, pwlen);
6766                 offset += 2;
6767
6768                 /* 4 reserved bytes */
6769                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6770                 offset += 4;
6771
6772                 break;
6773
6774         case 12:
6775                 /* security blob length */
6776                 sbloblen = tvb_get_letohs(tvb, offset);
6777                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6778                 offset += 2;
6779
6780                 /* 4 reserved bytes */
6781                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6782                 offset += 4;
6783
6784                 /* capabilities */
6785                 dissect_negprot_capabilities(tvb, tree, offset);
6786                 offset += 4;
6787
6788                 break;
6789
6790         case 13:
6791                 /* password length, ANSI*/
6792                 apwlen = tvb_get_letohs(tvb, offset);
6793                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
6794                         tvb, offset, 2, apwlen);
6795                 offset += 2;
6796
6797                 /* password length, Unicode*/
6798                 upwlen = tvb_get_letohs(tvb, offset);
6799                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
6800                         tvb, offset, 2, upwlen);
6801                 offset += 2;
6802
6803                 /* 4 reserved bytes */
6804                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
6805                 offset += 4;
6806
6807                 /* capabilities */
6808                 dissect_negprot_capabilities(tvb, tree, offset);
6809                 offset += 4;
6810
6811                 break;
6812         }
6813
6814         BYTE_COUNT;
6815
6816         if (wc==12) {
6817                 proto_item *blob_item;
6818
6819                 /* security blob */
6820                 /* If it runs past the end of the captured data, don't
6821                  * try to put all of it into the protocol tree as the
6822                  * raw security blob; we might get an exception on
6823                  * short frames and then we will not see anything at all
6824                  * of the security blob.
6825                  */
6826                 sbloblen_short = sbloblen;
6827                 if(sbloblen_short>tvb_length_remaining(tvb,offset)){
6828                         sbloblen_short=tvb_length_remaining(tvb,offset);
6829                 }
6830                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6831                                                 tvb, offset, sbloblen_short,
6832                                                 TRUE);
6833
6834                 /* As an optimization, because Windows is perverse,
6835                    we check to see if NTLMSSP is the first part of the
6836                    blob, and if so, call the NTLMSSP dissector,
6837                    otherwise we call the GSS-API dissector. This is because
6838                    Windows can request RAW NTLMSSP, but will happily handle
6839                    a client that wraps NTLMSSP in SPNEGO
6840                 */
6841
6842                 if(sbloblen){
6843                         tvbuff_t *blob_tvb;
6844                         proto_tree *blob_tree;
6845
6846                         blob_tree = proto_item_add_subtree(blob_item,
6847                                                            ett_smb_secblob);
6848                         CHECK_BYTE_COUNT(sbloblen);
6849
6850                         /*
6851                          * Set the reported length of this to the reported
6852                          * length of the blob, rather than the amount of
6853                          * data available from the blob, so that we'll
6854                          * throw the right exception if it's too short.
6855                          */
6856                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
6857                                                   sbloblen);
6858
6859                         if (si && si->ct && si->ct->raw_ntlmssp &&
6860                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
6861                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6862                                          blob_tree);
6863
6864                         }
6865                         else {
6866                           call_dissector(gssapi_handle, blob_tvb,
6867                                          pinfo, blob_tree);
6868                         }
6869
6870                         /* If we have found a uid->acct_name mapping, store it */
6871                         if(!pinfo->fd->flags.visited && si->sip){
6872                                 int idx=0;
6873                                 if((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
6874                                         if(ntlmssph && ntlmssph->type==3){
6875                                                 smb_uid_t *smb_uid;
6876
6877                                                 smb_uid=se_alloc(sizeof(smb_uid_t));
6878                                                 smb_uid->logged_in=-1;
6879                                                 smb_uid->logged_out=-1;
6880                                                 smb_uid->domain=se_strdup(ntlmssph->domain_name);
6881                                                 smb_uid->account=se_strdup(ntlmssph->acct_name);
6882
6883                                                 si->sip->extra_info=smb_uid;
6884                                                 si->sip->extra_info_type=SMB_EI_UID;
6885                                         }
6886                                 }
6887                         }
6888
6889                         COUNT_BYTES(sbloblen);
6890                 }
6891
6892                 /* OS
6893                  * Eventhough this field should honour the unicode flag
6894                  * some ms clients gets this wrong.
6895                  * At least XP SP1 sends this in ASCII
6896                  * even when the unicode flag is on.
6897                  * Test if the first three bytes are "Win"
6898                  * and if so just override the flag.
6899                  */
6900                 unicodeflag=si->unicode;
6901                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6902                         unicodeflag=FALSE;
6903                 }
6904                 an = get_unicode_or_ascii_string(tvb, &offset,
6905                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6906                 if (an == NULL)
6907                         goto endofcommand;
6908                 proto_tree_add_string(tree, hf_smb_os, tvb,
6909                         offset, an_len, an);
6910                 COUNT_BYTES(an_len);
6911
6912                 /* LANMAN */
6913                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
6914                  * padding/null string/whatever in front of this. W2K doesn't
6915                  * appear to. I suspect that's a bug that got fixed; I also
6916                  * suspect that, in practice, nobody ever looks at that field
6917                  * because the bug didn't appear to get fixed until NT 5.0....
6918                  *
6919                  * Eventhough this field should honour the unicode flag
6920                  * some ms clients gets this wrong.
6921                  * At least XP SP1 sends this in ASCII
6922                  * even when the unicode flag is on.
6923                  * Test if the first three bytes are "Win"
6924                  * and if so just override the flag.
6925                  */
6926                 unicodeflag=si->unicode;
6927                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
6928                         unicodeflag=FALSE;
6929                 }
6930                 an = get_unicode_or_ascii_string(tvb, &offset,
6931                         unicodeflag, &an_len, FALSE, FALSE, &bc);
6932                 if (an == NULL)
6933                         goto endofcommand;
6934                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6935                         offset, an_len, an);
6936                 COUNT_BYTES(an_len);
6937
6938                 /* Primary domain */
6939                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6940                  * byte in front of this, at least if all the strings are
6941                  * ASCII and the account name is empty. Another bug?
6942                  */
6943                 dn = get_unicode_or_ascii_string(tvb, &offset,
6944                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6945                 if (dn == NULL)
6946                         goto endofcommand;
6947                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6948                         offset, dn_len, dn);
6949                 COUNT_BYTES(dn_len);
6950         } else {
6951                 switch (wc) {
6952
6953                 case 10:
6954                         if(pwlen){
6955                                 /* password, ASCII */
6956                                 CHECK_BYTE_COUNT(pwlen);
6957                                 proto_tree_add_item(tree, hf_smb_password,
6958                                         tvb, offset, pwlen, TRUE);
6959                                 COUNT_BYTES(pwlen);
6960                         }
6961
6962                         break;
6963
6964                 case 13:
6965                         if(apwlen){
6966                                 /* password, ANSI */
6967                                 CHECK_BYTE_COUNT(apwlen);
6968                                 proto_tree_add_item(tree, hf_smb_ansi_password,
6969                                         tvb, offset, apwlen, TRUE);
6970                                 COUNT_BYTES(apwlen);
6971                         }
6972
6973                         if(upwlen){
6974                                 proto_item *item;
6975
6976                                 /* password, Unicode */
6977                                 CHECK_BYTE_COUNT(upwlen);
6978                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
6979                                         tvb, offset, upwlen, TRUE);
6980
6981                                 if (upwlen > 24) {
6982                                         proto_tree *subtree;
6983
6984                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
6985
6986                                         dissect_ntlmv2_response(
6987                                                 tvb, subtree, offset, upwlen);
6988                                 }
6989
6990                                 COUNT_BYTES(upwlen);
6991                         }
6992
6993                         break;
6994                 }
6995
6996                 /* Account Name */
6997                 an = get_unicode_or_ascii_string(tvb, &offset,
6998                         si->unicode, &an_len, FALSE, FALSE, &bc);
6999                 if (an == NULL)
7000                         goto endofcommand;
7001                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
7002                         an);
7003                 COUNT_BYTES(an_len);
7004
7005                 /* Primary domain */
7006                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
7007                  * byte in front of this, at least if all the strings are
7008                  * ASCII and the account name is empty. Another bug?
7009                  */
7010                 dn = get_unicode_or_ascii_string(tvb, &offset,
7011                         si->unicode, &dn_len, FALSE, FALSE, &bc);
7012                 if (dn == NULL)
7013                         goto endofcommand;
7014                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7015                         offset, dn_len, dn);
7016                 COUNT_BYTES(dn_len);
7017
7018                 if (check_col(pinfo->cinfo, COL_INFO)) {
7019                         col_append_str(pinfo->cinfo, COL_INFO, ", User: ");
7020
7021                         if (!dn[0] && !an[0])
7022                                 col_append_str(pinfo->cinfo, COL_INFO,
7023                                                 "anonymous");
7024                         else
7025                                 col_append_fstr(pinfo->cinfo, COL_INFO,
7026                                                 "%s\\%s",
7027                                                 format_text(dn, strlen(dn)),
7028                                                 format_text(an, strlen(an)));
7029                 }
7030
7031                 /* OS */
7032                 an = get_unicode_or_ascii_string(tvb, &offset,
7033                         si->unicode, &an_len, FALSE, FALSE, &bc);
7034                 if (an == NULL)
7035                         goto endofcommand;
7036                 proto_tree_add_string(tree, hf_smb_os, tvb,
7037                         offset, an_len, an);
7038                 COUNT_BYTES(an_len);
7039
7040                 /* LANMAN */
7041                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7042                  * padding/null string/whatever in front of this. W2K doesn't
7043                  * appear to. I suspect that's a bug that got fixed; I also
7044                  * suspect that, in practice, nobody ever looks at that field
7045                  * because the bug didn't appear to get fixed until NT 5.0....
7046                  */
7047                 an = get_unicode_or_ascii_string(tvb, &offset,
7048                         si->unicode, &an_len, FALSE, FALSE, &bc);
7049                 if (an == NULL)
7050                         goto endofcommand;
7051                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
7052                         offset, an_len, an);
7053                 COUNT_BYTES(an_len);
7054         }
7055
7056         END_OF_SMB
7057
7058         if (cmd != 0xff) {      /* there is an andX command */
7059                 if (andxoffset < offset)
7060                         THROW(ReportedBoundsError);
7061                 pinfo->private_data = si;
7062                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7063         }
7064
7065         return offset;
7066 }
7067
7068 static int
7069 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7070 {
7071         guint8  wc, cmd=0xff;
7072         guint16 andxoffset=0, bc;
7073         guint16 sbloblen=0;
7074         smb_info_t *si = pinfo->private_data;
7075         int an_len;
7076         const char *an;
7077
7078         DISSECTOR_ASSERT(si);
7079
7080         WORD_COUNT;
7081
7082         if(!pinfo->fd->flags.visited && si->sip && si->sip->extra_info &&
7083             si->sip->extra_info_type==SMB_EI_UID){
7084                 smb_uid_t *smb_uid;
7085
7086                 smb_uid=si->sip->extra_info;
7087                 smb_uid->logged_in=pinfo->fd->num;
7088                 se_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
7089         }
7090
7091         /* next smb command */
7092         cmd = tvb_get_guint8(tvb, offset);
7093         if(cmd!=0xff){
7094                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7095         } else {
7096                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7097         }
7098         offset += 1;
7099
7100         /* reserved byte */
7101         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7102         offset += 1;
7103
7104         /* andxoffset */
7105         andxoffset = tvb_get_letohs(tvb, offset);
7106         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7107         offset += 2;
7108
7109         /* flags */
7110         offset = dissect_setup_action(tvb, tree, offset);
7111
7112         if(wc==4){
7113                 /* security blob length */
7114                 sbloblen = tvb_get_letohs(tvb, offset);
7115                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7116                 offset += 2;
7117         }
7118
7119         BYTE_COUNT;
7120
7121         if(wc==4) {
7122                 proto_item *blob_item;
7123
7124                 /* security blob */
7125                 /* dont try to eat too much of we might get an exception on
7126                  * short frames and then we will not see anything at all
7127                  * of the security blob.
7128                  */
7129                 if(sbloblen>tvb_length_remaining(tvb,offset)){
7130                         sbloblen=tvb_length_remaining(tvb,offset);
7131                 }
7132                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7133                                                 tvb, offset, sbloblen, TRUE);
7134
7135                 if(sbloblen){
7136                         tvbuff_t *blob_tvb;
7137                         proto_tree *blob_tree;
7138
7139                         blob_tree = proto_item_add_subtree(blob_item,
7140                                                            ett_smb_secblob);
7141                         CHECK_BYTE_COUNT(sbloblen);
7142
7143                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen,
7144                                                     sbloblen);
7145
7146                         if (si && si->ct && si->ct->raw_ntlmssp &&
7147                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
7148                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7149                                          blob_tree);
7150
7151                         }
7152                         else {
7153                           call_dissector(gssapi_handle, blob_tvb, pinfo,
7154                                          blob_tree);
7155
7156                         }
7157
7158                         COUNT_BYTES(sbloblen);
7159                 }
7160         }
7161
7162         /* OS */
7163         an = get_unicode_or_ascii_string(tvb, &offset,
7164                 si->unicode, &an_len, FALSE, FALSE, &bc);
7165         if (an == NULL)
7166                 goto endofcommand;
7167         proto_tree_add_string(tree, hf_smb_os, tvb,
7168                 offset, an_len, an);
7169         COUNT_BYTES(an_len);
7170
7171         /* LANMAN */
7172         an = get_unicode_or_ascii_string(tvb, &offset,
7173                 si->unicode, &an_len, FALSE, FALSE, &bc);
7174         if (an == NULL)
7175                 goto endofcommand;
7176         proto_tree_add_string(tree, hf_smb_lanman, tvb,
7177                 offset, an_len, an);
7178         COUNT_BYTES(an_len);
7179
7180         if((wc==3)||(wc==4)) {
7181                 /* Primary domain */
7182                 an = get_unicode_or_ascii_string(tvb, &offset,
7183                         si->unicode, &an_len, FALSE, FALSE, &bc);
7184                 if (an == NULL)
7185                         goto endofcommand;
7186                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7187                         offset, an_len, an);
7188                 COUNT_BYTES(an_len);
7189         }
7190
7191         END_OF_SMB
7192
7193         if (cmd != 0xff) {      /* there is an andX command */
7194                 if (andxoffset < offset)
7195                         THROW(ReportedBoundsError);
7196                 pinfo->private_data = si;
7197                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7198         }
7199
7200         return offset;
7201 }
7202
7203
7204 static int
7205 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7206 {
7207         guint8  wc, cmd=0xff;
7208         guint16 andxoffset=0;
7209         guint16 bc;
7210
7211         WORD_COUNT;
7212
7213         /* next smb command */
7214         cmd = tvb_get_guint8(tvb, offset);
7215         if(cmd!=0xff){
7216                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7217         } else {
7218                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7219         }
7220         offset += 1;
7221
7222         /* reserved byte */
7223         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7224         offset += 1;
7225
7226         /* andxoffset */
7227         andxoffset = tvb_get_letohs(tvb, offset);
7228         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7229         offset += 2;
7230
7231         BYTE_COUNT;
7232
7233         END_OF_SMB
7234
7235         if (cmd != 0xff) {      /* there is an andX command */
7236                 if (andxoffset < offset)
7237                         THROW(ReportedBoundsError);
7238                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7239         }
7240
7241         return offset;
7242 }
7243
7244
7245 static const true_false_string tfs_connect_support_search = {
7246         "Exclusive search bits supported",
7247         "Exclusive search bits not supported"
7248 };
7249 static const true_false_string tfs_connect_support_in_dfs = {
7250         "Share is in Dfs",
7251         "Share isn't in Dfs"
7252 };
7253
7254 static int
7255 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7256 {
7257         guint16 mask;
7258         proto_item *item;
7259         proto_tree *tree;
7260
7261         mask = tvb_get_letohs(tvb, offset);
7262
7263         if(parent_tree){
7264                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7265                         "Optional Support: 0x%04x", mask);
7266                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
7267
7268                 proto_tree_add_boolean(tree, hf_smb_connect_support_search,
7269                         tvb, offset, 2, mask);
7270                 proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
7271                         tvb, offset, 2, mask);
7272         }
7273
7274         offset += 2;
7275
7276         return offset;
7277 }
7278
7279 static const true_false_string tfs_disconnect_tid = {
7280         "DISCONNECT TID",
7281         "Do NOT disconnect TID"
7282 };
7283
7284 static int
7285 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7286 {
7287         guint16 mask;
7288         proto_item *item;
7289         proto_tree *tree;
7290
7291         mask = tvb_get_letohs(tvb, offset);
7292
7293         if(parent_tree){
7294                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7295                         "Flags: 0x%04x", mask);
7296                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
7297
7298                 proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
7299                         tvb, offset, 2, mask);
7300         }
7301
7302         offset += 2;
7303
7304         return offset;
7305 }
7306
7307 static int
7308 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7309 {
7310         guint8  wc, cmd=0xff;
7311         guint16 bc;
7312         guint16 andxoffset=0, pwlen=0;
7313         smb_info_t *si = pinfo->private_data;
7314         int an_len;
7315         const char *an;
7316
7317         DISSECTOR_ASSERT(si);
7318
7319         WORD_COUNT;
7320
7321         /* next smb command */
7322         cmd = tvb_get_guint8(tvb, offset);
7323         if(cmd!=0xff){
7324                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7325         } else {
7326                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7327         }
7328         offset += 1;
7329
7330         /* reserved byte */
7331         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7332         offset += 1;
7333
7334         /* andxoffset */
7335         andxoffset = tvb_get_letohs(tvb, offset);
7336         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7337         offset += 2;
7338
7339         /* flags */
7340         offset = dissect_connect_flags(tvb, tree, offset);
7341
7342         /* password length*/
7343         pwlen = tvb_get_letohs(tvb, offset);
7344         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
7345         offset += 2;
7346
7347         BYTE_COUNT;
7348
7349         /* password */
7350         CHECK_BYTE_COUNT(pwlen);
7351         proto_tree_add_item(tree, hf_smb_password,
7352                 tvb, offset, pwlen, TRUE);
7353         COUNT_BYTES(pwlen);
7354
7355         /* Path */
7356         an = get_unicode_or_ascii_string(tvb, &offset,
7357                 si->unicode, &an_len, FALSE, FALSE, &bc);
7358         if (an == NULL)
7359                 goto endofcommand;
7360         proto_tree_add_string(tree, hf_smb_path, tvb,
7361                 offset, an_len, an);
7362         COUNT_BYTES(an_len);
7363
7364         /* store it for the tid->name/openframe/closeframe matching in
7365          * dissect_smb_tid()   called from the response.
7366          */
7367         if((!pinfo->fd->flags.visited) && si->sip && an){
7368                 si->sip->extra_info_type=SMB_EI_TIDNAME;
7369                 si->sip->extra_info=se_strdup(an);
7370         }
7371
7372         if (check_col(pinfo->cinfo, COL_INFO)) {
7373                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
7374                     format_text(an, strlen(an)));
7375         }
7376
7377         /*
7378          * NOTE: the Service string is always ASCII, even if the
7379          * "strings are Unicode" bit is set in the flags2 field
7380          * of the SMB.
7381          */
7382
7383         /* Service */
7384         /* XXX - what if this runs past bc? */
7385         an_len = tvb_strsize(tvb, offset);
7386         CHECK_BYTE_COUNT(an_len);
7387         an = tvb_get_ptr(tvb, offset, an_len);
7388         proto_tree_add_string(tree, hf_smb_service, tvb,
7389                 offset, an_len, an);
7390         COUNT_BYTES(an_len);
7391
7392         END_OF_SMB
7393
7394         if (cmd != 0xff) {      /* there is an andX command */
7395                 if (andxoffset < offset)
7396                         THROW(ReportedBoundsError);
7397                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7398         }
7399
7400         return offset;
7401 }
7402
7403
7404 static int
7405 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7406 {
7407         guint8  wc, wleft, cmd=0xff;
7408         guint16 andxoffset=0;
7409         guint16 bc;
7410         int an_len;
7411         const char *an;
7412         smb_info_t *si = pinfo->private_data;
7413
7414         DISSECTOR_ASSERT(si);
7415
7416         WORD_COUNT;
7417
7418         wleft = wc;     /* this is at least 1 */
7419
7420         /* next smb command */
7421         cmd = tvb_get_guint8(tvb, offset);
7422         if(cmd!=0xff){
7423                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7424         } else {
7425                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
7426         }
7427         offset += 1;
7428
7429         /* reserved byte */
7430         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7431         offset += 1;
7432
7433         wleft--;
7434         if (wleft == 0)
7435                 goto bytecount;
7436
7437         /* andxoffset */
7438         andxoffset = tvb_get_letohs(tvb, offset);
7439         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7440         offset += 2;
7441         wleft--;
7442         if (wleft == 0)
7443                 goto bytecount;
7444
7445         /* flags */
7446         offset = dissect_connect_support_bits(tvb, tree, offset);
7447         wleft--;
7448
7449         /* XXX - I've seen captures where this is 7, but I have no
7450            idea how to dissect it.  I'm guessing the third word
7451            contains connect support bits, which looks plausible
7452            from the values I've seen. */
7453
7454         while (wleft != 0) {
7455                 proto_tree_add_text(tree, tvb, offset, 2,
7456                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
7457                 offset += 2;
7458                 wleft--;
7459         }
7460
7461         BYTE_COUNT;
7462
7463         /*
7464          * NOTE: even though the SNIA CIFS spec doesn't say there's
7465          * a "Service" string if there's a word count of 2, the
7466          * document at
7467          *
7468          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
7469          *
7470          * (it's in an ugly format - text intended to be sent to a
7471          * printer, with backspaces and overstrikes used for boldfacing
7472          * and underlining; UNIX "col -b" can be used to strip the
7473          * overstrikes out) says there's a "Service" string there, and
7474          * some network traffic has it.
7475          */
7476
7477         /*
7478          * NOTE: the Service string is always ASCII, even if the
7479          * "strings are Unicode" bit is set in the flags2 field
7480          * of the SMB.
7481          */
7482
7483         /* Service */
7484         /* XXX - what if this runs past bc? */
7485         an_len = tvb_strsize(tvb, offset);
7486         CHECK_BYTE_COUNT(an_len);
7487         an = tvb_get_ptr(tvb, offset, an_len);
7488         proto_tree_add_string(tree, hf_smb_service, tvb,
7489                 offset, an_len, an);
7490         COUNT_BYTES(an_len);
7491
7492         /* Now when we know the service type, store it so that we know it for later commands down
7493            this tree */
7494         if(!pinfo->fd->flags.visited){
7495                 /* Remove any previous entry for this TID */
7496                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
7497                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
7498                 }
7499                 if(strcmp(an,"IPC") == 0){
7500                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
7501                 } else {
7502                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_NORMAL);
7503                 }
7504         }
7505
7506
7507         if(wc==3){
7508                 if (bc != 0) {
7509                         /*
7510                          * Sometimes this isn't present.
7511                          */
7512
7513                         /* Native FS */
7514                         an = get_unicode_or_ascii_string(tvb, &offset,
7515                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
7516                                 &bc);
7517                         if (an == NULL)
7518                                 goto endofcommand;
7519                         proto_tree_add_string(tree, hf_smb_fs, tvb,
7520                                 offset, an_len, an);
7521                         COUNT_BYTES(an_len);
7522                 }
7523         }
7524
7525         END_OF_SMB
7526
7527         if (cmd != 0xff) {      /* there is an andX command */
7528                 if (andxoffset < offset)
7529                         THROW(ReportedBoundsError);
7530                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
7531         }
7532
7533         return offset;
7534 }
7535
7536
7537
7538 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7539    NT Transaction command  begins here
7540    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7541 #define NT_TRANS_CREATE         1
7542 #define NT_TRANS_IOCTL          2
7543 #define NT_TRANS_SSD            3
7544 #define NT_TRANS_NOTIFY         4
7545 #define NT_TRANS_RENAME         5
7546 #define NT_TRANS_QSD            6
7547 #define NT_TRANS_GET_USER_QUOTA 7
7548 #define NT_TRANS_SET_USER_QUOTA 8
7549 const value_string nt_cmd_vals[] = {
7550         {NT_TRANS_CREATE,               "NT CREATE"},
7551         {NT_TRANS_IOCTL,                "NT IOCTL"},
7552         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
7553         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
7554         {NT_TRANS_RENAME,               "NT RENAME"},
7555         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
7556         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
7557         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
7558         {0, NULL}
7559 };
7560
7561 static const value_string nt_ioctl_isfsctl_vals[] = {
7562         {0,     "Device IOCTL"},
7563         {1,     "FS control : FSCTL"},
7564         {0, NULL}
7565 };
7566
7567 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
7568 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
7569         "Apply the command to share root handle (MUST BE Dfs)",
7570         "Apply to this share",
7571 };
7572
7573 static const value_string nt_notify_action_vals[] = {
7574         {1,     "ADDED (object was added"},
7575         {2,     "REMOVED (object was removed)"},
7576         {3,     "MODIFIED (object was modified)"},
7577         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
7578         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
7579         {6,     "ADDED_STREAM (a stream was added)"},
7580         {7,     "REMOVED_STREAM (a stream was removed)"},
7581         {8,     "MODIFIED_STREAM (a stream was modified)"},
7582         {0, NULL}
7583 };
7584
7585 static const value_string watch_tree_vals[] = {
7586         {0,     "Current directory only"},
7587         {1,     "Subdirectories also"},
7588         {0, NULL}
7589 };
7590
7591 #define NT_NOTIFY_STREAM_WRITE  0x00000800
7592 #define NT_NOTIFY_STREAM_SIZE   0x00000400
7593 #define NT_NOTIFY_STREAM_NAME   0x00000200
7594 #define NT_NOTIFY_SECURITY      0x00000100
7595 #define NT_NOTIFY_EA            0x00000080
7596 #define NT_NOTIFY_CREATION      0x00000040
7597 #define NT_NOTIFY_LAST_ACCESS   0x00000020
7598 #define NT_NOTIFY_LAST_WRITE    0x00000010
7599 #define NT_NOTIFY_SIZE          0x00000008
7600 #define NT_NOTIFY_ATTRIBUTES    0x00000004
7601 #define NT_NOTIFY_DIR_NAME      0x00000002
7602 #define NT_NOTIFY_FILE_NAME     0x00000001
7603 static const true_false_string tfs_nt_notify_stream_write = {
7604         "Notify on changes to STREAM WRITE",
7605         "Do NOT notify on changes to stream write",
7606 };
7607 static const true_false_string tfs_nt_notify_stream_size = {
7608         "Notify on changes to STREAM SIZE",
7609         "Do NOT notify on changes to stream size",
7610 };
7611 static const true_false_string tfs_nt_notify_stream_name = {
7612         "Notify on changes to STREAM NAME",
7613         "Do NOT notify on changes to stream name",
7614 };
7615 static const true_false_string tfs_nt_notify_security = {
7616         "Notify on changes to SECURITY",
7617         "Do NOT notify on changes to security",
7618 };
7619 static const true_false_string tfs_nt_notify_ea = {
7620         "Notify on changes to EA",
7621         "Do NOT notify on changes to EA",
7622 };
7623 static const true_false_string tfs_nt_notify_creation = {
7624         "Notify on changes to CREATION TIME",
7625         "Do NOT notify on changes to creation time",
7626 };
7627 static const true_false_string tfs_nt_notify_last_access = {
7628         "Notify on changes to LAST ACCESS TIME",
7629         "Do NOT notify on changes to last access time",
7630 };
7631 static const true_false_string tfs_nt_notify_last_write = {
7632         "Notify on changes to LAST WRITE TIME",
7633         "Do NOT notify on changes to last write time",
7634 };
7635 static const true_false_string tfs_nt_notify_size = {
7636         "Notify on changes to SIZE",
7637         "Do NOT notify on changes to size",
7638 };
7639 static const true_false_string tfs_nt_notify_attributes = {
7640         "Notify on changes to ATTRIBUTES",
7641         "Do NOT notify on changes to attributes",
7642 };
7643 static const true_false_string tfs_nt_notify_dir_name = {
7644         "Notify on changes to DIR NAME",
7645         "Do NOT notify on changes to dir name",
7646 };
7647 static const true_false_string tfs_nt_notify_file_name = {
7648         "Notify on changes to FILE NAME",
7649         "Do NOT notify on changes to file name",
7650 };
7651
7652 const value_string create_disposition_vals[] = {
7653         {0,     "Supersede (supersede existing file (if it exists))"},
7654         {1,     "Open (if file exists open it, else fail)"},
7655         {2,     "Create (if file exists fail, else create it)"},
7656         {3,     "Open If (if file exists open it, else create it)"},
7657         {4,     "Overwrite (if file exists overwrite, else fail)"},
7658         {5,     "Overwrite If (if file exists overwrite, else create it)"},
7659         {0, NULL}
7660 };
7661
7662 const value_string impersonation_level_vals[] = {
7663         {0,     "Anonymous"},
7664         {1,     "Identification"},
7665         {2,     "Impersonation"},
7666         {3,     "Delegation"},
7667         {0, NULL}
7668 };
7669
7670 static const true_false_string tfs_nt_security_flags_context_tracking = {
7671         "Security tracking mode is DYNAMIC",
7672         "Security tracking mode is STATIC",
7673 };
7674
7675 static const true_false_string tfs_nt_security_flags_effective_only = {
7676         "ONLY ENABLED aspects of the client's security context are available",
7677         "ALL aspects of the client's security context are available",
7678 };
7679
7680 static const true_false_string tfs_nt_create_bits_oplock = {
7681         "Requesting OPLOCK",
7682         "Does NOT request oplock"
7683 };
7684
7685 static const true_false_string tfs_nt_create_bits_boplock = {
7686         "Requesting BATCH OPLOCK",
7687         "Does NOT request batch oplock"
7688 };
7689
7690 /*
7691  * XXX - must be a directory, and can be a file, or can be a directory,
7692  * and must be a file?
7693  */
7694 static const true_false_string tfs_nt_create_bits_dir = {
7695         "Target of open MUST be a DIRECTORY",
7696         "Target of open can be a file"
7697 };
7698
7699 static const true_false_string tfs_nt_create_bits_ext_resp = {
7700   "Extended responses required",
7701   "Extended responses NOT required"
7702 };
7703
7704 static const true_false_string tfs_nt_access_mask_generic_read = {
7705         "GENERIC READ is set",
7706         "Generic read is NOT set"
7707 };
7708 static const true_false_string tfs_nt_access_mask_generic_write = {
7709         "GENERIC WRITE is set",
7710         "Generic write is NOT set"
7711 };
7712 static const true_false_string tfs_nt_access_mask_generic_execute = {
7713         "GENERIC EXECUTE is set",
7714         "Generic execute is NOT set"
7715 };
7716 static const true_false_string tfs_nt_access_mask_generic_all = {
7717         "GENERIC ALL is set",
7718         "Generic all is NOT set"
7719 };
7720 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
7721         "MAXIMUM ALLOWED is set",
7722         "Maximum allowed is NOT set"
7723 };
7724 static const true_false_string tfs_nt_access_mask_system_security = {
7725         "SYSTEM SECURITY is set",
7726         "System security is NOT set"
7727 };
7728 static const true_false_string tfs_nt_access_mask_synchronize = {
7729         "Can wait on handle to SYNCHRONIZE on completion of I/O",
7730         "Can NOT wait on handle to synchronize on completion of I/O"
7731 };
7732 static const true_false_string tfs_nt_access_mask_write_owner = {
7733         "Can WRITE OWNER (take ownership)",
7734         "Can NOT write owner (take ownership)"
7735 };
7736 static const true_false_string tfs_nt_access_mask_write_dac = {
7737         "OWNER may WRITE the DAC",
7738         "Owner may NOT write to the DAC"
7739 };
7740 static const true_false_string tfs_nt_access_mask_read_control = {
7741         "READ ACCESS to owner, group and ACL of the SID",
7742         "Read access is NOT granted to owner, group and ACL of the SID"
7743 };
7744 static const true_false_string tfs_nt_access_mask_delete = {
7745         "DELETE access",
7746         "NO delete access"
7747 };
7748 static const true_false_string tfs_nt_access_mask_write_attributes = {
7749         "WRITE ATTRIBUTES access",
7750         "NO write attributes access"
7751 };
7752 static const true_false_string tfs_nt_access_mask_read_attributes = {
7753         "READ ATTRIBUTES access",
7754         "NO read attributes access"
7755 };
7756 static const true_false_string tfs_nt_access_mask_delete_child = {
7757         "DELETE CHILD access",
7758         "NO delete child access"
7759 };
7760 static const true_false_string tfs_nt_access_mask_execute = {
7761         "EXECUTE access",
7762         "NO execute access"
7763 };
7764 static const true_false_string tfs_nt_access_mask_write_ea = {
7765         "WRITE EXTENDED ATTRIBUTES access",
7766         "NO write extended attributes access"
7767 };
7768 static const true_false_string tfs_nt_access_mask_read_ea = {
7769         "READ EXTENDED ATTRIBUTES access",
7770         "NO read extended attributes access"
7771 };
7772 static const true_false_string tfs_nt_access_mask_append = {
7773         "APPEND access",
7774         "NO append access"
7775 };
7776 static const true_false_string tfs_nt_access_mask_write = {
7777         "WRITE access",
7778         "NO write access"
7779 };
7780 static const true_false_string tfs_nt_access_mask_read = {
7781         "READ access",
7782         "NO read access"
7783 };
7784
7785 static const true_false_string tfs_nt_share_access_delete = {
7786         "Object can be shared for DELETE",
7787         "Object can NOT be shared for delete"
7788 };
7789 static const true_false_string tfs_nt_share_access_write = {
7790         "Object can be shared for WRITE",
7791         "Object can NOT be shared for write"
7792 };
7793 static const true_false_string tfs_nt_share_access_read = {
7794         "Object can be shared for READ",
7795         "Object can NOT be shared for read"
7796 };
7797
7798 static const value_string oplock_level_vals[] = {
7799         {0,     "No oplock granted"},
7800         {1,     "Exclusive oplock granted"},
7801         {2,     "Batch oplock granted"},
7802         {3,     "Level II oplock granted"},
7803         {0, NULL}
7804 };
7805
7806 static const value_string device_type_vals[] = {
7807         {0x00000001,    "Beep"},
7808         {0x00000002,    "CDROM"},
7809         {0x00000003,    "CDROM Filesystem"},
7810         {0x00000004,    "Controller"},
7811         {0x00000005,    "Datalink"},
7812         {0x00000006,    "Dfs"},
7813         {0x00000007,    "Disk"},
7814         {0x00000008,    "Disk Filesystem"},
7815         {0x00000009,    "Filesystem"},
7816         {0x0000000a,    "Inport Port"},
7817         {0x0000000b,    "Keyboard"},
7818         {0x0000000c,    "Mailslot"},
7819         {0x0000000d,    "MIDI-In"},
7820         {0x0000000e,    "MIDI-Out"},
7821         {0x0000000f,    "Mouse"},
7822         {0x00000010,    "Multi UNC Provider"},
7823         {0x00000011,    "Named Pipe"},
7824         {0x00000012,    "Network"},
7825         {0x00000013,    "Network Browser"},
7826         {0x00000014,    "Network Filesystem"},
7827         {0x00000015,    "NULL"},
7828         {0x00000016,    "Parallel Port"},
7829         {0x00000017,    "Physical card"},
7830         {0x00000018,    "Printer"},
7831         {0x00000019,    "Scanner"},
7832         {0x0000001a,    "Serial Mouse port"},
7833         {0x0000001b,    "Serial port"},
7834         {0x0000001c,    "Screen"},
7835         {0x0000001d,    "Sound"},
7836         {0x0000001e,    "Streams"},
7837         {0x0000001f,    "Tape"},
7838         {0x00000020,    "Tape Filesystem"},
7839         {0x00000021,    "Transport"},
7840         {0x00000022,    "Unknown"},
7841         {0x00000023,    "Video"},
7842         {0x00000024,    "Virtual Disk"},
7843         {0x00000025,    "WAVE-In"},
7844         {0x00000026,    "WAVE-Out"},
7845         {0x00000027,    "8042 Port"},
7846         {0x00000028,    "Network Redirector"},
7847         {0x00000029,    "Battery"},
7848         {0x0000002a,    "Bus Extender"},
7849         {0x0000002b,    "Modem"},
7850         {0x0000002c,    "VDM"},
7851         {0,     NULL}
7852 };
7853
7854 static const value_string is_directory_vals[] = {
7855         {0,     "This is NOT a directory"},
7856         {1,     "This is a DIRECTORY"},
7857         {0, NULL}
7858 };
7859
7860 typedef struct _nt_trans_data {
7861         int subcmd;
7862         guint32 sd_len;
7863         guint32 ea_len;
7864 } nt_trans_data;
7865
7866
7867
7868 static int
7869 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7870 {
7871         guint8 mask;
7872         proto_item *item;
7873         proto_tree *tree;
7874
7875         mask = tvb_get_guint8(tvb, offset);
7876
7877         if(parent_tree){
7878                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7879                         "Security Flags: 0x%02x", mask);
7880                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
7881
7882                 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
7883                         tvb, offset, 1, mask);
7884                 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
7885                         tvb, offset, 1, mask);
7886         }
7887
7888         offset += 1;
7889
7890         return offset;
7891 }
7892
7893 /*
7894  * XXX - there are some more flags in the description of "ZwOpenFile()"
7895  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
7896  * the wire as well?  (The spec at
7897  *
7898  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
7899  *
7900  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
7901  * via the SMB protocol.  The NT redirector should convert this option
7902  * to FILE_WRITE_THROUGH."
7903  *
7904  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
7905  * values one would infer from their position in the list of flags for
7906  * "ZwOpenFile()".  Most of the others probably have those values
7907  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
7908  * which might go over the wire (for the benefit of backup/restore software).
7909  */
7910 static const true_false_string tfs_nt_create_options_directory = {
7911         "File being created/opened must be a directory",
7912         "File being created/opened must not be a directory"
7913 };
7914 static const true_false_string tfs_nt_create_options_write_through = {
7915         "Writes should flush buffered data before completing",
7916         "Writes need not flush buffered data before completing"
7917 };
7918 static const true_false_string tfs_nt_create_options_sequential_only = {
7919         "The file will only be accessed sequentially",
7920         "The file might not only be accessed sequentially"
7921 };
7922 static const true_false_string tfs_nt_create_options_no_intermediate_buffering = {
7923         "NO intermediate buffering is allowed",
7924         "Intermediate buffering is allowed"
7925 };
7926 static const true_false_string tfs_nt_create_options_sync_io_alert = {
7927         "All operations SYNCHRONOUS, waits subject to termination from alert",
7928         "Operations NOT necessarily synchronous"
7929 };
7930 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
7931         "All operations SYNCHRONOUS, waits not subject to alert",
7932         "Operations NOT necessarily synchronous"
7933 };
7934 static const true_false_string tfs_nt_create_options_non_directory = {
7935         "File being created/opened must not be a directory",
7936         "File being created/opened must be a directory"
7937 };
7938 static const true_false_string tfs_nt_create_options_create_tree_connection = {
7939         "Create Tree Connections is SET",
7940         "Create Tree Connections is NOT set"
7941 };
7942 static const true_false_string tfs_nt_create_options_complete_if_oplocked = {
7943         "Complete if oplocked is SET",
7944         "Complete if oplocked is NOT set"
7945 };
7946 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
7947         "The client does not understand extended attributes",
7948         "The client understands extended attributes"
7949 };
7950 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
7951         "The client understands only 8.3 file names",
7952         "The client understands long file names"
7953 };
7954 static const true_false_string tfs_nt_create_options_random_access = {
7955         "The file will be accessed randomly",
7956         "The file will not be accessed randomly"
7957 };
7958 static const true_false_string tfs_nt_create_options_delete_on_close = {
7959         "The file should be deleted when it is closed",
7960         "The file should not be deleted when it is closed"
7961 };
7962 static const true_false_string tfs_nt_create_options_open_by_fileid = {
7963         "OpenByFileID bit is SET",
7964         "OpenByFileID is NOT set"
7965 };
7966 static const true_false_string tfs_nt_create_options_backup_intent = {
7967         "This is a create with BACKUP INTENT",
7968         "This is a normal create"
7969 };
7970 static const true_false_string tfs_nt_create_options_no_compression = {
7971         "Open/Create with NO Compression",
7972         "Compression is allowed for Open/Create"
7973 };
7974 static const true_false_string tfs_nt_create_options_reserve_opfilter = {
7975         "Reserve Opfilter is SET",
7976         "Reserve Opfilter is NOT set"
7977 };
7978 static const true_false_string tfs_nt_create_options_open_reparse_point = {
7979         "Open a Reparse Point",
7980         "Normal open"
7981 };
7982 static const true_false_string tfs_nt_create_options_open_no_recall = {
7983         "Open No Recall is SET",
7984         "Open no recall is NOT set"
7985 };
7986 static const true_false_string tfs_nt_create_options_open_for_free_space_query = {
7987         "This is an OPEN FOR FREE SPACE QUERY",
7988         "This is NOT an open for free space query"
7989 };
7990
7991 int
7992 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7993 {
7994         guint32 mask;
7995         proto_item *item;
7996         proto_tree *tree;
7997
7998         mask = tvb_get_letohl(tvb, offset);
7999
8000         if(parent_tree){
8001                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
8002                         "Completion Filter: 0x%08x", mask);
8003                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
8004
8005                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
8006                         tvb, offset, 4, mask);
8007                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
8008                         tvb, offset, 4, mask);
8009                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
8010                         tvb, offset, 4, mask);
8011                 proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
8012                         tvb, offset, 4, mask);
8013                 proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
8014                         tvb, offset, 4, mask);
8015                 proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
8016                         tvb, offset, 4, mask);
8017                 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
8018                         tvb, offset, 4, mask);
8019                 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
8020                         tvb, offset, 4, mask);
8021                 proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
8022                         tvb, offset, 4, mask);
8023                 proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
8024                         tvb, offset, 4, mask);
8025                 proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
8026                         tvb, offset, 4, mask);
8027                 proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
8028                         tvb, offset, 4, mask);
8029         }
8030
8031         offset += 4;
8032         return offset;
8033 }
8034
8035 static int
8036 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8037 {
8038         guint8 mask;
8039         proto_item *item;
8040         proto_tree *tree;
8041
8042         mask = tvb_get_guint8(tvb, offset);
8043
8044         if(parent_tree){
8045                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
8046                         "Completion Filter: 0x%02x", mask);
8047                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
8048
8049                 proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
8050                         tvb, offset, 1, mask);
8051         }
8052
8053         offset += 1;
8054         return offset;
8055 }
8056
8057 /*
8058  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
8059  * Native API Reference".
8060  */
8061 static const true_false_string tfs_nt_qsd_owner = {
8062         "Requesting OWNER security information",
8063         "NOT requesting owner security information",
8064 };
8065
8066 static const true_false_string tfs_nt_qsd_group = {
8067         "Requesting GROUP security information",
8068         "NOT requesting group security information",
8069 };
8070
8071 static const true_false_string tfs_nt_qsd_dacl = {
8072         "Requesting DACL security information",
8073         "NOT requesting DACL security information",
8074 };
8075
8076 static const true_false_string tfs_nt_qsd_sacl = {
8077         "Requesting SACL security information",
8078         "NOT requesting SACL security information",
8079 };
8080
8081 #define NT_QSD_OWNER    0x00000001
8082 #define NT_QSD_GROUP    0x00000002
8083 #define NT_QSD_DACL     0x00000004
8084 #define NT_QSD_SACL     0x00000008
8085
8086 int
8087 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8088 {
8089         guint32 mask;
8090         proto_item *item;
8091         proto_tree *tree;
8092
8093         mask = tvb_get_letohl(tvb, offset);
8094
8095         if(parent_tree){
8096                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
8097                         "Security Information: 0x%08x", mask);
8098                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
8099
8100                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
8101                         tvb, offset, 4, mask);
8102                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
8103                         tvb, offset, 4, mask);
8104                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
8105                         tvb, offset, 4, mask);
8106                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
8107                         tvb, offset, 4, mask);
8108         }
8109
8110         offset += 4;
8111
8112         return offset;
8113 }
8114
8115 static int
8116 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
8117 {
8118         int old_offset, old_sid_offset;
8119         guint32 qsize;
8120
8121         do {
8122                 old_offset=offset;
8123
8124                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8125                 qsize=tvb_get_letohl(tvb, offset);
8126                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8127                 COUNT_BYTES_TRANS_SUBR(4);
8128
8129                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8130                 /* length of SID */
8131                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8132                 COUNT_BYTES_TRANS_SUBR(4);
8133
8134                 /* 16 unknown bytes */
8135                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8136                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8137                             offset, 8, TRUE);
8138                 COUNT_BYTES_TRANS_SUBR(8);
8139
8140                 /* number of bytes for used quota */
8141                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8142                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
8143                 COUNT_BYTES_TRANS_SUBR(8);
8144
8145                 /* number of bytes for quota warning */
8146                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8147                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
8148                 COUNT_BYTES_TRANS_SUBR(8);
8149
8150                 /* number of bytes for quota limit */
8151                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8152                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
8153                 COUNT_BYTES_TRANS_SUBR(8);
8154
8155                 /* SID of the user */
8156                 old_sid_offset=offset;
8157                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8158                 *bcp -= (offset-old_sid_offset);
8159
8160                 if(qsize){
8161                         offset = old_offset+qsize;
8162                 }
8163         }while(qsize);
8164
8165
8166         return offset;
8167 }
8168
8169
8170 static int
8171 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)
8172 {
8173         proto_item *item = NULL;
8174         proto_tree *tree = NULL;
8175         smb_info_t *si;
8176         int old_offset = offset;
8177         guint16 bcp=bc; /* XXX fixme */
8178         struct access_mask_info *ami=NULL;
8179         tvbuff_t *ioctl_tvb;
8180
8181         si = (smb_info_t *)pinfo->private_data;
8182
8183         DISSECTOR_ASSERT(si);
8184
8185         if(parent_tree){
8186                 tvb_ensure_bytes_exist(tvb, offset, bc);
8187                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8188                                 "%s Data",
8189                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8190                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8191         }
8192
8193         switch(ntd->subcmd){
8194         case NT_TRANS_CREATE:
8195                 /* security descriptor */
8196                 if(ntd->sd_len){
8197                         offset = dissect_nt_sec_desc(
8198                                 tvb, offset, pinfo, tree, NULL, TRUE,
8199                                 ntd->sd_len, NULL);
8200                 }
8201
8202                 /* extended attributes */
8203                 if(ntd->ea_len){
8204                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8205                         offset += ntd->ea_len;
8206                 }
8207
8208                 break;
8209         case NT_TRANS_IOCTL:
8210                 /* ioctl data */
8211                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
8212                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, TRUE);
8213
8214
8215                 offset += bc;
8216
8217                 break;
8218         case NT_TRANS_SSD:
8219                 if(nti){
8220                         switch(nti->fid_type){
8221                         case SMB_FID_TYPE_FILE:
8222                                 ami= &smb_file_access_mask_info;
8223                                 break;
8224                         case SMB_FID_TYPE_DIR:
8225                                 ami= &smb_dir_access_mask_info;
8226                                 break;
8227                         }
8228                 }
8229
8230                 offset = dissect_nt_sec_desc(
8231                         tvb, offset, pinfo, tree, NULL, TRUE, bc, ami);
8232                 break;
8233         case NT_TRANS_NOTIFY:
8234                 break;
8235         case NT_TRANS_RENAME:
8236                 /* XXX not documented */
8237                 break;
8238         case NT_TRANS_QSD:
8239                 break;
8240         case NT_TRANS_GET_USER_QUOTA:
8241                 /* unknown 4 bytes */
8242                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8243                             offset, 4, TRUE);
8244                 offset += 4;
8245
8246                 /* length of SID */
8247                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8248                 offset +=4;
8249
8250                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8251                 break;
8252         case NT_TRANS_SET_USER_QUOTA:
8253                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8254                 break;
8255         }
8256
8257         /* ooops there were data we didnt know how to process */
8258         if((offset-old_offset) < bc){
8259                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8260                     bc - (offset-old_offset), TRUE);
8261                 offset += bc - (offset-old_offset);
8262         }
8263
8264         return offset;
8265 }
8266
8267 static int
8268 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)
8269 {
8270         proto_item *item = NULL;
8271         proto_tree *tree = NULL;
8272         smb_info_t *si;
8273         guint32 fn_len, create_flags, access_mask, file_attributes, share_access, create_options, create_disposition;
8274         const char *fn;
8275
8276         si = (smb_info_t *)pinfo->private_data;
8277
8278         DISSECTOR_ASSERT(si);
8279
8280         if(parent_tree){
8281                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8282                                 "%s Parameters",
8283                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8284                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8285         }
8286
8287         switch(ntd->subcmd){
8288         case NT_TRANS_CREATE:
8289                 /* Create flags */
8290                 create_flags=tvb_get_letohl(tvb, offset);
8291                 offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
8292                 bc -= 4;
8293
8294                 /* root directory fid */
8295                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8296                 COUNT_BYTES(4);
8297
8298                 /* nt access mask */
8299                 access_mask=tvb_get_letohl(tvb, offset);
8300                 offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
8301                 bc -= 4;
8302
8303                 /* allocation size */
8304                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8305                 COUNT_BYTES(8);
8306
8307                 /* Extended File Attributes */
8308                 file_attributes=tvb_get_letohl(tvb, offset);
8309                 offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
8310                 bc -= 4;
8311
8312                 /* share access */
8313                 share_access=tvb_get_letohl(tvb, offset);
8314                 offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
8315                 bc -= 4;
8316
8317                 /* create disposition */
8318                 create_disposition=tvb_get_letohl(tvb, offset);
8319                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8320                 COUNT_BYTES(4);
8321
8322                 /* create options */
8323                 create_options=tvb_get_letohl(tvb, offset);
8324                 offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
8325                 bc -= 4;
8326
8327                 /* sd length */
8328                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8329                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8330                 COUNT_BYTES(4);
8331
8332                 /* ea length */
8333                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8334                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8335                 COUNT_BYTES(4);
8336
8337                 /* file name len */
8338                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8339                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8340                 COUNT_BYTES(4);
8341
8342                 /* impersonation level */
8343                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8344                 COUNT_BYTES(4);
8345
8346                 /* security flags */
8347                 offset = dissect_nt_security_flags(tvb, tree, offset);
8348                 bc -= 1;
8349
8350                 /* file name */
8351                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8352                 if (fn != NULL) {
8353                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8354                                 fn);
8355                         COUNT_BYTES(fn_len);
8356                 }
8357
8358                 break;
8359         case NT_TRANS_IOCTL:
8360                 break;
8361         case NT_TRANS_SSD: {
8362                 guint16 fid;
8363                 smb_fid_info_t *fid_info;
8364
8365                 /* fid */
8366                 fid = tvb_get_letohs(tvb, offset);
8367                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8368                 offset += 2;
8369                 if(nti){
8370                         if(fid_info){
8371                                 nti->fid_type=fid_info->type;
8372                         } else {
8373                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8374                         }
8375                 }
8376
8377                 /* 2 reserved bytes */
8378                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8379                 offset += 2;
8380
8381                 /* security information */
8382                 offset = dissect_security_information_mask(tvb, tree, offset);
8383                 break;
8384         }
8385         case NT_TRANS_NOTIFY:
8386                 break;
8387         case NT_TRANS_RENAME:
8388                 /* XXX not documented */
8389                 break;
8390         case NT_TRANS_QSD: {
8391                 guint16 fid;
8392                 smb_fid_info_t *fid_info;
8393
8394                 /* fid */
8395                 fid = tvb_get_letohs(tvb, offset);
8396                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8397                 offset += 2;
8398                 if(nti){
8399                         if(fid_info){
8400                                 nti->fid_type=fid_info->type;
8401                         } else {
8402                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8403                         }
8404                 }
8405
8406                 /* 2 reserved bytes */
8407                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8408                 offset += 2;
8409
8410                 /* security information */
8411                 offset = dissect_security_information_mask(tvb, tree, offset);
8412                 break;
8413         }
8414         case NT_TRANS_GET_USER_QUOTA:
8415                 /* not decoded yet */
8416                 break;
8417         case NT_TRANS_SET_USER_QUOTA:
8418                 /* not decoded yet */
8419                 break;
8420         }
8421
8422         return offset;
8423 }
8424
8425 static int
8426 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8427 {
8428         proto_item *item = NULL;
8429         proto_tree *tree = NULL;
8430         int old_offset = offset;
8431         smb_info_t *si;
8432         smb_nt_transact_info_t *nti;
8433         smb_saved_info_t *sip;
8434
8435
8436         si = (smb_info_t *)pinfo->private_data;
8437         DISSECTOR_ASSERT(si);
8438         sip = si->sip;
8439         DISSECTOR_ASSERT(sip);
8440         nti=sip->extra_info;
8441
8442
8443         if(parent_tree){
8444                 tvb_ensure_bytes_exist(tvb, offset, len);
8445                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8446                                 "%s Setup",
8447                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8448                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8449         }
8450
8451         switch(ntd->subcmd){
8452         case NT_TRANS_CREATE:
8453                 break;
8454         case NT_TRANS_IOCTL: {
8455                 guint16 fid;
8456
8457                 /* function code */
8458                 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &nti->ioctl_function);
8459
8460                 /* fid */
8461                 fid = tvb_get_letohs(tvb, offset);
8462                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8463                 offset += 2;
8464
8465                 /* isfsctl */
8466                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8467                 offset += 1;
8468
8469                 /* isflags */
8470                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8471
8472                 break;
8473         }
8474         case NT_TRANS_SSD:
8475                 break;
8476         case NT_TRANS_NOTIFY: {
8477                 guint16 fid;
8478
8479                 /* completion filter */
8480                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8481
8482                 /* fid */
8483                 fid = tvb_get_letohs(tvb, offset);
8484                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
8485                 offset += 2;
8486
8487                 /* watch tree */
8488                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8489                 offset += 1;
8490
8491                 /* reserved byte */
8492                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8493                 offset += 1;
8494
8495                 break;
8496         }
8497         case NT_TRANS_RENAME:
8498                 /* XXX not documented */
8499                 break;
8500         case NT_TRANS_QSD:
8501                 break;
8502         case NT_TRANS_GET_USER_QUOTA:
8503                 /* not decoded yet */
8504                 break;
8505         case NT_TRANS_SET_USER_QUOTA:
8506                 /* not decoded yet */
8507                 break;
8508         }
8509
8510         return old_offset+len;
8511 }
8512
8513
8514 static int
8515 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8516 {
8517         guint8 wc, sc;
8518         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8519         smb_info_t *si;
8520         smb_saved_info_t *sip;
8521         int subcmd;
8522         nt_trans_data ntd;
8523         guint16 bc;
8524         guint32 padcnt;
8525         smb_nt_transact_info_t *nti=NULL;
8526
8527         ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
8528
8529         si = (smb_info_t *)pinfo->private_data;
8530         DISSECTOR_ASSERT(si);
8531         sip = si->sip;
8532
8533         WORD_COUNT;
8534
8535         if(wc>=19){
8536                 /* primary request */
8537                 /* max setup count */
8538                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8539                 offset += 1;
8540
8541                 /* 2 reserved bytes */
8542                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8543                 offset += 2;
8544         } else {
8545                 /* secondary request */
8546                 /* 3 reserved bytes */
8547                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8548                 offset += 3;
8549         }
8550
8551
8552         /* total param count */
8553         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8554         offset += 4;
8555
8556         /* total data count */
8557         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8558         offset += 4;
8559
8560         if(wc>=19){
8561                 /* primary request */
8562                 /* max param count */
8563                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8564                 offset += 4;
8565
8566                 /* max data count */
8567                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8568                 offset += 4;
8569         }
8570
8571         /* param count */
8572         pc = tvb_get_letohl(tvb, offset);
8573         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8574         offset += 4;
8575
8576         /* param offset */
8577         po = tvb_get_letohl(tvb, offset);
8578         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8579         offset += 4;
8580
8581         /* param displacement */
8582         if(wc>=19){
8583                 /* primary request*/
8584                 pd = 0;
8585         } else {
8586                 /* secondary request */
8587                 pd = tvb_get_letohl(tvb, offset);
8588                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8589                 offset += 4;
8590         }
8591
8592         /* data count */
8593         dc = tvb_get_letohl(tvb, offset);
8594         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8595         offset += 4;
8596
8597         /* data offset */
8598         od = tvb_get_letohl(tvb, offset);
8599         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8600         offset += 4;
8601
8602         /* data displacement */
8603         if(wc>=19){
8604                 /* primary request */
8605                 dd = 0;
8606         } else {
8607                 /* secondary request */
8608                 dd = tvb_get_letohl(tvb, offset);
8609                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8610                 offset += 4;
8611         }
8612
8613         /* setup count */
8614         if(wc>=19){
8615                 /* primary request */
8616                 sc = tvb_get_guint8(tvb, offset);
8617                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8618                 offset += 1;
8619         } else {
8620                 /* secondary request */
8621                 sc = 0;
8622         }
8623
8624         /* function */
8625         if(wc>=19){
8626                 /* primary request */
8627                 subcmd = tvb_get_letohs(tvb, offset);
8628                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8629                 if(check_col(pinfo->cinfo, COL_INFO)){
8630                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8631                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8632                 }
8633                 ntd.subcmd = subcmd;
8634                 if (!si->unidir && sip) {
8635                         if(!pinfo->fd->flags.visited){
8636                                 /*
8637                                  * Allocate a new smb_nt_transact_info_t
8638                                  * structure.
8639                                  */
8640                                 nti = se_alloc(sizeof(smb_nt_transact_info_t));
8641                                 nti->subcmd = subcmd;
8642                                 nti->fid_type=SMB_FID_TYPE_UNKNOWN;
8643                                 sip->extra_info = nti;
8644                                 sip->extra_info_type = SMB_EI_NTI;
8645                         } else {
8646                                 if(sip->extra_info_type == SMB_EI_NTI){
8647                                         nti=sip->extra_info;
8648                                 }
8649                         }
8650                 }
8651         } else {
8652                 /* secondary request */
8653                 if(check_col(pinfo->cinfo, COL_INFO)){
8654                         col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
8655                 }
8656         }
8657         offset += 2;
8658
8659         /* this is a padding byte */
8660         if(offset%1){
8661                 /* pad byte */
8662                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8663                 offset += 1;
8664         }
8665
8666         /* if there were any setup bytes, decode them */
8667         if(sc){
8668                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8669                 offset += sc*2;
8670         }
8671
8672         BYTE_COUNT;
8673
8674         /* parameters */
8675         if(po>(guint32)offset){
8676                 /* We have some initial padding bytes.
8677                 */
8678                 padcnt = po-offset;
8679                 if (padcnt > bc)
8680                         padcnt = bc;
8681                 CHECK_BYTE_COUNT(padcnt);
8682                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8683                 COUNT_BYTES(padcnt);
8684         }
8685         if(pc){
8686                 CHECK_BYTE_COUNT(pc);
8687                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc, nti);
8688                 COUNT_BYTES(pc);
8689         }
8690
8691         /* data */
8692         if(od>(guint32)offset){
8693                 /* We have some initial padding bytes.
8694                 */
8695                 padcnt = od-offset;
8696                 if (padcnt > bc)
8697                         padcnt = bc;
8698                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8699                 COUNT_BYTES(padcnt);
8700         }
8701         if(dc){
8702                 CHECK_BYTE_COUNT(dc);
8703                 dissect_nt_trans_data_request(
8704                         tvb, pinfo, offset, tree, dc, &ntd, nti);
8705                 COUNT_BYTES(dc);
8706         }
8707
8708         END_OF_SMB
8709
8710         return offset;
8711 }
8712
8713
8714
8715 static int
8716 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8717                                int offset, proto_tree *parent_tree, int len,
8718                                nt_trans_data *ntd _U_,
8719                                smb_nt_transact_info_t *nti)
8720 {
8721         proto_item *item = NULL;
8722         proto_tree *tree = NULL;
8723         smb_info_t *si;
8724         guint16 bcp;
8725         struct access_mask_info *ami=NULL;
8726         tvbuff_t *ioctl_tvb;
8727
8728         si = (smb_info_t *)pinfo->private_data;
8729         DISSECTOR_ASSERT(si);
8730
8731         if(parent_tree){
8732                 tvb_ensure_bytes_exist(tvb, offset, len);
8733                 if(nti != NULL){
8734                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8735                                 "%s Data",
8736                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8737                 } else {
8738                         /*
8739                          * We never saw the request to which this is a
8740                          * response.
8741                          */
8742                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8743                                 "Unknown NT Transaction Data (matching request not seen)");
8744                 }
8745                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8746         }
8747
8748         if (nti == NULL) {
8749                 offset += len;
8750                 return offset;
8751         }
8752         switch(nti->subcmd){
8753         case NT_TRANS_CREATE:
8754                 break;
8755         case NT_TRANS_IOCTL:
8756                 /* ioctl data */
8757                 ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)len, tvb_length_remaining(tvb, offset)), len);
8758                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, FALSE);
8759
8760                 offset += len;
8761
8762                 break;
8763         case NT_TRANS_SSD:
8764                 break;
8765         case NT_TRANS_NOTIFY:
8766                 break;
8767         case NT_TRANS_RENAME:
8768                 /* XXX not documented */
8769                 break;
8770         case NT_TRANS_QSD:
8771                 if(nti){
8772                         switch(nti->fid_type){
8773                         case SMB_FID_TYPE_FILE:
8774                                 ami= &smb_file_access_mask_info;
8775                                 break;
8776                         case SMB_FID_TYPE_DIR:
8777                                 ami= &smb_dir_access_mask_info;
8778                                 break;
8779                         }
8780                 }
8781                 offset = dissect_nt_sec_desc(
8782                         tvb, offset, pinfo, tree, NULL, TRUE, len, ami);
8783                 break;
8784         case NT_TRANS_GET_USER_QUOTA:
8785                 bcp=len;
8786                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8787                 break;
8788         case NT_TRANS_SET_USER_QUOTA:
8789                 /* not decoded yet */
8790                 break;
8791         }
8792
8793         return offset;
8794 }
8795
8796 static int
8797 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8798                                 int offset, proto_tree *parent_tree,
8799                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8800 {
8801         proto_item *item = NULL;
8802         proto_tree *tree = NULL;
8803         guint32 fn_len;
8804         const char *fn;
8805         smb_info_t *si;
8806         smb_nt_transact_info_t *nti;
8807         guint16 fid;
8808         int old_offset;
8809         guint32 neo;
8810         int padcnt;
8811         smb_fid_info_t *fid_info=NULL;
8812         guint16 ftype;
8813         guint8  isdir;
8814
8815         si = (smb_info_t *)pinfo->private_data;
8816         DISSECTOR_ASSERT(si);
8817
8818         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
8819                 nti = si->sip->extra_info;
8820         else
8821                 nti = NULL;
8822
8823         if(parent_tree){
8824                 tvb_ensure_bytes_exist(tvb, offset, len);
8825                 if(nti != NULL){
8826                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8827                                 "%s Parameters",
8828                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8829                 } else {
8830                         /*
8831                          * We never saw the request to which this is a
8832                          * response.
8833                          */
8834                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8835                                 "Unknown NT Transaction Parameters (matching request not seen)");
8836                 }
8837                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8838         }
8839
8840         if (nti == NULL) {
8841                 offset += len;
8842                 return offset;
8843         }
8844         switch(nti->subcmd){
8845         case NT_TRANS_CREATE:
8846                 /* oplock level */
8847                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8848                 offset += 1;
8849
8850                 /* reserved byte */
8851                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8852                 offset += 1;
8853
8854                 /* fid */
8855                 fid = tvb_get_letohs(tvb, offset);
8856                 fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
8857                 offset += 2;
8858
8859                 /* create action */
8860                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8861                 offset += 4;
8862
8863                 /* ea error offset */
8864                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8865                 offset += 4;
8866
8867                 /* create time */
8868                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8869                         hf_smb_create_time);
8870
8871                 /* access time */
8872                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8873                         hf_smb_access_time);
8874
8875                 /* last write time */
8876                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8877                         hf_smb_last_write_time);
8878
8879                 /* last change time */
8880                 offset = dissect_nt_64bit_time(tvb, tree, offset,
8881                         hf_smb_change_time);
8882
8883                 /* Extended File Attributes */
8884                 offset = dissect_file_ext_attr(tvb, tree, offset);
8885
8886                 /* allocation size */
8887                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8888                 offset += 8;
8889
8890                 /* end of file */
8891                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8892                 offset += 8;
8893
8894                 /* File Type */
8895                 ftype=tvb_get_letohs(tvb, offset);
8896                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8897                 offset += 2;
8898
8899                 /* device state */
8900                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8901
8902                 /* is directory */
8903                 isdir=tvb_get_guint8(tvb, offset);
8904                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8905                 offset += 1;
8906
8907                 /* Try to remember the type of this fid so that we can dissect
8908                  * any future security descriptor (access mask) properly
8909                  */
8910                 if(ftype==0){
8911                         if(isdir==0){
8912                                 if(fid_info){
8913                                         fid_info->type=SMB_FID_TYPE_FILE;
8914                                 }
8915                         } else {
8916                                 if(fid_info){
8917                                         fid_info->type=SMB_FID_TYPE_DIR;
8918                                 }
8919                         }
8920                 }
8921                 if(ftype==2){
8922                         if(fid_info){
8923                                 fid_info->type=SMB_FID_TYPE_PIPE;
8924                         }
8925                 }
8926                 break;
8927         case NT_TRANS_IOCTL:
8928                 break;
8929         case NT_TRANS_SSD:
8930                 break;
8931         case NT_TRANS_NOTIFY:
8932                 while(len){
8933                         old_offset = offset;
8934
8935                         /* next entry offset */
8936                         neo = tvb_get_letohl(tvb, offset);
8937                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8938                         COUNT_BYTES(4);
8939                         len -= 4;
8940                         /* broken implementations */
8941                         if(len<0)break;
8942
8943                         /* action */
8944                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8945                         COUNT_BYTES(4);
8946                         len -= 4;
8947                         /* broken implementations */
8948                         if(len<0)break;
8949
8950                         /* file name len */
8951                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8952                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8953                         COUNT_BYTES(4);
8954                         len -= 4;
8955                         /* broken implementations */
8956                         if(len<0)break;
8957
8958                         /* file name */
8959                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8960                         if (fn == NULL)
8961                                 break;
8962                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8963                                 fn);
8964                         COUNT_BYTES(fn_len);
8965                         len -= fn_len;
8966                         /* broken implementations */
8967                         if(len<0)break;
8968
8969                         if (neo == 0)
8970                                 break;  /* no more structures */
8971
8972                         /* skip to next structure */
8973                         padcnt = (old_offset + neo) - offset;
8974                         if (padcnt < 0) {
8975                                 /*
8976                                  * XXX - this is bogus; flag it?
8977                                  */
8978                                 padcnt = 0;
8979                         }
8980                         if (padcnt != 0) {
8981                                 COUNT_BYTES(padcnt);
8982                                 len -= padcnt;
8983                                 /* broken implementations */
8984                                 if(len<0)break;
8985                         }
8986                 }
8987                 break;
8988         case NT_TRANS_RENAME:
8989                 /* XXX not documented */
8990                 break;
8991         case NT_TRANS_QSD:
8992                 /*
8993                  * This appears to be the size of the security
8994                  * descriptor; the calling sequence of
8995                  * "ZwQuerySecurityObject()" suggests that it would
8996                  * be.  The actual security descriptor wouldn't
8997                  * follow if the max data count in the request
8998                  * was smaller; this lets the client know how
8999                  * big a buffer it needs to provide.
9000                  */
9001                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
9002                 offset += 4;
9003                 break;
9004         case NT_TRANS_GET_USER_QUOTA:
9005                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
9006                         tvb_get_letohl(tvb, offset));
9007                 offset += 4;
9008                 break;
9009         case NT_TRANS_SET_USER_QUOTA:
9010                 /* not decoded yet */
9011                 break;
9012         }
9013
9014         return offset;
9015 }
9016
9017 static int
9018 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
9019                                 int offset, proto_tree *parent_tree,
9020                                 int len, nt_trans_data *ntd _U_)
9021 {
9022         proto_item *item = NULL;
9023         proto_tree *tree = NULL;
9024         smb_info_t *si;
9025         smb_nt_transact_info_t *nti;
9026
9027         si = (smb_info_t *)pinfo->private_data;
9028         DISSECTOR_ASSERT(si);
9029
9030         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
9031                 nti = si->sip->extra_info;
9032         else
9033                 nti = NULL;
9034
9035         if(parent_tree){
9036                 tvb_ensure_bytes_exist(tvb, offset, len);
9037                 if(nti != NULL){
9038                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9039                                 "%s Setup",
9040                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
9041                 } else {
9042                         /*
9043                          * We never saw the request to which this is a
9044                          * response.
9045                          */
9046                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9047                                 "Unknown NT Transaction Setup (matching request not seen)");
9048                 }
9049                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
9050         }
9051
9052         if (nti == NULL) {
9053                 offset += len;
9054                 return offset;
9055         }
9056         switch(nti->subcmd){
9057         case NT_TRANS_CREATE:
9058                 break;
9059         case NT_TRANS_IOCTL:
9060                 break;
9061         case NT_TRANS_SSD:
9062                 break;
9063         case NT_TRANS_NOTIFY:
9064                 break;
9065         case NT_TRANS_RENAME:
9066                 /* XXX not documented */
9067                 break;
9068         case NT_TRANS_QSD:
9069                 break;
9070         case NT_TRANS_GET_USER_QUOTA:
9071                 /* not decoded yet */
9072                 break;
9073         case NT_TRANS_SET_USER_QUOTA:
9074                 /* not decoded yet */
9075                 break;
9076         }
9077
9078         return offset;
9079 }
9080
9081 static int
9082 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9083 {
9084         guint8 wc, sc;
9085         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
9086         guint32 td=0, tp=0;
9087         smb_info_t *si;
9088         smb_nt_transact_info_t *nti=NULL;
9089         static nt_trans_data ntd;
9090         guint16 bc;
9091         gint32 padcnt;
9092         fragment_data *r_fd = NULL;
9093         tvbuff_t *pd_tvb=NULL;
9094         gboolean save_fragmented;
9095
9096         si = (smb_info_t *)pinfo->private_data;
9097         DISSECTOR_ASSERT(si);
9098
9099         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_NTI)
9100                 nti = si->sip->extra_info;
9101         else
9102                 nti = NULL;
9103
9104         /* primary request */
9105         if(nti != NULL){
9106                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
9107                 if(check_col(pinfo->cinfo, COL_INFO)){
9108                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9109                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
9110                 }
9111         } else {
9112                 proto_tree_add_text(tree, tvb, offset, 0,
9113                         "Function: <unknown function - could not find matching request>");
9114                 if(check_col(pinfo->cinfo, COL_INFO)){
9115                         col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
9116                 }
9117         }
9118
9119         WORD_COUNT;
9120
9121         /* 3 reserved bytes */
9122         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
9123         offset += 3;
9124
9125         /* total param count */
9126         tp = tvb_get_letohl(tvb, offset);
9127         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
9128         offset += 4;
9129
9130         /* total data count */
9131         td = tvb_get_letohl(tvb, offset);
9132         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
9133         offset += 4;
9134
9135         /* param count */
9136         pc = tvb_get_letohl(tvb, offset);
9137         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
9138         offset += 4;
9139
9140         /* param offset */
9141         po = tvb_get_letohl(tvb, offset);
9142         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
9143         offset += 4;
9144
9145         /* param displacement */
9146         pd = tvb_get_letohl(tvb, offset);
9147         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
9148         offset += 4;
9149
9150         /* data count */
9151         dc = tvb_get_letohl(tvb, offset);
9152         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
9153         offset += 4;
9154
9155         /* data offset */
9156         od = tvb_get_letohl(tvb, offset);
9157         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9158         offset += 4;
9159
9160         /* data displacement */
9161         dd = tvb_get_letohl(tvb, offset);
9162         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9163         offset += 4;
9164
9165         /* setup count */
9166         sc = tvb_get_guint8(tvb, offset);
9167         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9168         offset += 1;
9169
9170         /* setup data */
9171         if(sc){
9172                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
9173                 offset += sc*2;
9174         }
9175
9176         BYTE_COUNT;
9177
9178         /* reassembly of SMB NT Transaction data payload.
9179            In this section we do reassembly of both the data and parameters
9180            blocks of the SMB transaction command.
9181         */
9182         save_fragmented = pinfo->fragmented;
9183         /* do we need reassembly? */
9184         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
9185                 /* oh yeah, either data or parameter section needs
9186                    reassembly...
9187                 */
9188                 pinfo->fragmented = TRUE;
9189                 if(smb_trans_reassembly){
9190                         /* ...and we were told to do reassembly */
9191                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
9192                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9193                                                              po, pc, pd, td+tp);
9194
9195                         }
9196                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
9197                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9198                                                              od, dc, dd+tp, td+tp);
9199                         }
9200                 }
9201         }
9202
9203         /* if we got a reassembled fd structure from the reassembly routine we
9204            must create pd_tvb from it
9205         */
9206         if(r_fd){
9207         proto_item *frag_tree_item;
9208
9209                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
9210                                              r_fd->datalen);
9211                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
9212                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9213
9214                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9215         }
9216
9217
9218         if(pd_tvb){
9219           /* we have reassembled data, grab param and data from there */
9220           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
9221                                           &ntd, (guint16) tvb_length(pd_tvb));
9222           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd, nti);
9223         } else {
9224           /* we do not have reassembled data, just use what we have in the
9225              packet as well as we can */
9226           /* parameters */
9227           if(po>(guint32)offset){
9228             /* We have some initial padding bytes.
9229              */
9230             padcnt = po-offset;
9231             if (padcnt > bc)
9232               padcnt = bc;
9233             CHECK_BYTE_COUNT(padcnt);
9234             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9235             COUNT_BYTES(padcnt);
9236           }
9237           if(pc){
9238             CHECK_BYTE_COUNT(pc);
9239             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
9240             COUNT_BYTES(pc);
9241           }
9242
9243           /* data */
9244           if(od>(guint32)offset){
9245             /* We have some initial padding bytes.
9246              */
9247             padcnt = od-offset;
9248             if (padcnt > bc)
9249               padcnt = bc;
9250             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9251             COUNT_BYTES(padcnt);
9252           }
9253           if(dc){
9254             CHECK_BYTE_COUNT(dc);
9255             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd, nti);
9256             COUNT_BYTES(dc);
9257           }
9258         }
9259         pinfo->fragmented = save_fragmented;
9260
9261         END_OF_SMB
9262
9263         return offset;
9264 }
9265
9266 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9267    NT Transaction command  ends here
9268    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9269
9270 static const value_string print_mode_vals[] = {
9271         {0,     "Text Mode"},
9272         {1,     "Graphics Mode"},
9273         {0, NULL}
9274 };
9275
9276 static int
9277 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9278 {
9279         smb_info_t *si = pinfo->private_data;
9280         int fn_len;
9281         const char *fn;
9282         guint8 wc;
9283         guint16 bc;
9284
9285         DISSECTOR_ASSERT(si);
9286
9287         WORD_COUNT;
9288
9289         /* setup len */
9290         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9291         offset += 2;
9292
9293         /* print mode */
9294         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9295         offset += 2;
9296
9297         BYTE_COUNT;
9298
9299         /* buffer format */
9300         CHECK_BYTE_COUNT(1);
9301         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9302         COUNT_BYTES(1);
9303
9304         /* print identifier */
9305         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9306         if (fn == NULL)
9307                 goto endofcommand;
9308         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9309                 fn);
9310         COUNT_BYTES(fn_len);
9311
9312         END_OF_SMB
9313
9314         return offset;
9315 }
9316
9317
9318 static int
9319 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9320 {
9321         int cnt;
9322         guint8 wc;
9323         guint16 bc, fid;
9324
9325         WORD_COUNT;
9326
9327         /* fid */
9328         fid = tvb_get_letohs(tvb, offset);
9329         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
9330         offset += 2;
9331
9332         BYTE_COUNT;
9333
9334         /* buffer format */
9335         CHECK_BYTE_COUNT(1);
9336         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9337         COUNT_BYTES(1);
9338
9339         /* data len */
9340         CHECK_BYTE_COUNT(2);
9341         cnt = tvb_get_letohs(tvb, offset);
9342         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9343         COUNT_BYTES(2);
9344
9345         /* file data */
9346         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9347
9348         END_OF_SMB
9349
9350         return offset;
9351 }
9352
9353
9354 static const value_string print_status_vals[] = {
9355         {1,     "Held or Stopped"},
9356         {2,     "Printing"},
9357         {3,     "Awaiting print"},
9358         {4,     "In intercept"},
9359         {5,     "File had error"},
9360         {6,     "Printer error"},
9361         {0, NULL}
9362 };
9363
9364 static int
9365 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9366 {
9367         guint8 wc;
9368         guint16 bc;
9369
9370         WORD_COUNT;
9371
9372         /* max count */
9373         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9374         offset += 2;
9375
9376         /* start index */
9377         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9378         offset += 2;
9379
9380         BYTE_COUNT;
9381
9382         END_OF_SMB
9383
9384         return offset;
9385 }
9386
9387 static int
9388 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9389     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9390 {
9391         proto_item *item = NULL;
9392         proto_tree *tree = NULL;
9393         smb_info_t *si = pinfo->private_data;
9394         int fn_len;
9395         const char *fn;
9396
9397         DISSECTOR_ASSERT(si);
9398
9399         if(parent_tree){
9400                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9401                         "Queue entry");
9402                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9403         }
9404
9405         /* queued time */
9406         CHECK_BYTE_COUNT_SUBR(4);
9407         offset = dissect_smb_datetime(tvb, tree, offset,
9408                 hf_smb_print_queue_date,
9409                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9410         *bcp -= 4;
9411
9412         /* status */
9413         CHECK_BYTE_COUNT_SUBR(1);
9414         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9415         COUNT_BYTES_SUBR(1);
9416
9417         /* spool file number */
9418         CHECK_BYTE_COUNT_SUBR(2);
9419         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9420         COUNT_BYTES_SUBR(2);
9421
9422         /* spool file size */
9423         CHECK_BYTE_COUNT_SUBR(4);
9424         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9425         COUNT_BYTES_SUBR(4);
9426
9427         /* reserved byte */
9428         CHECK_BYTE_COUNT_SUBR(1);
9429         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9430         COUNT_BYTES_SUBR(1);
9431
9432         /* file name */
9433         fn_len = 16;
9434         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9435         CHECK_STRING_SUBR(fn);
9436         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9437                 fn);
9438         COUNT_BYTES_SUBR(fn_len);
9439
9440         *trunc = FALSE;
9441         return offset;
9442 }
9443
9444 static int
9445 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9446 {
9447         guint16 cnt=0, len;
9448         guint8 wc;
9449         guint16 bc;
9450         gboolean trunc;
9451
9452         WORD_COUNT;
9453
9454         /* count */
9455         cnt = tvb_get_letohs(tvb, offset);
9456         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9457         offset += 2;
9458
9459         /* restart index */
9460         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9461         offset += 2;
9462
9463         BYTE_COUNT;
9464
9465         /* buffer format */
9466         CHECK_BYTE_COUNT(1);
9467         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9468         COUNT_BYTES(1);
9469
9470         /* data len */
9471         CHECK_BYTE_COUNT(2);
9472         len = tvb_get_letohs(tvb, offset);
9473         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9474         COUNT_BYTES(2);
9475
9476         /* queue elements */
9477         while(cnt--){
9478                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9479                     &bc, &trunc);
9480                 if (trunc)
9481                         goto endofcommand;
9482         }
9483
9484         END_OF_SMB
9485
9486         return offset;
9487 }
9488
9489
9490 static int
9491 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9492 {
9493         int name_len;
9494         guint16 bc;
9495         guint8 wc;
9496         guint16 message_len;
9497
9498         WORD_COUNT;
9499
9500         BYTE_COUNT;
9501
9502         /* buffer format */
9503         CHECK_BYTE_COUNT(1);
9504         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9505         COUNT_BYTES(1);
9506
9507         /* originator name */
9508         /* XXX - what if this runs past bc? */
9509         name_len = tvb_strsize(tvb, offset);
9510         CHECK_BYTE_COUNT(name_len);
9511         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9512             name_len, TRUE);
9513         COUNT_BYTES(name_len);
9514
9515         /* buffer format */
9516         CHECK_BYTE_COUNT(1);
9517         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9518         COUNT_BYTES(1);
9519
9520         /* destination name */
9521         /* XXX - what if this runs past bc? */
9522         name_len = tvb_strsize(tvb, offset);
9523         CHECK_BYTE_COUNT(name_len);
9524         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9525             name_len, TRUE);
9526         COUNT_BYTES(name_len);
9527
9528         /* buffer format */
9529         CHECK_BYTE_COUNT(1);
9530         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9531         COUNT_BYTES(1);
9532
9533         /* message len */
9534         CHECK_BYTE_COUNT(2);
9535         message_len = tvb_get_letohs(tvb, offset);
9536         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9537             message_len);
9538         COUNT_BYTES(2);
9539
9540         /* message */
9541         CHECK_BYTE_COUNT(message_len);
9542         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9543             TRUE);
9544         COUNT_BYTES(message_len);
9545
9546         END_OF_SMB
9547
9548         return offset;
9549 }
9550
9551 static int
9552 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9553 {
9554         int name_len;
9555         guint16 bc;
9556         guint8 wc;
9557
9558         WORD_COUNT;
9559
9560         BYTE_COUNT;
9561
9562         /* buffer format */
9563         CHECK_BYTE_COUNT(1);
9564         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9565         COUNT_BYTES(1);
9566
9567         /* originator name */
9568         /* XXX - what if this runs past bc? */
9569         name_len = tvb_strsize(tvb, offset);
9570         CHECK_BYTE_COUNT(name_len);
9571         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9572             name_len, TRUE);
9573         COUNT_BYTES(name_len);
9574
9575         /* buffer format */
9576         CHECK_BYTE_COUNT(1);
9577         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9578         COUNT_BYTES(1);
9579
9580         /* destination name */
9581         /* XXX - what if this runs past bc? */
9582         name_len = tvb_strsize(tvb, offset);
9583         CHECK_BYTE_COUNT(name_len);
9584         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9585             name_len, TRUE);
9586         COUNT_BYTES(name_len);
9587
9588         END_OF_SMB
9589
9590         return offset;
9591 }
9592
9593 static int
9594 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9595 {
9596         guint16 bc;
9597         guint8 wc;
9598
9599         WORD_COUNT;
9600
9601         /* message group ID */
9602         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9603         offset += 2;
9604
9605         BYTE_COUNT;
9606
9607         END_OF_SMB
9608
9609         return offset;
9610 }
9611
9612 static int
9613 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9614 {
9615         guint16 bc;
9616         guint8 wc;
9617         guint16 message_len;
9618
9619         WORD_COUNT;
9620
9621         BYTE_COUNT;
9622
9623         /* buffer format */
9624         CHECK_BYTE_COUNT(1);
9625         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9626         COUNT_BYTES(1);
9627
9628         /* message len */
9629         CHECK_BYTE_COUNT(2);
9630         message_len = tvb_get_letohs(tvb, offset);
9631         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9632             message_len);
9633         COUNT_BYTES(2);
9634
9635         /* message */
9636         CHECK_BYTE_COUNT(message_len);
9637         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9638             TRUE);
9639         COUNT_BYTES(message_len);
9640
9641         END_OF_SMB
9642
9643         return offset;
9644 }
9645
9646 static int
9647 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9648 {
9649         int name_len;
9650         guint16 bc;
9651         guint8 wc;
9652
9653         WORD_COUNT;
9654
9655         BYTE_COUNT;
9656
9657         /* buffer format */
9658         CHECK_BYTE_COUNT(1);
9659         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9660         COUNT_BYTES(1);
9661
9662         /* forwarded name */
9663         /* XXX - what if this runs past bc? */
9664         name_len = tvb_strsize(tvb, offset);
9665         CHECK_BYTE_COUNT(name_len);
9666         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9667             name_len, TRUE);
9668         COUNT_BYTES(name_len);
9669
9670         END_OF_SMB
9671
9672         return offset;
9673 }
9674
9675 static int
9676 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9677 {
9678         int name_len;
9679         guint16 bc;
9680         guint8 wc;
9681
9682         WORD_COUNT;
9683
9684         BYTE_COUNT;
9685
9686         /* buffer format */
9687         CHECK_BYTE_COUNT(1);
9688         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9689         COUNT_BYTES(1);
9690
9691         /* machine name */
9692         /* XXX - what if this runs past bc? */
9693         name_len = tvb_strsize(tvb, offset);
9694         CHECK_BYTE_COUNT(name_len);
9695         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9696             name_len, TRUE);
9697         COUNT_BYTES(name_len);
9698
9699         END_OF_SMB
9700
9701         return offset;
9702 }
9703
9704
9705 static int
9706 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9707 {
9708         guint8  wc, cmd=0xff;
9709         guint16 andxoffset=0;
9710         guint16 bc;
9711         smb_info_t *si = pinfo->private_data;
9712         int fn_len;
9713         const char *fn;
9714         guint32 create_flags=0, access_mask=0, file_attributes=0, share_access=0, create_options=0, create_disposition=0;
9715
9716         DISSECTOR_ASSERT(si);
9717
9718         WORD_COUNT;
9719
9720         /* next smb command */
9721         cmd = tvb_get_guint8(tvb, offset);
9722         if(cmd!=0xff){
9723                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9724         } else {
9725                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9726         }
9727         offset += 1;
9728
9729         /* reserved byte */
9730         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9731         offset += 1;
9732
9733         /* andxoffset */
9734         andxoffset = tvb_get_letohs(tvb, offset);
9735         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9736         offset += 2;
9737
9738         /* reserved byte */
9739         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9740         offset += 1;
9741
9742         /* file name len */
9743         fn_len = tvb_get_letohs(tvb, offset);
9744         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9745         offset += 2;
9746
9747         /* Create flags */
9748         create_flags=tvb_get_letohl(tvb, offset);
9749         offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
9750
9751         /* root directory fid */
9752         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9753         offset += 4;
9754
9755         /* nt access mask */
9756         access_mask=tvb_get_letohl(tvb, offset);
9757         offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
9758
9759         /* allocation size */
9760         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9761         offset += 8;
9762
9763         /* Extended File Attributes */
9764         file_attributes=tvb_get_letohl(tvb, offset);
9765         offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
9766
9767         /* share access */
9768         share_access=tvb_get_letohl(tvb, offset);
9769         offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
9770
9771         /* create disposition */
9772         create_disposition=tvb_get_letohl(tvb, offset);
9773         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9774         offset += 4;
9775
9776         /* create options */
9777         create_options=tvb_get_letohl(tvb, offset);
9778         offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
9779
9780         /* impersonation level */
9781         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9782         offset += 4;
9783
9784         /* security flags */
9785         offset = dissect_nt_security_flags(tvb, tree, offset);
9786
9787         BYTE_COUNT;
9788
9789         /* file name */
9790         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9791         if (fn == NULL)
9792                 goto endofcommand;
9793         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9794                 fn);
9795         COUNT_BYTES(fn_len);
9796
9797         /* store it for the fid->name/openframe/closeframe matching in
9798          * dissect_smb_fid()   called from the response.
9799          */
9800         if((!pinfo->fd->flags.visited) && si->sip && fn){
9801                 smb_fid_saved_info_t *fsi;
9802
9803                 fsi=se_alloc(sizeof(smb_fid_saved_info_t));
9804                 fsi->filename=se_strdup(fn);
9805                 fsi->create_flags=create_flags;
9806                 fsi->access_mask=access_mask;
9807                 fsi->file_attributes=file_attributes;
9808                 fsi->share_access=share_access;
9809                 fsi->create_options=create_options;
9810                 fsi->create_disposition=create_disposition;
9811
9812                 si->sip->extra_info_type=SMB_EI_FILEDATA;
9813                 si->sip->extra_info=fsi;
9814         }
9815
9816         if (check_col(pinfo->cinfo, COL_INFO)) {
9817                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9818                     format_text(fn, strlen(fn)));
9819         }
9820
9821         END_OF_SMB
9822
9823         if (cmd != 0xff) {      /* there is an andX command */
9824                 if (andxoffset < offset)
9825                         THROW(ReportedBoundsError);
9826                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9827         }
9828
9829         return offset;
9830 }
9831
9832
9833 static int
9834 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9835 {
9836         guint8  wc, cmd=0xff;
9837         guint16 andxoffset=0;
9838         guint16 bc;
9839         guint16 fid=0;
9840         guint16 ftype;
9841         guint8  isdir;
9842         smb_fid_info_t *fid_info=NULL;
9843         smb_info_t              *si;
9844
9845         si = pinfo->private_data;
9846
9847         WORD_COUNT;
9848
9849         /* next smb command */
9850         cmd = tvb_get_guint8(tvb, offset);
9851         if(cmd!=0xff){
9852                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9853         } else {
9854                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9855         }
9856         offset += 1;
9857
9858         /* reserved byte */
9859         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9860         offset += 1;
9861
9862         /* andxoffset */
9863         andxoffset = tvb_get_letohs(tvb, offset);
9864         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9865         offset += 2;
9866
9867         /* oplock level */
9868         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9869         offset += 1;
9870
9871         /* fid */
9872         fid = tvb_get_letohs(tvb, offset);
9873         fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
9874         offset += 2;
9875
9876         /* create action */
9877         /*XXX is this really the same as create disposition in the request? it looks so*/
9878         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9879         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9880         offset += 4;
9881
9882         /* create time */
9883         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
9884
9885         /* access time */
9886         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
9887
9888         /* last write time */
9889         offset = dissect_nt_64bit_time(tvb, tree, offset,
9890                 hf_smb_last_write_time);
9891
9892         /* last change time */
9893         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
9894
9895         /* Extended File Attributes */
9896         offset = dissect_file_ext_attr(tvb, tree, offset);
9897
9898         /* allocation size */
9899         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9900         offset += 8;
9901
9902         /* end of file */
9903         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9904         offset += 8;
9905
9906         /* File Type */
9907         ftype=tvb_get_letohs(tvb, offset);
9908         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9909         offset += 2;
9910
9911         /* IPC State */
9912         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9913
9914         /* is directory */
9915         isdir=tvb_get_guint8(tvb, offset);
9916         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9917         offset += 1;
9918
9919         /* Try to remember the type of this fid so that we can dissect
9920          * any future security descriptor (access mask) properly
9921          */
9922         if(ftype==0){
9923                 if(isdir==0){
9924                         if(fid_info){
9925                                 fid_info->type=SMB_FID_TYPE_FILE;
9926                         }
9927                 } else {
9928                         if(fid_info){
9929                                 fid_info->type=SMB_FID_TYPE_DIR;
9930                         }
9931                 }
9932         }
9933         if(ftype==2){
9934                 if(fid_info){
9935                         fid_info->type=SMB_FID_TYPE_PIPE;
9936                 }
9937         }
9938
9939         BYTE_COUNT;
9940
9941         END_OF_SMB
9942
9943         if (cmd != 0xff) {      /* there is an andX command */
9944                 if (andxoffset < offset)
9945                         THROW(ReportedBoundsError);
9946                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9947         }
9948
9949         /* if there was an error, add a generated filename to the tree */
9950         if(si->nt_status){
9951                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE);
9952         }
9953
9954         return offset;
9955 }
9956
9957
9958 static int
9959 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9960 {
9961         guint8 wc;
9962         guint16 bc;
9963
9964         WORD_COUNT;
9965
9966         BYTE_COUNT;
9967
9968         END_OF_SMB
9969
9970         return offset;
9971 }
9972
9973 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9974    BEGIN Transaction/Transaction2 Primary and secondary requests
9975    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9976
9977
9978 const value_string trans2_cmd_vals[] = {
9979         { 0x00,         "OPEN2" },
9980         { 0x01,         "FIND_FIRST2" },
9981         { 0x02,         "FIND_NEXT2" },
9982         { 0x03,         "QUERY_FS_INFO" },
9983         { 0x04,         "SET_FS_QUOTA" },
9984         { 0x05,         "QUERY_PATH_INFO" },
9985         { 0x06,         "SET_PATH_INFO" },
9986         { 0x07,         "QUERY_FILE_INFO" },
9987         { 0x08,         "SET_FILE_INFO" },
9988         { 0x09,         "FSCTL" },
9989         { 0x0A,         "IOCTL2" },
9990         { 0x0B,         "FIND_NOTIFY_FIRST" },
9991         { 0x0C,         "FIND_NOTIFY_NEXT" },
9992         { 0x0D,         "CREATE_DIRECTORY" },
9993         { 0x0E,         "SESSION_SETUP" },
9994         { 0x10,         "GET_DFS_REFERRAL" },
9995         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9996         { 0,    NULL }
9997 };
9998
9999 static const true_false_string tfs_tf_dtid = {
10000         "Also DISCONNECT TID",
10001         "Do NOT disconnect TID"
10002 };
10003 static const true_false_string tfs_tf_owt = {
10004         "One Way Transaction (NO RESPONSE)",
10005         "Two way transaction"
10006 };
10007
10008 static const true_false_string tfs_ff2_backup = {
10009         "Find WITH backup intent",
10010         "No backup intent"
10011 };
10012 static const true_false_string tfs_ff2_continue = {
10013         "CONTINUE search from previous position",
10014         "New search, do NOT continue from previous position"
10015 };
10016 static const true_false_string tfs_ff2_resume = {
10017         "Return RESUME keys",
10018         "Do NOT return resume keys"
10019 };
10020 static const true_false_string tfs_ff2_close_eos = {
10021         "CLOSE search if END OF SEARCH is reached",
10022         "Do NOT close search if end of search reached"
10023 };
10024 static const true_false_string tfs_ff2_close = {
10025         "CLOSE search after this request",
10026         "Do NOT close search after this request"
10027 };
10028
10029 /* used by
10030    TRANS2_FIND_FIRST2
10031 */
10032 static const value_string ff2_il_vals[] = {
10033         { 1,            "Info Standard"},
10034         { 2,            "Info Query EA Size"},
10035         { 3,            "Info Query EAs From List"},
10036         { 0x0101,       "Find File Directory Info"},
10037         { 0x0102,       "Find File Full Directory Info"},
10038         { 0x0103,       "Find File Names Info"},
10039         { 0x0104,       "Find File Both Directory Info"},
10040         { 0x0202,       "Find File UNIX"},
10041         {0, NULL}
10042 };
10043
10044 /* values used by :
10045         TRANS2_QUERY_PATH_INFORMATION
10046         TRANS2_QUERY_FILE_INFORMATION
10047 */
10048 static const value_string qpi_loi_vals[] = {
10049         { 1,            "Info Standard"},
10050         { 2,            "Info Query EA Size"},
10051         { 3,            "Info Query EAs From List"},
10052         { 4,            "Info Query All EAs"},
10053         { 6,            "Info Is Name Valid"},
10054         { 0x0101,       "Query File Basic Info"},
10055         { 0x0102,       "Query File Standard Info"},
10056         { 0x0103,       "Query File EA Info"},
10057         { 0x0104,       "Query File Name Info"},
10058         { 0x0107,       "Query File All Info"},
10059         { 0x0108,       "Query File Alt Name Info"},
10060         { 0x0109,       "Query File Stream Info"},
10061         { 0x010b,       "Query File Compression Info"},
10062         { 0x0200,       "Query File Unix Basic"},
10063         { 0x0201,       "Query File Unix Link"},
10064         { 0x0202,       "Query File Unix Hardlink"},
10065         { 0x0204,       "Query File Posix ACL"},
10066         { 0x0205,       "Query File Posix XATTR"},
10067         { 0x0206,       "Query File Posix Attr Flags"},
10068         { 0x0207,       "Query File Posix Permissions"},
10069         { 0x0208,       "Query File Posix Lock"},
10070         { 1004,         "Query File Basic Info"},
10071         { 1005,         "Query File Standard Info"},
10072         { 1006,         "Query File Internal Info"},
10073         { 1007,         "Query File EA Info"},
10074         { 1009,         "Query File Name Info"},
10075         { 1010,         "Query File Rename Info"},
10076         { 1011,         "Query File Link Info"},
10077         { 1012,         "Query File Names Info"},
10078         { 1013,         "Query File Disposition Info"},
10079         { 1014,         "Query File Position Info"},
10080         { 1015,         "Query File Full EA Info"},
10081         { 1016,         "Query File Mode Info"},
10082         { 1017,         "Query File Alignment Info"},
10083         { 1018,         "Query File All Info"},
10084         { 1019,         "Query File Allocation Info"},
10085         { 1020,         "Query File End of File Info"},
10086         { 1021,         "Query File Alt Name Info"},
10087         { 1022,         "Query File Stream Info"},
10088         { 1023,         "Query File Pipe Info"},
10089         { 1024,         "Query File Pipe Local Info"},
10090         { 1025,         "Query File Pipe Remote Info"},
10091         { 1026,         "Query File Mailslot Query Info"},
10092         { 1027,         "Query File Mailslot Set Info"},
10093         { 1028,         "Query File Compression Info"},
10094         { 1029,         "Query File ObjectID Info"},
10095         { 1030,         "Query File Completion Info"},
10096         { 1031,         "Query File Move Cluster Info"},
10097         { 1032,         "Query File Quota Info"},
10098         { 1033,         "Query File Reparsepoint Info"},
10099         { 1034,         "Query File Network Open Info"},
10100         { 1035,         "Query File Attribute Tag Info"},
10101         { 1036,         "Query File Tracking Info"},
10102         { 1037,         "Query File Maximum Info"},
10103         {0, NULL}
10104 };
10105
10106 /* values used by :
10107         TRANS2_SET_PATH_INFORMATION
10108         TRANS2_SET_FILE_INFORMATION
10109         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
10110         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
10111         well; note that they're different from the QUERY_PATH_INFORMATION
10112         and QUERY_FILE_INFORMATION values!)
10113 */
10114 static const value_string spi_loi_vals[] = {
10115         { 1,            "Info Standard"},
10116         { 2,            "Info Query EA Size"},
10117         { 4,            "Info Query All EAs"},
10118         { 0x0101,       "Set File Basic Info"},
10119         { 0x0102,       "Set File Disposition Info"},
10120         { 0x0103,       "Set File Allocation Info"},
10121         { 0x0104,       "Set File End Of File Info"},
10122         { 0x0200,       "Set File Unix Basic"},
10123         { 0x0201,       "Set File Unix Link"},
10124         { 0x0202,       "Set File Unix HardLink"},
10125         { 0x0204,       "Set File Unix ACL"},
10126         { 0x0205,       "Set File Unix XATTR"},
10127         { 0x0206,       "Set File Unix Attr Flags"},
10128         { 0x0208,       "Set File Posix Lock"},
10129         { 0x0209,       "Set File Posix Open"},
10130         { 0x020a,       "Set File Posix Unlink"},
10131         { 1004,         "Set File Basic Info"},
10132         { 1010,         "Set Rename Information"},
10133         { 1013,         "Set Disposition Information"},
10134         { 1014,         "Set Position Information"},
10135         { 1016,         "Set Mode Information"},
10136         { 1019,         "Set Allocation Information"},
10137         { 1020,         "Set EOF Information"},
10138         { 1023,         "Set File Pipe Information"},
10139         { 1025,         "Set File Pipe Remote Information"},
10140         { 1029,         "Set Copy On Write Information"},
10141         { 1032,         "Set OLE Class ID Information"},
10142         { 1039,         "Set Inherit Context Index Information"},
10143         { 1040,         "Set OLE Information (?)"},
10144         {0, NULL}
10145 };
10146
10147 static const value_string qfsi_vals[] = {
10148         { 1,            "Info Allocation"},
10149         { 2,            "Info Volume"},
10150         { 0x0101,       "Query FS Label Info"},
10151         { 0x0102,       "Query FS Volume Info"},
10152         { 0x0103,       "Query FS Size Info"},
10153         { 0x0104,       "Query FS Device Info"},
10154         { 0x0105,       "Query FS Attribute Info"},
10155         { 0x0200,       "Unix Query FS Info"},
10156         { 0x0301,       "Mac Query FS Info"},
10157         { 1001,         "Query FS Label Info"},
10158         { 1002,         "Query FS Volume Info"},
10159         { 1003,         "Query FS Size Info"},
10160         { 1004,         "Query FS Device Info"},
10161         { 1005,         "Query FS Attribute Info"},
10162         { 1006,         "Query FS Quota Info"},
10163         { 1007,         "Query Full FS Size Info"},
10164         { 1008,         "Object ID Information"},
10165         {0, NULL}
10166 };
10167
10168 static const value_string nt_rename_vals[] = {
10169         { 0x0103,       "Create Hard Link"},
10170         {0, NULL}
10171 };
10172
10173
10174 static const value_string delete_pending_vals[] = {
10175         {0,     "Normal, no pending delete"},
10176         {1,     "This object has DELETE PENDING"},
10177         {0, NULL}
10178 };
10179
10180 static const value_string alignment_vals[] = {
10181         {0,     "Byte alignment"},
10182         {1,     "Word (16bit) alignment"},
10183         {3,     "Long (32bit) alignment"},
10184         {7,     "8 byte boundary alignment"},
10185         {0x0f,  "16 byte boundary alignment"},
10186         {0x1f,  "32 byte boundary alignment"},
10187         {0x3f,  "64 byte boundary alignment"},
10188         {0x7f,  "128 byte boundary alignment"},
10189         {0xff,  "256 byte boundary alignment"},
10190         {0x1ff, "512 byte boundary alignment"},
10191         {0, NULL}
10192 };
10193
10194 static const true_false_string tfs_marked_for_deletion = {
10195         "File is MARKED FOR DELETION",
10196         "File is NOT marked for deletion"
10197 };
10198
10199 static const true_false_string tfs_get_dfs_server_hold_storage = {
10200         "Referral SERVER HOLDS STORAGE for the file",
10201         "Referral server does NOT hold storage for the file"
10202 };
10203 static const true_false_string tfs_get_dfs_fielding = {
10204         "The server in referral is FIELDING CAPABLE",
10205         "The server in referrals is NOT fielding capable"
10206 };
10207
10208 static const true_false_string tfs_dfs_referral_flags_strip = {
10209         "STRIP off pathconsumed characters before submitting",
10210         "Do NOT strip off any characters"
10211 };
10212
10213 static const value_string dfs_referral_server_type_vals[] = {
10214         {0,     "Don't know"},
10215         {1,     "SMB Server"},
10216         {2,     "Netware Server"},
10217         {3,     "Domain Server"},
10218         {0, NULL}
10219 };
10220
10221
10222 static const true_false_string tfs_device_char_removable = {
10223         "This is a REMOVABLE device",
10224         "This is NOT a removable device"
10225 };
10226 static const true_false_string tfs_device_char_read_only = {
10227         "This is a READ-ONLY device",
10228         "This is NOT a read-only device"
10229 };
10230 static const true_false_string tfs_device_char_floppy = {
10231         "This is a FLOPPY DISK device",
10232         "This is NOT a floppy disk device"
10233 };
10234 static const true_false_string tfs_device_char_write_once = {
10235         "This is a WRITE-ONCE device",
10236         "This is NOT a write-once device"
10237 };
10238 static const true_false_string tfs_device_char_remote = {
10239         "This is a REMOTE device",
10240         "This is NOT a remote device"
10241 };
10242 static const true_false_string tfs_device_char_mounted = {
10243         "This device is MOUNTED",
10244         "This device is NOT mounted"
10245 };
10246 static const true_false_string tfs_device_char_virtual = {
10247         "This is a VIRTUAL device",
10248         "This is NOT a virtual device"
10249 };
10250
10251
10252 static const true_false_string tfs_fs_attr_css = {
10253         "This FS supports CASE SENSITIVE SEARCHes",
10254         "This FS does NOT support case sensitive searches"
10255 };
10256 static const true_false_string tfs_fs_attr_cpn = {
10257         "This FS supports CASE PRESERVED NAMES",
10258         "This FS does NOT support case preserved names"
10259 };
10260 static const true_false_string tfs_fs_attr_uod = {
10261         "This FS supports UNICODE NAMES",
10262         "This FS does NOT support unicode names"
10263 };
10264 static const true_false_string tfs_fs_attr_pacls = {
10265         "This FS supports PERSISTENT ACLs",
10266         "This FS does NOT support persistent acls"
10267 };
10268 static const true_false_string tfs_fs_attr_fc = {
10269         "This FS supports COMPRESSED FILES",
10270         "This FS does NOT support compressed files"
10271 };
10272 static const true_false_string tfs_fs_attr_vq = {
10273         "This FS supports VOLUME QUOTAS",
10274         "This FS does NOT support volume quotas"
10275 };
10276 static const true_false_string tfs_fs_attr_srp = {
10277         "This FS supports REPARSE POINTS",
10278         "This FS does NOT support reparse points"
10279 };
10280 static const true_false_string tfs_fs_attr_srs = {
10281         "This FS supports REMOTE STORAGE",
10282         "This FS does NOT support remote storage"
10283 };
10284 static const true_false_string tfs_fs_attr_ssf = {
10285         "This FS supports SPARSE FILES",
10286         "This FS does NOT support sparse files"
10287 };
10288 static const true_false_string tfs_fs_attr_sla = {
10289         "This FS supports LFN APIs",
10290         "This FS does NOT support lfn apis"
10291 };
10292 static const true_false_string tfs_fs_attr_vic = {
10293         "This FS VOLUME IS COMPRESSED",
10294         "This FS volume is NOT compressed"
10295 };
10296 static const true_false_string tfs_fs_attr_soids = {
10297         "This FS supports OIDs",
10298         "This FS does NOT support OIDs"
10299 };
10300 static const true_false_string tfs_fs_attr_se = {
10301         "This FS supports ENCRYPTION",
10302         "This FS does NOT support encryption"
10303 };
10304 static const true_false_string tfs_fs_attr_ns = {
10305         "This FS supports NAMED STREAMS",
10306         "This FS does NOT support named streams"
10307 };
10308 static const true_false_string tfs_fs_attr_rov = {
10309         "This is a READ ONLY VOLUME",
10310         "This is a read/write volume"
10311 };
10312
10313 #define FF2_RESUME      0x0004
10314
10315 static int
10316 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10317 {
10318         guint16 mask;
10319         proto_item *item = NULL;
10320         proto_tree *tree = NULL;
10321         smb_info_t *si;
10322         smb_transact2_info_t *t2i;
10323
10324         mask = tvb_get_letohs(tvb, offset);
10325
10326         si = (smb_info_t *)pinfo->private_data;
10327         DISSECTOR_ASSERT(si);
10328
10329         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
10330                 t2i = si->sip->extra_info;
10331                 if (t2i != NULL) {
10332                         if (!pinfo->fd->flags.visited)
10333                                 t2i->resume_keys = (mask & FF2_RESUME);
10334                 }
10335         }
10336
10337         if(parent_tree){
10338                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10339                         "Flags: 0x%04x", mask);
10340                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
10341
10342                 proto_tree_add_boolean(tree, hf_smb_ff2_backup,
10343                         tvb, offset, 2, mask);
10344                 proto_tree_add_boolean(tree, hf_smb_ff2_continue,
10345                         tvb, offset, 2, mask);
10346                 proto_tree_add_boolean(tree, hf_smb_ff2_resume,
10347                         tvb, offset, 2, mask);
10348                 proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
10349                         tvb, offset, 2, mask);
10350                 proto_tree_add_boolean(tree, hf_smb_ff2_close,
10351                         tvb, offset, 2, mask);
10352         }
10353
10354         offset += 2;
10355
10356         return offset;
10357 }
10358
10359 #if 0
10360 static int
10361 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10362 {
10363         guint16 mask;
10364         proto_item *item;
10365         proto_tree *tree;
10366
10367         mask = tvb_get_letohs(tvb, offset);
10368
10369         if(parent_tree){
10370                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10371                         "IO Flag: 0x%04x", mask);
10372                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10373
10374                 proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10375                         tvb, offset, 2, mask);
10376                 proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10377                         tvb, offset, 2, mask);
10378         }
10379
10380         offset += 2;
10381
10382         return offset;
10383 }
10384 #endif
10385
10386 static int
10387 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10388     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
10389 {
10390         proto_item *item = NULL;
10391         proto_tree *tree = NULL;
10392         smb_info_t *si;
10393         smb_transact2_info_t *t2i;
10394         int fn_len;
10395         const char *fn;
10396
10397         si = (smb_info_t *)pinfo->private_data;
10398         DISSECTOR_ASSERT(si);
10399
10400         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
10401                 t2i = si->sip->extra_info;
10402         else
10403                 t2i = NULL;
10404
10405         if(parent_tree){
10406                 tvb_ensure_bytes_exist(tvb, offset, bc);
10407                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10408                                 "%s Parameters",
10409                                 val_to_str(subcmd, trans2_cmd_vals,
10410                                            "Unknown (0x%02x)"));
10411                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10412         }
10413
10414         switch(subcmd){
10415         case 0x00:      /*TRANS2_OPEN2*/
10416                 /* open flags */
10417                 CHECK_BYTE_COUNT_TRANS(2);
10418                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10419                 bc -= 2;
10420
10421                 /* desired access */
10422                 CHECK_BYTE_COUNT_TRANS(2);
10423                 offset = dissect_access(tvb, tree, offset, "Desired");
10424                 bc -= 2;
10425
10426                 /* Search Attributes */
10427                 CHECK_BYTE_COUNT_TRANS(2);
10428                 offset = dissect_search_attributes(tvb, tree, offset);
10429                 bc -= 2;
10430
10431                 /* File Attributes */
10432                 CHECK_BYTE_COUNT_TRANS(2);
10433                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10434                 bc -= 2;
10435
10436                 /* create time */
10437                 CHECK_BYTE_COUNT_TRANS(4);
10438                 offset = dissect_smb_datetime(tvb, tree, offset,
10439                         hf_smb_create_time,
10440                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10441                         TRUE);
10442                 bc -= 4;
10443
10444                 /* open function */
10445                 CHECK_BYTE_COUNT_TRANS(2);
10446                 offset = dissect_open_function(tvb, tree, offset);
10447                 bc -= 2;
10448
10449                 /* allocation size */
10450                 CHECK_BYTE_COUNT_TRANS(4);
10451                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10452                 COUNT_BYTES_TRANS(4);
10453
10454                 /* 10 reserved bytes */
10455                 CHECK_BYTE_COUNT_TRANS(10);
10456                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10457                 COUNT_BYTES_TRANS(10);
10458
10459                 /* file name */
10460                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10461                 CHECK_STRING_TRANS(fn);
10462                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10463                         fn);
10464                 COUNT_BYTES_TRANS(fn_len);
10465
10466                 if (check_col(pinfo->cinfo, COL_INFO)) {
10467                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10468                             format_text(fn, strlen(fn)));
10469                 }
10470                 break;
10471         case 0x01:      /*TRANS2_FIND_FIRST2*/
10472                 /* Search Attributes */
10473                 CHECK_BYTE_COUNT_TRANS(2);
10474                 offset = dissect_search_attributes(tvb, tree, offset);
10475                 bc -= 2;
10476
10477                 /* search count */
10478                 CHECK_BYTE_COUNT_TRANS(2);
10479                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10480                 COUNT_BYTES_TRANS(2);
10481
10482                 /* Find First2 flags */
10483                 CHECK_BYTE_COUNT_TRANS(2);
10484                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10485                 bc -= 2;
10486
10487                 /* Find First2 information level */
10488                 CHECK_BYTE_COUNT_TRANS(2);
10489                 si->info_level = tvb_get_letohs(tvb, offset);
10490                 if (t2i != NULL && !pinfo->fd->flags.visited)
10491                         t2i->info_level = si->info_level;
10492                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10493                 COUNT_BYTES_TRANS(2);
10494
10495                 /* storage type */
10496                 CHECK_BYTE_COUNT_TRANS(4);
10497                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10498                 COUNT_BYTES_TRANS(4);
10499
10500                 /* search pattern */
10501                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10502                 CHECK_STRING_TRANS(fn);
10503                 if(t2i && !t2i->name){
10504                         t2i->name = se_strdup(fn);
10505                 }
10506                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10507                         fn);
10508                 COUNT_BYTES_TRANS(fn_len);
10509
10510                 if (check_col(pinfo->cinfo, COL_INFO)) {
10511                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10512                             format_text(fn, strlen(fn)));
10513                 }
10514
10515                 break;
10516         case 0x02:      /*TRANS2_FIND_NEXT2*/
10517                 /* sid */
10518                 CHECK_BYTE_COUNT_TRANS(2);
10519                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10520                 COUNT_BYTES_TRANS(2);
10521
10522                 /* search count */
10523                 CHECK_BYTE_COUNT_TRANS(2);
10524                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10525                 COUNT_BYTES_TRANS(2);
10526
10527                 /* Find First2 information level */
10528                 CHECK_BYTE_COUNT_TRANS(2);
10529                 si->info_level = tvb_get_letohs(tvb, offset);
10530                 if (t2i != NULL && !pinfo->fd->flags.visited)
10531                         t2i->info_level = si->info_level;
10532                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10533                 COUNT_BYTES_TRANS(2);
10534
10535                 /* resume key */
10536                 CHECK_BYTE_COUNT_TRANS(4);
10537                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10538                 COUNT_BYTES_TRANS(4);
10539
10540                 /* Find First2 flags */
10541                 CHECK_BYTE_COUNT_TRANS(2);
10542                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10543                 bc -= 2;
10544
10545                 /* file name */
10546                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10547                 CHECK_STRING_TRANS(fn);
10548                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10549                         fn);
10550                 COUNT_BYTES_TRANS(fn_len);
10551
10552                 if (check_col(pinfo->cinfo, COL_INFO)) {
10553                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10554                             format_text(fn, strlen(fn)));
10555                 }
10556
10557                 break;
10558         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10559                 /* level of interest */
10560                 CHECK_BYTE_COUNT_TRANS(2);
10561                 si->info_level = tvb_get_letohs(tvb, offset);
10562                 if (t2i != NULL && !pinfo->fd->flags.visited)
10563                         t2i->info_level = si->info_level;
10564                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10565                 COUNT_BYTES_TRANS(2);
10566
10567                 if (check_col(pinfo->cinfo, COL_INFO))
10568                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10569                                         val_to_str(si->info_level, qfsi_vals,
10570                                                    "Unknown (0x%02x)"));
10571
10572                 break;
10573         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10574                 /* level of interest */
10575                 CHECK_BYTE_COUNT_TRANS(2);
10576                 si->info_level = tvb_get_letohs(tvb, offset);
10577                 if (t2i != NULL && !pinfo->fd->flags.visited)
10578                         t2i->info_level = si->info_level;
10579                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10580                 COUNT_BYTES_TRANS(2);
10581
10582                 if (check_col(pinfo->cinfo, COL_INFO)) {
10583                         col_append_fstr(
10584                                 pinfo->cinfo, COL_INFO, ", %s",
10585                                 val_to_str(si->info_level, qpi_loi_vals,
10586                                            "Unknown (%u)"));
10587                 }
10588
10589                 /* 4 reserved bytes */
10590                 CHECK_BYTE_COUNT_TRANS(4);
10591                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10592                 COUNT_BYTES_TRANS(4);
10593
10594                 /* file name */
10595                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10596                 CHECK_STRING_TRANS(fn);
10597                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10598                         fn);
10599                 COUNT_BYTES_TRANS(fn_len);
10600                 if(t2i && !t2i->name){
10601                         t2i->name = se_strdup(fn);
10602                 }
10603
10604                 if (check_col(pinfo->cinfo, COL_INFO)) {
10605                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10606                             format_text(fn, strlen(fn)));
10607                 }
10608
10609                 break;
10610         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10611                 /* level of interest */
10612                 CHECK_BYTE_COUNT_TRANS(2);
10613                 si->info_level = tvb_get_letohs(tvb, offset);
10614                 if (t2i != NULL && !pinfo->fd->flags.visited)
10615                         t2i->info_level = si->info_level;
10616                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10617                 COUNT_BYTES_TRANS(2);
10618
10619                 /* 4 reserved bytes */
10620                 CHECK_BYTE_COUNT_TRANS(4);
10621                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10622                 COUNT_BYTES_TRANS(4);
10623
10624                 /* file name */
10625                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10626                 CHECK_STRING_TRANS(fn);
10627                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10628                         fn);
10629                 COUNT_BYTES_TRANS(fn_len);
10630
10631                 if (check_col(pinfo->cinfo, COL_INFO)) {
10632                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10633                             format_text(fn, strlen(fn)));
10634                 }
10635
10636                 break;
10637         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10638                 guint16 fid;
10639
10640                 /* fid */
10641                 CHECK_BYTE_COUNT_TRANS(2);
10642                 fid = tvb_get_letohs(tvb, offset);
10643                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10644                 COUNT_BYTES_TRANS(2);
10645
10646                 /* level of interest */
10647                 CHECK_BYTE_COUNT_TRANS(2);
10648                 si->info_level = tvb_get_letohs(tvb, offset);
10649                 if (t2i != NULL && !pinfo->fd->flags.visited)
10650                         t2i->info_level = si->info_level;
10651                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10652                 COUNT_BYTES_TRANS(2);
10653
10654                 if (check_col(pinfo->cinfo, COL_INFO)) {
10655                         col_append_fstr(
10656                                 pinfo->cinfo, COL_INFO, ", %s",
10657                                 val_to_str(si->info_level, qpi_loi_vals,
10658                                            "Unknown (%u)"));
10659                 }
10660
10661                 break;
10662         }
10663         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10664                 guint16 fid;
10665
10666                 /* fid */
10667                 CHECK_BYTE_COUNT_TRANS(2);
10668                 fid = tvb_get_letohs(tvb, offset);
10669                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
10670                 COUNT_BYTES_TRANS(2);
10671
10672                 /* level of interest */
10673                 CHECK_BYTE_COUNT_TRANS(2);
10674                 si->info_level = tvb_get_letohs(tvb, offset);
10675                 if (t2i != NULL && !pinfo->fd->flags.visited)
10676                         t2i->info_level = si->info_level;
10677                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10678                 COUNT_BYTES_TRANS(2);
10679
10680 #if 0
10681                 /*
10682                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10683                  * Extensions Version 3.0, Document Version 1.11,
10684                  * July 19, 1990" says this is I/O flags, but it's
10685                  * reserved in the SNIA spec, and some clients appear
10686                  * to leave junk in it.
10687                  *
10688                  * Is this some field used only if a particular
10689                  * dialect was negotiated, so that clients can feel
10690                  * safe not setting it if they haven't negotiated that
10691                  * dialect?  Or do the (non-OS/2) clients simply not care
10692                  * about that particular OS/2-oriented dialect?
10693                  */
10694
10695                 /* IO Flag */
10696                 CHECK_BYTE_COUNT_TRANS(2);
10697                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10698                 bc -= 2;
10699 #else
10700                 /* 2 reserved bytes */
10701                 CHECK_BYTE_COUNT_TRANS(2);
10702                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10703                 COUNT_BYTES_TRANS(2);
10704 #endif
10705
10706                 break;
10707         }
10708         case 0x09:      /*TRANS2_FSCTL*/
10709                 /* this call has no parameter block in the request */
10710
10711                 /*
10712                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10713                  * Extensions Version 3.0, Document Version 1.11,
10714                  * July 19, 1990" says this this contains a
10715                  * "File system specific parameter block".  (That means
10716                  * we may not be able to dissect it in any case.)
10717                  */
10718                 break;
10719         case 0x0a:      /*TRANS2_IOCTL2*/
10720                 /* this call has no parameter block in the request */
10721
10722                 /*
10723                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10724                  * Extensions Version 3.0, Document Version 1.11,
10725                  * July 19, 1990" says this this contains a
10726                  * "Device/function specific parameter block".  (That
10727                  * means we may not be able to dissect it in any case.)
10728                  */
10729                 break;
10730         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10731                 /* Search Attributes */
10732                 CHECK_BYTE_COUNT_TRANS(2);
10733                 offset = dissect_search_attributes(tvb, tree, offset);
10734                 bc -= 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                 /* Find Notify information level */
10742                 CHECK_BYTE_COUNT_TRANS(2);
10743                 si->info_level = tvb_get_letohs(tvb, offset);
10744                 if (t2i != NULL && !pinfo->fd->flags.visited)
10745                         t2i->info_level = si->info_level;
10746                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10747                 COUNT_BYTES_TRANS(2);
10748
10749                 /* 4 reserved bytes */
10750                 CHECK_BYTE_COUNT_TRANS(4);
10751                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10752                 COUNT_BYTES_TRANS(4);
10753
10754                 /* file name */
10755                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10756                 CHECK_STRING_TRANS(fn);
10757                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10758                         fn);
10759                 COUNT_BYTES_TRANS(fn_len);
10760
10761                 if (check_col(pinfo->cinfo, COL_INFO)) {
10762                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10763                             format_text(fn, strlen(fn)));
10764                 }
10765
10766                 break;
10767         }
10768         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10769                 /* Monitor handle */
10770                 CHECK_BYTE_COUNT_TRANS(2);
10771                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10772                 COUNT_BYTES_TRANS(2);
10773
10774                 /* Number of changes to wait for */
10775                 CHECK_BYTE_COUNT_TRANS(2);
10776                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10777                 COUNT_BYTES_TRANS(2);
10778
10779                 break;
10780         }
10781         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10782                 /* 4 reserved bytes */
10783                 CHECK_BYTE_COUNT_TRANS(4);
10784                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10785                 COUNT_BYTES_TRANS(4);
10786
10787                 /* dir name */
10788                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10789                         FALSE, FALSE, &bc);
10790                 CHECK_STRING_TRANS(fn);
10791                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10792                         fn);
10793                 COUNT_BYTES_TRANS(fn_len);
10794
10795                 if (check_col(pinfo->cinfo, COL_INFO)) {
10796                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10797                             format_text(fn, strlen(fn)));
10798                 }
10799                 break;
10800         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10801                 /* XXX unknown structure*/
10802                 break;
10803         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10804                 /* referral level */
10805                 CHECK_BYTE_COUNT_TRANS(2);
10806                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10807                 COUNT_BYTES_TRANS(2);
10808
10809                 /* file name */
10810                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10811                 CHECK_STRING_TRANS(fn);
10812                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10813                         fn);
10814                 COUNT_BYTES_TRANS(fn_len);
10815
10816                 if (check_col(pinfo->cinfo, COL_INFO)) {
10817                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10818                             format_text(fn, strlen(fn)));
10819                 }
10820
10821                 break;
10822         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10823                 /* file name */
10824                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10825                 CHECK_STRING_TRANS(fn);
10826                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10827                         fn);
10828                 COUNT_BYTES_TRANS(fn_len);
10829
10830                 if (check_col(pinfo->cinfo, COL_INFO)) {
10831                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10832                             format_text(fn, strlen(fn)));
10833                 }
10834
10835                 break;
10836         }
10837
10838         /* ooops there were data we didnt know how to process */
10839         if(bc != 0){
10840                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10841                 offset += bc;
10842         }
10843
10844         return offset;
10845 }
10846
10847 /*
10848  * XXX - just use "dissect_connect_flags()" here?
10849  */
10850 static guint16
10851 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10852 {
10853         guint16 mask;
10854         proto_item *item;
10855         proto_tree *tree;
10856
10857         mask = tvb_get_letohs(tvb, offset);
10858
10859         if(parent_tree){
10860                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10861                         "Flags: 0x%04x", mask);
10862                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10863
10864                 proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10865                         tvb, offset, 2, mask);
10866                 proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10867                         tvb, offset, 2, mask);
10868         }
10869
10870         return mask;
10871 }
10872
10873
10874 static int
10875 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10876 {
10877         guint16 mask;
10878         proto_item *item;
10879         proto_tree *tree;
10880
10881         mask = tvb_get_letohs(tvb, offset);
10882
10883         if(parent_tree){
10884                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10885                         "Flags: 0x%04x", mask);
10886                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10887
10888                 proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10889                         tvb, offset, 2, mask);
10890                 proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10891                         tvb, offset, 2, mask);
10892         }
10893
10894         offset += 2;
10895         return offset;
10896 }
10897
10898 static int
10899 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10900 {
10901         guint16 mask;
10902         proto_item *item;
10903         proto_tree *tree;
10904
10905         mask = tvb_get_letohs(tvb, offset);
10906
10907         if(parent_tree){
10908                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10909                         "Flags: 0x%04x", mask);
10910                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10911
10912                 proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10913                         tvb, offset, 2, mask);
10914         }
10915
10916         offset += 2;
10917
10918         return offset;
10919 }
10920
10921
10922 /* dfs inconsistency data  (4.4.2)
10923 */
10924 static int
10925 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10926     proto_tree *tree, int offset, guint16 *bcp)
10927 {
10928         smb_info_t *si = pinfo->private_data;
10929         int fn_len;
10930         const char *fn;
10931
10932         DISSECTOR_ASSERT(si);
10933
10934         /*XXX shouldn this data hold version and size? unclear from doc*/
10935         /* referral version */
10936         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10937         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10938         COUNT_BYTES_TRANS_SUBR(2);
10939
10940         /* referral size */
10941         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10942         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10943         COUNT_BYTES_TRANS_SUBR(2);
10944
10945         /* referral server type */
10946         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10947         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10948         COUNT_BYTES_TRANS_SUBR(2);
10949
10950         /* referral flags */
10951         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10952         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10953         *bcp -= 2;
10954
10955         /* node name */
10956         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10957         CHECK_STRING_TRANS_SUBR(fn);
10958         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10959                 fn);
10960         COUNT_BYTES_TRANS_SUBR(fn_len);
10961
10962         return offset;
10963 }
10964
10965 /* get dfs referral data  (4.4.1)
10966 */
10967 static int
10968 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10969     proto_tree *tree, int offset, guint16 *bcp)
10970 {
10971         smb_info_t *si = pinfo->private_data;
10972         guint16 numref;
10973         guint16 refsize;
10974         guint16 pathoffset;
10975         guint16 altpathoffset;
10976         guint16 nodeoffset;
10977         int fn_len;
10978         int stroffset;
10979         int offsetoffset;
10980         guint16 save_bc;
10981         const char *fn;
10982         int unklen;
10983         int ucstring_end;
10984         int ucstring_len;
10985
10986         DISSECTOR_ASSERT(si);
10987
10988         /* path consumed */
10989         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10990         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10991         COUNT_BYTES_TRANS_SUBR(2);
10992
10993         /* num referrals */
10994         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10995         numref = tvb_get_letohs(tvb, offset);
10996         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10997         COUNT_BYTES_TRANS_SUBR(2);
10998
10999         /* get dfs flags */
11000         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11001         offset = dissect_get_dfs_flags(tvb, tree, offset);
11002         *bcp -= 2;
11003
11004         /* XXX - in at least one capture there appears to be 2 bytes
11005            of stuff after the Dfs flags, perhaps so that the header
11006            in front of the referral list is a multiple of 4 bytes long. */
11007         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11008         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
11009         COUNT_BYTES_TRANS_SUBR(2);
11010
11011         /* if there are any referrals */
11012         if(numref){
11013                 proto_item *ref_item = NULL;
11014                 proto_tree *ref_tree = NULL;
11015                 int old_offset=offset;
11016
11017                 if(tree){
11018                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
11019                         ref_item = proto_tree_add_text(tree,
11020                                 tvb, offset, *bcp, "Referrals");
11021                         ref_tree = proto_item_add_subtree(ref_item,
11022                                 ett_smb_dfs_referrals);
11023                 }
11024                 ucstring_end = -1;
11025
11026                 while(numref--){
11027                         proto_item *ri = NULL;
11028                         proto_tree *rt = NULL;
11029                         int old_offset=offset;
11030                         guint16 version;
11031
11032                         if(tree){
11033                                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
11034                                 ri = proto_tree_add_text(ref_tree,
11035                                         tvb, offset, *bcp, "Referral");
11036                                 rt = proto_item_add_subtree(ri,
11037                                         ett_smb_dfs_referral);
11038                         }
11039
11040                         /* referral version */
11041                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11042                         version = tvb_get_letohs(tvb, offset);
11043                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
11044                                 tvb, offset, 2, version);
11045                         COUNT_BYTES_TRANS_SUBR(2);
11046
11047                         /* referral size */
11048                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11049                         refsize = tvb_get_letohs(tvb, offset);
11050                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
11051                         COUNT_BYTES_TRANS_SUBR(2);
11052
11053                         /* referral server type */
11054                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11055                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
11056                         COUNT_BYTES_TRANS_SUBR(2);
11057
11058                         /* referral flags */
11059                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11060                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
11061                         *bcp -= 2;
11062
11063                         switch(version){
11064
11065                         case 1:
11066                                 /* node name */
11067                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11068                                 CHECK_STRING_TRANS_SUBR(fn);
11069                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
11070                                         fn);
11071                                 COUNT_BYTES_TRANS_SUBR(fn_len);
11072                                 break;
11073
11074                         case 2:
11075                         case 3: /* XXX - like version 2, but not identical;
11076                                    seen in a capture, but the format isn't
11077                                    documented */
11078                                 /* proximity */
11079                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11080                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
11081                                 COUNT_BYTES_TRANS_SUBR(2);
11082
11083                                 /* ttl */
11084                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11085                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
11086                                 COUNT_BYTES_TRANS_SUBR(2);
11087
11088                                 /* path offset */
11089                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11090                                 pathoffset = tvb_get_letohs(tvb, offset);
11091                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11092                                 COUNT_BYTES_TRANS_SUBR(2);
11093
11094                                 /* alt path offset */
11095                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11096                                 altpathoffset = tvb_get_letohs(tvb, offset);
11097                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11098                                 COUNT_BYTES_TRANS_SUBR(2);
11099
11100                                 /* node offset */
11101                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11102                                 nodeoffset = tvb_get_letohs(tvb, offset);
11103                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11104                                 COUNT_BYTES_TRANS_SUBR(2);
11105
11106                                 /* path */
11107                                 if (pathoffset != 0) {
11108                                         stroffset = old_offset + pathoffset;
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_path, 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
11125                                 /* alt path */
11126                                 if (altpathoffset != 0) {
11127                                         stroffset = old_offset + altpathoffset;
11128                                         offsetoffset = stroffset - offset;
11129                                         if (offsetoffset > 0 &&
11130                                             *bcp > offsetoffset) {
11131                                                 save_bc = *bcp;
11132                                                 *bcp -= offsetoffset;
11133                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11134                                                 CHECK_STRING_TRANS_SUBR(fn);
11135                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
11136                                                         fn);
11137                                                 stroffset += fn_len;
11138                                                 if (ucstring_end < stroffset)
11139                                                         ucstring_end = stroffset;
11140                                                 *bcp = save_bc;
11141                                         }
11142                                 }
11143
11144                                 /* node */
11145                                 if (nodeoffset != 0) {
11146                                         stroffset = old_offset + nodeoffset;
11147                                         offsetoffset = stroffset - offset;
11148                                         if (offsetoffset > 0 &&
11149                                             *bcp > offsetoffset) {
11150                                                 save_bc = *bcp;
11151                                                 *bcp -= offsetoffset;
11152                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11153                                                 CHECK_STRING_TRANS_SUBR(fn);
11154                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
11155                                                         fn);
11156                                                 stroffset += fn_len;
11157                                                 if (ucstring_end < stroffset)
11158                                                         ucstring_end = stroffset;
11159                                                 *bcp = save_bc;
11160                                         }
11161                                 }
11162                                 break;
11163                         }
11164
11165                         /*
11166                          * Show anything beyond the length of the referral
11167                          * as unknown data.
11168                          */
11169                         unklen = (old_offset + refsize) - offset;
11170                         if (unklen < 0) {
11171                                 /*
11172                                  * XXX - the length is bogus.
11173                                  */
11174                                 unklen = 0;
11175                         }
11176                         if (unklen != 0) {
11177                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
11178                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
11179                                     offset, unklen, TRUE);
11180                                 COUNT_BYTES_TRANS_SUBR(unklen);
11181                         }
11182
11183                         proto_item_set_len(ri, offset-old_offset);
11184                 }
11185
11186                 /*
11187                  * Treat the offset past the end of the last Unicode
11188                  * string after the referrals (if any) as the last
11189                  * offset.
11190                  */
11191                 if (ucstring_end > offset) {
11192                         ucstring_len = ucstring_end - offset;
11193                         if (*bcp < ucstring_len)
11194                                 ucstring_len = *bcp;
11195                         offset += ucstring_len;
11196                         *bcp -= ucstring_len;
11197                 }
11198                 proto_item_set_len(ref_item, offset-old_offset);
11199         }
11200
11201         return offset;
11202 }
11203
11204 /* This dissects the standard four 8-byte Windows timestamps ...
11205  */
11206 static int
11207 dissect_smb_standard_8byte_timestamps(tvbuff_t *tvb,
11208     packet_info *pinfo _U_, proto_tree *tree,
11209     int offset, guint16 *bcp, gboolean *trunc)
11210 {
11211         /* create time */
11212         CHECK_BYTE_COUNT_SUBR(8);
11213         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11214         *bcp -= 8;
11215
11216         /* access time */
11217         CHECK_BYTE_COUNT_SUBR(8);
11218         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
11219         *bcp -= 8;
11220
11221         /* last write time */
11222         CHECK_BYTE_COUNT_SUBR(8);
11223         offset = dissect_nt_64bit_time(tvb, tree, offset,
11224                 hf_smb_last_write_time);
11225         *bcp -= 8;
11226
11227         /* last change time */
11228         CHECK_BYTE_COUNT_SUBR(8);
11229         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
11230         *bcp -= 8;
11231
11232         *trunc = FALSE;
11233         return offset;
11234 }
11235
11236 /* this dissects the SMB_INFO_STANDARD
11237    as described in 4.2.16.1
11238 */
11239 static int
11240 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11241     int offset, guint16 *bcp, gboolean *trunc)
11242 {
11243         /* create time */
11244         CHECK_BYTE_COUNT_SUBR(4);
11245         offset = dissect_smb_datetime(tvb, tree, offset,
11246                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
11247                 FALSE);
11248         *bcp -= 4;
11249
11250         /* access time */
11251         CHECK_BYTE_COUNT_SUBR(4);
11252         offset = dissect_smb_datetime(tvb, tree, offset,
11253                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
11254                 FALSE);
11255         *bcp -= 4;
11256
11257         /* last write time */
11258         CHECK_BYTE_COUNT_SUBR(4);
11259         offset = dissect_smb_datetime(tvb, tree, offset,
11260                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
11261                 FALSE);
11262         *bcp -= 4;
11263
11264         /* data size */
11265         CHECK_BYTE_COUNT_SUBR(4);
11266         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11267         COUNT_BYTES_SUBR(4);
11268
11269         /* allocation size */
11270         CHECK_BYTE_COUNT_SUBR(4);
11271         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11272         COUNT_BYTES_SUBR(4);
11273
11274         /* File Attributes */
11275         CHECK_BYTE_COUNT_SUBR(2);
11276         offset = dissect_file_attributes(tvb, tree, offset, 2);
11277         *bcp -= 2;
11278
11279         /* ea length */
11280         CHECK_BYTE_COUNT_SUBR(4);
11281         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11282         COUNT_BYTES_SUBR(4);
11283
11284         *trunc = FALSE;
11285         return offset;
11286 }
11287
11288 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
11289    as described in 4.2.16.2
11290 */
11291 static int
11292 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11293     int offset, guint16 *bcp, gboolean *trunc)
11294 {
11295         guint8 name_len;
11296         guint16 data_len;
11297         /* EA size */
11298
11299         CHECK_BYTE_COUNT_SUBR(4);
11300         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11301         COUNT_BYTES_SUBR(4);
11302
11303         while (*bcp > 0) {
11304                 proto_item *item;
11305                 proto_tree *subtree;
11306                 int start_offset = offset;
11307                 guint8 *name;
11308
11309                 item = proto_tree_add_text(
11310                         tree, tvb, offset, 0, "Extended Attribute");
11311                 subtree = proto_item_add_subtree(item, ett_smb_ea);
11312
11313                 /* EA flags */
11314
11315                 CHECK_BYTE_COUNT_SUBR(1);
11316                 proto_tree_add_item(
11317                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
11318                 COUNT_BYTES_SUBR(1);
11319
11320                 /* EA name length */
11321
11322                 name_len = tvb_get_guint8(tvb, offset);
11323
11324                 CHECK_BYTE_COUNT_SUBR(1);
11325                 proto_tree_add_item(
11326                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
11327                 COUNT_BYTES_SUBR(1);
11328
11329                 /* EA data length */
11330
11331                 data_len = tvb_get_letohs(tvb, offset);
11332
11333                 CHECK_BYTE_COUNT_SUBR(2);
11334                 proto_tree_add_item(
11335                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
11336                 COUNT_BYTES_SUBR(2);
11337
11338                 /* EA name */
11339
11340                 name = tvb_get_ephemeral_string(tvb, offset, name_len);
11341                 proto_item_append_text(item, ": %s", format_text(name, strlen(name)));
11342
11343                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
11344                 proto_tree_add_item(
11345                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1,
11346                         TRUE);
11347                 COUNT_BYTES_SUBR(name_len + 1);
11348
11349                 /* EA data */
11350
11351                 CHECK_BYTE_COUNT_SUBR(data_len);
11352                 proto_tree_add_item(
11353                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
11354                 COUNT_BYTES_SUBR(data_len);
11355
11356                 proto_item_set_len(item, offset - start_offset);
11357         }
11358
11359         *trunc = FALSE;
11360         return offset;
11361 }
11362
11363 /* this dissects the SMB_INFO_IS_NAME_VALID
11364    as described in 4.2.16.3
11365 */
11366 static int
11367 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11368     int offset, guint16 *bcp, gboolean *trunc)
11369 {
11370         smb_info_t *si = pinfo->private_data;
11371         int fn_len;
11372         const char *fn;
11373
11374         DISSECTOR_ASSERT(si);
11375
11376         /* file name */
11377         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11378         CHECK_STRING_SUBR(fn);
11379         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11380                 fn);
11381         COUNT_BYTES_SUBR(fn_len);
11382
11383         *trunc = FALSE;
11384         return offset;
11385 }
11386
11387 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
11388    as described in 4.2.16.4
11389 */
11390 static int
11391 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11392     int offset, guint16 *bcp, gboolean *trunc)
11393 {
11394
11395         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11396         if (*trunc) {
11397           return offset;
11398         }
11399
11400         /* File Attributes */
11401         CHECK_BYTE_COUNT_SUBR(4);
11402         offset = dissect_file_attributes(tvb, tree, offset, 4);
11403         *bcp -= 4;
11404
11405         *trunc = FALSE;
11406         return offset;
11407 }
11408
11409 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
11410    as described in 4.2.16.5
11411 */
11412 int
11413 dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11414     int offset, guint16 *bcp, gboolean *trunc)
11415 {
11416         /* allocation size */
11417         CHECK_BYTE_COUNT_SUBR(8);
11418         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11419         COUNT_BYTES_SUBR(8);
11420
11421         /* end of file */
11422         CHECK_BYTE_COUNT_SUBR(8);
11423         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11424         COUNT_BYTES_SUBR(8);
11425
11426         /* number of links */
11427         CHECK_BYTE_COUNT_SUBR(4);
11428         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11429         COUNT_BYTES_SUBR(4);
11430
11431         /* delete pending */
11432         CHECK_BYTE_COUNT_SUBR(1);
11433         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11434         COUNT_BYTES_SUBR(1);
11435
11436         /* is directory */
11437         CHECK_BYTE_COUNT_SUBR(1);
11438         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11439         COUNT_BYTES_SUBR(1);
11440
11441         *trunc = FALSE;
11442         return offset;
11443 }
11444
11445 /* this dissects the SMB_QUERY_FILE_INTERNAL_INFO
11446 */
11447 int
11448 dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11449     int offset, guint16 *bcp, gboolean *trunc)
11450 {
11451         /* file id */
11452         CHECK_BYTE_COUNT_SUBR(8);
11453         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11454         COUNT_BYTES_SUBR(8);
11455
11456         *trunc = FALSE;
11457         return offset;
11458 }
11459
11460 /* this dissects the SMB_QUERY_FILE_POSITION_INFO
11461 */
11462 int
11463 dissect_qfi_SMB_FILE_POSITION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11464     int offset, guint16 *bcp, gboolean *trunc)
11465 {
11466         /* file id */
11467         CHECK_BYTE_COUNT_SUBR(8);
11468         proto_tree_add_item(tree, hf_smb_position, tvb, offset, 8, TRUE);
11469         COUNT_BYTES_SUBR(8);
11470
11471         *trunc = FALSE;
11472         return offset;
11473 }
11474
11475 /* this dissects the SMB_QUERY_FILE_MODE_INFO
11476 */
11477 int
11478 dissect_qfi_SMB_FILE_MODE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11479     int offset, guint16 *bcp, gboolean *trunc)
11480 {
11481         /* mode */
11482         CHECK_BYTE_COUNT_SUBR(4);
11483         proto_tree_add_item(tree, hf_smb_mode, tvb, offset, 4, TRUE);
11484         COUNT_BYTES_SUBR(4);
11485
11486         *trunc = FALSE;
11487         return offset;
11488 }
11489
11490 /* this dissects the SMB_QUERY_FILE_ALIGNMENT_INFO
11491 */
11492 int
11493 dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11494     int offset, guint16 *bcp, gboolean *trunc)
11495 {
11496         /* alignment */
11497         CHECK_BYTE_COUNT_SUBR(4);
11498         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11499         COUNT_BYTES_SUBR(4);
11500
11501         *trunc = FALSE;
11502         return offset;
11503 }
11504
11505 /* this dissects the SMB_QUERY_FILE_EA_INFO
11506    as described in 4.2.16.6
11507 */
11508 int
11509 dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11510     int offset, guint16 *bcp, gboolean *trunc)
11511 {
11512         /* ea length */
11513         CHECK_BYTE_COUNT_SUBR(4);
11514         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11515         COUNT_BYTES_SUBR(4);
11516
11517         *trunc = FALSE;
11518         return offset;
11519 }
11520
11521 /* this dissects the SMB_QUERY_FILE_ALLOCATION_INFO
11522 */
11523 int
11524 dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11525     int offset, guint16 *bcp, gboolean *trunc)
11526 {
11527         /* allocation size */
11528         CHECK_BYTE_COUNT_SUBR(8);
11529         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11530         COUNT_BYTES_SUBR(8);
11531
11532         *trunc = FALSE;
11533         return offset;
11534 }
11535
11536 /* this dissects the SMB_QUERY_FILE_ENDOFFILE_INFO
11537 */
11538 int
11539 dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11540     int offset, guint16 *bcp, gboolean *trunc)
11541 {
11542         /* end of file */
11543         CHECK_BYTE_COUNT_SUBR(8);
11544         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11545         COUNT_BYTES_SUBR(8);
11546
11547         *trunc = FALSE;
11548         return offset;
11549 }
11550
11551 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11552    as described in 4.2.16.7
11553    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11554    as described in 4.2.16.9
11555 */
11556 int
11557 dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11558     int offset, guint16 *bcp, gboolean *trunc)
11559 {
11560         smb_info_t *si = pinfo->private_data;
11561         int fn_len;
11562         const char *fn;
11563
11564         DISSECTOR_ASSERT(si);
11565
11566         /* file name len */
11567         CHECK_BYTE_COUNT_SUBR(4);
11568         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11569         COUNT_BYTES_SUBR(4);
11570
11571         /* file name */
11572         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11573         CHECK_STRING_SUBR(fn);
11574         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11575                 fn);
11576         COUNT_BYTES_SUBR(fn_len);
11577
11578         *trunc = FALSE;
11579         return offset;
11580 }
11581
11582 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11583    but not as described in 4.2.16.8 since CNIA spec is wrong
11584 */
11585 static int
11586 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11587     int offset, guint16 *bcp, gboolean *trunc)
11588 {
11589         smb_info_t *si;
11590         guint32 fn_len;
11591         const char *fn;
11592
11593         si = (smb_info_t *)pinfo->private_data;
11594
11595         DISSECTOR_ASSERT(si);
11596
11597         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
11598         if (*trunc) {
11599           return offset;
11600         }
11601
11602         /* File Attributes */
11603         CHECK_BYTE_COUNT_SUBR(4);
11604         offset = dissect_file_attributes(tvb, tree, offset, 4);
11605         *bcp -= 4;
11606
11607         /* 4 pad bytes */
11608         offset+=4;
11609         *bcp -= 4;
11610
11611         /* allocation size */
11612         CHECK_BYTE_COUNT_SUBR(8);
11613         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11614         COUNT_BYTES_SUBR(8);
11615
11616         /* end of file */
11617         CHECK_BYTE_COUNT_SUBR(8);
11618         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11619         COUNT_BYTES_SUBR(8);
11620
11621         /* number of links */
11622         CHECK_BYTE_COUNT_SUBR(4);
11623         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11624         COUNT_BYTES_SUBR(4);
11625
11626         /* delete pending */
11627         CHECK_BYTE_COUNT_SUBR(1);
11628         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11629         COUNT_BYTES_SUBR(1);
11630
11631         /* is directory */
11632         CHECK_BYTE_COUNT_SUBR(1);
11633         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11634         COUNT_BYTES_SUBR(1);
11635
11636         /* 2 pad bytes */
11637         offset+=2;
11638         *bcp -= 2;
11639
11640         /* ea length */
11641         CHECK_BYTE_COUNT_SUBR(4);
11642         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11643         COUNT_BYTES_SUBR(4);
11644
11645         /* file name len */
11646         CHECK_BYTE_COUNT_SUBR(4);
11647         fn_len = (guint32)tvb_get_letohl(tvb, offset);
11648         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11649         COUNT_BYTES_SUBR(4);
11650
11651
11652         /* file name */
11653         CHECK_BYTE_COUNT_SUBR(fn_len);
11654         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
11655         if (fn != NULL) {
11656                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11657                         fn);
11658                 COUNT_BYTES_SUBR(fn_len);
11659         }
11660
11661
11662         if (*trunc)
11663                 return offset;
11664
11665         return offset;
11666 }
11667
11668 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11669    as described in 4.2.16.10
11670 */
11671 int
11672 dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
11673     int offset, guint16 *bcp, gboolean *trunc, int unicode)
11674 {
11675         proto_item *item;
11676         proto_tree *tree;
11677         int old_offset;
11678         guint32 neo;
11679         int fn_len;
11680         const char *fn;
11681         int padcnt;
11682
11683
11684         for (;;) {
11685                 old_offset = offset;
11686
11687                 /* next entry offset */
11688                 CHECK_BYTE_COUNT_SUBR(4);
11689                 if(parent_tree){
11690                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
11691                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11692                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11693                 } else {
11694                         item = NULL;
11695                         tree = NULL;
11696                 }
11697
11698                 neo = tvb_get_letohl(tvb, offset);
11699                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11700                 COUNT_BYTES_SUBR(4);
11701
11702                 /* stream name len */
11703                 CHECK_BYTE_COUNT_SUBR(4);
11704                 fn_len = tvb_get_letohl(tvb, offset);
11705                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11706                 COUNT_BYTES_SUBR(4);
11707
11708                 /* stream size */
11709                 CHECK_BYTE_COUNT_SUBR(8);
11710                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11711                 COUNT_BYTES_SUBR(8);
11712
11713                 /* allocation size */
11714                 CHECK_BYTE_COUNT_SUBR(8);
11715                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11716                 COUNT_BYTES_SUBR(8);
11717
11718                 /* stream name */
11719                 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
11720                 CHECK_STRING_SUBR(fn);
11721                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11722                         fn);
11723                 COUNT_BYTES_SUBR(fn_len);
11724
11725                 proto_item_append_text(item, ": %s", format_text(fn, strlen(fn)));
11726                 proto_item_set_len(item, offset-old_offset);
11727
11728                 if (neo == 0)
11729                         break;  /* no more structures */
11730
11731                 /* skip to next structure */
11732                 padcnt = (old_offset + neo) - offset;
11733                 if (padcnt < 0) {
11734                         /*
11735                          * XXX - this is bogus; flag it?
11736                          */
11737                         padcnt = 0;
11738                 }
11739                 if (padcnt != 0) {
11740                         CHECK_BYTE_COUNT_SUBR(padcnt);
11741                         COUNT_BYTES_SUBR(padcnt);
11742                 }
11743         }
11744
11745         *trunc = FALSE;
11746         return offset;
11747 }
11748
11749 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11750    as described in 4.2.16.11
11751 */
11752 int
11753 dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11754     int offset, guint16 *bcp, gboolean *trunc)
11755 {
11756         /* compressed file size */
11757         CHECK_BYTE_COUNT_SUBR(8);
11758         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11759         COUNT_BYTES_SUBR(8);
11760
11761         /* compression format */
11762         CHECK_BYTE_COUNT_SUBR(2);
11763         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11764         COUNT_BYTES_SUBR(2);
11765
11766         /* compression unit shift */
11767         CHECK_BYTE_COUNT_SUBR(1);
11768         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11769         COUNT_BYTES_SUBR(1);
11770
11771         /* compression chunk shift */
11772         CHECK_BYTE_COUNT_SUBR(1);
11773         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11774         COUNT_BYTES_SUBR(1);
11775
11776         /* compression cluster shift */
11777         CHECK_BYTE_COUNT_SUBR(1);
11778         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11779         COUNT_BYTES_SUBR(1);
11780
11781         /* 3 reserved bytes */
11782         CHECK_BYTE_COUNT_SUBR(3);
11783         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11784         COUNT_BYTES_SUBR(3);
11785
11786         *trunc = FALSE;
11787         return offset;
11788 }
11789
11790 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11791
11792 static const value_string unix_file_type_vals[] = {
11793         { 0, "File" },
11794         { 1, "Directory" },
11795         { 2, "Symbolic link" },
11796         { 3, "Character device" },
11797         { 4, "Block device" },
11798         { 5, "FIFO" },
11799         { 6, "Socket" },
11800         { 0, NULL }
11801 };
11802
11803 static int
11804 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11805                   int offset, guint16 *bcp, gboolean *trunc)
11806 {
11807         /* End of file (file size) */
11808         CHECK_BYTE_COUNT_SUBR(8);
11809         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11810         COUNT_BYTES_SUBR(8);
11811
11812         /* Number of bytes */
11813         CHECK_BYTE_COUNT_SUBR(8);
11814         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11815         COUNT_BYTES_SUBR(8);
11816
11817         /* Last status change */
11818         CHECK_BYTE_COUNT_SUBR(8);
11819         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11820         *bcp -= 8;              /* dissect_nt_64bit_time() increments offset */
11821
11822         /* Last access time */
11823         CHECK_BYTE_COUNT_SUBR(8);
11824         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11825         *bcp -= 8;
11826
11827         /* Last modification time */
11828         CHECK_BYTE_COUNT_SUBR(8);
11829         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11830         *bcp -= 8;
11831
11832         /* File owner uid */
11833         CHECK_BYTE_COUNT_SUBR(8);
11834         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11835         COUNT_BYTES_SUBR(8);
11836
11837         /* File group gid */
11838         CHECK_BYTE_COUNT_SUBR(8);
11839         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11840         COUNT_BYTES_SUBR(8);
11841
11842         /* File type */
11843         CHECK_BYTE_COUNT_SUBR(4);
11844         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11845         COUNT_BYTES_SUBR(4);
11846
11847         /* Major device number */
11848         CHECK_BYTE_COUNT_SUBR(8);
11849         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11850         COUNT_BYTES_SUBR(8);
11851
11852         /* Minor device number */
11853         CHECK_BYTE_COUNT_SUBR(8);
11854         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11855         COUNT_BYTES_SUBR(8);
11856
11857         /* Unique id */
11858         CHECK_BYTE_COUNT_SUBR(8);
11859         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11860         COUNT_BYTES_SUBR(8);
11861
11862         /* Permissions */
11863         CHECK_BYTE_COUNT_SUBR(8);
11864         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11865         COUNT_BYTES_SUBR(8);
11866
11867         /* Nlinks */
11868         CHECK_BYTE_COUNT_SUBR(8);
11869         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11870         COUNT_BYTES_SUBR(8);
11871
11872         /* Sometimes there is one extra byte in the data field which I
11873            guess could be padding, but we are only using 4 or 8 byte
11874            data types so this is a bit confusing. -tpot */
11875
11876         *trunc = FALSE;
11877         return offset;
11878 }
11879
11880 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11881
11882 static int
11883 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11884                   int offset, guint16 *bcp, gboolean *trunc)
11885 {
11886         smb_info_t *si = pinfo->private_data;
11887         const char *fn;
11888         int fn_len;
11889
11890         DISSECTOR_ASSERT(si);
11891
11892         /* Link destination */
11893
11894         fn = get_unicode_or_ascii_string(
11895                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11896
11897         CHECK_STRING_SUBR(fn);
11898         proto_tree_add_string(
11899                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11900         COUNT_BYTES_SUBR(fn_len);
11901
11902         *trunc = FALSE;
11903         return offset;
11904 }
11905
11906 /* unix ACL
11907 */
11908 static int
11909 dissect_qpi_unix_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11910                   int offset, guint16 *bcp, gboolean *trunc)
11911 {
11912         guint16 version, num_file_aces, num_def_aces;
11913         static const int *perm_fields[] = {
11914                 &hf_smb_posix_ace_perm_read,
11915                 &hf_smb_posix_ace_perm_write,
11916                 &hf_smb_posix_ace_perm_execute,
11917                 NULL
11918         };
11919
11920         /* version */
11921         CHECK_BYTE_COUNT_SUBR(2);
11922         version = tvb_get_letohs(tvb, offset);
11923         proto_tree_add_item(tree, hf_smb_posix_acl_version, tvb, offset, 2, TRUE);
11924         COUNT_BYTES_SUBR(2);
11925
11926         /* num file acls */
11927         CHECK_BYTE_COUNT_SUBR(2);
11928         num_file_aces = tvb_get_letohs(tvb, offset);
11929         proto_tree_add_item(tree, hf_smb_posix_num_file_aces, tvb, offset, 2, TRUE);
11930         COUNT_BYTES_SUBR(2);
11931
11932         /* num default acls */
11933         CHECK_BYTE_COUNT_SUBR(2);
11934         num_def_aces = tvb_get_letohs(tvb, offset);
11935         proto_tree_add_item(tree, hf_smb_posix_num_def_aces, tvb, offset, 2, TRUE);
11936         COUNT_BYTES_SUBR(2);
11937
11938         while(num_file_aces--){
11939                 proto_item *it;
11940                 proto_tree *tr;
11941                 int old_offset = offset;
11942                 guint8 ace_type;
11943
11944                 it = proto_tree_add_text(tree, tvb, offset, 0, "ACE");
11945                 tr = proto_item_add_subtree(it, ett_smb_posic_ace);
11946
11947                 /* ace type */
11948                 CHECK_BYTE_COUNT_SUBR(1);
11949                 ace_type = tvb_get_guint8(tvb, offset);
11950                 proto_tree_add_item(tr, hf_smb_posix_ace_type, tvb, offset, 1, TRUE);
11951                 COUNT_BYTES_SUBR(1);
11952
11953                 CHECK_BYTE_COUNT_SUBR(1);
11954                 proto_tree_add_bitmask(tr, tvb, offset, hf_smb_posix_ace_flags, ett_smb_posix_ace_perms, perm_fields, FALSE);
11955                 COUNT_BYTES_SUBR(1);
11956
11957                 switch(ace_type){
11958                 case POSIX_ACE_TYPE_USER_OBJ:
11959                         CHECK_BYTE_COUNT_SUBR(4);
11960                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_uid, tvb, offset, 4, TRUE);
11961                         COUNT_BYTES_SUBR(4);
11962
11963                         CHECK_BYTE_COUNT_SUBR(4);
11964                         /* 4 reserved bytes */
11965                         COUNT_BYTES_SUBR(4);
11966                         break;
11967                 case POSIX_ACE_TYPE_GROUP_OBJ:
11968                         CHECK_BYTE_COUNT_SUBR(4);
11969                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_gid, tvb, offset, 4, TRUE);
11970                         COUNT_BYTES_SUBR(4);
11971
11972                         CHECK_BYTE_COUNT_SUBR(4);
11973                         /* 4 reserved bytes */
11974                         COUNT_BYTES_SUBR(4);
11975                         break;
11976
11977                 case POSIX_ACE_TYPE_MASK:
11978                 case POSIX_ACE_TYPE_OTHER:
11979                         CHECK_BYTE_COUNT_SUBR(8);
11980                         /* 8 reserved bytes */
11981                         COUNT_BYTES_SUBR(8);
11982                         break;
11983
11984                 case POSIX_ACE_TYPE_USER:
11985                         CHECK_BYTE_COUNT_SUBR(4);
11986                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_uid, tvb, offset, 4, TRUE);
11987                         COUNT_BYTES_SUBR(4);
11988
11989                         CHECK_BYTE_COUNT_SUBR(4);
11990                         /* 4 reserved bytes */
11991                         COUNT_BYTES_SUBR(4);
11992                         break;
11993
11994                 case POSIX_ACE_TYPE_GROUP:
11995                         CHECK_BYTE_COUNT_SUBR(4);
11996                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_gid, tvb, offset, 4, TRUE);
11997                         COUNT_BYTES_SUBR(4);
11998
11999                         CHECK_BYTE_COUNT_SUBR(4);
12000                         /* 4 reserved bytes */
12001                         COUNT_BYTES_SUBR(4);
12002                         break;
12003                 default:
12004                         proto_tree_add_text(tr, tvb, offset, 0, "Unknown posix ace type");
12005                         CHECK_BYTE_COUNT_SUBR(8);
12006                         /* skip 8 bytes */
12007                         COUNT_BYTES_SUBR(8);
12008                 }
12009
12010                 proto_item_set_len(it, offset-old_offset);
12011         }
12012
12013         return offset;
12014 }
12015
12016 static int
12017 dissect_qpi_unix_xattr(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12018                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12019 {
12020         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12021
12022         return offset;
12023 }
12024
12025 static int
12026 dissect_qpi_unix_attr_flags(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12027                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12028 {
12029         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12030
12031         return offset;
12032 }
12033
12034 static int
12035 dissect_qpi_unix_permissions(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12036                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12037 {
12038         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12039
12040         return offset;
12041 }
12042
12043 static int
12044 dissect_qpi_unix_lock(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12045                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12046 {
12047         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12048
12049         return offset;
12050 }
12051
12052 static int
12053 dissect_qpi_unix_open(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12054                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12055 {
12056         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12057
12058         return offset;
12059 }
12060
12061 static int
12062 dissect_qpi_unix_unlink(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
12063                   int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
12064 {
12065         proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
12066
12067         return offset;
12068 }
12069
12070 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
12071 */
12072 int
12073 dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
12074     packet_info *pinfo, proto_tree *tree,
12075     int offset, guint16 *bcp, gboolean *trunc)
12076 {
12077
12078         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12079         if (*trunc) {
12080           return offset;
12081         }
12082
12083         /* allocation size */
12084         CHECK_BYTE_COUNT_SUBR(8);
12085         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12086         COUNT_BYTES_SUBR(8);
12087
12088         /* end of file */
12089         CHECK_BYTE_COUNT_SUBR(8);
12090         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12091         COUNT_BYTES_SUBR(8);
12092
12093         /* File Attributes */
12094         CHECK_BYTE_COUNT_SUBR(4);
12095         offset = dissect_file_attributes(tvb, tree, offset, 4);
12096         *bcp -= 4;
12097
12098         /* Unknown, possibly count of network accessors ... */
12099         CHECK_BYTE_COUNT_SUBR(4);
12100         proto_tree_add_item(tree, hf_smb_network_unknown, tvb, offset, 4, TRUE);
12101         COUNT_BYTES_SUBR(4);
12102
12103         *trunc = FALSE;
12104         return offset;
12105 }
12106
12107 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
12108 */
12109 int
12110 dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb,
12111     packet_info *pinfo _U_, proto_tree *tree,
12112     int offset, guint16 *bcp, gboolean *trunc)
12113 {
12114         /* attribute */
12115         CHECK_BYTE_COUNT_SUBR(4);
12116         proto_tree_add_item(tree, hf_smb_attribute, tvb, offset, 4, TRUE);
12117         COUNT_BYTES_SUBR(4);
12118
12119         /* reparse tag */
12120         CHECK_BYTE_COUNT_SUBR(4);
12121         proto_tree_add_item(tree, hf_smb_reparse_tag, tvb, offset, 4, TRUE);
12122         COUNT_BYTES_SUBR(4);
12123
12124         *trunc = FALSE;
12125         return offset;
12126 }
12127
12128 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
12129    as described in 4.2.19.2
12130 */
12131 static int
12132 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12133     int offset, guint16 *bcp, gboolean *trunc)
12134 {
12135         /* marked for deletion? */
12136         CHECK_BYTE_COUNT_SUBR(1);
12137         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
12138         COUNT_BYTES_SUBR(1);
12139
12140         *trunc = FALSE;
12141         return offset;
12142 }
12143
12144 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
12145    as described in 4.2.19.3
12146 */
12147 static int
12148 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12149     int offset, guint16 *bcp, gboolean *trunc)
12150 {
12151         /* file allocation size */
12152         CHECK_BYTE_COUNT_SUBR(8);
12153         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12154         COUNT_BYTES_SUBR(8);
12155
12156         *trunc = FALSE;
12157         return offset;
12158 }
12159
12160 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
12161    as described in 4.2.19.4
12162 */
12163 static int
12164 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12165     int offset, guint16 *bcp, gboolean *trunc)
12166 {
12167         /* file end of file offset */
12168         CHECK_BYTE_COUNT_SUBR(8);
12169         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12170         COUNT_BYTES_SUBR(8);
12171
12172         *trunc = FALSE;
12173         return offset;
12174 }
12175
12176 /* Set File Rename Info */
12177
12178 static const true_false_string tfs_smb_replace = {
12179         "Remove target file if it exists",
12180         "Do NOT remove target file if it exists",
12181 };
12182
12183 static int
12184 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12185                     int offset, guint16 *bcp, gboolean *trunc)
12186 {
12187         smb_info_t *si = pinfo->private_data;
12188         const char *fn;
12189         guint32 target_name_len;
12190         int fn_len;
12191
12192         DISSECTOR_ASSERT(si);
12193
12194         /* Replace flag */
12195         CHECK_BYTE_COUNT_SUBR(4);
12196         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, TRUE);
12197         COUNT_BYTES_SUBR(4);
12198
12199         /* Root directory handle */
12200         CHECK_BYTE_COUNT_SUBR(4);
12201         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, TRUE);
12202         COUNT_BYTES_SUBR(4);
12203
12204         /* Target name length */
12205         CHECK_BYTE_COUNT_SUBR(4);
12206         target_name_len = tvb_get_letohl(tvb, offset);
12207         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
12208         COUNT_BYTES_SUBR(4);
12209
12210         /* Target name */
12211         fn_len = target_name_len;
12212         fn = get_unicode_or_ascii_string(
12213                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12214
12215         CHECK_STRING_SUBR(fn);
12216         proto_tree_add_string(
12217                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
12218         COUNT_BYTES_SUBR(fn_len);
12219
12220         *trunc = FALSE;
12221         return offset;
12222 }
12223
12224 static int
12225 dissect_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12226                     int offset, guint16 *bcp, gboolean *trunc)
12227 {
12228         smb_info_t *si = pinfo->private_data;
12229 /*      const char *fn;*/
12230 /*      guint32 target_name_len;*/
12231 /*      int fn_len;*/
12232
12233         DISSECTOR_ASSERT(si);
12234
12235         /* Disposition flags */
12236         CHECK_BYTE_COUNT_SUBR(1);
12237         proto_tree_add_item(tree, hf_smb_disposition_delete_on_close, tvb, offset, 1, TRUE);
12238         COUNT_BYTES_SUBR(1);
12239
12240         *trunc = FALSE;
12241         return offset;
12242 }
12243
12244 int
12245 dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12246                     int offset, guint16 *bcp, gboolean *trunc)
12247 {
12248         smb_info_t *si = pinfo->private_data;
12249
12250         DISSECTOR_ASSERT(si);
12251
12252         /* pipe info flag */
12253         CHECK_BYTE_COUNT_SUBR(1);
12254         proto_tree_add_item(tree, hf_smb_pipe_info_flag, tvb, offset, 1, TRUE);
12255         COUNT_BYTES_SUBR(1);
12256
12257         *trunc = FALSE;
12258         return offset;
12259 }
12260
12261 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
12262   TRANS2_QUERY_FILE_INFORMATION*/
12263 static int
12264 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12265     int offset, guint16 *bcp)
12266 {
12267         smb_info_t *si;
12268         gboolean trunc;
12269
12270         if(!*bcp){
12271                 return offset;
12272         }
12273
12274         si = (smb_info_t *)pinfo->private_data;
12275         DISSECTOR_ASSERT(si);
12276
12277         switch(si->info_level){
12278         case 1:         /*Info Standard*/
12279                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
12280                     &trunc);
12281                 break;
12282
12283         case 2:         /*Info Query EA Size*/
12284                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12285                     &trunc);
12286                 break;
12287         case 3:         /*Info Query EAs From List*/
12288         case 4:         /*Info Query All EAs*/
12289                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12290                     &trunc);
12291                 break;
12292         case 6:         /*Info Is Name Valid*/
12293                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
12294                     &trunc);
12295                 break;
12296         case 0x0101:    /*Query File Basic Info*/
12297         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
12298                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
12299                     &trunc);
12300                 break;
12301         case 0x0102:    /*Query File Standard Info*/
12302         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
12303                 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, bcp,
12304                     &trunc);
12305                 break;
12306         case 1006:      /* SMB_FILE_INTERNAL_INFORMATION */
12307                 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, bcp,
12308                     &trunc);
12309                 break;
12310         case 0x0103:    /*Query File EA Info*/
12311         case 1007:      /* SMB_FILE_EA_INFORMATION */
12312                 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, bcp,
12313                     &trunc);
12314                 break;
12315         case 0x0104:    /*Query File Name Info*/
12316         case 1009:      /* SMB_FILE_NAME_INFORMATION */
12317                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
12318                     &trunc);
12319                 break;
12320         case 1014:      /* SMB_FILE_POSITION_INFORMATION */
12321                 offset = dissect_qfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
12322                     &trunc);
12323                 break;
12324         case 1016:      /* SMB_FILE_MODE_INFORMATION */
12325                 offset = dissect_qfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
12326                     &trunc);
12327                 break;
12328         case 1017:      /* SMB_FILE_ALIGNMENT_INFORMATION */
12329                 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, bcp,
12330                     &trunc);
12331                 break;
12332         case 0x0107:    /*Query File All Info*/
12333         case 1018:      /* SMB_FILE_ALL_INFORMATION */
12334                 offset = dissect_qfi_SMB_FILE_ALL_INFO(tvb, pinfo, tree, offset, bcp,
12335                     &trunc);
12336                 break;
12337         case 1019:      /* SMB_FILE_ALLOCATION_INFORMATION */
12338                 offset = dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
12339                     &trunc);
12340                 break;
12341         case 1020:      /* SMB_FILE_ENDOFFILE_INFORMATION */
12342                 offset = dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
12343                     &trunc);
12344                 break;
12345         case 0x0108:    /*Query File Alt File Info*/
12346         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
12347                 offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
12348                     &trunc);
12349                 break;
12350         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
12351                 si->unicode = TRUE;
12352         case 0x0109:    /*Query File Stream Info*/
12353                 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, bcp,
12354                     &trunc, si->unicode);
12355                 break;
12356         case 0x010b:    /*Query File Compression Info*/
12357         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
12358                 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, bcp,
12359                     &trunc);
12360                 break;
12361         case 1034:     /* SMB_FILE_NETWORK_OPEN_INFO */
12362                 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
12363                 break;
12364         case 1035:     /* SMB_FILE_ATTRIBUTE_TAG_INFO */
12365                 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
12366                 break;
12367         case 0x0200:    /* Query File Unix Basic*/
12368                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
12369                                            &trunc);
12370                 break;
12371         case 0x0201:    /* Query File Unix Link*/
12372                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12373                                            &trunc);
12374                 break;
12375         case 0x0202:    /* Query File Unix HardLink*/
12376                 /* XXX add this from the SNIA doc */
12377                 break;
12378         case 0x0204:    /* Query File Unix ACL*/
12379                 offset = dissect_qpi_unix_acl(tvb, pinfo, tree, offset, bcp,
12380                                            &trunc);
12381                 break;
12382         case 0x0205:    /* Query File Unix XATTR*/
12383                 offset = dissect_qpi_unix_xattr(tvb, pinfo, tree, offset, bcp,
12384                                            &trunc);
12385                 break;
12386         case 0x0206:    /* Query File Unix Attr Flags*/
12387                 offset = dissect_qpi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
12388                                            &trunc);
12389                 break;
12390         case 0x0207:    /* Query File Unix Permissions*/
12391                 offset = dissect_qpi_unix_permissions(tvb, pinfo, tree, offset, bcp,
12392                                            &trunc);
12393                 break;
12394         case 0x0208:    /* Query File Unix Lock*/
12395                 offset = dissect_qpi_unix_lock(tvb, pinfo, tree, offset, bcp,
12396                                            &trunc);
12397                 break;
12398         }
12399
12400         return offset;
12401 }
12402
12403 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
12404   TRANS2_SET_FILE_INFORMATION*/
12405 static int
12406 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12407     int offset, guint16 *bcp)
12408 {
12409         smb_info_t *si;
12410         gboolean trunc;
12411
12412         if(!*bcp){
12413                 return offset;
12414         }
12415
12416         si = (smb_info_t *)pinfo->private_data;
12417         DISSECTOR_ASSERT(si);
12418
12419         switch(si->info_level){
12420         case 1:         /*Info Standard*/
12421                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
12422                     &trunc);
12423                 break;
12424         case 2:         /*Info Query EA Size*/
12425                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12426                     &trunc);
12427                 break;
12428         case 4:         /*Info Query All EAs*/
12429                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
12430                     &trunc);
12431                 break;
12432         case 0x0101:    /*Set File Basic Info*/
12433         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
12434                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
12435                     &trunc);
12436                 break;
12437         case 0x0102:    /*Set File Disposition Info*/
12438                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
12439                     &trunc);
12440                 break;
12441         case 0x0103:    /*Set File Allocation Info*/
12442                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
12443                     &trunc);
12444                 break;
12445         case 0x0104:    /*Set End Of File Info*/
12446                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
12447                     &trunc);
12448                 break;
12449         case 0x0200:    /*Set File Unix Basic.  Same as query. */
12450                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
12451                     &trunc);
12452                 break;
12453         case 0x0201:    /*Set File Unix Link.  Same as query. */
12454                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12455                     &trunc);
12456                 break;
12457         case 0x0202:    /*Set File Unix HardLink.  Same as link query. */
12458                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
12459                     &trunc);
12460                 break;
12461         case 0x0204:    /* Set File Unix ACL*/
12462                 offset = dissect_qpi_unix_acl(tvb, pinfo, tree, offset, bcp,
12463                                            &trunc);
12464                 break;
12465         case 0x0205:    /* Set File Unix XATTR*/
12466                 offset = dissect_qpi_unix_xattr(tvb, pinfo, tree, offset, bcp,
12467                                            &trunc);
12468                 break;
12469         case 0x0206:    /* Set File Unix Attr Flags*/
12470                 offset = dissect_qpi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
12471                                            &trunc);
12472                 break;
12473         case 0x0208:    /* Set File Unix Lock*/
12474                 offset = dissect_qpi_unix_lock(tvb, pinfo, tree, offset, bcp,
12475                                            &trunc);
12476                 break;
12477         case 0x0209:    /* Set File Unix Open*/
12478                 offset = dissect_qpi_unix_open(tvb, pinfo, tree, offset, bcp,
12479                                            &trunc);
12480                 break;
12481         case 0x020a:    /* Set File Unix Unlink*/
12482                 offset = dissect_qpi_unix_unlink(tvb, pinfo, tree, offset, bcp,
12483                                            &trunc);
12484                 break;
12485         case 1010:      /* Set File Rename */
12486                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
12487                     &trunc);
12488                 break;
12489         case 1013: /* Set Disposition Information */
12490                 offset = dissect_disposition_info(tvb, pinfo, tree, offset, bcp,
12491                     &trunc);
12492                 break;
12493         case 1023: /* Set Pipe Info */
12494                 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, bcp,
12495                     &trunc);
12496                 break;
12497         case 1014:
12498         case 1016:
12499         case 1019:
12500         case 1020:
12501         case 1025:
12502         case 1029:
12503         case 1032:
12504         case 1039:
12505         case 1040:
12506                 /* XXX: TODO, extra levels discovered by tridge */
12507                 break;
12508         }
12509
12510         return offset;
12511 }
12512
12513
12514 static const true_false_string tfs_quota_flags_deny_disk = {
12515         "DENY DISK SPACE for users exceeding quota limit",
12516         "Do NOT deny disk space for users exceeding quota limit"
12517 };
12518 static const true_false_string tfs_quota_flags_log_limit = {
12519         "LOG EVENT when a user exceeds their QUOTA LIMIT",
12520         "Do NOT log event when a user exceeds their quota limit"
12521 };
12522 static const true_false_string tfs_quota_flags_log_warning = {
12523         "LOG EVENT when a user exceeds their WARNING LEVEL",
12524         "Do NOT log event when a user exceeds their warning level"
12525 };
12526 static const true_false_string tfs_quota_flags_enabled = {
12527         "Quotas are ENABLED of this fs",
12528         "Quotas are NOT enabled on this fs"
12529 };
12530 static void
12531 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12532 {
12533         guint8 mask;
12534         proto_item *item;
12535         proto_tree *tree;
12536
12537         mask = tvb_get_guint8(tvb, offset);
12538
12539         if(parent_tree){
12540                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
12541                         "Quota Flags: 0x%02x %s", mask,
12542                         mask?"Enabled":"Disabled");
12543                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
12544
12545                 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
12546                         tvb, offset, 1, mask);
12547                 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
12548                         tvb, offset, 1, mask);
12549                 proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
12550                         tvb, offset, 1, mask);
12551
12552                 if(mask && (!(mask&0x01))){
12553                         proto_item *hidden_item;
12554                         hidden_item = proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
12555                                 tvb, offset, 1, 0x01);
12556                         PROTO_ITEM_SET_HIDDEN(hidden_item);
12557                 } else {
12558                         proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
12559                                 tvb, offset, 1, mask);
12560                 }
12561         }
12562
12563 }
12564
12565 int
12566 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
12567 {
12568         /* first 24 bytes are unknown */
12569         CHECK_BYTE_COUNT_TRANS_SUBR(24);
12570         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12571                     offset, 24, TRUE);
12572         COUNT_BYTES_TRANS_SUBR(24);
12573
12574         /* number of bytes for quota warning */
12575         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12576         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
12577         COUNT_BYTES_TRANS_SUBR(8);
12578
12579         /* number of bytes for quota limit */
12580         CHECK_BYTE_COUNT_TRANS_SUBR(8);
12581         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
12582         COUNT_BYTES_TRANS_SUBR(8);
12583
12584         /* one byte of quota flags */
12585         CHECK_BYTE_COUNT_TRANS_SUBR(1);
12586         dissect_quota_flags(tvb, tree, offset);
12587         COUNT_BYTES_TRANS_SUBR(1);
12588
12589         /* these 7 bytes are unknown */
12590         CHECK_BYTE_COUNT_TRANS_SUBR(7);
12591         proto_tree_add_item(tree, hf_smb_unknown, tvb,
12592                     offset, 7, TRUE);
12593         COUNT_BYTES_TRANS_SUBR(7);
12594
12595         return offset;
12596 }
12597
12598 static int
12599 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
12600     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
12601 {
12602         proto_item *item = NULL;
12603         proto_tree *tree = NULL;
12604         smb_info_t *si;
12605
12606         si = (smb_info_t *)pinfo->private_data;
12607         DISSECTOR_ASSERT(si);
12608
12609         if(parent_tree){
12610                 tvb_ensure_bytes_exist(tvb, offset, dc);
12611                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12612                                 "%s Data",
12613                                 val_to_str(subcmd, trans2_cmd_vals,
12614                                                 "Unknown (0x%02x)"));
12615                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12616         }
12617
12618         switch(subcmd){
12619         case 0x00:      /*TRANS2_OPEN2*/
12620                 /* XXX dont know how to decode FEAList */
12621                 break;
12622         case 0x01:      /*TRANS2_FIND_FIRST2*/
12623                 /* XXX dont know how to decode FEAList */
12624                 break;
12625         case 0x02:      /*TRANS2_FIND_NEXT2*/
12626                 /* XXX dont know how to decode FEAList */
12627                 break;
12628         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12629                 /* no data field in this request */
12630                 break;
12631         case 0x04:      /* TRANS2_SET_QUOTA */
12632                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
12633                 break;
12634         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12635                 /* no data field in this request */
12636                 /*
12637                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12638                  * Extensions Version 3.0, Document Version 1.11,
12639                  * July 19, 1990" says there may be "Additional
12640                  * FileInfoLevel dependent information" here.
12641                  *
12642                  * Was that just a cut-and-pasteo?
12643                  * TRANS2_SET_PATH_INFORMATION *does* have that information
12644                  * here.
12645                  */
12646                 break;
12647         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12648                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12649                 break;
12650         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12651                 /* no data field in this request */
12652                 /*
12653                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12654                  * Extensions Version 3.0, Document Version 1.11,
12655                  * July 19, 1990" says there may be "Additional
12656                  * FileInfoLevel dependent information" here.
12657                  *
12658                  * Was that just a cut-and-pasteo?
12659                  * TRANS2_SET_FILE_INFORMATION *does* have that information
12660                  * here.
12661                  */
12662                 break;
12663         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12664                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
12665                 break;
12666         case 0x09:      /*TRANS2_FSCTL*/
12667                 /*XXX dont know how to decode this yet */
12668
12669                 /*
12670                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12671                  * Extensions Version 3.0, Document Version 1.11,
12672                  * July 19, 1990" says this this contains a
12673                  * "File system specific data block".  (That means we
12674                  * may not be able to dissect it in any case.)
12675                  */
12676                 break;
12677         case 0x0a:      /*TRANS2_IOCTL2*/
12678                 /*XXX dont know how to decode this yet */
12679
12680                 /*
12681                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12682                  * Extensions Version 3.0, Document Version 1.11,
12683                  * July 19, 1990" says this this contains a
12684                  * "Device/function specific data block".  (That
12685                  * means we may not be able to dissect it in any case.)
12686                  */
12687                 break;
12688         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12689                 /*XXX dont know how to decode this yet */
12690
12691                 /*
12692                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12693                  * Extensions Version 3.0, Document Version 1.11,
12694                  * July 19, 1990" says this this contains "additional
12695                  * level dependent match data".
12696                  */
12697                 break;
12698         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12699                 /*XXX dont know how to decode this yet */
12700
12701                 /*
12702                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12703                  * Extensions Version 3.0, Document Version 1.11,
12704                  * July 19, 1990" says this this contains "additional
12705                  * level dependent monitor information".
12706                  */
12707                 break;
12708         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12709                 /* XXX optional FEAList, unknown what FEAList looks like*/
12710                 break;
12711         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12712                 /*XXX dont know how to decode this yet */
12713                 break;
12714         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12715                 /* no data field in this request */
12716                 break;
12717         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12718                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
12719                 break;
12720         }
12721
12722         /* ooops there were data we didnt know how to process */
12723         if(dc != 0){
12724                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12725                 offset += dc;
12726         }
12727
12728         return offset;
12729 }
12730
12731
12732 static void
12733 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
12734     proto_tree *tree)
12735 {
12736         int i;
12737         int offset;
12738         guint length;
12739
12740         /*
12741          * Show the setup words.
12742          */
12743         if (s_tvb != NULL) {
12744                 length = tvb_reported_length(s_tvb);
12745                 for (i = 0, offset = 0; length >= 2;
12746                     i++, offset += 2, length -= 2) {
12747                         /*
12748                          * XXX - add a setup word filterable field?
12749                          */
12750                         proto_tree_add_text(tree, s_tvb, offset, 2,
12751                             "Setup Word %d: 0x%04x", i,
12752                             tvb_get_letohs(s_tvb, offset));
12753                 }
12754         }
12755
12756         /*
12757          * Show the parameters, if any.
12758          */
12759         if (p_tvb != NULL) {
12760                 length = tvb_reported_length(p_tvb);
12761                 if (length != 0) {
12762                         proto_tree_add_text(tree, p_tvb, 0, length,
12763                             "Parameters: %s",
12764                             tvb_bytes_to_str(p_tvb, 0, length));
12765                 }
12766         }
12767
12768         /*
12769          * Show the data, if any.
12770          */
12771         if (d_tvb != NULL) {
12772                 length = tvb_reported_length(d_tvb);
12773                 if (length != 0) {
12774                         proto_tree_add_text(tree, d_tvb, 0, length,
12775                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
12776                 }
12777         }
12778 }
12779
12780 /* This routine handles the following 4 calls
12781    Transaction  0x25
12782    Transaction Secondary 0x26
12783    Transaction2 0x32
12784    Transaction2 Secondary 0x33
12785 */
12786 static int
12787 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
12788 {
12789         guint8 wc, sc=0;
12790         int so=offset;
12791         int sl=0;
12792         int spo=offset;
12793         int spc=0;
12794         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
12795         int subcmd = -1;
12796         guint32 to;
12797         int an_len;
12798         const char *an = NULL;
12799         smb_info_t *si;
12800         smb_transact2_info_t *t2i;
12801         smb_transact_info_t *tri;
12802         guint16 bc;
12803         int padcnt;
12804         gboolean dissected_trans;
12805
12806         si = (smb_info_t *)pinfo->private_data;
12807         DISSECTOR_ASSERT(si);
12808
12809         WORD_COUNT;
12810
12811         if(wc==8){
12812                 /*secondary client request*/
12813
12814                 /* total param count, only a 16bit integer here*/
12815                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12816                 offset += 2;
12817
12818                 /* total data count , only 16bit integer here*/
12819                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12820                 offset += 2;
12821
12822                 /* param count */
12823                 pc = tvb_get_letohs(tvb, offset);
12824                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12825                 offset += 2;
12826
12827                 /* param offset */
12828                 po = tvb_get_letohs(tvb, offset);
12829                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12830                 offset += 2;
12831
12832                 /* param disp */
12833                 pd = tvb_get_letohs(tvb, offset);
12834                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12835                 offset += 2;
12836
12837                 /* data count */
12838                 dc = tvb_get_letohs(tvb, offset);
12839                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12840                 offset += 2;
12841
12842                 /* data offset */
12843                 od = tvb_get_letohs(tvb, offset);
12844                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12845                 offset += 2;
12846
12847                 /* data disp */
12848                 dd = tvb_get_letohs(tvb, offset);
12849                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12850                 offset += 2;
12851
12852                 if(si->cmd==SMB_COM_TRANSACTION2){
12853                         guint16 fid;
12854
12855                         /* fid */
12856                         fid = tvb_get_letohs(tvb, offset);
12857                         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
12858
12859                         offset += 2;
12860                 }
12861
12862                 /* There are no setup words. */
12863                 so = offset;
12864                 sc = 0;
12865                 sl = 0;
12866         } else {
12867                 /* it is not a secondary request */
12868
12869                 /* total param count , only a 16 bit integer here*/
12870                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12871                 offset += 2;
12872
12873                 /* total data count , only 16bit integer here*/
12874                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12875                 offset += 2;
12876
12877                 /* max param count , only 16bit integer here*/
12878                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12879                 offset += 2;
12880
12881                 /* max data count, only 16bit integer here*/
12882                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12883                 offset += 2;
12884
12885                 /* max setup count, only 16bit integer here*/
12886                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12887                 offset += 1;
12888
12889                 /* reserved byte */
12890                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12891                 offset += 1;
12892
12893                 /* transaction flags */
12894                 tf = dissect_transaction_flags(tvb, tree, offset);
12895                 offset += 2;
12896
12897                 /* timeout */
12898                 to = tvb_get_letohl(tvb, offset);
12899                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", smbext20_timeout_msecs_to_str(to));
12900                 offset += 4;
12901
12902                 /* 2 reserved bytes */
12903                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12904                 offset += 2;
12905
12906                 /* param count */
12907                 pc = tvb_get_letohs(tvb, offset);
12908                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12909                 offset += 2;
12910
12911                 /* param offset */
12912                 po = tvb_get_letohs(tvb, offset);
12913                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12914                 offset += 2;
12915
12916                 /* param displacement is zero here */
12917                 pd = 0;
12918
12919                 /* data count */
12920                 dc = tvb_get_letohs(tvb, offset);
12921                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12922                 offset += 2;
12923
12924                 /* data offset */
12925                 od = tvb_get_letohs(tvb, offset);
12926                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12927                 offset += 2;
12928
12929                 /* data displacement is zero here */
12930                 dd = 0;
12931
12932                 /* setup count */
12933                 sc = tvb_get_guint8(tvb, offset);
12934                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12935                 offset += 1;
12936
12937                 /* reserved byte */
12938                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12939                 offset += 1;
12940
12941                 /* this is where the setup bytes, if any start */
12942                 so = offset;
12943                 sl = sc*2;
12944
12945                 /* if there were any setup bytes, decode them */
12946                 if(sc){
12947                         switch(si->cmd){
12948
12949                         case SMB_COM_TRANSACTION2:
12950                                 /* TRANSACTION2 only has one setup word and
12951                                    that is the subcommand code.
12952
12953                                    XXX - except for TRANS2_FSCTL
12954                                    and TRANS2_IOCTL. */
12955                                 subcmd = tvb_get_letohs(tvb, offset);
12956                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12957                                     tvb, offset, 2, subcmd);
12958                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12959                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12960                                             val_to_str(subcmd, trans2_cmd_vals,
12961                                                 "Unknown (0x%02x)"));
12962                                 }
12963                                 if (!si->unidir) {
12964                                         if(!pinfo->fd->flags.visited && si->sip){
12965                                                 /*
12966                                                  * Allocate a new
12967                                                  * smb_transact2_info_t
12968                                                  * structure.
12969                                                  */
12970                                                 t2i = se_alloc(sizeof(smb_transact2_info_t));
12971                                                 t2i->subcmd = subcmd;
12972                                                 t2i->info_level = -1;
12973                                                 t2i->resume_keys = FALSE;
12974                                                 t2i->name = NULL;
12975                                                 si->sip->extra_info = t2i;
12976                                                 si->sip->extra_info_type = SMB_EI_T2I;
12977                                         }
12978                                 }
12979
12980                                 /*
12981                                  * XXX - process TRANS2_FSCTL and
12982                                  * TRANS2_IOCTL setup words here.
12983                                  */
12984                                 break;
12985
12986                         case SMB_COM_TRANSACTION:
12987                                 /* TRANSACTION setup words processed below */
12988                                 break;
12989                         }
12990
12991                         offset += sl;
12992                 }
12993         }
12994
12995         BYTE_COUNT;
12996
12997         if(wc!=8){
12998                 /* primary request */
12999                 /* name is NULL if transaction2 */
13000                 if(si->cmd == SMB_COM_TRANSACTION){
13001                         /* Transaction Name */
13002                         an = get_unicode_or_ascii_string(tvb, &offset,
13003                                 si->unicode, &an_len, FALSE, FALSE, &bc);
13004                         if (an == NULL)
13005                                 goto endofcommand;
13006                         tvb_ensure_bytes_exist(tvb, offset, an_len);
13007                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
13008                                 offset, an_len, an);
13009                         COUNT_BYTES(an_len);
13010                 }
13011         }
13012
13013         /*
13014          * The pipe or mailslot arguments for Transaction start with
13015          * the first setup word (or where the first setup word would
13016          * be if there were any setup words), and run to the current
13017          * offset (which could mean that there aren't any).
13018          */
13019         spo = so;
13020         spc = offset - spo;
13021
13022         /* parameters */
13023         if(po>offset){
13024                 /* We have some initial padding bytes.
13025                 */
13026                 padcnt = po-offset;
13027                 if (padcnt > bc)
13028                         padcnt = bc;
13029                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
13030                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13031                 COUNT_BYTES(padcnt);
13032         }
13033         if(pc){
13034                 CHECK_BYTE_COUNT(pc);
13035                 switch(si->cmd) {
13036
13037                 case SMB_COM_TRANSACTION2:
13038                         /* TRANSACTION2 parameters*/
13039                         offset = dissect_transaction2_request_parameters(tvb,
13040                             pinfo, tree, offset, subcmd, pc);
13041                         bc -= pc;
13042                         break;
13043
13044                 case SMB_COM_TRANSACTION:
13045                         /* TRANSACTION parameters processed below */
13046                         COUNT_BYTES(pc);
13047                         break;
13048                 }
13049         }
13050
13051         /* data */
13052         if(od>offset){
13053                 /* We have some initial padding bytes.
13054                 */
13055                 padcnt = od-offset;
13056                 if (padcnt > bc)
13057                         padcnt = bc;
13058                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
13059                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13060                 COUNT_BYTES(padcnt);
13061         }
13062         if(dc){
13063                 CHECK_BYTE_COUNT(dc);
13064                 switch(si->cmd){
13065
13066                 case SMB_COM_TRANSACTION2:
13067                         /* TRANSACTION2 data*/
13068                         offset = dissect_transaction2_request_data(tvb, pinfo,
13069                             tree, offset, subcmd, dc);
13070                         bc -= dc;
13071                         break;
13072
13073                 case SMB_COM_TRANSACTION:
13074                         /* TRANSACTION data processed below */
13075                         COUNT_BYTES(dc);
13076                         break;
13077                 }
13078         }
13079
13080         /*TRANSACTION request parameters */
13081         if(si->cmd==SMB_COM_TRANSACTION){
13082                 /*XXX replace this block with a function and use that one
13083                      for both requests/responses*/
13084                 if(dd==0){
13085                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
13086                         tvbuff_t *sp_tvb, *pd_tvb;
13087
13088                         if(pc>0){
13089                                 if(pc>tvb_length_remaining(tvb, po)){
13090                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
13091                                 } else {
13092                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
13093                                 }
13094                         } else {
13095                                 p_tvb = NULL;
13096                         }
13097                         if(dc>0){
13098                                 if(dc>tvb_length_remaining(tvb, od)){
13099                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
13100                                 } else {
13101                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
13102                                 }
13103                         } else {
13104                                 d_tvb = NULL;
13105                         }
13106                         if(sl){
13107                                 if(sl>tvb_length_remaining(tvb, so)){
13108                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
13109                                 } else {
13110                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
13111                                 }
13112                         } else {
13113                                 s_tvb = NULL;
13114                         }
13115
13116                         if (!si->unidir) {
13117                                 if(!pinfo->fd->flags.visited && si->sip){
13118                                         /*
13119                                          * Allocate a new smb_transact_info_t
13120                                          * structure.
13121                                          */
13122                                         tri = se_alloc(sizeof(smb_transact_info_t));
13123                                         tri->subcmd = -1;
13124                                         tri->trans_subcmd = -1;
13125                                         tri->function = -1;
13126                                         tri->fid = -1;
13127                                         tri->lanman_cmd = 0;
13128                                         tri->param_descrip = NULL;
13129                                         tri->data_descrip = NULL;
13130                                         tri->aux_data_descrip = NULL;
13131                                         tri->info_level = -1;
13132                                         si->sip->extra_info = tri;
13133                                         si->sip->extra_info_type = SMB_EI_TRI;
13134                                 } else {
13135                                         /*
13136                                          * We already filled the structure
13137                                          * in; don't bother doing so again.
13138                                          */
13139                                         tri = NULL;
13140                                 }
13141                         } else {
13142                                 /*
13143                                  * This is a unidirectional message, for
13144                                  * which there will be no reply; don't
13145                                  * bother allocating an "smb_transact_info_t"
13146                                  * structure for it.
13147                                  */
13148                                 tri = NULL;
13149                         }
13150                         dissected_trans = FALSE;
13151                         if (an == NULL)
13152                                 goto endofcommand;
13153                         if(strncmp("\\PIPE\\", an, 6) == 0){
13154                                 if (tri != NULL)
13155                                         tri->subcmd=TRANSACTION_PIPE;
13156
13157                                 /*
13158                                  * A tvbuff containing the setup words and
13159                                  * the pipe path.
13160                                  */
13161                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
13162
13163                                 /*
13164                                  * A tvbuff containing the parameters and the
13165                                  * data.
13166                                  */
13167                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
13168
13169                                 dissected_trans = dissect_pipe_smb(sp_tvb,
13170                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
13171                                     top_tree);
13172
13173                                 /* In case we did not see the TreeConnect call,
13174                                    store this TID here as well as a IPC TID
13175                                    so we know that future Read/Writes to this
13176                                    TID is (probably) DCERPC.
13177                                 */
13178                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
13179                                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
13180                                 }
13181                                 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
13182                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
13183                                 if (tri != NULL)
13184                                         tri->subcmd=TRANSACTION_MAILSLOT;
13185
13186                                 /*
13187                                  * A tvbuff containing the setup words and
13188                                  * the mailslot path.
13189                                  */
13190                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
13191                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
13192                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
13193                         }
13194                         if (!dissected_trans)
13195                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
13196                 } else {
13197                         if(check_col(pinfo->cinfo, COL_INFO)){
13198                                 col_append_str(pinfo->cinfo, COL_INFO,
13199                                         "[transact continuation]");
13200                         }
13201                 }
13202         }
13203
13204         END_OF_SMB
13205
13206         return offset;
13207 }
13208
13209
13210
13211 static int
13212 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13213     int offset, guint16 *bcp, gboolean *trunc)
13214 {
13215         int fn_len;
13216         const char *fn;
13217         int old_offset = offset;
13218         proto_item *item = NULL;
13219         proto_tree *tree = NULL;
13220         smb_info_t *si;
13221         smb_transact2_info_t *t2i;
13222         gboolean resume_keys = FALSE;
13223
13224         si = (smb_info_t *)pinfo->private_data;
13225         DISSECTOR_ASSERT(si);
13226
13227         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
13228                 t2i = si->sip->extra_info;
13229                 if (t2i != NULL)
13230                         resume_keys = t2i->resume_keys;
13231         }
13232
13233         if(parent_tree){
13234                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13235                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13236                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13237                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13238         }
13239
13240         if (resume_keys) {
13241                 /* resume key */
13242                 CHECK_BYTE_COUNT_SUBR(4);
13243                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
13244                 COUNT_BYTES_SUBR(4);
13245         }
13246
13247         /* create time */
13248         CHECK_BYTE_COUNT_SUBR(4);
13249         offset = dissect_smb_datetime(tvb, tree, offset,
13250                 hf_smb_create_time,
13251                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
13252         *bcp -= 4;
13253
13254         /* access time */
13255         CHECK_BYTE_COUNT_SUBR(4);
13256         offset = dissect_smb_datetime(tvb, tree, offset,
13257                 hf_smb_access_time,
13258                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
13259         *bcp -= 4;
13260
13261         /* last write time */
13262         CHECK_BYTE_COUNT_SUBR(4);
13263         offset = dissect_smb_datetime(tvb, tree, offset,
13264                 hf_smb_last_write_time,
13265                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
13266         *bcp -= 4;
13267
13268         /* data size */
13269         CHECK_BYTE_COUNT_SUBR(4);
13270         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13271         COUNT_BYTES_SUBR(4);
13272
13273         /* allocation size */
13274         CHECK_BYTE_COUNT_SUBR(4);
13275         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
13276         COUNT_BYTES_SUBR(4);
13277
13278         /* File Attributes */
13279         CHECK_BYTE_COUNT_SUBR(2);
13280         offset = dissect_file_attributes(tvb, tree, offset, 2);
13281         *bcp -= 2;
13282
13283         /* file name len */
13284         CHECK_BYTE_COUNT_SUBR(1);
13285         fn_len = tvb_get_guint8(tvb, offset);
13286         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
13287         COUNT_BYTES_SUBR(1);
13288         if (si->unicode)
13289                 fn_len += 2;    /* include terminating '\0' */
13290         else
13291                 fn_len++;       /* include terminating '\0' */
13292
13293         /* file name */
13294         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13295         CHECK_STRING_SUBR(fn);
13296         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13297                 fn);
13298         COUNT_BYTES_SUBR(fn_len);
13299
13300         if (check_col(pinfo->cinfo, COL_INFO)) {
13301                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13302                     format_text(fn, strlen(fn)));
13303         }
13304
13305         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13306         proto_item_set_len(item, offset-old_offset);
13307
13308         *trunc = FALSE;
13309         return offset;
13310 }
13311
13312 static int
13313 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13314     int offset, guint16 *bcp, gboolean *trunc)
13315 {
13316         int fn_len;
13317         const char *fn;
13318         int old_offset = offset;
13319         proto_item *item = NULL;
13320         proto_tree *tree = NULL;
13321         smb_info_t *si;
13322         smb_transact2_info_t *t2i;
13323         gboolean resume_keys = FALSE;
13324
13325         si = (smb_info_t *)pinfo->private_data;
13326         DISSECTOR_ASSERT(si);
13327
13328         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
13329                 t2i = si->sip->extra_info;
13330                 if (t2i != NULL)
13331                         resume_keys = t2i->resume_keys;
13332         }
13333
13334         if(parent_tree){
13335                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13336                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13337                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13338                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13339         }
13340
13341         if (resume_keys) {
13342                 /* resume key */
13343                 CHECK_BYTE_COUNT_SUBR(4);
13344                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
13345                 COUNT_BYTES_SUBR(4);
13346         }
13347
13348         /* create time */
13349         CHECK_BYTE_COUNT_SUBR(4);
13350         offset = dissect_smb_datetime(tvb, tree, offset,
13351                 hf_smb_create_time,
13352                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
13353         *bcp -= 4;
13354
13355         /* access time */
13356         CHECK_BYTE_COUNT_SUBR(4);
13357         offset = dissect_smb_datetime(tvb, tree, offset,
13358                 hf_smb_access_time,
13359                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
13360         *bcp -= 4;
13361
13362         /* last write time */
13363         CHECK_BYTE_COUNT_SUBR(4);
13364         offset = dissect_smb_datetime(tvb, tree, offset,
13365                 hf_smb_last_write_time,
13366                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
13367         *bcp -= 4;
13368
13369         /* data size */
13370         CHECK_BYTE_COUNT_SUBR(4);
13371         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13372         COUNT_BYTES_SUBR(4);
13373
13374         /* allocation size */
13375         CHECK_BYTE_COUNT_SUBR(4);
13376         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
13377         COUNT_BYTES_SUBR(4);
13378
13379         /* File Attributes */
13380         CHECK_BYTE_COUNT_SUBR(2);
13381         offset = dissect_file_attributes(tvb, tree, offset, 2);
13382         *bcp -= 2;
13383
13384         /* ea length */
13385         CHECK_BYTE_COUNT_SUBR(4);
13386         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13387         COUNT_BYTES_SUBR(4);
13388
13389         /* file name len */
13390         CHECK_BYTE_COUNT_SUBR(1);
13391         fn_len = tvb_get_guint8(tvb, offset);
13392         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
13393         COUNT_BYTES_SUBR(1);
13394         if (si->unicode)
13395                 fn_len += 2;    /* include terminating '\0' */
13396         else
13397                 fn_len++;       /* include terminating '\0' */
13398
13399         /* file name */
13400         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13401         CHECK_STRING_SUBR(fn);
13402         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13403                 fn);
13404         COUNT_BYTES_SUBR(fn_len);
13405
13406         if (check_col(pinfo->cinfo, COL_INFO)) {
13407                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13408                     format_text(fn, strlen(fn)));
13409         }
13410
13411         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13412         proto_item_set_len(item, offset-old_offset);
13413
13414         *trunc = FALSE;
13415         return offset;
13416 }
13417
13418 static int
13419 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13420     int offset, guint16 *bcp, gboolean *trunc)
13421 {
13422         int fn_len;
13423         const char *fn;
13424         int old_offset = offset;
13425         proto_item *item = NULL;
13426         proto_tree *tree = NULL;
13427         smb_info_t *si;
13428         guint32 neo;
13429         int padcnt;
13430
13431         si = (smb_info_t *)pinfo->private_data;
13432         DISSECTOR_ASSERT(si);
13433
13434         if(parent_tree){
13435                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13436                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13437                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13438                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13439         }
13440
13441         /*
13442          * We assume that the presence of a next entry offset implies the
13443          * absence of a resume key, as appears to be the case for 4.3.4.6.
13444          */
13445
13446         /* next entry offset */
13447         CHECK_BYTE_COUNT_SUBR(4);
13448         neo = tvb_get_letohl(tvb, offset);
13449         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13450         COUNT_BYTES_SUBR(4);
13451
13452         /* file index */
13453         CHECK_BYTE_COUNT_SUBR(4);
13454         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13455         COUNT_BYTES_SUBR(4);
13456
13457         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13458         if (*trunc) {
13459           return offset;
13460         }
13461
13462         /* end of file */
13463         CHECK_BYTE_COUNT_SUBR(8);
13464         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13465         COUNT_BYTES_SUBR(8);
13466
13467         /* allocation size */
13468         CHECK_BYTE_COUNT_SUBR(8);
13469         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13470         COUNT_BYTES_SUBR(8);
13471
13472         /* Extended File Attributes */
13473         CHECK_BYTE_COUNT_SUBR(4);
13474         offset = dissect_file_ext_attr(tvb, tree, offset);
13475         *bcp -= 4;
13476
13477         /* file name len */
13478         CHECK_BYTE_COUNT_SUBR(4);
13479         fn_len = tvb_get_letohl(tvb, offset);
13480         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13481         COUNT_BYTES_SUBR(4);
13482
13483         /* file name */
13484         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13485         CHECK_STRING_SUBR(fn);
13486         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13487                 fn);
13488         COUNT_BYTES_SUBR(fn_len);
13489
13490         if (check_col(pinfo->cinfo, COL_INFO)) {
13491                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13492                     format_text(fn, strlen(fn)));
13493         }
13494
13495         /* skip to next structure */
13496         if(neo){
13497                 padcnt = (old_offset + neo) - offset;
13498                 if (padcnt < 0) {
13499                         /*
13500                          * XXX - this is bogus; flag it?
13501                          */
13502                         padcnt = 0;
13503                 }
13504                 if (padcnt != 0) {
13505                         CHECK_BYTE_COUNT_SUBR(padcnt);
13506                         COUNT_BYTES_SUBR(padcnt);
13507                 }
13508         }
13509
13510         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13511         proto_item_set_len(item, offset-old_offset);
13512
13513         *trunc = FALSE;
13514         return offset;
13515 }
13516
13517 static int
13518 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13519     int offset, guint16 *bcp, gboolean *trunc)
13520 {
13521         int fn_len;
13522         const char *fn;
13523         int old_offset = offset;
13524         proto_item *item = NULL;
13525         proto_tree *tree = NULL;
13526         smb_info_t *si;
13527         guint32 neo;
13528         int padcnt;
13529
13530         si = (smb_info_t *)pinfo->private_data;
13531         DISSECTOR_ASSERT(si);
13532
13533         if(parent_tree){
13534                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13535                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13536                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13537                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13538         }
13539
13540         /*
13541          * We assume that the presence of a next entry offset implies the
13542          * absence of a resume key, as appears to be the case for 4.3.4.6.
13543          */
13544
13545         /* next entry offset */
13546         CHECK_BYTE_COUNT_SUBR(4);
13547         neo = tvb_get_letohl(tvb, offset);
13548         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13549         COUNT_BYTES_SUBR(4);
13550
13551         /* file index */
13552         CHECK_BYTE_COUNT_SUBR(4);
13553         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13554         COUNT_BYTES_SUBR(4);
13555
13556         /* standard 8-byte timestamps */
13557         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13558         if (*trunc) {
13559           return offset;
13560         }
13561
13562         /* end of file */
13563         CHECK_BYTE_COUNT_SUBR(8);
13564         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13565         COUNT_BYTES_SUBR(8);
13566
13567         /* allocation size */
13568         CHECK_BYTE_COUNT_SUBR(8);
13569         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13570         COUNT_BYTES_SUBR(8);
13571
13572         /* Extended File Attributes */
13573         CHECK_BYTE_COUNT_SUBR(4);
13574         offset = dissect_file_ext_attr(tvb, tree, offset);
13575         *bcp -= 4;
13576
13577         /* file name len */
13578         CHECK_BYTE_COUNT_SUBR(4);
13579         fn_len = tvb_get_letohl(tvb, offset);
13580         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13581         COUNT_BYTES_SUBR(4);
13582
13583         /* ea length */
13584         CHECK_BYTE_COUNT_SUBR(4);
13585         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13586         COUNT_BYTES_SUBR(4);
13587
13588         /* file name */
13589         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13590         CHECK_STRING_SUBR(fn);
13591         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13592                 fn);
13593         COUNT_BYTES_SUBR(fn_len);
13594
13595         if (check_col(pinfo->cinfo, COL_INFO)) {
13596                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13597                     format_text(fn, strlen(fn)));
13598         }
13599
13600         /* skip to next structure */
13601         if(neo){
13602                 padcnt = (old_offset + neo) - offset;
13603                 if (padcnt < 0) {
13604                         /*
13605                          * XXX - this is bogus; flag it?
13606                          */
13607                         padcnt = 0;
13608                 }
13609                 if (padcnt != 0) {
13610                         CHECK_BYTE_COUNT_SUBR(padcnt);
13611                         COUNT_BYTES_SUBR(padcnt);
13612                 }
13613         }
13614
13615         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13616         proto_item_set_len(item, offset-old_offset);
13617
13618         *trunc = FALSE;
13619         return offset;
13620 }
13621
13622 static int
13623 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13624     int offset, guint16 *bcp, gboolean *trunc)
13625 {
13626         int fn_len, sfn_len;
13627         const char *fn, *sfn;
13628         int old_offset = offset;
13629         proto_item *item = NULL;
13630         proto_tree *tree = NULL;
13631         smb_info_t *si;
13632         guint32 neo;
13633         int padcnt;
13634
13635         si = (smb_info_t *)pinfo->private_data;
13636         DISSECTOR_ASSERT(si);
13637
13638         if(parent_tree){
13639                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13640                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13641                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13642                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13643         }
13644
13645         /*
13646          * XXX - I have not seen any of these that contain a resume
13647          * key, even though some of the requests had the "return resume
13648          * key" flag set.
13649          */
13650
13651         /* next entry offset */
13652         CHECK_BYTE_COUNT_SUBR(4);
13653         neo = tvb_get_letohl(tvb, offset);
13654         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13655         COUNT_BYTES_SUBR(4);
13656
13657         /* file index */
13658         CHECK_BYTE_COUNT_SUBR(4);
13659         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13660         COUNT_BYTES_SUBR(4);
13661
13662         /* dissect standard 8-byte timestamps */
13663         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13664         if (*trunc) {
13665           return offset;
13666         }
13667
13668         /* end of file */
13669         CHECK_BYTE_COUNT_SUBR(8);
13670         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
13671         COUNT_BYTES_SUBR(8);
13672
13673         /* allocation size */
13674         CHECK_BYTE_COUNT_SUBR(8);
13675         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13676         COUNT_BYTES_SUBR(8);
13677
13678         /* Extended File Attributes */
13679         CHECK_BYTE_COUNT_SUBR(4);
13680         offset = dissect_file_ext_attr(tvb, tree, offset);
13681         *bcp -= 4;
13682
13683         /* file name len */
13684         CHECK_BYTE_COUNT_SUBR(4);
13685         fn_len = tvb_get_letohl(tvb, offset);
13686         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13687         COUNT_BYTES_SUBR(4);
13688
13689         /*
13690          * EA length.
13691          *
13692          * XXX - in one captures, this has the topmost bit set, and the
13693          * rest of the bits have the value 7.  Is the topmost bit being
13694          * set some indication that the value *isn't* the length of
13695          * the EAs?
13696          */
13697         CHECK_BYTE_COUNT_SUBR(4);
13698         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13699         COUNT_BYTES_SUBR(4);
13700
13701         /* short file name len */
13702         CHECK_BYTE_COUNT_SUBR(1);
13703         sfn_len = tvb_get_guint8(tvb, offset);
13704         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
13705         COUNT_BYTES_SUBR(1);
13706
13707         /* reserved byte */
13708         CHECK_BYTE_COUNT_SUBR(1);
13709         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13710         COUNT_BYTES_SUBR(1);
13711
13712         /* short file name - it's not always in Unicode */
13713         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
13714         CHECK_STRING_SUBR(sfn);
13715         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
13716                 sfn);
13717         COUNT_BYTES_SUBR(24);
13718
13719         /* file name */
13720         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13721         CHECK_STRING_SUBR(fn);
13722         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13723                 fn);
13724         COUNT_BYTES_SUBR(fn_len);
13725
13726         if (check_col(pinfo->cinfo, COL_INFO)) {
13727                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13728                     format_text(fn, strlen(fn)));
13729         }
13730
13731         /* skip to next structure */
13732         if(neo){
13733                 padcnt = (old_offset + neo) - offset;
13734                 if (padcnt < 0) {
13735                         /*
13736                          * XXX - this is bogus; flag it?
13737                          */
13738                         padcnt = 0;
13739                 }
13740                 if (padcnt != 0) {
13741                         CHECK_BYTE_COUNT_SUBR(padcnt);
13742                         COUNT_BYTES_SUBR(padcnt);
13743                 }
13744         }
13745
13746         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13747         proto_item_set_len(item, offset-old_offset);
13748
13749         *trunc = FALSE;
13750         return offset;
13751 }
13752
13753 static int
13754 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
13755     int offset, guint16 *bcp, gboolean *trunc)
13756 {
13757         int fn_len;
13758         const char *fn;
13759         int old_offset = offset;
13760         proto_item *item = NULL;
13761         proto_tree *tree = NULL;
13762         smb_info_t *si;
13763         guint32 neo;
13764         int padcnt;
13765
13766         si = (smb_info_t *)pinfo->private_data;
13767         DISSECTOR_ASSERT(si);
13768
13769         if(parent_tree){
13770                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
13771                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
13772                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
13773                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13774         }
13775
13776         /*
13777          * We assume that the presence of a next entry offset implies the
13778          * absence of a resume key, as appears to be the case for 4.3.4.6.
13779          */
13780
13781         /* next entry offset */
13782         CHECK_BYTE_COUNT_SUBR(4);
13783         neo = tvb_get_letohl(tvb, offset);
13784         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13785         COUNT_BYTES_SUBR(4);
13786
13787         /* file index */
13788         CHECK_BYTE_COUNT_SUBR(4);
13789         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13790         COUNT_BYTES_SUBR(4);
13791
13792         /* file name len */
13793         CHECK_BYTE_COUNT_SUBR(4);
13794         fn_len = tvb_get_letohl(tvb, offset);
13795         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13796         COUNT_BYTES_SUBR(4);
13797
13798         /* file name */
13799         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13800         CHECK_STRING_SUBR(fn);
13801         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13802                 fn);
13803         COUNT_BYTES_SUBR(fn_len);
13804
13805         if (check_col(pinfo->cinfo, COL_INFO)) {
13806                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13807                     format_text(fn, strlen(fn)));
13808         }
13809
13810         /* skip to next structure */
13811         if(neo){
13812                 padcnt = (old_offset + neo) - offset;
13813                 if (padcnt < 0) {
13814                         /*
13815                          * XXX - this is bogus; flag it?
13816                          */
13817                         padcnt = 0;
13818                 }
13819                 if (padcnt != 0) {
13820                         CHECK_BYTE_COUNT_SUBR(padcnt);
13821                         COUNT_BYTES_SUBR(padcnt);
13822                 }
13823         }
13824
13825         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
13826         proto_item_set_len(item, offset-old_offset);
13827
13828         *trunc = FALSE;
13829         return offset;
13830 }
13831
13832 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
13833
13834 static int
13835 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
13836                 proto_tree *tree, int offset, guint16 *bcp,
13837                 gboolean *trunc)
13838 {
13839         smb_info_t *si = pinfo->private_data;
13840         const char *fn;
13841         int fn_len;
13842
13843         DISSECTOR_ASSERT(si);
13844
13845         /* NextEntryOffset */
13846         CHECK_BYTE_COUNT_SUBR(4);
13847         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
13848         COUNT_BYTES_SUBR(4);
13849
13850         /* ResumeKey */
13851         CHECK_BYTE_COUNT_SUBR(4);
13852         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
13853         COUNT_BYTES_SUBR(4);
13854
13855         /* End of file (file size) */
13856         CHECK_BYTE_COUNT_SUBR(8);
13857         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
13858         COUNT_BYTES_SUBR(8);
13859
13860         /* Number of bytes */
13861         CHECK_BYTE_COUNT_SUBR(8);
13862         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
13863         COUNT_BYTES_SUBR(8);
13864
13865         /* Last status change */
13866         CHECK_BYTE_COUNT_SUBR(8);
13867         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
13868         *bcp -= 8;
13869
13870         /* Last access time */
13871         CHECK_BYTE_COUNT_SUBR(8);
13872         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
13873         *bcp -= 8;
13874
13875         /* Last modification time */
13876         CHECK_BYTE_COUNT_SUBR(8);
13877         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
13878         *bcp -= 8;
13879
13880         /* File owner uid */
13881         CHECK_BYTE_COUNT_SUBR(8);
13882         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
13883         COUNT_BYTES_SUBR(8);
13884
13885         /* File group gid */
13886         CHECK_BYTE_COUNT_SUBR(8);
13887         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
13888         COUNT_BYTES_SUBR(8);
13889
13890         /* File type */
13891         CHECK_BYTE_COUNT_SUBR(4);
13892         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
13893         COUNT_BYTES_SUBR(4);
13894
13895         /* Major device number */
13896         CHECK_BYTE_COUNT_SUBR(8);
13897         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
13898         COUNT_BYTES_SUBR(8);
13899
13900         /* Minor device number */
13901         CHECK_BYTE_COUNT_SUBR(8);
13902         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
13903         COUNT_BYTES_SUBR(8);
13904
13905         /* Unique id */
13906         CHECK_BYTE_COUNT_SUBR(8);
13907         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
13908         COUNT_BYTES_SUBR(8);
13909
13910         /* Permissions */
13911         CHECK_BYTE_COUNT_SUBR(8);
13912         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
13913         COUNT_BYTES_SUBR(8);
13914
13915         /* Nlinks */
13916         CHECK_BYTE_COUNT_SUBR(8);
13917         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
13918         COUNT_BYTES_SUBR(8);
13919
13920         /* Name */
13921
13922         fn = get_unicode_or_ascii_string(
13923                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13924
13925         CHECK_STRING_SUBR(fn);
13926         proto_tree_add_string(
13927                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13928         COUNT_BYTES_SUBR(fn_len);
13929
13930         /* Pad to 4 bytes */
13931
13932         if (offset % 4)
13933                 offset += 4 - (offset % 4);
13934
13935         *trunc = FALSE;
13936         return offset;
13937 }
13938
13939 /*dissect the data block for TRANS2_FIND_FIRST2*/
13940 static int
13941 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13942     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13943 {
13944         smb_info_t *si;
13945
13946         if(!*bcp){
13947                 return offset;
13948         }
13949
13950         si = (smb_info_t *)pinfo->private_data;
13951         DISSECTOR_ASSERT(si);
13952
13953         switch(si->info_level){
13954         case 1:         /*Info Standard*/
13955                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13956                     trunc);
13957                 break;
13958         case 2:         /*Info Query EA Size*/
13959                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13960                     trunc);
13961                 break;
13962         case 3:         /*Info Query EAs From List same as
13963                                 InfoQueryEASize*/
13964                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13965                     trunc);
13966                 break;
13967         case 0x0101:    /*Find File Directory Info*/
13968                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13969                     trunc);
13970                 break;
13971         case 0x0102:    /*Find File Full Directory Info*/
13972                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13973                     trunc);
13974                 break;
13975         case 0x0103:    /*Find File Names Info*/
13976                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13977                     trunc);
13978                 break;
13979         case 0x0104:    /*Find File Both Directory Info*/
13980                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13981                     trunc);
13982                 break;
13983         case 0x0202:    /*Find File UNIX*/
13984                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13985                     trunc);
13986                 break;
13987         default:        /* unknown info level */
13988                 *trunc = FALSE;
13989                 break;
13990         }
13991         return offset;
13992 }
13993
13994
13995 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
13996 static int
13997 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13998 {
13999         guint32 mask;
14000         proto_item *item;
14001         proto_tree *tree;
14002
14003         mask = tvb_get_letohl(tvb, offset);
14004
14005         if(parent_tree){
14006                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
14007                         "FS Attributes: 0x%08x", mask);
14008                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
14009
14010                 /* case sensitive search */
14011                 proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
14012                         tvb, offset, 4, mask);
14013                 /* case preserved names */
14014                 proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
14015                         tvb, offset, 4, mask);
14016                 /* unicode on disk */
14017                 proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
14018                         tvb, offset, 4, mask);
14019                 /* persistent acls */
14020                 proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
14021                         tvb, offset, 4, mask);
14022                 /* file compression */
14023                 proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
14024                         tvb, offset, 4, mask);
14025                 /* volume quotas */
14026                 proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
14027                         tvb, offset, 4, mask);
14028                 /* sparse files */
14029                 proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
14030                         tvb, offset, 4, mask);
14031                 /* reparse points */
14032                 proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
14033                         tvb, offset, 4, mask);
14034                 /* remote storage */
14035                 proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
14036                         tvb, offset, 4, mask);
14037                 /* lfn apis */
14038                 proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
14039                         tvb, offset, 4, mask);
14040                 /* volume is compressed */
14041                 proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
14042                         tvb, offset, 4, mask);
14043                 /* support oids */
14044                 proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
14045                         tvb, offset, 4, mask);
14046                 /* encryption */
14047                 proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
14048                         tvb, offset, 4, mask);
14049                 /* named streams */
14050                 proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
14051                         tvb, offset, 4, mask);
14052                 /* read only volume */
14053                 proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
14054                         tvb, offset, 4, mask);
14055         }
14056
14057         offset += 4;
14058         return offset;
14059 }
14060
14061
14062 static int
14063 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
14064 {
14065         guint32 mask;
14066         proto_item *item;
14067         proto_tree *tree;
14068
14069         mask = tvb_get_letohl(tvb, offset);
14070
14071         if(parent_tree){
14072                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
14073                         "Device Characteristics: 0x%08x", mask);
14074                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
14075
14076                 proto_tree_add_boolean(tree, hf_smb_device_char_removable,
14077                         tvb, offset, 4, mask);
14078                 proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
14079                         tvb, offset, 4, mask);
14080                 proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
14081                         tvb, offset, 4, mask);
14082                 proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
14083                         tvb, offset, 4, mask);
14084                 proto_tree_add_boolean(tree, hf_smb_device_char_remote,
14085                         tvb, offset, 4, mask);
14086                 proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
14087                         tvb, offset, 4, mask);
14088                 proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
14089                         tvb, offset, 4, mask);
14090         }
14091
14092         offset += 4;
14093         return offset;
14094 }
14095
14096 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
14097
14098 static const true_false_string tfs_smb_mac_access_ctrl = {
14099   "Macintosh Access Control Supported",
14100   "Macintosh Access Control Not Supported"
14101 };
14102
14103 static const true_false_string tfs_smb_mac_getset_comments = {
14104   "Macintosh Get & Set Comments Supported",
14105   "Macintosh Get & Set Comments Not Supported"
14106 };
14107
14108 static const true_false_string tfs_smb_mac_desktopdb_calls = {
14109   "Macintosh Get & Set Desktop Database Info Supported",
14110   "Macintosh Get & Set Desktop Database Info Supported"
14111 };
14112
14113 static const true_false_string tfs_smb_mac_unique_ids = {
14114   "Macintosh Unique IDs Supported",
14115   "Macintosh Unique IDs Not Supported"
14116 };
14117
14118 static const true_false_string tfs_smb_mac_streams = {
14119   "Macintosh and Streams Extensions Not Supported",
14120   "Macintosh and Streams Extensions Supported"
14121 };
14122
14123 int
14124 dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
14125 {
14126         int fn_len, vll;
14127         const char *fn;
14128
14129         /* create time */
14130         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14131         offset = dissect_nt_64bit_time(tvb, tree, offset,
14132                 hf_smb_create_time);
14133         *bcp -= 8;
14134
14135         /* volume serial number */
14136         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14137         proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
14138         COUNT_BYTES_TRANS_SUBR(4);
14139
14140         /* volume label length */
14141         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14142         vll = tvb_get_letohl(tvb, offset);
14143         proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
14144         COUNT_BYTES_TRANS_SUBR(4);
14145
14146         /* 2 reserved bytes */
14147         CHECK_BYTE_COUNT_TRANS_SUBR(2);
14148         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14149         COUNT_BYTES_TRANS_SUBR(2);
14150
14151         /* label */
14152         fn_len = vll;
14153         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
14154         CHECK_STRING_TRANS_SUBR(fn);
14155         proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14156                 fn);
14157         COUNT_BYTES_TRANS_SUBR(fn_len);
14158
14159         return offset;
14160 }
14161
14162 int
14163 dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14164 {
14165         /* allocation size */
14166         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14167         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
14168         COUNT_BYTES_TRANS_SUBR(8);
14169
14170         /* free allocation units */
14171         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14172         proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
14173         COUNT_BYTES_TRANS_SUBR(8);
14174
14175         /* sectors per unit */
14176         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14177         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14178         COUNT_BYTES_TRANS_SUBR(4);
14179
14180         /* bytes per sector */
14181         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14182         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
14183         COUNT_BYTES_TRANS_SUBR(4);
14184
14185         return offset;
14186 }
14187
14188 int
14189 dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14190 {
14191         /* device type */
14192         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14193         proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
14194         COUNT_BYTES_TRANS_SUBR(4);
14195
14196         /* device characteristics */
14197         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14198         offset = dissect_device_characteristics(tvb, tree, offset);
14199         *bcp -= 4;
14200
14201         return offset;
14202 }
14203
14204 int
14205 dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
14206 {
14207         int fn_len, fnl;
14208         const char *fn;
14209
14210         /* FS attributes */
14211         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14212         offset = dissect_fs_attributes(tvb, tree, offset);
14213         *bcp -= 4;
14214
14215         /* max name len */
14216         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14217         proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
14218         COUNT_BYTES_TRANS_SUBR(4);
14219
14220         /* fs name length */
14221         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14222         fnl = tvb_get_letohl(tvb, offset);
14223         proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
14224         COUNT_BYTES_TRANS_SUBR(4);
14225
14226         /* label */
14227         fn_len = fnl;
14228         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
14229         CHECK_STRING_TRANS_SUBR(fn);
14230         proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
14231                 fn);
14232         COUNT_BYTES_TRANS_SUBR(fn_len);
14233
14234         return offset;
14235 }
14236
14237 int
14238 dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
14239 {
14240         CHECK_BYTE_COUNT_TRANS_SUBR(64);
14241
14242         dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
14243
14244         COUNT_BYTES_TRANS_SUBR(64);
14245
14246         return offset;
14247 }
14248
14249 int
14250 dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
14251 {
14252         /* allocation size */
14253         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14254         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
14255         COUNT_BYTES_TRANS_SUBR(8);
14256
14257         /* caller free allocation units */
14258         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14259         proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
14260         COUNT_BYTES_TRANS_SUBR(8);
14261
14262         /* actual free allocation units */
14263         CHECK_BYTE_COUNT_TRANS_SUBR(8);
14264         proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
14265         COUNT_BYTES_TRANS_SUBR(8);
14266
14267         /* sectors per unit */
14268         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14269         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14270         COUNT_BYTES_TRANS_SUBR(4);
14271
14272         /* bytes per sector */
14273         CHECK_BYTE_COUNT_TRANS_SUBR(4);
14274         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
14275         COUNT_BYTES_TRANS_SUBR(4);
14276
14277         return offset;
14278 }
14279
14280 static int
14281 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
14282     int offset, guint16 *bcp)
14283 {
14284         smb_info_t *si;
14285         int fn_len, vll;
14286         const char *fn;
14287         guint support = 0;
14288         proto_item *item = NULL;
14289         proto_tree *ti = NULL;
14290
14291         if(!*bcp){
14292                 return offset;
14293         }
14294
14295         si = (smb_info_t *)pinfo->private_data;
14296         DISSECTOR_ASSERT(si);
14297
14298         switch(si->info_level){
14299         case 1:         /* SMB_INFO_ALLOCATION */
14300                 /* filesystem id */
14301                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14302                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
14303                 COUNT_BYTES_TRANS_SUBR(4);
14304
14305                 /* sectors per unit */
14306                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14307                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
14308                 COUNT_BYTES_TRANS_SUBR(4);
14309
14310                 /* units */
14311                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14312                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
14313                 COUNT_BYTES_TRANS_SUBR(4);
14314
14315                 /* avail units */
14316                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14317                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
14318                 COUNT_BYTES_TRANS_SUBR(4);
14319
14320                 /* bytes per sector, only 16bit integer here */
14321                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14322                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14323                 COUNT_BYTES_TRANS_SUBR(2);
14324
14325                 break;
14326         case 2:         /* SMB_INFO_VOLUME */
14327                 /* volume serial number */
14328                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14329                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
14330                 COUNT_BYTES_TRANS_SUBR(4);
14331
14332                 /* volume label length, only one byte here */
14333                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
14334                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
14335                 COUNT_BYTES_TRANS_SUBR(1);
14336
14337                 /* label */
14338                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
14339                 CHECK_STRING_TRANS_SUBR(fn);
14340                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14341                         fn);
14342                 COUNT_BYTES_TRANS_SUBR(fn_len);
14343
14344                 break;
14345         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
14346         case 1002:      /* SMB_FS_LABEL_INFORMATION */
14347                 /* volume label length */
14348                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14349                 vll = tvb_get_letohl(tvb, offset);
14350                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
14351                 COUNT_BYTES_TRANS_SUBR(4);
14352
14353                 /* label */
14354                 fn_len = vll;
14355                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14356                 CHECK_STRING_TRANS_SUBR(fn);
14357                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
14358                         fn);
14359                 COUNT_BYTES_TRANS_SUBR(fn_len);
14360
14361                 break;
14362         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
14363         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
14364                 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
14365                 break;
14366         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
14367         case 1003:      /* SMB_FS_SIZE_INFORMATION */
14368                 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
14369                 break;
14370         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
14371         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
14372                 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, bcp);
14373                 break;
14374         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
14375         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
14376                 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
14377                 break;
14378         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
14379                 proto_item *item = NULL;
14380                 proto_tree *subtree = NULL;
14381                 guint32 caps_lo, caps_hi;
14382
14383                 /* MajorVersionNumber */
14384                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14385                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
14386                 COUNT_BYTES_TRANS_SUBR(2);
14387
14388                 /* MinorVersionNumber */
14389                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
14390                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
14391                 COUNT_BYTES_TRANS_SUBR(2);
14392
14393                 /* Capability */
14394
14395                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14396
14397                 caps_lo = tvb_get_letohl(tvb, offset);
14398                 caps_hi = tvb_get_letohl(tvb, offset + 4);
14399
14400                 if (tree) {
14401                         item = proto_tree_add_text(
14402                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x",
14403                                 caps_hi, caps_lo);
14404                         subtree = proto_item_add_subtree(
14405                                 item, ett_smb_unix_capabilities);
14406                 }
14407
14408                 proto_tree_add_boolean(
14409                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8,
14410                         caps_lo);
14411
14412                 proto_tree_add_boolean(
14413                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8,
14414                         caps_lo);
14415
14416                 COUNT_BYTES_TRANS_SUBR(8);
14417
14418                 break;
14419         }
14420         case 0x301:     /* MAC_QUERY_FS_INFO */
14421                 /* Create time */
14422                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14423                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
14424                 *bcp -= 8;
14425                 /* Modify Time */
14426                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14427                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
14428                 *bcp -= 8;
14429                 /* Backup Time */
14430                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
14431                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
14432                 *bcp -= 8;
14433                 /* Allocation blocks */
14434                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14435                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
14436                                     offset,
14437                                     4, TRUE);
14438                 COUNT_BYTES_TRANS_SUBR(4);
14439                 /* Allocation Block Size */
14440                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14441                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
14442                                     offset, 4, TRUE);
14443                 COUNT_BYTES_TRANS_SUBR(4);
14444                 /* Free Block Count */
14445                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14446                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
14447                                     offset, 4, TRUE);
14448                 COUNT_BYTES_TRANS_SUBR(4);
14449                 /* Finder Info ... */
14450                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
14451                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
14452                                             offset, 32,
14453                                             tvb_get_ptr(tvb, offset,32),
14454                                             "Finder Info: %s",
14455                                             tvb_format_text(tvb, offset, 32));
14456                 COUNT_BYTES_TRANS_SUBR(32);
14457                 /* Number Files */
14458                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14459                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
14460                                     offset, 4, TRUE);
14461                 COUNT_BYTES_TRANS_SUBR(4);
14462                 /* Number of Root Directories */
14463                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14464                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
14465                                     offset, 4, TRUE);
14466                 COUNT_BYTES_TRANS_SUBR(4);
14467                 /* Number of files */
14468                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14469                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
14470                                     offset, 4, TRUE);
14471                 COUNT_BYTES_TRANS_SUBR(4);
14472                 /* Dir Count */
14473                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14474                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
14475                                     offset, 4, TRUE);
14476                 COUNT_BYTES_TRANS_SUBR(4);
14477                 /* Mac Support Flags */
14478                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
14479                 support = tvb_get_ntohl(tvb, offset);
14480                 item = proto_tree_add_text(tree, tvb, offset, 4,
14481                                            "Mac Support Flags: 0x%08x", support);
14482                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
14483                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
14484                                        tvb, offset, 4, support);
14485                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
14486                                        tvb, offset, 4, support);
14487                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
14488                                        tvb, offset, 4, support);
14489                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
14490                                        tvb, offset, 4, support);
14491                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
14492                                        tvb, offset, 4, support);
14493                 COUNT_BYTES_TRANS_SUBR(4);
14494                 break;
14495         case 1006:      /* QUERY_FS_QUOTA_INFO */
14496                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
14497                 break;
14498         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
14499                 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
14500                 break;
14501         case 1008: /* Query Object ID */ {
14502                 offset = dissect_qfsi_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, bcp);
14503                 break;
14504             }
14505         }
14506
14507         return offset;
14508 }
14509
14510 static int
14511 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
14512     proto_tree *parent_tree)
14513 {
14514         proto_item *item = NULL;
14515         proto_tree *tree = NULL;
14516         smb_info_t *si;
14517         smb_transact2_info_t *t2i;
14518         int count;
14519         gboolean trunc;
14520         int offset = 0;
14521         guint16 dc;
14522
14523         dc = tvb_reported_length(tvb);
14524
14525         si = (smb_info_t *)pinfo->private_data;
14526         DISSECTOR_ASSERT(si);
14527
14528         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14529                 t2i = si->sip->extra_info;
14530         else
14531                 t2i = NULL;
14532
14533         if(parent_tree){
14534                 if (t2i != NULL && t2i->subcmd != -1) {
14535                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
14536                                 "%s Data",
14537                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14538                                         "Unknown (0x%02x)"));
14539                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
14540                 } else {
14541                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
14542                                 "Unknown Transaction2 Data");
14543                 }
14544         }
14545
14546         if (t2i == NULL) {
14547                 offset += dc;
14548                 return offset;
14549         }
14550         switch(t2i->subcmd){
14551         case 0x00:      /*TRANS2_OPEN2*/
14552                 /* XXX not implemented yet. See SNIA doc */
14553                 break;
14554         case 0x01:      /*TRANS2_FIND_FIRST2*/
14555                 /* returned data */
14556                 count = si->info_count;
14557
14558         if(count == -1) {
14559             break;
14560         }
14561                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14562                         col_append_str(pinfo->cinfo, COL_INFO,
14563                         ", Files:");
14564                 }
14565
14566                 while(count--){
14567                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14568                                 offset, &dc, &trunc);
14569                         if (trunc)
14570                                 break;
14571                 }
14572                 break;
14573         case 0x02:      /*TRANS2_FIND_NEXT2*/
14574                 /* returned data */
14575                 count = si->info_count;
14576
14577         if(count == -1) {
14578             break;
14579         }
14580                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
14581                         col_append_str(pinfo->cinfo, COL_INFO,
14582                         ", Files:");
14583                 }
14584
14585                 while(count--){
14586                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
14587                                 offset, &dc, &trunc);
14588                         if (trunc)
14589                                 break;
14590                 }
14591                 break;
14592         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14593                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
14594                 break;
14595         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14596                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14597                 break;
14598         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14599                 /* no data in this response */
14600                 break;
14601         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14602                 /* identical to QUERY_PATH_INFO */
14603                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
14604                 break;
14605         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14606                 /* no data in this response */
14607                 break;
14608         case 0x09:      /*TRANS2_FSCTL*/
14609                 /* XXX dont know how to dissect this one (yet)*/
14610
14611                 /*
14612                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14613                  * Extensions Version 3.0, Document Version 1.11,
14614                  * July 19, 1990" says this this contains a
14615                  * "File system specific return data block".
14616                  * (That means we may not be able to dissect it in any
14617                  * case.)
14618                  */
14619                 break;
14620         case 0x0a:      /*TRANS2_IOCTL2*/
14621                 /* XXX dont know how to dissect this one (yet)*/
14622
14623                 /*
14624                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14625                  * Extensions Version 3.0, Document Version 1.11,
14626                  * July 19, 1990" says this this contains a
14627                  * "Device/function specific return data block".
14628                  * (That means we may not be able to dissect it in any
14629                  * case.)
14630                  */
14631                 break;
14632         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14633                 /* XXX dont know how to dissect this one (yet)*/
14634
14635                 /*
14636                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14637                  * Extensions Version 3.0, Document Version 1.11,
14638                  * July 19, 1990" says this this contains "the level
14639                  * dependent information about the changes which
14640                  * occurred".
14641                  */
14642                 break;
14643         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14644                 /* XXX dont know how to dissect this one (yet)*/
14645
14646                 /*
14647                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14648                  * Extensions Version 3.0, Document Version 1.11,
14649                  * July 19, 1990" says this this contains "the level
14650                  * dependent information about the changes which
14651                  * occurred".
14652                  */
14653                 break;
14654         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14655                 /* no data in this response */
14656                 break;
14657         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14658                 /* XXX dont know how to dissect this one (yet)*/
14659                 break;
14660         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14661                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
14662                 break;
14663         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14664                 /* the SNIA spec appears to say the response has no data */
14665                 break;
14666         case -1:
14667                 /*
14668                  * We don't know what the matching request was; don't
14669                  * bother putting anything else into the tree for the data.
14670                  */
14671                 offset += dc;
14672                 dc = 0;
14673                 break;
14674         }
14675
14676         /* ooops there were data we didnt know how to process */
14677         if(dc != 0){
14678                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
14679                 offset += dc;
14680         }
14681
14682         return offset;
14683 }
14684
14685
14686 static void
14687 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14688 {
14689         proto_item *item = NULL;
14690         proto_tree *tree = NULL;
14691         smb_info_t *si;
14692         smb_transact2_info_t *t2i;
14693         guint16 fid;
14694         int lno;
14695         int offset = 0;
14696         int pc;
14697
14698         pc = tvb_reported_length(tvb);
14699
14700         si = (smb_info_t *)pinfo->private_data;
14701         DISSECTOR_ASSERT(si);
14702
14703         if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I)
14704                 t2i = si->sip->extra_info;
14705         else
14706                 t2i = NULL;
14707
14708         if(parent_tree){
14709                 if (t2i != NULL && t2i->subcmd != -1) {
14710                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14711                                 "%s Parameters",
14712                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
14713                                                 "Unknown (0x%02x)"));
14714                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
14715                 } else {
14716                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
14717                                 "Unknown Transaction2 Parameters");
14718                 }
14719         }
14720
14721         if (t2i == NULL) {
14722                 offset += pc;
14723                 return;
14724         }
14725         switch(t2i->subcmd){
14726         case 0x00:      /*TRANS2_OPEN2*/
14727                 /* fid */
14728                 fid = tvb_get_letohs(tvb, offset);
14729                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
14730                 offset += 2;
14731
14732                 /*
14733                  * XXX - Microsoft Networks SMB File Sharing Protocol
14734                  * Extensions Version 3.0, Document Version 1.11,
14735                  * July 19, 1990 says that the file attributes, create
14736                  * time (which it says is the last modification time),
14737                  * data size, granted access, file type, and IPC state
14738                  * are returned only if bit 0 is set in the open flags,
14739                  * and that the EA length is returned only if bit 3
14740                  * is set in the open flags.  Does that mean that,
14741                  * at least in that SMB dialect, those fields are not
14742                  * present in the reply parameters if the bits in
14743                  * question aren't set?
14744                  */
14745
14746                 /* File Attributes */
14747                 offset = dissect_file_attributes(tvb, tree, offset, 2);
14748
14749                 /* create time */
14750                 offset = dissect_smb_datetime(tvb, tree, offset,
14751                         hf_smb_create_time,
14752                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
14753
14754                 /* data size */
14755                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
14756                 offset += 4;
14757
14758                 /* granted access */
14759                 offset = dissect_access(tvb, tree, offset, "Granted");
14760
14761                 /* File Type */
14762                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
14763                 offset += 2;
14764
14765                 /* IPC State */
14766                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
14767
14768                 /* open_action */
14769                 offset = dissect_open_action(tvb, tree, offset);
14770
14771                 /* server unique file ID */
14772                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
14773                 offset += 4;
14774
14775                 /* ea error offset, only a 16 bit integer here */
14776                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14777                 offset += 2;
14778
14779                 /* ea length */
14780                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
14781                 offset += 4;
14782
14783                 break;
14784         case 0x01:      /*TRANS2_FIND_FIRST2*/
14785                 /* Find First2 information level */
14786                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
14787
14788                 /* sid */
14789                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
14790                 offset += 2;
14791
14792                 /* search count */
14793                 si->info_count = tvb_get_letohs(tvb, offset);
14794                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14795                 offset += 2;
14796
14797                 /* end of search */
14798                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14799                 offset += 2;
14800
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                 /* last name offset */
14806                 lno = tvb_get_letohs(tvb, offset);
14807                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14808                 offset += 2;
14809
14810                 break;
14811         case 0x02:      /*TRANS2_FIND_NEXT2*/
14812                 /* search count */
14813                 si->info_count = tvb_get_letohs(tvb, offset);
14814                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
14815                 offset += 2;
14816
14817                 /* end of search */
14818                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
14819                 offset += 2;
14820
14821                 /* ea_error_offset, only a 16 bit integer here*/
14822                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14823                 offset += 2;
14824
14825                 /* last name offset */
14826                 lno = tvb_get_letohs(tvb, offset);
14827                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
14828                 offset += 2;
14829
14830                 break;
14831         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
14832                 /* no parameter block here */
14833                 break;
14834         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
14835                 /* ea_error_offset, only a 16 bit integer here*/
14836                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14837                 offset += 2;
14838
14839                 break;
14840         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
14841                 /* ea_error_offset, only a 16 bit integer here*/
14842                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14843                 offset += 2;
14844
14845                 break;
14846         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
14847                 /* ea_error_offset, only a 16 bit integer here*/
14848                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14849                 offset += 2;
14850
14851                 break;
14852         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
14853                 /* ea_error_offset, only a 16 bit integer here*/
14854                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14855                 offset += 2;
14856
14857                 break;
14858         case 0x09:      /*TRANS2_FSCTL*/
14859                 /* XXX dont know how to dissect this one (yet)*/
14860
14861                 /*
14862                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14863                  * Extensions Version 3.0, Document Version 1.11,
14864                  * July 19, 1990" says this this contains a
14865                  * "File system specific return parameter block".
14866                  * (That means we may not be able to dissect it in any
14867                  * case.)
14868                  */
14869                 break;
14870         case 0x0a:      /*TRANS2_IOCTL2*/
14871                 /* XXX dont know how to dissect this one (yet)*/
14872
14873                 /*
14874                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14875                  * Extensions Version 3.0, Document Version 1.11,
14876                  * July 19, 1990" says this this contains a
14877                  * "Device/function specific return parameter block".
14878                  * (That means we may not be able to dissect it in any
14879                  * case.)
14880                  */
14881                 break;
14882         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14883                 /* Find Notify information level */
14884                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14885
14886                 /* Monitor handle */
14887                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14888                 offset += 2;
14889
14890                 /* Change count */
14891                 si->info_count = tvb_get_letohs(tvb, offset);
14892                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14893                 offset += 2;
14894
14895                 /* ea_error_offset, only a 16 bit integer here*/
14896                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14897                 offset += 2;
14898
14899                 break;
14900         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14901                 /* Find Notify information level */
14902                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14903
14904                 /* Change count */
14905                 si->info_count = tvb_get_letohs(tvb, offset);
14906                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14907                 offset += 2;
14908
14909                 /* ea_error_offset, only a 16 bit integer here*/
14910                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14911                 offset += 2;
14912
14913                 break;
14914         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14915                 /* ea error offset, only a 16 bit integer here */
14916                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14917                 offset += 2;
14918
14919                 break;
14920         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14921                 /* XXX dont know how to dissect this one (yet)*/
14922                 break;
14923         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14924                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14925                 break;
14926         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14927                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14928                 break;
14929         case -1:
14930                 /*
14931                  * We don't know what the matching request was; don't
14932                  * bother putting anything else into the tree for the data.
14933                  */
14934                 offset += pc;
14935                 break;
14936         }
14937
14938         /* ooops there were data we didnt know how to process */
14939         if(offset<pc){
14940                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
14941                 offset += pc-offset;
14942         }
14943 }
14944
14945
14946 static int
14947 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14948 {
14949         guint8 sc, wc;
14950         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
14951         smb_info_t *si;
14952         smb_transact2_info_t *t2i = NULL;
14953         guint16 bc;
14954         int padcnt;
14955         gboolean dissected_trans;
14956         fragment_data *r_fd = NULL;
14957         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
14958         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
14959         gboolean save_fragmented;
14960         proto_item *item;
14961
14962         si = (smb_info_t *)pinfo->private_data;
14963         DISSECTOR_ASSERT(si);
14964
14965         switch(si->cmd){
14966         case SMB_COM_TRANSACTION2:
14967                 /* transaction2 */
14968                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_T2I) {
14969                         t2i = si->sip->extra_info;
14970                 } else
14971                         t2i = NULL;
14972                 if (t2i == NULL) {
14973                         /*
14974                          * We didn't see the matching request, so we don't
14975                          * know what type of transaction this is.
14976                          */
14977                         proto_tree_add_text(tree, tvb, 0, 0,
14978                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
14979                         if (check_col(pinfo->cinfo, COL_INFO)) {
14980                                 col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
14981                         }
14982                 } else {
14983                         si->info_level = t2i->info_level;
14984                         if (t2i->subcmd == -1) {
14985                                 /*
14986                                  * We didn't manage to extract the subcommand
14987                                  * from the matching request (perhaps because
14988                                  * the frame was short), so we don't know what
14989                                  * type of transaction this is.
14990                                  */
14991                                 proto_tree_add_text(tree, tvb, 0, 0,
14992                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
14993                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14994                                         col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
14995                                 }
14996                         } else {
14997                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
14998                                 /* FIND_FIRST2 */
14999                                 if(t2i && t2i->subcmd==0x0001){
15000                                         item=proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
15001                                         PROTO_ITEM_SET_GENERATED(item);
15002                                         if(t2i->name){
15003                                                 item=proto_tree_add_string(tree, hf_smb_search_pattern, tvb, 0, 0, t2i->name);
15004                                                 PROTO_ITEM_SET_GENERATED(item);
15005                                         }
15006                                 }
15007
15008                                 /* QUERY_PATH_INFORMATION */
15009                                 if(t2i && t2i->subcmd==0x0005){
15010                                         item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
15011                                         PROTO_ITEM_SET_GENERATED(item);
15012                                         if(t2i->name){
15013                                                 item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, t2i->name);
15014                                                 PROTO_ITEM_SET_GENERATED(item);
15015                                         }
15016                                 }
15017                                 /* QUERY_FILE_INFORMATION */
15018                                 if(t2i && t2i->subcmd==0x0007){
15019                                         item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
15020                                         PROTO_ITEM_SET_GENERATED(item);
15021                                 }
15022                                 /* QUERY_FS_INFORMATION */
15023                                 if(t2i && t2i->subcmd==0x0003){
15024                                         item=proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level);
15025                                         PROTO_ITEM_SET_GENERATED(item);
15026                                 }
15027
15028                                 if (t2i && check_col(pinfo->cinfo, COL_INFO)) {
15029                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
15030                                                 val_to_str(t2i->subcmd,
15031                                                         trans2_cmd_vals,
15032                                                         "<unknown (0x%02x)>"));
15033                                 }
15034                         }
15035                 }
15036                 break;
15037         }
15038
15039         WORD_COUNT;
15040
15041         /* total param count, only a 16bit integer here */
15042         tp = tvb_get_letohs(tvb, offset);
15043         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
15044         offset += 2;
15045
15046         /* total data count, only a 16 bit integer here */
15047         td = tvb_get_letohs(tvb, offset);
15048         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
15049         offset += 2;
15050
15051         /* 2 reserved bytes */
15052         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
15053         offset += 2;
15054
15055         /* param count */
15056         pc = tvb_get_letohs(tvb, offset);
15057         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
15058         offset += 2;
15059
15060         /* param offset */
15061         po = tvb_get_letohs(tvb, offset);
15062         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
15063         offset += 2;
15064
15065         /* param disp */
15066         pd = tvb_get_letohs(tvb, offset);
15067         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
15068         offset += 2;
15069
15070         /* data count */
15071         dc = tvb_get_letohs(tvb, offset);
15072         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
15073         offset += 2;
15074
15075         /* data offset */
15076         od = tvb_get_letohs(tvb, offset);
15077         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
15078         offset += 2;
15079
15080         /* data disp */
15081         dd = tvb_get_letohs(tvb, offset);
15082         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
15083         offset += 2;
15084
15085         /* setup count */
15086         sc = tvb_get_guint8(tvb, offset);
15087         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
15088         offset += 1;
15089
15090         /* reserved byte */
15091         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
15092         offset += 1;
15093
15094
15095         /* if there were any setup bytes, put them in a tvb for later */
15096         if(sc){
15097                 if((2*sc)>tvb_length_remaining(tvb, offset)){
15098                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
15099                 } else {
15100                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
15101                 }
15102                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
15103         } else {
15104                 s_tvb = NULL;
15105                 sp_tvb=NULL;
15106         }
15107         offset += 2*sc;
15108
15109
15110         BYTE_COUNT;
15111
15112
15113         /* reassembly of SMB Transaction data payload.
15114            In this section we do reassembly of both the data and parameters
15115            blocks of the SMB transaction command.
15116         */
15117         save_fragmented = pinfo->fragmented;
15118         /* do we need reassembly? */
15119         if( (td!=dc) || (tp!=pc) ){
15120                 /* oh yeah, either data or parameter section needs
15121                    reassembly
15122                 */
15123                 pinfo->fragmented = TRUE;
15124                 if(smb_trans_reassembly){
15125                         /* ...and we were told to do reassembly */
15126                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
15127                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
15128                                                              po, pc, pd, td+tp);
15129
15130                         }
15131                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
15132                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
15133                                                              od, dc, dd+tp, td+tp);
15134                         }
15135                 }
15136         }
15137
15138         /* if we got a reassembled fd structure from the reassembly routine we must
15139            create pd_tvb from it
15140         */
15141         if(r_fd){
15142         proto_item *frag_tree_item;
15143
15144                 pd_tvb = tvb_new_child_real_data(tvb, r_fd->data, r_fd->datalen,
15145                                              r_fd->datalen);
15146                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
15147                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
15148         }
15149
15150
15151         if(pd_tvb){
15152                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
15153                 if(tp){
15154                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
15155                 }
15156                 if(td){
15157                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
15158                 }
15159         } else {
15160                 /* It was not reassembled. Do as best as we can.
15161                  * in this case we always try to dissect the stuff if
15162                  * data and param displacement is 0. i.e. for the first
15163                  * (and maybe only) packet.
15164                  */
15165                 if( (pd==0) && (dd==0) ){
15166                         int min;
15167                         int reported_min;
15168                         min = MIN(pc,tvb_length_remaining(tvb,po));
15169                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
15170                         if(min && reported_min) {
15171                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
15172                         }
15173                         min = MIN(dc,tvb_length_remaining(tvb,od));
15174                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
15175                         if(min && reported_min) {
15176                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
15177                         }
15178                         /*
15179                          * A tvbuff containing the parameters
15180                          * and the data.
15181                          * XXX - check pc and dc as well?
15182                          */
15183                         if (tvb_length_remaining(tvb, po)){
15184                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
15185                         }
15186                 }
15187         }
15188
15189
15190
15191         /* parameters */
15192         if(po>offset){
15193                 /* We have some padding bytes.
15194                 */
15195                 padcnt = po-offset;
15196                 if (padcnt > bc)
15197                         padcnt = bc;
15198                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
15199                 COUNT_BYTES(padcnt);
15200         }
15201         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
15202                 /* TRANSACTION2 parameters*/
15203                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
15204         }
15205         COUNT_BYTES(pc);
15206
15207
15208         /* data */
15209         if(od>offset){
15210                 /* We have some initial padding bytes.
15211                 */
15212                 padcnt = od-offset;
15213                 if (padcnt > bc)
15214                         padcnt = bc;
15215                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
15216                 COUNT_BYTES(padcnt);
15217         }
15218         /*
15219          * If the data count is bigger than the count of bytes
15220          * remaining, clamp it so that the count of bytes remaining
15221          * doesn't go negative.
15222          */
15223         if (dc > bc)
15224                 dc = bc;
15225         COUNT_BYTES(dc);
15226
15227
15228
15229         /* from now on, everything is in separate tvbuffs so we dont count
15230            the bytes with COUNT_BYTES any more.
15231            neither do we reference offset any more (which by now points to the
15232            first byte AFTER this PDU */
15233
15234
15235         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
15236                 /* TRANSACTION2 parameters*/
15237                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
15238         }
15239
15240
15241         if(si->cmd==SMB_COM_TRANSACTION){
15242                 smb_transact_info_t *tri;
15243
15244                 dissected_trans = FALSE;
15245                 if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_TRI)
15246                         tri = si->sip->extra_info;
15247                 else
15248                         tri = NULL;
15249                 if (tri != NULL) {
15250                         switch(tri->subcmd){
15251
15252                         case TRANSACTION_PIPE:
15253                                 /* This function is safe to call for
15254                                    s_tvb==sp_tvb==NULL, i.e. if we don't
15255                                    know them at this point.
15256                                    It's also safe to call if "p_tvb"
15257                                    or "d_tvb" are null.
15258                                 */
15259                                 if( pd_tvb) {
15260                                         dissected_trans = dissect_pipe_smb(
15261                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
15262                                                 d_tvb, NULL, pinfo, top_tree);
15263                                 }
15264                                 break;
15265
15266                         case TRANSACTION_MAILSLOT:
15267                                 /* This one should be safe to call
15268                                    even if s_tvb and sp_tvb is NULL
15269                                 */
15270                                 if(d_tvb){
15271                                         dissected_trans = dissect_mailslot_smb(
15272                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
15273                                                 top_tree);
15274                                 }
15275                                 break;
15276                         }
15277                 }
15278                 if (!dissected_trans) {
15279                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
15280                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
15281                 }
15282         }
15283
15284
15285         if( (p_tvb==0) && (d_tvb==0) ){
15286                 if(check_col(pinfo->cinfo, COL_INFO)){
15287                         col_append_str(pinfo->cinfo, COL_INFO,
15288                                        "[transact continuation]");
15289                 }
15290         }
15291
15292         pinfo->fragmented = save_fragmented;
15293         END_OF_SMB
15294
15295         return offset;
15296 }
15297
15298
15299 static int
15300 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15301 {
15302         guint8 wc;
15303         guint16 bc;
15304
15305         WORD_COUNT;
15306
15307         /* Monitor handle */
15308         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
15309         offset += 2;
15310
15311         BYTE_COUNT;
15312
15313         END_OF_SMB
15314
15315         return offset;
15316 }
15317
15318 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15319    END Transaction/Transaction2 Primary and secondary requests
15320    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15321
15322
15323 static int
15324 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
15325 {
15326         guint8 wc;
15327         guint16 bc;
15328
15329         WORD_COUNT;
15330
15331         if (wc != 0) {
15332                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
15333                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
15334                 offset += wc*2;
15335         }
15336
15337         BYTE_COUNT;
15338
15339         if (bc != 0) {
15340                 tvb_ensure_bytes_exist(tvb, offset, bc);
15341                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
15342                 offset += bc;
15343                 bc = 0;
15344         }
15345
15346         END_OF_SMB
15347
15348         return offset;
15349 }
15350
15351 typedef struct _smb_function {
15352        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15353        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15354 } smb_function;
15355
15356 static smb_function smb_dissector[256] = {
15357   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
15358   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
15359   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
15360   /* 0x03 Create File*/  {dissect_create_file_request, dissect_create_file_response},
15361   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
15362   /* 0x05 Flush File*/  {dissect_flush_file_request, dissect_empty},
15363   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
15364   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_rename_file_response},
15365   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
15366   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
15367   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
15368   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
15369   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
15370   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
15371   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
15372   /* 0x0f Create New*/  {dissect_create_file_request, dissect_create_new_response},
15373
15374   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
15375   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
15376   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
15377   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
15378   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
15379   /* 0x15 */  {dissect_unknown, dissect_unknown},
15380   /* 0x16 */  {dissect_unknown, dissect_unknown},
15381   /* 0x17 */  {dissect_unknown, dissect_unknown},
15382   /* 0x18 */  {dissect_unknown, dissect_unknown},
15383   /* 0x19 */  {dissect_unknown, dissect_unknown},
15384   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
15385   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
15386   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
15387   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
15388   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
15389   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
15390
15391   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
15392   /* 0x21 */  {dissect_unknown, dissect_unknown},
15393   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
15394   /* 0x23 Query Info2*/  {dissect_query_information2_request, dissect_query_information2_response},
15395   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
15396   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
15397   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
15398   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
15399   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
15400   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
15401   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
15402   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
15403   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
15404   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
15405   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
15406   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
15407
15408   /* 0x30 */  {dissect_unknown, dissect_unknown},
15409   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
15410   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
15411   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
15412   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
15413   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
15414   /* 0x36 */  {dissect_unknown, dissect_unknown},
15415   /* 0x37 */  {dissect_unknown, dissect_unknown},
15416   /* 0x38 */  {dissect_unknown, dissect_unknown},
15417   /* 0x39 */  {dissect_unknown, dissect_unknown},
15418   /* 0x3a */  {dissect_unknown, dissect_unknown},
15419   /* 0x3b */  {dissect_unknown, dissect_unknown},
15420   /* 0x3c */  {dissect_unknown, dissect_unknown},
15421   /* 0x3d */  {dissect_unknown, dissect_unknown},
15422   /* 0x3e */  {dissect_unknown, dissect_unknown},
15423   /* 0x3f */  {dissect_unknown, dissect_unknown},
15424
15425   /* 0x40 */  {dissect_unknown, dissect_unknown},
15426   /* 0x41 */  {dissect_unknown, dissect_unknown},
15427   /* 0x42 */  {dissect_unknown, dissect_unknown},
15428   /* 0x43 */  {dissect_unknown, dissect_unknown},
15429   /* 0x44 */  {dissect_unknown, dissect_unknown},
15430   /* 0x45 */  {dissect_unknown, dissect_unknown},
15431   /* 0x46 */  {dissect_unknown, dissect_unknown},
15432   /* 0x47 */  {dissect_unknown, dissect_unknown},
15433   /* 0x48 */  {dissect_unknown, dissect_unknown},
15434   /* 0x49 */  {dissect_unknown, dissect_unknown},
15435   /* 0x4a */  {dissect_unknown, dissect_unknown},
15436   /* 0x4b */  {dissect_unknown, dissect_unknown},
15437   /* 0x4c */  {dissect_unknown, dissect_unknown},
15438   /* 0x4d */  {dissect_unknown, dissect_unknown},
15439   /* 0x4e */  {dissect_unknown, dissect_unknown},
15440   /* 0x4f */  {dissect_unknown, dissect_unknown},
15441
15442   /* 0x50 */  {dissect_unknown, dissect_unknown},
15443   /* 0x51 */  {dissect_unknown, dissect_unknown},
15444   /* 0x52 */  {dissect_unknown, dissect_unknown},
15445   /* 0x53 */  {dissect_unknown, dissect_unknown},
15446   /* 0x54 */  {dissect_unknown, dissect_unknown},
15447   /* 0x55 */  {dissect_unknown, dissect_unknown},
15448   /* 0x56 */  {dissect_unknown, dissect_unknown},
15449   /* 0x57 */  {dissect_unknown, dissect_unknown},
15450   /* 0x58 */  {dissect_unknown, dissect_unknown},
15451   /* 0x59 */  {dissect_unknown, dissect_unknown},
15452   /* 0x5a */  {dissect_unknown, dissect_unknown},
15453   /* 0x5b */  {dissect_unknown, dissect_unknown},
15454   /* 0x5c */  {dissect_unknown, dissect_unknown},
15455   /* 0x5d */  {dissect_unknown, dissect_unknown},
15456   /* 0x5e */  {dissect_unknown, dissect_unknown},
15457   /* 0x5f */  {dissect_unknown, dissect_unknown},
15458
15459   /* 0x60 */  {dissect_unknown, dissect_unknown},
15460   /* 0x61 */  {dissect_unknown, dissect_unknown},
15461   /* 0x62 */  {dissect_unknown, dissect_unknown},
15462   /* 0x63 */  {dissect_unknown, dissect_unknown},
15463   /* 0x64 */  {dissect_unknown, dissect_unknown},
15464   /* 0x65 */  {dissect_unknown, dissect_unknown},
15465   /* 0x66 */  {dissect_unknown, dissect_unknown},
15466   /* 0x67 */  {dissect_unknown, dissect_unknown},
15467   /* 0x68 */  {dissect_unknown, dissect_unknown},
15468   /* 0x69 */  {dissect_unknown, dissect_unknown},
15469   /* 0x6a */  {dissect_unknown, dissect_unknown},
15470   /* 0x6b */  {dissect_unknown, dissect_unknown},
15471   /* 0x6c */  {dissect_unknown, dissect_unknown},
15472   /* 0x6d */  {dissect_unknown, dissect_unknown},
15473   /* 0x6e */  {dissect_unknown, dissect_unknown},
15474   /* 0x6f */  {dissect_unknown, dissect_unknown},
15475
15476   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
15477   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
15478   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
15479   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
15480   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
15481   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
15482   /* 0x76 */  {dissect_unknown, dissect_unknown},
15483   /* 0x77 */  {dissect_unknown, dissect_unknown},
15484   /* 0x78 */  {dissect_unknown, dissect_unknown},
15485   /* 0x79 */  {dissect_unknown, dissect_unknown},
15486   /* 0x7a */  {dissect_unknown, dissect_unknown},
15487   /* 0x7b */  {dissect_unknown, dissect_unknown},
15488   /* 0x7c */  {dissect_unknown, dissect_unknown},
15489   /* 0x7d */  {dissect_unknown, dissect_unknown},
15490   /* 0x7e */  {dissect_unknown, dissect_unknown},
15491   /* 0x7f */  {dissect_unknown, dissect_unknown},
15492
15493   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
15494   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
15495   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
15496   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
15497   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
15498   /* 0x85 */  {dissect_unknown, dissect_unknown},
15499   /* 0x86 */  {dissect_unknown, dissect_unknown},
15500   /* 0x87 */  {dissect_unknown, dissect_unknown},
15501   /* 0x88 */  {dissect_unknown, dissect_unknown},
15502   /* 0x89 */  {dissect_unknown, dissect_unknown},
15503   /* 0x8a */  {dissect_unknown, dissect_unknown},
15504   /* 0x8b */  {dissect_unknown, dissect_unknown},
15505   /* 0x8c */  {dissect_unknown, dissect_unknown},
15506   /* 0x8d */  {dissect_unknown, dissect_unknown},
15507   /* 0x8e */  {dissect_unknown, dissect_unknown},
15508   /* 0x8f */  {dissect_unknown, dissect_unknown},
15509
15510   /* 0x90 */  {dissect_unknown, dissect_unknown},
15511   /* 0x91 */  {dissect_unknown, dissect_unknown},
15512   /* 0x92 */  {dissect_unknown, dissect_unknown},
15513   /* 0x93 */  {dissect_unknown, dissect_unknown},
15514   /* 0x94 */  {dissect_unknown, dissect_unknown},
15515   /* 0x95 */  {dissect_unknown, dissect_unknown},
15516   /* 0x96 */  {dissect_unknown, dissect_unknown},
15517   /* 0x97 */  {dissect_unknown, dissect_unknown},
15518   /* 0x98 */  {dissect_unknown, dissect_unknown},
15519   /* 0x99 */  {dissect_unknown, dissect_unknown},
15520   /* 0x9a */  {dissect_unknown, dissect_unknown},
15521   /* 0x9b */  {dissect_unknown, dissect_unknown},
15522   /* 0x9c */  {dissect_unknown, dissect_unknown},
15523   /* 0x9d */  {dissect_unknown, dissect_unknown},
15524   /* 0x9e */  {dissect_unknown, dissect_unknown},
15525   /* 0x9f */  {dissect_unknown, dissect_unknown},
15526
15527   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
15528   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
15529   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
15530   /* 0xa3 */  {dissect_unknown, dissect_unknown},
15531   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
15532   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
15533   /* 0xa6 */  {dissect_unknown, dissect_unknown},
15534   /* 0xa7 */  {dissect_unknown, dissect_unknown},
15535   /* 0xa8 */  {dissect_unknown, dissect_unknown},
15536   /* 0xa9 */  {dissect_unknown, dissect_unknown},
15537   /* 0xaa */  {dissect_unknown, dissect_unknown},
15538   /* 0xab */  {dissect_unknown, dissect_unknown},
15539   /* 0xac */  {dissect_unknown, dissect_unknown},
15540   /* 0xad */  {dissect_unknown, dissect_unknown},
15541   /* 0xae */  {dissect_unknown, dissect_unknown},
15542   /* 0xaf */  {dissect_unknown, dissect_unknown},
15543
15544   /* 0xb0 */  {dissect_unknown, dissect_unknown},
15545   /* 0xb1 */  {dissect_unknown, dissect_unknown},
15546   /* 0xb2 */  {dissect_unknown, dissect_unknown},
15547   /* 0xb3 */  {dissect_unknown, dissect_unknown},
15548   /* 0xb4 */  {dissect_unknown, dissect_unknown},
15549   /* 0xb5 */  {dissect_unknown, dissect_unknown},
15550   /* 0xb6 */  {dissect_unknown, dissect_unknown},
15551   /* 0xb7 */  {dissect_unknown, dissect_unknown},
15552   /* 0xb8 */  {dissect_unknown, dissect_unknown},
15553   /* 0xb9 */  {dissect_unknown, dissect_unknown},
15554   /* 0xba */  {dissect_unknown, dissect_unknown},
15555   /* 0xbb */  {dissect_unknown, dissect_unknown},
15556   /* 0xbc */  {dissect_unknown, dissect_unknown},
15557   /* 0xbd */  {dissect_unknown, dissect_unknown},
15558   /* 0xbe */  {dissect_unknown, dissect_unknown},
15559   /* 0xbf */  {dissect_unknown, dissect_unknown},
15560
15561   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_open_print_file_response},
15562   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
15563   /* 0xc2 Close Print File*/  {dissect_close_print_file_request, dissect_empty},
15564   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
15565   /* 0xc4 */  {dissect_unknown, dissect_unknown},
15566   /* 0xc5 */  {dissect_unknown, dissect_unknown},
15567   /* 0xc6 */  {dissect_unknown, dissect_unknown},
15568   /* 0xc7 */  {dissect_unknown, dissect_unknown},
15569   /* 0xc8 */  {dissect_unknown, dissect_unknown},
15570   /* 0xc9 */  {dissect_unknown, dissect_unknown},
15571   /* 0xca */  {dissect_unknown, dissect_unknown},
15572   /* 0xcb */  {dissect_unknown, dissect_unknown},
15573   /* 0xcc */  {dissect_unknown, dissect_unknown},
15574   /* 0xcd */  {dissect_unknown, dissect_unknown},
15575   /* 0xce */  {dissect_unknown, dissect_unknown},
15576   /* 0xcf */  {dissect_unknown, dissect_unknown},
15577
15578   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
15579   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
15580   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
15581   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
15582   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
15583   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
15584   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
15585   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
15586   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
15587   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
15588   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
15589   /* 0xdb */  {dissect_unknown, dissect_unknown},
15590   /* 0xdc */  {dissect_unknown, dissect_unknown},
15591   /* 0xdd */  {dissect_unknown, dissect_unknown},
15592   /* 0xde */  {dissect_unknown, dissect_unknown},
15593   /* 0xdf */  {dissect_unknown, dissect_unknown},
15594
15595   /* 0xe0 */  {dissect_unknown, dissect_unknown},
15596   /* 0xe1 */  {dissect_unknown, dissect_unknown},
15597   /* 0xe2 */  {dissect_unknown, dissect_unknown},
15598   /* 0xe3 */  {dissect_unknown, dissect_unknown},
15599   /* 0xe4 */  {dissect_unknown, dissect_unknown},
15600   /* 0xe5 */  {dissect_unknown, dissect_unknown},
15601   /* 0xe6 */  {dissect_unknown, dissect_unknown},
15602   /* 0xe7 */  {dissect_unknown, dissect_unknown},
15603   /* 0xe8 */  {dissect_unknown, dissect_unknown},
15604   /* 0xe9 */  {dissect_unknown, dissect_unknown},
15605   /* 0xea */  {dissect_unknown, dissect_unknown},
15606   /* 0xeb */  {dissect_unknown, dissect_unknown},
15607   /* 0xec */  {dissect_unknown, dissect_unknown},
15608   /* 0xed */  {dissect_unknown, dissect_unknown},
15609   /* 0xee */  {dissect_unknown, dissect_unknown},
15610   /* 0xef */  {dissect_unknown, dissect_unknown},
15611
15612   /* 0xf0 */  {dissect_unknown, dissect_unknown},
15613   /* 0xf1 */  {dissect_unknown, dissect_unknown},
15614   /* 0xf2 */  {dissect_unknown, dissect_unknown},
15615   /* 0xf3 */  {dissect_unknown, dissect_unknown},
15616   /* 0xf4 */  {dissect_unknown, dissect_unknown},
15617   /* 0xf5 */  {dissect_unknown, dissect_unknown},
15618   /* 0xf6 */  {dissect_unknown, dissect_unknown},
15619   /* 0xf7 */  {dissect_unknown, dissect_unknown},
15620   /* 0xf8 */  {dissect_unknown, dissect_unknown},
15621   /* 0xf9 */  {dissect_unknown, dissect_unknown},
15622   /* 0xfa */  {dissect_unknown, dissect_unknown},
15623   /* 0xfb */  {dissect_unknown, dissect_unknown},
15624   /* 0xfc */  {dissect_unknown, dissect_unknown},
15625   /* 0xfd */  {dissect_unknown, dissect_unknown},
15626   /* 0xfe */  {dissect_unknown, dissect_unknown},
15627   /* 0xff */  {dissect_unknown, dissect_unknown},
15628 };
15629
15630 static int
15631 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
15632 {
15633         smb_info_t *si;
15634         smb_saved_info_t *sip;
15635
15636         si = pinfo->private_data;
15637         DISSECTOR_ASSERT(si);
15638
15639         if(cmd!=0xff){
15640                 proto_item *cmd_item;
15641                 proto_tree *cmd_tree;
15642                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
15643
15644                 if (check_col(pinfo->cinfo, COL_INFO)) {
15645                         if(first_pdu){
15646                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15647                                         "%s %s",
15648                                         decode_smb_name(cmd),
15649                                         (si->request)? "Request" : "Response");
15650                         } else {
15651                                 col_append_fstr(pinfo->cinfo, COL_INFO,
15652                                         "; %s",
15653                                         decode_smb_name(cmd));
15654                         }
15655
15656                 }
15657
15658                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
15659                         "%s %s (0x%02x)",
15660                         decode_smb_name(cmd),
15661                         (si->request)?"Request":"Response",
15662                         cmd);
15663
15664                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
15665
15666                 /* we track FIDs on a per transaction basis.
15667                    if this was a request and the fid was seen in a reply
15668                    we add a "generated" fid tree for this pdu and v.v.
15669                  */
15670                 sip = si->sip;
15671                 if (sip && sip->fid) {
15672                         if( (si->request && (!sip->fid_seen_in_request))
15673                           ||((!si->request) && sip->fid_seen_in_request) ){
15674                                 dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE);
15675                         }
15676                 }
15677
15678                 dissector = (si->request)?
15679                         smb_dissector[cmd].request:smb_dissector[cmd].response;
15680
15681                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
15682                 proto_item_set_end(cmd_item, tvb, offset);
15683         }
15684         return offset;
15685 }
15686
15687
15688 /* NOTE: this value_string array will also be used to access data directly by
15689  * index instead of val_to_str() since
15690  * 1, the array will always span every value from 0x00 to 0xff and
15691  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
15692  * This means that this value_string array MUST always
15693  * 1, contain all entries 0x00 to 0xff
15694  * 2, all entries must be in order.
15695  */
15696 const value_string smb_cmd_vals[] = {
15697   { 0x00, "Create Directory" },
15698   { 0x01, "Delete Directory" },
15699   { 0x02, "Open" },
15700   { 0x03, "Create" },
15701   { 0x04, "Close" },
15702   { 0x05, "Flush" },
15703   { 0x06, "Delete" },
15704   { 0x07, "Rename" },
15705   { 0x08, "Query Information" },
15706   { 0x09, "Set Information" },
15707   { 0x0A, "Read" },
15708   { 0x0B, "Write" },
15709   { 0x0C, "Lock Byte Range" },
15710   { 0x0D, "Unlock Byte Range" },
15711   { 0x0E, "Create Temp" },
15712   { 0x0F, "Create New" },
15713   { 0x10, "Check Directory" },
15714   { 0x11, "Process Exit" },
15715   { 0x12, "Seek" },
15716   { 0x13, "Lock And Read" },
15717   { 0x14, "Write And Unlock" },
15718   { 0x15, "unknown-0x15" },
15719   { 0x16, "unknown-0x16" },
15720   { 0x17, "unknown-0x17" },
15721   { 0x18, "unknown-0x18" },
15722   { 0x19, "unknown-0x19" },
15723   { 0x1A, "Read Raw" },
15724   { 0x1B, "Read MPX" },
15725   { 0x1C, "Read MPX Secondary" },
15726   { 0x1D, "Write Raw" },
15727   { 0x1E, "Write MPX" },
15728   { 0x1F, "Write MPX Secondary" },
15729   { 0x20, "Write Complete" },
15730   { 0x21, "unknown-0x21" },
15731   { 0x22, "Set Information2" },
15732   { 0x23, "Query Information2" },
15733   { 0x24, "Locking AndX" },
15734   { 0x25, "Trans" },
15735   { 0x26, "Trans Secondary" },
15736   { 0x27, "IOCTL" },
15737   { 0x28, "IOCTL Secondary" },
15738   { 0x29, "Copy" },
15739   { 0x2A, "Move" },
15740   { 0x2B, "Echo" },
15741   { 0x2C, "Write And Close" },
15742   { 0x2D, "Open AndX" },
15743   { 0x2E, "Read AndX" },
15744   { 0x2F, "Write AndX" },
15745   { 0x30, "unknown-0x30" },
15746   { 0x31, "Close And Tree Disconnect" },
15747   { 0x32, "Trans2" },
15748   { 0x33, "Trans2 Secondary" },
15749   { 0x34, "Find Close2" },
15750   { 0x35, "Find Notify Close" },
15751   { 0x36, "unknown-0x36" },
15752   { 0x37, "unknown-0x37" },
15753   { 0x38, "unknown-0x38" },
15754   { 0x39, "unknown-0x39" },
15755   { 0x3A, "unknown-0x3A" },
15756   { 0x3B, "unknown-0x3B" },
15757   { 0x3C, "unknown-0x3C" },
15758   { 0x3D, "unknown-0x3D" },
15759   { 0x3E, "unknown-0x3E" },
15760   { 0x3F, "unknown-0x3F" },
15761   { 0x40, "unknown-0x40" },
15762   { 0x41, "unknown-0x41" },
15763   { 0x42, "unknown-0x42" },
15764   { 0x43, "unknown-0x43" },
15765   { 0x44, "unknown-0x44" },
15766   { 0x45, "unknown-0x45" },
15767   { 0x46, "unknown-0x46" },
15768   { 0x47, "unknown-0x47" },
15769   { 0x48, "unknown-0x48" },
15770   { 0x49, "unknown-0x49" },
15771   { 0x4A, "unknown-0x4A" },
15772   { 0x4B, "unknown-0x4B" },
15773   { 0x4C, "unknown-0x4C" },
15774   { 0x4D, "unknown-0x4D" },
15775   { 0x4E, "unknown-0x4E" },
15776   { 0x4F, "unknown-0x4F" },
15777   { 0x50, "unknown-0x50" },
15778   { 0x51, "unknown-0x51" },
15779   { 0x52, "unknown-0x52" },
15780   { 0x53, "unknown-0x53" },
15781   { 0x54, "unknown-0x54" },
15782   { 0x55, "unknown-0x55" },
15783   { 0x56, "unknown-0x56" },
15784   { 0x57, "unknown-0x57" },
15785   { 0x58, "unknown-0x58" },
15786   { 0x59, "unknown-0x59" },
15787   { 0x5A, "unknown-0x5A" },
15788   { 0x5B, "unknown-0x5B" },
15789   { 0x5C, "unknown-0x5C" },
15790   { 0x5D, "unknown-0x5D" },
15791   { 0x5E, "unknown-0x5E" },
15792   { 0x5F, "unknown-0x5F" },
15793   { 0x60, "unknown-0x60" },
15794   { 0x61, "unknown-0x61" },
15795   { 0x62, "unknown-0x62" },
15796   { 0x63, "unknown-0x63" },
15797   { 0x64, "unknown-0x64" },
15798   { 0x65, "unknown-0x65" },
15799   { 0x66, "unknown-0x66" },
15800   { 0x67, "unknown-0x67" },
15801   { 0x68, "unknown-0x68" },
15802   { 0x69, "unknown-0x69" },
15803   { 0x6A, "unknown-0x6A" },
15804   { 0x6B, "unknown-0x6B" },
15805   { 0x6C, "unknown-0x6C" },
15806   { 0x6D, "unknown-0x6D" },
15807   { 0x6E, "unknown-0x6E" },
15808   { 0x6F, "unknown-0x6F" },
15809   { 0x70, "Tree Connect" },
15810   { 0x71, "Tree Disconnect" },
15811   { 0x72, "Negotiate Protocol" },
15812   { 0x73, "Session Setup AndX" },
15813   { 0x74, "Logoff AndX" },
15814   { 0x75, "Tree Connect AndX" },
15815   { 0x76, "unknown-0x76" },
15816   { 0x77, "unknown-0x77" },
15817   { 0x78, "unknown-0x78" },
15818   { 0x79, "unknown-0x79" },
15819   { 0x7A, "unknown-0x7A" },
15820   { 0x7B, "unknown-0x7B" },
15821   { 0x7C, "unknown-0x7C" },
15822   { 0x7D, "unknown-0x7D" },
15823   { 0x7E, "unknown-0x7E" },
15824   { 0x7F, "unknown-0x7F" },
15825   { 0x80, "Query Information Disk" },
15826   { 0x81, "Search" },
15827   { 0x82, "Find" },
15828   { 0x83, "Find Unique" },
15829   { 0x84, "Find Close" },
15830   { 0x85, "unknown-0x85" },
15831   { 0x86, "unknown-0x86" },
15832   { 0x87, "unknown-0x87" },
15833   { 0x88, "unknown-0x88" },
15834   { 0x89, "unknown-0x89" },
15835   { 0x8A, "unknown-0x8A" },
15836   { 0x8B, "unknown-0x8B" },
15837   { 0x8C, "unknown-0x8C" },
15838   { 0x8D, "unknown-0x8D" },
15839   { 0x8E, "unknown-0x8E" },
15840   { 0x8F, "unknown-0x8F" },
15841   { 0x90, "unknown-0x90" },
15842   { 0x91, "unknown-0x91" },
15843   { 0x92, "unknown-0x92" },
15844   { 0x93, "unknown-0x93" },
15845   { 0x94, "unknown-0x94" },
15846   { 0x95, "unknown-0x95" },
15847   { 0x96, "unknown-0x96" },
15848   { 0x97, "unknown-0x97" },
15849   { 0x98, "unknown-0x98" },
15850   { 0x99, "unknown-0x99" },
15851   { 0x9A, "unknown-0x9A" },
15852   { 0x9B, "unknown-0x9B" },
15853   { 0x9C, "unknown-0x9C" },
15854   { 0x9D, "unknown-0x9D" },
15855   { 0x9E, "unknown-0x9E" },
15856   { 0x9F, "unknown-0x9F" },
15857   { 0xA0, "NT Trans" },
15858   { 0xA1, "NT Trans Secondary" },
15859   { 0xA2, "NT Create AndX" },
15860   { 0xA3, "unknown-0xA3" },
15861   { 0xA4, "NT Cancel" },
15862   { 0xA5, "NT Rename" },
15863   { 0xA6, "unknown-0xA6" },
15864   { 0xA7, "unknown-0xA7" },
15865   { 0xA8, "unknown-0xA8" },
15866   { 0xA9, "unknown-0xA9" },
15867   { 0xAA, "unknown-0xAA" },
15868   { 0xAB, "unknown-0xAB" },
15869   { 0xAC, "unknown-0xAC" },
15870   { 0xAD, "unknown-0xAD" },
15871   { 0xAE, "unknown-0xAE" },
15872   { 0xAF, "unknown-0xAF" },
15873   { 0xB0, "unknown-0xB0" },
15874   { 0xB1, "unknown-0xB1" },
15875   { 0xB2, "unknown-0xB2" },
15876   { 0xB3, "unknown-0xB3" },
15877   { 0xB4, "unknown-0xB4" },
15878   { 0xB5, "unknown-0xB5" },
15879   { 0xB6, "unknown-0xB6" },
15880   { 0xB7, "unknown-0xB7" },
15881   { 0xB8, "unknown-0xB8" },
15882   { 0xB9, "unknown-0xB9" },
15883   { 0xBA, "unknown-0xBA" },
15884   { 0xBB, "unknown-0xBB" },
15885   { 0xBC, "unknown-0xBC" },
15886   { 0xBD, "unknown-0xBD" },
15887   { 0xBE, "unknown-0xBE" },
15888   { 0xBF, "unknown-0xBF" },
15889   { 0xC0, "Open Print File" },
15890   { 0xC1, "Write Print File" },
15891   { 0xC2, "Close Print File" },
15892   { 0xC3, "Get Print Queue" },
15893   { 0xC4, "unknown-0xC4" },
15894   { 0xC5, "unknown-0xC5" },
15895   { 0xC6, "unknown-0xC6" },
15896   { 0xC7, "unknown-0xC7" },
15897   { 0xC8, "unknown-0xC8" },
15898   { 0xC9, "unknown-0xC9" },
15899   { 0xCA, "unknown-0xCA" },
15900   { 0xCB, "unknown-0xCB" },
15901   { 0xCC, "unknown-0xCC" },
15902   { 0xCD, "unknown-0xCD" },
15903   { 0xCE, "unknown-0xCE" },
15904   { 0xCF, "unknown-0xCF" },
15905   { 0xD0, "Send Single Block Message" },
15906   { 0xD1, "Send Broadcast Message" },
15907   { 0xD2, "Forward User Name" },
15908   { 0xD3, "Cancel Forward" },
15909   { 0xD4, "Get Machine Name" },
15910   { 0xD5, "Send Start of Multi-block Message" },
15911   { 0xD6, "Send End of Multi-block Message" },
15912   { 0xD7, "Send Text of Multi-block Message" },
15913   { 0xD8, "SMBreadbulk" },
15914   { 0xD9, "SMBwritebulk" },
15915   { 0xDA, "SMBwritebulkdata" },
15916   { 0xDB, "unknown-0xDB" },
15917   { 0xDC, "unknown-0xDC" },
15918   { 0xDD, "unknown-0xDD" },
15919   { 0xDE, "unknown-0xDE" },
15920   { 0xDF, "unknown-0xDF" },
15921   { 0xE0, "unknown-0xE0" },
15922   { 0xE1, "unknown-0xE1" },
15923   { 0xE2, "unknown-0xE2" },
15924   { 0xE3, "unknown-0xE3" },
15925   { 0xE4, "unknown-0xE4" },
15926   { 0xE5, "unknown-0xE5" },
15927   { 0xE6, "unknown-0xE6" },
15928   { 0xE7, "unknown-0xE7" },
15929   { 0xE8, "unknown-0xE8" },
15930   { 0xE9, "unknown-0xE9" },
15931   { 0xEA, "unknown-0xEA" },
15932   { 0xEB, "unknown-0xEB" },
15933   { 0xEC, "unknown-0xEC" },
15934   { 0xED, "unknown-0xED" },
15935   { 0xEE, "unknown-0xEE" },
15936   { 0xEF, "unknown-0xEF" },
15937   { 0xF0, "unknown-0xF0" },
15938   { 0xF1, "unknown-0xF1" },
15939   { 0xF2, "unknown-0xF2" },
15940   { 0xF3, "unknown-0xF3" },
15941   { 0xF4, "unknown-0xF4" },
15942   { 0xF5, "unknown-0xF5" },
15943   { 0xF6, "unknown-0xF6" },
15944   { 0xF7, "unknown-0xF7" },
15945   { 0xF8, "unknown-0xF8" },
15946   { 0xF9, "unknown-0xF9" },
15947   { 0xFA, "unknown-0xFA" },
15948   { 0xFB, "unknown-0xFB" },
15949   { 0xFC, "unknown-0xFC" },
15950   { 0xFD, "unknown-0xFD" },
15951   { 0xFE, "SMBinvalid" },
15952   { 0xFF, "unknown-0xFF" },
15953   { 0x00, NULL },
15954 };
15955
15956 static const char *decode_smb_name(guint8 cmd)
15957 {
15958   return(smb_cmd_vals[cmd].strptr);
15959 }
15960
15961
15962
15963 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15964  * Everything TVBUFFIFIED above this line
15965  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15966
15967
15968 static void
15969 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
15970 {
15971         conv_tables_t *ct = ctarg;
15972
15973         if (ct->unmatched)
15974                 g_hash_table_destroy(ct->unmatched);
15975         if (ct->matched)
15976                 g_hash_table_destroy(ct->matched);
15977         if (ct->tid_service)
15978                 g_hash_table_destroy(ct->tid_service);
15979         g_free(ct);
15980 }
15981
15982 static void
15983 smb_init_protocol(void)
15984 {
15985         /*
15986          * Free the hash tables attached to the conversation table
15987          * structures, and then free the list of conversation table
15988          * data structures.
15989          */
15990         if (conv_tables) {
15991                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
15992                 g_slist_free(conv_tables);
15993                 conv_tables = NULL;
15994         }
15995 }
15996
15997 static const value_string errcls_types[] = {
15998   { SMB_SUCCESS, "Success"},
15999   { SMB_ERRDOS, "DOS Error"},
16000   { SMB_ERRSRV, "Server Error"},
16001   { SMB_ERRHRD, "Hardware Error"},
16002   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
16003   { 0, NULL }
16004 };
16005
16006 /* Error codes for the ERRSRV class */
16007
16008 static const value_string SRV_errors[] = {
16009   {SMBE_error, "Non specific error code"},
16010   {SMBE_badpw, "Bad password"},
16011   {SMBE_badtype, "Reserved"},
16012   {SMBE_access, "No permissions to perform the requested operation"},
16013   {SMBE_invnid, "TID invalid"},
16014   {SMBE_invnetname, "Invalid network name. Service not found"},
16015   {SMBE_invdevice, "Invalid device"},
16016   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
16017   {SMBE_qfull, "Print queue full"},
16018   {SMBE_qtoobig, "Queued item too big"},
16019   {SMBE_qeof, "EOF on print queue dump"},
16020   {SMBE_invpfid, "Invalid print file in smb_fid"},
16021   {SMBE_smbcmd, "Unrecognised command"},
16022   {SMBE_srverror, "SMB server internal error"},
16023   {SMBE_filespecs, "Fid and pathname invalid combination"},
16024   {SMBE_badlink, "Bad link in request ???"},
16025   {SMBE_badpermits, "Access specified for a file is not valid"},
16026   {SMBE_badpid, "Bad process id in request"},
16027   {SMBE_setattrmode, "Attribute mode invalid"},
16028   {SMBE_paused, "Message server paused"},
16029   {SMBE_msgoff, "Not receiving messages"},
16030   {SMBE_noroom, "No room for message"},
16031   {SMBE_rmuns, "Too many remote usernames"},
16032   {SMBE_timeout, "Operation timed out"},
16033   {SMBE_noresource, "No resources currently available for request."},
16034   {SMBE_toomanyuids, "Too many userids"},
16035   {SMBE_baduid, "Bad userid"},
16036   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
16037   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
16038   {SMBE_contMPX, "Resume MPX mode"},
16039   {SMBE_badPW, "Bad Password???"},
16040   {SMBE_nosupport, "Operation not supported"},
16041   { 0, NULL}
16042 };
16043
16044 /* Error codes for the ERRHRD class */
16045
16046 static const value_string HRD_errors[] = {
16047   {SMBE_nowrite, "Read only media"},
16048   {SMBE_badunit, "Unknown device"},
16049   {SMBE_notready, "Drive not ready"},
16050   {SMBE_badcmd, "Unknown command"},
16051   {SMBE_data, "Data (CRC) error"},
16052   {SMBE_badreq, "Bad request structure length"},
16053   {SMBE_seek, "Seek error"},
16054   {SMBE_badmedia, "Unknown media type"},
16055   {SMBE_badsector, "Sector not found"},
16056   {SMBE_nopaper, "Printer out of paper"},
16057   {SMBE_write, "Write fault"},
16058   {SMBE_read, "Read fault"},
16059   {SMBE_general, "General failure"},
16060   {SMBE_badshare, "A open conflicts with an existing open"},
16061   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
16062   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
16063   {SMBE_FCBunavail, "No FCBs are available to process request"},
16064   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
16065   {SMBE_diskfull, "Disk full???"},
16066   {0, NULL}
16067 };
16068
16069 static const char *decode_smb_error(guint8 errcls, guint16 errcode)
16070 {
16071
16072   switch (errcls) {
16073
16074   case SMB_SUCCESS:
16075
16076     return("No Error");   /* No error ??? */
16077
16078   case SMB_ERRDOS:
16079
16080     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
16081
16082   case SMB_ERRSRV:
16083
16084     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
16085
16086   case SMB_ERRHRD:
16087
16088     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
16089
16090   default:
16091
16092     return("Unknown error class!");
16093
16094   }
16095
16096 }
16097
16098 static const true_false_string tfs_smb_flags_lock = {
16099         "Lock&Read, Write&Unlock are supported",
16100         "Lock&Read, Write&Unlock are not supported"
16101 };
16102 static const true_false_string tfs_smb_flags_receive_buffer = {
16103         "Receive buffer has been posted",
16104         "Receive buffer has not been posted"
16105 };
16106 static const true_false_string tfs_smb_flags_caseless = {
16107         "Path names are caseless",
16108         "Path names are case sensitive"
16109 };
16110 static const true_false_string tfs_smb_flags_canon = {
16111         "Pathnames are canonicalized",
16112         "Pathnames are not canonicalized"
16113 };
16114 static const true_false_string tfs_smb_flags_oplock = {
16115         "OpLock requested/granted",
16116         "OpLock not requested/granted"
16117 };
16118 static const true_false_string tfs_smb_flags_notify = {
16119         "Notify client on all modifications",
16120         "Notify client only on open"
16121 };
16122 static const true_false_string tfs_smb_flags_response = {
16123         "Message is a response to the client/redirector",
16124         "Message is a request to the server"
16125 };
16126
16127 static int
16128 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16129 {
16130         guint8 mask;
16131         proto_item *item;
16132         proto_tree *tree;
16133
16134         mask = tvb_get_guint8(tvb, offset);
16135
16136         if(parent_tree){
16137                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16138                         "Flags: 0x%02x", mask);
16139                 tree = proto_item_add_subtree(item, ett_smb_flags);
16140
16141                 proto_tree_add_boolean(tree, hf_smb_flags_response,
16142                         tvb, offset, 1, mask);
16143                 proto_tree_add_boolean(tree, hf_smb_flags_notify,
16144                         tvb, offset, 1, mask);
16145                 proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16146                         tvb, offset, 1, mask);
16147                 proto_tree_add_boolean(tree, hf_smb_flags_canon,
16148                         tvb, offset, 1, mask);
16149                 proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16150                         tvb, offset, 1, mask);
16151                 proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16152                         tvb, offset, 1, mask);
16153                 proto_tree_add_boolean(tree, hf_smb_flags_lock,
16154                         tvb, offset, 1, mask);
16155         }
16156
16157         offset += 1;
16158         return offset;
16159 }
16160
16161
16162
16163 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16164         "Long file names are allowed in the response",
16165         "Long file names are not allowed in the response"
16166 };
16167 static const true_false_string tfs_smb_flags2_ea = {
16168         "Extended attributes are supported",
16169         "Extended attributes are not supported"
16170 };
16171 static const true_false_string tfs_smb_flags2_sec_sig = {
16172         "Security signatures are supported",
16173         "Security signatures are not supported"
16174 };
16175 static const true_false_string tfs_smb_flags2_long_names_used = {
16176         "Path names in request are long file names",
16177         "Path names in request are not long file names"
16178 };
16179 static const true_false_string tfs_smb_flags2_esn = {
16180         "Extended security negotiation is supported",
16181         "Extended security negotiation is not supported"
16182 };
16183 static const true_false_string tfs_smb_flags2_dfs = {
16184         "Resolve pathnames with Dfs",
16185         "Don't resolve pathnames with Dfs"
16186 };
16187 static const true_false_string tfs_smb_flags2_roe = {
16188         "Permit reads if execute-only",
16189         "Don't permit reads if execute-only"
16190 };
16191 static const true_false_string tfs_smb_flags2_nt_error = {
16192         "Error codes are NT error codes",
16193         "Error codes are DOS error codes"
16194 };
16195 static const true_false_string tfs_smb_flags2_string = {
16196         "Strings are Unicode",
16197         "Strings are ASCII"
16198 };
16199 static int
16200 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16201 {
16202         guint16 mask;
16203         proto_item *item;
16204         proto_tree *tree;
16205
16206         mask = tvb_get_letohs(tvb, offset);
16207
16208         if(parent_tree){
16209                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16210                         "Flags2: 0x%04x", mask);
16211                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16212
16213                 proto_tree_add_boolean(tree, hf_smb_flags2_string,
16214                         tvb, offset, 2, mask);
16215                 proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16216                         tvb, offset, 2, mask);
16217                 proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16218                         tvb, offset, 2, mask);
16219                 proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16220                         tvb, offset, 2, mask);
16221                 proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16222                         tvb, offset, 2, mask);
16223                 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16224                         tvb, offset, 2, mask);
16225                 proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16226                         tvb, offset, 2, mask);
16227                 proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16228                         tvb, offset, 2, mask);
16229                 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16230                         tvb, offset, 2, mask);
16231         }
16232         offset += 2;
16233         return offset;
16234 }
16235
16236
16237
16238 #define SMB_FLAGS_DIRN 0x80
16239
16240
16241 static void
16242 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16243 {
16244         int offset = 0;
16245         proto_item *item = NULL, *hitem = NULL;
16246         proto_tree *tree = NULL, *htree = NULL;
16247         proto_item *tmp_item=NULL;
16248         guint8          flags;
16249         guint16         flags2;
16250         smb_info_t              *si;
16251         smb_saved_info_t *sip = NULL;
16252         smb_saved_info_key_t key;
16253         smb_saved_info_key_t *new_key;
16254         guint8 errclass = 0;
16255         guint16 errcode = 0;
16256         guint32 pid_mid;
16257         conversation_t *conversation;
16258         nstime_t t, deltat;
16259
16260         si=ep_alloc0(sizeof(smb_info_t));
16261
16262         top_tree=parent_tree;
16263
16264         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
16265                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16266         }
16267         if (check_col(pinfo->cinfo, COL_INFO)){
16268                 col_clear(pinfo->cinfo, COL_INFO);
16269         }
16270
16271         /* start off using the local variable, we will allocate a new one if we
16272            need to*/
16273         si->cmd = tvb_get_guint8(tvb, offset+4);
16274         flags = tvb_get_guint8(tvb, offset+9);
16275         /*
16276          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16277          * the direction flag appears never to be set, even for what appear
16278          * to be replies.  Do some SMB servers fail to set that flag,
16279          * under the assumption that the client knows it's a reply because
16280          * it received it?
16281          */
16282         si->request = !(flags&SMB_FLAGS_DIRN);
16283         flags2 = tvb_get_letohs(tvb, offset+10);
16284         if(flags2 & 0x8000){
16285                 si->unicode = TRUE; /* Mark them as Unicode */
16286         } else {
16287                 si->unicode = FALSE;
16288         }
16289         si->tid = tvb_get_letohs(tvb, offset+24);
16290         si->pid = tvb_get_letohs(tvb, offset+26);
16291         si->uid = tvb_get_letohs(tvb, offset+28);
16292         si->mid = tvb_get_letohs(tvb, offset+30);
16293         pid_mid = (si->pid << 16) | si->mid;
16294         si->info_level = -1;
16295         si->info_count = -1;
16296
16297         if (parent_tree) {
16298                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16299                         -1, FALSE);
16300                 tree = proto_item_add_subtree(item, ett_smb);
16301
16302                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16303                         "SMB Header");
16304
16305                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16306         }
16307
16308         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16309         offset += 4;  /* Skip the marker */
16310
16311         /* find which conversation we are part of and get the tables for that
16312            conversation*/
16313         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
16314                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16315         if(!conversation){
16316                 /* OK this is a new conversation so lets create it */
16317                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
16318                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16319         }
16320         /* see if we already have the smb data for this conversation */
16321         si->ct=conversation_get_proto_data(conversation, proto_smb);
16322         if(!si->ct){
16323                 /* No, not yet. create it and attach it to the conversation */
16324                 si->ct = g_malloc(sizeof(conv_tables_t));
16325
16326                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16327                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16328                         smb_saved_info_equal_matched);
16329                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16330                         smb_saved_info_equal_unmatched);
16331                 si->ct->tid_service=g_hash_table_new(
16332                         smb_saved_info_hash_unmatched,
16333                         smb_saved_info_equal_unmatched);
16334                 si->ct->raw_ntlmssp = 0;
16335
16336                 si->ct->fid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB fid_tree");
16337                 si->ct->tid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB tid_tree");
16338                 si->ct->uid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB uid_tree");
16339                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16340         }
16341
16342         if( (si->request)
16343             &&  (si->mid==0)
16344             &&  (si->uid==0)
16345             &&  (si->pid==0)
16346             &&  (si->tid==0) ){
16347                 /* this is a broadcast SMB packet, there will not be a reply.
16348                    We dont need to do anything
16349                 */
16350                 si->unidir = TRUE;
16351         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16352                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16353                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16354                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16355                 /* Ok, we got a special request type. This request is either
16356                    an NT Cancel or a continuation relative to a real request
16357                    in an earlier packet.  In either case, we don't expect any
16358                    responses to this packet.  For continuations, any later
16359                    responses we see really just belong to the original request.
16360                    Anyway, we want to remember this packet somehow and
16361                    remember which original request it is associated with so
16362                    we can say nice things such as "This is a Cancellation to
16363                    the request in frame x", but we don't want the
16364                    request/response matching to get messed up.
16365
16366                    The only thing we do in this case is trying to find which original
16367                    request we match with and insert an entry for this "special"
16368                    request for later reference. We continue to reference the original
16369                    requests smb_saved_info_t but we dont touch it or change anything
16370                    in it.
16371                 */
16372
16373                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16374
16375                 if(!pinfo->fd->flags.visited){
16376                         /* try to find which original call we match and if we
16377                            find it add us to the matched table. Dont touch
16378                            anything else since we dont want this one to mess
16379                            up the request/response matching. We still consider
16380                            the initial call the real request and this is only
16381                            some sort of continuation.
16382                         */
16383                         /* we only check the unmatched table and assume that the
16384                            last seen MID matching ours is the right one.
16385                            This can fail but is better than nothing
16386                         */
16387                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16388                         if(sip!=NULL){
16389                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16390                                 new_key->frame = pinfo->fd->num;
16391                                 new_key->pid_mid = pid_mid;
16392                                 g_hash_table_insert(si->ct->matched, new_key,
16393                                     sip);
16394                         }
16395                 } else {
16396                         /* we have seen this packet before; check the
16397                            matching table
16398                         */
16399                         key.frame = pinfo->fd->num;
16400                         key.pid_mid = pid_mid;
16401                         sip=g_hash_table_lookup(si->ct->matched, &key);
16402                         if(sip==NULL){
16403                         /*
16404                           We didn't find it.
16405                           Too bad, unfortunately there is not really much we can
16406                           do now since this means that we never saw the initial
16407                           request.
16408                          */
16409                         }
16410                 }
16411
16412
16413                 if(sip && sip->frame_req){
16414                         switch(si->cmd){
16415                         case SMB_COM_NT_CANCEL:
16416                                 tmp_item=proto_tree_add_uint(htree, hf_smb_cancel_to,
16417                                                     tvb, 0, 0, sip->frame_req);
16418                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16419                                 break;
16420                         case SMB_COM_TRANSACTION_SECONDARY:
16421                         case SMB_COM_TRANSACTION2_SECONDARY:
16422                         case SMB_COM_NT_TRANSACT_SECONDARY:
16423                                 tmp_item=proto_tree_add_uint(htree, hf_smb_continuation_to,
16424                                                     tvb, 0, 0, sip->frame_req);
16425                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16426                                 break;
16427                         }
16428                 } else {
16429                         switch(si->cmd){
16430                         case SMB_COM_NT_CANCEL:
16431                                 proto_tree_add_text(htree, tvb, 0, 0,
16432                                                     "Cancellation to: <unknown frame>");
16433                                 break;
16434                         case SMB_COM_TRANSACTION_SECONDARY:
16435                         case SMB_COM_TRANSACTION2_SECONDARY:
16436                         case SMB_COM_NT_TRANSACT_SECONDARY:
16437                                 proto_tree_add_text(htree, tvb, 0, 0,
16438                                                     "Continuation to: <unknown frame>");
16439                                 break;
16440                         }
16441                 }
16442         } else { /* normal bidirectional request or response */
16443                 si->unidir = FALSE;
16444
16445                 if(!pinfo->fd->flags.visited){
16446                         /* first see if we find an unmatched smb "equal" to
16447                            the current one
16448                         */
16449                         sip=g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16450                         if(sip!=NULL){
16451                                 gboolean cmd_match=FALSE;
16452
16453                                 /*
16454                                  * Make sure the SMB we found was the
16455                                  * same command, or a different command
16456                                  * that's another valid type of reply
16457                                  * to that command.
16458                                  */
16459                                 if(si->cmd==sip->cmd){
16460                                         cmd_match=TRUE;
16461                                 }
16462                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16463                                         cmd_match=TRUE;
16464                                 }
16465                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16466                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16467                                         cmd_match=TRUE;
16468                                 }
16469                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16470                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16471                                         cmd_match=TRUE;
16472                                 }
16473                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16474                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16475                                         cmd_match=TRUE;
16476                                 }
16477
16478                                 if( (si->request) || (!cmd_match) ) {
16479                                         /* We are processing an SMB request but there was already
16480                                            another "identical" smb request we had not matched yet.
16481                                            This must mean that either we have a retransmission or that the
16482                                            response to the previous one was lost and the client has reused
16483                                            the MID for this conversation. In either case it's not much more
16484                                            we can do than forget the old request and concentrate on the
16485                                            present one instead.
16486
16487                                            We also do this cleanup if we see that the cmd in the original
16488                                            request in sip->cmd is not compatible with the current cmd.
16489                                            This is to prevent matching errors such as if there were two
16490                                            SMBs of different cmds but with identical MID and PID values and
16491                                            if wireshark lost the first reply and the second request.
16492                                         */
16493                                         g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16494                                         sip=NULL; /* XXX should free it as well */
16495                                 } else {
16496                                         /* we have found a response to some
16497                                            request we have seen earlier.
16498                                            What we do now depends on whether
16499                                            this is the first response to that
16500                                            request we see (id frame_res==0) or
16501                                            if it's a response to a request
16502                                            for which we've seen an earlier
16503                                            response that's continued.
16504                                         */
16505                                         if(sip->frame_res==0 ||
16506                                            sip->flags & SMB_SIF_IS_CONTINUED){
16507                                                 /* OK, it is the first response
16508                                                    we have seen to this packet,
16509                                                    or it's a continuation of
16510                                                    a response we've seen. */
16511                                                 sip->frame_res = pinfo->fd->num;
16512                                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16513                                                 new_key->frame = sip->frame_res;
16514                                                 new_key->pid_mid = pid_mid;
16515                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16516                                                 /* We remove the entry for unmatched since we have found a match.
16517                                                  * We have to do this since the MID value wraps so quickly (effective only 10 bits)
16518                                                  * and if there is packetloss in the trace (maybe due to large holes
16519                                                  * created by a sniffer device not being able to keep up
16520                                                  * with the line rate.
16521                                                  * There is a real possibility that the following would occur which is painful :
16522                                                  * 1, -> Request  MID:5
16523                                                  * 2, <- Response MID:5
16524                                                  *   3, ->Request  MID:5 (missing from capture)
16525                                                  * 4, <- Response MID:5
16526                                                  * We DONT want #4 to be presented as a response to #1
16527                                                  */
16528                                                 g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
16529                                         } else {
16530                                                 /* We have already seen another response to this MID.
16531                                                    Since the MID in reality is only something like 10 bits
16532                                                    this probably means that we just have a MID that is being
16533                                                    reused due to the small MID space and that this is a new
16534                                                    command we did not see the original request for.
16535                                                 */
16536                                                 sip=NULL;
16537                                         }
16538                                 }
16539                         }
16540                         if(si->request){
16541                                 sip = se_alloc(sizeof(smb_saved_info_t));
16542                                 sip->frame_req = pinfo->fd->num;
16543                                 sip->frame_res = 0;
16544                                 sip->req_time = pinfo->fd->abs_ts;
16545                                 sip->flags = 0;
16546                                 if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))
16547                                     == (void *)TID_IPC) {
16548                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16549                                 }
16550                                 sip->cmd = si->cmd;
16551                                 sip->extra_info = NULL;
16552                                 sip->extra_info_type = SMB_EI_NONE;
16553                                 sip->fid=0;
16554                                 sip->fid_seen_in_request=0;
16555                                 g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
16556                                 new_key = se_alloc(sizeof(smb_saved_info_key_t));
16557                                 new_key->frame = sip->frame_req;
16558                                 new_key->pid_mid = pid_mid;
16559                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16560                         }
16561                 } else {
16562                         /* we have seen this packet before; check the
16563                            matching table.
16564                            If we haven't yet seen the reply, we won't
16565                            find the info for it; we don't need it, as
16566                            we only use it to save information, and, as
16567                            we've seen this packet before, we've already
16568                            saved the information.
16569                         */
16570                         key.frame = pinfo->fd->num;
16571                         key.pid_mid = pid_mid;
16572                         sip=g_hash_table_lookup(si->ct->matched, &key);
16573                 }
16574         }
16575
16576         /*
16577          * Pass the "sip" on to subdissectors through "si".
16578          */
16579         si->sip = sip;
16580
16581         if (sip != NULL) {
16582                 /*
16583                  * Put in fields for the frame number of the frame to which
16584                  * this is a response or the frame with the response to this
16585                  * frame - if we know the frame number (i.e., it's not 0).
16586                  */
16587                 if(si->request){
16588                         if (sip->frame_res != 0) {
16589                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16590                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16591                         }
16592                 } else {
16593                         if (sip->frame_req != 0) {
16594                                 tmp_item=proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16595                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16596                                 t = pinfo->fd->abs_ts;
16597                                 nstime_delta(&deltat, &t, &sip->req_time);
16598                                 tmp_item=proto_tree_add_time(htree, hf_smb_time, tvb,
16599                                     0, 0, &deltat);
16600                                 PROTO_ITEM_SET_GENERATED(tmp_item);
16601                         }
16602                 }
16603         }
16604
16605         /* smb command */
16606         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);
16607         offset += 1;
16608
16609         if(flags2 & 0x4000){
16610                 /* handle NT 32 bit error code */
16611
16612                 si->nt_status = tvb_get_letohl(tvb, offset);
16613
16614                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16615                         TRUE);
16616                 offset += 4;
16617
16618         } else {
16619                 /* handle DOS error code & class */
16620                 errclass = tvb_get_guint8(tvb, offset);
16621                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16622                         errclass);
16623                 offset += 1;
16624
16625                 /* reserved byte */
16626                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16627                 offset += 1;
16628
16629                 /* error code */
16630                 /* XXX - the type of this field depends on the value of
16631                  * "errcls", so there is isn't a single value_string array
16632                  * fo it, so there can't be a single field for it.
16633                  */
16634                 errcode = tvb_get_letohs(tvb, offset);
16635                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16636                         offset, 2, errcode, "Error Code: %s",
16637                         decode_smb_error(errclass, errcode));
16638                 offset += 2;
16639         }
16640
16641         /* flags */
16642         offset = dissect_smb_flags(tvb, htree, offset);
16643
16644         /* flags2 */
16645         offset = dissect_smb_flags2(tvb, htree, offset);
16646
16647         /*
16648          * The document at
16649          *
16650          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16651          *
16652          * (a text version of "Microsoft Networks SMB FILE SHARING
16653          * PROTOCOL, Document Version 6.0p") says that:
16654          *
16655          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16656          *      the "High Part of PID";
16657          *
16658          *      the next four bytes are reserved;
16659          *
16660          *      the next four bytes are, for SMB-over-IPX (with no
16661          *      NetBIOS involved) two bytes of Session ID and two bytes
16662          *      of SequenceNumber.
16663          *
16664          * Network Monitor 2.x dissects the four bytes before the Session ID
16665          * as a "Key", and the two bytes after the SequenceNumber as
16666          * a "Group ID".
16667          *
16668          * The "High Part of PID" has been seen in calls other than NT
16669          * Create and X, although most of them appear to be I/O on DCE RPC
16670          * pipes opened with the NT Create and X in question.
16671          */
16672         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16673         offset += 2;
16674
16675         if (pinfo->ptype == PT_IPX &&
16676             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16677              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16678              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16679                 /*
16680                  * This is SMB-over-IPX.
16681                  * XXX - do we have to worry about "sequenced commands",
16682                  * as per the Samba document?  They say that for
16683                  * "unsequenced commands" (with a sequence number of 0),
16684                  * the Mid must be unique, but perhaps the Mid doesn't
16685                  * have to be unique for sequenced commands.  In at least
16686                  * one capture with SMB-over-IPX, however, the Mids
16687                  * are unique even for sequenced commands.
16688                  */
16689                 /* Key */
16690                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16691                     TRUE);
16692                 offset += 4;
16693
16694                 /* Session ID */
16695                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16696                     TRUE);
16697                 offset += 2;
16698
16699                 /* Sequence number */
16700                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16701                     TRUE);
16702                 offset += 2;
16703
16704                 /* Group ID */
16705                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16706                     TRUE);
16707                 offset += 2;
16708         } else {
16709                 /*
16710                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16711                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16712                  * bytes after the "High part of PID" are an 8-byte
16713                  * signature ...
16714                  */
16715                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16716                 offset += 8;
16717
16718                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16719                 offset += 2;
16720         }
16721
16722         pinfo->private_data = si;
16723
16724         /* TID
16725          * TreeConnectAndX(0x75) is special, here it is the mere fact of
16726          * having a response that means that the share was mapped and we
16727          * need to track it
16728          */
16729         if(!pinfo->fd->flags.visited && si->cmd==0x75 && !si->request){
16730                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE);
16731         } else {
16732                 offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE);
16733         }
16734
16735         /* PID */
16736         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16737         offset += 2;
16738
16739         /* UID */
16740         offset=dissect_smb_uid(tvb, htree, offset, si);
16741
16742         /* MID */
16743         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16744         offset += 2;
16745
16746         /* tap the packet before the dissectors are called so we still get
16747            the tap listener called even if there is an exception.
16748         */
16749         tap_queue_packet(smb_tap, pinfo, si);
16750         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16751
16752         /* Append error info from this packet to info string. */
16753         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16754                 if (flags2 & 0x4000) {
16755                         /*
16756                          * The status is an NT status code; was there
16757                          * an error?
16758                          */
16759                         if ((si->nt_status & 0xC0000000) == 0xC0000000) {
16760                                 /*
16761                                  * Yes.
16762                                  */
16763                                 col_append_fstr(
16764                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16765                                         val_to_str(si->nt_status, NT_errors,
16766                                             "Unknown (0x%08X)"));
16767                         }
16768                 } else {
16769                         /*
16770                          * The status is a DOS error class and code; was
16771                          * there an error?
16772                          */
16773                         if (errclass != SMB_SUCCESS) {
16774                                 /*
16775                                  * Yes.
16776                                  */
16777                                 col_append_fstr(
16778                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16779                                         decode_smb_error(errclass, errcode));
16780                         }
16781                 }
16782         }
16783 }
16784
16785 static gboolean
16786 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16787 {
16788         /* must check that this really is a smb packet */
16789         if (tvb_length(tvb) < 4)
16790                 return FALSE;
16791
16792         if( (tvb_get_guint8(tvb, 0) != 0xff)
16793             || (tvb_get_guint8(tvb, 1) != 'S')
16794             || (tvb_get_guint8(tvb, 2) != 'M')
16795             || (tvb_get_guint8(tvb, 3) != 'B') ){
16796                 return FALSE;
16797         }
16798
16799         dissect_smb(tvb, pinfo, parent_tree);
16800         return TRUE;
16801 }
16802
16803 void
16804 proto_register_smb(void)
16805 {
16806         static hf_register_info hf[] = {
16807         { &hf_smb_cmd,
16808                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16809                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16810
16811         { &hf_smb_trans2_subcmd,
16812                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16813                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16814
16815         { &hf_smb_nt_trans_subcmd,
16816                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16817                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16818
16819         { &hf_smb_word_count,
16820                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16821                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16822
16823         { &hf_smb_byte_count,
16824                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16825                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16826
16827         { &hf_smb_response_to,
16828                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16829                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16830
16831         { &hf_smb_time,
16832                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16833                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16834
16835         { &hf_smb_response_in,
16836                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16837                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16838
16839         { &hf_smb_continuation_to,
16840                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16841                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16842
16843         { &hf_smb_nt_status,
16844                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16845                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16846
16847         { &hf_smb_error_class,
16848                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16849                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16850
16851         { &hf_smb_error_code,
16852                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16853                 NULL, 0, "DOS Error Code", HFILL }},
16854
16855         { &hf_smb_reserved,
16856                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16857                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16858
16859         { &hf_smb_sig,
16860                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16861                 NULL, 0, "Signature bytes", HFILL }},
16862
16863         { &hf_smb_key,
16864                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16865                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16866
16867         { &hf_smb_session_id,
16868                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16869                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16870
16871         { &hf_smb_sequence_num,
16872                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16873                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16874
16875         { &hf_smb_group_id,
16876                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16877                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16878
16879         { &hf_smb_pid,
16880                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16881                 NULL, 0, "Process ID", HFILL }},
16882
16883         { &hf_smb_pid_high,
16884                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16885                 NULL, 0, "Process ID High Bytes", HFILL }},
16886
16887         { &hf_smb_tid,
16888                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16889                 NULL, 0, "Tree ID", HFILL }},
16890
16891         { &hf_smb_uid,
16892                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16893                 NULL, 0, "User ID", HFILL }},
16894
16895         { &hf_smb_mid,
16896                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16897                 NULL, 0, "Multiplex ID", HFILL }},
16898
16899         { &hf_smb_flags_lock,
16900                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16901                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16902
16903         { &hf_smb_flags_receive_buffer,
16904                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16905                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16906
16907         { &hf_smb_flags_caseless,
16908                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16909                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16910
16911         { &hf_smb_flags_canon,
16912                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16913                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16914
16915         { &hf_smb_flags_oplock,
16916                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16917                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16918
16919         { &hf_smb_flags_notify,
16920                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16921                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16922
16923         { &hf_smb_flags_response,
16924                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16925                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16926
16927         { &hf_smb_flags2_long_names_allowed,
16928                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16929                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16930
16931         { &hf_smb_flags2_ea,
16932                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16933                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16934
16935         { &hf_smb_flags2_sec_sig,
16936                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16937                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16938
16939         { &hf_smb_flags2_long_names_used,
16940                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16941                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16942
16943         { &hf_smb_flags2_esn,
16944                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16945                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16946
16947         { &hf_smb_flags2_dfs,
16948                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16949                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16950
16951         { &hf_smb_flags2_roe,
16952                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16953                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16954
16955         { &hf_smb_flags2_nt_error,
16956                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16957                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16958
16959         { &hf_smb_flags2_string,
16960                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16961                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16962
16963         { &hf_smb_buffer_format,
16964                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16965                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16966
16967         { &hf_smb_dialect_name,
16968                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16969                 NULL, 0, "Name of dialect", HFILL }},
16970
16971         { &hf_smb_dialect_index,
16972                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16973                 NULL, 0, "Index of selected dialect", HFILL }},
16974
16975         { &hf_smb_max_trans_buf_size,
16976                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16977                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16978
16979         { &hf_smb_max_mpx_count,
16980                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16981                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16982
16983         { &hf_smb_max_vcs_num,
16984                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16985                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16986
16987         { &hf_smb_session_key,
16988                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16989                 NULL, 0, "Unique token identifying this session", HFILL }},
16990
16991         { &hf_smb_server_timezone,
16992                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16993                 NULL, 0, "Current timezone at server.", HFILL }},
16994
16995         { &hf_smb_encryption_key_length,
16996                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16997                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16998
16999         { &hf_smb_encryption_key,
17000                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
17001                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
17002
17003         { &hf_smb_primary_domain,
17004                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
17005                 NULL, 0, "The server's primary domain", HFILL }},
17006
17007         { &hf_smb_server,
17008                 { "Server", "smb.server", FT_STRING, BASE_NONE,
17009                 NULL, 0, "The name of the DC/server", HFILL }},
17010
17011         { &hf_smb_max_raw_buf_size,
17012                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
17013                 NULL, 0, "Maximum raw buffer size", HFILL }},
17014
17015         { &hf_smb_server_guid,
17016                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
17017                 NULL, 0, "Globally unique identifier for this server", HFILL }},
17018
17019         { &hf_smb_security_blob_len,
17020                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
17021                 NULL, 0, "Security blob length", HFILL }},
17022
17023         { &hf_smb_security_blob,
17024                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
17025                 NULL, 0, "Security blob", HFILL }},
17026
17027         { &hf_smb_sm_mode16,
17028                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
17029                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17030
17031         { &hf_smb_sm_password16,
17032                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
17033                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17034
17035         { &hf_smb_sm_mode,
17036                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
17037                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17038
17039         { &hf_smb_sm_password,
17040                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
17041                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17042
17043         { &hf_smb_sm_signatures,
17044                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
17045                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
17046
17047         { &hf_smb_sm_sig_required,
17048                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
17049                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
17050
17051         { &hf_smb_rm_read,
17052                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
17053                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
17054
17055         { &hf_smb_rm_write,
17056                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
17057                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
17058
17059         { &hf_smb_server_date_time,
17060                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
17061                 NULL, 0, "Current date and time at server", HFILL }},
17062
17063         { &hf_smb_server_smb_date,
17064                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
17065                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
17066
17067         { &hf_smb_server_smb_time,
17068                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
17069                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
17070
17071         { &hf_smb_server_cap_raw_mode,
17072                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
17073                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
17074
17075         { &hf_smb_server_cap_mpx_mode,
17076                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
17077                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
17078
17079         { &hf_smb_server_cap_unicode,
17080                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
17081                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
17082
17083         { &hf_smb_server_cap_large_files,
17084                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
17085                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
17086
17087         { &hf_smb_server_cap_nt_smbs,
17088                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
17089                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
17090
17091         { &hf_smb_server_cap_rpc_remote_apis,
17092                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
17093                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
17094
17095         { &hf_smb_server_cap_nt_status,
17096                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
17097                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
17098
17099         { &hf_smb_server_cap_level_ii_oplocks,
17100                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
17101                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
17102
17103         { &hf_smb_server_cap_lock_and_read,
17104                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
17105                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
17106
17107         { &hf_smb_server_cap_nt_find,
17108                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
17109                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
17110
17111         { &hf_smb_server_cap_dfs,
17112                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
17113                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
17114
17115         { &hf_smb_server_cap_infolevel_passthru,
17116                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
17117                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
17118
17119         { &hf_smb_server_cap_large_readx,
17120                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
17121                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
17122
17123         { &hf_smb_server_cap_large_writex,
17124                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
17125                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
17126
17127         { &hf_smb_server_cap_unix,
17128                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
17129                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
17130
17131         { &hf_smb_server_cap_reserved,
17132                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
17133                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
17134
17135         { &hf_smb_server_cap_bulk_transfer,
17136                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
17137                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
17138
17139         { &hf_smb_server_cap_compressed_data,
17140                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
17141                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
17142
17143         { &hf_smb_server_cap_extended_security,
17144                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
17145                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
17146
17147         { &hf_smb_system_time,
17148                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
17149                 NULL, 0, "System Time", HFILL }},
17150
17151         { &hf_smb_unknown,
17152                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
17153                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
17154
17155         { &hf_smb_dir_name,
17156                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17157                 NULL, 0, "SMB Directory Name", HFILL }},
17158
17159         { &hf_smb_echo_count,
17160                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17161                 NULL, 0, "Number of times to echo data back", HFILL }},
17162
17163         { &hf_smb_echo_data,
17164                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
17165                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17166
17167         { &hf_smb_echo_seq_num,
17168                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17169                 NULL, 0, "Sequence number for this echo response", HFILL }},
17170
17171         { &hf_smb_max_buf_size,
17172                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17173                 NULL, 0, "Max client buffer size", HFILL }},
17174
17175         { &hf_smb_path,
17176                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17177                 NULL, 0, "Path. Server name and share name", HFILL }},
17178
17179         { &hf_smb_service,
17180                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17181                 NULL, 0, "Service name", HFILL }},
17182
17183         { &hf_smb_password,
17184                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17185                 NULL, 0, "Password", HFILL }},
17186
17187         { &hf_smb_ansi_password,
17188                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17189                 NULL, 0, "ANSI Password", HFILL }},
17190
17191         { &hf_smb_unicode_password,
17192                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17193                 NULL, 0, "Unicode Password", HFILL }},
17194
17195         { &hf_smb_move_flags_file,
17196                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17197                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17198
17199         { &hf_smb_move_flags_dir,
17200                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17201                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17202
17203         { &hf_smb_move_flags_verify,
17204                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17205                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17206
17207         { &hf_smb_files_moved,
17208                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17209                 NULL, 0, "Number of files moved", HFILL }},
17210
17211         { &hf_smb_copy_flags_file,
17212                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17213                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17214
17215         { &hf_smb_copy_flags_dir,
17216                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17217                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17218
17219         { &hf_smb_copy_flags_dest_mode,
17220                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17221                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17222
17223         { &hf_smb_copy_flags_source_mode,
17224                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17225                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17226
17227         { &hf_smb_copy_flags_verify,
17228                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17229                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17230
17231         { &hf_smb_copy_flags_tree_copy,
17232                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17233                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17234
17235         { &hf_smb_copy_flags_ea_action,
17236                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17237                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17238
17239         { &hf_smb_count,
17240                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17241                 NULL, 0, "Count number of items/bytes", HFILL }},
17242
17243         { &hf_smb_count_low,
17244                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
17245                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
17246
17247         { &hf_smb_count_high,
17248                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
17249                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
17250
17251         { &hf_smb_file_name,
17252                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17253                 NULL, 0, "File Name", HFILL }},
17254
17255         { &hf_smb_open_function_create,
17256                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17257                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17258
17259         { &hf_smb_open_function_open,
17260                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17261                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17262
17263         { &hf_smb_fid,
17264                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17265                 NULL, 0, "FID: File ID", HFILL }},
17266
17267         { &hf_smb_file_attr_read_only_16bit,
17268                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17269                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17270
17271         { &hf_smb_file_attr_read_only_8bit,
17272                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17273                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17274
17275         { &hf_smb_file_attr_hidden_16bit,
17276                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17277                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17278
17279         { &hf_smb_file_attr_hidden_8bit,
17280                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17281                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17282
17283         { &hf_smb_file_attr_system_16bit,
17284                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17285                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17286
17287         { &hf_smb_file_attr_system_8bit,
17288                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17289                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17290
17291         { &hf_smb_file_attr_volume_16bit,
17292                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17293                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17294
17295         { &hf_smb_file_attr_volume_8bit,
17296                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17297                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17298
17299         { &hf_smb_file_attr_directory_16bit,
17300                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17301                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17302
17303         { &hf_smb_file_attr_directory_8bit,
17304                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17305                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17306
17307         { &hf_smb_file_attr_archive_16bit,
17308                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17309                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17310
17311         { &hf_smb_file_attr_archive_8bit,
17312                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17313                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17314
17315         { &hf_smb_file_attr_device,
17316                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17317                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17318
17319         { &hf_smb_file_attr_normal,
17320                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17321                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17322
17323         { &hf_smb_file_attr_temporary,
17324                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17325                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17326
17327         { &hf_smb_file_attr_sparse,
17328                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17329                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17330
17331         { &hf_smb_file_attr_reparse,
17332                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17333                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17334
17335         { &hf_smb_file_attr_compressed,
17336                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17337                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17338
17339         { &hf_smb_file_attr_offline,
17340                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17341                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17342
17343         { &hf_smb_file_attr_not_content_indexed,
17344                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17345                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17346
17347         { &hf_smb_file_attr_encrypted,
17348                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17349                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17350
17351         { &hf_smb_file_size,
17352                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17353                 NULL, 0, "File Size", HFILL }},
17354
17355         { &hf_smb_search_attribute_read_only,
17356                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17357                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17358
17359         { &hf_smb_search_attribute_hidden,
17360                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17361                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17362
17363         { &hf_smb_search_attribute_system,
17364                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17365                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17366
17367         { &hf_smb_search_attribute_volume,
17368                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17369                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17370
17371         { &hf_smb_search_attribute_directory,
17372                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17373                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17374
17375         { &hf_smb_search_attribute_archive,
17376                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17377                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17378
17379         { &hf_smb_access_mode,
17380                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17381                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17382
17383         { &hf_smb_access_sharing,
17384                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17385                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17386
17387         { &hf_smb_access_locality,
17388                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17389                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17390
17391         { &hf_smb_access_caching,
17392                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17393                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17394
17395         { &hf_smb_access_writetru,
17396                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17397                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17398
17399         { &hf_smb_create_time,
17400                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17401                 NULL, 0, "Creation Time", HFILL }},
17402
17403         { &hf_smb_modify_time,
17404                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17405                   NULL, 0, "Modification Time", HFILL }},
17406
17407         { &hf_smb_backup_time,
17408                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17409                   NULL, 0, "Backup time", HFILL}},
17410
17411         { &hf_smb_mac_alloc_block_count,
17412                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17413                   NULL, 0, "Allocation Block Count", HFILL}},
17414
17415         { &hf_smb_mac_alloc_block_size,
17416                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17417                   NULL, 0, "Allocation Block Size", HFILL}},
17418
17419         { &hf_smb_mac_free_block_count,
17420                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17421                   NULL, 0, "Free Block Count", HFILL}},
17422
17423         { &hf_smb_mac_root_file_count,
17424                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17425                 NULL, 0, "Root File Count", HFILL}},
17426
17427         { &hf_smb_mac_root_dir_count,
17428           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17429             NULL, 0, "Root Directory Count", HFILL}},
17430
17431         { &hf_smb_mac_file_count,
17432           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17433             NULL, 0, "File Count", HFILL}},
17434
17435         { &hf_smb_mac_dir_count,
17436           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17437             NULL, 0, "Directory Count", HFILL}},
17438
17439         { &hf_smb_mac_support_flags,
17440           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17441             NULL, 0, "Mac Support Flags", HFILL}},
17442
17443         { &hf_smb_mac_sup_access_ctrl,
17444           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17445             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17446
17447         { &hf_smb_mac_sup_getset_comments,
17448           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17449             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17450
17451         { &hf_smb_mac_sup_desktopdb_calls,
17452           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17453             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17454
17455         { &hf_smb_mac_sup_unique_ids,
17456           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17457             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17458
17459         { &hf_smb_mac_sup_streams,
17460           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17461             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17462
17463         { &hf_smb_create_dos_date,
17464                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17465                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17466
17467         { &hf_smb_create_dos_time,
17468                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17469                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17470
17471         { &hf_smb_last_write_time,
17472                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17473                 NULL, 0, "Time this file was last written to", HFILL }},
17474
17475         { &hf_smb_last_write_dos_date,
17476                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17477                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17478
17479         { &hf_smb_last_write_dos_time,
17480                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17481                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17482
17483         { &hf_smb_old_file_name,
17484                 { "Old File Name", "smb.old_file", FT_STRING, BASE_NONE,
17485                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17486
17487         { &hf_smb_offset,
17488                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17489                 NULL, 0, "Offset in file", HFILL }},
17490
17491         { &hf_smb_remaining,
17492                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17493                 NULL, 0, "Remaining number of bytes", HFILL }},
17494
17495         { &hf_smb_padding,
17496                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17497                 NULL, 0, "Padding or unknown data", HFILL }},
17498
17499         { &hf_smb_file_data,
17500                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17501                 NULL, 0, "Data read/written to the file", HFILL }},
17502
17503         { &hf_smb_mac_fndrinfo,
17504                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17505                   NULL, 0, "Finder Info", HFILL}},
17506
17507         { &hf_smb_total_data_len,
17508                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17509                 NULL, 0, "Total length of data", HFILL }},
17510
17511         { &hf_smb_data_len,
17512                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17513                 NULL, 0, "Length of data", HFILL }},
17514
17515         { &hf_smb_data_len_low,
17516                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17517                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17518
17519         { &hf_smb_data_len_high,
17520                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17521                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17522
17523         { &hf_smb_seek_mode,
17524                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17525                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17526
17527         { &hf_smb_access_time,
17528                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17529                 NULL, 0, "Last Access Time", HFILL }},
17530
17531         { &hf_smb_access_dos_date,
17532                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17533                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17534
17535         { &hf_smb_access_dos_time,
17536                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17537                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17538
17539         { &hf_smb_data_size,
17540                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17541                 NULL, 0, "Data Size", HFILL }},
17542
17543         { &hf_smb_alloc_size,
17544                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17545                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17546
17547         { &hf_smb_max_count,
17548                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17549                 NULL, 0, "Maximum Count", HFILL }},
17550
17551         { &hf_smb_max_count_low,
17552                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17553                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17554
17555         { &hf_smb_max_count_high,
17556                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17557                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17558
17559         { &hf_smb_min_count,
17560                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17561                 NULL, 0, "Minimum Count", HFILL }},
17562
17563         { &hf_smb_timeout,
17564                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17565                 NULL, 0, "Timeout in miliseconds", HFILL }},
17566
17567         { &hf_smb_high_offset,
17568                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17569                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17570
17571         { &hf_smb_units,
17572                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17573                 NULL, 0, "Total number of units at server", HFILL }},
17574
17575         { &hf_smb_bpu,
17576                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17577                 NULL, 0, "Blocks per unit at server", HFILL }},
17578
17579         { &hf_smb_blocksize,
17580                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17581                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17582
17583         { &hf_smb_freeunits,
17584                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17585                 NULL, 0, "Number of free units at server", HFILL }},
17586
17587         { &hf_smb_data_offset,
17588                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17589                 NULL, 0, "Data Offset", HFILL }},
17590
17591         { &hf_smb_dcm,
17592                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17593                 NULL, 0, "Data Compaction Mode", HFILL }},
17594
17595         { &hf_smb_request_mask,
17596                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17597                 NULL, 0, "Connectionless mode mask", HFILL }},
17598
17599         { &hf_smb_response_mask,
17600                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17601                 NULL, 0, "Connectionless mode mask", HFILL }},
17602
17603         { &hf_smb_search_id,
17604                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17605                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17606
17607         { &hf_smb_write_mode_write_through,
17608                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17609                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17610
17611         { &hf_smb_write_mode_return_remaining,
17612                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17613                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17614
17615         { &hf_smb_write_mode_raw,
17616                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17617                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17618
17619         { &hf_smb_write_mode_message_start,
17620                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17621                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17622
17623         { &hf_smb_write_mode_connectionless,
17624                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17625                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17626
17627         { &hf_smb_resume_key_len,
17628                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17629                 NULL, 0, "Resume Key length", HFILL }},
17630
17631         { &hf_smb_resume_find_id,
17632                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17633                 NULL, 0, "Handle for Find operation", HFILL }},
17634
17635         { &hf_smb_resume_server_cookie,
17636                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17637                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17638
17639         { &hf_smb_resume_client_cookie,
17640                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17641                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17642
17643         { &hf_smb_andxoffset,
17644                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17645                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17646
17647         { &hf_smb_lock_type_large,
17648                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17649                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17650
17651         { &hf_smb_lock_type_cancel,
17652                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17653                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17654
17655         { &hf_smb_lock_type_change,
17656                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17657                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17658
17659         { &hf_smb_lock_type_oplock,
17660                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17661                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17662
17663         { &hf_smb_lock_type_shared,
17664                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17665                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17666
17667         { &hf_smb_locking_ol,
17668                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17669                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17670
17671         { &hf_smb_number_of_locks,
17672                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17673                 NULL, 0, "Number of lock requests in this request", HFILL }},
17674
17675         { &hf_smb_number_of_unlocks,
17676                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17677                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17678
17679         { &hf_smb_lock_long_length,
17680                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
17681                 NULL, 0, "Length of lock/unlock region", HFILL }},
17682
17683         { &hf_smb_lock_long_offset,
17684                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
17685                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17686
17687         { &hf_smb_file_type,
17688                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17689                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17690
17691         { &hf_smb_ipc_state_nonblocking,
17692                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17693                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17694
17695         { &hf_smb_ipc_state_endpoint,
17696                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17697                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17698
17699         { &hf_smb_ipc_state_pipe_type,
17700                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17701                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17702
17703         { &hf_smb_ipc_state_read_mode,
17704                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17705                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17706
17707         { &hf_smb_ipc_state_icount,
17708                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17709                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17710
17711         { &hf_smb_server_fid,
17712                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17713                 NULL, 0, "Server unique File ID", HFILL }},
17714
17715         { &hf_smb_open_flags_add_info,
17716                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17717                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17718
17719         { &hf_smb_open_flags_ex_oplock,
17720                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17721                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17722
17723         { &hf_smb_open_flags_batch_oplock,
17724                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17725                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17726
17727         { &hf_smb_open_flags_ealen,
17728                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17729                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17730
17731         { &hf_smb_open_action_open,
17732                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17733                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17734
17735         { &hf_smb_open_action_lock,
17736                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17737                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17738
17739         { &hf_smb_vc_num,
17740                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17741                 NULL, 0, "VC Number", HFILL }},
17742
17743         { &hf_smb_password_len,
17744                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17745                 NULL, 0, "Length of password", HFILL }},
17746
17747         { &hf_smb_ansi_password_len,
17748                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17749                 NULL, 0, "Length of ANSI password", HFILL }},
17750
17751         { &hf_smb_unicode_password_len,
17752                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17753                 NULL, 0, "Length of Unicode password", HFILL }},
17754
17755         { &hf_smb_account,
17756                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17757                 NULL, 0, "Account, username", HFILL }},
17758
17759         { &hf_smb_os,
17760                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17761                 NULL, 0, "Which OS we are running", HFILL }},
17762
17763         { &hf_smb_lanman,
17764                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17765                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17766
17767         { &hf_smb_setup_action_guest,
17768                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17769                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17770
17771         { &hf_smb_fs,
17772                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17773                 NULL, 0, "Native File System", HFILL }},
17774
17775         { &hf_smb_connect_flags_dtid,
17776                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17777                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17778
17779         { &hf_smb_connect_support_search,
17780                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17781                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17782
17783         { &hf_smb_connect_support_in_dfs,
17784                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17785                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17786
17787         { &hf_smb_max_setup_count,
17788                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17789                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17790
17791         { &hf_smb_total_param_count,
17792                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17793                 NULL, 0, "Total number of parameter bytes", HFILL }},
17794
17795         { &hf_smb_total_data_count,
17796                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17797                 NULL, 0, "Total number of data bytes", HFILL }},
17798
17799         { &hf_smb_max_param_count,
17800                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17801                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17802
17803         { &hf_smb_max_data_count,
17804                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17805                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17806
17807         { &hf_smb_param_disp16,
17808                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17809                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17810
17811         { &hf_smb_param_count16,
17812                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17813                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17814
17815         { &hf_smb_param_offset16,
17816                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17817                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17818
17819         { &hf_smb_param_disp32,
17820                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17821                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17822
17823         { &hf_smb_param_count32,
17824                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17825                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17826
17827         { &hf_smb_param_offset32,
17828                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17829                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17830
17831         { &hf_smb_data_count16,
17832                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17833                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17834
17835         { &hf_smb_data_disp16,
17836                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17837                 NULL, 0, "Data Displacement", HFILL }},
17838
17839         { &hf_smb_data_offset16,
17840                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17841                 NULL, 0, "Data Offset", HFILL }},
17842
17843         { &hf_smb_data_count32,
17844                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17845                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17846
17847         { &hf_smb_data_disp32,
17848                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17849                 NULL, 0, "Data Displacement", HFILL }},
17850
17851         { &hf_smb_data_offset32,
17852                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17853                 NULL, 0, "Data Offset", HFILL }},
17854
17855         { &hf_smb_setup_count,
17856                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17857                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17858
17859         { &hf_smb_nt_ioctl_isfsctl,
17860                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17861                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17862
17863         { &hf_smb_nt_ioctl_flags_root_handle,
17864                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17865                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17866
17867         { &hf_smb_nt_notify_action,
17868                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17869                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17870
17871         { &hf_smb_nt_notify_watch_tree,
17872                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17873                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17874
17875         { &hf_smb_nt_notify_stream_write,
17876                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17877                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17878
17879         { &hf_smb_nt_notify_stream_size,
17880                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17881                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17882
17883         { &hf_smb_nt_notify_stream_name,
17884                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17885                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17886
17887         { &hf_smb_nt_notify_security,
17888                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17889                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17890
17891         { &hf_smb_nt_notify_ea,
17892                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17893                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17894
17895         { &hf_smb_nt_notify_creation,
17896                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17897                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17898
17899         { &hf_smb_nt_notify_last_access,
17900                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17901                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17902
17903         { &hf_smb_nt_notify_last_write,
17904                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17905                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17906
17907         { &hf_smb_nt_notify_size,
17908                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17909                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17910
17911         { &hf_smb_nt_notify_attributes,
17912                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17913                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17914
17915         { &hf_smb_nt_notify_dir_name,
17916                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17917                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17918
17919         { &hf_smb_nt_notify_file_name,
17920                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17921                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17922
17923         { &hf_smb_root_dir_fid,
17924                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17925                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17926
17927         { &hf_smb_alloc_size64,
17928                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17929                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17930
17931         { &hf_smb_nt_create_disposition,
17932                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17933                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17934
17935         { &hf_smb_sd_length,
17936                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17937                 NULL, 0, "Total length of security descriptor", HFILL }},
17938
17939         { &hf_smb_ea_list_length,
17940                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17941                 NULL, 0, "Total length of extended attributes", HFILL }},
17942
17943         { &hf_smb_ea_flags,
17944                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17945                 NULL, 0, "EA Flags", HFILL }},
17946
17947         { &hf_smb_ea_name_length,
17948                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17949                 NULL, 0, "EA Name Length", HFILL }},
17950
17951         { &hf_smb_ea_data_length,
17952                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17953                 NULL, 0, "EA Data Length", HFILL }},
17954
17955         { &hf_smb_ea_name,
17956                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17957                 NULL, 0, "EA Name", HFILL }},
17958
17959         { &hf_smb_ea_data,
17960                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17961                 NULL, 0, "EA Data", HFILL }},
17962
17963         { &hf_smb_file_name_len,
17964                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17965                 NULL, 0, "Length of File Name", HFILL }},
17966
17967         { &hf_smb_nt_impersonation_level,
17968                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17969                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17970
17971         { &hf_smb_nt_security_flags_context_tracking,
17972                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17973                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17974
17975         { &hf_smb_nt_security_flags_effective_only,
17976                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17977                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17978
17979         { &hf_smb_nt_access_mask_generic_read,
17980                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17981                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17982
17983         { &hf_smb_nt_access_mask_generic_write,
17984                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17985                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17986
17987         { &hf_smb_nt_access_mask_generic_execute,
17988                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17989                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17990
17991         { &hf_smb_nt_access_mask_generic_all,
17992                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17993                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17994
17995         { &hf_smb_nt_access_mask_maximum_allowed,
17996                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17997                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
17998
17999         { &hf_smb_nt_access_mask_system_security,
18000                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
18001                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
18002
18003         { &hf_smb_nt_access_mask_synchronize,
18004                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
18005                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
18006
18007         { &hf_smb_nt_access_mask_write_owner,
18008                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
18009                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
18010
18011         { &hf_smb_nt_access_mask_write_dac,
18012                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
18013                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
18014
18015         { &hf_smb_nt_access_mask_read_control,
18016                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
18017                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
18018
18019         { &hf_smb_nt_access_mask_delete,
18020                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
18021                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
18022
18023         { &hf_smb_nt_access_mask_write_attributes,
18024                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
18025                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
18026
18027         { &hf_smb_nt_access_mask_read_attributes,
18028                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
18029                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
18030
18031         { &hf_smb_nt_access_mask_delete_child,
18032                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
18033                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
18034
18035         /*
18036          * "Execute" for files, "traverse" for directories.
18037          */
18038         { &hf_smb_nt_access_mask_execute,
18039                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
18040                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
18041
18042         { &hf_smb_nt_access_mask_write_ea,
18043                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
18044                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
18045
18046         { &hf_smb_nt_access_mask_read_ea,
18047                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
18048                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
18049
18050         /*
18051          * "Append data" for files, "add subdirectory" for directories,
18052          * "create pipe instance" for named pipes.
18053          */
18054         { &hf_smb_nt_access_mask_append,
18055                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
18056                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
18057
18058         /*
18059          * "Write data" for files and pipes, "add file" for directory.
18060          */
18061         { &hf_smb_nt_access_mask_write,
18062                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
18063                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
18064
18065         /*
18066          * "Read data" for files and pipes, "list directory" for directory.
18067          */
18068         { &hf_smb_nt_access_mask_read,
18069                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
18070                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
18071
18072         { &hf_smb_nt_create_bits_oplock,
18073                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
18074                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
18075
18076         { &hf_smb_nt_create_bits_boplock,
18077                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
18078                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
18079
18080         { &hf_smb_nt_create_bits_dir,
18081                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
18082                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
18083
18084         { &hf_smb_nt_create_bits_ext_resp,
18085           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32,
18086             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
18087
18088         { &hf_smb_nt_create_options_directory_file,
18089                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
18090                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
18091
18092         { &hf_smb_nt_create_options_write_through,
18093                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
18094                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
18095
18096         { &hf_smb_nt_create_options_sequential_only,
18097                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
18098                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will access to thsis file only be sequential?", HFILL }},
18099
18100         { &hf_smb_nt_create_options_no_intermediate_buffering,
18101                 { "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
18102                 TFS(&tfs_nt_create_options_no_intermediate_buffering), 0x00000008, "Is intermediate buffering allowed?", HFILL }},
18103
18104         { &hf_smb_nt_create_options_sync_io_alert,
18105                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
18106                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
18107
18108         { &hf_smb_nt_create_options_sync_io_nonalert,
18109                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
18110                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
18111
18112         { &hf_smb_nt_create_options_non_directory_file,
18113                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
18114                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
18115
18116         { &hf_smb_nt_create_options_create_tree_connection,
18117                 { "Create Tree Connection", "smb.nt.create_options.create_tree_connection", FT_BOOLEAN, 32,
18118                 TFS(&tfs_nt_create_options_create_tree_connection), 0x00000080, "Create Tree Connection flag", HFILL }},
18119
18120         { &hf_smb_nt_create_options_complete_if_oplocked,
18121                 { "Complete If Oplocked", "smb.nt.create_options.complete_if_oplocked", FT_BOOLEAN, 32,
18122                 TFS(&tfs_nt_create_options_complete_if_oplocked), 0x00000100, "Complete if oplocked flag", HFILL }},
18123
18124         { &hf_smb_nt_create_options_no_ea_knowledge,
18125                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
18126                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
18127
18128         { &hf_smb_nt_create_options_eight_dot_three_only,
18129                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
18130                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
18131
18132         { &hf_smb_nt_create_options_random_access,
18133                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
18134                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
18135
18136         { &hf_smb_nt_create_options_delete_on_close,
18137                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
18138                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
18139         { &hf_smb_nt_create_options_open_by_fileid,
18140                 { "Open By FileID", "smb.nt.create_options.open_by_fileid", FT_BOOLEAN, 32,
18141                 TFS(&tfs_nt_create_options_open_by_fileid), 0x00002000, "Open file by inode", HFILL }},
18142
18143         { &hf_smb_nt_create_options_backup_intent,
18144                 { "Backup Intent", "smb.nt.create_options.backup_intent", FT_BOOLEAN, 32,
18145                 TFS(&tfs_nt_create_options_backup_intent), 0x00004000, "Is this opened by BACKUP ADMIN for backup intent?", HFILL }},
18146
18147         { &hf_smb_nt_create_options_no_compression,
18148                 { "No Compression", "smb.nt.create_options.no_compression", FT_BOOLEAN, 32,
18149                 TFS(&tfs_nt_create_options_no_compression), 0x00008000, "Is compression allowed?", HFILL }},
18150
18151         { &hf_smb_nt_create_options_reserve_opfilter,
18152                 { "Reserve Opfilter", "smb.nt.create_options.reserve_opfilter", FT_BOOLEAN, 32,
18153                 TFS(&tfs_nt_create_options_reserve_opfilter), 0x00100000, "Reserve Opfilter flag", HFILL }},
18154
18155         { &hf_smb_nt_create_options_open_reparse_point,
18156                 { "Open Reparse Point", "smb.nt.create_options.open_reparse_point", FT_BOOLEAN, 32,
18157                 TFS(&tfs_nt_create_options_open_reparse_point), 0x00200000, "Is this an open of a reparse point or of the normal file?", HFILL }},
18158
18159         { &hf_smb_nt_create_options_open_no_recall,
18160                 { "Open No Recall", "smb.nt.create_options.open_no_recall", FT_BOOLEAN, 32,
18161                 TFS(&tfs_nt_create_options_open_no_recall), 0x00400000, "Open no recall flag", HFILL }},
18162
18163         { &hf_smb_nt_create_options_open_for_free_space_query,
18164                 { "Open For Free Space query", "smb.nt.create_options.open_for_free_space_query", FT_BOOLEAN, 32,
18165                 TFS(&tfs_nt_create_options_open_for_free_space_query), 0x00800000, "Open For Free Space Query flag", HFILL }},
18166
18167         { &hf_smb_nt_share_access_read,
18168                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
18169                 TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
18170
18171         { &hf_smb_nt_share_access_write,
18172                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
18173                 TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
18174
18175         { &hf_smb_nt_share_access_delete,
18176                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
18177                 TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, "", HFILL }},
18178
18179         { &hf_smb_file_eattr_read_only,
18180                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
18181                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18182
18183         { &hf_smb_file_eattr_hidden,
18184                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
18185                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18186
18187         { &hf_smb_file_eattr_system,
18188                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
18189                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18190
18191         { &hf_smb_file_eattr_volume,
18192                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18193                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18194
18195         { &hf_smb_file_eattr_directory,
18196                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18197                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18198
18199         { &hf_smb_file_eattr_archive,
18200                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18201                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18202
18203         { &hf_smb_file_eattr_device,
18204                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18205                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18206
18207         { &hf_smb_file_eattr_normal,
18208                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18209                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18210
18211         { &hf_smb_file_eattr_temporary,
18212                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18213                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18214
18215         { &hf_smb_file_eattr_sparse,
18216                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18217                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18218
18219         { &hf_smb_file_eattr_reparse,
18220                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18221                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18222
18223         { &hf_smb_file_eattr_compressed,
18224                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18225                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18226
18227         { &hf_smb_file_eattr_offline,
18228                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18229                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18230
18231         { &hf_smb_file_eattr_not_content_indexed,
18232                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18233                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18234
18235         { &hf_smb_file_eattr_encrypted,
18236                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18237                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18238
18239         { &hf_smb_sec_desc_len,
18240                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18241                 NULL, 0, "Security Descriptor Length", HFILL }},
18242
18243         { &hf_smb_nt_qsd_owner,
18244                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18245                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18246
18247         { &hf_smb_nt_qsd_group,
18248                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18249                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18250
18251         { &hf_smb_nt_qsd_dacl,
18252                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18253                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18254
18255         { &hf_smb_nt_qsd_sacl,
18256                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18257                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18258
18259         { &hf_smb_extended_attributes,
18260                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
18261                 NULL, 0, "Extended Attributes", HFILL }},
18262
18263         { &hf_smb_oplock_level,
18264                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18265                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18266
18267         { &hf_smb_create_action,
18268                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18269                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18270
18271         { &hf_smb_file_id,
18272                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18273                 NULL, 0, "Server unique file ID", HFILL }},
18274
18275         { &hf_smb_ea_error_offset,
18276                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18277                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18278
18279         { &hf_smb_end_of_file,
18280                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18281                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18282
18283         { &hf_smb_replace,
18284                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
18285                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
18286
18287         { &hf_smb_root_dir_handle,
18288                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
18289                 NULL, 0, "Root directory handle", HFILL }},
18290
18291         { &hf_smb_target_name_len,
18292                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
18293                 NULL, 0, "Length of target file name", HFILL }},
18294
18295         { &hf_smb_target_name,
18296                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
18297                 NULL, 0, "Target file name", HFILL }},
18298
18299         { &hf_smb_device_type,
18300                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18301                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18302
18303         { &hf_smb_is_directory,
18304                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18305                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18306
18307         { &hf_smb_next_entry_offset,
18308                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18309                 NULL, 0, "Offset to next entry", HFILL }},
18310
18311         { &hf_smb_change_time,
18312                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18313                 NULL, 0, "Last Change Time", HFILL }},
18314
18315         { &hf_smb_setup_len,
18316                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18317                 NULL, 0, "Length of printer setup data", HFILL }},
18318
18319         { &hf_smb_print_mode,
18320                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18321                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18322
18323         { &hf_smb_print_identifier,
18324                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18325                 NULL, 0, "Identifier string for this print job", HFILL }},
18326
18327         { &hf_smb_restart_index,
18328                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18329                 NULL, 0, "Index of entry after last returned", HFILL }},
18330
18331         { &hf_smb_print_queue_date,
18332                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18333                 NULL, 0, "Date when this entry was queued", HFILL }},
18334
18335         { &hf_smb_print_queue_dos_date,
18336                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18337                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18338
18339         { &hf_smb_print_queue_dos_time,
18340                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18341                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18342
18343         { &hf_smb_print_status,
18344                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18345                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18346
18347         { &hf_smb_print_spool_file_number,
18348                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18349                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18350
18351         { &hf_smb_print_spool_file_size,
18352                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18353                 NULL, 0, "Number of bytes in spool file", HFILL }},
18354
18355         { &hf_smb_print_spool_file_name,
18356                 { "Name", "smb.print.spool.name", FT_STRINGZ, BASE_NONE,
18357                 NULL, 0, "Name of client that submitted this job", HFILL }},
18358
18359         { &hf_smb_start_index,
18360                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18361                 NULL, 0, "First queue entry to return", HFILL }},
18362
18363         { &hf_smb_originator_name,
18364                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18365                 NULL, 0, "Name of sender of message", HFILL }},
18366
18367         { &hf_smb_destination_name,
18368                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18369                 NULL, 0, "Name of recipient of message", HFILL }},
18370
18371         { &hf_smb_message_len,
18372                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18373                 NULL, 0, "Length of message", HFILL }},
18374
18375         { &hf_smb_message,
18376                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18377                 NULL, 0, "Message text", HFILL }},
18378
18379         { &hf_smb_mgid,
18380                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18381                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18382
18383         { &hf_smb_forwarded_name,
18384                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18385                 NULL, 0, "Recipient name being forwarded", HFILL }},
18386
18387         { &hf_smb_machine_name,
18388                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18389                 NULL, 0, "Name of target machine", HFILL }},
18390
18391         { &hf_smb_cancel_to,
18392                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18393                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18394
18395         { &hf_smb_trans_name,
18396                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18397                 NULL, 0, "Name of transaction", HFILL }},
18398
18399         { &hf_smb_transaction_flags_dtid,
18400                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18401                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18402
18403         { &hf_smb_transaction_flags_owt,
18404                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18405                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18406
18407         { &hf_smb_search_count,
18408                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18409                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18410
18411         { &hf_smb_search_pattern,
18412                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18413                 NULL, 0, "Search Pattern", HFILL }},
18414
18415         { &hf_smb_ff2_backup,
18416                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18417                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18418
18419         { &hf_smb_ff2_continue,
18420                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18421                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18422
18423         { &hf_smb_ff2_resume,
18424                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18425                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18426
18427         { &hf_smb_ff2_close_eos,
18428                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18429                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18430
18431         { &hf_smb_ff2_close,
18432                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18433                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18434
18435         { &hf_smb_ff2_information_level,
18436                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18437                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18438
18439         { &hf_smb_qpi_loi,
18440                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18441                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18442
18443         { &hf_smb_spi_loi,
18444                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18445                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18446
18447 #if 0
18448         { &hf_smb_sfi_writetru,
18449                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18450                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18451
18452         { &hf_smb_sfi_caching,
18453                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18454                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18455 #endif
18456
18457         { &hf_smb_storage_type,
18458                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18459                 NULL, 0, "Type of storage", HFILL }},
18460
18461         { &hf_smb_resume,
18462                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18463                 NULL, 0, "Resume Key", HFILL }},
18464
18465         { &hf_smb_max_referral_level,
18466                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18467                 NULL, 0, "Latest referral version number understood", HFILL }},
18468
18469         { &hf_smb_qfsi_information_level,
18470                 { "Level of Interest", "smb.qfsi_loi", FT_UINT16, BASE_HEX,
18471                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18472
18473         { &hf_smb_nt_rename_level,
18474                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18475                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18476
18477         { &hf_smb_cluster_count,
18478                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18479                 NULL, 0, "Number of clusters", HFILL }},
18480
18481         { &hf_smb_number_of_links,
18482                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18483                 NULL, 0, "Number of hard links to the file", HFILL }},
18484
18485         { &hf_smb_delete_pending,
18486                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18487                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18488
18489         { &hf_smb_index_number,
18490                 { "Index Number", "smb.index_number", FT_UINT64, BASE_HEX,
18491                 NULL, 0, "File system unique identifier", HFILL }},
18492
18493         { &hf_smb_position,
18494                 { "Position", "smb.position", FT_UINT64, BASE_DEC,
18495                 NULL, 0, "File position", HFILL }},
18496
18497         { &hf_smb_current_offset,
18498                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18499                 NULL, 0, "Current offset in the file", HFILL }},
18500
18501         { &hf_smb_t2_alignment,
18502                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18503                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18504
18505         { &hf_smb_t2_stream_name_length,
18506                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18507                 NULL, 0, "Length of stream name", HFILL }},
18508
18509         { &hf_smb_t2_stream_size,
18510                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18511                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18512
18513         { &hf_smb_t2_stream_name,
18514                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18515                 NULL, 0, "Name of the stream", HFILL }},
18516
18517         { &hf_smb_t2_compressed_file_size,
18518                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18519                 NULL, 0, "Size of the compressed file", HFILL }},
18520
18521         { &hf_smb_t2_compressed_format,
18522                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18523                 NULL, 0, "Compression algorithm used", HFILL }},
18524
18525         { &hf_smb_t2_compressed_unit_shift,
18526                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18527                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18528
18529         { &hf_smb_t2_compressed_chunk_shift,
18530                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18531                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18532
18533         { &hf_smb_t2_compressed_cluster_shift,
18534                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18535                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18536
18537         { &hf_smb_t2_marked_for_deletion,
18538                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18539                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18540
18541         { &hf_smb_dfs_path_consumed,
18542                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18543                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18544
18545         { &hf_smb_dfs_num_referrals,
18546                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18547                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18548
18549         { &hf_smb_get_dfs_server_hold_storage,
18550                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18551                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18552
18553         { &hf_smb_get_dfs_fielding,
18554                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18555                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18556
18557         { &hf_smb_dfs_referral_version,
18558                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18559                 NULL, 0, "Version of referral element", HFILL }},
18560
18561         { &hf_smb_dfs_referral_size,
18562                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18563                 NULL, 0, "Size of referral element", HFILL }},
18564
18565         { &hf_smb_dfs_referral_server_type,
18566                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18567                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18568
18569         { &hf_smb_dfs_referral_flags_strip,
18570                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18571                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18572
18573         { &hf_smb_dfs_referral_node_offset,
18574                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18575                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18576
18577         { &hf_smb_dfs_referral_node,
18578                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18579                 NULL, 0, "Name of entity to visit next", HFILL }},
18580
18581         { &hf_smb_dfs_referral_proximity,
18582                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18583                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18584
18585         { &hf_smb_dfs_referral_ttl,
18586                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18587                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18588
18589         { &hf_smb_dfs_referral_path_offset,
18590                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18591                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18592
18593         { &hf_smb_dfs_referral_path,
18594                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18595                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18596
18597         { &hf_smb_dfs_referral_alt_path_offset,
18598                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18599                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18600
18601         { &hf_smb_dfs_referral_alt_path,
18602                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18603                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18604
18605         { &hf_smb_end_of_search,
18606                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18607                 NULL, 0, "Was last entry returned?", HFILL }},
18608
18609         { &hf_smb_last_name_offset,
18610                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18611                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18612
18613         { &hf_smb_fn_information_level,
18614                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18615                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18616
18617         { &hf_smb_monitor_handle,
18618                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18619                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18620
18621         { &hf_smb_change_count,
18622                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18623                 NULL, 0, "Number of changes to wait for", HFILL }},
18624
18625         { &hf_smb_file_index,
18626                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18627                 NULL, 0, "File index", HFILL }},
18628
18629         { &hf_smb_short_file_name,
18630                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18631                 NULL, 0, "Short (8.3) File Name", HFILL }},
18632
18633         { &hf_smb_short_file_name_len,
18634                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18635                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18636
18637         { &hf_smb_fs_id,
18638                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18639                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18640
18641         { &hf_smb_sector_unit,
18642                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18643                 NULL, 0, "Sectors per allocation unit", HFILL }},
18644
18645         { &hf_smb_fs_units,
18646                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18647                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18648
18649         { &hf_smb_fs_sector,
18650                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18651                 NULL, 0, "Bytes per sector", HFILL }},
18652
18653         { &hf_smb_avail_units,
18654                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18655                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18656
18657         { &hf_smb_volume_serial_num,
18658                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18659                 NULL, 0, "Volume serial number", HFILL }},
18660
18661         { &hf_smb_volume_label_len,
18662                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18663                 NULL, 0, "Length of volume label", HFILL }},
18664
18665         { &hf_smb_volume_label,
18666                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18667                 NULL, 0, "Volume label", HFILL }},
18668
18669         { &hf_smb_free_alloc_units64,
18670                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18671                 NULL, 0, "Number of free allocation units", HFILL }},
18672
18673         { &hf_smb_caller_free_alloc_units64,
18674                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18675                 NULL, 0, "Number of caller free allocation units", HFILL }},
18676
18677         { &hf_smb_actual_free_alloc_units64,
18678                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18679                 NULL, 0, "Number of actual free allocation units", HFILL }},
18680
18681         { &hf_smb_soft_quota_limit,
18682                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18683                 NULL, 0, "Soft Quota treshold", HFILL }},
18684
18685         { &hf_smb_hard_quota_limit,
18686                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18687                 NULL, 0, "Hard Quota limit", HFILL }},
18688
18689         { &hf_smb_user_quota_used,
18690                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18691                 NULL, 0, "How much Quota is used by this user", HFILL }},
18692
18693         { &hf_smb_max_name_len,
18694                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18695                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18696
18697         { &hf_smb_fs_name_len,
18698                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18699                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18700
18701         { &hf_smb_fs_name,
18702                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18703                 NULL, 0, "Name of filesystem", HFILL }},
18704
18705         { &hf_smb_device_char_removable,
18706                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18707                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18708
18709         { &hf_smb_device_char_read_only,
18710                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18711                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18712
18713         { &hf_smb_device_char_floppy,
18714                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18715                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18716
18717         { &hf_smb_device_char_write_once,
18718                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18719                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18720
18721         { &hf_smb_device_char_remote,
18722                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18723                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18724
18725         { &hf_smb_device_char_mounted,
18726                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18727                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18728
18729         { &hf_smb_device_char_virtual,
18730                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18731                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18732
18733         { &hf_smb_fs_attr_css,
18734                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18735                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18736
18737         { &hf_smb_fs_attr_cpn,
18738                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18739                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18740
18741         { &hf_smb_fs_attr_uod,
18742                 { "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
18743                 TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
18744
18745         { &hf_smb_fs_attr_pacls,
18746                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18747                 TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
18748
18749         { &hf_smb_fs_attr_fc,
18750                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18751                 TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
18752
18753         { &hf_smb_fs_attr_vq,
18754                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18755                 TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
18756
18757         { &hf_smb_fs_attr_ssf,
18758                 { "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
18759                 TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
18760
18761         { &hf_smb_fs_attr_srp,
18762                 { "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
18763                 TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
18764
18765         { &hf_smb_fs_attr_srs,
18766                 { "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
18767                 TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
18768
18769         { &hf_smb_fs_attr_sla,
18770                 { "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
18771                 TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
18772
18773         { &hf_smb_fs_attr_vic,
18774                 { "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
18775                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
18776
18777         { &hf_smb_fs_attr_soids,
18778                 { "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
18779                 TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
18780
18781         { &hf_smb_fs_attr_se,
18782                 { "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
18783                 TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
18784
18785         { &hf_smb_fs_attr_ns,
18786                 { "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
18787                 TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
18788
18789         { &hf_smb_fs_attr_rov,
18790                 { "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
18791                 TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
18792
18793         { &hf_smb_user_quota_offset,
18794                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18795                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18796
18797         { &hf_smb_pipe_write_len,
18798                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18799                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18800
18801         { &hf_smb_quota_flags_deny_disk,
18802                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18803                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18804
18805         { &hf_smb_quota_flags_log_limit,
18806                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18807                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18808
18809         { &hf_smb_quota_flags_log_warning,
18810                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18811                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18812
18813         { &hf_smb_quota_flags_enabled,
18814                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18815                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18816
18817         { &hf_smb_segment_overlap,
18818                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18819                         "Fragment overlaps with other fragments", HFILL }},
18820
18821         { &hf_smb_segment_overlap_conflict,
18822                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18823                         "Overlapping fragments contained conflicting data", HFILL }},
18824
18825         { &hf_smb_segment_multiple_tails,
18826                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18827                         "Several tails were found when defragmenting the packet", HFILL }},
18828
18829         { &hf_smb_segment_too_long_fragment,
18830                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18831                         "Fragment contained data past end of packet", HFILL }},
18832
18833         { &hf_smb_segment_error,
18834                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18835                         "Defragmentation error due to illegal fragments", HFILL }},
18836
18837         { &hf_smb_opened_in,
18838                 { "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18839                         "The frame this fid was opened", HFILL }},
18840
18841         { &hf_smb_closed_in,
18842                 { "Closed in", "smb.fid.closed_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18843                         "The frame this fid was closed", HFILL }},
18844
18845         { &hf_smb_mapped_in,
18846                 { "Mapped in", "smb.fid.mapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18847                         "The frame this share was mapped", HFILL }},
18848
18849         { &hf_smb_unmapped_in,
18850                 { "Unmapped in", "smb.fid.unmapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18851                         "The frame this share was unmapped", HFILL }},
18852
18853         { &hf_smb_segment,
18854                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18855                         "SMB Segment", HFILL }},
18856
18857         { &hf_smb_segments,
18858                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18859                         "SMB Segments", HFILL }},
18860
18861         { &hf_smb_unix_major_version,
18862           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
18863             NULL, 0, "UNIX Major Version", HFILL }},
18864
18865         { &hf_smb_unix_minor_version,
18866           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
18867             NULL, 0, "UNIX Minor Version", HFILL }},
18868
18869         { &hf_smb_unix_capability_fcntl,
18870           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
18871                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18872
18873         { &hf_smb_unix_capability_posix_acl,
18874           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
18875                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18876
18877         { &hf_smb_file_access_mask_read_data,
18878           { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
18879                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18880
18881         { &hf_smb_file_access_mask_write_data,
18882           { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
18883                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18884
18885         { &hf_smb_file_access_mask_append_data,
18886           { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
18887                 TFS(&flags_set_truth), 0x00000004, "", HFILL }},
18888
18889         { &hf_smb_file_access_mask_read_ea,
18890           { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
18891                 TFS(&flags_set_truth), 0x00000008, "", HFILL }},
18892
18893         { &hf_smb_file_access_mask_write_ea,
18894           { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
18895                 TFS(&flags_set_truth), 0x00000010, "", HFILL }},
18896
18897         { &hf_smb_file_access_mask_execute,
18898           { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
18899                 TFS(&flags_set_truth), 0x00000020, "", HFILL }},
18900
18901         { &hf_smb_file_access_mask_read_attribute,
18902           { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
18903                 TFS(&flags_set_truth), 0x00000080, "", HFILL }},
18904
18905         { &hf_smb_file_access_mask_write_attribute,
18906           { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
18907                 TFS(&flags_set_truth), 0x00000100, "", HFILL }},
18908
18909         { &hf_smb_dir_access_mask_list,
18910           { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
18911                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18912
18913         { &hf_smb_dir_access_mask_add_file,
18914           { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
18915                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18916
18917         { &hf_smb_dir_access_mask_add_subdir,
18918           { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
18919                 TFS(&flags_set_truth), 0x00000004, "", HFILL }},
18920
18921         { &hf_smb_dir_access_mask_read_ea,
18922           { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
18923                 TFS(&flags_set_truth), 0x00000008, "", HFILL }},
18924
18925         { &hf_smb_dir_access_mask_write_ea,
18926           { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
18927                 TFS(&flags_set_truth), 0x00000010, "", HFILL }},
18928
18929         { &hf_smb_dir_access_mask_traverse,
18930           { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
18931                 TFS(&flags_set_truth), 0x00000020, "", HFILL }},
18932
18933         { &hf_smb_dir_access_mask_delete_child,
18934           { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
18935                 TFS(&flags_set_truth), 0x00000040, "", HFILL }},
18936
18937         { &hf_smb_dir_access_mask_read_attribute,
18938           { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
18939                 TFS(&flags_set_truth), 0x00000080, "", HFILL }},
18940
18941         { &hf_smb_dir_access_mask_write_attribute,
18942           { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
18943                 TFS(&flags_set_truth), 0x00000100, "", HFILL }},
18944
18945         { &hf_smb_unix_file_size,
18946           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
18947             NULL, 0, "", HFILL }},
18948
18949         { &hf_smb_unix_file_num_bytes,
18950           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
18951             NULL, 0, "Number of bytes used to store the file", HFILL }},
18952
18953         { &hf_smb_unix_file_last_status,
18954           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
18955             NULL, 0, "", HFILL }},
18956
18957         { &hf_smb_unix_file_last_access,
18958           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
18959             NULL, 0, "", HFILL }},
18960
18961         { &hf_smb_unix_file_last_change,
18962           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
18963             NULL, 0, "", HFILL }},
18964
18965         { &hf_smb_unix_file_uid,
18966           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
18967             NULL, 0, "", HFILL }},
18968
18969         { &hf_smb_unix_file_gid,
18970           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
18971             NULL, 0, "", HFILL }},
18972
18973         { &hf_smb_unix_file_type,
18974           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
18975             VALS(unix_file_type_vals), 0, "", HFILL }},
18976
18977         { &hf_smb_unix_file_dev_major,
18978           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
18979             NULL, 0, "", HFILL }},
18980
18981         { &hf_smb_unix_file_dev_minor,
18982           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
18983             NULL, 0, "", HFILL }},
18984
18985         { &hf_smb_unix_file_unique_id,
18986           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
18987             NULL, 0, "", HFILL }},
18988
18989         { &hf_smb_unix_file_permissions,
18990           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
18991             NULL, 0, "", HFILL }},
18992
18993         { &hf_smb_unix_file_nlinks,
18994           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
18995             NULL, 0, "", HFILL }},
18996
18997         { &hf_smb_unix_file_link_dest,
18998           { "Link destination", "smb.unix.file.link_dest", FT_STRING,
18999             BASE_NONE, NULL, 0, "", HFILL }},
19000
19001         { &hf_smb_unix_find_file_nextoffset,
19002           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
19003             NULL, 0, "", HFILL }},
19004
19005         { &hf_smb_unix_find_file_resumekey,
19006           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
19007             NULL, 0, "", HFILL }},
19008
19009         { &hf_smb_network_unknown,
19010           { "Unknown field", "smb.unknown", FT_UINT32, BASE_HEX,
19011             NULL, 0, "", HFILL }},
19012
19013         { &hf_smb_create_flags,
19014           { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
19015             NULL, 0, "", HFILL }},
19016
19017         { &hf_smb_create_options,
19018           { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
19019             NULL, 0, "", HFILL }},
19020
19021         { &hf_smb_share_access,
19022           { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
19023             NULL, 0, "", HFILL }},
19024
19025         { &hf_smb_access_mask,
19026           { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
19027             NULL, 0, "", HFILL }},
19028
19029         { &hf_smb_mode,
19030           { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
19031             NULL, 0, "", HFILL }},
19032
19033         { &hf_smb_attribute,
19034           { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
19035             NULL, 0, "", HFILL }},
19036
19037         { &hf_smb_reparse_tag,
19038           { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
19039             NULL, 0, "", HFILL }},
19040
19041         { &hf_smb_disposition_delete_on_close,
19042           { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
19043                 TFS(&tfs_disposition_delete_on_close), 0x01, "", HFILL }},
19044
19045         { &hf_smb_pipe_info_flag,
19046           { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
19047                 TFS(&tfs_pipe_info_flag), 0x01, "", HFILL }},
19048
19049         { &hf_smb_logged_in,
19050           { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_DEC,
19051                 NULL, 0, "", HFILL }},
19052
19053         { &hf_smb_logged_out,
19054           { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_DEC,
19055                 NULL, 0, "", HFILL }},
19056
19057         { &hf_smb_file_rw_offset,
19058           { "File Offset", "smb.file.rw.offset", FT_UINT32, BASE_DEC,
19059                 NULL, 0, "", HFILL }},
19060
19061         { &hf_smb_file_rw_length,
19062           { "File RW Length", "smb.file.rw.length", FT_UINT32, BASE_DEC,
19063                 NULL, 0, "", HFILL }},
19064
19065         { &hf_smb_posix_acl_version,
19066           { "Posix ACL version", "smb.posix_acl.version", FT_UINT16, BASE_DEC,
19067                 NULL, 0, "", HFILL }},
19068
19069         { &hf_smb_posix_num_file_aces,
19070           { "Number of file ACEs", "smb.posix_acl.num_file_aces", FT_UINT16, BASE_DEC,
19071                 NULL, 0, "", HFILL }},
19072
19073         { &hf_smb_posix_num_def_aces,
19074           { "Number of default ACEs", "smb.posix_acl.num_def_aces", FT_UINT16, BASE_DEC,
19075                 NULL, 0, "", HFILL }},
19076
19077         { &hf_smb_posix_ace_type,
19078           { "ACE Type", "smb.posix_acl.ace_type", FT_UINT8, BASE_DEC,
19079                 VALS(&ace_type_vals), 0, "", HFILL }},
19080
19081         { &hf_smb_posix_ace_flags,
19082           { "Permissions", "smb.posix_acl.ace_perms", FT_UINT8, BASE_HEX,
19083                 NULL, 0, "", HFILL }},
19084
19085         { &hf_smb_posix_ace_perm_read,
19086           {"READ", "smb.posix_acl.ace_perms.read", FT_BOOLEAN, 8,
19087                 NULL, 0x04, "", HFILL}},
19088
19089         { &hf_smb_posix_ace_perm_write,
19090           {"WRITE", "smb.posix_acl.ace_perms.write", FT_BOOLEAN, 8,
19091                 NULL, 0x02, "", HFILL}},
19092
19093         { &hf_smb_posix_ace_perm_execute,
19094           {"EXECUTE", "smb.posix_acl.ace_perms.execute", FT_BOOLEAN, 8,
19095                 NULL, 0x01, "", HFILL}},
19096
19097         { &hf_smb_posix_ace_perm_owner_uid,
19098           { "Owner UID", "smb.posix_acl.ace_perms.owner_uid", FT_UINT32, BASE_DEC,
19099                 NULL, 0, "", HFILL }},
19100
19101         { &hf_smb_posix_ace_perm_owner_gid,
19102           { "Owner GID", "smb.posix_acl.ace_perms.owner_gid", FT_UINT32, BASE_DEC,
19103                 NULL, 0, "", HFILL }},
19104
19105         { &hf_smb_posix_ace_perm_uid,
19106           { "UID", "smb.posix_acl.ace_perms.uid", FT_UINT32, BASE_DEC,
19107                 NULL, 0, "", HFILL }},
19108
19109         { &hf_smb_posix_ace_perm_gid,
19110           { "GID", "smb.posix_acl.ace_perms.gid", FT_UINT32, BASE_DEC,
19111                 NULL, 0, "", HFILL }},
19112
19113         };
19114
19115         static gint *ett[] = {
19116                 &ett_smb,
19117                 &ett_smb_fid,
19118                 &ett_smb_tid,
19119                 &ett_smb_uid,
19120                 &ett_smb_hdr,
19121                 &ett_smb_command,
19122                 &ett_smb_fileattributes,
19123                 &ett_smb_capabilities,
19124                 &ett_smb_aflags,
19125                 &ett_smb_dialect,
19126                 &ett_smb_dialects,
19127                 &ett_smb_mode,
19128                 &ett_smb_rawmode,
19129                 &ett_smb_flags,
19130                 &ett_smb_flags2,
19131                 &ett_smb_desiredaccess,
19132                 &ett_smb_search,
19133                 &ett_smb_file,
19134                 &ett_smb_openfunction,
19135                 &ett_smb_filetype,
19136                 &ett_smb_openaction,
19137                 &ett_smb_writemode,
19138                 &ett_smb_lock_type,
19139                 &ett_smb_ssetupandxaction,
19140                 &ett_smb_optionsup,
19141                 &ett_smb_time_date,
19142                 &ett_smb_move_copy_flags,
19143                 &ett_smb_file_attributes,
19144                 &ett_smb_search_resume_key,
19145                 &ett_smb_search_dir_info,
19146                 &ett_smb_unlocks,
19147                 &ett_smb_unlock,
19148                 &ett_smb_locks,
19149                 &ett_smb_lock,
19150                 &ett_smb_open_flags,
19151                 &ett_smb_ipc_state,
19152                 &ett_smb_open_action,
19153                 &ett_smb_setup_action,
19154                 &ett_smb_connect_flags,
19155                 &ett_smb_connect_support_bits,
19156                 &ett_smb_nt_access_mask,
19157                 &ett_smb_nt_create_bits,
19158                 &ett_smb_nt_create_options,
19159                 &ett_smb_nt_share_access,
19160                 &ett_smb_nt_security_flags,
19161                 &ett_smb_nt_trans_setup,
19162                 &ett_smb_nt_trans_data,
19163                 &ett_smb_nt_trans_param,
19164                 &ett_smb_nt_notify_completion_filter,
19165                 &ett_smb_nt_ioctl_flags,
19166                 &ett_smb_security_information_mask,
19167                 &ett_smb_print_queue_entry,
19168                 &ett_smb_transaction_flags,
19169                 &ett_smb_transaction_params,
19170                 &ett_smb_find_first2_flags,
19171 #if 0
19172                 &ett_smb_ioflag,
19173 #endif
19174                 &ett_smb_transaction_data,
19175                 &ett_smb_stream_info,
19176                 &ett_smb_dfs_referrals,
19177                 &ett_smb_dfs_referral,
19178                 &ett_smb_dfs_referral_flags,
19179                 &ett_smb_get_dfs_flags,
19180                 &ett_smb_ff2_data,
19181                 &ett_smb_device_characteristics,
19182                 &ett_smb_fs_attributes,
19183                 &ett_smb_segments,
19184                 &ett_smb_segment,
19185                 &ett_smb_quotaflags,
19186                 &ett_smb_secblob,
19187                 &ett_smb_mac_support_flags,
19188                 &ett_smb_unicode_password,
19189                 &ett_smb_ea,
19190                 &ett_smb_unix_capabilities,
19191                 &ett_smb_posic_ace,
19192                 &ett_smb_posix_ace_perms
19193         };
19194         module_t *smb_module;
19195
19196         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19197             "SMB", "smb");
19198         proto_register_subtree_array(ett, array_length(ett));
19199         proto_register_field_array(proto_smb, hf, array_length(hf));
19200
19201         proto_do_register_windows_common(proto_smb);
19202
19203         register_init_routine(&smb_init_protocol);
19204         smb_module = prefs_register_protocol(proto_smb, NULL);
19205         prefs_register_bool_preference(smb_module, "trans_reassembly",
19206                 "Reassemble SMB Transaction payload",
19207                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19208                 &smb_trans_reassembly);
19209         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19210                 "Reassemble DCERPC over SMB",
19211                 "Whether the dissector should reassemble DCERPC over SMB commands",
19212                 &smb_dcerpc_reassembly);
19213         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19214                 "Snoop SID to Name mappings",
19215                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19216                 &sid_name_snooping);
19217
19218         register_init_routine(smb_trans_reassembly_init);
19219         smb_tap = register_tap("smb");
19220
19221         register_dissector("smb", dissect_smb, proto_smb);
19222 }
19223
19224 void
19225 proto_reg_handoff_smb(void)
19226 {
19227         dissector_handle_t smb_handle;
19228
19229         gssapi_handle = find_dissector("gssapi");
19230         ntlmssp_handle = find_dissector("ntlmssp");
19231
19232         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19233         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19234         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19235
19236         smb_handle = find_dissector("smb");
19237         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19238         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19239         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER, smb_handle);
19240         dissector_add("spp.socket", IDP_SOCKET_SMB, smb_handle);
19241 }