Fix Dead Store (Dead assignement/Dead increment) Warning found by Clang
[obnox/wireshark/wip.git] / epan / dissectors / packet-smb2.c
1 /* packet-smb2.c
2  * Routines for smb2 packet dissection
3  * Ronnie Sahlberg 2005
4  *
5  * For documentation of this protocol, see:
6  *
7  * http://wiki.wireshark.org/SMB2
8  * http://msdn.microsoft.com/en-us/library/cc246482(PROT.10).aspx
9  *
10  * If you edit this file, keep the wiki updated as well.
11  *
12  * $Id$
13  *
14  * Wireshark - Network traffic analyzer
15  * By Gerald Combs <gerald@wireshark.org>
16  * Copyright 1998 Gerald Combs
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License
20  * as published by the Free Software Foundation; either version 2
21  * of the License, or (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include <epan/packet.h>
38 #include <epan/conversation.h>
39 #include <epan/tap.h>
40 #include <epan/emem.h>
41
42 #include "packet-smb2.h"
43 #include "packet-dcerpc.h"
44 #include "packet-ntlmssp.h"
45 #include "packet-windows-common.h"
46 #include "packet-smb-common.h"
47 #include "packet-smb.h"
48 #include "packet-dcerpc-nt.h"
49 #include <string.h>
50
51
52
53 static int proto_smb2 = -1;
54 static int hf_smb2_cmd = -1;
55 static int hf_smb2_nt_status = -1;
56 static int hf_smb2_response_to = -1;
57 static int hf_smb2_response_in = -1;
58 static int hf_smb2_time = -1;
59 static int hf_smb2_header_len = -1;
60 static int hf_smb2_seqnum = -1;
61 static int hf_smb2_pid = -1;
62 static int hf_smb2_tid = -1;
63 static int hf_smb2_aid = -1;
64 static int hf_smb2_sesid = -1;
65 static int hf_smb2_previous_sesid = -1;
66 static int hf_smb2_flags_response = -1;
67 static int hf_smb2_flags_async_cmd = -1;
68 static int hf_smb2_flags_dfs_op = -1;
69 static int hf_smb2_flags_chained = -1;
70 static int hf_smb2_flags_signature = -1;
71 static int hf_smb2_chain_offset = -1;
72 static int hf_smb2_response_buffer_offset = -1;
73 static int hf_smb2_security_blob_offset = -1;
74 static int hf_smb2_security_blob_len = -1;
75 static int hf_smb2_security_blob = -1;
76 static int hf_smb2_ioctl_in_data = -1;
77 static int hf_smb2_ioctl_out_data = -1;
78 static int hf_smb2_unknown = -1;
79 static int hf_smb2_twrp_timestamp = -1;
80 static int hf_smb2_mxac_timestamp = -1;
81 static int hf_smb2_mxac_status = -1;
82 static int hf_smb2_qfid_fid = -1;
83 static int hf_smb2_create_timestamp = -1;
84 static int hf_smb2_oplock = -1;
85 static int hf_smb2_close_flags = -1;
86 static int hf_smb2_notify_flags = -1;
87 static int hf_smb2_last_access_timestamp = -1;
88 static int hf_smb2_last_write_timestamp = -1;
89 static int hf_smb2_last_change_timestamp = -1;
90 static int hf_smb2_current_time = -1;
91 static int hf_smb2_boot_time = -1;
92 static int hf_smb2_filename = -1;
93 static int hf_smb2_filename_len = -1;
94 static int hf_smb2_nlinks = -1;
95 static int hf_smb2_delete_pending = -1;
96 static int hf_smb2_is_directory = -1;
97 static int hf_smb2_file_id = -1;
98 static int hf_smb2_allocation_size = -1;
99 static int hf_smb2_end_of_file = -1;
100 static int hf_smb2_tree = -1;
101 static int hf_smb2_find_pattern = -1;
102 static int hf_smb2_find_info_level = -1;
103 static int hf_smb2_find_info_blob = -1;
104 static int hf_smb2_client_guid = -1;
105 static int hf_smb2_server_guid = -1;
106 static int hf_smb2_object_id = -1;
107 static int hf_smb2_birth_volume_id = -1;
108 static int hf_smb2_birth_object_id = -1;
109 static int hf_smb2_domain_id = -1;
110 static int hf_smb2_class = -1;
111 static int hf_smb2_infolevel = -1;
112 static int hf_smb2_infolevel_file_info = -1;
113 static int hf_smb2_infolevel_fs_info = -1;
114 static int hf_smb2_infolevel_sec_info = -1;
115 static int hf_smb2_max_response_size = -1;
116 static int hf_smb2_max_ioctl_in_size = -1;
117 static int hf_smb2_max_ioctl_out_size = -1;
118 static int hf_smb2_required_buffer_size = -1;
119 static int hf_smb2_response_size = -1;
120 static int hf_smb2_setinfo_size = -1;
121 static int hf_smb2_setinfo_offset = -1;
122 static int hf_smb2_file_basic_info = -1;
123 static int hf_smb2_file_standard_info = -1;
124 static int hf_smb2_file_internal_info = -1;
125 static int hf_smb2_file_ea_info = -1;
126 static int hf_smb2_file_access_info = -1;
127 static int hf_smb2_file_rename_info = -1;
128 static int hf_smb2_file_disposition_info = -1;
129 static int hf_smb2_file_position_info = -1;
130 static int hf_smb2_file_info_0f = -1;
131 static int hf_smb2_file_mode_info = -1;
132 static int hf_smb2_file_alignment_info = -1;
133 static int hf_smb2_file_all_info = -1;
134 static int hf_smb2_file_allocation_info = -1;
135 static int hf_smb2_file_endoffile_info = -1;
136 static int hf_smb2_file_alternate_name_info = -1;
137 static int hf_smb2_file_stream_info = -1;
138 static int hf_smb2_file_pipe_info = -1;
139 static int hf_smb2_file_compression_info = -1;
140 static int hf_smb2_file_network_open_info = -1;
141 static int hf_smb2_file_attribute_tag_info = -1;
142 static int hf_smb2_fs_info_01 = -1;
143 static int hf_smb2_fs_info_03 = -1;
144 static int hf_smb2_fs_info_04 = -1;
145 static int hf_smb2_fs_info_05 = -1;
146 static int hf_smb2_fs_info_06 = -1;
147 static int hf_smb2_fs_info_07 = -1;
148 static int hf_smb2_fs_objectid_info = -1;
149 static int hf_smb2_sec_info_00 = -1;
150 static int hf_smb2_fid = -1;
151 static int hf_smb2_write_length = -1;
152 static int hf_smb2_write_data = -1;
153 static int hf_smb2_write_flags = -1;
154 static int hf_smb2_write_flags_write_through = -1;
155 static int hf_smb2_write_count = -1;
156 static int hf_smb2_write_remaining = -1;
157 static int hf_smb2_read_length = -1;
158 static int hf_smb2_read_remaining = -1;
159 static int hf_smb2_file_offset = -1;
160 static int hf_smb2_read_data = -1;
161 static int hf_smb2_disposition_delete_on_close = -1;
162 static int hf_smb2_create_disposition = -1;
163 static int hf_smb2_create_chain_offset = -1;
164 static int hf_smb2_create_chain_data = -1;
165 static int hf_smb2_data_offset = -1;
166 static int hf_smb2_data_length = -1;
167 static int hf_smb2_extrainfo = -1;
168 static int hf_smb2_create_action = -1;
169 static int hf_smb2_next_offset = -1;
170 static int hf_smb2_ea_size = -1;
171 static int hf_smb2_ea_flags = -1;
172 static int hf_smb2_ea_name_len = -1;
173 static int hf_smb2_ea_data_len = -1;
174 static int hf_smb2_ea_name = -1;
175 static int hf_smb2_ea_data = -1;
176 static int hf_smb2_buffer_code_len = -1;
177 static int hf_smb2_buffer_code_flags_dyn = -1;
178 static int hf_smb2_olb_offset = -1;
179 static int hf_smb2_olb_length = -1;
180 static int hf_smb2_tag = -1;
181 static int hf_smb2_impersonation_level = -1;
182 static int hf_smb2_ioctl_function = -1;
183 static int hf_smb2_ioctl_function_device = -1;
184 static int hf_smb2_ioctl_function_access = -1;
185 static int hf_smb2_ioctl_function_function = -1;
186 static int hf_smb2_ioctl_function_method = -1;
187 static int hf_smb2_ioctl_shadow_copy_num_volumes = -1;
188 static int hf_smb2_ioctl_shadow_copy_num_labels = -1;
189 static int hf_smb2_ioctl_shadow_copy_count = -1;
190 static int hf_smb2_ioctl_shadow_copy_label = -1;
191 static int hf_smb2_compression_format = -1;
192 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
193 static int hf_smb2_acct_name = -1;
194 static int hf_smb2_domain_name = -1;
195 static int hf_smb2_host_name = -1;
196 static int hf_smb2_auth_frame = -1;
197 static int hf_smb2_tcon_frame = -1;
198 static int hf_smb2_share_type = -1;
199 static int hf_smb2_signature = -1;
200 static int hf_smb2_credit_charge = -1;
201 static int hf_smb2_credits_requested = -1;
202 static int hf_smb2_credits_granted = -1;
203 static int hf_smb2_dialect_count = -1;
204 static int hf_smb2_security_mode = -1;
205 static int hf_smb2_secmode_flags_sign_required = -1;
206 static int hf_smb2_secmode_flags_sign_enabled = -1;
207 static int hf_smb2_capabilities = -1;
208 static int hf_smb2_cap_dfs = -1;
209 static int hf_smb2_cap_leasing = -1;
210 static int hf_smb2_cap_large_mtu = -1;
211 static int hf_smb2_dialect = -1;
212 static int hf_smb2_max_trans_size = -1;
213 static int hf_smb2_max_read_size = -1;
214 static int hf_smb2_max_write_size = -1;
215 static int hf_smb2_vcnum = -1;
216 static int hf_smb2_channel = -1;
217 static int hf_smb2_session_flags = -1;
218 static int hf_smb2_ses_flags_guest = -1;
219 static int hf_smb2_ses_flags_null = -1;
220 static int hf_smb2_share_flags = -1;
221 static int hf_smb2_share_flags_dfs = -1;
222 static int hf_smb2_share_flags_dfs_root = -1;
223 static int hf_smb2_share_flags_restrict_exclusive_opens = -1;
224 static int hf_smb2_share_flags_force_shared_delete = -1;
225 static int hf_smb2_share_flags_allow_namespace_caching = -1;
226 static int hf_smb2_share_flags_access_based_dir_enum = -1;
227 static int hf_smb2_share_flags_force_levelii_oplock = -1;
228 static int hf_smb2_share_flags_enable_hash = -1;
229 static int hf_smb2_share_caching = -1;
230 static int hf_smb2_share_caps = -1;
231 static int hf_smb2_share_caps_dfs = -1;
232 static int hf_smb2_create_flags = -1;
233 static int hf_smb2_lock_count = -1;
234 static int hf_smb2_min_count = -1;
235 static int hf_smb2_remaining_bytes = -1;
236 static int hf_smb2_channel_info_offset = -1;
237 static int hf_smb2_channel_info_length = -1;
238 static int hf_smb2_ioctl_flags = -1;
239 static int hf_smb2_ioctl_is_fsctl = -1;
240 static int hf_smb2_close_pq_attrib = -1;
241 static int hf_smb2_notify_watch_tree = -1;
242 static int hf_smb2_output_buffer_len = -1;
243 static int hf_smb2_notify_out_data = -1;
244 static int hf_smb2_find_flags = -1;
245 static int hf_smb2_find_flags_restart_scans = -1;
246 static int hf_smb2_find_flags_single_entry = -1;
247 static int hf_smb2_find_flags_index_specified = -1;
248 static int hf_smb2_find_flags_reopen = -1;
249 static int hf_smb2_file_index = -1;
250 static int hf_smb2_file_directory_info = -1;
251 static int hf_smb2_both_directory_info = -1;
252 static int hf_smb2_short_name_len = -1;
253 static int hf_smb2_short_name = -1;
254 static int hf_smb2_id_both_directory_info = -1;
255 static int hf_smb2_full_directory_info = -1;
256 static int hf_smb2_file_name_info = -1;
257 static int hf_smb2_lock_info = -1;
258 static int hf_smb2_lock_length = -1;
259 static int hf_smb2_lock_flags = -1;
260 static int hf_smb2_lock_flags_shared = -1;
261 static int hf_smb2_lock_flags_exclusive = -1;
262 static int hf_smb2_lock_flags_unlock = -1;
263 static int hf_smb2_lock_flags_fail_immediately = -1;
264 static int hf_smb2_dhnq_buffer_reserved = -1;
265 static int hf_smb2_error_byte_count = -1;
266 static int hf_smb2_error_data = -1;
267 static int hf_smb2_error_reserved = -1;
268 static int hf_smb2_reserved = -1;
269
270 static gint ett_smb2 = -1;
271 static gint ett_smb2_olb = -1;
272 static gint ett_smb2_ea = -1;
273 static gint ett_smb2_header = -1;
274 static gint ett_smb2_command = -1;
275 static gint ett_smb2_secblob = -1;
276 static gint ett_smb2_file_basic_info = -1;
277 static gint ett_smb2_file_standard_info = -1;
278 static gint ett_smb2_file_internal_info = -1;
279 static gint ett_smb2_file_ea_info = -1;
280 static gint ett_smb2_file_access_info = -1;
281 static gint ett_smb2_file_position_info = -1;
282 static gint ett_smb2_file_mode_info = -1;
283 static gint ett_smb2_file_alignment_info = -1;
284 static gint ett_smb2_file_all_info = -1;
285 static gint ett_smb2_file_allocation_info = -1;
286 static gint ett_smb2_file_endoffile_info = -1;
287 static gint ett_smb2_file_alternate_name_info = -1;
288 static gint ett_smb2_file_stream_info = -1;
289 static gint ett_smb2_file_pipe_info = -1;
290 static gint ett_smb2_file_compression_info = -1;
291 static gint ett_smb2_file_network_open_info = -1;
292 static gint ett_smb2_file_attribute_tag_info = -1;
293 static gint ett_smb2_file_rename_info = -1;
294 static gint ett_smb2_file_disposition_info = -1;
295 static gint ett_smb2_file_info_0f = -1;
296 static gint ett_smb2_fs_info_01 = -1;
297 static gint ett_smb2_fs_info_03 = -1;
298 static gint ett_smb2_fs_info_04 = -1;
299 static gint ett_smb2_fs_info_05 = -1;
300 static gint ett_smb2_fs_info_06 = -1;
301 static gint ett_smb2_fs_info_07 = -1;
302 static gint ett_smb2_fs_objectid_info = -1;
303 static gint ett_smb2_sec_info_00 = -1;
304 static gint ett_smb2_tid_tree = -1;
305 static gint ett_smb2_sesid_tree = -1;
306 static gint ett_smb2_create_chain_element = -1;
307 static gint ett_smb2_MxAc_buffer = -1;
308 static gint ett_smb2_QFid_buffer = -1;
309 static gint ett_smb2_ioctl_function = -1;
310 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
311 static gint ett_smb2_flags = -1;
312 static gint ett_smb2_sec_mode = -1;
313 static gint ett_smb2_capabilities = -1;
314 static gint ett_smb2_ses_flags = -1;
315 static gint ett_smb2_share_flags = -1;
316 static gint ett_smb2_share_caps = -1;
317 static gint ett_smb2_ioctl_flags = -1;
318 static gint ett_smb2_close_flags = -1;
319 static gint ett_smb2_notify_flags = -1;
320 static gint ett_smb2_write_flags = -1;
321 static gint ett_smb2_find_flags = -1;
322 static gint ett_smb2_file_directory_info = -1;
323 static gint ett_smb2_both_directory_info = -1;
324 static gint ett_smb2_id_both_directory_info = -1;
325 static gint ett_smb2_full_directory_info = -1;
326 static gint ett_smb2_file_name_info = -1;
327 static gint ett_smb2_lock_info = -1;
328 static gint ett_smb2_lock_flags = -1;
329
330 static int smb2_tap = -1;
331
332 static dissector_handle_t gssapi_handle = NULL;
333 static dissector_handle_t ntlmssp_handle = NULL;
334
335 static heur_dissector_list_t smb2_heur_subdissector_list;
336
337 #define SMB2_CLASS_FILE_INFO    0x01
338 #define SMB2_CLASS_FS_INFO      0x02
339 #define SMB2_CLASS_SEC_INFO     0x03
340 static const value_string smb2_class_vals[] = {
341         { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
342         { SMB2_CLASS_FS_INFO,   "FS_INFO"},
343         { SMB2_CLASS_SEC_INFO,  "SEC_INFO"},
344         { 0, NULL }
345 };
346
347 #define SMB2_SHARE_TYPE_DISK    0x01
348 #define SMB2_SHARE_TYPE_PIPE    0x02
349 #define SMB2_SHARE_TYPE_PRINT   0x03
350 static const value_string smb2_share_type_vals[] = {
351         { SMB2_SHARE_TYPE_DISK,         "Physical disk" },
352         { SMB2_SHARE_TYPE_PIPE,         "Named pipe" },
353         { SMB2_SHARE_TYPE_PRINT,        "Printer" },
354         { 0, NULL }
355 };
356
357
358 #define SMB2_FILE_BASIC_INFO    0x04
359 #define SMB2_FILE_STANDARD_INFO 0x05
360 #define SMB2_FILE_INTERNAL_INFO 0x06
361 #define SMB2_FILE_EA_INFO       0x07
362 #define SMB2_FILE_ACCESS_INFO   0x08
363 #define SMB2_FILE_RENAME_INFO   0x0a
364 #define SMB2_FILE_DISPOSITION_INFO      0x0d
365 #define SMB2_FILE_POSITION_INFO 0x0e
366 #define SMB2_FILE_INFO_0f       0x0f
367 #define SMB2_FILE_MODE_INFO     0x10
368 #define SMB2_FILE_ALIGNMENT_INFO        0x11
369 #define SMB2_FILE_ALL_INFO      0x12
370 #define SMB2_FILE_ALLOCATION_INFO       0x13
371 #define SMB2_FILE_ENDOFFILE_INFO        0x14
372 #define SMB2_FILE_ALTERNATE_NAME_INFO   0x15
373 #define SMB2_FILE_STREAM_INFO           0x16
374 #define SMB2_FILE_PIPE_INFO             0x17
375 #define SMB2_FILE_COMPRESSION_INFO      0x1c
376 #define SMB2_FILE_NETWORK_OPEN_INFO     0x22
377 #define SMB2_FILE_ATTRIBUTE_TAG_INFO    0x23
378 static const value_string smb2_file_info_levels[] = {
379         {SMB2_FILE_BASIC_INFO,          "SMB2_FILE_BASIC_INFO" },
380         {SMB2_FILE_STANDARD_INFO,       "SMB2_FILE_STANDARD_INFO" },
381         {SMB2_FILE_INTERNAL_INFO,       "SMB2_FILE_INTERNAL_INFO" },
382         {SMB2_FILE_EA_INFO,             "SMB2_FILE_EA_INFO" },
383         {SMB2_FILE_ACCESS_INFO,         "SMB2_FILE_ACCESS_INFO" },
384         {SMB2_FILE_RENAME_INFO,         "SMB2_FILE_RENAME_INFO" },
385         {SMB2_FILE_DISPOSITION_INFO,    "SMB2_FILE_DISPOSITION_INFO" },
386         {SMB2_FILE_POSITION_INFO,       "SMB2_FILE_POSITION_INFO" },
387         {SMB2_FILE_INFO_0f,             "SMB2_FILE_INFO_0f" },
388         {SMB2_FILE_MODE_INFO,           "SMB2_FILE_MODE_INFO" },
389         {SMB2_FILE_ALIGNMENT_INFO,      "SMB2_FILE_ALIGNMENT_INFO" },
390         {SMB2_FILE_ALL_INFO,            "SMB2_FILE_ALL_INFO" },
391         {SMB2_FILE_ALLOCATION_INFO,     "SMB2_FILE_ALLOCATION_INFO" },
392         {SMB2_FILE_ENDOFFILE_INFO,      "SMB2_FILE_ENDOFFILE_INFO" },
393         {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
394         {SMB2_FILE_STREAM_INFO,         "SMB2_FILE_STREAM_INFO" },
395         {SMB2_FILE_PIPE_INFO,           "SMB2_FILE_PIPE_INFO" },
396         {SMB2_FILE_COMPRESSION_INFO,    "SMB2_FILE_COMPRESSION_INFO" },
397         {SMB2_FILE_NETWORK_OPEN_INFO,   "SMB2_FILE_NETWORK_OPEN_INFO" },
398         {SMB2_FILE_ATTRIBUTE_TAG_INFO,  "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
399         { 0, NULL }
400 };
401
402
403
404 #define SMB2_FS_INFO_01         0x01
405 #define SMB2_FS_INFO_03         0x03
406 #define SMB2_FS_INFO_04         0x04
407 #define SMB2_FS_INFO_05         0x05
408 #define SMB2_FS_INFO_06         0x06
409 #define SMB2_FS_INFO_07         0x07
410 #define SMB2_FS_OBJECTID_INFO   0x08
411 static const value_string smb2_fs_info_levels[] = {
412         {SMB2_FS_INFO_01,       "SMB2_FS_INFO_01" },
413         {SMB2_FS_INFO_03,       "SMB2_FS_INFO_03" },
414         {SMB2_FS_INFO_04,       "SMB2_FS_INFO_04" },
415         {SMB2_FS_INFO_05,       "SMB2_FS_INFO_05" },
416         {SMB2_FS_INFO_06,       "SMB2_FS_INFO_06" },
417         {SMB2_FS_INFO_07,       "SMB2_FS_INFO_07" },
418         {SMB2_FS_OBJECTID_INFO, "SMB2_FS_OBJECTID_INFO" },
419         { 0, NULL }
420 };
421
422 #define SMB2_SEC_INFO_00        0x00
423 static const value_string smb2_sec_info_levels[] = {
424         {SMB2_SEC_INFO_00,      "SMB2_SEC_INFO_00" },
425         { 0, NULL }
426 };
427
428 #define SMB2_FIND_DIRECTORY_INFO         0x01
429 #define SMB2_FIND_FULL_DIRECTORY_INFO    0x02
430 #define SMB2_FIND_BOTH_DIRECTORY_INFO    0x03
431 #define SMB2_FIND_INDEX_SPECIFIED        0x04
432 #define SMB2_FIND_NAME_INFO              0x0C
433 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
434 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
435 static const value_string smb2_find_info_levels[] = {
436         { SMB2_FIND_DIRECTORY_INFO,             "SMB2_FIND_DIRECTORY_INFO" },
437         { SMB2_FIND_FULL_DIRECTORY_INFO,        "SMB2_FIND_FULL_DIRECTORY_INFO" },
438         { SMB2_FIND_BOTH_DIRECTORY_INFO,        "SMB2_FIND_BOTH_DIRECTORY_INFO" },
439         { SMB2_FIND_INDEX_SPECIFIED,            "SMB2_FIND_INDEX_SPECIFIED" },
440         { SMB2_FIND_NAME_INFO,                  "SMB2_FIND_NAME_INFO" },
441         { SMB2_FIND_ID_BOTH_DIRECTORY_INFO,     "SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
442         { SMB2_FIND_ID_FULL_DIRECTORY_INFO,     "SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
443         { 0, NULL }
444 };
445
446 /* unmatched smb_saved_info structures.
447    For unmatched smb_saved_info structures we store the smb_saved_info
448    structure using the SEQNUM field.
449 */
450 static gint
451 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
452 {
453         smb2_saved_info_t *key1 = (smb2_saved_info_t *)k1;
454         smb2_saved_info_t *key2 = (smb2_saved_info_t *)k2;
455         return key1->seqnum==key2->seqnum;
456 }
457 static guint
458 smb2_saved_info_hash_unmatched(gconstpointer k)
459 {
460         smb2_saved_info_t *key = (smb2_saved_info_t *)k;
461         guint32 hash;
462
463         hash=(guint32) (key->seqnum&0xffffffff);
464         return hash;
465 }
466
467 /* matched smb_saved_info structures.
468    For matched smb_saved_info structures we store the smb_saved_info
469    structure using the SEQNUM field.
470 */
471 static gint
472 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
473 {
474         smb2_saved_info_t *key1 = (smb2_saved_info_t *)k1;
475         smb2_saved_info_t *key2 = (smb2_saved_info_t *)k2;
476         return key1->seqnum==key2->seqnum;
477 }
478 static guint
479 smb2_saved_info_hash_matched(gconstpointer k)
480 {
481         smb2_saved_info_t *key = (smb2_saved_info_t *)k;
482         guint32 hash;
483
484         hash=(guint32) (key->seqnum&0xffffffff);
485         return hash;
486 }
487
488 /* For Tids of a specific conversation.
489    This keeps track of tid->sharename mappings and other information about the
490    tid.
491    qqq
492    We might need to refine this if it occurs that tids are reused on a single
493    conversation.   we dont worry about that yet for simplicity
494 */
495 static gint
496 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
497 {
498         smb2_tid_info_t *key1 = (smb2_tid_info_t *)k1;
499         smb2_tid_info_t *key2 = (smb2_tid_info_t *)k2;
500         return key1->tid==key2->tid;
501 }
502 static guint
503 smb2_tid_info_hash(gconstpointer k)
504 {
505         smb2_tid_info_t *key = (smb2_tid_info_t *)k;
506         guint32 hash;
507
508         hash=key->tid;
509         return hash;
510 }
511
512 /* For Uids of a specific conversation.
513    This keeps track of uid->acct_name mappings and other information about the
514    uid.
515    qqq
516    We might need to refine this if it occurs that uids are reused on a single
517    conversation.   we dont worry about that yet for simplicity
518 */
519 static gint
520 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
521 {
522         smb2_sesid_info_t *key1 = (smb2_sesid_info_t *)k1;
523         smb2_sesid_info_t *key2 = (smb2_sesid_info_t *)k2;
524         return key1->sesid==key2->sesid;
525 }
526 static guint
527 smb2_sesid_info_hash(gconstpointer k)
528 {
529         smb2_sesid_info_t *key = (smb2_sesid_info_t *)k;
530         guint32 hash;
531
532         hash=(guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
533         return hash;
534 }
535
536 static int dissect_smb2_file_info_0f(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
537
538
539 /* This is a helper to dissect the common string type
540  * uint16 offset
541  * uint16 length
542  * ...
543  * char *string
544  *
545  * This function is called twice, first to decode the offset/length and
546  * second time to dissect the actual string.
547  * It is done this way since there is no guarantee that we have the full packet and we dont
548  * want to abort dissection too early if the packet ends somewhere between the
549  * length/offset and the actual buffer.
550  *
551  */
552 enum offset_length_buffer_offset_size {
553         OLB_O_UINT16_S_UINT16,
554         OLB_O_UINT16_S_UINT32,
555         OLB_O_UINT32_S_UINT32,
556         OLB_S_UINT32_O_UINT32
557 };
558 typedef struct _offset_length_buffer_t {
559         guint32 off;
560         guint32 len;
561         int off_offset;
562         int len_offset;
563         enum offset_length_buffer_offset_size offset_size;
564         int hfindex;
565 } offset_length_buffer_t;
566 static int
567 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
568                                enum offset_length_buffer_offset_size offset_size, int hfindex)
569 {
570         olb->hfindex=hfindex;
571         olb->offset_size=offset_size;
572         switch(offset_size){
573         case OLB_O_UINT16_S_UINT16:
574                 olb->off=tvb_get_letohs(tvb, offset);
575                 olb->off_offset=offset;
576                 offset += 2;
577                 olb->len=tvb_get_letohs(tvb, offset);
578                 olb->len_offset=offset;
579                 offset += 2;
580                 break;
581         case OLB_O_UINT16_S_UINT32:
582                 olb->off=tvb_get_letohs(tvb, offset);
583                 olb->off_offset=offset;
584                 offset += 2;
585                 olb->len=tvb_get_letohl(tvb, offset);
586                 olb->len_offset=offset;
587                 offset += 4;
588                 break;
589         case OLB_O_UINT32_S_UINT32:
590                 olb->off=tvb_get_letohl(tvb, offset);
591                 olb->off_offset=offset;
592                 offset += 4;
593                 olb->len=tvb_get_letohl(tvb, offset);
594                 olb->len_offset=offset;
595                 offset += 4;
596                 break;
597         case OLB_S_UINT32_O_UINT32:
598                 olb->len=tvb_get_letohl(tvb, offset);
599                 olb->len_offset=offset;
600                 offset += 4;
601                 olb->off=tvb_get_letohl(tvb, offset);
602                 olb->off_offset=offset;
603                 offset += 4;
604                 break;
605         }
606
607         return offset;
608 }
609
610 #define OLB_TYPE_UNICODE_STRING         0x01
611 #define OLB_TYPE_ASCII_STRING           0x02
612 static const char *
613 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
614 {
615         int len, off;
616         proto_item *item=NULL;
617         proto_tree *tree=NULL;
618         const char *name=NULL;
619         guint16 bc;
620         int offset;
621
622         offset=olb->off;
623         len=olb->len;
624         off=olb->off;
625         bc=tvb_length_remaining(tvb, offset);
626
627
628         /* sanity check */
629         tvb_ensure_bytes_exist(tvb, off, len);
630         if(((off+len)<off)
631         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))){
632                 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
633                                     "Invalid offset/length. Malformed packet");
634
635                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
636
637                 return NULL;
638         }
639
640
641         switch(type){
642         case OLB_TYPE_UNICODE_STRING:
643                 name = get_unicode_or_ascii_string(tvb, &off,
644                         TRUE, &len, TRUE, TRUE, &bc);
645                 if(!name){
646                         name="";
647                 }
648                 if(parent_tree){
649                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
650                         tree = proto_item_add_subtree(item, ett_smb2_olb);
651                 }
652                 break;
653         case OLB_TYPE_ASCII_STRING:
654                 name = get_unicode_or_ascii_string(tvb, &off,
655                         FALSE, &len, TRUE, TRUE, &bc);
656                 if(!name){
657                         name="";
658                 }
659                 if(parent_tree){
660                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
661                         tree = proto_item_add_subtree(item, ett_smb2_olb);
662                 }
663                 break;
664         }
665
666         switch(olb->offset_size){
667         case OLB_O_UINT16_S_UINT16:
668                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
669                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, TRUE);
670                 break;
671         case OLB_O_UINT16_S_UINT32:
672                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
673                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
674                 break;
675         case OLB_O_UINT32_S_UINT32:
676                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
677                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
678                 break;
679         case OLB_S_UINT32_O_UINT32:
680                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
681                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
682                 break;
683         }
684
685         return name;
686 }
687
688 static void
689 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
690                         offset_length_buffer_t *olb, smb2_info_t *si,
691                         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
692 {
693         int len, off;
694         proto_item *sub_item=NULL;
695         proto_tree *sub_tree=NULL;
696         tvbuff_t *sub_tvb=NULL;
697         int offset;
698
699         offset=olb->off;
700         len=olb->len;
701         off=olb->off;
702
703         /* sanity check */
704         tvb_ensure_bytes_exist(tvb, off, len);
705         if(((off+len)<off)
706         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))){
707                 proto_tree_add_text(parent_tree, tvb, offset, tvb_length_remaining(tvb, offset),
708                                     "Invalid offset/length. Malformed packet");
709
710                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
711
712                 return;
713         }
714
715         /* if we dont want/need a subtree */
716         if(olb->hfindex==-1){
717                 sub_item=parent_tree;
718                 sub_tree=parent_tree;
719         } else {
720                 if(parent_tree){
721                         sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, TRUE);
722                         sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
723                 }
724         }
725
726         switch(olb->offset_size){
727         case OLB_O_UINT16_S_UINT16:
728                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
729                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, TRUE);
730                 break;
731         case OLB_O_UINT16_S_UINT32:
732                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
733                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
734                 break;
735         case OLB_O_UINT32_S_UINT32:
736                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
737                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
738                 break;
739         case OLB_S_UINT32_O_UINT32:
740                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
741                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
742                 break;
743         }
744
745         if (off == 0 || len == 0) {
746                 proto_item_append_text(sub_item, ": NO DATA");
747                 return;
748         }
749
750         if (!dissector) {
751                 return;
752         }
753
754         sub_tvb=tvb_new_subset(tvb, off, MIN((int)len, tvb_length_remaining(tvb, off)), len);
755
756         dissector(sub_tvb, pinfo, sub_tree, si);
757
758         return;
759 }
760
761 static int
762 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
763 {
764         if (olb->off == 0) {
765                 return offset;
766         }
767         return MAX(offset, (int)(olb->off + olb->len));
768 }
769
770 typedef struct _smb2_function {
771        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
772        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
773 } smb2_function;
774
775 static const true_false_string tfs_flags_response = {
776         "This is a RESPONSE",
777         "This is a REQUEST"
778 };
779
780 static const true_false_string tfs_flags_async_cmd = {
781         "This is an ASYNC command",
782         "This is a SYNC command"
783 };
784
785 static const true_false_string tfs_flags_dfs_op = {
786         "This is a DFS OPERATION",
787         "This is a normal operation"
788 };
789
790 static const true_false_string tfs_flags_chained = {
791         "This pdu a CHAINED command",
792         "This pdu is NOT a chained command"
793 };
794
795 static const true_false_string tfs_flags_signature = {
796         "This pdu is SIGNED",
797         "This pdu is NOT signed"
798 };
799
800 static const true_false_string tfs_cap_dfs = {
801         "This host supports DFS",
802         "This host does NOT support DFS"
803 };
804
805 static const true_false_string tfs_cap_leasing = {
806         "This host supports LEASING",
807         "This host does NOT support LEASING"
808 };
809
810 static const true_false_string tfs_cap_large_mtu = {
811         "This host supports LARGE_MTU",
812         "This host does NOT support LARGE_MTU"
813 };
814
815 static const value_string compression_format_vals[] = {
816   { 0, "COMPRESSION_FORMAT_NONE" },
817   { 1, "COMPRESSION_FORMAT_DEFAULT" },
818   { 2, "COMPRESSION_FORMAT_LZNT1" },
819   { 0, NULL }
820 };
821
822
823 static const value_string smb2_ioctl_vals[] = {
824   /* dissector implemented */
825   {0x0011c017, "IOCTL_DO_DCERPC"},
826   {0x00144064, "FSCTL_GET_SHADOW_COPY_DATA"},
827   {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},
828   {0x0009009C, "FSCTL_GET_OBJECT_ID"},
829   {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
830   {0x00098098, "FSCTL_SET_OBJECT_ID"},
831   {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},
832   {0x0009003C, "FSCTL_GET_COMPRESSION"},
833   {0x0009C040, "FSCTL_SET_COMPRESSION"},
834
835   /* dissector not yet implemented */
836   {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
837   {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
838   {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
839   {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
840   {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
841   {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
842   {0x00090018, "FSCTL_LOCK_VOLUME"},
843   {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
844   {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
845   {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
846   {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
847   {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
848   {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
849   {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
850   {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
851   {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
852   {0x00090058, "FSCTL_QUERY_FAT_BPB"},
853   {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
854   {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
855   {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
856   {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
857   {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
858   {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
859   {0x00090074, "FSCTL_MOVE_FILE"},
860   {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
861   {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
862   {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
863   {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
864   {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
865   {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
866   {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
867   {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
868   {0x000900A8, "FSCTL_GET_REPARSE_POINT"},
869   {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
870   {0x000940B3, "FSCTL_ENUM_USN_DATA"},
871   {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
872   {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
873   {0x000980C4, "FSCTL_SET_SPARSE"},
874   {0x000980C8, "FSCTL_SET_ZERO_DATA"},
875   {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},
876   {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
877   {0x000900D4, "FSCTL_SET_ENCRYPTION"},
878   {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
879   {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
880   {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
881   {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
882   {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
883   {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
884   {0x000900F0, "FSCTL_EXTEND_VOLUME"},
885   { 0, NULL }
886 };
887
888
889 static const value_string smb2_ioctl_device_vals[] = {
890   { 0x0001, "BEEP" },
891   { 0x0002, "CD_ROM" },
892   { 0x0003, "CD_ROM_FILE_SYSTEM" },
893   { 0x0004, "CONTROLLER" },
894   { 0x0005, "DATALINK" },
895   { 0x0006, "DFS" },
896   { 0x0007, "DISK" },
897   { 0x0008, "DISK_FILE_SYSTEM" },
898   { 0x0009, "FILE_SYSTEM" },
899   { 0x000a, "INPORT_PORT" },
900   { 0x000b, "KEYBOARD" },
901   { 0x000c, "MAILSLOT" },
902   { 0x000d, "MIDI_IN" },
903   { 0x000e, "MIDI_OUT" },
904   { 0x000f, "MOUSE" },
905   { 0x0010, "MULTI_UNC_PROVIDER" },
906   { 0x0011, "NAMED_PIPE" },
907   { 0x0012, "NETWORK" },
908   { 0x0013, "NETWORK_BROWSER" },
909   { 0x0014, "NETWORK_FILE_SYSTEM" },
910   { 0x0015, "NULL" },
911   { 0x0016, "PARALLEL_PORT" },
912   { 0x0017, "PHYSICAL_NETCARD" },
913   { 0x0018, "PRINTER" },
914   { 0x0019, "SCANNER" },
915   { 0x001a, "SERIAL_MOUSE_PORT" },
916   { 0x001b, "SERIAL_PORT" },
917   { 0x001c, "SCREEN" },
918   { 0x001d, "SOUND" },
919   { 0x001e, "STREAMS" },
920   { 0x001f, "TAPE" },
921   { 0x0020, "TAPE_FILE_SYSTEM" },
922   { 0x0021, "TRANSPORT" },
923   { 0x0022, "UNKNOWN" },
924   { 0x0023, "VIDEO" },
925   { 0x0024, "VIRTUAL_DISK" },
926   { 0x0025, "WAVE_IN" },
927   { 0x0026, "WAVE_OUT" },
928   { 0x0027, "8042_PORT" },
929   { 0x0028, "NETWORK_REDIRECTOR" },
930   { 0x0029, "BATTERY" },
931   { 0x002a, "BUS_EXTENDER" },
932   { 0x002b, "MODEM" },
933   { 0x002c, "VDM" },
934   { 0x002d, "MASS_STORAGE" },
935   { 0x002e, "SMB" },
936   { 0x002f, "KS" },
937   { 0x0030, "CHANGER" },
938   { 0x0031, "SMARTCARD" },
939   { 0x0032, "ACPI" },
940   { 0x0033, "DVD" },
941   { 0x0034, "FULLSCREEN_VIDEO" },
942   { 0x0035, "DFS_FILE_SYSTEM" },
943   { 0x0036, "DFS_VOLUME" },
944   { 0x0037, "SERENUM" },
945   { 0x0038, "TERMSRV" },
946   { 0x0039, "KSEC" },
947   { 0, NULL }
948 };
949
950 static const value_string smb2_ioctl_access_vals[] = {
951   { 0x00, "FILE_ANY_ACCESS" },
952   { 0x01, "FILE_READ_ACCESS" },
953   { 0x02, "FILE_WRITE_ACCESS" },
954   { 0x03, "FILE_READ_WRITE_ACCESS" },
955   { 0, NULL }
956 };
957
958 static const value_string smb2_ioctl_method_vals[] = {
959   { 0x00, "METHOD_BUFFERED" },
960   { 0x01, "METHOD_IN_DIRECT" },
961   { 0x02, "METHOD_OUT_DIRECT" },
962   { 0x03, "METHOD_NEITHER" },
963   { 0, NULL }
964 };
965
966 /* this is called from both smb and smb2. */
967 int
968 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
969 {
970         proto_item *item=NULL;
971         proto_tree *tree=NULL;
972         guint32 ioctl_function;
973
974         if(parent_tree){
975                 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, TRUE);
976                 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
977         }
978
979         ioctl_function=tvb_get_letohl(tvb, offset);
980         if (ioctlfunc)
981                 *ioctlfunc=ioctl_function;
982         if(ioctl_function){
983                 /* device */
984                 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, TRUE);
985                 if (check_col(pinfo->cinfo, COL_INFO)){
986                         col_append_fstr(
987                                 pinfo->cinfo, COL_INFO, " %s",
988                                 val_to_str((ioctl_function>>16)&0xffff, smb2_ioctl_device_vals,
989                                 "Unknown (0x%08X)"));
990                 }
991
992                 /* access */
993                 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, TRUE);
994
995                 /* function */
996                 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, TRUE);
997                 if (check_col(pinfo->cinfo, COL_INFO)){
998                         col_append_fstr(
999                                 pinfo->cinfo, COL_INFO, " Function:0x%04x",
1000                                 (ioctl_function>>2)&0x0fff);
1001                 }
1002
1003                 /* method */
1004                 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, TRUE);
1005         }
1006
1007         offset += 4;
1008
1009         return offset;
1010 }
1011
1012 /* fake the dce/rpc support structures so we can piggy back on
1013  * dissect_nt_policy_hnd()   since this will allow us
1014  * a cheap way to track where FIDs are opened, closed
1015  * and fid->filename mappings
1016  * if we want to do those things in the future.
1017  */
1018 #define FID_MODE_OPEN           0
1019 #define FID_MODE_CLOSE          1
1020 #define FID_MODE_USE            2
1021 #define FID_MODE_DHNQ           3
1022 #define FID_MODE_DHNC           4
1023 static int
1024 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
1025 {
1026         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1027         static dcerpc_info di;  /* fake dcerpc_info struct */
1028         static dcerpc_call_value call_data;
1029         void *old_private_data;
1030         e_ctx_hnd policy_hnd;
1031         proto_item *hnd_item=NULL;
1032         char *fid_name;
1033         guint32 open_frame = 0, close_frame = 0;
1034
1035         di.conformant_run=0;
1036         /* we need di->call_data->flags.NDR64 == 0 */
1037         di.call_data=&call_data;
1038         old_private_data=pinfo->private_data;
1039         pinfo->private_data=&di;
1040
1041         switch(mode){
1042         case FID_MODE_OPEN:
1043                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
1044                 if(!pinfo->fd->flags.visited){
1045                         if(si->saved && si->saved->extra_info_type==SMB2_EI_FILENAME){
1046                                 fid_name = se_strdup_printf("File: %s", (char *)si->saved->extra_info);
1047                         } else {
1048                                 fid_name = se_strdup_printf("File: ");
1049                         }
1050                         dcerpc_store_polhnd_name(&policy_hnd, pinfo,
1051                                                   fid_name);
1052                 }
1053                 break;
1054         case FID_MODE_CLOSE:
1055                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
1056                 break;
1057         case FID_MODE_USE:
1058         case FID_MODE_DHNQ:
1059         case FID_MODE_DHNC:
1060                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
1061                 break;
1062         }
1063
1064         pinfo->private_data=old_private_data;
1065
1066
1067         /* put the filename in col_info */
1068         if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->fd->num)) {
1069                 if(fid_name){
1070                         if(hnd_item){
1071                                 proto_item_append_text(hnd_item, " %s", fid_name);
1072                         }
1073                         if (check_col(pinfo->cinfo, COL_INFO)){
1074                                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", fid_name);
1075                         }
1076                 }
1077         }
1078
1079         return offset;
1080 }
1081
1082
1083 /* this info level is unique to SMB2 and differst from the corresponding
1084  * SMB_FILE_ALL_INFO in SMB
1085  */
1086 static int
1087 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1088 {
1089         proto_item *item=NULL;
1090         proto_tree *tree=NULL;
1091         int length;
1092         const char *name="";
1093         guint16 bc;
1094
1095         if(parent_tree){
1096                 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, TRUE);
1097                 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
1098         }
1099
1100         /* create time */
1101         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1102
1103         /* last access */
1104         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1105
1106         /* last write */
1107         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1108
1109         /* last change */
1110         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1111
1112         /* File Attributes */
1113         offset = dissect_file_ext_attr(tvb, tree, offset);
1114
1115         /* some unknown bytes */
1116         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1117         offset += 4;
1118
1119         /* allocation size */
1120         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
1121         offset += 8;
1122
1123         /* end of file */
1124         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
1125         offset += 8;
1126
1127         /* number of links */
1128         proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, TRUE);
1129         offset += 4;
1130
1131         /* delete pending */
1132         proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, TRUE);
1133         offset += 1;
1134
1135         /* is directory */
1136         proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, TRUE);
1137         offset += 1;
1138
1139         /* padding */
1140         offset += 2;
1141
1142         /* file id */
1143         proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, TRUE);
1144         offset += 8;
1145
1146         /* ea size */
1147         proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
1148         offset += 4;
1149
1150         /* access mask */
1151         offset = dissect_smb_access_mask(tvb, tree, offset);
1152
1153         /* some unknown bytes */
1154         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, FALSE);
1155         offset += 16;
1156
1157         /* file name length */
1158         length=tvb_get_letohs(tvb, offset);
1159         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, TRUE);
1160         offset += 2;
1161
1162         /* some unknown bytes */
1163         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
1164         offset += 2;
1165
1166         /* file name */
1167         if(length){
1168                 bc=tvb_length_remaining(tvb, offset);
1169                 name = get_unicode_or_ascii_string(tvb, &offset,
1170                         TRUE, &length, TRUE, TRUE, &bc);
1171                 if(name){
1172                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1173                                 offset, length, name);
1174                 }
1175
1176         }
1177         offset += length;
1178
1179
1180         return offset;
1181 }
1182
1183
1184 static int
1185 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1186 {
1187         proto_item *item=NULL;
1188         proto_tree *tree=NULL;
1189         guint16 bc;
1190         gboolean trunc;
1191
1192         if(parent_tree){
1193                 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, TRUE);
1194                 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
1195         }
1196
1197         bc=tvb_length_remaining(tvb, offset);
1198         offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1199
1200         return offset;
1201 }
1202
1203 static int
1204 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1205 {
1206         proto_item *item=NULL;
1207         proto_tree *tree=NULL;
1208         guint16 bc;
1209         gboolean trunc;
1210
1211         if(parent_tree){
1212                 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, TRUE);
1213                 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
1214         }
1215
1216         bc=tvb_length_remaining(tvb, offset);
1217         offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1218
1219         return offset;
1220 }
1221
1222 static int
1223 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1224 {
1225         proto_item *item=NULL;
1226         proto_tree *tree=NULL;
1227         guint16 bc;
1228         gboolean trunc;
1229
1230         if(parent_tree){
1231                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, TRUE);
1232                 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
1233         }
1234
1235         bc=tvb_length_remaining(tvb, offset);
1236         offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1237
1238         return offset;
1239 }
1240
1241
1242 static int
1243 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1244 {
1245         proto_item *item=NULL;
1246         proto_tree *tree=NULL;
1247
1248         if(parent_tree){
1249                 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, TRUE);
1250                 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
1251         }
1252
1253         /* create time */
1254         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1255
1256         /* last access */
1257         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1258
1259         /* last write */
1260         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1261
1262         /* last change */
1263         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1264
1265         /* File Attributes */
1266         offset = dissect_file_ext_attr(tvb, tree, offset);
1267
1268         /* some unknown bytes */
1269         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1270         offset += 4;
1271
1272         return offset;
1273 }
1274
1275 static int
1276 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1277 {
1278         proto_item *item=NULL;
1279         proto_tree *tree=NULL;
1280         guint16 bc;
1281         gboolean trunc;
1282
1283         if(parent_tree){
1284                 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, TRUE);
1285                 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
1286         }
1287
1288         bc=tvb_length_remaining(tvb, offset);
1289         offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1290
1291         return offset;
1292 }
1293 static int
1294 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1295 {
1296         proto_item *item=NULL;
1297         proto_tree *tree=NULL;
1298         guint16 bc;
1299         gboolean trunc;
1300
1301         if(parent_tree){
1302                 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, TRUE);
1303                 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
1304         }
1305
1306         bc=tvb_length_remaining(tvb, offset);
1307         offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1308
1309         return offset;
1310 }
1311 static int
1312 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1313 {
1314         proto_item *item=NULL;
1315         proto_tree *tree=NULL;
1316         guint16 bc;
1317         gboolean trunc;
1318
1319         if(parent_tree){
1320                 item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, TRUE);
1321                 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
1322         }
1323
1324         bc=tvb_length_remaining(tvb, offset);
1325         offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1326
1327         return offset;
1328 }
1329 static int
1330 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1331 {
1332         proto_item *item=NULL;
1333         proto_tree *tree=NULL;
1334         guint16 bc;
1335         gboolean trunc;
1336
1337         if(parent_tree){
1338                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, TRUE);
1339                 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
1340         }
1341
1342         bc=tvb_length_remaining(tvb, offset);
1343         offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1344
1345         return offset;
1346 }
1347 static int
1348 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1349 {
1350         proto_item *item=NULL;
1351         proto_tree *tree=NULL;
1352         guint16 bc;
1353         gboolean trunc;
1354
1355         if(parent_tree){
1356                 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, TRUE);
1357                 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
1358         }
1359
1360         bc=tvb_length_remaining(tvb, offset);
1361         offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1362
1363         return offset;
1364 }
1365
1366 static int
1367 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1368 {
1369         proto_item *item=NULL;
1370         proto_tree *tree=NULL;
1371
1372         if(parent_tree){
1373                 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, TRUE);
1374                 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
1375         }
1376
1377         /* access mask */
1378         offset = dissect_smb_access_mask(tvb, tree, offset);
1379
1380         return offset;
1381 }
1382
1383 static int
1384 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1385 {
1386         proto_item *item=NULL;
1387         proto_tree *tree=NULL;
1388         guint16 bc;
1389         gboolean trunc;
1390
1391         if(parent_tree){
1392                 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, TRUE);
1393                 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
1394         }
1395
1396         bc=tvb_length_remaining(tvb, offset);
1397         offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1398
1399         return offset;
1400 }
1401
1402 static int
1403 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1404 {
1405         proto_item *item=NULL;
1406         proto_tree *tree=NULL;
1407         guint16 bc;
1408         gboolean trunc;
1409
1410         if(parent_tree){
1411                 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, TRUE);
1412                 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
1413         }
1414
1415         bc=tvb_length_remaining(tvb, offset);
1416         offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
1417
1418         return offset;
1419 }
1420
1421 static int
1422 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1423 {
1424         proto_item *item=NULL;
1425         proto_tree *tree=NULL;
1426         guint16 bc;
1427         gboolean trunc;
1428
1429         if(parent_tree){
1430                 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, TRUE);
1431                 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
1432         }
1433
1434         bc=tvb_length_remaining(tvb, offset);
1435         offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1436
1437         return offset;
1438 }
1439
1440 static int
1441 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1442 {
1443         proto_item *item=NULL;
1444         proto_tree *tree=NULL;
1445         guint16 bc;
1446         gboolean trunc;
1447
1448         if(parent_tree){
1449                 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, TRUE);
1450                 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
1451         }
1452
1453         bc=tvb_length_remaining(tvb, offset);
1454         offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1455
1456         return offset;
1457 }
1458
1459 static int
1460 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1461 {
1462         proto_item *item=NULL;
1463         proto_tree *tree=NULL;
1464         guint16 bc;
1465         gboolean trunc;
1466
1467         if(parent_tree){
1468                 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, TRUE);
1469                 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
1470         }
1471
1472
1473         bc=tvb_length_remaining(tvb, offset);
1474         offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1475
1476         return offset;
1477 }
1478
1479 static int
1480 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1481 {
1482         proto_item *item=NULL;
1483         proto_tree *tree=NULL;
1484         guint16 bc;
1485         gboolean trunc;
1486
1487         if(parent_tree){
1488                 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, TRUE);
1489                 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
1490         }
1491
1492
1493         bc=tvb_length_remaining(tvb, offset);
1494         offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1495
1496         return offset;
1497 }
1498
1499 static const true_false_string tfs_disposition_delete_on_close = {
1500         "DELETE this file when closed",
1501         "Normal access, do not delete on close"
1502 };
1503
1504 static int
1505 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1506 {
1507         proto_item *item=NULL;
1508         proto_tree *tree=NULL;
1509
1510         if(parent_tree){
1511                 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, TRUE);
1512                 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
1513         }
1514
1515         /* file disposition */
1516         proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, TRUE);
1517
1518         return offset;
1519 }
1520
1521 static int
1522 dissect_smb2_file_info_0f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1523 {
1524         proto_item *item=NULL;
1525         proto_tree *tree=NULL;
1526         guint32 next_offset;
1527         guint8 ea_name_len, ea_data_len;
1528
1529         if(parent_tree){
1530                 item = proto_tree_add_item(parent_tree, hf_smb2_file_info_0f, tvb, offset, -1, TRUE);
1531                 tree = proto_item_add_subtree(item, ett_smb2_file_info_0f);
1532         }
1533
1534         while(1){
1535                 int length;
1536                 const char *name="";
1537                 const char *data="";
1538                 guint16 bc;
1539                 int start_offset=offset;
1540                 proto_item *ea_item=NULL;
1541                 proto_tree *ea_tree=NULL;
1542
1543                 if(tree){
1544                         ea_item = proto_tree_add_text(tree, tvb, offset, -1, "EA:");
1545                         ea_tree = proto_item_add_subtree(ea_item, ett_smb2_ea);
1546                 }
1547
1548                 /* next offset */
1549                 next_offset=tvb_get_letohl(tvb, offset);
1550                 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
1551                 offset += 4;
1552
1553                 /* EA flags */
1554                 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, TRUE);
1555                 offset += 1;
1556
1557                 /* EA Name Length */
1558                 ea_name_len=tvb_get_guint8(tvb, offset);
1559                 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, TRUE);
1560                 offset += 1;
1561
1562                 /* EA Data Length */
1563                 ea_data_len=tvb_get_guint8(tvb, offset);
1564                 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 1, TRUE);
1565                 offset += 1;
1566
1567                 /* some unknown bytes */
1568                 proto_tree_add_item(ea_tree, hf_smb2_unknown, tvb, offset, 1, TRUE);
1569                 offset += 1;
1570
1571                 /* ea name */
1572                 length=ea_name_len;
1573                 if(length){
1574                         bc=tvb_length_remaining(tvb, offset);
1575                         name = get_unicode_or_ascii_string(tvb, &offset,
1576                                 FALSE, &length, TRUE, TRUE, &bc);
1577                         if(name){
1578                                 proto_tree_add_string(ea_tree, hf_smb2_ea_name, tvb,
1579                                         offset, length, name);
1580                         }
1581                 }
1582                 offset += ea_name_len;
1583
1584                 /* separator byte */
1585                 offset += 1;
1586
1587                 /* ea data */
1588                 length=ea_data_len;
1589                 if(length){
1590                         bc=tvb_length_remaining(tvb, offset);
1591                         data = get_unicode_or_ascii_string(tvb, &offset,
1592                                 FALSE, &length, TRUE, TRUE, &bc);
1593                         if(data){
1594                                 proto_tree_add_string(ea_tree, hf_smb2_ea_data, tvb,
1595                                         offset, length, data);
1596                         }
1597                 }
1598                 offset += ea_data_len;
1599
1600
1601                 if(ea_item){
1602                         proto_item_append_text(ea_item, " %s := %s", name, data);
1603                 }
1604                 proto_item_set_len(ea_item, offset-start_offset);
1605
1606
1607                 if(!next_offset){
1608                         break;
1609                 }
1610                 if(next_offset>256){
1611                         break;
1612                 }
1613
1614                 offset = start_offset+next_offset;
1615         }
1616
1617         return offset;
1618 }
1619
1620 static int
1621 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1622 {
1623         proto_item *item=NULL;
1624         proto_tree *tree=NULL;
1625         int length;
1626         const char *name="";
1627         guint16 bc;
1628
1629
1630         if(parent_tree){
1631                 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, TRUE);
1632                 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
1633         }
1634
1635         /* some unknown bytes */
1636         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, FALSE);
1637         offset += 16;
1638
1639         /* file name length */
1640         length=tvb_get_letohs(tvb, offset);
1641         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, TRUE);
1642         offset += 2;
1643
1644         /* some unknown bytes */
1645         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
1646         offset += 2;
1647
1648         /* file name */
1649         if(length){
1650                 bc=tvb_length_remaining(tvb, offset);
1651                 name = get_unicode_or_ascii_string(tvb, &offset,
1652                         TRUE, &length, TRUE, TRUE, &bc);
1653                 if(name){
1654                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1655                                 offset, length, name);
1656                 }
1657
1658                 if (check_col(pinfo->cinfo, COL_INFO)){
1659                         col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s",
1660                         name);
1661                 }
1662         }
1663         offset += length;
1664
1665         /* some unknown bytes */
1666         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1667         offset += 4;
1668
1669         return offset;
1670 }
1671
1672 static int
1673 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1674 {
1675         proto_item *item=NULL;
1676         proto_tree *tree=NULL;
1677
1678         if(parent_tree){
1679                 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, TRUE);
1680                 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
1681         }
1682
1683         /* security descriptor */
1684         offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_length_remaining(tvb, offset), NULL);
1685
1686         return offset;
1687 }
1688
1689 static int
1690 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1691 {
1692         proto_item *item=NULL;
1693         proto_tree *tree=NULL;
1694         guint16 bc;
1695
1696         if(parent_tree){
1697                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, TRUE);
1698                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
1699         }
1700
1701         bc=tvb_length_remaining(tvb, offset);
1702         offset=dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
1703
1704         return offset;
1705 }
1706
1707 static int
1708 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1709 {
1710         proto_item *item=NULL;
1711         proto_tree *tree=NULL;
1712         guint16 bc;
1713
1714         if(parent_tree){
1715                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, TRUE);
1716                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
1717         }
1718
1719         bc=tvb_length_remaining(tvb, offset);
1720         offset=dissect_nt_quota(tvb, tree, offset, &bc);
1721
1722         return offset;
1723 }
1724
1725 static int
1726 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1727 {
1728         proto_item *item=NULL;
1729         proto_tree *tree=NULL;
1730
1731         if(parent_tree){
1732                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, TRUE);
1733                 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
1734         }
1735
1736         /* FILE_OBJECTID_BUFFER */
1737         offset=dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
1738
1739         return offset;
1740 }
1741
1742 static int
1743 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1744 {
1745         proto_item *item=NULL;
1746         proto_tree *tree=NULL;
1747         guint16 bc;
1748
1749         if(parent_tree){
1750                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, TRUE);
1751                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
1752         }
1753
1754         bc=tvb_length_remaining(tvb, offset);
1755         offset=dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
1756
1757         return offset;
1758 }
1759
1760 static int
1761 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1762 {
1763         proto_item *item=NULL;
1764         proto_tree *tree=NULL;
1765         guint16 bc;
1766
1767         if(parent_tree){
1768                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, TRUE);
1769                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
1770         }
1771
1772
1773         bc=tvb_length_remaining(tvb, offset);
1774         offset=dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
1775
1776         return offset;
1777 }
1778
1779 static int
1780 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1781 {
1782         proto_item *item=NULL;
1783         proto_tree *tree=NULL;
1784         guint16 bc;
1785
1786         if(parent_tree){
1787                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, TRUE);
1788                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
1789         }
1790
1791
1792         bc=tvb_length_remaining(tvb, offset);
1793         offset=dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
1794
1795         return offset;
1796 }
1797
1798 static int
1799 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1800 {
1801         proto_item *item=NULL;
1802         proto_tree *tree=NULL;
1803         guint16 bc;
1804
1805         if(parent_tree){
1806                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, TRUE);
1807                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
1808         }
1809
1810
1811         bc=tvb_length_remaining(tvb, offset);
1812         offset=dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
1813
1814         return offset;
1815 }
1816
1817 static const value_string oplock_vals[] = {
1818         { 0x00, "No oplock" },
1819         { 0x01, "Level2 oplock" },
1820         { 0x08, "Exclusive oplock" },
1821         { 0x09, "Batch oplock" },
1822         { 0, NULL }
1823 };
1824
1825 static int
1826 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1827 {
1828         proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, TRUE);
1829
1830         offset += 1;
1831         return offset;
1832 }
1833
1834 static int
1835 dissect_smb2_buffercode(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 *length)
1836 {
1837         guint16 buffer_code;
1838
1839         /* dissect the first 2 bytes of the command PDU */
1840         buffer_code = tvb_get_letohs(tvb, offset);
1841         proto_tree_add_uint(tree, hf_smb2_buffer_code_len, tvb, offset, 2, buffer_code&0xfffe);
1842         proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, TRUE);
1843         offset += 2;
1844
1845         if(length){
1846                 *length=buffer_code&0xfffe;
1847         }
1848
1849         return offset;
1850 }
1851
1852 #define NEGPROT_CAP_DFS         0x00000001
1853 #define NEGPROT_CAP_LEASING     0x00000002
1854 #define NEGPROT_CAP_LARGE_MTU   0x00000004
1855 static int
1856 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1857 {
1858         guint32 cap;
1859         proto_item *item=NULL;
1860         proto_tree *tree=NULL;
1861
1862         cap = tvb_get_letohl(tvb, offset);
1863
1864         item = proto_tree_add_item(parent_tree, hf_smb2_capabilities, tvb, offset, 4, TRUE);
1865         tree = proto_item_add_subtree(item, ett_smb2_capabilities);
1866
1867
1868         proto_tree_add_boolean(tree, hf_smb2_cap_dfs, tvb, offset, 4, cap);
1869         proto_tree_add_boolean(tree, hf_smb2_cap_leasing, tvb, offset, 4, cap);
1870         proto_tree_add_boolean(tree, hf_smb2_cap_large_mtu, tvb, offset, 4, cap);
1871
1872
1873         offset += 4;
1874
1875         return offset;
1876 }
1877
1878
1879
1880 #define NEGPROT_SIGN_REQ        0x0002
1881 #define NEGPROT_SIGN_ENABLED    0x0001
1882
1883 static int
1884 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1885 {
1886         guint8 sm;
1887         proto_item *item=NULL;
1888         proto_tree *tree=NULL;
1889
1890         sm = tvb_get_guint8(tvb, offset);
1891
1892         item = proto_tree_add_item(parent_tree, hf_smb2_security_mode, tvb, offset, 1, TRUE);
1893         tree = proto_item_add_subtree(item, ett_smb2_sec_mode);
1894
1895
1896         proto_tree_add_boolean(tree, hf_smb2_secmode_flags_sign_required, tvb, offset, 1, sm);
1897         proto_tree_add_boolean(tree, hf_smb2_secmode_flags_sign_enabled, tvb, offset, 1, sm);
1898
1899
1900         offset += 1;
1901
1902         return offset;
1903 }
1904
1905 #define SES_FLAGS_GUEST         0x0001
1906 #define SES_FLAGS_NULL          0x0002
1907
1908 static int
1909 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1910 {
1911         guint16 sf;
1912         proto_item *item=NULL;
1913         proto_tree *tree=NULL;
1914
1915         sf = tvb_get_letohs(tvb, offset);
1916
1917         item = proto_tree_add_item(parent_tree, hf_smb2_session_flags, tvb, offset, 2, TRUE);
1918         tree = proto_item_add_subtree(item, ett_smb2_ses_flags);
1919
1920
1921         proto_tree_add_boolean(tree, hf_smb2_ses_flags_null, tvb, offset, 2, sf);
1922         proto_tree_add_boolean(tree, hf_smb2_ses_flags_guest, tvb, offset, 2, sf);
1923
1924
1925         offset += 2;
1926
1927         return offset;
1928 }
1929
1930 #define SHARE_FLAGS_manual_caching              0x00000000
1931 #define SHARE_FLAGS_auto_caching                0x00000010
1932 #define SHARE_FLAGS_vdo_caching                 0x00000020
1933 #define SHARE_FLAGS_no_caching                  0x00000030
1934
1935 static const value_string share_cache_vals[] = {
1936         { SHARE_FLAGS_manual_caching,   "Manual caching" },
1937         { SHARE_FLAGS_auto_caching,     "Auto caching" },
1938         { SHARE_FLAGS_vdo_caching,      "VDO caching" },
1939         { SHARE_FLAGS_no_caching,       "No caching" },
1940         { 0, NULL }
1941 };
1942
1943 #define SHARE_FLAGS_dfs                         0x00000001
1944 #define SHARE_FLAGS_dfs_root                    0x00000002
1945 #define SHARE_FLAGS_restrict_exclusive_opens    0x00000100
1946 #define SHARE_FLAGS_force_shared_delete         0x00000200
1947 #define SHARE_FLAGS_allow_namespace_caching     0x00000400
1948 #define SHARE_FLAGS_access_based_dir_enum       0x00000800
1949 #define SHARE_FLAGS_force_levelii_oplock        0x00001000
1950 #define SHARE_FLAGS_enable_hash                 0x00002000
1951
1952 static int
1953 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
1954 {
1955         static const int *sf_fields[] = {
1956                 &hf_smb2_share_flags_dfs,
1957                 &hf_smb2_share_flags_dfs_root,
1958                 &hf_smb2_share_flags_restrict_exclusive_opens,
1959                 &hf_smb2_share_flags_force_shared_delete,
1960                 &hf_smb2_share_flags_allow_namespace_caching,
1961                 &hf_smb2_share_flags_access_based_dir_enum,
1962                 &hf_smb2_share_flags_force_levelii_oplock,
1963                 &hf_smb2_share_flags_enable_hash,
1964                 NULL
1965         };
1966         proto_item *item;
1967         guint32 cp;
1968
1969         item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, TRUE);
1970
1971         cp = tvb_get_letohl(tvb, offset);
1972         cp &= 0x00000030;
1973         proto_tree_add_uint_format(item, hf_smb2_share_caching, tvb, offset, 4, cp, "Caching policy: %s (%08x)", val_to_str(cp, share_cache_vals, "Unknown:%u"), cp);
1974
1975
1976         offset += 4;
1977
1978         return offset;
1979 }
1980
1981 #define SHARE_CAPS_DFS          0x00000008
1982
1983 static int
1984 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
1985 {
1986         static const int *sc_fields[] = {
1987                 &hf_smb2_share_caps_dfs,
1988                 NULL
1989         };
1990
1991         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, TRUE);
1992
1993         offset += 4;
1994
1995         return offset;
1996 }
1997
1998 static void
1999 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
2000 {
2001         if( (tvb_length(tvb)>=7)
2002         &&  (!tvb_memeql(tvb, 0, "NTLMSSP", 7))){
2003                 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
2004         } else {
2005                 call_dissector(gssapi_handle, tvb, pinfo, tree);
2006         }
2007         return;
2008 }
2009
2010 static int
2011 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2012 {
2013         offset_length_buffer_t s_olb;
2014         const ntlmssp_header_t *ntlmssph;
2015         static int ntlmssp_tap_id = 0;
2016         int idx;
2017
2018         if(!ntlmssp_tap_id){
2019                 GString *error_string;
2020                 /* We dont specify any callbacks at all.
2021                  * Instead we manually fetch the tapped data after the
2022                  * security blob has been fully dissected and before
2023                  * we exit from this dissector.
2024                  */
2025                 error_string=register_tap_listener("ntlmssp", NULL, NULL,
2026                     TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL);
2027                 if(!error_string){
2028                         ntlmssp_tap_id=find_tap_id("ntlmssp");
2029                 }
2030         }
2031
2032
2033         /* buffer code */
2034         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2035         /* some unknown bytes */
2036
2037         /* num vcs */
2038         proto_tree_add_item(tree, hf_smb2_vcnum, tvb, offset, 1, TRUE);
2039         offset += 1;
2040
2041         /* security mode */
2042         offset = dissect_smb2_secmode(tree, tvb, offset);
2043
2044         /* capabilities */
2045         offset = dissect_smb2_capabilities(tree, tvb, offset);
2046
2047         /* channel */
2048         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, TRUE);
2049         offset += 4;
2050
2051         /* security blob offset/length */
2052         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2053
2054         /* previous session id */
2055         proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, TRUE);
2056         offset += 8;
2057
2058
2059         /* the security blob itself */
2060         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2061
2062         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2063
2064         /* If we have found a uid->acct_name mapping, store it */
2065         if(!pinfo->fd->flags.visited){
2066                 idx=0;
2067                 while((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
2068                         if(ntlmssph && ntlmssph->type==3){
2069                                 smb2_sesid_info_t *sesid;
2070                                 sesid=se_alloc(sizeof(smb2_sesid_info_t));
2071                                 sesid->sesid=si->sesid;
2072                                 sesid->acct_name=se_strdup(ntlmssph->acct_name);
2073                                 sesid->domain_name=se_strdup(ntlmssph->domain_name);
2074                                 sesid->host_name=se_strdup(ntlmssph->host_name);
2075                                 sesid->auth_frame=pinfo->fd->num;
2076                                 sesid->tids= g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
2077                                 g_hash_table_insert(si->conv->sesids, sesid, sesid);
2078                         }
2079                 }
2080         }
2081
2082         return offset;
2083 }
2084
2085 static int
2086 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2087 {
2088         gint byte_count;
2089
2090         /* buffer code */
2091         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2092
2093
2094         /* Reserved (2 bytes) */
2095         proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 2, TRUE);
2096         offset += 2;
2097
2098         /* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
2099         byte_count = tvb_get_ntohl(tvb, offset);
2100         proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, TRUE);
2101         offset += 4;
2102
2103         /* If the ByteCount field is zero then the server MUST supply an ErrorData field
2104            that is one byte in length */
2105         if (byte_count == 0) byte_count = 1;
2106
2107         /* ErrorData (variable): A variable-length data field that contains extended
2108            error information.*/
2109         proto_tree_add_item(tree, hf_smb2_error_data, tvb, offset, byte_count, TRUE);
2110         offset += byte_count;
2111
2112         return offset;
2113 }
2114
2115 static int
2116 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2117 {
2118         offset_length_buffer_t s_olb;
2119
2120         /* session_setup is special and we don't use dissect_smb2_error_response() here! */
2121
2122         /* buffer code */
2123         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2124
2125         /* session flags */
2126         offset = dissect_smb2_ses_flags(tree, tvb, offset);
2127
2128         /* security blob offset/length */
2129         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2130
2131         /* the security blob itself */
2132         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2133
2134         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2135
2136         return offset;
2137 }
2138
2139 static int
2140 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2141 {
2142         offset_length_buffer_t olb;
2143         const char *buf;
2144
2145         /* buffer code */
2146         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2147
2148         /* reserved */
2149         offset += 2;
2150
2151         /* tree  offset/length */
2152         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
2153
2154         /* tree string */
2155         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2156
2157         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2158
2159         /* treelen  +1 is overkill here if the string is unicode,
2160          * but who ever has more than a handful of TCON in a trace anyways
2161          */
2162         if(!pinfo->fd->flags.visited && si->saved && buf && olb.len){
2163                 si->saved->extra_info_type=SMB2_EI_TREENAME;
2164                 si->saved->extra_info=se_alloc(olb.len+1);
2165                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2166         }
2167
2168         if (check_col(pinfo->cinfo, COL_INFO)){
2169                 col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s", buf);
2170         }
2171
2172
2173         return offset;
2174 }
2175 static int
2176 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2177 {
2178         guint16 share_type;
2179
2180         switch (si->status) {
2181         case 0x00000000: break;
2182         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2183         }
2184
2185         /* buffer code */
2186         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2187
2188         /* share type */
2189         share_type = tvb_get_letohs(tvb, offset);
2190         proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 1, TRUE);
2191         /* Next byte is reserved  and must be set to zero */
2192         offset += 2;
2193
2194         if(!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type==SMB2_EI_TREENAME && si->session) {
2195                 smb2_tid_info_t *tid, tid_key;
2196
2197                 tid_key.tid=si->tid;
2198                 tid=g_hash_table_lookup(si->session->tids, &tid_key);
2199                 if(tid){
2200                         g_hash_table_remove(si->session->tids, &tid_key);
2201                 }
2202                 tid=se_alloc(sizeof(smb2_tid_info_t));
2203                 tid->tid=si->tid;
2204                 tid->name=(char *)si->saved->extra_info;
2205                 tid->connect_frame=pinfo->fd->num;
2206                 tid->share_type=share_type;
2207
2208                 g_hash_table_insert(si->session->tids, tid, tid);
2209
2210                 si->saved->extra_info_type=SMB2_EI_NONE;
2211                 si->saved->extra_info=NULL;
2212         }
2213
2214         /* share flags */
2215         offset = dissect_smb2_share_flags(tree, tvb, offset);
2216
2217         /* share capabilities */
2218         offset = dissect_smb2_share_caps(tree, tvb, offset);
2219
2220         /* this is some sort of access mask */
2221         offset = dissect_smb_access_mask(tvb, tree, offset);
2222
2223         return offset;
2224 }
2225
2226 static int
2227 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2228 {
2229         /* buffer code */
2230         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2231
2232         /* reserved */
2233         offset += 2;
2234
2235         return offset;
2236 }
2237
2238 static int
2239 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2240 {
2241         switch (si->status) {
2242         case 0x00000000: break;
2243         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2244         }
2245
2246         /* buffer code */
2247         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2248
2249         /* reserved */
2250         offset += 2;
2251
2252         return offset;
2253 }
2254
2255 static int
2256 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2257 {
2258         /* buffer code */
2259         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2260
2261         /* reserved bytes */
2262         offset += 2;
2263
2264         return offset;
2265 }
2266
2267 static int
2268 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2269 {
2270         switch (si->status) {
2271         case 0x00000000: break;
2272         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2273         }
2274
2275         /* buffer code */
2276         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2277
2278         /* reserved bytes */
2279         offset += 2;
2280
2281         return offset;
2282 }
2283
2284 static int
2285 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2286 {
2287         /* buffer code */
2288         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2289
2290         /* some unknown bytes */
2291         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2292         offset += 2;
2293
2294         return offset;
2295 }
2296
2297 static int
2298 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2299 {
2300         switch (si->status) {
2301         case 0x00000000: break;
2302         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2303         }
2304
2305         /* buffer code */
2306         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2307
2308         /* some unknown bytes */
2309         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2310         offset += 2;
2311
2312         return offset;
2313 }
2314
2315 static int
2316 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2317 {
2318         proto_tree *flags_tree = NULL;
2319         proto_item *flags_item = NULL;
2320
2321         /* buffer code */
2322         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2323
2324         /* notify flags */
2325         if (tree) {
2326                 flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, TRUE);
2327                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
2328         }
2329         proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, TRUE);
2330         offset += 2;
2331
2332         /* output buffer length */
2333         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, TRUE);
2334         offset += 4;
2335
2336         /* fid */
2337         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2338
2339         /* completion filter */
2340         offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
2341
2342         /* reserved */
2343         offset += 4;
2344
2345         return offset;
2346 }
2347
2348 static void
2349 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
2350 {
2351         proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), TRUE);
2352 }
2353
2354 static int
2355 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
2356 {
2357         offset_length_buffer_t olb;
2358
2359         switch (si->status) {
2360         case 0x00000000: break;
2361         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2362         }
2363
2364         /* buffer code */
2365         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2366
2367         /* out buffer offset/length */
2368         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
2369
2370         /* out buffer */
2371         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
2372         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2373
2374         return offset;
2375 }
2376
2377 #define SMB2_FIND_FLAG_RESTART_SCANS            0x01
2378 #define SMB2_FIND_FLAG_SINGLE_ENTRY             0x02
2379 #define SMB2_FIND_FLAG_INDEX_SPECIFIED          0x04
2380 #define SMB2_FIND_FLAG_REOPEN                   0x10
2381
2382 static int
2383 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2384 {
2385         offset_length_buffer_t olb;
2386         const char *buf;
2387         guint8 il;
2388         static const int *f_fields[] = {
2389                 &hf_smb2_find_flags_restart_scans,
2390                 &hf_smb2_find_flags_single_entry,
2391                 &hf_smb2_find_flags_index_specified,
2392                 &hf_smb2_find_flags_reopen,
2393                 NULL
2394         };
2395
2396         /* buffer code */
2397         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2398
2399         il=tvb_get_guint8(tvb, offset);
2400         if(si->saved){
2401                 si->saved->infolevel=il;
2402         }
2403
2404         /* infolevel */
2405         proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
2406         offset += 1;
2407
2408         /* find flags */
2409         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, TRUE);
2410         offset += 1;
2411
2412         /* file index */
2413         proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2414         offset += 4;
2415
2416         /* fid */
2417         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2418
2419         /* search pattern  offset/length */
2420         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_find_pattern);
2421
2422         /* output buffer length */
2423         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, TRUE);
2424         offset += 4;
2425
2426         /* search pattern */
2427         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2428
2429         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2430
2431         if(!pinfo->fd->flags.visited && si->saved && olb.len){
2432                 si->saved->extra_info_type=SMB2_EI_FINDPATTERN;
2433                 si->saved->extra_info=g_malloc(olb.len+1);
2434                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2435         }
2436
2437         if (check_col(pinfo->cinfo, COL_INFO)){
2438                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
2439                         val_to_str(il, smb2_find_info_levels, "(Level:0x%02x)"),
2440                         buf);
2441         }
2442
2443         return offset;
2444 }
2445
2446 static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2447 {
2448         int offset = 0;
2449         proto_item *item=NULL;
2450         proto_tree *tree=NULL;
2451         const char *name=NULL;
2452         guint16 bc;
2453
2454         while(tvb_length_remaining(tvb, offset) > 4){
2455                 int old_offset = offset;
2456                 int next_offset;
2457                 int file_name_len;
2458
2459                 if(parent_tree){
2460                         item = proto_tree_add_item(parent_tree, hf_smb2_file_directory_info, tvb, offset, -1, TRUE);
2461                         tree = proto_item_add_subtree(item, ett_smb2_file_directory_info);
2462                 }
2463
2464                 /* next offset */
2465                 next_offset = tvb_get_letohl(tvb, offset);
2466                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2467                 offset += 4;
2468
2469                 /* file index */
2470                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2471                 offset += 4;
2472
2473                 /* create time */
2474                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2475
2476                 /* last access */
2477                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2478
2479                 /* last write */
2480                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2481
2482                 /* last change */
2483                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2484
2485                 /* end of file */
2486                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2487                 offset += 8;
2488
2489                 /* allocation size */
2490                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2491                 offset += 8;
2492
2493                 /* File Attributes */
2494                 offset = dissect_file_ext_attr(tvb, tree, offset);
2495
2496                 /* file name length */
2497                 file_name_len=tvb_get_letohl(tvb, offset);
2498                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2499                 offset += 4;
2500
2501                 /* file name */
2502                 if(file_name_len){
2503                         bc=file_name_len;
2504                         name = get_unicode_or_ascii_string(tvb, &offset,
2505                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2506                         if(name){
2507                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2508                                         offset, file_name_len, name);
2509                                 proto_item_append_text(item, ": %s", name);
2510
2511                         }
2512                 }
2513
2514                 proto_item_set_len(item, offset-old_offset);
2515
2516                 if (next_offset == 0){
2517                         return;
2518                 }
2519
2520                 offset = old_offset+next_offset;
2521                 if (offset < old_offset) {
2522                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2523                                     "Invalid offset/length. Malformed packet");
2524                         return;
2525                 }
2526         }
2527         return;
2528 }
2529
2530 static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2531 {
2532         int offset = 0;
2533         proto_item *item=NULL;
2534         proto_tree *tree=NULL;
2535         const char *name=NULL;
2536         guint16 bc;
2537
2538         while(tvb_length_remaining(tvb, offset) > 4){
2539                 int old_offset = offset;
2540                 int next_offset;
2541                 int file_name_len;
2542
2543                 if(parent_tree){
2544                         item = proto_tree_add_item(parent_tree, hf_smb2_full_directory_info, tvb, offset, -1, TRUE);
2545                         tree = proto_item_add_subtree(item, ett_smb2_full_directory_info);
2546                 }
2547
2548                 /* next offset */
2549                 next_offset = tvb_get_letohl(tvb, offset);
2550                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2551                 offset += 4;
2552
2553                 /* file index */
2554                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2555                 offset += 4;
2556
2557                 /* create time */
2558                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2559
2560                 /* last access */
2561                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2562
2563                 /* last write */
2564                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2565
2566                 /* last change */
2567                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2568
2569                 /* end of file */
2570                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2571                 offset += 8;
2572
2573                 /* allocation size */
2574                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2575                 offset += 8;
2576
2577                 /* File Attributes */
2578                 offset = dissect_file_ext_attr(tvb, tree, offset);
2579
2580                 /* file name length */
2581                 file_name_len=tvb_get_letohl(tvb, offset);
2582                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2583                 offset += 4;
2584
2585                 /* ea size */
2586                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2587                 offset += 4;
2588
2589                 /* file name */
2590                 if(file_name_len){
2591                         bc=file_name_len;
2592                         name = get_unicode_or_ascii_string(tvb, &offset,
2593                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2594                         if(name){
2595                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2596                                         offset, file_name_len, name);
2597                                 proto_item_append_text(item, ": %s", name);
2598
2599                         }
2600                 }
2601
2602                 proto_item_set_len(item, offset-old_offset);
2603
2604                 if (next_offset == 0){
2605                         return;
2606                 }
2607
2608                 offset = old_offset+next_offset;
2609                 if (offset < old_offset) {
2610                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2611                                     "Invalid offset/length. Malformed packet");
2612                         return;
2613                 }
2614         }
2615         return;
2616 }
2617
2618 static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2619 {
2620         int offset = 0;
2621         proto_item *item=NULL;
2622         proto_tree *tree=NULL;
2623         const char *name=NULL;
2624         guint16 bc;
2625
2626         while(tvb_length_remaining(tvb, offset) > 4){
2627                 int old_offset = offset;
2628                 int next_offset;
2629                 int file_name_len;
2630                 int short_name_len;
2631
2632                 if(parent_tree){
2633                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, TRUE);
2634                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
2635                 }
2636
2637                 /* next offset */
2638                 next_offset = tvb_get_letohl(tvb, offset);
2639                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2640                 offset += 4;
2641
2642                 /* file index */
2643                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2644                 offset += 4;
2645
2646                 /* create time */
2647                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2648
2649                 /* last access */
2650                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2651
2652                 /* last write */
2653                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2654
2655                 /* last change */
2656                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2657
2658                 /* end of file */
2659                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2660                 offset += 8;
2661
2662                 /* allocation size */
2663                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2664                 offset += 8;
2665
2666                 /* File Attributes */
2667                 offset = dissect_file_ext_attr(tvb, tree, offset);
2668
2669                 /* file name length */
2670                 file_name_len=tvb_get_letohl(tvb, offset);
2671                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2672                 offset += 4;
2673
2674                 /* ea size */
2675                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2676                 offset += 4;
2677
2678                 /* short name length */
2679                 short_name_len=tvb_get_guint8(tvb, offset);
2680                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, TRUE);
2681                 offset += 1;
2682
2683                 /* reserved */
2684                 offset += 1;
2685
2686                 /* short name */
2687                 if(short_name_len){
2688                         bc=short_name_len;
2689                         name = get_unicode_or_ascii_string(tvb, &offset,
2690                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
2691                         if(name){
2692                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
2693                                         offset, short_name_len, name);
2694                         }
2695                 }
2696                 offset += 24;
2697
2698                 /* file name */
2699                 if(file_name_len){
2700                         bc=file_name_len;
2701                         name = get_unicode_or_ascii_string(tvb, &offset,
2702                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2703                         if(name){
2704                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2705                                         offset, file_name_len, name);
2706                                 proto_item_append_text(item, ": %s", name);
2707
2708                         }
2709                 }
2710
2711                 proto_item_set_len(item, offset-old_offset);
2712
2713                 if (next_offset == 0){
2714                         return;
2715                 }
2716
2717                 offset = old_offset+next_offset;
2718                 if (offset < old_offset) {
2719                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2720                                     "Invalid offset/length. Malformed packet");
2721                         return;
2722                 }
2723         }
2724         return;
2725 }
2726
2727 static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2728 {
2729         int offset = 0;
2730         proto_item *item=NULL;
2731         proto_tree *tree=NULL;
2732         const char *name=NULL;
2733         guint16 bc;
2734
2735         while(tvb_length_remaining(tvb, offset) > 4){
2736                 int old_offset = offset;
2737                 int next_offset;
2738                 int file_name_len;
2739
2740                 if(parent_tree){
2741                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, TRUE);
2742                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
2743                 }
2744
2745                 /* next offset */
2746                 next_offset = tvb_get_letohl(tvb, offset);
2747                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2748                 offset += 4;
2749
2750                 /* file index */
2751                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2752                 offset += 4;
2753
2754                 /* file name length */
2755                 file_name_len=tvb_get_letohl(tvb, offset);
2756                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2757                 offset += 4;
2758
2759                 /* file name */
2760                 if(file_name_len){
2761                         bc=file_name_len;
2762                         name = get_unicode_or_ascii_string(tvb, &offset,
2763                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2764                         if(name){
2765                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2766                                         offset, file_name_len, name);
2767                                 proto_item_append_text(item, ": %s", name);
2768
2769                         }
2770                 }
2771
2772                 proto_item_set_len(item, offset-old_offset);
2773
2774                 if (next_offset == 0){
2775                         return;
2776                 }
2777
2778                 offset = old_offset+next_offset;
2779                 if (offset < old_offset) {
2780                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2781                                     "Invalid offset/length. Malformed packet");
2782                         return;
2783                 }
2784         }
2785         return;
2786 }
2787
2788 static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2789 {
2790         int offset = 0;
2791         proto_item *item=NULL;
2792         proto_tree *tree=NULL;
2793         const char *name=NULL;
2794         guint16 bc;
2795
2796         while(tvb_length_remaining(tvb, offset) > 4){
2797                 int old_offset = offset;
2798                 int next_offset;
2799                 int file_name_len;
2800                 int short_name_len;
2801
2802                 if(parent_tree){
2803                         item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, TRUE);
2804                         tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
2805                 }
2806
2807                 /* next offset */
2808                 next_offset = tvb_get_letohl(tvb, offset);
2809                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2810                 offset += 4;
2811
2812                 /* file index */
2813                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2814                 offset += 4;
2815
2816                 /* create time */
2817                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2818
2819                 /* last access */
2820                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2821
2822                 /* last write */
2823                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2824
2825                 /* last change */
2826                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2827
2828                 /* end of file */
2829                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2830                 offset += 8;
2831
2832                 /* allocation size */
2833                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2834                 offset += 8;
2835
2836                 /* File Attributes */
2837                 offset = dissect_file_ext_attr(tvb, tree, offset);
2838
2839                 /* file name length */
2840                 file_name_len=tvb_get_letohl(tvb, offset);
2841                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2842                 offset += 4;
2843
2844                 /* ea size */
2845                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2846                 offset += 4;
2847
2848                 /* short name length */
2849                 short_name_len=tvb_get_guint8(tvb, offset);
2850                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, TRUE);
2851                 offset += 1;
2852
2853                 /* reserved */
2854                 offset += 1;
2855
2856                 /* short name */
2857                 if(short_name_len){
2858                         bc=short_name_len;
2859                         name = get_unicode_or_ascii_string(tvb, &offset,
2860                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
2861                         if(name){
2862                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
2863                                         offset, short_name_len, name);
2864                         }
2865                 }
2866                 offset += 24;
2867
2868                 /* reserved */
2869                 offset += 2;
2870
2871                 /* file id */
2872                 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, TRUE);
2873                 offset += 8;
2874
2875                 /* file name */
2876                 if(file_name_len){
2877                         bc=file_name_len;
2878                         name = get_unicode_or_ascii_string(tvb, &offset,
2879                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2880                         if(name){
2881                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2882                                         offset, file_name_len, name);
2883                                 proto_item_append_text(item, ": %s", name);
2884
2885                         }
2886                 }
2887
2888                 proto_item_set_len(item, offset-old_offset);
2889
2890                 if (next_offset == 0){
2891                         return;
2892                 }
2893
2894                 offset = old_offset+next_offset;
2895                 if (offset < old_offset) {
2896                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2897                                     "Invalid offset/length. Malformed packet");
2898                         return;
2899                 }
2900         }
2901         return;
2902 }
2903
2904
2905 typedef struct _smb2_find_dissector_t {
2906         guint32 level;
2907         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
2908 } smb2_find_dissector_t;
2909
2910 smb2_find_dissector_t smb2_find_dissectors[] = {
2911         {SMB2_FIND_DIRECTORY_INFO,      dissect_smb2_file_directory_info},
2912         {SMB2_FIND_FULL_DIRECTORY_INFO, dissect_smb2_full_directory_info},
2913         {SMB2_FIND_BOTH_DIRECTORY_INFO, dissect_smb2_both_directory_info},
2914         {SMB2_FIND_NAME_INFO,           dissect_smb2_file_name_info},
2915         {SMB2_FIND_ID_BOTH_DIRECTORY_INFO,dissect_smb2_id_both_directory_info},
2916         {0, NULL}
2917 };
2918
2919 static void
2920 dissect_smb2_find_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
2921 {
2922         smb2_find_dissector_t *dis = smb2_find_dissectors;
2923
2924         while(dis->dissector){
2925                 if(si && si->saved && si->saved){
2926                         if(dis->level ==si->saved->infolevel){
2927                                 dis->dissector(tvb, pinfo, tree, si);
2928                                 return;
2929                         }
2930                 }
2931                 dis++;
2932         }
2933
2934         proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), FALSE);
2935         return;
2936 }
2937
2938 static int
2939 dissect_smb2_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2940 {
2941         offset_length_buffer_t olb;
2942         proto_item *item=NULL;
2943
2944         if(si->saved){
2945                 /* infolevel */
2946                 item=proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 0, si->saved->infolevel);
2947                 PROTO_ITEM_SET_GENERATED(item);
2948         }
2949
2950         if(!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type==SMB2_EI_FINDPATTERN) {
2951                 if (check_col(pinfo->cinfo, COL_INFO)){
2952                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
2953                                 val_to_str(si->saved->infolevel, smb2_find_info_levels, "(Level:0x%02x)"),
2954                                 (const char *)si->saved->extra_info);
2955                 }
2956
2957                 g_free(si->saved->extra_info);
2958                 si->saved->extra_info_type=SMB2_EI_NONE;
2959                 si->saved->extra_info=NULL;
2960         }
2961
2962         switch (si->status) {
2963         case 0x00000000: break;
2964         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2965         }
2966
2967         /* buffer code */
2968         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2969
2970         /* findinfo offset */
2971         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_find_info_blob);
2972
2973         /* the buffer */
2974         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_find_data);
2975
2976         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2977
2978         return offset;
2979 }
2980
2981 static int
2982 dissect_smb2_negotiate_protocol_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2983 {
2984         guint16 dc;
2985
2986         /* buffer code */
2987         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2988
2989         /* dialect count */
2990         dc = tvb_get_letohs(tvb, offset);
2991         proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, TRUE);
2992         offset += 2;
2993
2994         /* security mode, skip second byte */
2995         offset = dissect_smb2_secmode(tree, tvb, offset);
2996         offset++;
2997
2998
2999         /* reserved */
3000         offset += 2;
3001
3002         /* capabilities */
3003         offset = dissect_smb2_capabilities(tree, tvb, offset);
3004
3005         /* client guid */
3006         proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, TRUE);
3007         offset += 16;
3008
3009         /* client boot time */
3010         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
3011         offset += 8;
3012
3013         for(;dc>0;dc--){
3014                 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, TRUE);
3015                 offset += 2;
3016         }
3017
3018         return offset;
3019 }
3020
3021 static int
3022 dissect_smb2_negotiate_protocol_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3023 {
3024         offset_length_buffer_t s_olb;
3025
3026         switch (si->status) {
3027         case 0x00000000: break;
3028         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3029         }
3030
3031         /* buffer code */
3032         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3033
3034         /* security mode, skip second byte */
3035         offset = dissect_smb2_secmode(tree, tvb, offset);
3036         offset++;
3037
3038         /* dialect picked */
3039         proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, TRUE);
3040         offset += 2;
3041
3042         /* reserved */
3043         offset += 2;
3044
3045         /* server GUID */
3046         proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, TRUE);
3047         offset += 16;
3048
3049         /* capabilities */
3050         offset = dissect_smb2_capabilities(tree, tvb, offset);
3051
3052         /* max trans size */
3053         proto_tree_add_item(tree, hf_smb2_max_trans_size, tvb, offset, 4, TRUE);
3054         offset += 4;
3055
3056         /* max read size */
3057         proto_tree_add_item(tree, hf_smb2_max_read_size, tvb, offset, 4, TRUE);
3058         offset += 4;
3059
3060         /* max write size */
3061         proto_tree_add_item(tree, hf_smb2_max_write_size, tvb, offset, 4, TRUE);
3062         offset += 4;
3063
3064         /* current time */
3065         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_current_time);
3066         offset += 8;
3067
3068         /* boot time */
3069         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
3070         offset += 8;
3071
3072         /* security blob offset/length */
3073         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3074
3075         /* the security blob itself */
3076         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3077
3078         /* reserved */
3079         offset += 4;
3080
3081         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3082
3083         return offset;
3084 }
3085
3086 static int
3087 dissect_smb2_getinfo_parameters(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
3088 {
3089         switch(si->saved->class){
3090         case SMB2_CLASS_FILE_INFO:
3091                 switch(si->saved->infolevel){
3092                 default:
3093                         /* we dont handle this infolevel yet */
3094                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3095                         offset += tvb_length_remaining(tvb, offset);
3096                 }
3097                 break;
3098         case SMB2_CLASS_FS_INFO:
3099                 switch(si->saved->infolevel){
3100                 default:
3101                         /* we dont handle this infolevel yet */
3102                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3103                         offset += tvb_length_remaining(tvb, offset);
3104                 }
3105                 break;
3106         case SMB2_CLASS_SEC_INFO:
3107                 switch(si->saved->infolevel){
3108                 case SMB2_SEC_INFO_00:
3109                         dissect_security_information_mask(tvb, tree, offset+8);
3110                         break;
3111                 default:
3112                         /* we dont handle this infolevel yet */
3113                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3114                         offset += tvb_length_remaining(tvb, offset);
3115                 }
3116                 break;
3117         default:
3118                 /* we dont handle this class yet */
3119                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3120                 offset += tvb_length_remaining(tvb, offset);
3121         }
3122         return offset;
3123 }
3124
3125
3126 static int
3127 dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
3128 {
3129         char cl, il;
3130         proto_item *item;
3131         int hfindex;
3132         static const value_string dummy_value_string[] = {
3133                 { 0, NULL }
3134         };
3135         const value_string *vs;
3136
3137         if(si->flags & SMB2_FLAGS_RESPONSE){
3138                 if(!si->saved){
3139                         return offset;
3140                 }
3141                 cl=si->saved->class;
3142                 il=si->saved->infolevel;
3143         } else {
3144                 cl=tvb_get_guint8(tvb, offset);
3145                 il=tvb_get_guint8(tvb, offset+1);
3146                 if(si->saved){
3147                         si->saved->class=cl;
3148                         si->saved->infolevel=il;
3149                 }
3150         }
3151
3152
3153         switch(cl){
3154         case SMB2_CLASS_FILE_INFO:
3155                 hfindex=hf_smb2_infolevel_file_info;
3156                 vs=smb2_file_info_levels;
3157                 break;
3158         case SMB2_CLASS_FS_INFO:
3159                 hfindex=hf_smb2_infolevel_fs_info;
3160                 vs=smb2_fs_info_levels;
3161                 break;
3162         case SMB2_CLASS_SEC_INFO:
3163                 hfindex=hf_smb2_infolevel_sec_info;
3164                 vs=smb2_sec_info_levels;
3165                 break;
3166         default:
3167                 hfindex=hf_smb2_infolevel;
3168                 vs=dummy_value_string;
3169         }
3170
3171
3172         /* class */
3173         item=proto_tree_add_uint(tree, hf_smb2_class, tvb, offset, 1, cl);
3174         if(si->flags & SMB2_FLAGS_RESPONSE){
3175                 PROTO_ITEM_SET_GENERATED(item);
3176         }
3177         /* infolevel */
3178         item=proto_tree_add_uint(tree, hfindex, tvb, offset+1, 1, il);
3179         if(si->flags & SMB2_FLAGS_RESPONSE){
3180                 PROTO_ITEM_SET_GENERATED(item);
3181         }
3182         offset += 2;
3183
3184         if(!(si->flags & SMB2_FLAGS_RESPONSE)){
3185                 /* Only update COL_INFO for requests. It clutters the
3186                  * display ab bit too much if we do it for replies
3187                  * as well.
3188                  */
3189                 if (check_col(pinfo->cinfo, COL_INFO)){
3190                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s/%s",
3191                                 val_to_str(cl, smb2_class_vals, "(Class:0x%02x)"),
3192                                 val_to_str(il, vs, "(Level:0x%02x)"));
3193                 }
3194         }
3195
3196         return offset;
3197 }
3198
3199 static int
3200 dissect_smb2_getinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3201 {
3202         /* buffer code */
3203         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3204
3205         /* class and info level */
3206         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3207
3208         /* max response size */
3209         proto_tree_add_item(tree, hf_smb2_max_response_size, tvb, offset, 4, TRUE);
3210         offset += 4;
3211
3212         /* parameters */
3213         if(si->saved){
3214                 dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
3215         } else {
3216                 /* some unknown bytes */
3217                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3218         }
3219         offset += 16;
3220
3221         /* fid */
3222         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3223
3224         return offset;
3225 }
3226
3227 static int
3228 dissect_smb2_infolevel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si, guint8 class, guint8 infolevel)
3229 {
3230         int old_offset = offset;
3231
3232         switch(class){
3233         case SMB2_CLASS_FILE_INFO:
3234                 switch(infolevel){
3235                 case SMB2_FILE_BASIC_INFO:
3236                         offset = dissect_smb2_file_basic_info(tvb, pinfo, tree, offset, si);
3237                         break;
3238                 case SMB2_FILE_STANDARD_INFO:
3239                         offset = dissect_smb2_file_standard_info(tvb, pinfo, tree, offset, si);
3240                         break;
3241                 case SMB2_FILE_INTERNAL_INFO:
3242                         offset = dissect_smb2_file_internal_info(tvb, pinfo, tree, offset, si);
3243                         break;
3244                 case SMB2_FILE_EA_INFO:
3245                         offset = dissect_smb2_file_ea_info(tvb, pinfo, tree, offset, si);
3246                         break;
3247                 case SMB2_FILE_ACCESS_INFO:
3248                         offset = dissect_smb2_file_access_info(tvb, pinfo, tree, offset, si);
3249                         break;
3250                 case SMB2_FILE_RENAME_INFO:
3251                         offset = dissect_smb2_file_rename_info(tvb, pinfo, tree, offset, si);
3252                         break;
3253