Document the new Copy Profile button.
[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  * See http://wiki.wireshark.org/SMB2  for documentation of
6  * this protocol.
7  * If you edit this file, keep the wiki updated as well.
8  *
9  * $Id$
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <epan/packet.h>
35 #include <epan/conversation.h>
36 #include <epan/tap.h>
37 #include <epan/emem.h>
38
39 #include "packet-smb2.h"
40 #include "packet-dcerpc.h"
41 #include "packet-ntlmssp.h"
42 #include "packet-windows-common.h"
43 #include "packet-smb-common.h"
44 #include "packet-smb.h"
45 #include "packet-dcerpc-nt.h"
46 #include <string.h>
47
48
49
50 static int proto_smb2 = -1;
51 static int hf_smb2_cmd = -1;
52 static int hf_smb2_nt_status = -1;
53 static int hf_smb2_response_to = -1;
54 static int hf_smb2_response_in = -1;
55 static int hf_smb2_time = -1;
56 static int hf_smb2_header_len = -1;
57 static int hf_smb2_seqnum = -1;
58 static int hf_smb2_pid = -1;
59 static int hf_smb2_tid = -1;
60 static int hf_smb2_aid = -1;
61 static int hf_smb2_sesid = -1;
62 static int hf_smb2_previous_sesid = -1;
63 static int hf_smb2_flags_response = -1;
64 static int hf_smb2_flags_async_cmd = -1;
65 static int hf_smb2_flags_dfs_op = -1;
66 static int hf_smb2_flags_chained = -1;
67 static int hf_smb2_flags_signature = -1;
68 static int hf_smb2_chain_offset = -1;
69 static int hf_smb2_response_buffer_offset = -1;
70 static int hf_smb2_security_blob_offset = -1;
71 static int hf_smb2_security_blob_len = -1;
72 static int hf_smb2_security_blob = -1;
73 static int hf_smb2_ioctl_in_data = -1;
74 static int hf_smb2_ioctl_out_data = -1;
75 static int hf_smb2_unknown = -1;
76 static int hf_smb2_unknown_timestamp = -1;
77 static int hf_smb2_create_timestamp = -1;
78 static int hf_smb2_oplock = -1;
79 static int hf_smb2_close_flags = -1;
80 static int hf_smb2_notify_flags = -1;
81 static int hf_smb2_last_access_timestamp = -1;
82 static int hf_smb2_last_write_timestamp = -1;
83 static int hf_smb2_last_change_timestamp = -1;
84 static int hf_smb2_current_time = -1;
85 static int hf_smb2_boot_time = -1;
86 static int hf_smb2_filename = -1;
87 static int hf_smb2_filename_len = -1;
88 static int hf_smb2_nlinks = -1;
89 static int hf_smb2_delete_pending = -1;
90 static int hf_smb2_is_directory = -1;
91 static int hf_smb2_file_id = -1;
92 static int hf_smb2_allocation_size = -1;
93 static int hf_smb2_end_of_file = -1;
94 static int hf_smb2_tree = -1;
95 static int hf_smb2_find_pattern = -1;
96 static int hf_smb2_find_info_level = -1;
97 static int hf_smb2_find_info_blob = -1;
98 static int hf_smb2_client_guid = -1;
99 static int hf_smb2_server_guid = -1;
100 static int hf_smb2_object_id = -1;
101 static int hf_smb2_birth_volume_id = -1;
102 static int hf_smb2_birth_object_id = -1;
103 static int hf_smb2_domain_id = -1;
104 static int hf_smb2_class = -1;
105 static int hf_smb2_infolevel = -1;
106 static int hf_smb2_infolevel_file_info = -1;
107 static int hf_smb2_infolevel_fs_info = -1;
108 static int hf_smb2_infolevel_sec_info = -1;
109 static int hf_smb2_max_response_size = -1;
110 static int hf_smb2_max_ioctl_in_size = -1;
111 static int hf_smb2_max_ioctl_out_size = -1;
112 static int hf_smb2_required_buffer_size = -1;
113 static int hf_smb2_response_size = -1;
114 static int hf_smb2_setinfo_size = -1;
115 static int hf_smb2_setinfo_offset = -1;
116 static int hf_smb2_file_basic_info = -1;
117 static int hf_smb2_file_standard_info = -1;
118 static int hf_smb2_file_internal_info = -1;
119 static int hf_smb2_file_ea_info = -1;
120 static int hf_smb2_file_access_info = -1;
121 static int hf_smb2_file_rename_info = -1;
122 static int hf_smb2_file_disposition_info = -1;
123 static int hf_smb2_file_position_info = -1;
124 static int hf_smb2_file_info_0f = -1;
125 static int hf_smb2_file_mode_info = -1;
126 static int hf_smb2_file_alignment_info = -1;
127 static int hf_smb2_file_all_info = -1;
128 static int hf_smb2_file_allocation_info = -1;
129 static int hf_smb2_file_endoffile_info = -1;
130 static int hf_smb2_file_alternate_name_info = -1;
131 static int hf_smb2_file_stream_info = -1;
132 static int hf_smb2_file_pipe_info = -1;
133 static int hf_smb2_file_compression_info = -1;
134 static int hf_smb2_file_network_open_info = -1;
135 static int hf_smb2_file_attribute_tag_info = -1;
136 static int hf_smb2_fs_info_01 = -1;
137 static int hf_smb2_fs_info_03 = -1;
138 static int hf_smb2_fs_info_04 = -1;
139 static int hf_smb2_fs_info_05 = -1;
140 static int hf_smb2_fs_info_06 = -1;
141 static int hf_smb2_fs_info_07 = -1;
142 static int hf_smb2_fs_objectid_info = -1;
143 static int hf_smb2_sec_info_00 = -1;
144 static int hf_smb2_fid = -1;
145 static int hf_smb2_write_length = -1;
146 static int hf_smb2_write_data = -1;
147 static int hf_smb2_read_length = -1;
148 static int hf_smb2_read_remaining = -1;
149 static int hf_smb2_file_offset = -1;
150 static int hf_smb2_read_data = -1;
151 static int hf_smb2_disposition_delete_on_close = -1;
152 static int hf_smb2_create_disposition = -1;
153 static int hf_smb2_create_chain_offset = -1;
154 static int hf_smb2_create_chain_data = -1;
155 static int hf_smb2_data_offset = -1;
156 static int hf_smb2_data_length = -1;
157 static int hf_smb2_extrainfo = -1;
158 static int hf_smb2_create_action = -1;
159 static int hf_smb2_next_offset = -1;
160 static int hf_smb2_ea_size = -1;
161 static int hf_smb2_ea_flags = -1;
162 static int hf_smb2_ea_name_len = -1;
163 static int hf_smb2_ea_data_len = -1;
164 static int hf_smb2_ea_name = -1;
165 static int hf_smb2_ea_data = -1;
166 static int hf_smb2_buffer_code_len = -1;
167 static int hf_smb2_buffer_code_flags_dyn = -1;
168 static int hf_smb2_olb_offset = -1;
169 static int hf_smb2_olb_length = -1;
170 static int hf_smb2_tag = -1;
171 static int hf_smb2_impersonation_level = -1;
172 static int hf_smb2_ioctl_function = -1;
173 static int hf_smb2_ioctl_function_device = -1;
174 static int hf_smb2_ioctl_function_access = -1;
175 static int hf_smb2_ioctl_function_function = -1;
176 static int hf_smb2_ioctl_function_method = -1;
177 static int hf_smb2_ioctl_shadow_copy_num_volumes = -1;
178 static int hf_smb2_ioctl_shadow_copy_num_labels = -1;
179 static int hf_smb2_ioctl_shadow_copy_count = -1;
180 static int hf_smb2_ioctl_shadow_copy_label = -1;
181 static int hf_smb2_compression_format = -1;
182 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
183 static int hf_smb2_acct_name = -1;
184 static int hf_smb2_domain_name = -1;
185 static int hf_smb2_host_name = -1;
186 static int hf_smb2_auth_frame = -1;
187 static int hf_smb2_tcon_frame = -1;
188 static int hf_smb2_share_type = -1;
189 static int hf_smb2_signature = -1;
190 static int hf_smb2_epoch = -1;
191 static int hf_smb2_credits_requested = -1;
192 static int hf_smb2_credits_granted = -1;
193 static int hf_smb2_dialect_count = -1;
194 static int hf_smb2_security_mode = -1;
195 static int hf_smb2_secmode_flags_sign_required = -1;
196 static int hf_smb2_secmode_flags_sign_enabled = -1;
197 static int hf_smb2_capabilities = -1;
198 static int hf_smb2_cap_dfs = -1;
199 static int hf_smb2_dialect = -1;
200 static int hf_smb2_max_trans_size = -1;
201 static int hf_smb2_max_read_size = -1;
202 static int hf_smb2_max_write_size = -1;
203 static int hf_smb2_vcnum = -1;
204 static int hf_smb2_channel = -1;
205 static int hf_smb2_session_flags = -1;
206 static int hf_smb2_ses_flags_guest = -1;
207 static int hf_smb2_ses_flags_null = -1;
208 static int hf_smb2_share_flags = -1;
209 static int hf_smb2_share_flags_dfs = -1;
210 static int hf_smb2_share_flags_dfs_root = -1;
211 static int hf_smb2_share_flags_restrict_exclusive_opens = -1;
212 static int hf_smb2_share_flags_force_shared_delete = -1;
213 static int hf_smb2_share_flags_allow_namespace_caching = -1;
214 static int hf_smb2_share_flags_access_based_dir_enum = -1;
215 static int hf_smb2_share_caching = -1;
216 static int hf_smb2_share_caps = -1;
217 static int hf_smb2_share_caps_dfs = -1;
218 static int hf_smb2_create_flags = -1;
219 static int hf_smb2_lock_count = -1;
220 static int hf_smb2_min_count = -1;
221 static int hf_smb2_remaining_bytes = -1;
222 static int hf_smb2_channel_info_offset = -1;
223 static int hf_smb2_channel_info_length = -1;
224 static int hf_smb2_ioctl_flags = -1;
225 static int hf_smb2_ioctl_is_fsctl = -1;
226 static int hf_smb2_close_pq_attrib = -1;
227 static int hf_smb2_notify_watch_tree = -1;
228 static int hf_smb2_output_buffer_len = -1;
229 static int hf_smb2_notify_out_data = -1;
230 static int hf_smb2_find_flags = -1;
231 static int hf_smb2_find_flags_restart_scans = -1;
232 static int hf_smb2_find_flags_single_entry = -1;
233 static int hf_smb2_find_flags_index_specified = -1;
234 static int hf_smb2_find_flags_reopen = -1;
235 static int hf_smb2_file_index = -1;
236 static int hf_smb2_file_directory_info = -1;
237 static int hf_smb2_both_directory_info = -1;
238 static int hf_smb2_short_name_len = -1;
239 static int hf_smb2_short_name = -1;
240 static int hf_smb2_id_both_directory_info = -1;
241 static int hf_smb2_full_directory_info = -1;
242 static int hf_smb2_file_name_info = -1;
243 static int hf_smb2_lock_info = -1;
244 static int hf_smb2_lock_length = -1;
245 static int hf_smb2_lock_flags = -1;
246 static int hf_smb2_lock_flags_shared = -1;
247 static int hf_smb2_lock_flags_exclusive = -1;
248 static int hf_smb2_lock_flags_unlock = -1;
249 static int hf_smb2_lock_flags_fail_immediately = -1;
250 static int hf_smb2_error_byte_count = -1;
251 static int hf_smb2_error_data = -1;
252 static int hf_smb2_error_reserved = -1;
253
254 static gint ett_smb2 = -1;
255 static gint ett_smb2_olb = -1;
256 static gint ett_smb2_ea = -1;
257 static gint ett_smb2_header = -1;
258 static gint ett_smb2_command = -1;
259 static gint ett_smb2_secblob = -1;
260 static gint ett_smb2_file_basic_info = -1;
261 static gint ett_smb2_file_standard_info = -1;
262 static gint ett_smb2_file_internal_info = -1;
263 static gint ett_smb2_file_ea_info = -1;
264 static gint ett_smb2_file_access_info = -1;
265 static gint ett_smb2_file_position_info = -1;
266 static gint ett_smb2_file_mode_info = -1;
267 static gint ett_smb2_file_alignment_info = -1;
268 static gint ett_smb2_file_all_info = -1;
269 static gint ett_smb2_file_allocation_info = -1;
270 static gint ett_smb2_file_endoffile_info = -1;
271 static gint ett_smb2_file_alternate_name_info = -1;
272 static gint ett_smb2_file_stream_info = -1;
273 static gint ett_smb2_file_pipe_info = -1;
274 static gint ett_smb2_file_compression_info = -1;
275 static gint ett_smb2_file_network_open_info = -1;
276 static gint ett_smb2_file_attribute_tag_info = -1;
277 static gint ett_smb2_file_rename_info = -1;
278 static gint ett_smb2_file_disposition_info = -1;
279 static gint ett_smb2_file_info_0f = -1;
280 static gint ett_smb2_fs_info_01 = -1;
281 static gint ett_smb2_fs_info_03 = -1;
282 static gint ett_smb2_fs_info_04 = -1;
283 static gint ett_smb2_fs_info_05 = -1;
284 static gint ett_smb2_fs_info_06 = -1;
285 static gint ett_smb2_fs_info_07 = -1;
286 static gint ett_smb2_fs_objectid_info = -1;
287 static gint ett_smb2_sec_info_00 = -1;
288 static gint ett_smb2_tid_tree = -1;
289 static gint ett_smb2_sesid_tree = -1;
290 static gint ett_smb2_create_chain_element = -1;
291 static gint ett_smb2_MxAc_buffer = -1;
292 static gint ett_smb2_ioctl_function = -1;
293 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
294 static gint ett_smb2_flags = -1;
295 static gint ett_smb2_sec_mode = -1;
296 static gint ett_smb2_capabilities = -1;
297 static gint ett_smb2_ses_flags = -1;
298 static gint ett_smb2_share_flags = -1;
299 static gint ett_smb2_share_caps = -1;
300 static gint ett_smb2_ioctl_flags = -1;
301 static gint ett_smb2_close_flags = -1;
302 static gint ett_smb2_notify_flags = -1;
303 static gint ett_smb2_find_flags = -1;
304 static gint ett_smb2_file_directory_info = -1;
305 static gint ett_smb2_both_directory_info = -1;
306 static gint ett_smb2_id_both_directory_info = -1;
307 static gint ett_smb2_full_directory_info = -1;
308 static gint ett_smb2_file_name_info = -1;
309 static gint ett_smb2_lock_info = -1;
310 static gint ett_smb2_lock_flags = -1;
311
312 static int smb2_tap = -1;
313
314 static dissector_handle_t gssapi_handle = NULL;
315 static dissector_handle_t ntlmssp_handle = NULL;
316
317 static heur_dissector_list_t smb2_heur_subdissector_list;
318
319 #define SMB2_CLASS_FILE_INFO    0x01
320 #define SMB2_CLASS_FS_INFO      0x02
321 #define SMB2_CLASS_SEC_INFO     0x03
322 static const value_string smb2_class_vals[] = {
323         { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
324         { SMB2_CLASS_FS_INFO,   "FS_INFO"},
325         { SMB2_CLASS_SEC_INFO,  "SEC_INFO"},
326         { 0, NULL }
327 };
328
329 #define SMB2_SHARE_TYPE_FILE    0x0001
330 #define SMB2_SHARE_TYPE_IPC     0x0002
331 #define SMB2_SHARE_TYPE_PRINT   0x0003
332 static const value_string smb2_share_type_vals[] = {
333         { SMB2_SHARE_TYPE_FILE,         "File Share" },
334         { SMB2_SHARE_TYPE_IPC,          "IPC share" },
335         { SMB2_SHARE_TYPE_PRINT,        "Print Share" },
336         { 0, NULL }
337 };
338
339
340 #define SMB2_FILE_BASIC_INFO    0x04
341 #define SMB2_FILE_STANDARD_INFO 0x05
342 #define SMB2_FILE_INTERNAL_INFO 0x06
343 #define SMB2_FILE_EA_INFO       0x07
344 #define SMB2_FILE_ACCESS_INFO   0x08
345 #define SMB2_FILE_RENAME_INFO   0x0a
346 #define SMB2_FILE_DISPOSITION_INFO      0x0d
347 #define SMB2_FILE_POSITION_INFO 0x0e
348 #define SMB2_FILE_INFO_0f       0x0f
349 #define SMB2_FILE_MODE_INFO     0x10
350 #define SMB2_FILE_ALIGNMENT_INFO        0x11
351 #define SMB2_FILE_ALL_INFO      0x12
352 #define SMB2_FILE_ALLOCATION_INFO       0x13
353 #define SMB2_FILE_ENDOFFILE_INFO        0x14
354 #define SMB2_FILE_ALTERNATE_NAME_INFO   0x15
355 #define SMB2_FILE_STREAM_INFO           0x16
356 #define SMB2_FILE_PIPE_INFO             0x17
357 #define SMB2_FILE_COMPRESSION_INFO      0x1c
358 #define SMB2_FILE_NETWORK_OPEN_INFO     0x22
359 #define SMB2_FILE_ATTRIBUTE_TAG_INFO    0x23
360 static const value_string smb2_file_info_levels[] = {
361         {SMB2_FILE_BASIC_INFO,          "SMB2_FILE_BASIC_INFO" },
362         {SMB2_FILE_STANDARD_INFO,       "SMB2_FILE_STANDARD_INFO" },
363         {SMB2_FILE_INTERNAL_INFO,       "SMB2_FILE_INTERNAL_INFO" },
364         {SMB2_FILE_EA_INFO,             "SMB2_FILE_EA_INFO" },
365         {SMB2_FILE_ACCESS_INFO,         "SMB2_FILE_ACCESS_INFO" },
366         {SMB2_FILE_RENAME_INFO,         "SMB2_FILE_RENAME_INFO" },
367         {SMB2_FILE_DISPOSITION_INFO,    "SMB2_FILE_DISPOSITION_INFO" },
368         {SMB2_FILE_POSITION_INFO,       "SMB2_FILE_POSITION_INFO" },
369         {SMB2_FILE_INFO_0f,             "SMB2_FILE_INFO_0f" },
370         {SMB2_FILE_MODE_INFO,           "SMB2_FILE_MODE_INFO" },
371         {SMB2_FILE_ALIGNMENT_INFO,      "SMB2_FILE_ALIGNMENT_INFO" },
372         {SMB2_FILE_ALL_INFO,            "SMB2_FILE_ALL_INFO" },
373         {SMB2_FILE_ALLOCATION_INFO,     "SMB2_FILE_ALLOCATION_INFO" },
374         {SMB2_FILE_ENDOFFILE_INFO,      "SMB2_FILE_ENDOFFILE_INFO" },
375         {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
376         {SMB2_FILE_STREAM_INFO,         "SMB2_FILE_STREAM_INFO" },
377         {SMB2_FILE_PIPE_INFO,           "SMB2_FILE_PIPE_INFO" },
378         {SMB2_FILE_COMPRESSION_INFO,    "SMB2_FILE_COMPRESSION_INFO" },
379         {SMB2_FILE_NETWORK_OPEN_INFO,   "SMB2_FILE_NETWORK_OPEN_INFO" },
380         {SMB2_FILE_ATTRIBUTE_TAG_INFO,  "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
381         { 0, NULL }
382 };
383
384
385
386 #define SMB2_FS_INFO_01         0x01
387 #define SMB2_FS_INFO_03         0x03
388 #define SMB2_FS_INFO_04         0x04
389 #define SMB2_FS_INFO_05         0x05
390 #define SMB2_FS_INFO_06         0x06
391 #define SMB2_FS_INFO_07         0x07
392 #define SMB2_FS_OBJECTID_INFO   0x08
393 static const value_string smb2_fs_info_levels[] = {
394         {SMB2_FS_INFO_01,       "SMB2_FS_INFO_01" },
395         {SMB2_FS_INFO_03,       "SMB2_FS_INFO_03" },
396         {SMB2_FS_INFO_04,       "SMB2_FS_INFO_04" },
397         {SMB2_FS_INFO_05,       "SMB2_FS_INFO_05" },
398         {SMB2_FS_INFO_06,       "SMB2_FS_INFO_06" },
399         {SMB2_FS_INFO_07,       "SMB2_FS_INFO_07" },
400         {SMB2_FS_OBJECTID_INFO, "SMB2_FS_OBJECTID_INFO" },
401         { 0, NULL }
402 };
403
404 #define SMB2_SEC_INFO_00        0x00
405 static const value_string smb2_sec_info_levels[] = {
406         {SMB2_SEC_INFO_00,      "SMB2_SEC_INFO_00" },
407         { 0, NULL }
408 };
409
410 #define SMB2_FIND_DIRECTORY_INFO         0x01
411 #define SMB2_FIND_FULL_DIRECTORY_INFO    0x02
412 #define SMB2_FIND_BOTH_DIRECTORY_INFO    0x03
413 #define SMB2_FIND_INDEX_SPECIFIED        0x04
414 #define SMB2_FIND_NAME_INFO              0x0C
415 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
416 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
417 static const value_string smb2_find_info_levels[] = {
418         { SMB2_FIND_DIRECTORY_INFO,             "SMB2_FIND_DIRECTORY_INFO" },
419         { SMB2_FIND_FULL_DIRECTORY_INFO,        "SMB2_FIND_FULL_DIRECTORY_INFO" },
420         { SMB2_FIND_BOTH_DIRECTORY_INFO,        "SMB2_FIND_BOTH_DIRECTORY_INFO" },
421         { SMB2_FIND_INDEX_SPECIFIED,            "SMB2_FIND_INDEX_SPECIFIED" },
422         { SMB2_FIND_NAME_INFO,                  "SMB2_FIND_NAME_INFO" },
423         { SMB2_FIND_ID_BOTH_DIRECTORY_INFO,     "SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
424         { SMB2_FIND_ID_FULL_DIRECTORY_INFO,     "SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
425         { 0, NULL }
426 };
427
428 /* unmatched smb_saved_info structures.
429    For unmatched smb_saved_info structures we store the smb_saved_info
430    structure using the SEQNUM field.
431 */
432 static gint
433 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
434 {
435         smb2_saved_info_t *key1 = (smb2_saved_info_t *)k1;
436         smb2_saved_info_t *key2 = (smb2_saved_info_t *)k2;
437         return key1->seqnum==key2->seqnum;
438 }
439 static guint
440 smb2_saved_info_hash_unmatched(gconstpointer k)
441 {
442         smb2_saved_info_t *key = (smb2_saved_info_t *)k;
443         guint32 hash;
444
445         hash=(guint32) (key->seqnum&0xffffffff);
446         return hash;
447 }
448
449 /* matched smb_saved_info structures.
450    For matched smb_saved_info structures we store the smb_saved_info
451    structure using the SEQNUM field.
452 */
453 static gint
454 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
455 {
456         smb2_saved_info_t *key1 = (smb2_saved_info_t *)k1;
457         smb2_saved_info_t *key2 = (smb2_saved_info_t *)k2;
458         return key1->seqnum==key2->seqnum;
459 }
460 static guint
461 smb2_saved_info_hash_matched(gconstpointer k)
462 {
463         smb2_saved_info_t *key = (smb2_saved_info_t *)k;
464         guint32 hash;
465
466         hash=(guint32) (key->seqnum&0xffffffff);
467         return hash;
468 }
469
470 /* For Tids of a specific conversation.
471    This keeps track of tid->sharename mappings and other information about the
472    tid.
473    qqq
474    We might need to refine this if it occurs that tids are reused on a single
475    conversation.   we dont worry about that yet for simplicity
476 */
477 static gint
478 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
479 {
480         smb2_tid_info_t *key1 = (smb2_tid_info_t *)k1;
481         smb2_tid_info_t *key2 = (smb2_tid_info_t *)k2;
482         return key1->tid==key2->tid;
483 }
484 static guint
485 smb2_tid_info_hash(gconstpointer k)
486 {
487         smb2_tid_info_t *key = (smb2_tid_info_t *)k;
488         guint32 hash;
489
490         hash=key->tid;
491         return hash;
492 }
493
494 /* For Uids of a specific conversation.
495    This keeps track of uid->acct_name mappings and other information about the
496    uid.
497    qqq
498    We might need to refine this if it occurs that uids are reused on a single
499    conversation.   we dont worry about that yet for simplicity
500 */
501 static gint
502 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
503 {
504         smb2_sesid_info_t *key1 = (smb2_sesid_info_t *)k1;
505         smb2_sesid_info_t *key2 = (smb2_sesid_info_t *)k2;
506         return key1->sesid==key2->sesid;
507 }
508 static guint
509 smb2_sesid_info_hash(gconstpointer k)
510 {
511         smb2_sesid_info_t *key = (smb2_sesid_info_t *)k;
512         guint32 hash;
513
514         hash=(guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
515         return hash;
516 }
517
518 static int dissect_smb2_file_info_0f(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
519
520
521 /* This is a helper to dissect the common string type
522  * uint16 offset
523  * uint16 length
524  * ...
525  * char *string
526  *
527  * This function is called twice, first to decode the offset/length and
528  * second time to dissect the actual string.
529  * It is done this way since there is no guarantee that we have the full packet and we dont
530  * want to abort dissection too early if the packet ends somewhere between the
531  * length/offset and the actual buffer.
532  *
533  */
534 enum offset_length_buffer_offset_size {
535         OLB_O_UINT16_S_UINT16,
536         OLB_O_UINT16_S_UINT32,
537         OLB_O_UINT32_S_UINT32,
538         OLB_S_UINT32_O_UINT32
539 };
540 typedef struct _offset_length_buffer_t {
541         guint32 off;
542         guint32 len;
543         int off_offset;
544         int len_offset;
545         enum offset_length_buffer_offset_size offset_size;
546         int hfindex;
547 } offset_length_buffer_t;
548 static int
549 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
550                                enum offset_length_buffer_offset_size offset_size, int hfindex)
551 {
552         olb->hfindex=hfindex;
553         olb->offset_size=offset_size;
554         switch(offset_size){
555         case OLB_O_UINT16_S_UINT16:
556                 olb->off=tvb_get_letohs(tvb, offset);
557                 olb->off_offset=offset;
558                 offset += 2;
559                 olb->len=tvb_get_letohs(tvb, offset);
560                 olb->len_offset=offset;
561                 offset += 2;
562                 break;
563         case OLB_O_UINT16_S_UINT32:
564                 olb->off=tvb_get_letohs(tvb, offset);
565                 olb->off_offset=offset;
566                 offset += 2;
567                 olb->len=tvb_get_letohl(tvb, offset);
568                 olb->len_offset=offset;
569                 offset += 4;
570                 break;
571         case OLB_O_UINT32_S_UINT32:
572                 olb->off=tvb_get_letohl(tvb, offset);
573                 olb->off_offset=offset;
574                 offset += 4;
575                 olb->len=tvb_get_letohl(tvb, offset);
576                 olb->len_offset=offset;
577                 offset += 4;
578                 break;
579         case OLB_S_UINT32_O_UINT32:
580                 olb->len=tvb_get_letohl(tvb, offset);
581                 olb->len_offset=offset;
582                 offset += 4;
583                 olb->off=tvb_get_letohl(tvb, offset);
584                 olb->off_offset=offset;
585                 offset += 4;
586                 break;
587         }
588
589         return offset;
590 }
591
592 #define OLB_TYPE_UNICODE_STRING         0x01
593 #define OLB_TYPE_ASCII_STRING           0x02
594 static const char *
595 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
596 {
597         int len, off;
598         proto_item *item=NULL;
599         proto_tree *tree=NULL;
600         const char *name=NULL;
601         guint16 bc;
602         int offset;
603
604         offset=olb->off;
605         len=olb->len;
606         off=olb->off;
607         bc=tvb_length_remaining(tvb, offset);
608
609
610         /* sanity check */
611         tvb_ensure_bytes_exist(tvb, off, len);
612         if(((off+len)<off)
613         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))){
614                 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
615                                     "Invalid offset/length. Malformed packet");
616
617                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
618
619                 return NULL;
620         }
621
622
623         switch(type){
624         case OLB_TYPE_UNICODE_STRING:
625                 name = get_unicode_or_ascii_string(tvb, &off,
626                         TRUE, &len, TRUE, TRUE, &bc);
627                 if(!name){
628                         name="";
629                 }
630                 if(parent_tree){
631                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
632                         tree = proto_item_add_subtree(item, ett_smb2_olb);
633                 }
634                 break;
635         case OLB_TYPE_ASCII_STRING:
636                 name = get_unicode_or_ascii_string(tvb, &off,
637                         FALSE, &len, TRUE, TRUE, &bc);
638                 if(!name){
639                         name="";
640                 }
641                 if(parent_tree){
642                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
643                         tree = proto_item_add_subtree(item, ett_smb2_olb);
644                 }
645                 break;
646         }
647
648         switch(olb->offset_size){
649         case OLB_O_UINT16_S_UINT16:
650                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
651                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, TRUE);
652                 break;
653         case OLB_O_UINT16_S_UINT32:
654                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
655                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
656                 break;
657         case OLB_O_UINT32_S_UINT32:
658                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
659                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
660                 break;
661         case OLB_S_UINT32_O_UINT32:
662                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
663                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
664                 break;
665         }
666
667         return name;
668 }
669
670 static void
671 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
672                         offset_length_buffer_t *olb, smb2_info_t *si,
673                         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
674 {
675         int len, off;
676         proto_item *sub_item=NULL;
677         proto_tree *sub_tree=NULL;
678         tvbuff_t *sub_tvb=NULL;
679         guint16 bc;
680         int offset;
681
682         offset=olb->off;
683         len=olb->len;
684         off=olb->off;
685         bc=tvb_length_remaining(tvb, offset);
686
687         /* sanity check */
688         tvb_ensure_bytes_exist(tvb, off, len);
689         if(((off+len)<off)
690         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))){
691                 proto_tree_add_text(parent_tree, tvb, offset, tvb_length_remaining(tvb, offset),
692                                     "Invalid offset/length. Malformed packet");
693
694                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
695
696                 return;
697         }
698
699         /* if we dont want/need a subtree */
700         if(olb->hfindex==-1){
701                 sub_item=parent_tree;
702                 sub_tree=parent_tree;
703         } else {
704                 if(parent_tree){
705                         sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, TRUE);
706                         sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
707                 }
708         }
709
710         switch(olb->offset_size){
711         case OLB_O_UINT16_S_UINT16:
712                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
713                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, TRUE);
714                 break;
715         case OLB_O_UINT16_S_UINT32:
716                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
717                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
718                 break;
719         case OLB_O_UINT32_S_UINT32:
720                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
721                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
722                 break;
723         case OLB_S_UINT32_O_UINT32:
724                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
725                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
726                 break;
727         }
728
729         if (off == 0 || len == 0) {
730                 proto_item_append_text(sub_item, ": NO DATA");
731                 return;
732         }
733
734         if (!dissector) {
735                 return;
736         }
737
738         sub_tvb=tvb_new_subset(tvb, off, MIN((int)len, tvb_length_remaining(tvb, off)), len);
739
740         dissector(sub_tvb, pinfo, sub_tree, si);
741
742         return;
743 }
744
745 static int
746 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
747 {
748         if (olb->off == 0) {
749                 return offset;
750         }
751         return MAX(offset, (int)(olb->off + olb->len));
752 }
753
754 typedef struct _smb2_function {
755        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
756        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
757 } smb2_function;
758
759 static const true_false_string tfs_flags_response = {
760         "This is a RESPONSE",
761         "This is a REQUEST"
762 };
763
764 static const true_false_string tfs_flags_async_cmd = {
765         "This is an ASYNC command",
766         "This is a SYNC command"
767 };
768
769 static const true_false_string tfs_flags_dfs_op = {
770         "This is a DFS OPERATION",
771         "This is a normal operation"
772 };
773
774 static const true_false_string tfs_flags_chained = {
775         "This pdu a CHAINED command",
776         "This pdu is NOT a chained command"
777 };
778
779 static const true_false_string tfs_flags_signature = {
780         "This pdu is SIGNED",
781         "This pdu is NOT signed"
782 };
783
784 static const true_false_string tfs_cap_dfs = {
785         "This host supports DFS",
786         "This host does NOT support DFS"
787 };
788
789 static const value_string compression_format_vals[] = {
790   { 0, "COMPRESSION_FORMAT_NONE" },
791   { 1, "COMPRESSION_FORMAT_DEFAULT" },
792   { 2, "COMPRESSION_FORMAT_LZNT1" },
793   { 0, NULL }
794 };
795
796
797 static const value_string smb2_ioctl_vals[] = {
798   /* dissector implemented */
799   {0x0011c017, "IOCTL_DO_DCERPC"},
800   {0x00144064, "FSCTL_GET_SHADOW_COPY_DATA"},
801   {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},
802   {0x0009009C, "FSCTL_GET_OBJECT_ID"},
803   {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
804   {0x00098098, "FSCTL_SET_OBJECT_ID"},
805   {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},
806   {0x0009003C, "FSCTL_GET_COMPRESSION"},
807   {0x0009C040, "FSCTL_SET_COMPRESSION"},
808
809   /* dissector not yet implemented */
810   {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
811   {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
812   {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
813   {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
814   {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
815   {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
816   {0x00090018, "FSCTL_LOCK_VOLUME"},
817   {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
818   {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
819   {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
820   {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
821   {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
822   {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
823   {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
824   {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
825   {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
826   {0x00090058, "FSCTL_QUERY_FAT_BPB"},
827   {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
828   {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
829   {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
830   {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
831   {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
832   {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
833   {0x00090074, "FSCTL_MOVE_FILE"},
834   {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
835   {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
836   {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
837   {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
838   {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
839   {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
840   {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
841   {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
842   {0x000900A8, "FSCTL_GET_REPARSE_POINT"},
843   {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
844   {0x000940B3, "FSCTL_ENUM_USN_DATA"},
845   {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
846   {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
847   {0x000980C4, "FSCTL_SET_SPARSE"},
848   {0x000980C8, "FSCTL_SET_ZERO_DATA"},
849   {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},
850   {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
851   {0x000900D4, "FSCTL_SET_ENCRYPTION"},
852   {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
853   {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
854   {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
855   {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
856   {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
857   {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
858   {0x000900F0, "FSCTL_EXTEND_VOLUME"},
859   { 0, NULL }
860 };
861
862
863 static const value_string smb2_ioctl_device_vals[] = {
864   { 0x0001, "BEEP" },
865   { 0x0002, "CD_ROM" },
866   { 0x0003, "CD_ROM_FILE_SYSTEM" },
867   { 0x0004, "CONTROLLER" },
868   { 0x0005, "DATALINK" },
869   { 0x0006, "DFS" },
870   { 0x0007, "DISK" },
871   { 0x0008, "DISK_FILE_SYSTEM" },
872   { 0x0009, "FILE_SYSTEM" },
873   { 0x000a, "INPORT_PORT" },
874   { 0x000b, "KEYBOARD" },
875   { 0x000c, "MAILSLOT" },
876   { 0x000d, "MIDI_IN" },
877   { 0x000e, "MIDI_OUT" },
878   { 0x000f, "MOUSE" },
879   { 0x0010, "MULTI_UNC_PROVIDER" },
880   { 0x0011, "NAMED_PIPE" },
881   { 0x0012, "NETWORK" },
882   { 0x0013, "NETWORK_BROWSER" },
883   { 0x0014, "NETWORK_FILE_SYSTEM" },
884   { 0x0015, "NULL" },
885   { 0x0016, "PARALLEL_PORT" },
886   { 0x0017, "PHYSICAL_NETCARD" },
887   { 0x0018, "PRINTER" },
888   { 0x0019, "SCANNER" },
889   { 0x001a, "SERIAL_MOUSE_PORT" },
890   { 0x001b, "SERIAL_PORT" },
891   { 0x001c, "SCREEN" },
892   { 0x001d, "SOUND" },
893   { 0x001e, "STREAMS" },
894   { 0x001f, "TAPE" },
895   { 0x0020, "TAPE_FILE_SYSTEM" },
896   { 0x0021, "TRANSPORT" },
897   { 0x0022, "UNKNOWN" },
898   { 0x0023, "VIDEO" },
899   { 0x0024, "VIRTUAL_DISK" },
900   { 0x0025, "WAVE_IN" },
901   { 0x0026, "WAVE_OUT" },
902   { 0x0027, "8042_PORT" },
903   { 0x0028, "NETWORK_REDIRECTOR" },
904   { 0x0029, "BATTERY" },
905   { 0x002a, "BUS_EXTENDER" },
906   { 0x002b, "MODEM" },
907   { 0x002c, "VDM" },
908   { 0x002d, "MASS_STORAGE" },
909   { 0x002e, "SMB" },
910   { 0x002f, "KS" },
911   { 0x0030, "CHANGER" },
912   { 0x0031, "SMARTCARD" },
913   { 0x0032, "ACPI" },
914   { 0x0033, "DVD" },
915   { 0x0034, "FULLSCREEN_VIDEO" },
916   { 0x0035, "DFS_FILE_SYSTEM" },
917   { 0x0036, "DFS_VOLUME" },
918   { 0x0037, "SERENUM" },
919   { 0x0038, "TERMSRV" },
920   { 0x0039, "KSEC" },
921   { 0, NULL }
922 };
923
924 static const value_string smb2_ioctl_access_vals[] = {
925   { 0x00, "FILE_ANY_ACCESS" },
926   { 0x01, "FILE_READ_ACCESS" },
927   { 0x02, "FILE_WRITE_ACCESS" },
928   { 0x03, "FILE_READ_WRITE_ACCESS" },
929   { 0, NULL }
930 };
931
932 static const value_string smb2_ioctl_method_vals[] = {
933   { 0x00, "METHOD_BUFFERED" },
934   { 0x01, "METHOD_IN_DIRECT" },
935   { 0x02, "METHOD_OUT_DIRECT" },
936   { 0x03, "METHOD_NEITHER" },
937   { 0, NULL }
938 };
939
940 /* this is called from both smb and smb2. */
941 int
942 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
943 {
944         proto_item *item=NULL;
945         proto_tree *tree=NULL;
946         guint32 ioctl_function;
947
948         if(parent_tree){
949                 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, TRUE);
950                 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
951         }
952
953         ioctl_function=tvb_get_letohl(tvb, offset);
954         if (ioctlfunc) 
955                 *ioctlfunc=ioctl_function;
956         if(ioctl_function){
957                 /* device */
958                 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, TRUE);
959                 if (check_col(pinfo->cinfo, COL_INFO)){
960                         col_append_fstr(
961                                 pinfo->cinfo, COL_INFO, " %s",
962                                 val_to_str((ioctl_function>>16)&0xffff, smb2_ioctl_device_vals,
963                                 "Unknown (0x%08X)"));
964                 }
965
966                 /* access */
967                 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, TRUE);
968
969                 /* function */
970                 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, TRUE);
971                 if (check_col(pinfo->cinfo, COL_INFO)){
972                         col_append_fstr(
973                                 pinfo->cinfo, COL_INFO, " Function:0x%04x",
974                                 (ioctl_function>>2)&0x0fff);
975                 }
976
977                 /* method */
978                 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, TRUE);
979         }
980
981         offset += 4;
982
983         return offset;
984 }
985
986 /* fake the dce/rpc support structures so we can piggy back on
987  * dissect_nt_policy_hnd()   since this will allow us
988  * a cheap way to track where FIDs are opened, closed
989  * and fid->filename mappings
990  * if we want to do those things in the future.
991  */
992 #define FID_MODE_OPEN           0
993 #define FID_MODE_CLOSE          1
994 #define FID_MODE_USE            2
995 #define FID_MODE_DHNQ           3
996 #define FID_MODE_DHNC           4
997 static int
998 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
999 {
1000         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1001         static dcerpc_info di;  /* fake dcerpc_info struct */
1002         static dcerpc_call_value call_data;
1003         void *old_private_data;
1004         e_ctx_hnd policy_hnd;
1005         proto_item *hnd_item=NULL;
1006         char *fid_name;
1007         guint32 open_frame = 0, close_frame = 0;
1008
1009         di.conformant_run=0;
1010         /* we need di->call_data->flags.NDR64 == 0 */
1011         di.call_data=&call_data;
1012         old_private_data=pinfo->private_data;
1013         pinfo->private_data=&di;
1014
1015         switch(mode){
1016         case FID_MODE_OPEN:
1017                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
1018                 if(!pinfo->fd->flags.visited){
1019                         if(si->saved && si->saved->extra_info_type==SMB2_EI_FILENAME){
1020                                 fid_name = se_strdup_printf("File: %s", (char *)si->saved->extra_info);
1021                         } else {
1022                                 fid_name = se_strdup_printf("File: ");
1023                         }
1024                         dcerpc_store_polhnd_name(&policy_hnd, pinfo,
1025                                                   fid_name);
1026                 }
1027                 break;
1028         case FID_MODE_CLOSE:
1029                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
1030                 break;
1031         case FID_MODE_USE:
1032         case FID_MODE_DHNQ:
1033         case FID_MODE_DHNC:
1034                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
1035                 break;
1036         }
1037
1038         pinfo->private_data=old_private_data;
1039
1040
1041         /* put the filename in col_info */
1042         if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->fd->num)) {
1043                 if(fid_name){
1044                         if(hnd_item){
1045                                 proto_item_append_text(hnd_item, " %s", fid_name);
1046                         }
1047                         if (check_col(pinfo->cinfo, COL_INFO)){
1048                                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", fid_name);
1049                         }
1050                 }
1051         }
1052
1053         return offset;
1054 }
1055
1056
1057 /* this info level is unique to SMB2 and differst from the corresponding
1058  * SMB_FILE_ALL_INFO in SMB
1059  */
1060 static int
1061 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1062 {
1063         proto_item *item=NULL;
1064         proto_tree *tree=NULL;
1065         int length;
1066         const char *name="";
1067         guint16 bc;
1068
1069         if(parent_tree){
1070                 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, TRUE);
1071                 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
1072         }
1073
1074         /* create time */
1075         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1076
1077         /* last access */
1078         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1079
1080         /* last write */
1081         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1082
1083         /* last change */
1084         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1085
1086         /* File Attributes */
1087         offset = dissect_file_attributes(tvb, tree, offset, 4);
1088
1089         /* some unknown bytes */
1090         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1091         offset += 4;
1092
1093         /* allocation size */
1094         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
1095         offset += 8;
1096
1097         /* end of file */
1098         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
1099         offset += 8;
1100
1101         /* number of links */
1102         proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, TRUE);
1103         offset += 4;
1104
1105         /* delete pending */
1106         proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, TRUE);
1107         offset += 1;
1108
1109         /* is directory */
1110         proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, TRUE);
1111         offset += 1;
1112
1113         /* padding */
1114         offset += 2;
1115
1116         /* file id */
1117         proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, TRUE);
1118         offset += 8;
1119
1120         /* ea size */
1121         proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
1122         offset += 4;
1123
1124         /* access mask */
1125         offset = dissect_smb_access_mask(tvb, tree, offset);
1126
1127         /* some unknown bytes */
1128         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, FALSE);
1129         offset += 16;
1130
1131         /* file name length */
1132         length=tvb_get_letohs(tvb, offset);
1133         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, TRUE);
1134         offset += 2;
1135
1136         /* some unknown bytes */
1137         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
1138         offset += 2;
1139
1140         /* file name */
1141         if(length){
1142                 bc=tvb_length_remaining(tvb, offset);
1143                 name = get_unicode_or_ascii_string(tvb, &offset,
1144                         TRUE, &length, TRUE, TRUE, &bc);
1145                 if(name){
1146                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1147                                 offset, length, name);
1148                 }
1149
1150         }
1151         offset += length;
1152
1153
1154         return offset;
1155 }
1156
1157
1158 static int
1159 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1160 {
1161         proto_item *item=NULL;
1162         proto_tree *tree=NULL;
1163         guint16 bc;
1164         gboolean trunc;
1165
1166         if(parent_tree){
1167                 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, TRUE);
1168                 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
1169         }
1170
1171         bc=tvb_length_remaining(tvb, offset);
1172         offset = dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1173
1174         return offset;
1175 }
1176
1177 static int
1178 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1179 {
1180         proto_item *item=NULL;
1181         proto_tree *tree=NULL;
1182         guint16 bc;
1183         gboolean trunc;
1184
1185         if(parent_tree){
1186                 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, TRUE);
1187                 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
1188         }
1189
1190         bc=tvb_length_remaining(tvb, offset);
1191         offset = dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1192
1193         return offset;
1194 }
1195
1196 static int
1197 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1198 {
1199         proto_item *item=NULL;
1200         proto_tree *tree=NULL;
1201         guint16 bc;
1202         gboolean trunc;
1203
1204         if(parent_tree){
1205                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, TRUE);
1206                 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
1207         }
1208
1209         bc=tvb_length_remaining(tvb, offset);
1210         offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1211
1212         return offset;
1213 }
1214
1215
1216 static int
1217 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1218 {
1219         proto_item *item=NULL;
1220         proto_tree *tree=NULL;
1221
1222         if(parent_tree){
1223                 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, TRUE);
1224                 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
1225         }
1226
1227         /* create time */
1228         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1229
1230         /* last access */
1231         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1232
1233         /* last write */
1234         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1235
1236         /* last change */
1237         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1238
1239         /* File Attributes */
1240         offset = dissect_file_attributes(tvb, tree, offset, 4);
1241
1242         /* some unknown bytes */
1243         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1244         offset += 4;
1245
1246         return offset;
1247 }
1248
1249 static int
1250 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1251 {
1252         proto_item *item=NULL;
1253         proto_tree *tree=NULL;
1254         guint16 bc;
1255         gboolean trunc;
1256
1257         if(parent_tree){
1258                 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, TRUE);
1259                 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
1260         }
1261
1262         bc=tvb_length_remaining(tvb, offset);
1263         offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1264
1265         return offset;
1266 }
1267 static int
1268 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1269 {
1270         proto_item *item=NULL;
1271         proto_tree *tree=NULL;
1272         guint16 bc;
1273         gboolean trunc;
1274
1275         if(parent_tree){
1276                 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, TRUE);
1277                 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
1278         }
1279
1280         bc=tvb_length_remaining(tvb, offset);
1281         offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1282
1283         return offset;
1284 }
1285 static int
1286 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1287 {
1288         proto_item *item=NULL;
1289         proto_tree *tree=NULL;
1290         guint16 bc;
1291         gboolean trunc;
1292
1293         if(parent_tree){
1294                 item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, TRUE);
1295                 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
1296         }
1297
1298         bc=tvb_length_remaining(tvb, offset);
1299         offset = dissect_qfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1300
1301         return offset;
1302 }
1303 static int
1304 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1305 {
1306         proto_item *item=NULL;
1307         proto_tree *tree=NULL;
1308         guint16 bc;
1309         gboolean trunc;
1310
1311         if(parent_tree){
1312                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, TRUE);
1313                 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
1314         }
1315
1316         bc=tvb_length_remaining(tvb, offset);
1317         offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1318
1319         return offset;
1320 }
1321 static int
1322 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1323 {
1324         proto_item *item=NULL;
1325         proto_tree *tree=NULL;
1326         guint16 bc;
1327         gboolean trunc;
1328
1329         if(parent_tree){
1330                 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, TRUE);
1331                 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
1332         }
1333
1334         bc=tvb_length_remaining(tvb, offset);
1335         offset = dissect_qfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1336
1337         return offset;
1338 }
1339
1340 static int
1341 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1342 {
1343         proto_item *item=NULL;
1344         proto_tree *tree=NULL;
1345
1346         if(parent_tree){
1347                 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, TRUE);
1348                 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
1349         }
1350
1351         /* access mask */
1352         offset = dissect_smb_access_mask(tvb, tree, offset);
1353
1354         return offset;
1355 }
1356
1357 static int
1358 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1359 {
1360         proto_item *item=NULL;
1361         proto_tree *tree=NULL;
1362         guint16 bc;
1363         gboolean trunc;
1364
1365         if(parent_tree){
1366                 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, TRUE);
1367                 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
1368         }
1369
1370         bc=tvb_length_remaining(tvb, offset);
1371         offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1372
1373         return offset;
1374 }
1375
1376 static int
1377 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1378 {
1379         proto_item *item=NULL;
1380         proto_tree *tree=NULL;
1381         guint16 bc;
1382         gboolean trunc;
1383
1384         if(parent_tree){
1385                 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, TRUE);
1386                 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
1387         }
1388
1389         bc=tvb_length_remaining(tvb, offset);
1390         offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
1391
1392         return offset;
1393 }
1394
1395 static int
1396 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1397 {
1398         proto_item *item=NULL;
1399         proto_tree *tree=NULL;
1400         guint16 bc;
1401         gboolean trunc;
1402
1403         if(parent_tree){
1404                 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, TRUE);
1405                 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
1406         }
1407
1408         bc=tvb_length_remaining(tvb, offset);
1409         offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1410
1411         return offset;
1412 }
1413
1414 static int
1415 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1416 {
1417         proto_item *item=NULL;
1418         proto_tree *tree=NULL;
1419         guint16 bc;
1420         gboolean trunc;
1421
1422         if(parent_tree){
1423                 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, TRUE);
1424                 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
1425         }
1426
1427         bc=tvb_length_remaining(tvb, offset);
1428         offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1429
1430         return offset;
1431 }
1432
1433 static int
1434 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1435 {
1436         proto_item *item=NULL;
1437         proto_tree *tree=NULL;
1438         guint16 bc;
1439         gboolean trunc;
1440
1441         if(parent_tree){
1442                 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, TRUE);
1443                 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
1444         }
1445
1446
1447         bc=tvb_length_remaining(tvb, offset);
1448         offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1449
1450         return offset;
1451 }
1452
1453 static int
1454 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1455 {
1456         proto_item *item=NULL;
1457         proto_tree *tree=NULL;
1458         guint16 bc;
1459         gboolean trunc;
1460
1461         if(parent_tree){
1462                 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, TRUE);
1463                 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
1464         }
1465
1466
1467         bc=tvb_length_remaining(tvb, offset);
1468         offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1469
1470         return offset;
1471 }
1472
1473 static const true_false_string tfs_disposition_delete_on_close = {
1474         "DELETE this file when closed",
1475         "Normal access, do not delete on close"
1476 };
1477
1478 static int
1479 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1480 {
1481         proto_item *item=NULL;
1482         proto_tree *tree=NULL;
1483
1484         if(parent_tree){
1485                 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, TRUE);
1486                 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
1487         }
1488
1489         /* file disposition */
1490         proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, TRUE);
1491
1492         return offset;
1493 }
1494
1495 static int
1496 dissect_smb2_file_info_0f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1497 {
1498         proto_item *item=NULL;
1499         proto_tree *tree=NULL;
1500         guint32 next_offset;
1501         guint8 ea_name_len, ea_data_len;
1502
1503         if(parent_tree){
1504                 item = proto_tree_add_item(parent_tree, hf_smb2_file_info_0f, tvb, offset, -1, TRUE);
1505                 tree = proto_item_add_subtree(item, ett_smb2_file_info_0f);
1506         }
1507
1508         while(1){
1509                 int length;
1510                 const char *name="";
1511                 const char *data="";
1512                 guint16 bc;
1513                 int start_offset=offset;
1514                 proto_item *ea_item=NULL;
1515                 proto_tree *ea_tree=NULL;
1516
1517                 if(tree){
1518                         ea_item = proto_tree_add_text(tree, tvb, offset, -1, "EA:");
1519                         ea_tree = proto_item_add_subtree(ea_item, ett_smb2_ea);
1520                 }
1521
1522                 /* next offset */
1523                 next_offset=tvb_get_letohl(tvb, offset);
1524                 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
1525                 offset += 4;
1526
1527                 /* EA flags */
1528                 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, TRUE);
1529                 offset += 1;
1530
1531                 /* EA Name Length */
1532                 ea_name_len=tvb_get_guint8(tvb, offset);
1533                 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, TRUE);
1534                 offset += 1;
1535
1536                 /* EA Data Length */
1537                 ea_data_len=tvb_get_guint8(tvb, offset);
1538                 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 1, TRUE);
1539                 offset += 1;
1540
1541                 /* some unknown bytes */
1542                 proto_tree_add_item(ea_tree, hf_smb2_unknown, tvb, offset, 1, TRUE);
1543                 offset += 1;
1544
1545                 /* ea name */
1546                 length=ea_name_len;
1547                 if(length){
1548                         bc=tvb_length_remaining(tvb, offset);
1549                         name = get_unicode_or_ascii_string(tvb, &offset,
1550                                 FALSE, &length, TRUE, TRUE, &bc);
1551                         if(name){
1552                                 proto_tree_add_string(ea_tree, hf_smb2_ea_name, tvb,
1553                                         offset, length, name);
1554                         }
1555                 }
1556                 offset += ea_name_len;
1557
1558                 /* separator byte */
1559                 offset += 1;
1560
1561                 /* ea data */
1562                 length=ea_data_len;
1563                 if(length){
1564                         bc=tvb_length_remaining(tvb, offset);
1565                         data = get_unicode_or_ascii_string(tvb, &offset,
1566                                 FALSE, &length, TRUE, TRUE, &bc);
1567                         if(data){
1568                                 proto_tree_add_string(ea_tree, hf_smb2_ea_data, tvb,
1569                                         offset, length, data);
1570                         }
1571                 }
1572                 offset += ea_data_len;
1573
1574
1575                 if(ea_item){
1576                         proto_item_append_text(ea_item, " %s := %s", name, data);
1577                 }
1578                 proto_item_set_len(ea_item, offset-start_offset);
1579
1580
1581                 if(!next_offset){
1582                         break;
1583                 }
1584                 if(next_offset>256){
1585                         break;
1586                 }
1587
1588                 offset = start_offset+next_offset;
1589         }
1590
1591         return offset;
1592 }
1593
1594 static int
1595 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1596 {
1597         proto_item *item=NULL;
1598         proto_tree *tree=NULL;
1599         int length;
1600         const char *name="";
1601         guint16 bc;
1602
1603
1604         if(parent_tree){
1605                 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, TRUE);
1606                 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
1607         }
1608
1609         /* some unknown bytes */
1610         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, FALSE);
1611         offset += 16;
1612
1613         /* file name length */
1614         length=tvb_get_letohs(tvb, offset);
1615         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, TRUE);
1616         offset += 2;
1617
1618         /* some unknown bytes */
1619         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
1620         offset += 2;
1621
1622         /* file name */
1623         if(length){
1624                 bc=tvb_length_remaining(tvb, offset);
1625                 name = get_unicode_or_ascii_string(tvb, &offset,
1626                         TRUE, &length, TRUE, TRUE, &bc);
1627                 if(name){
1628                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1629                                 offset, length, name);
1630                 }
1631
1632                 if (check_col(pinfo->cinfo, COL_INFO)){
1633                         col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s",
1634                         name);
1635                 }
1636         }
1637         offset += length;
1638
1639         /* some unknown bytes */
1640         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1641         offset += 4;
1642
1643         return offset;
1644 }
1645
1646 static int
1647 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1648 {
1649         proto_item *item=NULL;
1650         proto_tree *tree=NULL;
1651
1652         if(parent_tree){
1653                 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, TRUE);
1654                 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
1655         }
1656
1657         /* security descriptor */
1658         offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_length_remaining(tvb, offset), NULL);
1659
1660         return offset;
1661 }
1662
1663 static int
1664 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1665 {
1666         proto_item *item=NULL;
1667         proto_tree *tree=NULL;
1668         guint16 bc;
1669
1670         if(parent_tree){
1671                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, TRUE);
1672                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
1673         }
1674
1675         bc=tvb_length_remaining(tvb, offset);
1676         offset=dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
1677
1678         return offset;
1679 }
1680
1681 static int
1682 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1683 {
1684         proto_item *item=NULL;
1685         proto_tree *tree=NULL;
1686         guint16 bc;
1687
1688         if(parent_tree){
1689                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, TRUE);
1690                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
1691         }
1692
1693         bc=tvb_length_remaining(tvb, offset);
1694         offset=dissect_nt_quota(tvb, tree, offset, &bc);
1695
1696         return offset;
1697 }
1698
1699 static int
1700 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1701 {
1702         proto_item *item=NULL;
1703         proto_tree *tree=NULL;
1704
1705         if(parent_tree){
1706                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, TRUE);
1707                 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
1708         }
1709
1710         /* FILE_OBJECTID_BUFFER */
1711         offset=dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
1712
1713         return offset;
1714 }
1715
1716 static int
1717 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1718 {
1719         proto_item *item=NULL;
1720         proto_tree *tree=NULL;
1721         guint16 bc;
1722
1723         if(parent_tree){
1724                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, TRUE);
1725                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
1726         }
1727
1728         bc=tvb_length_remaining(tvb, offset);
1729         offset=dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
1730
1731         return offset;
1732 }
1733
1734 static int
1735 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1736 {
1737         proto_item *item=NULL;
1738         proto_tree *tree=NULL;
1739         guint16 bc;
1740
1741         if(parent_tree){
1742                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, TRUE);
1743                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
1744         }
1745
1746
1747         bc=tvb_length_remaining(tvb, offset);
1748         offset=dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
1749
1750         return offset;
1751 }
1752
1753 static int
1754 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1755 {
1756         proto_item *item=NULL;
1757         proto_tree *tree=NULL;
1758         guint16 bc;
1759
1760         if(parent_tree){
1761                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, TRUE);
1762                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
1763         }
1764
1765
1766         bc=tvb_length_remaining(tvb, offset);
1767         offset=dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
1768
1769         return offset;
1770 }
1771
1772 static int
1773 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1774 {
1775         proto_item *item=NULL;
1776         proto_tree *tree=NULL;
1777         guint16 bc;
1778
1779         if(parent_tree){
1780                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, TRUE);
1781                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
1782         }
1783
1784
1785         bc=tvb_length_remaining(tvb, offset);
1786         offset=dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
1787
1788         return offset;
1789 }
1790
1791 static const value_string oplock_vals[] = {
1792         { 0x00, "No oplock" },
1793         { 0x01, "Level2 oplock" },
1794         { 0x08, "Exclusive oplock" },
1795         { 0x09, "Batch oplock" },
1796         { 0, NULL }
1797 };
1798
1799 static int
1800 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1801 {
1802         proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, TRUE);
1803
1804         offset += 1;
1805         return offset;
1806 }
1807
1808 static int
1809 dissect_smb2_buffercode(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 *length)
1810 {
1811         guint16 buffer_code;
1812
1813         /* dissect the first 2 bytes of the command PDU */
1814         buffer_code = tvb_get_letohs(tvb, offset);
1815         proto_tree_add_uint(tree, hf_smb2_buffer_code_len, tvb, offset, 2, buffer_code&0xfffe);
1816         proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, TRUE);
1817         offset += 2;
1818
1819         if(length){
1820                 *length=buffer_code&0xfffe;
1821         }
1822
1823         return offset;
1824 }
1825
1826 #define NEGPROT_CAP_DFS         0x00000001
1827 static int
1828 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1829 {
1830         guint32 cap;
1831         proto_item *item=NULL;
1832         proto_tree *tree=NULL;
1833
1834         cap = tvb_get_letohl(tvb, offset);
1835
1836         item = proto_tree_add_item(parent_tree, hf_smb2_capabilities, tvb, offset, 4, TRUE);
1837         tree = proto_item_add_subtree(item, ett_smb2_capabilities);
1838
1839
1840         proto_tree_add_boolean(tree, hf_smb2_cap_dfs, tvb, offset, 4, cap);
1841
1842
1843         offset += 4;
1844
1845         return offset;
1846 }
1847
1848
1849
1850 #define NEGPROT_SIGN_REQ        0x0002
1851 #define NEGPROT_SIGN_ENABLED    0x0001
1852
1853 static int
1854 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1855 {
1856         guint8 sm;
1857         proto_item *item=NULL;
1858         proto_tree *tree=NULL;
1859
1860         sm = tvb_get_guint8(tvb, offset);
1861
1862         item = proto_tree_add_item(parent_tree, hf_smb2_security_mode, tvb, offset, 1, TRUE);
1863         tree = proto_item_add_subtree(item, ett_smb2_sec_mode);
1864
1865
1866         proto_tree_add_boolean(tree, hf_smb2_secmode_flags_sign_required, tvb, offset, 1, sm);
1867         proto_tree_add_boolean(tree, hf_smb2_secmode_flags_sign_enabled, tvb, offset, 1, sm);
1868
1869
1870         offset += 1;
1871
1872         return offset;
1873 }
1874
1875 #define SES_FLAGS_GUEST         0x0001
1876 #define SES_FLAGS_NULL          0x0002
1877
1878 static int
1879 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1880 {
1881         guint16 sf;
1882         proto_item *item=NULL;
1883         proto_tree *tree=NULL;
1884
1885         sf = tvb_get_letohs(tvb, offset);
1886
1887         item = proto_tree_add_item(parent_tree, hf_smb2_session_flags, tvb, offset, 2, TRUE);
1888         tree = proto_item_add_subtree(item, ett_smb2_ses_flags);
1889
1890
1891         proto_tree_add_boolean(tree, hf_smb2_ses_flags_null, tvb, offset, 2, sf);
1892         proto_tree_add_boolean(tree, hf_smb2_ses_flags_guest, tvb, offset, 2, sf);
1893
1894
1895         offset += 2;
1896
1897         return offset;
1898 }
1899
1900 #define SHARE_FLAGS_manual_caching              0x00000000
1901 #define SHARE_FLAGS_auto_caching                0x00000010
1902 #define SHARE_FLAGS_vdo_caching                 0x00000020
1903 #define SHARE_FLAGS_no_caching                  0x00000030
1904
1905 static const value_string share_cache_vals[] = {
1906         { SHARE_FLAGS_manual_caching,   "manual_caching" },
1907         { SHARE_FLAGS_auto_caching,     "auto_caching" },
1908         { SHARE_FLAGS_vdo_caching,      "vdo_caching" },
1909         { SHARE_FLAGS_no_caching,       "no_caching" },
1910         { 0, NULL }
1911 };
1912
1913 #define SHARE_FLAGS_dfs                         0x00000001
1914 #define SHARE_FLAGS_dfs_root                    0x00000002
1915 #define SHARE_FLAGS_restrict_exclusive_opens    0x00000100
1916 #define SHARE_FLAGS_force_shared_delete         0x00000200
1917 #define SHARE_FLAGS_allow_namespace_caching     0x00000400
1918 #define SHARE_FLAGS_access_based_dir_enum       0x00000800
1919
1920 static int
1921 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
1922 {
1923         static const int *sf_fields[] = {
1924                 &hf_smb2_share_flags_dfs,
1925                 &hf_smb2_share_flags_dfs_root,
1926                 &hf_smb2_share_flags_restrict_exclusive_opens,
1927                 &hf_smb2_share_flags_force_shared_delete,
1928                 &hf_smb2_share_flags_allow_namespace_caching,
1929                 &hf_smb2_share_flags_access_based_dir_enum,
1930                 NULL
1931         };
1932         proto_item *item;
1933         guint32 cp;
1934
1935         item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, TRUE);
1936
1937         cp = tvb_get_letohl(tvb, offset);
1938         cp &= 0x00000030;
1939         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);
1940
1941
1942         offset += 4;
1943
1944         return offset;
1945 }
1946
1947 #define SHARE_CAPS_DFS          0x00000008
1948
1949 static int
1950 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
1951 {
1952         static const int *sc_fields[] = {
1953                 &hf_smb2_share_caps_dfs,
1954                 NULL
1955         };
1956         proto_item *item;
1957
1958         item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, TRUE);
1959
1960
1961         offset += 4;
1962
1963         return offset;
1964 }
1965
1966 static void
1967 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
1968 {
1969         if( (tvb_length(tvb)>=7)
1970         &&  (!tvb_memeql(tvb, 0, "NTLMSSP", 7))){
1971                 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
1972         } else {
1973                 call_dissector(gssapi_handle, tvb, pinfo, tree);
1974         }
1975         return;
1976 }
1977
1978 static int
1979 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
1980 {
1981         offset_length_buffer_t s_olb;
1982         const ntlmssp_header_t *ntlmssph;
1983         static int ntlmssp_tap_id = 0;
1984         int idx;
1985
1986         if(!ntlmssp_tap_id){
1987                 GString *error_string;
1988                 /* We dont specify any callbacks at all.
1989                  * Instead we manually fetch the tapped data after the
1990                  * security blob has been fully dissected and before
1991                  * we exit from this dissector.
1992                  */
1993                 error_string=register_tap_listener("ntlmssp", NULL, NULL,
1994                     0, NULL, NULL, NULL);
1995                 if(!error_string){
1996                         ntlmssp_tap_id=find_tap_id("ntlmssp");
1997                 }
1998         }
1999
2000
2001         /* buffer code */
2002         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2003         /* some unknown bytes */
2004
2005         /* num vcs */
2006         proto_tree_add_item(tree, hf_smb2_vcnum, tvb, offset, 1, TRUE);
2007         offset += 1;
2008
2009         /* security mode */
2010         offset = dissect_smb2_secmode(tree, tvb, offset);
2011
2012         /* capabilities */
2013         offset = dissect_smb2_capabilities(tree, tvb, offset);
2014
2015         /* channel */
2016         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, TRUE);
2017         offset += 4;
2018
2019         /* security blob offset/length */
2020         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2021
2022         /* previous session id */
2023         proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, TRUE);
2024         offset += 8;
2025
2026
2027         /* the security blob itself */
2028         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2029
2030         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2031
2032         /* If we have found a uid->acct_name mapping, store it */
2033         if(!pinfo->fd->flags.visited){
2034                 idx=0;
2035                 while((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
2036                         if(ntlmssph && ntlmssph->type==3){
2037                                 smb2_sesid_info_t *sesid;
2038                                 sesid=se_alloc(sizeof(smb2_sesid_info_t));
2039                                 sesid->sesid=si->sesid;
2040                                 sesid->acct_name=se_strdup(ntlmssph->acct_name);
2041                                 sesid->domain_name=se_strdup(ntlmssph->domain_name);
2042                                 sesid->host_name=se_strdup(ntlmssph->host_name);
2043                                 sesid->auth_frame=pinfo->fd->num;
2044                                 sesid->tids= g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
2045                                 g_hash_table_insert(si->conv->sesids, sesid, sesid);
2046                         }
2047                 }
2048         }
2049
2050         return offset;
2051 }
2052
2053 static int
2054 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2055 {
2056         gint byte_count;
2057
2058         /* buffer code */
2059         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2060
2061
2062         /* Reserved (2 bytes) */
2063         proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 2, TRUE);
2064         offset += 2;
2065
2066         /* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
2067         byte_count = tvb_get_ntohl(tvb, offset);
2068         proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, TRUE);
2069         offset += 4;
2070
2071         /* If the ByteCount field is zero then the server MUST supply an ErrorData field 
2072            that is one byte in length */
2073         if (byte_count == 0) byte_count = 1;
2074
2075         /* ErrorData (variable): A variable-length data field that contains extended 
2076            error information.*/
2077         proto_tree_add_item(tree, hf_smb2_error_data, tvb, offset, byte_count, TRUE);
2078         offset += byte_count;
2079
2080         return offset;
2081 }
2082
2083 static int
2084 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2085 {
2086         offset_length_buffer_t s_olb;
2087
2088         /* session_setup is special and we don't use dissect_smb2_error_response() here! */
2089
2090         /* buffer code */
2091         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2092
2093         /* session flags */
2094         offset = dissect_smb2_ses_flags(tree, tvb, offset);
2095
2096         /* security blob offset/length */
2097         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2098
2099         /* the security blob itself */
2100         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2101
2102         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2103
2104         return offset;
2105 }
2106
2107 static int
2108 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2109 {
2110         offset_length_buffer_t olb;
2111         const char *buf;
2112
2113         /* buffer code */
2114         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2115
2116         /* reserved */
2117         offset += 2;
2118
2119         /* tree  offset/length */
2120         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
2121
2122         /* tree string */
2123         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2124
2125         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2126
2127         /* treelen  +1 is overkill here if the string is unicode,
2128          * but who ever has more than a handful of TCON in a trace anyways
2129          */
2130         if(!pinfo->fd->flags.visited && si->saved && buf && olb.len){
2131                 si->saved->extra_info_type=SMB2_EI_TREENAME;
2132                 si->saved->extra_info=se_alloc(olb.len+1);
2133                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2134         }
2135
2136         if (check_col(pinfo->cinfo, COL_INFO)){
2137                 col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s", buf);
2138         }
2139
2140
2141         return offset;
2142 }
2143 static int
2144 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2145 {
2146         guint16 share_type;
2147
2148         switch (si->status) {
2149         case 0x00000000: break;
2150         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2151         }
2152
2153         /* buffer code */
2154         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2155
2156         /* share type */
2157         share_type = tvb_get_letohs(tvb, offset);
2158         proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 2, TRUE);
2159         offset += 2;
2160
2161         if(!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type==SMB2_EI_TREENAME && si->session) {
2162                 smb2_tid_info_t *tid, tid_key;
2163
2164                 tid_key.tid=si->tid;
2165                 tid=g_hash_table_lookup(si->session->tids, &tid_key);
2166                 if(tid){
2167                         g_hash_table_remove(si->session->tids, &tid_key);
2168                 }
2169                 tid=se_alloc(sizeof(smb2_tid_info_t));
2170                 tid->tid=si->tid;
2171                 tid->name=(char *)si->saved->extra_info;
2172                 tid->connect_frame=pinfo->fd->num;
2173                 tid->share_type=share_type;
2174
2175                 g_hash_table_insert(si->session->tids, tid, tid);
2176
2177                 si->saved->extra_info_type=SMB2_EI_NONE;
2178                 si->saved->extra_info=NULL;
2179         }
2180
2181         /* share flags */
2182         offset = dissect_smb2_share_flags(tree, tvb, offset);
2183
2184         /* share capabilities */
2185         offset = dissect_smb2_share_caps(tree, tvb, offset);
2186
2187         /* this is some sort of access mask */
2188         offset = dissect_smb_access_mask(tvb, tree, offset);
2189
2190         return offset;
2191 }
2192
2193 static int
2194 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2195 {
2196         /* buffer code */
2197         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2198
2199         /* reserved */
2200         offset += 2;
2201
2202         return offset;
2203 }
2204
2205 static int
2206 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2207 {
2208         switch (si->status) {
2209         case 0x00000000: break;
2210         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2211         }
2212
2213         /* buffer code */
2214         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2215
2216         /* reserved */
2217         offset += 2;
2218
2219         return offset;
2220 }
2221
2222 static int
2223 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2224 {
2225         /* buffer code */
2226         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2227
2228         /* reserved bytes */
2229         offset += 2;
2230
2231         return offset;
2232 }
2233
2234 static int
2235 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2236 {
2237         switch (si->status) {
2238         case 0x00000000: break;
2239         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2240         }
2241
2242         /* buffer code */
2243         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2244
2245         /* reserved bytes */
2246         offset += 2;
2247
2248         return offset;
2249 }
2250
2251 static int
2252 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2253 {
2254         /* buffer code */
2255         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2256
2257         /* some unknown bytes */
2258         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2259         offset += 2;
2260
2261         return offset;
2262 }
2263
2264 static int
2265 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2266 {
2267         switch (si->status) {
2268         case 0x00000000: break;
2269         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2270         }
2271
2272         /* buffer code */
2273         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2274
2275         /* some unknown bytes */
2276         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2277         offset += 2;
2278
2279         return offset;
2280 }
2281
2282 static int
2283 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2284 {
2285         proto_tree *flags_tree = NULL;
2286         proto_item *flags_item = NULL;
2287
2288         /* buffer code */
2289         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2290
2291         /* notify flags */
2292         if (tree) {
2293                 flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, TRUE);
2294                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
2295         }
2296         proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, TRUE);
2297         offset += 2;
2298
2299         /* output buffer length */
2300         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, TRUE);
2301         offset += 4;
2302
2303         /* fid */
2304         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2305
2306         /* completion filter */
2307         offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
2308
2309         /* reserved */
2310         offset += 4;
2311
2312         return offset;
2313 }
2314
2315 static void
2316 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
2317 {
2318         proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), TRUE);
2319 }
2320
2321 static int
2322 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
2323 {
2324         offset_length_buffer_t olb;
2325
2326         switch (si->status) {
2327         case 0x00000000: break;
2328         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2329         }
2330
2331         /* buffer code */
2332         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2333
2334         /* out buffer offset/length */
2335         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
2336
2337         /* out buffer */
2338         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
2339         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2340
2341         return offset;
2342 }
2343
2344 #define SMB2_FIND_FLAG_RESTART_SCANS            0x01
2345 #define SMB2_FIND_FLAG_SINGLE_ENTRY             0x02
2346 #define SMB2_FIND_FLAG_INDEX_SPECIFIED          0x04
2347 #define SMB2_FIND_FLAG_REOPEN                   0x10
2348
2349 static int
2350 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2351 {
2352         offset_length_buffer_t olb;
2353         const char *buf;
2354         guint8 il;
2355         static const int *f_fields[] = {
2356                 &hf_smb2_find_flags_restart_scans,
2357                 &hf_smb2_find_flags_single_entry,
2358                 &hf_smb2_find_flags_index_specified,
2359                 &hf_smb2_find_flags_reopen,
2360                 NULL
2361         };
2362
2363         /* buffer code */
2364         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2365
2366         il=tvb_get_guint8(tvb, offset);
2367         if(si->saved){
2368                 si->saved->infolevel=il;
2369         }
2370
2371         /* infolevel */
2372         proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
2373         offset += 1;
2374
2375         /* find flags */
2376         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, TRUE);
2377         offset += 1;
2378
2379         /* file index */
2380         proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2381         offset += 4;
2382
2383         /* fid */
2384         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2385
2386         /* search pattern  offset/length */
2387         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_find_pattern);
2388
2389         /* output buffer length */
2390         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, TRUE);
2391         offset += 4;
2392
2393         /* search pattern */
2394         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2395
2396         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2397
2398         if(!pinfo->fd->flags.visited && si->saved && olb.len){
2399                 si->saved->extra_info_type=SMB2_EI_FINDPATTERN;
2400                 si->saved->extra_info=g_malloc(olb.len+1);
2401                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2402         }
2403
2404         if (check_col(pinfo->cinfo, COL_INFO)){
2405                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
2406                         val_to_str(il, smb2_find_info_levels, "(Level:0x%02x)"),
2407                         buf);
2408         }
2409
2410         return offset;
2411 }
2412
2413 static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2414 {
2415         int offset = 0;
2416         proto_item *item=NULL;
2417         proto_tree *tree=NULL;
2418         const char *name=NULL;
2419         guint16 bc;
2420
2421         while(tvb_length_remaining(tvb, offset) > 4){
2422                 int old_offset = offset;
2423                 int next_offset;
2424                 int file_name_len;
2425
2426                 if(parent_tree){
2427                         item = proto_tree_add_item(parent_tree, hf_smb2_file_directory_info, tvb, offset, -1, TRUE);
2428                         tree = proto_item_add_subtree(item, ett_smb2_file_directory_info);
2429                 }
2430
2431                 /* next offset */       
2432                 next_offset = tvb_get_letohl(tvb, offset);
2433                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2434                 offset += 4;
2435
2436                 /* file index */
2437                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2438                 offset += 4;
2439
2440                 /* create time */
2441                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2442
2443                 /* last access */
2444                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2445
2446                 /* last write */
2447                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2448
2449                 /* last change */
2450                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2451
2452                 /* end of file */
2453                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2454                 offset += 8;
2455
2456                 /* allocation size */
2457                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2458                 offset += 8;
2459
2460                 /* File Attributes */
2461                 offset = dissect_file_attributes(tvb, tree, offset, 4);
2462
2463                 /* file name length */
2464                 file_name_len=tvb_get_letohl(tvb, offset);
2465                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2466                 offset += 4;
2467
2468                 /* file name */
2469                 if(file_name_len){
2470                         bc=file_name_len;
2471                         name = get_unicode_or_ascii_string(tvb, &offset,
2472                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2473                         if(name){
2474                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2475                                         offset, file_name_len, name);
2476                                 proto_item_append_text(item, ": %s", name);
2477
2478                         }
2479                 }
2480
2481                 proto_item_set_len(item, offset-old_offset);
2482
2483                 if (next_offset == 0){
2484                         return;
2485                 }
2486
2487                 offset = old_offset+next_offset;
2488                 if (offset < old_offset) {
2489                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2490                                     "Invalid offset/length. Malformed packet");
2491                         return;
2492                 }
2493         }
2494         return;
2495 }
2496
2497 static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2498 {
2499         int offset = 0;
2500         proto_item *item=NULL;
2501         proto_tree *tree=NULL;
2502         const char *name=NULL;
2503         guint16 bc;
2504
2505         while(tvb_length_remaining(tvb, offset) > 4){
2506                 int old_offset = offset;
2507                 int next_offset;
2508                 int file_name_len;
2509
2510                 if(parent_tree){
2511                         item = proto_tree_add_item(parent_tree, hf_smb2_full_directory_info, tvb, offset, -1, TRUE);
2512                         tree = proto_item_add_subtree(item, ett_smb2_full_directory_info);
2513                 }
2514
2515                 /* next offset */       
2516                 next_offset = tvb_get_letohl(tvb, offset);
2517                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2518                 offset += 4;
2519
2520                 /* file index */
2521                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2522                 offset += 4;
2523
2524                 /* create time */
2525                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2526
2527                 /* last access */
2528                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2529
2530                 /* last write */
2531                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2532
2533                 /* last change */
2534                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2535
2536                 /* end of file */
2537                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2538                 offset += 8;
2539
2540                 /* allocation size */
2541                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2542                 offset += 8;
2543
2544                 /* File Attributes */
2545                 offset = dissect_file_attributes(tvb, tree, offset, 4);
2546
2547                 /* file name length */
2548                 file_name_len=tvb_get_letohl(tvb, offset);
2549                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2550                 offset += 4;
2551
2552                 /* ea size */
2553                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2554                 offset += 4;
2555
2556                 /* file name */
2557                 if(file_name_len){
2558                         bc=file_name_len;
2559                         name = get_unicode_or_ascii_string(tvb, &offset,
2560                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2561                         if(name){
2562                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2563                                         offset, file_name_len, name);
2564                                 proto_item_append_text(item, ": %s", name);
2565
2566                         }
2567                 }
2568
2569                 proto_item_set_len(item, offset-old_offset);
2570
2571                 if (next_offset == 0){
2572                         return;
2573                 }
2574
2575                 offset = old_offset+next_offset;
2576                 if (offset < old_offset) {
2577                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2578                                     "Invalid offset/length. Malformed packet");
2579                         return;
2580                 }
2581         }
2582         return;
2583 }
2584
2585 static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2586 {
2587         int offset = 0;
2588         proto_item *item=NULL;
2589         proto_tree *tree=NULL;
2590         const char *name=NULL;
2591         guint16 bc;
2592
2593         while(tvb_length_remaining(tvb, offset) > 4){
2594                 int old_offset = offset;
2595                 int next_offset;
2596                 int file_name_len;
2597                 int ea_size;
2598                 int short_name_len;
2599
2600                 if(parent_tree){
2601                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, TRUE);
2602                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
2603                 }
2604
2605                 /* next offset */       
2606                 next_offset = tvb_get_letohl(tvb, offset);
2607                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2608                 offset += 4;
2609
2610                 /* file index */
2611                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2612                 offset += 4;
2613
2614                 /* create time */
2615                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2616
2617                 /* last access */
2618                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2619
2620                 /* last write */
2621                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2622
2623                 /* last change */
2624                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2625
2626                 /* end of file */
2627                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2628                 offset += 8;
2629
2630                 /* allocation size */
2631                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2632                 offset += 8;
2633
2634                 /* File Attributes */
2635                 offset = dissect_file_attributes(tvb, tree, offset, 4);
2636
2637                 /* file name length */
2638                 file_name_len=tvb_get_letohl(tvb, offset);
2639                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2640                 offset += 4;
2641
2642                 /* ea size */
2643                 ea_size=tvb_get_letohl(tvb, offset);
2644                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2645                 offset += 4;
2646
2647                 /* short name length */
2648                 short_name_len=tvb_get_guint8(tvb, offset);
2649                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, TRUE);
2650                 offset += 1;
2651
2652                 /* reserved */
2653                 offset += 1;
2654
2655                 /* short name */
2656                 if(short_name_len){
2657                         bc=short_name_len;
2658                         name = get_unicode_or_ascii_string(tvb, &offset,
2659                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
2660                         if(name){
2661                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
2662                                         offset, short_name_len, name);
2663                         }
2664                 }
2665                 offset += 24;
2666
2667                 /* file name */
2668                 if(file_name_len){
2669                         bc=file_name_len;
2670                         name = get_unicode_or_ascii_string(tvb, &offset,
2671                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2672                         if(name){
2673                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2674                                         offset, file_name_len, name);
2675                                 proto_item_append_text(item, ": %s", name);
2676
2677                         }
2678                 }
2679
2680                 proto_item_set_len(item, offset-old_offset);
2681
2682                 if (next_offset == 0){
2683                         return;
2684                 }
2685
2686                 offset = old_offset+next_offset;
2687                 if (offset < old_offset) {
2688                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2689                                     "Invalid offset/length. Malformed packet");
2690                         return;
2691                 }
2692         }
2693         return;
2694 }
2695
2696 static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2697 {
2698         int offset = 0;
2699         proto_item *item=NULL;
2700         proto_tree *tree=NULL;
2701         const char *name=NULL;
2702         guint16 bc;
2703
2704         while(tvb_length_remaining(tvb, offset) > 4){
2705                 int old_offset = offset;
2706                 int next_offset;
2707                 int file_name_len;
2708
2709                 if(parent_tree){
2710                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, TRUE);
2711                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
2712                 }
2713
2714                 /* next offset */       
2715                 next_offset = tvb_get_letohl(tvb, offset);
2716                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2717                 offset += 4;
2718
2719                 /* file index */
2720                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2721                 offset += 4;
2722
2723                 /* file name length */
2724                 file_name_len=tvb_get_letohl(tvb, offset);
2725                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2726                 offset += 4;
2727
2728                 /* file name */
2729                 if(file_name_len){
2730                         bc=file_name_len;
2731                         name = get_unicode_or_ascii_string(tvb, &offset,
2732                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2733                         if(name){
2734                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2735                                         offset, file_name_len, name);
2736                                 proto_item_append_text(item, ": %s", name);
2737
2738                         }
2739                 }
2740
2741                 proto_item_set_len(item, offset-old_offset);
2742
2743                 if (next_offset == 0){
2744                         return;
2745                 }
2746
2747                 offset = old_offset+next_offset;
2748                 if (offset < old_offset) {
2749                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2750                                     "Invalid offset/length. Malformed packet");
2751                         return;
2752                 }
2753         }
2754         return;
2755 }
2756
2757 static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2758 {
2759         int offset = 0;
2760         proto_item *item=NULL;
2761         proto_tree *tree=NULL;
2762         const char *name=NULL;
2763         guint16 bc;
2764
2765         while(tvb_length_remaining(tvb, offset) > 4){
2766                 int old_offset = offset;
2767                 int next_offset;
2768                 int file_name_len;
2769                 int ea_size;
2770                 int short_name_len;
2771
2772                 if(parent_tree){
2773                         item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, TRUE);
2774                         tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
2775                 }
2776
2777                 /* next offset */       
2778                 next_offset = tvb_get_letohl(tvb, offset);
2779                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2780                 offset += 4;
2781
2782                 /* file index */
2783                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2784                 offset += 4;
2785
2786                 /* create time */
2787                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2788
2789                 /* last access */
2790                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2791
2792                 /* last write */
2793                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2794
2795                 /* last change */
2796                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2797
2798                 /* end of file */
2799                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2800                 offset += 8;
2801
2802                 /* allocation size */
2803                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2804                 offset += 8;
2805
2806                 /* File Attributes */
2807                 offset = dissect_file_attributes(tvb, tree, offset, 4);
2808
2809                 /* file name length */
2810                 file_name_len=tvb_get_letohl(tvb, offset);
2811                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2812                 offset += 4;
2813
2814                 /* ea size */
2815                 ea_size=tvb_get_letohl(tvb, offset);
2816                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2817                 offset += 4;
2818
2819                 /* short name length */
2820                 short_name_len=tvb_get_guint8(tvb, offset);
2821                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, TRUE);
2822                 offset += 1;
2823
2824                 /* reserved */
2825                 offset += 1;
2826
2827                 /* short name */
2828                 if(short_name_len){
2829                         bc=short_name_len;
2830                         name = get_unicode_or_ascii_string(tvb, &offset,
2831                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
2832                         if(name){
2833                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
2834                                         offset, short_name_len, name);
2835                         }
2836                 }
2837                 offset += 24;
2838
2839                 /* reserved */
2840                 offset += 2;
2841
2842                 /* file id */
2843                 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, TRUE);
2844                 offset += 8;
2845
2846                 /* file name */
2847                 if(file_name_len){
2848                         bc=file_name_len;
2849                         name = get_unicode_or_ascii_string(tvb, &offset,
2850                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2851                         if(name){
2852                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2853                                         offset, file_name_len, name);
2854                                 proto_item_append_text(item, ": %s", name);
2855
2856                         }
2857                 }
2858
2859                 proto_item_set_len(item, offset-old_offset);
2860
2861                 if (next_offset == 0){
2862                         return;
2863                 }
2864
2865                 offset = old_offset+next_offset;
2866                 if (offset < old_offset) {
2867                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2868                                     "Invalid offset/length. Malformed packet");
2869                         return;
2870                 }
2871         }
2872         return;
2873 }
2874
2875
2876 typedef struct _smb2_find_dissector_t {
2877         guint32 level;
2878         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
2879 } smb2_find_dissector_t;
2880
2881 smb2_find_dissector_t smb2_find_dissectors[] = {
2882         {SMB2_FIND_DIRECTORY_INFO,      dissect_smb2_file_directory_info},
2883         {SMB2_FIND_FULL_DIRECTORY_INFO, dissect_smb2_full_directory_info},
2884         {SMB2_FIND_BOTH_DIRECTORY_INFO, dissect_smb2_both_directory_info},
2885         {SMB2_FIND_NAME_INFO,           dissect_smb2_file_name_info},
2886         {SMB2_FIND_ID_BOTH_DIRECTORY_INFO,dissect_smb2_id_both_directory_info},
2887         {0, NULL}
2888 };
2889
2890 static void
2891 dissect_smb2_find_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
2892 {
2893         smb2_find_dissector_t *dis = smb2_find_dissectors;
2894
2895         while(dis->dissector){
2896                 if(si && si->saved && si->saved){
2897                         if(dis->level ==si->saved->infolevel){
2898                                 dis->dissector(tvb, pinfo, tree, si);
2899                                 return;
2900                         }
2901                 }
2902                 dis++;
2903         }
2904
2905         proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), FALSE);
2906         return;
2907 }
2908
2909 static int
2910 dissect_smb2_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2911 {
2912         offset_length_buffer_t olb;
2913         proto_item *item=NULL;
2914
2915         if(si->saved){
2916                 /* infolevel */
2917                 item=proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 0, si->saved->infolevel);
2918                 PROTO_ITEM_SET_GENERATED(item);
2919         }
2920
2921         if(!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type==SMB2_EI_FINDPATTERN) {
2922                 if (check_col(pinfo->cinfo, COL_INFO)){
2923                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
2924                                 val_to_str(si->saved->infolevel, smb2_find_info_levels, "(Level:0x%02x)"),
2925                                 (const char *)si->saved->extra_info);
2926                 }
2927
2928                 g_free(si->saved->extra_info);
2929                 si->saved->extra_info_type=SMB2_EI_NONE;
2930                 si->saved->extra_info=NULL;
2931         }
2932         
2933         switch (si->status) {
2934         case 0x00000000: break;
2935         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2936         }
2937
2938         /* buffer code */
2939         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2940
2941         /* findinfo offset */
2942         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_find_info_blob);
2943
2944         /* the buffer */
2945         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_find_data);
2946
2947         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2948
2949         return offset;
2950 }
2951
2952 static int
2953 dissect_smb2_negotiate_protocol_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2954 {
2955         guint16 dc;
2956
2957         /* buffer code */
2958         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2959
2960         /* dialect count */
2961         dc = tvb_get_letohs(tvb, offset);
2962         proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, TRUE);
2963         offset += 2;
2964
2965         /* security mode, skip second byte */
2966         offset = dissect_smb2_secmode(tree, tvb, offset);
2967         offset++;
2968
2969
2970         /* reserved */
2971         offset += 2;
2972
2973         /* capabilities */
2974         offset = dissect_smb2_capabilities(tree, tvb, offset);
2975
2976         /* client guid */
2977         proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, TRUE);
2978         offset += 16;
2979
2980         /* client boot time */
2981         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
2982         offset += 8;
2983
2984         for(;dc>0;dc--){
2985                 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, TRUE);
2986                 offset += 2;
2987         }
2988
2989         return offset;
2990 }
2991
2992 static int
2993 dissect_smb2_negotiate_protocol_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2994 {
2995         offset_length_buffer_t s_olb;
2996
2997         switch (si->status) {
2998         case 0x00000000: break;
2999         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3000         }
3001
3002         /* buffer code */
3003         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3004
3005         /* security mode, skip second byte */
3006         offset = dissect_smb2_secmode(tree, tvb, offset);
3007         offset++;
3008
3009         /* dialect picked */
3010         proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, TRUE);
3011         offset += 2;
3012
3013         /* reserved */
3014         offset += 2;
3015
3016         /* server GUID */
3017         proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, TRUE);
3018         offset += 16;
3019
3020         /* capabilities */
3021         offset = dissect_smb2_capabilities(tree, tvb, offset);
3022
3023         /* max trans size */
3024         proto_tree_add_item(tree, hf_smb2_max_trans_size, tvb, offset, 4, TRUE);
3025         offset += 4;
3026
3027         /* max read size */
3028         proto_tree_add_item(tree, hf_smb2_max_read_size, tvb, offset, 4, TRUE);
3029         offset += 4;
3030
3031         /* max write size */
3032         proto_tree_add_item(tree, hf_smb2_max_write_size, tvb, offset, 4, TRUE);
3033         offset += 4;
3034
3035         /* current time */
3036         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_current_time);
3037         offset += 8;
3038
3039         /* boot time */
3040         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
3041         offset += 8;
3042
3043         /* security blob offset/length */
3044         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3045
3046         /* the security blob itself */
3047         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3048
3049         /* reserved */
3050         offset += 4;
3051
3052         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3053
3054         return offset;
3055 }
3056
3057 static void
3058 dissect_smb2_getinfo_parameters(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
3059 {
3060         switch(si->saved->class){
3061         case SMB2_CLASS_FILE_INFO:
3062                 switch(si->saved->infolevel){
3063                 default:
3064                         /* we dont handle this infolevel yet */
3065                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3066                         offset += tvb_length_remaining(tvb, offset);
3067                 }
3068                 break;
3069         case SMB2_CLASS_FS_INFO:
3070                 switch(si->saved->infolevel){
3071                 default:
3072                         /* we dont handle this infolevel yet */
3073                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3074                         offset += tvb_length_remaining(tvb, offset);
3075                 }
3076                 break;
3077         case SMB2_CLASS_SEC_INFO:
3078                 switch(si->saved->infolevel){
3079                 case SMB2_SEC_INFO_00:
3080                         dissect_security_information_mask(tvb, tree, offset+8);
3081                         break;
3082                 default:
3083                         /* we dont handle this infolevel yet */
3084                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3085                         offset += tvb_length_remaining(tvb, offset);
3086                 }
3087                 break;
3088         default:
3089                 /* we dont handle this class yet */
3090                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3091         }
3092 }
3093
3094
3095 static int
3096 dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
3097 {
3098         char cl, il;
3099         proto_item *item;
3100         int hfindex;
3101         static const value_string dummy_value_string[] = {
3102                 { 0, NULL }
3103         };
3104         const value_string *vs;
3105
3106         if(si->flags & SMB2_FLAGS_RESPONSE){
3107                 if(!si->saved){
3108                         return offset;
3109                 }
3110                 cl=si->saved->class;
3111                 il=si->saved->infolevel;
3112         } else {
3113                 cl=tvb_get_guint8(tvb, offset);
3114                 il=tvb_get_guint8(tvb, offset+1);
3115                 if(si->saved){
3116                         si->saved->class=cl;
3117                         si->saved->infolevel=il;
3118                 }
3119         }
3120
3121
3122         switch(cl){
3123         case SMB2_CLASS_FILE_INFO:
3124                 hfindex=hf_smb2_infolevel_file_info;
3125                 vs=smb2_file_info_levels;
3126                 break;
3127         case SMB2_CLASS_FS_INFO:
3128                 hfindex=hf_smb2_infolevel_fs_info;
3129                 vs=smb2_fs_info_levels;
3130                 break;
3131         case SMB2_CLASS_SEC_INFO:
3132                 hfindex=hf_smb2_infolevel_sec_info;
3133                 vs=smb2_sec_info_levels;
3134                 break;
3135         default:
3136                 hfindex=hf_smb2_infolevel;
3137                 vs=dummy_value_string;
3138         }
3139
3140
3141         /* class */
3142         item=proto_tree_add_uint(tree, hf_smb2_class, tvb, offset, 1, cl);
3143         if(si->flags & SMB2_FLAGS_RESPONSE){
3144                 PROTO_ITEM_SET_GENERATED(item);
3145         }
3146         /* infolevel */
3147         item=proto_tree_add_uint(tree, hfindex, tvb, offset+1, 1, il);
3148         if(si->flags & SMB2_FLAGS_RESPONSE){
3149                 PROTO_ITEM_SET_GENERATED(item);
3150         }
3151         offset += 2;
3152
3153         if(!(si->flags & SMB2_FLAGS_RESPONSE)){
3154                 /* Only update COL_INFO for requests. It clutters the
3155                  * display ab bit too much if we do it for replies
3156                  * as well.
3157                  */
3158                 if (check_col(pinfo->cinfo, COL_INFO)){
3159                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s/%s",
3160                                 val_to_str(cl, smb2_class_vals, "(Class:0x%02x)"),
3161                                 val_to_str(il, vs, "(Level:0x%02x)"));
3162                 }
3163         }
3164
3165         return offset;
3166 }
3167
3168 static int
3169 dissect_smb2_getinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3170 {
3171         /* buffer code */
3172         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3173
3174         /* class and info level */
3175         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3176
3177         /* max response size */
3178         proto_tree_add_item(tree, hf_smb2_max_response_size, tvb, offset, 4, TRUE);
3179         offset += 4;
3180
3181         /* parameters */
3182         if(si->saved){
3183                 dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
3184         } else {
3185                 /* some unknown bytes */
3186                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3187         }
3188         offset += 16;
3189
3190         /* fid */
3191         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3192
3193         return offset;
3194 }
3195
3196 static void
3197 dissect_smb2_infolevel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si, guint8 class, guint8 infolevel)
3198 {
3199         int old_offset = offset;
3200
3201         switch(class){
3202         case SMB2_CLASS_FILE_INFO:
3203                 switch(infolevel){
3204                 case SMB2_FILE_BASIC_INFO:
3205                         dissect_smb2_file_basic_info(tvb, pinfo, tree, offset, si);
3206                         break;
3207                 case SMB2_FILE_STANDARD_INFO:
3208                         dissect_smb2_file_standard_info(tvb, pinfo, tree, offset, si);
3209                         break;
3210                 case SMB2_FILE_INTERNAL_INFO:
3211                         dissect_smb2_file_internal_info(tvb, pinfo, tree, offset, si);
3212                         break;
3213                 case SMB2_FILE_EA_INFO:
3214                         dissect_smb2_file_ea_info(tvb, pinfo, tree, offset, si);
3215                         break;
3216                 case SMB2_FILE_ACCESS_INFO:
3217                         dissect_smb2_file_access_info(tvb, pinfo, tree, offset, si);
3218                         break;
3219                 case SMB2_FILE_RENAME_INFO:
3220                         dissect_smb2_file_rename_info(tvb, pinfo, tree, offset, si);
3221                         break;
3222                 case SMB2_FILE_DISPOSITION_INFO:
3223                         dissect_smb2_file_disposition_info(tvb, pinfo, tree, offset, si);
3224                         break;
3225                 case SMB2_FILE_POSITION_INFO:
3226                         dissect_smb2_file_position_info(tvb, pinfo, tree, offset, si);
3227                         break;
3228                 case SMB2_FILE_INFO_0f:
3229                         dissect_smb2_file_info_0f(tvb, pinfo, tree, offset, si);
3230                         break;
3231                 case SMB2_FILE_MODE_INFO:
3232                         dissect_smb2_file_mode_info(tvb, pinfo, tree, offset, si);
3233                         break;
3234                 case SMB2_FILE_ALIGNMENT_INFO:
3235                         dissect_smb2_file_alignment_info(tvb, pinfo, tree, offset, si);
3236                         break;
3237                 case SMB2_FILE_ALL_INFO:
3238                         dissect_smb2_file_all_info(tvb, pinfo, tree, offset, si);
3239                         break;
3240                 case SMB2_FILE_ALLOCATION_INFO:
3241                         dissect_smb2_file_allocation_info(tvb, pinfo, tree, offset, si);
3242                         break;
3243                 case SMB2_FILE_ENDOFFILE_INFO:
3244                         dissect_smb2_file_endoffile_info(tvb, pinfo, tree, offset, si);
3245                         break;
3246                 case SMB2_FILE_ALTERNATE_NAME_INFO:
3247                         dissect_smb2_file_alternate_name_info(tvb, pinfo, tree, offset, si);
3248                         break;
3249                 case SMB2_FILE_STREAM_INFO:
3250                         dissect_smb2_file_stream_info(tvb, pinfo, tree, offset, si);
3251                         break;
3252                 case SMB2_FILE_PIPE_INFO:
3253                         dissect_smb2_file_pipe_info(tvb, pinfo, tree, offset, si);
3254                         break;
3255                 case SMB2_FILE_COMPRESSION_INFO:
3256                         dissect_smb2_file_compression_info(tvb, pinfo, tree, offset, si);
3257                         break;
3258                 case SMB2_FILE_NETWORK_OPEN_INFO:
3259                         dissect_smb2_file_network_open_info(tvb, pinfo, tree, offset, si);
3260                         break;
3261                 case SMB2_FILE_ATTRIBUTE_TAG_INFO:
3262                         dissect_smb2_file_attribute_tag_info(tvb, pinfo, tree, offset, si);
3263                         break;
3264                 default:
3265                         /* we dont handle this infolevel yet */
3266                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
3267                         offset += tvb_length_remaining(tvb, offset);
3268                 }
3269                 break;
3270         case SMB2_CLASS_FS_INFO:
3271                 switch(infolevel){
3272                 case SMB2_FS_INFO_01:
3273                         dissect_smb2_fs_info_01(tvb, pinfo, tree, offset, si);
3274                         break;
3275                 case SMB2_FS_INFO_03:
3276                         dissect_smb2_fs_info_03(tvb, pinfo, tree, offset, si);
3277                         break;
3278                 case SMB2_FS_INFO_04:
3279                         dissect_smb2_fs_info_04(tvb, pinfo, tree, offset, si);
3280                         break;
3281                 case SMB2_FS_INFO_05:
3282                         dissect_smb2_fs_info_05(tvb, pinfo, tree, offset, si);
3283                         break;
3284                 case SMB2_FS_INFO_06:
3285                         dissect_smb2_fs_info_06(tvb, pinfo, tree, offset, si);
3286                         break;
3287                 case SMB2_FS_INFO_07:
3288                         dissect_smb2_fs_info_07(tvb, pinfo, tree, offset, si);
3289                         break;
3290                 case SMB2_FS_OBJECTID_INFO:
3291                         dissect_smb2_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, si);
3292                         break;
3293                 default:
3294                         /* we dont handle this infolevel yet */
3295                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
3296                         offset += tvb_length_remaining(tvb, offset);
3297                 }
3298                 break;
3299         case SMB2_CLASS_SEC_INFO:
3300                 switch(infolevel){
3301                 case SMB2_SEC_INFO_00:
3302                         dissect_smb2_sec_info_00(tvb, pinfo, tree, offset, si);
3303                         break;
3304                 default:
3305                         /* we dont handle this infolevel yet */
3306                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
3307                         offset += tvb_length_remaining(tvb, offset);
3308                 }
3309                 break;
3310         default:
3311                 /* we dont handle this class yet */
3312                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
3313         }
3314
3315         /* if we get BUFFER_OVERFLOW there will be truncated data */
3316         if (si->status == 0x80000005) {
3317                 proto_item *item;
3318                 item=proto_tree_add_text(tree, tvb, old_offset, 0, "Truncated...");
3319                 PROTO_ITEM_SET_GENERATED(item);
3320         }
3321 }
3322
3323 static void
3324 dissect_smb2_getinfo_response_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
3325 {
3326         /* data */
3327         if(si->saved){
3328                 dissect_smb2_infolevel(tvb, pinfo, tree, 0, si, si->saved->class, si->saved->infolevel);
3329         } else {
3330                 /* some unknown bytes */
3331                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), FALSE);
3332         }
3333
3334         return;
3335 }
3336
3337
3338 static int
3339 dissect_smb2_getinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3340 {
3341         offset_length_buffer_t olb;
3342
3343         /* class/infolevel */
3344         dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3345
3346         switch (si->status) {
3347         case 0x00000000: break;
3348         /* if we get BUFFER_OVERFLOW there will be truncated data */
3349         case 0x80000005: break;
3350         /* if we get BUFFER_TOO_SMALL there will not be any data there, only
3351          * a guin32 specifying how big the buffer needs to be
3352          */
3353         case 0xc0000023:
3354                 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3355                 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
3356                 proto_tree_add_item(tree, hf_smb2_required_buffer_size, tvb, offset, 4, TRUE);
3357                 offset += 4;
3358
3359                 return offset;
3360         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3361         }
3362
3363
3364         /* buffer code */
3365         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3366          /* response buffer offset  and size */
3367         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
3368
3369         /* response data*/
3370         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_getinfo_response_data);
3371
3372         return offset;
3373 }
3374
3375 static int
3376 dissect_smb2_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3377 {
3378         proto_tree *flags_tree = NULL;
3379         proto_item *flags_item = NULL;
3380
3381         /* buffer code */
3382         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3383
3384         /* close flags */
3385         if (tree) {
3386                 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, TRUE);
3387                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
3388         }
3389         proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, TRUE);
3390         offset += 2;
3391
3392         /* padding */
3393         offset += 4;
3394
3395         /* fid */
3396         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_CLOSE);
3397
3398         return offset;
3399 }
3400
3401 static int
3402 dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3403 {
3404         proto_tree *flags_tree = NULL;
3405         proto_item *flags_item = NULL;
3406
3407         switch (si->status) {
3408         case 0x00000000: break;
3409         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3410         }
3411
3412         /* buffer code */
3413         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3414
3415         /* close flags */
3416         if (tree) {
3417                 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, TRUE);
3418                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
3419         }
3420         offset += 2;
3421
3422         /* reserved */
3423         offset += 4;
3424
3425         /* create time */
3426         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3427
3428         /* last access */
3429         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3430
3431         /* last write */
3432         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3433
3434         /* last change */
3435         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3436
3437         /* allocation size */
3438         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
3439         offset += 8;
3440
3441         /* end of file */
3442         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
3443         offset += 8;
3444
3445         /* File Attributes */
3446         offset = dissect_file_attributes(tvb, tree, offset, 4);
3447
3448         return offset;
3449 }
3450
3451 static int
3452 dissect_smb2_flush_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3453 {
3454         /* buffer code */
3455         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3456
3457         /* some unknown bytes */
3458         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, TRUE);
3459         offset += 6;
3460
3461         /* fid */
3462         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3463
3464         return offset;
3465 }
3466
3467 static int
3468 dissect_smb2_flush_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3469 {
3470         switch (si->status) {
3471         case 0x00000000: break;
3472         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3473         }
3474
3475         /* buffer code */
3476         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3477
3478         /* some unknown bytes */
3479         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
3480         offset += 2;
3481
3482         return offset;
3483 }
3484
3485
3486 static int
3487 dissect_smb2_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3488 {
3489         guint16 lock_count;
3490
3491         /* buffer code */
3492         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3493
3494         /* lock count */
3495         lock_count = tvb_get_letohs(tvb, offset);
3496         proto_tree_add_item(tree, hf_smb2_lock_count, tvb, offset, 2, TRUE);
3497         offset += 2;
3498
3499         /* reserved */
3500         offset += 4;
3501
3502         /* fid */
3503         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3504
3505         while (lock_count--) {
3506                 proto_item *lock_item=NULL;
3507                 proto_tree *lock_tree=NULL;
3508                 static const int *lf_fields[] = {       
3509                         &hf_smb2_lock_flags_shared,
3510                         &hf_smb2_lock_flags_exclusive,
3511                         &hf_smb2_lock_flags_unlock,
3512                         &hf_smb2_lock_flags_fail_immediately,
3513                         NULL
3514                 };
3515
3516                 if(tree){
3517                         lock_item = proto_tree_add_item(tree, hf_smb2_lock_info, tvb, offset, 24, TRUE);
3518                         lock_tree = proto_item_add_subtree(lock_item, ett_smb2_lock_info);
3519                 }
3520
3521                 /* offset */
3522                 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, TRUE);
3523                 offset += 8;
3524
3525                 /* count */
3526                 proto_tree_add_item(lock_tree, hf_smb2_lock_length, tvb, offset, 8, TRUE);
3527                 offset += 8;
3528
3529                 /* flags */
3530                 proto_tree_add_bitmask(lock_tree, tvb, offset, hf_smb2_lock_flags, ett_smb2_lock_flags, lf_fields, TRUE);
3531                 offset += 4;
3532
3533                 /* reserved */
3534                 offset += 4;
3535         }
3536
3537         return offset;
3538 }
3539
3540 static int
3541 dissect_smb2_lock_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3542 {
3543         switch (si->status) {
3544         case 0x00000000: break;
3545         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3546         }
3547
3548         /* buffer code */
3549         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3550
3551         /* some unknown bytes */
3552         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
3553         offset += 2;
3554
3555         return offset;
3556 }
3557 static int
3558 dissect_smb2_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3559 {
3560         /* buffer code */
3561         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3562
3563         /* some unknown bytes */
3564         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
3565         offset += 2;
3566
3567         return offset;
3568 }
3569
3570
3571 static int
3572 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, guint32 datalen, proto_tree *top_tree)
3573 {
3574         int tvblen;
3575         int result;
3576
3577         tvbuff_t *dcerpc_tvb;
3578         tvblen = tvb_length_remaining(tvb, offset);
3579         dcerpc_tvb = tvb_new_subset(tvb, offset, MIN((int)datalen, tvb_length_remaining(tvb, offset)), datalen);
3580
3581         /* dissect the full PDU */
3582         result = dissector_try_heuristic(smb2_heur_subdissector_list, dcerpc_tvb, pinfo, top_tree);
3583
3584
3585         offset += datalen;
3586
3587         return offset;
3588 }
3589
3590
3591 static int
3592 dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3593 {
3594         guint32 length;
3595         guint64 off;
3596
3597         /* buffer code */
3598         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3599
3600         /* data offset */
3601         proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, TRUE);
3602         offset += 2;
3603
3604         /* length */
3605         length=tvb_get_letohl(tvb, offset);
3606         proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, TRUE);
3607         offset += 4;
3608
3609         /* offset */
3610         off=tvb_get_letoh64(tvb, offset);
3611         proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, TRUE);
3612         offset += 8;
3613
3614         if (check_col(pinfo->cinfo, COL_INFO)){
3615                 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", length, off);
3616         }
3617
3618         /* fid */
3619         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3620
3621         /* some unknown bytes */
3622         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3623         offset += 16;
3624
3625
3626         /* data or dcerpc ?*/
3627         if(length && si->tree && si->tree->share_type == SMB2_SHARE_TYPE_IPC){
3628                 offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si->top_tree);
3629                 return offset;
3630         }
3631
3632         /* just ordinary data */
3633         proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, TRUE);
3634         offset += MIN(length,(guint32)tvb_length_remaining(tvb, offset));
3635
3636         return offset;
3637 }
3638
3639
3640 static int
3641 dissect_smb2_write_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3642 {
3643         switch (si->status) {
3644         case 0x00000000: break;
3645         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3646         }
3647
3648         /* buffer code */
3649         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3650         /* some unknown bytes */
3651         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
3652         offset += 2;
3653
3654         /* length */
3655         proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, TRUE);
3656         offset += 4;
3657
3658         /* some unknown bytes */
3659         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 9, TRUE);
3660         offset += 9;
3661
3662         return offset;
3663 }
3664
3665 static void
3666 dissect_smb2_IOCTL_DO_DCERPC(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *top_tree, gboolean data_in _U_)
3667 {
3668         dissect_file_data_dcerpc(tvb, pinfo, tree, offset, tvb_length_remaining(tvb, offset), top_tree);
3669
3670         return;
3671 }
3672
3673 static void
3674 dissect_smb2_FSCTL_GET_SHADOW_COPY_DATA(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
3675 {
3676         guint32 num_volumes, num_labels;
3677
3678         /* There is no in data */
3679         if(data_in){
3680                 return;
3681         }
3682
3683         /* num volumes */
3684         num_volumes=tvb_get_letohl(tvb, offset);
3685         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_volumes, tvb, offset, 4, TRUE);
3686         offset += 4;
3687
3688         /* num labels */
3689         num_labels=tvb_get_letohl(tvb, offset);
3690         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_labels, tvb, offset, 4, TRUE);
3691         offset += 4;
3692
3693         /* count */
3694         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_count, tvb, offset, 4, TRUE);
3695         offset += 4;
3696
3697         while(num_volumes--){
3698                 const char *name;
3699                 guint16 bc;
3700                 int len=0;
3701                 int old_offset=offset;
3702
3703                 bc=tvb_length_remaining(tvb, offset);
3704                 name = get_unicode_or_ascii_string(tvb, &offset,
3705                         TRUE, &len, TRUE, FALSE, &bc);
3706                 proto_tree_add_string(tree, hf_smb2_ioctl_shadow_copy_label, tvb, old_offset, len, name);
3707
3708                 offset = old_offset+len;
3709
3710                 if(!len){
3711                         break;
3712                 }
3713         }
3714
3715         return;
3716 }
3717
3718 int
3719 dissect_smb2_FILE_OBJECTID_BUFFER(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
3720 {
3721         proto_item *item=NULL;
3722         proto_tree *tree=NULL;
3723
3724         /* FILE_OBJECTID_BUFFER */
3725         if(parent_tree){
3726                 item = proto_tree_add_item(parent_tree, hf_smb2_FILE_OBJECTID_BUFFER, tvb, offset, 64, TRUE);
3727                 tree = proto_item_add_subtree(item, ett_smb2_FILE_OBJECTID_BUFFER);
3728         }
3729
3730         /* Object ID */
3731         proto_tree_add_item(tree, hf_smb2_object_id, tvb, offset, 16, TRUE);
3732         offset += 16;
3733
3734         /* Birth Volume ID */
3735         proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, TRUE);
3736         offset += 16;
3737
3738         /* Birth Object ID */
3739         proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, TRUE);
3740         offset += 16;
3741
3742         /* Domain ID */
3743         proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, TRUE);
3744         offset += 16;
3745
3746         return offset;
3747 }
3748
3749 static void
3750 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
3751 {
3752
3753         /* There is no in data */
3754         if(data_in){
3755                 return;
3756         }
3757
3758         /* FILE_OBJECTID_BUFFER */
3759         offset=dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
3760
3761         return;
3762 }
3763
3764 static void
3765 dissect_smb2_FSCTL_GET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
3766 {
3767
3768         /* There is no in data */
3769         if(data_in){
3770                 return;
3771         }
3772
3773         /* compression format */
3774         proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, TRUE);
3775         offset += 2;
3776
3777         return;
3778 }
3779 static void
3780 dissect_smb2_FSCTL_SET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
3781 {
3782
3783         /* There is no out data */
3784         if(!data_in){
3785                 return;
3786         }
3787
3788         /* compression format */
3789         proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, TRUE);
3790         offset += 2;
3791
3792         return;
3793 }
3794
3795 static void
3796 dissect_smb2_FSCTL_SET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
3797 {
3798
3799         /* There is no out data */
3800         if(!data_in){
3801                 return;
3802         }
3803
3804         /* FILE_OBJECTID_BUFFER */
3805         offset=dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
3806
3807         return;
3808 }
3809
3810 static void
3811 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
3812 {
3813
3814         /* There is no out data */
3815         if(!data_in){
3816                 return;
3817         }
3818
3819         /* FILE_OBJECTID_BUFFER->ExtendedInfo */
3820
3821         /* Birth Volume ID */
3822         proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, TRUE);
3823         offset += 16;
3824
3825         /* Birth Object ID */
3826         proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, TRUE);
3827         offset += 16;
3828
3829         /* Domain ID */
3830         proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, TRUE);
3831         offset += 16;
3832
3833         return;
3834 }
3835
3836 void
3837 dissect_smb2_ioctl_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *top_tree, guint32 ioctl_function, gboolean data_in)
3838 {
3839         switch(ioctl_function){
3840         case 0x0011c017:
3841                 dissect_smb2_IOCTL_DO_DCERPC(tvb, pinfo, tree, 0, top_tree, data_in);
3842                 break;
3843         case 0x00144064: /* FSCTL_GET_SHADOW_COPY_DATA */
3844                 dissect_smb2_FSCTL_GET_SHADOW_COPY_DATA(tvb, pinfo, tree, 0, data_in);
3845                 break;
3846         case 0x0009009C: /* FSCTL_GET_OBJECT_ID */
3847         case 0x000900c0: /* FSCTL_CREATE_OR_GET_OBJECT_ID */
3848                 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
3849                 break;
3850         case 0x00098098: /* FSCTL_SET_OBJECT_ID */
3851                 dissect_smb2_FSCTL_SET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
3852                 break;
3853         case 0x000980BC: /* FSCTL_SET_OBJECT_ID_EXTENDED */
3854                 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvb, pinfo, tree, 0, data_in);
3855                 break;
3856         case 0x0009003C: /* FSCTL_GET_COMPRESSION */
3857                 dissect_smb2_FSCTL_GET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
3858                 break;
3859         case 0x0009C040: /* FSCTL_SET_COMPRESSION */
3860                 dissect_smb2_FSCTL_SET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
3861                 break;
3862         default:
3863                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), TRUE);
3864         }
3865
3866         return;
3867 }
3868
3869 static void
3870 dissect_smb2_ioctl_data_in(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
3871 {
3872         dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, TRUE);
3873 }
3874
3875 static void
3876 dissect_smb2_ioctl_data_out(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
3877 {
3878         dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, FALSE);
3879 }
3880
3881 static int
3882 dissect_smb2_ioctl_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3883 {
3884         offset_length_buffer_t o_olb;
3885         offset_length_buffer_t i_olb;
3886         proto_tree *flags_tree = NULL;
3887         proto_item *flags_item = NULL;
3888
3889         /* buffer code */
3890         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3891
3892         /* reserved */
3893         offset += 2;
3894
3895         /* ioctl function */
3896         offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
3897
3898         /* fid */
3899         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3900
3901         /* in buffer offset/length */
3902         offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
3903
3904         /* max ioctl in size */
3905         proto_tree_add_item(tree, hf_smb2_max_ioctl_in_size, tvb, offset, 4, TRUE);
3906         offset += 4;
3907
3908         /* out buffer offset/length */
3909         offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
3910
3911         /* max ioctl out size */
3912         proto_tree_add_item(tree, hf_smb2_max_ioctl_out_size, tvb, offset, 4, TRUE);
3913         offset += 4;
3914
3915         /* flags */
3916         if(tree){
3917                 flags_item = proto_tree_add_item(tree, hf_smb2_ioctl_flags, tvb, offset, 4, TRUE);
3918                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_ioctl_flags);
3919         }
3920         proto_tree_add_item(flags_tree, hf_smb2_ioctl_is_fsctl, tvb, offset, 4, TRUE);
3921         offset += 4;
3922
3923         /* reserved */
3924         offset += 4;
3925
3926         /* try to decode these blobs in the order they were encoded
3927          * so that for "short" packets we will dissect as much as possible
3928          * before aborting with "short packet"
3929          */
3930         if(i_olb.off>o_olb.off){
3931                 /* out buffer */
3932                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
3933                 /* in buffer */
3934                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
3935         } else {
3936                 /* in buffer */
3937                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
3938                 /* out buffer */
3939                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
3940         }
3941
3942         offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
3943         offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
3944
3945         return offset;
3946 }
3947
3948 static int
3949 dissect_smb2_ioctl_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3950 {
3951         offset_length_buffer_t o_olb;
3952         offset_length_buffer_t i_olb;
3953         proto_tree *flags_tree = NULL;
3954         proto_item *flags_item = NULL;
3955
3956         switch (si->status) {
3957         case 0x00000000: break;
3958         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3959         }
3960
3961         /* buffer code */
3962         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3963
3964         /* some unknown bytes */
3965         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
3966         offset += 2;
3967
3968         /* ioctl function */
3969         offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
3970
3971         /* fid */
3972         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3973
3974         /* in buffer offset/length */
3975         offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
3976
3977         /* out buffer offset/length */
3978         offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
3979
3980
3981         /* flags */
3982         if(tree){
3983                 flags_item = proto_tree_add_item(tree, hf_smb2_ioctl_flags, tvb, offset, 4, TRUE);
3984                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_ioctl_flags);
3985         }
3986         offset += 4;
3987
3988         /* reserved */
3989         offset += 4;
3990
3991         /* try to decode these blobs in the order they were encoded
3992          * so that for "short" packets we will dissect as much as possible
3993          * before aborting with "short packet"
3994          */
3995         if(i_olb.off>o_olb.off){
3996                 /* out buffer */
3997                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
3998                 /* in buffer */
3999                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
4000         } else {
4001                 /* in buffer */
4002                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
4003                 /* out buffer */
4004                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
4005         }
4006
4007         offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
4008         offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
4009
4010         return offset;
4011 }
4012
4013
4014 static int
4015 dissect_smb2_read_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4016 {
4017         guint32 len;
4018         guint64 off;
4019
4020         /* buffer code */
4021         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4022
4023         /* padding and reserved */
4024         offset += 2;
4025
4026         /* length */
4027         len=tvb_get_letohl(tvb, offset);
4028         proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, TRUE);
4029         offset += 4;
4030
4031         /* offset */
4032         off=tvb_get_letoh64(tvb, offset);
4033         proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, TRUE);
4034         offset += 8;
4035
4036         if (check_col(pinfo->cinfo, COL_INFO)){
4037                 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", len, off);
4038         }
4039
4040         /* fid */
4041         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4042
4043         /* minimum count */
4044         proto_tree_add_item(tree, hf_smb2_min_count, tvb, offset, 4, TRUE);
4045
4046         /* channel */
4047         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, TRUE);
4048         offset += 4;
4049
4050         /* remaining bytes */
4051         proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, TRUE);
4052         offset += 4;
4053
4054         /* channel info offset */
4055         proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, TRUE);
4056         offset += 2;
4057
4058         /* channel info length */
4059         proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, TRUE);
4060         offset += 2;
4061
4062         /* there is a buffer here   but it is never used (yet) */
4063
4064         return offset;
4065 }
4066
4067
4068 static int
4069 dissect_smb2_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
4070 {
4071         guint32 length;
4072
4073         switch (si->status) {
4074         case 0x00000000: break;
4075         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
4076         }
4077
4078         /* buffer code */
4079         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4080
4081         /* data offset */
4082         proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, TRUE);
4083         offset += 2;
4084
4085         /* length  might even be 64bits if they are ambitious*/
4086         length=tvb_get_letohl(tvb, offset);
4087         proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, TRUE);
4088         offset += 4;
4089
4090         /* remaining */
4091         proto_tree_add_item(tree, hf_smb2_read_remaining, tvb, offset, 4, TRUE);
4092         offset += 4;
4093
4094         /* reserved */
4095         offset += 4;
4096
4097         /* data or dcerpc ?
4098          * If the pidvalid flag is set we assume it is a deferred
4099          * STATUS_PENDING read and thus a named pipe (==dcerpc)
4100          */
4101         if(length && ( (si->tree && si->tree->share_type == SMB2_SHARE_TYPE_IPC)||(si->flags & SMB2_FLAGS_ASYNC_CMD))){
4102                 offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si->top_tree);
4103                 return offset;
4104         }
4105
4106         /* data */
4107         proto_tree_add_item(tree, hf_smb2_read_data, tvb, offset, length, TRUE);
4108         offset += MIN(length,(guint32)tvb_length_remaining(tvb, offset));
4109
4110         return offset;
4111 }
4112
4113 static void
4114 dissect_smb2_ExtA_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4115 {
4116         proto_item *item=NULL;
4117         if (tree) {
4118                 item = proto_tree_get_parent(tree);
4119                 proto_item_append_text(item, ": SMB2_FILE_INFO_0f");
4120         }
4121         dissect_smb2_file_info_0f(tvb, pinfo, tree, 0, si);
4122         return;
4123 }
4124
4125 static void
4126 dissect_smb2_TWrp_buffer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
4127 {
4128         proto_item *item=NULL;
4129         if (tree) {
4130                 item = proto_tree_get_parent(tree);
4131                 proto_item_append_text(item, ": Timestamp");
4132         }
4133         dissect_nt_64bit_time(tvb, tree, 0, hf_smb2_unknown_timestamp);
4134
4135         return;
4136 }
4137
4138
4139 static void
4140 dissect_smb2_AlSi_buffer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
4141 {
4142         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, 0, 8, TRUE);
4143 }
4144
4145 static void
4146 dissect_smb2_DHnQ_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4147 {
4148         dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNQ);
4149 }
4150
4151 static void
4152 dissect_smb2_DHnC_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4153 {
4154         dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNC);
4155 }
4156
4157 static void
4158 dissect_smb2_MxAc_buffer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
4159 {
4160         int offset=0;
4161         proto_item *item=NULL;
4162         proto_item *sub_item=NULL;
4163         proto_tree *sub_tree=NULL;
4164
4165         if (tree) {
4166                 item = proto_tree_get_parent(tree);
4167         }
4168
4169         if (tvb_length(tvb) == 0) {
4170                 if (item) {
4171                         proto_item_append_text(item, ": NO DATA");
4172                 }
4173                 return;
4174         }
4175
4176         if (item) {
4177                 proto_item_append_text(item, ": MxAc INFO");
4178                 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "MxAc INFO");
4179                 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_MxAc_buffer);
4180         }
4181
4182         proto_tree_add_item(sub_tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
4183         offset += 4;
4184
4185         offset = dissect_smb_access_mask(tvb, sub_tree, offset);
4186
4187         return;
4188 }
4189
4190 static void
4191 dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si)
4192 {
4193         offset_length_buffer_t tag_olb;
4194         offset_length_buffer_t data_olb;
4195         const char *tag;
4196         guint16 chain_offset;
4197         int offset=0;
4198         int len=-1;
4199         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
4200         proto_item *sub_item=NULL;
4201         proto_tree *sub_tree=NULL;
4202         proto_item *parent_item=NULL;
4203
4204         chain_offset=tvb_get_letohl(tvb, offset);
4205         if (chain_offset) {
4206                 len = chain_offset;
4207         }
4208
4209         if(parent_tree){
4210                 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "Chain Element");
4211                 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_create_chain_element);
4212                 parent_item = proto_tree_get_parent(parent_tree);
4213         }
4214
4215         /* chain offset */
4216         proto_tree_add_item(sub_tree, hf_smb2_create_chain_offset, tvb, offset, 4, TRUE);
4217         offset += 4;
4218
4219         /* tag  offset/length */
4220         offset = dissect_smb2_olb_length_offset(tvb, offset, &tag_olb, OLB_O_UINT16_S_UINT32, hf_smb2_tag);
4221
4222         /* data  offset/length */
4223         offset = dissect_smb2_olb_length_offset(tvb, offset, &data_olb, OLB_O_UINT16_S_UINT32, hf_smb2_create_chain_data);
4224
4225         /* tag string */
4226         tag = dissect_smb2_olb_string(pinfo, sub_tree, tvb, &tag_olb, OLB_TYPE_ASCII_STRING);
4227
4228         proto_item_append_text(parent_item, " %s", tag);
4229         proto_item_append_text(sub_item, ": %s", tag);
4230
4231         /* data */
4232         dissector = NULL;
4233         if(!strcmp(tag, "ExtA")){
4234                 dissector = dissect_smb2_ExtA_buffer;
4235         } else if(!strcmp(tag, "AlSi")){
4236                 dissector = dissect_smb2_AlSi_buffer;
4237         } else if(!strcmp(tag, "MxAc")){
4238                 dissector = dissect_smb2_MxAc_buffer;
4239         } else if(!strcmp(tag, "DHnQ")){
4240                 dissector = dissect_smb2_DHnQ_buffer;
4241         } else if(!strcmp(tag, "DHnC")){
4242                 dissector = dissect_smb2_DHnC_buffer;
4243         } else if(!strcmp(tag, "TWrp")){
4244                 dissector = dissect_smb2_TWrp_buffer;
4245         }
4246
4247         dissect_smb2_olb_buffer(pinfo, sub_tree, tvb, &data_olb, si, dissector);
4248
4249         if(chain_offset){
4250                 tvbuff_t *chain_tvb;
4251                 chain_tvb=tvb_new_subset(tvb, chain_offset, tvb_length_remaining(tvb, chain_offset), tvb_reported_length_remaining(tvb, chain_offset));
4252
4253                 /* next extra info */
4254                 dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si);
4255         }
4256         return;
4257 }
4258
4259 static int
4260 dissect_smb2_create_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4261 {
4262         offset_length_buffer_t f_olb, e_olb;
4263         const char *fname;
4264
4265         /* buffer code */
4266         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4267
4268         /* security flags */
4269         offset++;
4270
4271         /* oplock */
4272         offset = dissect_smb2_oplock(tree, tvb, offset);
4273
4274         /* impersonation level */
4275         proto_tree_add_item(tree, hf_smb2_impersonation_level, tvb, offset, 4, TRUE);
4276         offset += 4;
4277
4278         /* create flags */
4279         proto_tree_add_item(tree, hf_smb2_create_flags, tvb, offset, 8, TRUE);
4280         offset += 8;
4281
4282         /* reserved */
4283         offset += 8;
4284
4285         /* access mask */
4286         offset = dissect_smb_access_mask(tvb, tree, offset);
4287
4288         /* File Attributes */
4289         offset = dissect_file_attributes(tvb, tree, offset, 4);
4290
4291         /* share access */
4292         offset = dissect_nt_share_access(tvb, tree, offset);
4293
4294         /* create disposition */
4295         proto_tree_add_item(tree, hf_smb2_create_disposition, tvb, offset, 4, TRUE);
4296         offset += 4;
4297
4298         /* create options */
4299         offset = dissect_nt_create_options(tvb, tree, offset);
4300
4301         /* filename  offset/length */
4302         offset = dissect_smb2_olb_length_offset(tvb, offset, &f_olb, OLB_O_UINT16_S_UINT16, hf_smb2_filename);
4303
4304         /* extrainfo offset */
4305         offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
4306
4307         /* filename string */
4308         fname = dissect_smb2_olb_string(pinfo, tree, tvb, &f_olb, OLB_TYPE_UNICODE_STRING);
4309         if (check_col(pinfo->cinfo, COL_INFO)){
4310                 col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", fname);
4311         }
4312
4313         /* save the name if it looks sane */
4314         if(!pinfo->fd->flags.visited){
4315                 if(si->saved && si->saved->extra_info_type==SMB2_EI_FILENAME){
4316                         g_free(si->saved->extra_info);
4317                         si->saved->extra_info=NULL;
4318                         si->saved->extra_info_type=SMB2_EI_NONE;
4319                 }
4320                 if(si->saved && f_olb.len && f_olb.len<256){
4321                         si->saved->extra_info_type=SMB2_EI_FILENAME;
4322                         si->saved->extra_info=g_malloc(f_olb.len+1);
4323                         g_snprintf(si->saved->extra_info, f_olb.len+1, "%s", fname);
4324                 }
4325         }
4326
4327         /* If extrainfo_offset is non-null then this points to another
4328          * buffer. The offset is relative to the start of the smb packet
4329          */
4330         dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
4331
4332         offset = dissect_smb2_olb_tvb_max_offset(offset, &f_olb);
4333         offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
4334
4335         return offset;
4336 }
4337
4338 static int
4339 dissect_smb2_create_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4340 {
4341         offset_length_buffer_t e_olb;
4342
4343         switch (si->status) {
4344         case 0x00000000: break;
4345         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
4346         }
4347
4348         /* buffer code */
4349         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4350
4351         /* oplock */
4352         offset = dissect_smb2_oplock(tree, tvb, offset);
4353
4354         /* reserved */
4355         offset++;
4356
4357         /* create action */
4358         proto_tree_add_item(tree, hf_smb2_create_action, tvb, offset, 4, TRUE);
4359         offset += 4;
4360
4361         /* create time */
4362         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4363
4364         /* last access */
4365         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4366
4367         /* last write */
4368         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4369
4370         /* last change */
4371         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4372
4373         /* allocation size */
4374         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
4375         offset += 8;
4376
4377         /* end of file */
4378         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
4379         offset += 8;
4380
4381         /* File Attributes */
4382         offset = dissect_file_attributes(tvb, tree, offset, 4);
4383
4384         /* reserved */
4385         offset += 4;
4386
4387         /* fid */
4388         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_OPEN);
4389
4390         /* extrainfo offset */
4391         offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
4392
4393         /* If extrainfo_offset is non-null then this points to another
4394          * buffer. The offset is relative to the start of the smb packet
4395          */
4396         dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
4397
4398         offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
4399
4400         /* free si->saved->extra_info   we dont need it any more */
4401         if(si->saved && si->saved->extra_info_type==SMB2_EI_FILENAME){
4402                 g_free(si->saved->extra_info);
4403                 si->saved->extra_info=NULL;
4404                 si->saved->extra_info_type=SMB2_EI_NONE;
4405         }
4406
4407         return offset;
4408 }
4409
4410
4411 static int
4412 dissect_smb2_setinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4413 {
4414         guint32 setinfo_size;
4415         guint16 setinfo_offset;
4416
4417         /* buffer code */
4418         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4419
4420         /* class and info level */
4421         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
4422
4423         /* size */
4424         setinfo_size=tvb_get_letohl(tvb, offset);
4425         proto_tree_add_item(tree, hf_smb2_setinfo_size, tvb, offset, 4, TRUE);
4426         offset += 4;
4427
4428         /* offset */
4429         setinfo_offset=tvb_get_letohs(tvb, offset);
4430         proto_tree_add_item(tree, hf_smb2_setinfo_offset, tvb, offset, 2, TRUE);
4431         offset += 2;
4432
4433         /* some unknown bytes */
4434         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, TRUE);
4435         offset += 6;
4436
4437         /* fid */
4438         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4439
4440         /* data */
4441         if(si->saved)
4442           dissect_smb2_infolevel(tvb, pinfo, tree, setinfo_offset, si, si->saved->class, si->saved->infolevel);
4443         offset = setinfo_offset + setinfo_size;
4444
4445         return offset;
4446 }
4447
4448 static int
4449 dissect_smb2_setinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4450 {
4451         /* class/infolevel */
4452         dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
4453
4454         switch (si->status) {
4455         case 0x00000000: break;
4456         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
4457         }
4458
4459         /* buffer code */
4460         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4461
4462         return offset;
4463 }
4464
4465 static int
4466 dissect_smb2_break_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4467 {
4468         /* buffer code */
4469         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4470
4471         /* oplock */
4472         offset = dissect_smb2_oplock(tree, tvb, offset);
4473
4474         /* reserved */
4475         offset += 1;
4476
4477         /* reserved */
4478         offset += 4;
4479
4480         /* fid */
4481         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4482
4483         return offset;
4484 }
4485
4486 static int
4487 dissect_smb2_break_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4488 {
4489         switch (si->status) {
4490         case 0x00000000: break;
4491         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
4492         }
4493
4494         /* buffer code */
4495         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4496
4497         /* oplock */
4498         offset = dissect_smb2_oplock(tree, tvb, offset);
4499
4500         /* reserved */
4501         offset += 1;
4502
4503         /* reserved */
4504         offset += 4;
4505
4506         /* fid */
4507         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4508
4509         /* in break requests from server to client here're 24 byte zero bytes
4510          * which are likely a bug in windows (they may use 2* 24 bytes instead of just
4511          * 1 *24 bytes
4512          */
4513
4514         return offset;
4515 }
4516
4517 /* names here are just until we find better names for these functions */
4518 const value_string smb2_cmd_vals[] = {
4519   { 0x00, "NegotiateProtocol" },
4520   { 0x01, "SessionSetup" },
4521   { 0x02, "SessionLogoff" },
4522   { 0x03, "TreeConnect" },
4523   { 0x04, "TreeDisconnect" },
4524   { 0x05, "Create" },
4525   { 0x06, "Close" },
4526   { 0x07, "Flush" },
4527   { 0x08, "Read" },
4528   { 0x09, "Write" },
4529   { 0x0A, "Lock" },
4530   { 0x0B, "Ioctl" },
4531   { 0x0C, "Cancel" },
4532   { 0x0D, "KeepAlive" },
4533   { 0x0E, "Find" },
4534   { 0x0F, "Notify" },
4535   { 0x10, "GetInfo" },
4536   { 0x11, "SetInfo" },
4537   { 0x12, "Break" },
4538   { 0x13, "unknown-0x13" },
4539   { 0x14, "unknown-0x14" },
4540   { 0x15, "unknown-0x15" },
4541   { 0x16, "unknown-0x16" },
4542   { 0x17, "unknown-0x17" },
4543   { 0x18, "unknown-0x18" },
4544   { 0x19, "unknown-0x19" },
4545   { 0x1A, "unknown-0x1A" },
4546   { 0x1B, "unknown-0x1B" },
4547   { 0x1C, "unknown-0x1C" },
4548   { 0x1D, "unknown-0x1D" },
4549   { 0x1E, "unknown-0x1E" },
4550   { 0x1F, "unknown-0x1F" },
4551   { 0x20, "unknown-0x20" },
4552   { 0x21, "unknown-0x21" },
4553   { 0x22, "unknown-0x22" },
4554   { 0x23, "unknown-0x23" },
4555   { 0x24, "unknown-0x24" },
4556   { 0x25, "unknown-0x25" },
4557   { 0x26, "unknown-0x26" },
4558   { 0x27, "unknown-0x27" },
4559   { 0x28, "unknown-0x28" },
4560   { 0x29, "unknown-0x29" },
4561   { 0x2A, "unknown-0x2A" },
4562   { 0x2B, "unknown-0x2B" },
4563   { 0x2C, "unknown-0x2C" },
4564   { 0x2D, "unknown-0x2D" },
4565   { 0x2E, "unknown-0x2E" },
4566   { 0x2F, "unknown-0x2F" },
4567   { 0x30, "unknown-0x30" },
4568   { 0x31, "unknown-0x31" },
4569   { 0x32, "unknown-0x32" },
4570   { 0x33, "unknown-0x33" },
4571   { 0x34, "unknown-0x34" },
4572   { 0x35, "unknown-0x35" },
4573   { 0x36, "unknown-0x36" },
4574   { 0x37, "unknown-0x37" },
4575   { 0x38, "unknown-0x38" },
4576   { 0x39, "unknown-0x39" },
4577   { 0x3A, "unknown-0x3A" },
4578   { 0x3B, "unknown-0x3B" },
4579   { 0x3C, "unknown-0x3C" },
4580   { 0x3D, "unknown-0x3D" },
4581   { 0x3E, "unknown-0x3E" },
4582   { 0x3F, "unknown-0x3F" },
4583   { 0x40, "unknown-0x40" },
4584   { 0x41, "unknown-0x41" },
4585   { 0x42, "unknown-0x42" },
4586   { 0x43, "unknown-0x43" },
4587   { 0x44, "unknown-0x44" },
4588   { 0x45, "unknown-0x45" },
4589   { 0x46, "unknown-0x46" },
4590   { 0x47, "unknown-0x47" },
4591   { 0x48, "unknown-0x48" },
4592   { 0x49, "unknown-0x49" },
4593   { 0x4A, "unknown-0x4A" },
4594   { 0x4B, "unknown-0x4B" },
4595   { 0x4C, "unknown-0x4C" },
4596   { 0x4D, "unknown-0x4D" },
4597   { 0x4E, "unknown-0x4E" },
4598   { 0x4F, "unknown-0x4F" },
4599   { 0x50, "unknown-0x50" },
4600   { 0x51, "unknown-0x51" },
4601   { 0x52, "unknown-0x52" },
4602   { 0x53, "unknown-0x53" },
4603   { 0x54, "unknown-0x54" },
4604   { 0x55, "unknown-0x55" },
4605   { 0x56, "unknown-0x56" },
4606   { 0x57, "unknown-0x57" },
4607   { 0x58, "unknown-0x58" },
4608   { 0x59, "unknown-0x59" },
4609   { 0x5A, "unknown-0x5A" },
4610   { 0x5B, "unknown-0x5B" },
4611   { 0x5C, "unknown-0x5C" },
4612   { 0x5D, "unknown-0x5D" },
4613   { 0x5E, "unknown-0x5E" },
4614   { 0x5F, "unknown-0x5F" },
4615   { 0x60, "unknown-0x60" },
4616   { 0x61, "unknown-0x61" },
4617   { 0x62, "unknown-0x62" },
4618   { 0x63, "unknown-0x63" },
4619   { 0x64, "unknown-0x64" },
4620   { 0x65, "unknown-0x65" },
4621   { 0x66, "unknown-0x66" },
4622   { 0x67, "unknown-0x67" },
4623   { 0x68, "unknown-0x68" },
4624   { 0x69, "unknown-0x69" },
4625   { 0x6A, "unknown-0x6A" },
4626   { 0x6B, "unknown-0x6B" },
4627   { 0x6C, "unknown-0x6C" },
4628   { 0x6D, "unknown-0x6D" },
4629   { 0x6E, "unknown-0x6E" },
4630   { 0x6F, "unknown-0x6F" },
4631   { 0x70, "unknown-0x70" },
4632   { 0x71, "unknown-0x71" },
4633   { 0x72, "unknown-0x72" },
4634   { 0x73, "unknown-0x73" },
4635   { 0x74, "unknown-0x74" },
4636   { 0x75, "unknown-0x75" },
4637   { 0x76, "unknown-0x76" },
4638   { 0x77, "unknown-0x77" },
4639   { 0x78, "unknown-0x78" },
4640   { 0x79, "unknown-0x79" },
4641   { 0x7A, "unknown-0x7A" },
4642   { 0x7B, "unknown-0x7B" },
4643   { 0x7C, "unknown-0x7C" },
4644   { 0x7D, "unknown-0x7D" },
4645   { 0x7E, "unknown-0x7E" },
4646   { 0x7F, "unknown-0x7F" },
4647   { 0x80, "unknown-0x80" },
4648   { 0x81, "unknown-0x81" },
4649   { 0x82, "unknown-0x82" },
4650   { 0x83, "unknown-0x83" },
4651   { 0x84, "unknown-0x84" },
4652   { 0x85, "unknown-0x85" },
4653   { 0x86, "unknown-0x86" },
4654   { 0x87, "unknown-0x87" },
4655   { 0x88, "unknown-0x88" },
4656   { 0x89, "unknown-0x89" },
4657   { 0x8A, "unknown-0x8A" },
4658   { 0x8B, "unknown-0x8B" },
4659   { 0x8C, "unknown-0x8C" },
4660   { 0x8D, "unknown-0x8D" },
4661   { 0x8E, "unknown-0x8E" },
4662   { 0x8F, "unknown-0x8F" },
4663   { 0x90, "unknown-0x90" },
4664   { 0x91, "unknown-0x91" },
4665   { 0x92, "unknown-0x92" },
4666   { 0x93, "unknown-0x93" },
4667   { 0x94, "unknown-0x94" },
4668   { 0x95, "unknown-0x95" },
4669   { 0x96, "unknown-0x96" },
4670   { 0x97, "unknown-0x97" },
4671   { 0x98, "unknown-0x98" },
4672   { 0x99, "unknown-0x99" },
4673   { 0x9A, "unknown-0x9A" },
4674   { 0x9B, "unknown-0x9B" },
4675   { 0x9C, "unknown-0x9C" },
4676   { 0x9D, "unknown-0x9D" },
4677   { 0x9E, "unknown-0x9E" },
4678   { 0x9F, "unknown-0x9F" },
4679   { 0xA0, "unknown-0xA0" },
4680   { 0xA1, "unknown-0xA1" },
4681   { 0xA2, "unknown-0xA2" },
4682   { 0xA3, "unknown-0xA3" },
4683   { 0xA4, "unknown-0xA4" },
4684   { 0xA5, "unknown-0xA5" },
4685   { 0xA6, "unknown-0xA6" },
4686   { 0xA7, "unknown-0xA7" },
4687   { 0xA8, "unknown-0xA8" },
4688   { 0xA9, "unknown-0xA9" },
4689   { 0xAA, "unknown-0xAA" },
4690   { 0xAB, "unknown-0xAB" },
4691   { 0xAC, "unknown-0xAC" },
4692   { 0xAD, "unknown-0xAD" },
4693   { 0xAE, "unknown-0xAE" },
4694   { 0xAF, "unknown-0xAF" },
4695   { 0xB0, "unknown-0xB0" },
4696   { 0xB1, "unknown-0xB1" },
4697   { 0xB2, "unknown-0xB2" },
4698   { 0xB3, "unknown-0xB3" },
4699   { 0xB4, "unknown-0xB4" },
4700   { 0xB5, "unknown-0xB5" },
4701   { 0xB6, "unknown-0xB6" },
4702   { 0xB7, "unknown-0xB7" },
4703   { 0xB8, "unknown-0xB8" },
4704   { 0xB9, "unknown-0xB9" },
4705   { 0xBA, "unknown-0xBA" },
4706   { 0xBB, "unknown-0xBB" },
4707   { 0xBC, "unknown-0xBC" },
4708   { 0xBD, "unknown-0xBD" },
4709   { 0xBE, "unknown-0xBE" },
4710   { 0xBF, "unknown-0xBF" },
4711   { 0xC0, "unknown-0xC0" },
4712   { 0xC1, "unknown-0xC1" },
4713   { 0xC2, "unknown-0xC2" },
4714   { 0xC3, "unknown-0xC3" },
4715   { 0xC4, "unknown-0xC4" },
4716   { 0xC5, "unknown-0xC5" },
4717   { 0xC6, "unknown-0xC6" },
4718   { 0xC7, "unknown-0xC7" },
4719   { 0xC8, "unknown-0xC8" },
4720   { 0xC9, "unknown-0xC9" },
4721   { 0xCA, "unknown-0xCA" },
4722   { 0xCB, "unknown-0xCB" },
4723   { 0xCC, "unknown-0xCC" },
4724   { 0xCD, "unknown-0xCD" },
4725   { 0xCE, "unknown-0xCE" },
4726   { 0xCF, "unknown-0xCF" },
4727   { 0xD0, "unknown-0xD0" },
4728   { 0xD1, "unknown-0xD1" },
4729   { 0xD2, "unknown-0xD2" },
4730   { 0xD3, "unknown-0xD3" },
4731   { 0xD4, "unknown-0xD4" },
4732   { 0xD5, "unknown-0xD5" },
4733   { 0xD6, "unknown-0xD6" },
4734   { 0xD7, "unknown-0xD7" },
4735   { 0xD8, "unknown-0xD8" },
4736   { 0xD9, "unknown-0xD9" },
4737   { 0xDA, "unknown-0xDA" },
4738   { 0xDB, "unknown-0xDB" },
4739   { 0xDC, "unknown-0xDC" },
4740   { 0xDD, "unknown-0xDD" },
4741   { 0xDE, "unknown-0xDE" },
4742   { 0xDF, "unknown-0xDF" },
4743   { 0xE0, "unknown-0xE0" },
4744   { 0xE1, "unknown-0xE1" },
4745   { 0xE2, "unknown-0xE2" },
4746   { 0xE3, "unknown-0xE3" },
4747   { 0xE4, "unknown-0xE4" },
4748   { 0xE5, "unknown-0xE5" },
4749   { 0xE6, "unknown-0xE6" },
4750   { 0xE7, "unknown-0xE7" },
4751   { 0xE8, "unknown-0xE8" },
4752   { 0xE9, "unknown-0xE9" },
4753   { 0xEA, "unknown-0xEA" },
4754   { 0xEB, "unknown-0xEB" },
4755   { 0xEC, "unknown-0xEC" },
4756   { 0xED, "unknown-0xED" },
4757   { 0xEE, "unknown-0xEE" },
4758   { 0xEF, "unknown-0xEF" },
4759   { 0xF0, "unknown-0xF0" },
4760   { 0xF1, "unknown-0xF1" },
4761   { 0xF2, "unknown-0xF2" },
4762   { 0xF3, "unknown-0xF3" },
4763   { 0xF4, "unknown-0xF4" },
4764   { 0xF5, "unknown-0xF5" },
4765   { 0xF6, "unknown-0xF6" },
4766   { 0xF7, "unknown-0xF7" },
4767   { 0xF8, "unknown-0xF8" },
4768   { 0xF9, "unknown-0xF9" },
4769   { 0xFA, "unknown-0xFA" },
4770   { 0xFB, "unknown-0xFB" },
4771   { 0xFC, "unknown-0xFC" },
4772   { 0xFD, "unknown-0xFD" },
4773   { 0xFE, "unknown-0xFE" },
4774   { 0xFF, "unknown-0xFF" },
4775   { 0x00, NULL },
4776 };
4777 static const char *decode_smb2_name(guint16 cmd)
4778 {
4779   if (cmd > 0xFF) return "unknown";
4780   return(smb2_cmd_vals[cmd & 0xFF].strptr);
4781 }
4782
4783 static smb2_function smb2_dissector[256] = {
4784   /* 0x00 NegotiateProtocol*/
4785         {dissect_smb2_negotiate_protocol_request,
4786          dissect_smb2_negotiate_protocol_response},
4787   /* 0x01 SessionSetup*/
4788         {dissect_smb2_session_setup_request,
4789          dissect_smb2_session_setup_response},
4790   /* 0x02 SessionLogoff*/
4791         {dissect_smb2_sessionlogoff_request,
4792          dissect_smb2_sessionlogoff_response},
4793   /* 0x03 TreeConnect*/
4794         {dissect_smb2_tree_connect_request,
4795          dissect_smb2_tree_connect_response},
4796   /* 0x04 TreeDisconnect*/
4797         {dissect_smb2_tree_disconnect_request,
4798          dissect_smb2_tree_disconnect_response},
4799   /* 0x05 Create*/
4800         {dissect_smb2_create_request,
4801          dissect_smb2_create_response},
4802   /* 0x06 Close*/
4803         {dissect_smb2_close_request,
4804          dissect_smb2_close_response},
4805   /* 0x07 Flush*/
4806         {dissect_smb2_flush_request,
4807          dissect_smb2_flush_response},
4808   /* 0x08 Read*/
4809         {dissect_smb2_read_request,
4810          dissect_smb2_read_response},
4811   /* 0x09 Writew*/
4812         {dissect_smb2_write_request,
4813          dissect_smb2_write_response},
4814   /* 0x0a Lock */
4815         {dissect_smb2_lock_request,
4816          dissect_smb2_lock_response},
4817   /* 0x0b Ioctl*/
4818         {dissect_smb2_ioctl_request,
4819          dissect_smb2_ioctl_response},
4820   /* 0x0c Cancel*/
4821         {dissect_smb2_cancel_request,
4822          NULL},
4823   /* 0x0d KeepAlive*/
4824         {dissect_smb2_keepalive_request,
4825          dissect_smb2_keepalive_response},
4826   /* 0x0e Find*/
4827         {dissect_smb2_find_request,
4828          dissect_smb2_find_response},
4829   /* 0x0f Notify*/
4830         {dissect_smb2_notify_request,
4831          dissect_smb2_notify_response},
4832   /* 0x10 GetInfo*/
4833         {dissect_smb2_getinfo_request,
4834          dissect_smb2_getinfo_response},
4835   /* 0x11 SetInfo*/
4836         {dissect_smb2_setinfo_request,
4837          dissect_smb2_setinfo_response},
4838   /* 0x12 Break */
4839         {dissect_smb2_break_request,
4840          dissect_smb2_break_response},
4841   /* 0x13 */  {NULL, NULL},
4842   /* 0x14 */  {NULL, NULL},
4843   /* 0x15 */  {NULL, NULL},
4844   /* 0x16 */  {NULL, NULL},
4845   /* 0x17 */  {NULL, NULL},
4846   /* 0x18 */  {NULL, NULL},
4847   /* 0x19 */  {NULL, NULL},
4848   /* 0x1a */  {NULL, NULL},
4849   /* 0x1b */  {NULL, NULL},
4850   /* 0x1c */  {NULL, NULL},
4851   /* 0x1d */  {NULL, NULL},
4852   /* 0x1e */  {NULL, NULL},
4853   /* 0x1f */  {NULL, NULL},
4854   /* 0x20 */  {NULL, NULL},
4855   /* 0x21 */  {NULL, NULL},
4856   /* 0x22 */  {NULL, NULL},
4857   /* 0x23 */  {NULL, NULL},
4858   /* 0x24 */  {NULL, NULL},
4859   /* 0x25 */  {NULL, NULL},
4860   /* 0x26 */  {NULL, NULL},
4861   /* 0x27 */  {NULL, NULL},
4862   /* 0x28 */  {NULL, NULL},
4863   /* 0x29 */  {NULL, NULL},
4864   /* 0x2a */  {NULL, NULL},
4865   /* 0x2b */  {NULL, NULL},
4866   /* 0x2c */  {NULL, NULL},
4867   /* 0x2d */  {NULL, NULL},
4868   /* 0x2e */  {NULL, NULL},
4869   /* 0x2f */  {NULL, NULL},
4870   /* 0x30 */  {NULL, NULL},
4871   /* 0x31 */  {NULL, NULL},
4872   /* 0x32 */  {NULL, NULL},
4873   /* 0x33 */  {NULL, NULL},
4874   /* 0x34 */  {NULL, NULL},
4875   /* 0x35 */  {NULL, NULL},
4876   /* 0x36 */  {NULL, NULL},
4877   /* 0x37 */  {NULL, NULL},
4878   /* 0x38 */  {NULL, NULL},
4879   /* 0x39 */  {NULL, NULL},
4880   /* 0x3a */  {NULL, NULL},
4881   /* 0x3b */  {NULL, NULL},
4882   /* 0x3c */  {NULL, NULL},
4883   /* 0x3d */  {NULL, NULL},
4884   /* 0x3e */  {NULL, NULL},
4885   /* 0x3f */  {NULL, NULL},
4886   /* 0x40 */  {NULL, NULL},
4887   /* 0x41 */  {NULL, NULL},
4888   /* 0x42 */  {NULL, NULL},
4889   /* 0x43 */  {NULL, NULL},
4890   /* 0x44 */  {NULL, NULL},
4891   /* 0x45 */  {NULL, NULL},
4892   /* 0x46 */  {NULL, NULL},
4893   /* 0x47 */  {NULL, NULL},
4894   /* 0x48 */  {NULL, NULL},
4895   /* 0x49 */  {NULL, NULL},
4896   /* 0x4a */  {NULL, NULL},
4897   /* 0x4b */  {NULL, NULL},
4898   /* 0x4c */  {NULL, NULL},
4899   /* 0x4d */  {NULL, NULL},
4900   /* 0x4e */  {NULL, NULL},
4901   /* 0x4f */  {NULL, NULL},
4902   /* 0x50 */  {NULL, NULL},
4903   /* 0x51 */  {NULL, NULL},
4904   /* 0x52 */  {NULL, NULL},
4905   /* 0x53 */  {NULL, NULL},
4906   /* 0x54 */  {NULL, NULL},
4907   /* 0x55 */  {NULL, NULL},
4908   /* 0x56 */  {NULL, NULL},
4909   /* 0x57 */  {NULL, NULL},
4910   /* 0x58 */  {NULL, NULL},
4911   /* 0x59 */  {NULL, NULL},
4912   /* 0x5a */  {NULL, NULL},
4913   /* 0x5b */  {NULL, NULL},
4914   /* 0x5c */  {NULL, NULL},
4915   /* 0x5d */  {NULL, NULL},
4916   /* 0x5e */  {NULL, NULL},
4917   /* 0x5f */  {NULL, NULL},
4918   /* 0x60 */  {NULL, NULL},
4919   /* 0x61 */  {NULL, NULL},
4920   /* 0x62 */  {NULL, NULL},
4921   /* 0x63 */  {NULL, NULL},
4922   /* 0x64 */  {NULL, NULL},
4923   /* 0x65 */  {NULL, NULL},
4924   /* 0x66 */  {NULL, NULL},
4925   /* 0x67 */  {NULL, NULL},
4926   /* 0x68 */  {NULL, NULL},
4927   /* 0x69 */  {NULL, NULL},
4928   /* 0x6a */  {NULL, NULL},
4929   /* 0x6b */  {NULL, NULL},
4930   /* 0x6c */  {NULL, NULL},
4931   /* 0x6d */  {NULL, NULL},
4932   /* 0x6e */  {NULL, NULL},
4933   /* 0x6f */  {NULL, NULL},
4934   /* 0x70 */  {NULL, NULL},
4935   /* 0x71 */  {NULL, NULL},
4936   /* 0x72 */  {NULL, NULL},
4937   /* 0x73 */  {NULL, NULL},
4938   /* 0x74 */  {NULL, NULL},
4939   /* 0x75 */  {NULL, NULL},
4940   /* 0x76 */  {NULL, NULL},
4941   /* 0x77 */  {NULL, NULL},
4942   /* 0x78 */  {NULL, NULL},
4943   /* 0x79 */  {NULL, NULL},
4944   /* 0x7a */  {NULL, NULL},
4945   /* 0x7b */  {NULL, NULL},
4946   /* 0x7c */  {NULL, NULL},
4947   /* 0x7d */  {NULL, NULL},
4948   /* 0x7e */  {NULL, NULL},
4949   /* 0x7f */  {NULL, NULL},
4950   /* 0x80 */  {NULL, NULL},
4951   /* 0x81 */  {NULL, NULL},
4952   /* 0x82 */  {NULL, NULL},
4953   /* 0x83 */  {NULL, NULL},
4954   /* 0x84 */  {NULL, NULL},
4955   /* 0x85 */  {NULL, NULL},
4956   /* 0x86 */  {NULL, NULL},
4957   /* 0x87 */  {NULL, NULL},
4958   /* 0x88 */  {NULL, NULL},
4959   /* 0x89 */  {NULL, NULL},
4960   /* 0x8a */  {NULL, NULL},
4961   /* 0x8b */  {NULL, NULL},
4962   /* 0x8c */  {NULL, NULL},
4963   /* 0x8d */  {NULL, NULL},
4964   /* 0x8e */  {NULL, NULL},
4965   /* 0x8f */  {NULL, NULL},
4966   /* 0x90 */  {NULL, NULL},
4967   /* 0x91 */  {NULL, NULL},
4968   /* 0x92 */  {NULL, NULL},
4969   /* 0x93 */  {NULL, NULL},
4970   /* 0x94 */  {NULL, NULL},
4971   /* 0x95 */  {NULL, NULL},
4972   /* 0x96 */  {NULL, NULL},
4973   /* 0x97 */  {NULL, NULL},
4974   /* 0x98 */  {NULL, NULL},
4975   /* 0x99 */  {NULL, NULL},
4976   /* 0x9a */  {NULL, NULL},
4977   /* 0x9b */  {NULL, NULL},
4978   /* 0x9c */  {NULL, NULL},
4979   /* 0x9d */  {NULL, NULL},
4980   /* 0x9e */  {NULL, NULL},
4981   /* 0x9f */  {NULL, NULL},
4982   /* 0xa0 */  {NULL, NULL},
4983   /* 0xa1 */  {NULL, NULL},
4984   /* 0xa2 */  {NULL, NULL},
4985   /* 0xa3 */  {NULL, NULL},
4986   /* 0xa4 */  {NULL, NULL},
4987   /* 0xa5 */  {NULL, NULL},
4988   /* 0xa6 */  {NULL, NULL},
4989   /* 0xa7 */  {NULL, NULL},
4990   /* 0xa8 */  {NULL, NULL},
4991   /* 0xa9 */  {NULL, NULL},
4992   /* 0xaa */  {NULL, NULL},
4993   /* 0xab */  {NULL, NULL},
4994   /* 0xac */  {NULL, NULL},
4995   /* 0xad */  {NULL, NULL},
4996   /* 0xae */  {NULL, NULL},
4997   /* 0xaf */  {NULL, NULL},
4998   /* 0xb0 */  {NULL, NULL},
4999   /* 0xb1 */  {NULL, NULL},
5000   /* 0xb2 */  {NULL, NULL},
5001   /* 0xb3 */  {NULL, NULL},
5002   /* 0xb4 */  {NULL, NULL},
5003   /* 0xb5 */  {NULL, NULL},
5004   /* 0xb6 */  {NULL, NULL},
5005   /* 0xb7 */  {NULL, NULL},
5006   /* 0xb8 */  {NULL, NULL},
5007   /* 0xb9 */  {NULL, NULL},
5008   /* 0xba */  {NULL, NULL},
5009   /* 0xbb */  {NULL, NULL},
5010   /* 0xbc */  {NULL, NULL},
5011   /* 0xbd */  {NULL, NULL},
5012   /* 0xbe */  {NULL, NULL},
5013   /* 0xbf */  {NULL, NULL},
5014   /* 0xc0 */  {NULL, NULL},
5015   /* 0xc1 */  {NULL, NULL},
5016   /* 0xc2 */  {NULL, NULL},
5017   /* 0xc3 */  {NULL, NULL},
5018   /* 0xc4 */  {NULL, NULL},
5019   /* 0xc5 */  {NULL, NULL},
5020   /* 0xc6 */  {NULL, NULL},
5021   /* 0xc7 */  {NULL, NULL},
5022   /* 0xc8 */  {NULL, NULL},
5023   /* 0xc9 */  {NULL, NULL},
5024   /* 0xca */  {NULL, NULL},
5025   /* 0xcb */  {NULL, NULL},
5026   /* 0xcc */  {NULL, NULL},
5027   /* 0xcd */  {NULL, NULL},
5028   /* 0xce */  {NULL, NULL},
5029   /* 0xcf */  {NULL, NULL},
5030   /* 0xd0 */  {NULL, NULL},
5031   /* 0xd1 */  {NULL, NULL},
5032   /* 0xd2 */  {NULL, NULL},
5033   /* 0xd3 */  {NULL, NULL},
5034   /* 0xd4 */  {NULL, NULL},
5035   /* 0xd5 */  {NULL, NULL},
5036   /* 0xd6 */  {NULL, NULL},
5037   /* 0xd7 */  {NULL, NULL},
5038   /* 0xd8 */  {NULL, NULL},
5039   /* 0xd9 */  {NULL, NULL},
5040   /* 0xda */  {NULL, NULL},
5041   /* 0xdb */  {NULL, NULL},
5042   /* 0xdc */  {NULL, NULL},
5043   /* 0xdd */  {NULL, NULL},
5044   /* 0xde */  {NULL, NULL},
5045   /* 0xdf */  {NULL, NULL},
5046   /* 0xe0 */  {NULL, NULL},
5047   /* 0xe1 */  {NULL, NULL},
5048   /* 0xe2 */  {NULL, NULL},
5049   /* 0xe3 */  {NULL, NULL},
5050   /* 0xe4 */  {NULL, NULL},
5051   /* 0xe5 */  {NULL, NULL},
5052   /* 0xe6 */  {NULL, NULL},
5053   /* 0xe7 */  {NULL, NULL},
5054   /* 0xe8 */  {NULL, NULL},
5055   /* 0xe9 */  {NULL, NULL},
5056   /* 0xea */  {NULL, NULL},
5057   /* 0xeb */  {NULL, NULL},
5058   /* 0xec */  {NULL, NULL},
5059   /* 0xed */  {NULL, NULL},
5060   /* 0xee */  {NULL, NULL},
5061   /* 0xef */  {NULL, NULL},
5062   /* 0xf0 */  {NULL, NULL},
5063   /* 0xf1 */  {NULL, NULL},
5064   /* 0xf2 */  {NULL, NULL},
5065   /* 0xf3 */  {NULL, NULL},
5066   /* 0xf4 */  {NULL, NULL},
5067   /* 0xf5 */  {NULL, NULL},
5068   /* 0xf6 */  {NULL, NULL},
5069   /* 0xf7 */  {NULL, NULL},
5070   /* 0xf8 */  {NULL, NULL},
5071   /* 0xf9 */  {NULL, NULL},
5072   /* 0xfa */  {NULL, NULL},
5073   /* 0xfb */  {NULL, NULL},
5074   /* 0xfc */  {NULL, NULL},
5075   /* 0xfd */  {NULL, NULL},
5076   /* 0xfe */  {NULL, NULL},
5077   /* 0xff */  {NULL, NULL},
5078 };
5079
5080
5081 static int
5082 dissect_smb2_command(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
5083 {
5084         int (*cmd_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
5085         proto_item *cmd_item;
5086         proto_tree *cmd_tree;
5087         int old_offset = offset;
5088
5089         cmd_item = proto_tree_add_text(tree, tvb, offset, -1,
5090                         "%s %s (0x%02x)",
5091                         decode_smb2_name(si->opcode),
5092                         (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request",
5093                         si->opcode);
5094         cmd_tree = proto_item_add_subtree(cmd_item, ett_smb2_command);
5095
5096
5097         cmd_dissector=(si->flags & SMB2_FLAGS_RESPONSE)?
5098                 smb2_dissector[si->opcode&0xff].response:
5099                 smb2_dissector[si->opcode&0xff].request;
5100         if(cmd_dissector){
5101                 offset=(*cmd_dissector)(tvb, pinfo, cmd_tree, offset, si);
5102         } else {
5103                 proto_tree_add_item(cmd_tree, hf_smb2_unknown, tvb, offset, -1, FALSE);
5104                 offset=tvb_length(tvb);
5105         }
5106
5107         proto_item_set_len(cmd_item, offset-old_offset);
5108
5109         return offset;
5110 }
5111
5112 static int
5113 dissect_smb2_tid_sesid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
5114 {
5115         proto_item *tid_item=NULL;
5116         proto_tree *tid_tree=NULL;
5117         smb2_tid_info_t tid_key;
5118         int tid_offset = 0;
5119         proto_item *sesid_item=NULL;
5120         proto_tree *sesid_tree=NULL;
5121         smb2_sesid_info_t sesid_key;
5122         int sesid_offset;
5123         proto_item *item;
5124         unsigned int pid;
5125
5126
5127         if (si->flags&SMB2_FLAGS_ASYNC_CMD) {
5128                 proto_tree_add_item(tree, hf_smb2_aid, tvb, offset, 8, TRUE);
5129                 offset += 8;
5130         } else {
5131                 /* Process ID */
5132                 pid=tvb_get_letohl(tvb, offset);
5133                 proto_tree_add_uint_format(tree, hf_smb2_pid, tvb, offset, 4, pid, "Process Id: %08x",pid);
5134                 offset += 4;
5135
5136                 /* Tree ID */
5137                 tid_offset = offset;
5138                 si->tid=tvb_get_letohl(tvb, offset);
5139                 tid_item=proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 4, TRUE);
5140                 if(tree){
5141                         tid_tree=proto_item_add_subtree(tid_item, ett_smb2_tid_tree);
5142                 }
5143                 offset += 4;
5144         }
5145
5146         /* Session ID */
5147         sesid_offset = offset;
5148         si->sesid=tvb_get_letoh64(tvb, offset);
5149         sesid_item=proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, TRUE);
5150         if(tree){
5151                 sesid_tree=proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
5152         }
5153         offset += 8;
5154
5155         /* now we need to first lookup the uid session */
5156         sesid_key.sesid=si->sesid;
5157         si->session=g_hash_table_lookup(si->conv->sesids, &sesid_key);
5158         if(!si->session) {
5159                 if (si->opcode != 0x03) return offset;
5160
5161                 /* if we come to a session that is unknown, and the operation is
5162                  * a tree connect, we create a dummy sessison, so we can hang the
5163                  * tree data on it
5164                  */
5165                 si->session=se_alloc(sizeof(smb2_sesid_info_t));
5166                 si->session->sesid=si->sesid;
5167                 si->session->acct_name=NULL;
5168                 si->session->domain_name=NULL;
5169                 si->session->host_name=NULL;
5170                 si->session->auth_frame=(guint32)-1;
5171                 si->session->tids= g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
5172                 g_hash_table_insert(si->conv->sesids, si->session, si->session);
5173
5174                 return offset;
5175         }
5176
5177         if (si->session->auth_frame != (guint32)-1) {
5178                 item=proto_tree_add_string(sesid_tree, hf_smb2_acct_name, tvb, sesid_offset, 0, si->session->acct_name);
5179                 PROTO_ITEM_SET_GENERATED(item);
5180                 proto_item_append_text(sesid_item, " Acct:%s", si->session->acct_name);
5181
5182                 item=proto_tree_add_string(sesid_tree, hf_smb2_domain_name, tvb, sesid_offset, 0, si->session->domain_name);
5183                 PROTO_ITEM_SET_GENERATED(item);
5184                 proto_item_append_text(sesid_item, " Domain:%s", si->session->domain_name);
5185
5186                 item=proto_tree_add_string(sesid_tree, hf_smb2_host_name, tvb, sesid_offset, 0, si->session->host_name);
5187                 PROTO_ITEM_SET_GENERATED(item);
5188                 proto_item_append_text(sesid_item, " Host:%s", si->session->host_name);
5189
5190                 item=proto_tree_add_uint(sesid_tree, hf_smb2_auth_frame, tvb, sesid_offset, 0, si->session->auth_frame);
5191                 PROTO_ITEM_SET_GENERATED(item);
5192         }
5193
5194         if (!(si->flags&SMB2_FLAGS_ASYNC_CMD)) {
5195                 /* see if we can find the name for this tid */
5196                 tid_key.tid=si->tid;
5197                 si->tree=g_hash_table_lookup(si->session->tids, &tid_key);
5198                 if(!si->tree) return offset;
5199
5200                 item=proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, tid_offset, 4, si->tree->name);
5201                 PROTO_ITEM_SET_GENERATED(item);
5202                 proto_item_append_text(tid_item, "  %s", si->tree->name);
5203
5204                 item=proto_tree_add_uint(tid_tree, hf_smb2_share_type, tvb, tid_offset, 0, si->tree->share_type);
5205                 PROTO_ITEM_SET_GENERATED(item);
5206         
5207                 item=proto_tree_add_uint(tid_tree, hf_smb2_tcon_frame, tvb, tid_offset, 0, si->tree->connect_frame);
5208                 PROTO_ITEM_SET_GENERATED(item);
5209         }
5210
5211         return offset;
5212 }
5213
5214 static int
5215 dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolean first_in_chain)
5216 {
5217         proto_item *seqnum_item;
5218         proto_item *item=NULL;
5219         proto_tree *tree=NULL;
5220         proto_item *header_item=NULL;
5221         proto_tree *header_tree=NULL;
5222         proto_item *flags_item=NULL;
5223         proto_tree *flags_tree=NULL;
5224         int offset = 0;
5225         int chain_offset = 0;
5226         guint16 header_len;
5227         conversation_t *conversation;
5228         smb2_saved_info_t *ssi=NULL, ssi_key;
5229         smb2_info_t *si;
5230
5231         si=ep_alloc(sizeof(smb2_info_t));
5232         si->conv=NULL;
5233         si->saved=NULL;
5234         si->tree=NULL;
5235         si->top_tree=parent_tree;
5236
5237         /* find which conversation we are part of and get the data for that
5238          * conversation
5239          */
5240         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
5241         if(!conversation){
5242                 /* OK this is a new conversation so lets create it */
5243                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
5244                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
5245         }
5246         si->conv=conversation_get_proto_data(conversation, proto_smb2);
5247         if(!si->conv){
5248                 /* no smb2_into_t structure for this conversation yet,
5249                  * create it.
5250                  */
5251                 si->conv=se_alloc(sizeof(smb2_conv_info_t));
5252                 /* qqq this leaks memory for now since we never free
5253                    the hashtables */
5254                 si->conv->matched= g_hash_table_new(smb2_saved_info_hash_matched,
5255                         smb2_saved_info_equal_matched);
5256                 si->conv->unmatched= g_hash_table_new(smb2_saved_info_hash_unmatched,
5257                         smb2_saved_info_equal_unmatched);
5258                 si->conv->sesids= g_hash_table_new(smb2_sesid_info_hash,
5259                         smb2_sesid_info_equal);
5260
5261                 conversation_add_proto_data(conversation, proto_smb2, si->conv);
5262         }
5263
5264
5265         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB2");
5266         if (check_col(pinfo->cinfo, COL_INFO)){
5267                 if (first_in_chain) {
5268                         /* first packet */
5269                         col_clear(pinfo->cinfo, COL_INFO);
5270                 } else {
5271                         col_append_str(pinfo->cinfo, COL_INFO, ";");
5272                 }
5273         }
5274
5275         if (parent_tree) {
5276                 item = proto_tree_add_item(parent_tree, proto_smb2, tvb, offset,
5277                         -1, FALSE);
5278                 tree = proto_item_add_subtree(item, ett_smb2);
5279         }
5280
5281
5282         if (tree) {
5283                 header_item = proto_tree_add_text(tree, tvb, offset, -1, "SMB2 Header");
5284                 header_tree = proto_item_add_subtree(header_item, ett_smb2_header);
5285         }
5286
5287         /* Decode the header */
5288         /* SMB2 marker */
5289         proto_tree_add_text(header_tree, tvb, offset, 4, "Server Component: SMB2");
5290         offset += 4;
5291
5292         /* header length */
5293         header_len=tvb_get_letohs(tvb, offset);
5294         proto_tree_add_item(header_tree, hf_smb2_header_len, tvb, offset, 2, TRUE);
5295         offset += 2;
5296
5297         /* epoch */
5298         proto_tree_add_item(header_tree, hf_smb2_epoch, tvb, offset, 2, TRUE);
5299         offset += 2;
5300
5301         /* Status Code */
5302         si->status=tvb_get_letohl(tvb, offset);
5303         proto_tree_add_item(header_tree, hf_smb2_nt_status, tvb, offset, 4, TRUE);
5304         offset += 4;
5305
5306
5307         /* opcode */
5308         si->opcode=tvb_get_letohs(tvb, offset);
5309         proto_tree_add_item(header_tree, hf_smb2_cmd, tvb, offset, 2, TRUE);
5310         offset += 2;
5311
5312         /* we need the flags before we know how to parse the credits field */
5313         si->flags=tvb_get_letohl(tvb, offset+2);
5314
5315         /* credits */
5316         if (si->flags & SMB2_FLAGS_RESPONSE) {
5317                 proto_tree_add_item(header_tree, hf_smb2_credits_granted, tvb, offset, 2, TRUE);
5318         } else {
5319                 proto_tree_add_item(header_tree, hf_smb2_credits_requested, tvb, offset, 2, TRUE);
5320         }
5321         offset += 2;
5322
5323         /* flags */
5324         if(header_tree){
5325                 flags_item = proto_tree_add_text(header_tree, tvb, offset, 4,
5326                         "Flags: 0x%08x", si->flags);
5327                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_flags);
5328         }
5329         proto_tree_add_boolean(flags_tree, hf_smb2_flags_dfs_op, tvb, offset, 4, si->flags);
5330         proto_tree_add_boolean(flags_tree, hf_smb2_flags_signature, tvb, offset, 4, si->flags);
5331         proto_tree_add_boolean(flags_tree, hf_smb2_flags_chained, tvb, offset, 4, si->flags);
5332         proto_tree_add_boolean(flags_tree, hf_smb2_flags_async_cmd, tvb, offset, 4, si->flags);
5333         proto_tree_add_boolean(flags_tree, hf_smb2_flags_response, tvb, offset, 4, si->flags);
5334
5335         offset += 4;
5336
5337         /* some unknown bytes */
5338         chain_offset=tvb_get_letohl(tvb, offset);
5339         proto_tree_add_item(header_tree, hf_smb2_chain_offset, tvb, offset, 4, FALSE);
5340         offset += 4;
5341
5342         /* command sequence number*/
5343         si->seqnum=tvb_get_letoh64(tvb, offset);
5344         ssi_key.seqnum=si->seqnum;
5345         seqnum_item=proto_tree_add_item(header_tree, hf_smb2_seqnum, tvb, offset, 8, TRUE);
5346         if(seqnum_item && (si->seqnum==-1)){
5347                 proto_item_append_text(seqnum_item, " (unsolicited response)");
5348         }
5349         offset += 8;
5350
5351         /* Tree ID and Session ID */
5352         offset = dissect_smb2_tid_sesid(pinfo, header_tree, tvb, offset, si);
5353
5354         /* Signature */
5355         proto_tree_add_item(header_tree, hf_smb2_signature, tvb, offset, 16, FALSE);
5356         offset += 16;
5357
5358         proto_item_set_len(header_item, offset);
5359
5360
5361         if (check_col(pinfo->cinfo, COL_INFO)){
5362                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
5363                         decode_smb2_name(si->opcode),
5364                         (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request");
5365                 if(si->status){
5366                         col_append_fstr(
5367                                 pinfo->cinfo, COL_INFO, ", Error: %s",
5368                                 val_to_str(si->status, NT_errors,
5369                                 "Unknown (0x%08X)"));
5370                 }
5371         }
5372
5373
5374         if(!pinfo->fd->flags.visited){
5375                 /* see if we can find this seqnum in the unmatched table */
5376                 ssi=g_hash_table_lookup(si->conv->unmatched, &ssi_key);
5377
5378                 if(!(si->flags & SMB2_FLAGS_RESPONSE)){
5379                         /* This is a request */
5380                         if(ssi){
5381                                 /* this is a request and we already found
5382                                  * an older ssi so just delete the previous
5383                                  * one
5384                                  */
5385                                 g_hash_table_remove(si->conv->unmatched, ssi);
5386                                 ssi=NULL;
5387                         }
5388
5389                         if(!ssi){
5390                                 /* no we couldnt find it, so just add it then
5391                                  * if was a request we are decoding
5392                                  */
5393                                 ssi=se_alloc(sizeof(smb2_saved_info_t));
5394                                 ssi->class=0;
5395                                 ssi->infolevel=0;
5396                                 ssi->seqnum=ssi_key.seqnum;
5397                                 ssi->frame_req=pinfo->fd->num;
5398                                 ssi->frame_res=0;
5399                                 ssi->req_time=pinfo->fd->abs_ts;
5400                                 ssi->extra_info=NULL;
5401                                 ssi->extra_info_type=SMB2_EI_NONE;
5402                                 g_hash_table_insert(si->conv->unmatched, ssi, ssi);
5403                         }
5404                 } else {
5405                         /* This is a response */
5406                         if(ssi){
5407                                 /* just  set the response frame and move it to the matched table */
5408                                 ssi->frame_res=pinfo->fd->num;
5409                                 g_hash_table_remove(si->conv->unmatched, ssi);
5410                                 g_hash_table_insert(si->conv->matched, ssi, ssi);
5411                         }
5412                 }
5413         } else {
5414                 /* see if we can find this seqnum in the matched table */
5415                 ssi=g_hash_table_lookup(si->conv->matched, &ssi_key);
5416                 /* if we couldnt find it in the matched table, it might still
5417                  * be in the unmatched table
5418                  */
5419                 if(!ssi){
5420                         ssi=g_hash_table_lookup(si->conv->unmatched, &ssi_key);
5421                 }
5422         }
5423
5424         if(ssi){
5425                 if(!(si->flags & SMB2_FLAGS_RESPONSE)){
5426                         if(ssi->frame_res){
5427                                 proto_item *tmp_item;
5428                                 tmp_item=proto_tree_add_uint(header_tree, hf_smb2_response_in, tvb, 0, 0, ssi->frame_res);
5429                                 PROTO_ITEM_SET_GENERATED(tmp_item);
5430                         }
5431                 } else {
5432                         if(ssi->frame_req){
5433                                 proto_item *tmp_item;
5434                                 nstime_t t, deltat;
5435
5436                                 tmp_item=proto_tree_add_uint(header_tree, hf_smb2_response_to, tvb, 0, 0, ssi->frame_req);
5437                                 PROTO_ITEM_SET_GENERATED(tmp_item);
5438                                 t = pinfo->fd->abs_ts;
5439                                 nstime_delta(&deltat, &t, &ssi->req_time);
5440                                 tmp_item=proto_tree_add_time(header_tree, hf_smb2_time, tvb,
5441                                     0, 0, &deltat);
5442                                 PROTO_ITEM_SET_GENERATED(tmp_item);
5443                         }
5444                 }
5445         }
5446         /* if we dont have ssi yet we must fake it */
5447         /*qqq*/
5448         si->saved=ssi;
5449
5450         tap_queue_packet(smb2_tap, pinfo, si);
5451
5452         /* Decode the payload */
5453         offset = dissect_smb2_command(pinfo, tree, tvb, offset, si);
5454
5455         if (chain_offset > 0) {
5456                 tvbuff_t *next_tvb;
5457
5458                 if (chain_offset < offset) {
5459                         THROW(ReportedBoundsError);
5460                 }
5461                 proto_item_set_len(item, chain_offset);
5462
5463                 next_tvb = tvb_new_subset_remaining(tvb, chain_offset);
5464                 offset = dissect_smb2(next_tvb, pinfo, parent_tree, FALSE);
5465         }
5466
5467         return offset;
5468 }
5469
5470 static gboolean
5471 dissect_smb2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
5472 {
5473         int offset = 0;
5474
5475         /* must check that this really is a smb2 packet */
5476         if (tvb_length(tvb) < 4)
5477                 return FALSE;
5478
5479         if( (tvb_get_guint8(tvb, 0) != 0xfe)
5480             || (tvb_get_guint8(tvb, 1) != 'S')
5481             || (tvb_get_guint8(tvb, 2) != 'M')
5482             || (tvb_get_guint8(tvb, 3) != 'B') ){
5483                 return FALSE;
5484         }
5485
5486         offset = dissect_smb2(tvb, pinfo, parent_tree, TRUE);
5487
5488         return TRUE;
5489 }
5490
5491 void
5492 proto_register_smb2(void)
5493 {
5494         static hf_register_info hf[] = {
5495         { &hf_smb2_cmd,
5496                 { "Command", "smb2.cmd", FT_UINT16, BASE_DEC,
5497                 VALS(smb2_cmd_vals), 0, "SMB2 Command Opcode", HFILL }},
5498         { &hf_smb2_response_to,
5499                 { "Response to", "smb2.response_to", FT_FRAMENUM, BASE_NONE,
5500                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
5501         { &hf_smb2_response_in,
5502                 { "Response in", "smb2.response_in", FT_FRAMENUM, BASE_NONE,
5503                 NULL, 0, "The response to this packet is in this packet", HFILL }},
5504         { &hf_smb2_time,
5505                 { "Time from request", "smb2.time", FT_RELATIVE_TIME, BASE_NONE,
5506                 NULL, 0, "Time between Request and Response for SMB2 cmds", HFILL }},
5507         { &hf_smb2_header_len,
5508                 { "Header Length", "smb2.header_len", FT_UINT16, BASE_DEC,
5509                 NULL, 0, "SMB2 Size of Header", HFILL }},
5510         { &hf_smb2_nt_status,
5511                 { "NT Status", "smb2.nt_status", FT_UINT32, BASE_HEX,
5512                 VALS(NT_errors), 0, "NT Status code", HFILL }},
5513         { &hf_smb2_seqnum,
5514                 { "Command Sequence Number", "smb2.seq_num", FT_INT64, BASE_DEC,
5515                 NULL, 0, "SMB2 Command Sequence Number", HFILL }},
5516         { &hf_smb2_tid,
5517                 { "Tree Id", "smb2.tid", FT_UINT32, BASE_HEX,
5518                 NULL, 0, "SMB2 Tree Id", HFILL }},
5519         { &hf_smb2_aid,
5520                 { "Async Id", "smb2.aid", FT_UINT64, BASE_HEX,
5521                 NULL, 0, "SMB2 Async Id", HFILL }},
5522         { &hf_smb2_sesid,
5523                 { "Session Id", "smb2.sesid", FT_UINT64, BASE_HEX,
5524                 NULL, 0, "SMB2 Session Id", HFILL }},
5525         { &hf_smb2_previous_sesid,
5526                 { "Previous Session Id", "smb2.previous_sesid", FT_UINT64, BASE_HEX,
5527                 NULL, 0, "SMB2 Previous Session Id", HFILL }},
5528         { &hf_smb2_chain_offset,
5529                 { "Chain Offset", "smb2.chain_offset", FT_UINT32, BASE_HEX,
5530                 NULL, 0, "SMB2 Chain Offset", HFILL }},
5531         { &hf_smb2_end_of_file,
5532                 { "End Of File", "smb2.eof", FT_UINT64, BASE_DEC,
5533                 NULL, 0, "SMB2 End Of File/File size", HFILL }},
5534         { &hf_smb2_nlinks,
5535                 { "Number of Links", "smb2.nlinks", FT_UINT32, BASE_DEC,
5536                 NULL, 0, "Number of links to this object", HFILL }},
5537         { &hf_smb2_file_id,
5538                 { "File Id", "smb2.file_id", FT_UINT64, BASE_HEX,
5539                 NULL, 0, "SMB2 File Id", HFILL }},
5540         { &hf_smb2_allocation_size,
5541                 { "Allocation Size", "smb2.allocation_size", FT_UINT64, BASE_DEC,
5542                 NULL, 0, "SMB2 Allocation Size for this object", HFILL }},
5543         { &hf_smb2_max_response_size,
5544                 { "Max Response Size", "smb2.max_response_size", FT_UINT32, BASE_DEC,
5545                 NULL, 0, "SMB2 Maximum response size", HFILL }},
5546         { &hf_smb2_setinfo_size,
5547                 { "Setinfo Size", "smb2.setinfo_size", FT_UINT32, BASE_DEC,
5548                 NULL, 0, "SMB2 setinfo size", HFILL }},
5549         { &hf_smb2_setinfo_offset,
5550                 { "Setinfo Offset", "smb2.setinfo_offset", FT_UINT16, BASE_HEX,
5551                 NULL, 0, "SMB2 setinfo offset", HFILL }},
5552         { &hf_smb2_max_ioctl_out_size,
5553                 { "Max Ioctl Out Size", "smb2.max_ioctl_out_size", FT_UINT32, BASE_DEC,
5554                 NULL, 0, "SMB2 Maximum ioctl out size", HFILL }},
5555         { &hf_smb2_max_ioctl_in_size,
5556                 { "Max Ioctl In Size", "smb2.max_ioctl_in_size", FT_UINT32, BASE_DEC,
5557                 NULL, 0, "SMB2 Maximum ioctl out size", HFILL }},
5558         { &hf_smb2_response_size,
5559                 { "Response Size", "smb2.response_size", FT_UINT32, BASE_DEC,
5560                 NULL, 0, "SMB2 response size", HFILL }},
5561         { &hf_smb2_required_buffer_size,
5562                 { "Required Buffer Size", "smb2.required_size", FT_UINT32, BASE_DEC,
5563                 NULL, 0, "SMB2 required buffer size", HFILL }},
5564         { &hf_smb2_pid,
5565                 { "Process Id", "smb2.pid", FT_UINT32, BASE_HEX,
5566                 NULL, 0, "SMB2 Process Id", HFILL }},
5567         { &hf_smb2_flags_response,
5568                 { "Response", "smb2.flags.response", FT_BOOLEAN, 32,
5569                 TFS(&tfs_flags_response), SMB2_FLAGS_RESPONSE, "Whether this is an SMB2 Request or Response", HFILL }},
5570         { &hf_smb2_flags_async_cmd,
5571                 { "Async command", "smb2.flags.async", FT_BOOLEAN, 32,
5572                 TFS(&tfs_flags_async_cmd), SMB2_FLAGS_ASYNC_CMD, NULL, HFILL }},
5573         { &hf_smb2_flags_dfs_op,
5574                 { "DFS operation", "smb2.flags.dfs", FT_BOOLEAN, 32,
5575                 TFS(&tfs_flags_dfs_op), SMB2_FLAGS_DFS_OP, NULL, HFILL }},
5576         { &hf_smb2_flags_chained,
5577                 { "Chained", "smb2.flags.chained", FT_BOOLEAN, 32,
5578                 TFS(&tfs_flags_chained), SMB2_FLAGS_CHAINED, "Whether the pdu continues a chain or not", HFILL }},
5579         { &hf_smb2_flags_signature,
5580                 { "Signing", "smb2.flags.signature", FT_BOOLEAN, 32,
5581                 TFS(&tfs_flags_signature), SMB2_FLAGS_SIGNATURE, "Whether the pdu is signed or not", HFILL }},
5582         { &hf_smb2_tree,
5583                 { "Tree", "smb2.tree", FT_STRING, BASE_NONE,
5584                 NULL, 0, "Name of the Tree/Share", HFILL }},
5585         { &hf_smb2_filename,
5586                 { "Filename", "smb2.filename", FT_STRING, BASE_NONE,
5587                 NULL, 0, "Name of the file", HFILL }},
5588         { &hf_smb2_filename_len,
5589                 { "Filename Length", "smb2.filename.len", FT_UINT32, BASE_DEC,
5590                 NULL, 0, "Length of the file name", HFILL }},
5591
5592         { &hf_smb2_security_blob_len,
5593                 { "Security Blob Length", "smb2.security_blob_len", FT_UINT16, BASE_DEC,
5594                 NULL, 0, "Security blob length", HFILL }},
5595
5596         { &hf_smb2_security_blob_offset,
5597                 { "Security Blob Offset", "smb2.security_blob_offset", FT_UINT16, BASE_HEX,
5598                 NULL, 0, "Offset into the SMB2 PDU of the blob", HFILL }},
5599
5600         { &hf_smb2_response_buffer_offset,
5601                 { "Response Buffer Offset", "smb2.response_buffer_offset", FT_UINT16, BASE_HEX,
5602                 NULL, 0, "Offset of the response buffer", HFILL }},
5603
5604         { &hf_smb2_data_offset,
5605                 { "Data Offset", "smb2.data_offset", FT_UINT16, BASE_HEX,
5606                 NULL, 0, "Offset to data", HFILL }},
5607
5608         { &hf_smb2_find_info_level,
5609                 { "Info Level", "smb2.find.infolevel", FT_UINT32, BASE_DEC,
5610                 VALS(smb2_find_info_levels), 0, "Find_Info Infolevel", HFILL }},
5611         { &hf_smb2_find_flags,
5612                 { "Find Flags", "smb2.find.flags", FT_UINT8, BASE_HEX,
5613                 NULL, 0, NULL, HFILL }},
5614
5615         { &hf_smb2_find_pattern,
5616                 { "Search Pattern", "smb2.find.pattern", FT_STRING, BASE_NONE,
5617                 NULL, 0, "Find pattern", HFILL }},
5618
5619         { &hf_smb2_find_info_blob,
5620                 { "Info", "smb2.security_blob", FT_BYTES, BASE_NONE,
5621                 NULL, 0, "Find Info", HFILL }},
5622
5623         { &hf_smb2_ea_size,
5624                 { "EA Size", "smb2.ea_size", FT_UINT32, BASE_DEC,
5625                 NULL, 0, "Size of EA data", HFILL }},
5626
5627         { &hf_smb2_class,
5628                 { "Class", "smb2.class", FT_UINT8, BASE_HEX,
5629                 VALS(smb2_class_vals), 0, "Info class", HFILL }},
5630
5631         { &hf_smb2_infolevel,
5632                 { "InfoLevel", "smb2.infolevel", FT_UINT8, BASE_HEX,
5633                 NULL, 0, "Infolevel", HFILL }},
5634
5635         { &hf_smb2_infolevel_file_info,
5636                 { "InfoLevel", "smb2.file_info.infolevel", FT_UINT8, BASE_HEX,
5637                 VALS(smb2_file_info_levels), 0, "File_Info Infolevel", HFILL }},
5638
5639         { &hf_smb2_infolevel_fs_info,
5640                 { "InfoLevel", "smb2.fs_info.infolevel", FT_UINT8, BASE_HEX,
5641                 VALS(smb2_fs_info_levels), 0, "Fs_Info Infolevel", HFILL }},
5642
5643         { &hf_smb2_infolevel_sec_info,
5644                 { "InfoLevel", "smb2.sec_info.infolevel", FT_UINT8, BASE_HEX,
5645                 VALS(smb2_sec_info_levels), 0, "Sec_Info Infolevel", HFILL }},
5646
5647         { &hf_smb2_write_length,
5648                 { "Write Length", "smb2.write_length", FT_UINT32, BASE_DEC,
5649                 NULL, 0, "Amount of data to write", HFILL }},
5650
5651         { &hf_smb2_read_length,
5652                 { "Read Length", "smb2.read_length", FT_UINT32, BASE_DEC,
5653                 NULL, 0, "Amount of data to read", HFILL }},
5654
5655         { &hf_smb2_read_remaining,
5656                 { "Read Remaining", "smb2.read_remaining", FT_UINT32, BASE_DEC,
5657                 NULL, 0, NULL, HFILL }},
5658
5659         { &hf_smb2_create_flags,
5660                 { "Create Flags", "smb2.create_flags", FT_UINT64, BASE_HEX,
5661                 NULL, 0, NULL, HFILL }},
5662
5663         { &hf_smb2_file_offset,
5664                 { "File Offset", "smb2.file_offset", FT_UINT64, BASE_DEC,
5665                 NULL, 0, NULL, HFILL }},
5666
5667         { &hf_smb2_security_blob,
5668                 { "Security Blob", "smb2.security_blob", FT_BYTES, BASE_NONE,
5669                 NULL, 0, "Security blob", HFILL }},
5670
5671         { &hf_smb2_ioctl_out_data,
5672                 { "Out Data", "smb2.ioctl.out", FT_NONE, BASE_NONE,
5673                 NULL, 0, "Ioctl Out", HFILL }},
5674
5675         { &hf_smb2_ioctl_in_data,
5676                 { "In Data", "smb2.ioctl.in", FT_NONE, BASE_NONE,
5677                 NULL, 0, "Ioctl In", HFILL }},
5678
5679         { &hf_smb2_server_guid,
5680           { "Server Guid", "smb2.server_guid", FT_GUID, BASE_NONE,
5681                 NULL, 0, "Server GUID", HFILL }},
5682
5683         { &hf_smb2_client_guid,
5684           { "Client Guid", "smb2.client_guid", FT_GUID, BASE_NONE,
5685                 NULL, 0, "Client GUID", HFILL }},
5686
5687         { &hf_smb2_object_id,
5688           { "ObjectId", "smb2.object_id", FT_GUID, BASE_NONE,
5689                 NULL, 0, "ObjectID for this FID", HFILL }},
5690
5691         { &hf_smb2_birth_volume_id,
5692           { "BirthVolumeId", "smb2.birth_volume_id", FT_GUID, BASE_NONE,
5693                 NULL, 0, "ObjectID for the volume where this FID was originally created", HFILL }},
5694
5695         { &hf_smb2_birth_object_id,
5696           { "BirthObjectId", "smb2.birth_object_id", FT_GUID, BASE_NONE,
5697                 NULL, 0, "ObjectID for this FID when it was originally created", HFILL }},
5698
5699         { &hf_smb2_domain_id,
5700           { "DomainId", "smb2.domain_id", FT_GUID, BASE_NONE,
5701                 NULL, 0, NULL, HFILL }},
5702
5703         { &hf_smb2_create_timestamp,
5704                 { "Create", "smb2.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
5705                 NULL, 0, "Time when this object was created", HFILL }},
5706
5707         { &hf_smb2_fid,
5708                 { "File Id", "smb2.fid", FT_GUID, BASE_NONE,
5709                 NULL, 0, "SMB2 File Id", HFILL }},
5710
5711         { &hf_smb2_write_data,
5712                 { "Write Data", "smb2.write_data", FT_BYTES, BASE_NONE,
5713                 NULL, 0, "SMB2 Data to be written", HFILL }},
5714
5715         { &hf_smb2_read_data,
5716                 { "Read Data", "smb2.read_data", FT_BYTES, BASE_NONE,
5717                 NULL, 0, "SMB2 Data that is read", HFILL }},
5718
5719         { &hf_smb2_last_access_timestamp,
5720                 { "Last Access", "smb2.last_access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
5721                 NULL, 0, "Time when this object was last accessed", HFILL }},
5722
5723         { &hf_smb2_last_write_timestamp,
5724                 { "Last Write", "smb2.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
5725                 NULL, 0, "Time when this object was last written to", HFILL }},
5726
5727         { &hf_smb2_last_change_timestamp,
5728                 { "Last Change", "smb2.last_change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
5729                 NULL, 0, "Time when this object was last changed", HFILL }},
5730
5731         { &hf_smb2_file_all_info,
5732                 { "SMB2_FILE_ALL_INFO", "smb2.smb2_file_all_info", FT_NONE, BASE_NONE,
5733                 NULL, 0, "SMB2_FILE_ALL_INFO structure", HFILL }},
5734
5735         { &hf_smb2_file_allocation_info,
5736                 { "SMB2_FILE_ALLOCATION_INFO", "smb2.smb2_file_allocation_info", FT_NONE, BASE_NONE,
5737                 NULL, 0, "SMB2_FILE_ALLOCATION_INFO structure", HFILL }},
5738
5739         { &hf_smb2_file_endoffile_info,
5740                 { "SMB2_FILE_ENDOFFILE_INFO", "smb2.smb2_file_endoffile_info", FT_NONE, BASE_NONE,
5741                 NULL, 0, "SMB2_FILE_ENDOFFILE_INFO structure", HFILL }},
5742
5743         { &hf_smb2_file_alternate_name_info,
5744                 { "SMB2_FILE_ALTERNATE_NAME_INFO", "smb2.smb2_file_alternate_name_info", FT_NONE, BASE_NONE,
5745                 NULL, 0, "SMB2_FILE_ALTERNATE_NAME_INFO structure", HFILL }},
5746
5747         { &hf_smb2_file_stream_info,
5748                 { "SMB2_FILE_STREAM_INFO", "smb2.smb2_file_stream_info", FT_NONE, BASE_NONE,
5749                 NULL, 0, "SMB2_FILE_STREAM_INFO structure", HFILL }},
5750
5751         { &hf_smb2_file_pipe_info,
5752                 { "SMB2_FILE_PIPE_INFO", "smb2.smb2_file_pipe_info", FT_NONE, BASE_NONE,
5753                 NULL, 0, "SMB2_FILE_PIPE_INFO structure", HFILL }},
5754
5755         { &hf_smb2_file_compression_info,
5756                 { "SMB2_FILE_COMPRESSION_INFO", "smb2.smb2_file_compression_info", FT_NONE, BASE_NONE,
5757                 NULL, 0, "SMB2_FILE_COMPRESSION_INFO structure", HFILL }},
5758
5759         { &hf_smb2_file_basic_info,
5760                 { "SMB2_FILE_BASIC_INFO", "smb2.smb2_file_basic_info", FT_NONE, BASE_NONE,
5761                 NULL, 0, "SMB2_FILE_BASIC_INFO structure", HFILL }},
5762
5763         { &hf_smb2_file_standard_info,
5764                 { "SMB2_FILE_STANDARD_INFO", "smb2.smb2_file_standard_info", FT_NONE, BASE_NONE,
5765                 NULL, 0, "SMB2_FILE_STANDARD_INFO structure", HFILL }},
5766
5767         { &hf_smb2_file_internal_info,
5768                 { "SMB2_FILE_INTERNAL_INFO", "smb2.smb2_file_internal_info", FT_NONE, BASE_NONE,
5769                 NULL, 0, "SMB2_FILE_INTERNAL_INFO structure", HFILL }},
5770
5771         { &hf_smb2_file_mode_info,
5772                 { "SMB2_FILE_MODE_INFO", "smb2.smb2_file_mode_info", FT_NONE, BASE_NONE,
5773                 NULL, 0, "SMB2_FILE_MODE_INFO structure", HFILL }},
5774
5775         { &hf_smb2_file_alignment_info,
5776                 { "SMB2_FILE_ALIGNMENT_INFO", "smb2.smb2_file_alignment_info", FT_NONE, BASE_NONE,
5777                 NULL, 0, "SMB2_FILE_ALIGNMENT_INFO structure", HFILL }},
5778
5779         { &hf_smb2_file_position_info,
5780                 { "SMB2_FILE_POSITION_INFO", "smb2.smb2_file_position_info", FT_NONE, BASE_NONE,
5781                 NULL, 0, "SMB2_FILE_POSITION_INFO structure", HFILL }},
5782
5783         { &hf_smb2_file_access_info,
5784                 { "SMB2_FILE_ACCESS_INFO", "smb2.smb2_file_access_info", FT_NONE, BASE_NONE,
5785                 NULL, 0, "SMB2_FILE_ACCESS_INFO structure", HFILL }},
5786
5787         { &hf_smb2_file_ea_info,
5788                 { "SMB2_FILE_EA_INFO", "smb2.smb2_file_ea_info", FT_NONE, BASE_NONE,
5789                 NULL, 0, "SMB2_FILE_EA_INFO structure", HFILL }},
5790
5791         { &hf_smb2_file_network_open_info,
5792                 { "SMB2_FILE_NETWORK_OPEN_INFO", "smb2.smb2_file_network_open_info", FT_NONE, BASE_NONE,
5793                 NULL, 0, "SMB2_FILE_NETWORK_OPEN_INFO structure", HFILL }},
5794
5795         { &hf_smb2_file_attribute_tag_info,
5796                 { "SMB2_FILE_ATTRIBUTE_TAG_INFO", "smb2.smb2_file_attribute_tag_info", FT_NONE, BASE_NONE,
5797                 NULL, 0, "SMB2_FILE_ATTRIBUTE_TAG_INFO structure", HFILL }},
5798
5799         { &hf_smb2_file_disposition_info,
5800                 { "SMB2_FILE_DISPOSITION_INFO", "smb2.smb2_file_disposition_info", FT_NONE, BASE_NONE,
5801                 NULL, 0, "SMB2_FILE_DISPOSITION_INFO structure", HFILL }},
5802
5803         { &hf_smb2_file_info_0f,
5804                 { "SMB2_FILE_INFO_0f", "smb2.smb2_file_info_0f", FT_NONE, BASE_NONE,
5805                 NULL, 0, "SMB2_FILE_INFO_0f structure", HFILL }},
5806
5807         { &hf_smb2_file_rename_info,
5808                 { "SMB2_FILE_RENAME_INFO", "smb2.smb2_file_rename_info", FT_NONE, BASE_NONE,
5809                 NULL, 0, "SMB2_FILE_RENAME_INFO structure", HFILL }},
5810
5811         { &hf_smb2_fs_info_01,
5812                 { "SMB2_FS_INFO_01", "smb2.smb2_fs_info_01", FT_NONE, BASE_NONE,
5813                 NULL, 0, "SMB2_FS_INFO_01 structure", HFILL }},
5814
5815         { &hf_smb2_fs_info_03,
5816                 { "SMB2_FS_INFO_03", "smb2.smb2_fs_info_03", FT_NONE, BASE_NONE,
5817                 NULL, 0, "SMB2_FS_INFO_03 structure", HFILL }},
5818
5819         { &hf_smb2_fs_info_04,
5820                 { "SMB2_FS_INFO_04", "smb2.smb2_fs_info_04", FT_NONE, BASE_NONE,
5821                 NULL, 0, "SMB2_FS_INFO_04 structure", HFILL }},
5822
5823         { &hf_smb2_fs_info_05,
5824                 { "SMB2_FS_INFO_05", "smb2.smb2_fs_info_05", FT_NONE, BASE_NONE,
5825                 NULL, 0, "SMB2_FS_INFO_05 structure", HFILL }},
5826
5827         { &hf_smb2_fs_info_06,
5828                 { "SMB2_FS_INFO_06", "smb2.smb2_fs_info_06", FT_NONE, BASE_NONE,
5829                 NULL, 0, "SMB2_FS_INFO_06 structure", HFILL }},
5830
5831         { &hf_smb2_fs_info_07,
5832                 { "SMB2_FS_INFO_07", "smb2.smb2_fs_info_07", FT_NONE, BASE_NONE,
5833                 NULL, 0, "SMB2_FS_INFO_07 structure", HFILL }},
5834
5835         { &hf_smb2_fs_objectid_info,
5836                 { "SMB2_FS_OBJECTID_INFO", "smb2.smb2_fs_objectid_info", FT_NONE, BASE_NONE,
5837                 NULL, 0, "SMB2_FS_OBJECTID_INFO structure", HFILL }},
5838
5839         { &hf_smb2_sec_info_00,
5840                 { "SMB2_SEC_INFO_00", "smb2.smb2_sec_info_00", FT_NONE, BASE_NONE,
5841                 NULL, 0, "SMB2_SEC_INFO_00 structure", HFILL }},
5842
5843         { &hf_smb2_disposition_delete_on_close,
5844           { "Delete on close", "smb2.disposition.delete_on_close", FT_BOOLEAN, 8,
5845                 TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }},
5846
5847
5848         { &hf_smb2_create_disposition,
5849                 { "Disposition", "smb2.create.disposition", FT_UINT32, BASE_DEC,
5850                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
5851
5852         { &hf_smb2_create_action,
5853                 { "Create Action", "smb2.create.action", FT_UINT32, BASE_DEC,
5854                 VALS(oa_open_vals), 0, NULL, HFILL }},
5855
5856         { &hf_smb2_extrainfo,
5857                 { "ExtraInfo", "smb2.create.extrainfo", FT_NONE, BASE_NONE,
5858                 NULL, 0, "Create ExtraInfo", HFILL }},
5859
5860         { &hf_smb2_create_chain_offset,
5861                 { "Chain Offset", "smb2.create.chain_offset", FT_UINT32, BASE_HEX,
5862                 NULL, 0, "Offset to next entry in chain or 0", HFILL }},
5863
5864         { &hf_smb2_create_chain_data,
5865                 { "Data", "smb2.create.chain_data", FT_NONE, BASE_NONE,
5866                 NULL, 0, "Chain Data", HFILL }},
5867
5868         { &hf_smb2_FILE_OBJECTID_BUFFER,
5869                 { "FILE_OBJECTID_BUFFER", "smb2.FILE_OBJECTID_BUFFER", FT_NONE, BASE_NONE,
5870                 NULL, 0, "A FILE_OBJECTID_BUFFER structure", HFILL }},
5871
5872         { &hf_smb2_data_length,
5873                 { "Data Length", "smb2.create.data_length", FT_UINT32, BASE_DEC,
5874                 NULL, 0, "Length Data or 0", HFILL }},
5875
5876         { &hf_smb2_next_offset,
5877                 { "Next Offset", "smb2.next_offset", FT_UINT32, BASE_DEC,
5878                 NULL, 0, "Offset to next buffer or 0", HFILL }},
5879
5880         { &hf_smb2_current_time,
5881                 { "Current Time", "smb2.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
5882                 NULL, 0, "Current Time at server", HFILL }},
5883
5884         { &hf_smb2_boot_time,
5885                 { "Boot Time", "smb2.boot_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
5886                 NULL, 0, "Boot Time at server", HFILL }},
5887
5888         { &hf_smb2_ea_flags,
5889                 { "EA Flags", "smb2.ea.flags", FT_UINT8, BASE_HEX,
5890                 NULL, 0, NULL, HFILL }},
5891
5892         { &hf_smb2_ea_name_len,
5893                 { "EA Name Length", "smb2.ea.name_len", FT_UINT8, BASE_DEC,
5894                 NULL, 0, NULL, HFILL }},
5895
5896         { &hf_smb2_ea_data_len,
5897                 { "EA Data Length", "smb2.ea.data_len", FT_UINT8, BASE_DEC,
5898                 NULL, 0, NULL, HFILL }},
5899
5900         { &hf_smb2_delete_pending,
5901                 { "Delete Pending", "smb2.delete_pending", FT_UINT8, BASE_DEC,
5902                 NULL, 0, NULL, HFILL }},
5903
5904         { &hf_smb2_is_directory,
5905                 { "Is Directory", "smb2.is_directory", FT_UINT8, BASE_DEC,
5906                 NULL, 0, "Is this a directory?", HFILL }},
5907
5908         { &hf_smb2_oplock,
5909                 { "Oplock", "smb2.create.oplock", FT_UINT8, BASE_HEX,
5910                 VALS(oplock_vals), 0, "Oplock type", HFILL }},
5911
5912         { &hf_smb2_close_flags,
5913                 { "Close Flags", "smb2.close.flags", FT_UINT16, BASE_HEX,
5914                 NULL, 0, "close flags", HFILL }},
5915
5916         { &hf_smb2_notify_flags,
5917                 { "Notify Flags", "smb2.notify.flags", FT_UINT16, BASE_HEX,
5918                 NULL, 0, NULL, HFILL }},
5919
5920         { &hf_smb2_buffer_code_len,
5921                 { "Length", "smb2.buffer_code.length", FT_UINT16, BASE_DEC,
5922                 NULL, 0, "Length of fixed portion of PDU", HFILL }},
5923
5924         { &hf_smb2_olb_length,
5925                 { "Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
5926                 NULL, 0, "Length of the buffer", HFILL }},
5927
5928         { &hf_smb2_olb_offset,
5929                 { "Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
5930                 NULL, 0, "Offset to the buffer", HFILL }},
5931
5932         { &hf_smb2_buffer_code_flags_dyn,
5933                 { "Dynamic Part", "smb2.buffer_code.dynamic", FT_BOOLEAN, 16,
5934                 NULL, 0x0001, "Whether a dynamic length blob follows", HFILL }},
5935
5936         { &hf_smb2_ea_data,
5937                 { "EA Data", "smb2.ea.data", FT_STRING, BASE_NONE,
5938                 NULL, 0, NULL, HFILL }},
5939
5940         { &hf_smb2_ea_name,
5941                 { "EA Name", "smb2.ea.name", FT_STRING, BASE_NONE,
5942                 NULL, 0, NULL, HFILL }},
5943
5944         { &hf_smb2_impersonation_level,
5945                 { "Impersonation", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
5946                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
5947
5948         { &hf_smb2_ioctl_function,
5949                 { "Function", "smb2.ioctl.function", FT_UINT32, BASE_HEX,
5950                 VALS(smb2_ioctl_vals), 0, "Ioctl function", HFILL }},
5951
5952         { &hf_smb2_ioctl_function_device,
5953                 { "Device", "smb2.ioctl.function.device", FT_UINT32, BASE_HEX,
5954                 VALS(smb2_ioctl_device_vals), 0xffff0000, "Device for Ioctl", HFILL }},
5955
5956         { &hf_smb2_ioctl_function_access,
5957                 { "Access", "smb2.ioctl.function.access", FT_UINT32, BASE_HEX,
5958                 VALS(smb2_ioctl_access_vals), 0x0000c000, "Access for Ioctl", HFILL }},
5959
5960         { &hf_smb2_ioctl_function_function,
5961                 { "Function", "smb2.ioctl.function.function", FT_UINT32, BASE_HEX,
5962                 NULL, 0x00003ffc, "Function for Ioctl", HFILL }},
5963
5964         { &hf_smb2_ioctl_function_method,
5965                 { "Method", "smb2.ioctl.function.method", FT_UINT32, BASE_HEX,
5966                 VALS(smb2_ioctl_method_vals), 0x00000003, "Method for Ioctl", HFILL }},
5967
5968         { &hf_smb2_ioctl_shadow_copy_num_volumes,
5969                 { "Num Volumes", "smb2.ioctl.shadow_copy.num_volumes", FT_UINT32, BASE_DEC,
5970                 NULL, 0, "Number of shadow copy volumes", HFILL }},
5971
5972         { &hf_smb2_ioctl_shadow_copy_num_labels,
5973                 { "Num Labels", "smb2.ioctl.shadow_copy.num_labels", FT_UINT32, BASE_DEC,
5974                 NULL, 0, "Number of shadow copy labels", HFILL }},
5975
5976         { &hf_smb2_ioctl_shadow_copy_label,
5977                 { "Label", "smb2.ioctl.shadow_copy.label", FT_STRING, BASE_NONE,
5978                 NULL, 0, "Shadow copy label", HFILL }},
5979
5980         { &hf_smb2_compression_format,
5981                 { "Compression Format", "smb2.compression_format", FT_UINT16, BASE_DEC,
5982                 VALS(compression_format_vals), 0, "Compression to use", HFILL }},
5983
5984         { &hf_smb2_share_type,
5985                 { "Share Type", "smb2.share_type", FT_UINT16, BASE_DEC,
5986                 VALS(smb2_share_type_vals), 0, "Type of share", HFILL }},
5987
5988         { &hf_smb2_epoch,
5989                 { "Epoch", "smb2.epoch", FT_UINT16, BASE_DEC,
5990                 NULL, 0, NULL, HFILL }},
5991
5992         { &hf_smb2_credits_requested,
5993                 { "Credits requested", "smb2.credits.requested", FT_UINT16, BASE_DEC,
5994                 NULL, 0, NULL, HFILL }},
5995
5996         { &hf_smb2_credits_granted,
5997                 { "Credits granted", "smb2.credits.granted", FT_UINT16, BASE_DEC,
5998                 NULL, 0, NULL, HFILL }},
5999
6000         { &hf_smb2_dialect_count,
6001                 { "Dialect count", "smb2.dialect_count", FT_UINT16, BASE_DEC,
6002                 NULL, 0, NULL, HFILL }},
6003
6004         { &hf_smb2_dialect,
6005                 { "Dialect", "smb2.dialect", FT_UINT16, BASE_HEX,
6006                 NULL, 0, NULL, HFILL }},
6007
6008         { &hf_smb2_security_mode,
6009                 { "Security mode", "smb2.sec_mode", FT_UINT8, BASE_HEX,
6010                 NULL, 0, NULL, HFILL }},
6011
6012         { &hf_smb2_session_flags,
6013                 { "Session Flags", "smb2.session_flags", FT_UINT16, BASE_HEX,
6014                 NULL, 0, NULL, HFILL }},
6015
6016         { &hf_smb2_lock_count,
6017                 { "Lock Count", "smb2.lock_count", FT_UINT16, BASE_DEC,
6018                 NULL, 0, NULL, HFILL }},
6019
6020         { &hf_smb2_capabilities,
6021                 { "Capabilities", "smb2.capabilities", FT_UINT32, BASE_HEX,
6022                 NULL, 0, NULL, HFILL }},
6023
6024         { &hf_smb2_ioctl_shadow_copy_count,
6025                 { "Count", "smb2.ioctl.shadow_copy.count", FT_UINT32, BASE_DEC,
6026                 NULL, 0, "Number of bytes for shadow copy label strings", HFILL }},
6027
6028         { &hf_smb2_auth_frame,
6029                 { "Authenticated in Frame", "smb2.auth_frame", FT_UINT32, BASE_DEC,
6030                 NULL, 0, "Which frame this user was authenticated in", HFILL }},
6031
6032         { &hf_smb2_tcon_frame,
6033                 { "Connected in Frame", "smb2.tcon_frame", FT_UINT32, BASE_DEC,
6034                 NULL, 0, "Which frame this share was connected in", HFILL }},
6035
6036         { &hf_smb2_tag,
6037                 { "Tag", "smb2.tag", FT_STRING, BASE_NONE,
6038                 NULL, 0, "Tag of chain entry", HFILL }},
6039
6040         { &hf_smb2_acct_name,
6041                 { "Account", "smb2.acct", FT_STRING, BASE_NONE,
6042                 NULL, 0, "Account Name", HFILL }},
6043
6044         { &hf_smb2_domain_name,
6045                 { "Domain", "smb2.domain", FT_STRING, BASE_NONE,
6046                 NULL, 0, "Domain Name", HFILL }},
6047
6048         { &hf_smb2_host_name,
6049                 { "Host", "smb2.host", FT_STRING, BASE_NONE,
6050                 NULL, 0, "Host Name", HFILL }},
6051
6052         { &hf_smb2_signature,
6053                 { "Signature", "smb2.signature", FT_BYTES, BASE_NONE,
6054                 NULL, 0, NULL, HFILL }},
6055
6056         { &hf_smb2_unknown,
6057                 { "unknown", "smb2.unknown", FT_BYTES, BASE_NONE,
6058                 NULL, 0, "Unknown bytes", HFILL }},
6059
6060         { &hf_smb2_unknown_timestamp,
6061                 { "Timestamp", "smb2.unknown.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
6062                 NULL, 0, "Unknown timestamp", HFILL }},
6063
6064         { &hf_smb2_ses_flags_guest,
6065                 { "Guest", "smb2.ses_flags.guest", FT_BOOLEAN, 16,
6066                 NULL, SES_FLAGS_GUEST, NULL, HFILL }},
6067
6068         { &hf_smb2_ses_flags_null,
6069                 { "Null", "smb2.ses_flags.null", FT_BOOLEAN, 16,
6070                 NULL, SES_FLAGS_NULL, NULL, HFILL }},
6071
6072         { &hf_smb2_secmode_flags_sign_required,
6073                 { "Signing required", "smb2.sec_mode.sign_required", FT_BOOLEAN, 8,
6074                 NULL, NEGPROT_SIGN_REQ, "Is signing required", HFILL }},
6075
6076         { &hf_smb2_secmode_flags_sign_enabled,
6077                 { "Signing enabled", "smb2.sec_mode.sign_enabled", FT_BOOLEAN, 8,
6078                 NULL, NEGPROT_SIGN_ENABLED, "Is signing enabled", HFILL }},
6079
6080         { &hf_smb2_cap_dfs,
6081                 { "DFS", "smb2.capabilities.dfs", FT_BOOLEAN, 32,
6082                 TFS(&tfs_cap_dfs), NEGPROT_CAP_DFS, "If the host supports dfs", HFILL }},
6083
6084         { &hf_smb2_max_trans_size,
6085                 { "Max Transaction Size", "smb2.max_trans_size", FT_UINT32, BASE_DEC,
6086                 NULL, 0, "Maximum size of a transaction", HFILL }},
6087
6088         { &hf_smb2_max_read_size,
6089                 { "Max Read Size", "smb2.max_read_size", FT_UINT32, BASE_DEC,
6090                 NULL, 0, "Maximum size of a read", HFILL }},
6091
6092         { &hf_smb2_max_write_size,
6093                 { "Max Write Size", "smb2.max_write_size", FT_UINT32, BASE_DEC,
6094                 NULL, 0, "Maximum size of a write", HFILL }},
6095
6096         { &hf_smb2_vcnum,
6097                 { "VC Num", "smb2.num_vc", FT_UINT8, BASE_DEC,
6098                 NULL, 0, "Number of VCs", HFILL }},
6099
6100         { &hf_smb2_channel,
6101                 { "Channel", "smb2.channel", FT_UINT32, BASE_DEC,
6102                 NULL, 0, NULL, HFILL }},
6103
6104         { &hf_smb2_share_flags,
6105                 { "Share flags", "smb2.share_flags", FT_UINT32, BASE_HEX,
6106                 NULL, 0, "share flags", HFILL }},
6107
6108         { &hf_smb2_share_flags_dfs,
6109                 { "dfs", "smb2.share_flags.dfs", FT_BOOLEAN, 32,
6110                 NULL, SHARE_FLAGS_dfs, NULL, HFILL }},
6111
6112         { &hf_smb2_share_flags_dfs_root,
6113                 { "dfs_root", "smb2.share_flags.dfs_root", FT_BOOLEAN, 32,
6114                 NULL, SHARE_FLAGS_dfs_root, NULL, HFILL }},
6115
6116         { &hf_smb2_share_flags_restrict_exclusive_opens,
6117                 { "restrict_exclusive_opens", "smb2.share_flags.restrict_exclusive_opens", FT_BOOLEAN, 32,
6118                 NULL, SHARE_FLAGS_restrict_exclusive_opens, NULL, HFILL }},
6119
6120         { &hf_smb2_share_flags_force_shared_delete,
6121                 { "force_shared_delete", "smb2.share_flags.force_shared_delete", FT_BOOLEAN, 32,
6122                 NULL, SHARE_FLAGS_force_shared_delete, NULL, HFILL }},
6123
6124         { &hf_smb2_share_flags_allow_namespace_caching,
6125                 { "allow_namespace_caching", "smb2.share_flags.allow_namespace_caching", FT_BOOLEAN, 32,
6126                 NULL, SHARE_FLAGS_allow_namespace_caching, NULL, HFILL }},
6127
6128         { &hf_smb2_share_flags_access_based_dir_enum,
6129                 { "access_based_dir_enum", "smb2.share_flags.access_based_dir_enum", FT_BOOLEAN, 32,
6130                 NULL, SHARE_FLAGS_access_based_dir_enum, NULL, HFILL }},
6131
6132         { &hf_smb2_share_caching,
6133                 { "Caching policy", "smb2.share.caching", FT_UINT32, BASE_HEX,
6134                 VALS(share_cache_vals), 0, NULL, HFILL }},
6135
6136         { &hf_smb2_share_caps,
6137                 { "Share Capabilities", "smb2.share_caps", FT_UINT32, BASE_HEX,
6138                 NULL, 0, NULL, HFILL }},
6139
6140         { &hf_smb2_ioctl_flags,
6141                 { "Flags", "smb2.ioctl.flags", FT_UINT32, BASE_HEX,
6142                 NULL, 0, NULL, HFILL }},
6143
6144         { &hf_smb2_min_count,
6145                 { "Min Count", "smb2.min_count", FT_UINT32, BASE_DEC,
6146                 NULL, 0, NULL, HFILL }},
6147
6148         { &hf_smb2_remaining_bytes,
6149                 { "Remaining Bytes", "smb2.remaining_bytes", FT_UINT32, BASE_DEC,               NULL, 0, NULL, HFILL }},
6150
6151         { &hf_smb2_channel_info_offset,
6152                 { "Channel Info Offset", "smb2.channel_info_offset", FT_UINT16, BASE_DEC,
6153                 NULL, 0, NULL, HFILL }},
6154
6155         { &hf_smb2_channel_info_length,
6156                 { "Channel Info Length", "smb2.channel_info_length", FT_UINT16, BASE_DEC,
6157                 NULL, 0, NULL, HFILL }},
6158
6159         { &hf_smb2_share_caps_dfs,
6160                 { "dfs", "smb2.share_caps.dfs", FT_BOOLEAN, 32,
6161                 NULL, SHARE_CAPS_DFS, NULL, HFILL }},
6162
6163         { &hf_smb2_ioctl_is_fsctl,
6164                 { "Is FSCTL", "smb2.ioctl.is_fsctl", FT_BOOLEAN, 32,
6165                 NULL, 0x00000001, NULL, HFILL }},
6166
6167         { &hf_smb2_output_buffer_len,
6168                 { "Output Buffer Length", "smb2.output_buffer_len", FT_UINT16, BASE_DEC,
6169                 NULL, 0, NULL, HFILL }},
6170
6171         { &hf_smb2_close_pq_attrib,
6172                 { "PostQuery Attrib", "smb2.close.pq_attrib", FT_BOOLEAN, 16,
6173                 NULL, 0x0001, NULL, HFILL }},
6174
6175         { &hf_smb2_notify_watch_tree,
6176                 { "Watch Tree", "smb2.notify.watch_tree", FT_BOOLEAN, 16,
6177                 NULL, 0x0001, NULL, HFILL }},
6178
6179         { &hf_smb2_notify_out_data,
6180                 { "Out Data", "smb2.notify.out", FT_NONE, BASE_NONE,
6181                 NULL, 0, NULL, HFILL }},
6182
6183         { &hf_smb2_find_flags_restart_scans,
6184                 { "Restart Scans", "smb2.find.restart_scans", FT_BOOLEAN, 8,
6185                 NULL, SMB2_FIND_FLAG_RESTART_SCANS, NULL, HFILL }},
6186
6187         { &hf_smb2_find_flags_single_entry,
6188                 { "Single Entry", "smb2.find.single_entry", FT_BOOLEAN, 8,
6189                 NULL, SMB2_FIND_FLAG_SINGLE_ENTRY, NULL, HFILL }},
6190
6191         { &hf_smb2_find_flags_index_specified,
6192                 { "Index Specified", "smb2.find.index_specified", FT_BOOLEAN, 8,
6193                 NULL, SMB2_FIND_FLAG_INDEX_SPECIFIED, NULL, HFILL }},
6194
6195         { &hf_smb2_find_flags_reopen,
6196                 { "Reopen", "smb2.find.reopen", FT_BOOLEAN, 8,
6197                 NULL, SMB2_FIND_FLAG_REOPEN, NULL, HFILL }},
6198
6199         { &hf_smb2_file_index,
6200                 { "File Index", "smb2.file_index", FT_UINT32, BASE_HEX,
6201                 NULL, 0, NULL, HFILL }},
6202
6203         { &hf_smb2_file_directory_info,
6204                 { "FileDirectoryInfo", "smb2.find.file_directory_info", FT_NONE, BASE_NONE,
6205                 NULL, 0, NULL, HFILL }},
6206
6207         { &hf_smb2_full_directory_info,
6208                 { "FullDirectoryInfo", "smb2.find.full_directory_info", FT_NONE, BASE_NONE,
6209                 NULL, 0, NULL, HFILL }},
6210
6211         { &hf_smb2_both_directory_info,
6212                 { "FileBothDirectoryInfo", "smb2.find.both_directory_info", FT_NONE, BASE_NONE,
6213                 NULL, 0, NULL, HFILL }},
6214
6215         { &hf_smb2_id_both_directory_info,
6216                 { "FileIdBothDirectoryInfo", "smb2.find.id_both_directory_info", FT_NONE, BASE_NONE,
6217                 NULL, 0, NULL, HFILL }},
6218
6219         { &hf_smb2_short_name_len,
6220                 { "Short Name Length", "smb2.short_name_len", FT_UINT8, BASE_DEC,
6221                 NULL, 0, NULL, HFILL }},
6222  
6223         { &hf_smb2_short_name,
6224                 { "Short Name", "smb2.shortname", FT_STRING, BASE_NONE,
6225                 NULL, 0, NULL, HFILL }},
6226         { &hf_smb2_file_name_info,
6227                 { "FileNameInfo", "smb2.find.name_info", FT_NONE, BASE_NONE,
6228                 NULL, 0, NULL, HFILL }},
6229
6230         { &hf_smb2_lock_info,
6231                 { "Lock Info", "smb2.lock_info", FT_NONE, BASE_NONE,
6232                 NULL, 0, NULL, HFILL }},
6233
6234         { &hf_smb2_lock_length,
6235                 { "Length", "smb2.lock_length", FT_UINT64, BASE_DEC,
6236                 NULL, 0, NULL, HFILL }},
6237
6238         { &hf_smb2_lock_flags,
6239                 { "Flags", "smb2.lock_flags", FT_UINT32, BASE_HEX,
6240                 NULL, 0, NULL, HFILL }},
6241
6242         { &hf_smb2_lock_flags_shared,
6243                 { "Shared", "smb2.lock_flags.shared", FT_BOOLEAN, 32,
6244                 NULL, 0x00000001, NULL, HFILL }},
6245
6246         { &hf_smb2_lock_flags_exclusive,
6247                 { "Exclusive", "smb2.lock_flags.exclusive", FT_BOOLEAN, 32,
6248                 NULL, 0x00000002, NULL, HFILL }},
6249
6250         { &hf_smb2_lock_flags_unlock,
6251                 { "Unlock", "smb2.lock_flags.unlock", FT_BOOLEAN, 32,
6252                 NULL, 0x00000004, NULL, HFILL }},
6253
6254         { &hf_smb2_lock_flags_fail_immediately,
6255                 { "Fail Immediately", "smb2.lock_flags.fail_immediately", FT_BOOLEAN, 32,
6256                 NULL, 0x00000010, NULL, HFILL }},
6257
6258         { &hf_smb2_error_reserved,
6259                 { "Reserved", "smb2.error.reserved", FT_UINT16, BASE_HEX,
6260                 NULL, 0, NULL, HFILL }},
6261
6262         { &hf_smb2_error_byte_count,
6263                 { "Byte Count", "smb2.error.byte_count", FT_UINT32, BASE_DEC,
6264                 NULL, 0, NULL, HFILL }},
6265
6266         { &hf_smb2_error_data,
6267                 { "Error Data", "smb2.error.data", FT_BYTES, BASE_NONE,
6268                 NULL, 0, NULL, HFILL }},
6269
6270         };
6271
6272         static gint *ett[] = {
6273                 &ett_smb2,
6274                 &ett_smb2_ea,
6275                 &ett_smb2_olb,
6276                 &ett_smb2_header,
6277                 &ett_smb2_command,
6278                 &ett_smb2_secblob,
6279                 &ett_smb2_file_basic_info,
6280                 &ett_smb2_file_standard_info,
6281                 &ett_smb2_file_internal_info,
6282                 &ett_smb2_file_ea_info,
6283                 &ett_smb2_file_access_info,
6284                 &ett_smb2_file_rename_info,
6285                 &ett_smb2_file_disposition_info,
6286                 &ett_smb2_file_position_info,
6287                 &ett_smb2_file_info_0f,
6288                 &ett_smb2_file_mode_info,
6289                 &ett_smb2_file_alignment_info,
6290                 &ett_smb2_file_all_info,
6291                 &ett_smb2_file_allocation_info,
6292                 &ett_smb2_file_endoffile_info,
6293                 &ett_smb2_file_alternate_name_info,
6294                 &ett_smb2_file_stream_info,
6295                 &ett_smb2_file_pipe_info,
6296                 &ett_smb2_file_compression_info,
6297                 &ett_smb2_file_network_open_info,
6298                 &ett_smb2_file_attribute_tag_info,
6299                 &ett_smb2_fs_info_01,
6300                 &ett_smb2_fs_info_03,
6301                 &ett_smb2_fs_info_04,
6302                 &ett_smb2_fs_info_05,
6303                 &ett_smb2_fs_info_06,
6304                 &ett_smb2_fs_info_07,
6305                 &ett_smb2_fs_objectid_info,
6306                 &ett_smb2_sec_info_00,
6307                 &ett_smb2_tid_tree,
6308                 &ett_smb2_sesid_tree,
6309                 &ett_smb2_create_chain_element,
6310                 &ett_smb2_MxAc_buffer,
6311                 &ett_smb2_ioctl_function,
6312                 &ett_smb2_FILE_OBJECTID_BUFFER,
6313                 &ett_smb2_flags,
6314                 &ett_smb2_sec_mode,
6315                 &ett_smb2_capabilities,
6316                 &ett_smb2_ses_flags,
6317                 &ett_smb2_share_flags,
6318                 &ett_smb2_share_caps,
6319                 &ett_smb2_ioctl_flags,
6320                 &ett_smb2_close_flags,
6321                 &ett_smb2_notify_flags,
6322                 &ett_smb2_find_flags,
6323                 &ett_smb2_file_directory_info,
6324                 &ett_smb2_both_directory_info,
6325                 &ett_smb2_id_both_directory_info,
6326                 &ett_smb2_full_directory_info,
6327                 &ett_smb2_file_name_info,
6328                 &ett_smb2_lock_info,
6329                 &ett_smb2_lock_flags,
6330         };
6331
6332         proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
6333             "SMB2", "smb2");
6334         proto_register_subtree_array(ett, array_length(ett));
6335         proto_register_field_array(proto_smb2, hf, array_length(hf));
6336
6337         register_heur_dissector_list("smb2_heur_subdissectors", &smb2_heur_subdissector_list);
6338         smb2_tap = register_tap("smb2");
6339 }
6340
6341 void
6342 proto_reg_handoff_smb2(void)
6343 {
6344         gssapi_handle = find_dissector("gssapi");
6345         ntlmssp_handle = find_dissector("ntlmssp");
6346         heur_dissector_add("netbios", dissect_smb2_heur, proto_smb2);
6347 }