* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
-
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
#include <epan/to_str.h>
#include <epan/asn1.h>
#include <epan/reassemble.h>
+#include <epan/uat.h>
#include "packet-smb2.h"
#include "packet-ntlmssp.h"
#include "packet-smb-common.h"
#include "packet-dcerpc-nt.h"
+#include "read_keytab_file.h"
+
#include <wsutil/wsgcrypt.h>
#define NT_STATUS_PENDING 0x00000103
static int hf_smb2_max_ioctl_out_size = -1;
static int hf_smb2_flags = -1;
static int hf_smb2_required_buffer_size = -1;
-static int hf_smb2_getinfo_size = -1;
-static int hf_smb2_getinfo_offset = -1;
+static int hf_smb2_getinfo_input_size = -1;
+static int hf_smb2_getinfo_input_offset = -1;
static int hf_smb2_getinfo_additional = -1;
static int hf_smb2_getinfo_flags = -1;
static int hf_smb2_setinfo_size = -1;
static int hf_smb2_negotiate_context_data_length = -1;
static int hf_smb2_negotiate_context_offset = -1;
static int hf_smb2_negotiate_context_count = -1;
+static int hf_smb2_hash_alg_count = -1;
+static int hf_smb2_hash_algorithm = -1;
+static int hf_smb2_salt_length = -1;
+static int hf_smb2_salt = -1;
+static int hf_smb2_cipher_count = -1;
+static int hf_smb2_cipher_id = -1;
static int hf_smb2_ea_size = -1;
static int hf_smb2_ea_flags = -1;
static int hf_smb2_ea_name_len = -1;
static int hf_smb2_ea_data_len = -1;
static int hf_smb2_ea_name = -1;
static int hf_smb2_ea_data = -1;
+static int hf_smb2_position_information = -1;
+static int hf_smb2_mode_information = -1;
+static int hf_smb2_mode_file_write_through = -1;
+static int hf_smb2_mode_file_sequential_only = -1;
+static int hf_smb2_mode_file_no_intermediate_buffering = -1;
+static int hf_smb2_mode_file_synchronous_io_alert = -1;
+static int hf_smb2_mode_file_synchronous_io_nonalert = -1;
+static int hf_smb2_mode_file_delete_on_close = -1;
+static int hf_smb2_alignment_information = -1;
static int hf_smb2_buffer_code = -1;
static int hf_smb2_buffer_code_len = -1;
static int hf_smb2_buffer_code_flags_dyn = -1;
static int hf_smb2_ioctl_function_method = -1;
static int hf_smb2_ioctl_resiliency_timeout = -1;
static int hf_smb2_ioctl_resiliency_reserved = -1;
+static int hf_smb2_ioctl_shared_virtual_disk_support = -1;
+static int hf_smb2_ioctl_shared_virtual_disk_handle_state = -1;
+static int hf_smb2_ioctl_sqos_protocol_version = -1;
+static int hf_smb2_ioctl_sqos_reserved = -1;
+static int hf_smb2_ioctl_sqos_options = -1;
+static int hf_smb2_ioctl_sqos_op_set_logical_flow_id = -1;
+static int hf_smb2_ioctl_sqos_op_set_policy = -1;
+static int hf_smb2_ioctl_sqos_op_probe_policy = -1;
+static int hf_smb2_ioctl_sqos_op_get_status = -1;
+static int hf_smb2_ioctl_sqos_op_update_counters = -1;
+static int hf_smb2_ioctl_sqos_logical_flow_id = -1;
+static int hf_smb2_ioctl_sqos_policy_id = -1;
+static int hf_smb2_ioctl_sqos_initiator_id = -1;
+static int hf_smb2_ioctl_sqos_limit = -1;
+static int hf_smb2_ioctl_sqos_reservation = -1;
+static int hf_smb2_ioctl_sqos_initiator_name = -1;
+static int hf_smb2_ioctl_sqos_initiator_node_name = -1;
+static int hf_smb2_ioctl_sqos_io_count_increment = -1;
+static int hf_smb2_ioctl_sqos_normalized_io_count_increment = -1;
+static int hf_smb2_ioctl_sqos_latency_increment = -1;
+static int hf_smb2_ioctl_sqos_lower_latency_increment = -1;
+static int hf_smb2_ioctl_sqos_bandwidth_limit = -1;
+static int hf_smb2_ioctl_sqos_kilobyte_count_increment = -1;
+static int hf_smb2_ioctl_sqos_time_to_live = -1;
+static int hf_smb2_ioctl_sqos_status = -1;
+static int hf_smb2_ioctl_sqos_maximum_io_rate = -1;
+static int hf_smb2_ioctl_sqos_minimum_io_rate = -1;
+static int hf_smb2_ioctl_sqos_base_io_size = -1;
+static int hf_smb2_ioctl_sqos_reserved2 = -1;
+static int hf_smb2_ioctl_sqos_maximum_bandwidth = -1;
static int hf_windows_sockaddr_family = -1;
static int hf_windows_sockaddr_port = -1;
static int hf_windows_sockaddr_in_addr = -1;
static int hf_smb2_session_flags = -1;
static int hf_smb2_ses_flags_guest = -1;
static int hf_smb2_ses_flags_null = -1;
+static int hf_smb2_ses_flags_encrypt = -1;
static int hf_smb2_share_flags = -1;
static int hf_smb2_share_flags_dfs = -1;
static int hf_smb2_share_flags_dfs_root = -1;
static int hf_smb2_svhdx_open_device_context_open_request_id = -1;
static int hf_smb2_svhdx_open_device_context_initiator_host_name_len = -1;
static int hf_smb2_svhdx_open_device_context_initiator_host_name = -1;
+static int hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized = -1;
+static int hf_smb2_svhdx_open_device_context_server_service_version = -1;
+static int hf_smb2_svhdx_open_device_context_virtual_sector_size = -1;
+static int hf_smb2_svhdx_open_device_context_physical_sector_size = -1;
+static int hf_smb2_svhdx_open_device_context_virtual_size = -1;
static int hf_smb2_posix_v1_version = -1;
static int hf_smb2_posix_v1_request = -1;
static int hf_smb2_posix_v1_supported_features = -1;
static gint ett_smb2_share_caps = -1;
static gint ett_smb2_ioctl_flags = -1;
static gint ett_smb2_ioctl_network_interface = -1;
+static gint ett_smb2_ioctl_sqos_opeations = -1;
static gint ett_smb2_fsctl_range_data = -1;
static gint ett_windows_sockaddr = -1;
static gint ett_smb2_close_flags = -1;
static expert_field ei_smb2_invalid_length = EI_INIT;
static expert_field ei_smb2_bad_response = EI_INIT;
+static expert_field ei_smb2_invalid_getinfo_offset = EI_INIT;
+static expert_field ei_smb2_invalid_getinfo_size = EI_INIT;
+static expert_field ei_smb2_empty_getinfo_buffer = EI_INIT;
static int smb2_tap = -1;
static int smb2_eo_tap = -1;
"Fragments"
};
+#define FILE_BYTE_ALIGNMENT 0x00
+#define FILE_WORD_ALIGNMENT 0x01
+#define FILE_LONG_ALIGNMENT 0x03
+#define FILE_QUAD_ALIGNMENT 0x07
+#define FILE_OCTA_ALIGNMENT 0x0f
+#define FILE_32_BYTE_ALIGNMENT 0x1f
+#define FILE_64_BYTE_ALIGNMENT 0x3f
+#define FILE_128_BYTE_ALIGNMENT 0x7f
+#define FILE_256_BYTE_ALIGNMENT 0xff
+#define FILE_512_BYTE_ALIGNMENT 0x1ff
+static const value_string smb2_alignment_vals[] = {
+ { FILE_BYTE_ALIGNMENT, "FILE_BYTE_ALIGNMENT" },
+ { FILE_WORD_ALIGNMENT, "FILE_WORD_ALIGNMENT" },
+ { FILE_LONG_ALIGNMENT, "FILE_LONG_ALIGNMENT" },
+ { FILE_OCTA_ALIGNMENT, "FILE_OCTA_ALIGNMENT" },
+ { FILE_32_BYTE_ALIGNMENT, "FILE_32_BYTE_ALIGNMENT" },
+ { FILE_64_BYTE_ALIGNMENT, "FILE_64_BYTE_ALIGNMENT" },
+ { FILE_128_BYTE_ALIGNMENT, "FILE_128_BYTE_ALIGNMENT" },
+ { FILE_256_BYTE_ALIGNMENT, "FILE_256_BYTE_ALIGNMENT" },
+ { FILE_512_BYTE_ALIGNMENT, "FILE_512_BYTE_ALIGNMENT" },
+ { 0, NULL }
+};
+
+
#define SMB2_CLASS_FILE_INFO 0x01
#define SMB2_CLASS_FS_INFO 0x02
#define SMB2_CLASS_SEC_INFO 0x03
{ 0, NULL }
};
+#define SMB2_HASH_ALGORITHM_SHA_512 0x0001
+static const value_string smb2_hash_algorithm_types[] = {
+ { SMB2_HASH_ALGORITHM_SHA_512, "SHA-512" },
+ { 0, NULL }
+};
+
+#define SMB2_CIPHER_AES_128_CCM 0x0001
+#define SMB2_CIPHER_AES_128_GCM 0x0002
+static const value_string smb2_cipher_types[] = {
+ { SMB2_CIPHER_AES_128_CCM, "AES-128-CCM" },
+ { SMB2_CIPHER_AES_128_GCM, "AES-128-GCM" },
+ { 0, NULL }
+};
+
+static const val64_string unique_unsolicited_response[] = {
+ { 0xffffffffffffffff, "unsolicited response" },
+ { 0, NULL }
+};
+
#define SMB2_NUM_PROCEDURES 256
static void
-smb2stat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+smb2stat_init(struct register_srt* srt _U_, GArray* srt_array)
{
srt_stat_table *smb2_srt_table;
guint32 i;
- smb2_srt_table = init_srt_table("SMB2", NULL, srt_array, SMB2_NUM_PROCEDURES, "Commands", "smb2.cmd", gui_callback, gui_data, NULL);
+ smb2_srt_table = init_srt_table("SMB2", NULL, srt_array, SMB2_NUM_PROCEDURES, "Commands", "smb2.cmd", NULL);
for (i = 0; i < SMB2_NUM_PROCEDURES; i++)
{
init_srt_table_row(smb2_srt_table, i, val_to_str_ext_const(i, &smb2_cmd_vals_ext, "<unknown>"));
}
}
-static int
+static tap_packet_status
smb2stat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
{
guint i = 0;
/* we are only interested in response packets */
if(!(si->flags&SMB2_FLAGS_RESPONSE)){
- return 0;
+ return TAP_PACKET_DONT_REDRAW;
+ }
+ /* We should not include cancel and oplock break requests either */
+ if (si->opcode == SMB2_COM_CANCEL || si->opcode == SMB2_COM_BREAK) {
+ return TAP_PACKET_DONT_REDRAW;
}
+
/* if we haven't seen the request, just ignore it */
if(!si->saved){
- return 0;
+ return TAP_PACKET_DONT_REDRAW;
}
/* SMB2 SRT can be very inaccurate in the presence of retransmissions. Retransmitted responses
* for the last received response accomplishes this goal without requiring the TCP pref
* "Do not call subdissectors for error packets" to be set. */
if ((si->saved->frame_req == 0) || (si->saved->frame_res != pinfo->num))
- return 0;
+ return TAP_PACKET_DONT_REDRAW;
smb2_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
add_srt_table_data(smb2_srt_table, si->opcode, &si->saved->req_time, pinfo);
- return 1;
+ return TAP_PACKET_REDRAW;
}
+/* Structure for SessionID <=> SessionKey mapping for decryption. */
+typedef struct _smb2_seskey_field_t {
+ guchar *id;
+ guint id_len;
+ guchar *key;
+ guint key_len;
+} smb2_seskey_field_t;
+
+static smb2_seskey_field_t *seskey_list = NULL;
+static guint num_seskey_list = 0;
static const gint8 zeros[NTLMSSP_KEY_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+/* Callbacks for SessionID <=> SessionKey mapping. */
+UAT_BUFFER_CB_DEF(seskey_list, id, smb2_seskey_field_t, id, id_len)
+UAT_BUFFER_CB_DEF(seskey_list, key, smb2_seskey_field_t, key, key_len)
+
+#define SMB_SESSION_ID_SIZE 8
+
+static gboolean seskey_list_update_cb(void *r, char **err)
+{
+ smb2_seskey_field_t *rec = (smb2_seskey_field_t *)r;
+
+ *err = NULL;
+
+ if (rec->id_len != SMB_SESSION_ID_SIZE) {
+ *err = g_strdup("Session ID must be " G_STRINGIFY(SMB_SESSION_ID_SIZE) " bytes long and in hexadecimal");
+ return FALSE;
+ }
+
+ if (rec->key_len == 0 || rec->key_len > NTLMSSP_KEY_LEN) {
+ *err = g_strdup("Session Key must be a non-empty hexadecimal string representing at most " G_STRINGIFY(NTLMSSP_KEY_LEN) " bytes");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void* seskey_list_copy_cb(void *n, const void *o, size_t siz _U_)
+{
+ smb2_seskey_field_t *new_rec = (smb2_seskey_field_t *)n;
+ const smb2_seskey_field_t *old_rec = (const smb2_seskey_field_t *)o;
+
+ new_rec->id_len = old_rec->id_len;
+ new_rec->id = old_rec->id ? (guchar *)g_memdup(old_rec->id, old_rec->id_len) : NULL;
+ new_rec->key_len = old_rec->key_len;
+ new_rec->key = old_rec->key ? (guchar *)g_memdup(old_rec->key, old_rec->key_len) : NULL;
+
+ return new_rec;
+}
+
+static void seskey_list_free_cb(void *r)
+{
+ smb2_seskey_field_t *rec = (smb2_seskey_field_t *)r;
+
+ g_free(rec->id);
+ g_free(rec->key);
+}
+
+static gboolean seskey_find_sid_key(guint64 sesid, guint8 *out_key)
+{
+ guint i;
+
+ for (i = 0; i < num_seskey_list; i++) {
+ const smb2_seskey_field_t *p = &seskey_list[i];
+ if (memcmp(&sesid, p->id, SMB_SESSION_ID_SIZE) == 0) {
+ memset(out_key, 0, NTLMSSP_KEY_LEN);
+ memcpy(out_key, p->key, p->key_len);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/* ExportObject preferences variable */
gboolean eosmb2_take_name_as_fid = FALSE ;
return FALSE;
}
-static void smb2_key_derivation(const guint8 *KI _U_, guint32 KI_len _U_,
- const guint8 *Label _U_, guint32 Label_len _U_,
- const guint8 *Context _U_, guint32 Context_len _U_,
+static void smb2_key_derivation(const guint8 *KI, guint32 KI_len,
+ const guint8 *Label, guint32 Label_len,
+ const guint8 *Context, guint32 Context_len,
guint8 KO[16])
{
-#ifdef HAVE_LIBGCRYPT
gcry_md_hd_t hd = NULL;
guint8 buf[4];
guint8 *digest = NULL;
gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
gcry_md_setkey(hd, KI, KI_len);
+printf("found KI_len[%d]\n", KI_len);
+
memset(buf, 0, sizeof(buf));
buf[3] = 1;
gcry_md_write(hd, buf, sizeof(buf));
memcpy(KO, digest, 16);
gcry_md_close(hd);
-#else
- memset(KO, 0, 16);
-#endif
}
/* for export-object-smb2 */
return;
}
- /* if we don't want/need a subtree */
- if (olb->hfindex == -1) {
- sub_item = parent_tree;
- sub_tree = parent_tree;
- } else {
- if (parent_tree) {
- sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, ENC_NA);
- sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
- }
- }
-
switch (olb->offset_size) {
case OLB_O_UINT16_S_UINT16:
- proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
break;
case OLB_O_UINT16_S_UINT32:
- proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
break;
case OLB_O_UINT32_S_UINT32:
- proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
break;
case OLB_S_UINT32_O_UINT32:
- proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
break;
}
+ /* if we don't want/need a subtree */
+ if (olb->hfindex == -1) {
+ sub_item = parent_tree;
+ sub_tree = parent_tree;
+ } else {
+ if (parent_tree) {
+ sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
+ }
+ }
+
if (off == 0 || len == 0) {
proto_item_append_text(sub_item, ": NO DATA");
return;
return;
}
- sub_tvb = tvb_new_subset(tvb, off, MIN((int)len, tvb_captured_length_remaining(tvb, off)), len);
+ sub_tvb = tvb_new_subset_length_caplen(tvb, off, MIN((int)len, tvb_captured_length_remaining(tvb, off)), len);
dissector(sub_tvb, pinfo, sub_tree, si);
}
{0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
{0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
{0x000900F0, "FSCTL_EXTEND_VOLUME"},
+ {0x00090244, "FSCTL_CSV_TUNNEL_REQUEST"},
{0x0009027C, "FSCTL_GET_INTEGRITY_INFORMATION"},
- {0x00090284, "FSCTL_QUERY_FILE_REGIONS"},
+ {0x00090284, "FSCTL_QUERY_FILE_REGIONS"}, /* dissector implemented */
+ {0x000902c8, "FSCTL_CSV_SYNC_TUNNEL_REQUEST"},
{0x00090300, "FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT"}, /* dissector implemented */
{0x00090304, "FSCTL_SVHDX_SYNC_TUNNEL_REQUEST"}, /* dissector implemented */
{0x00090308, "FSCTL_SVHDX_SET_INITIATOR_INFORMATION"},
{0x00090314, "FSCTL_DELETE_EXTERNAL_BACKING"},
{0x00090318, "FSCTL_ENUM_EXTERNAL_BACKING"},
{0x0009031F, "FSCTL_ENUM_OVERLAY"},
+ {0x00090350, "FSCTL_STORAGE_QOS_CONTROL"}, /* dissector implemented */
+ {0x00090364, "FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST"}, /* dissector implemented */
{0x000940B3, "FSCTL_ENUM_USN_DATA"},
{0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
{0x000940BB, "FSCTL_READ_USN_JOURNAL"},
{ 0, NULL }
};
+static const value_string smb2_ioctl_shared_virtual_disk_vals[] = {
+ { 0x01, "SharedVirtualDisksSupported" },
+ { 0x07, "SharedVirtualDiskCDPSnapshotsSupported" },
+ { 0, NULL }
+};
+
+static const value_string smb2_ioctl_shared_virtual_disk_hstate_vals[] = {
+ { 0x00, "HandleStateNone" },
+ { 0x01, "HandleStateFileShared" },
+ { 0x03, "HandleStateShared" },
+ { 0, NULL }
+};
+
/* this is called from both smb and smb2. */
int
dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
switch (mode) {
case FID_MODE_OPEN:
offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
- if (!pinfo->fd->flags.visited) {
+ if (!pinfo->fd->visited) {
sfi = wmem_new(wmem_file_scope(), smb2_fid_info_t);
*sfi = sfi_key;
if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
int length;
const char *name = "";
guint16 bc;
+ static const int *mode_fields[] = {
+ &hf_smb2_mode_file_write_through,
+ &hf_smb2_mode_file_sequential_only,
+ &hf_smb2_mode_file_no_intermediate_buffering,
+ &hf_smb2_mode_file_synchronous_io_alert,
+ &hf_smb2_mode_file_synchronous_io_nonalert,
+ &hf_smb2_mode_file_delete_on_close,
+ NULL,
+ };
if (parent_tree) {
item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, ENC_NA);
/* access mask */
offset = dissect_smb_access_mask(tvb, tree, offset);
- /* some unknown bytes */
- proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
- offset += 16;
+ /* Position Information */
+ proto_tree_add_item(tree, hf_smb2_position_information, tvb, offset, 8, ENC_NA);
+ offset += 8;
+
+ /* Mode Information */
+ proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_mode_information, ett_smb2_file_mode_info, mode_fields, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* Alignment Information */
+ proto_tree_add_item(tree, hf_smb2_alignment_information, tvb, offset, 4, ENC_NA);
+ offset +=4;
/* file name length */
length = tvb_get_letohs(tvb, offset);
#define SES_FLAGS_GUEST 0x0001
#define SES_FLAGS_NULL 0x0002
+#define SES_FLAGS_ENCRYPT 0x0004
static int
dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
static const int * flags[] = {
&hf_smb2_ses_flags_guest,
&hf_smb2_ses_flags_null,
+ &hf_smb2_ses_flags_encrypt,
NULL
};
}
}
+/*
+ * Derive client and server decryption keys from the secret session key
+ * and set them in the session object.
+ */
+static void smb2_set_session_keys(smb2_sesid_info_t *sesid, const guint8 *session_key)
+{
+ if (memcmp(session_key, zeros, NTLMSSP_KEY_LEN) != 0) {
+ smb2_key_derivation(session_key,
+ NTLMSSP_KEY_LEN,
+ "SMB2AESCCM", 11,
+ "ServerIn ", 10,
+ sesid->server_decryption_key);
+ smb2_key_derivation(session_key,
+ NTLMSSP_KEY_LEN,
+ "SMB2AESCCM", 11,
+ "ServerOut", 10,
+ sesid->client_decryption_key);
+ } else {
+ memset(sesid->server_decryption_key, 0,
+ sizeof(sesid->server_decryption_key));
+ memset(sesid->client_decryption_key, 0,
+ sizeof(sesid->client_decryption_key));
+ }
+}
+
static int
dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
{
* we exit from this dissector.
*/
error_string = register_tap_listener("ntlmssp", NULL, NULL,
- TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL);
+ TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL, NULL);
if (!error_string) {
ntlmssp_tap_id = find_tap_id("ntlmssp");
} else {
offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
/* If we have found a uid->acct_name mapping, store it */
- if (!pinfo->fd->flags.visited) {
+ if (!pinfo->fd->visited) {
idx = 0;
while ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL) {
if (ntlmssph && ntlmssph->type == NTLMSSP_AUTH) {
smb2_sesid_info_t *sesid;
+ guint8 custom_seskey[NTLMSSP_KEY_LEN];
+ const guint8 *session_key;
+
sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
sesid->sesid = si->sesid;
sesid->acct_name = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
sesid->domain_name = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
sesid->host_name = wmem_strdup(wmem_file_scope(), ntlmssph->host_name);
- if (memcmp(ntlmssph->session_key, zeros, NTLMSSP_KEY_LEN) != 0) {
- smb2_key_derivation(ntlmssph->session_key,
- NTLMSSP_KEY_LEN,
- "SMB2AESCCM", 11,
- "ServerIn ", 10,
- sesid->server_decryption_key);
- smb2_key_derivation(ntlmssph->session_key,
- NTLMSSP_KEY_LEN,
- "SMB2AESCCM", 11,
- "ServerOut", 10,
- sesid->client_decryption_key);
+
+ /* Try to see first if we have a
+ * session key set in the pref for
+ * this particular session id */
+ if (seskey_find_sid_key(si->sesid, custom_seskey)) {
+ session_key = custom_seskey;
} else {
- memset(sesid->server_decryption_key, 0,
- sizeof(sesid->server_decryption_key));
- memset(sesid->client_decryption_key, 0,
- sizeof(sesid->client_decryption_key));
+ session_key = ntlmssph->session_key;
}
+ smb2_set_session_keys(sesid, session_key);
sesid->server_port = pinfo->destport;
sesid->auth_frame = pinfo->num;
sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
}
}
+ /* If we have found a uid->acct_name mapping, store it */
+ if(!pinfo->fd->flags.visited) {// && si->status == 0){
+#ifdef HAVE_KERBEROS
+ enc_key_t *ek;
+
+ if (krb_decrypt){
+ read_keytab_file_from_preferences();
+ }
+
+ for(ek=enc_key_list;ek;ek=ek->next){
+ if (ek->fd_num == -1) {
+ continue;
+ }
+
+ if (ek->fd_num != (int)pinfo->fd->num) {
+ continue;
+ }
+
+ break;
+ }
+ if (ek != NULL) {
+ smb2_sesid_info_t *sesid;
+ guint8 session_key[16] = { 0, };
+
+ memcpy(session_key, ek->keyvalue, MIN(ek->keylength, 16));
+
+ sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
+ sesid->sesid = si->sesid;
+ /* TODO: fill in the correct information */
+ sesid->acct_name = NULL;
+ sesid->domain_name = NULL;
+ sesid->host_name = NULL;
+ smb2_key_derivation(session_key, sizeof(session_key),
+ "SMB2AESCCM", 11,
+ "ServerIn ", 10,
+ sesid->server_decryption_key);
+ smb2_key_derivation(session_key, sizeof(session_key),
+ "SMB2AESCCM", 11,
+ "ServerOut", 10,
+ sesid->client_decryption_key);
+ sesid->server_port = pinfo->destport;
+ sesid->auth_frame = pinfo->fd->num;
+ sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
+ g_hash_table_insert(si->conv->sesids, sesid, sesid);
+ }
+#endif
+ }
+
return offset;
}
/* If we have found a uid->acct_name mapping, store it */
#ifdef HAVE_KERBEROS
- if (!pinfo->fd->flags.visited && si->status == 0) {
+ if (!pinfo->fd->visited && si->status == 0) {
enc_key_t *ek;
if (krb_decrypt) {
if (ek != NULL) {
smb2_sesid_info_t *sesid;
- guint8 session_key[16] = { 0, };
-
- memcpy(session_key, ek->keyvalue, MIN(ek->keylength, 16));
+ guint8 custom_seskey[NTLMSSP_KEY_LEN] = { 0, };
+ const guint8 *session_key;
sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
sesid->sesid = si->sesid;
sesid->acct_name = NULL;
sesid->domain_name = NULL;
sesid->host_name = NULL;
- smb2_key_derivation(session_key, sizeof(session_key),
- "SMB2AESCCM", 11,
- "ServerIn ", 10,
- sesid->server_decryption_key);
- smb2_key_derivation(session_key, sizeof(session_key),
- "SMB2AESCCM", 11,
- "ServerOut", 10,
- sesid->client_decryption_key);
+
+ if (seskey_find_sid_key(si->sesid, custom_seskey)) {
+ session_key = custom_seskey;
+ } else {
+ session_key = ek->keyvalue;
+ }
+ smb2_set_session_keys(sesid, session_key);
sesid->server_port = pinfo->srcport;
sesid->auth_frame = pinfo->num;
sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
/* treelen +1 is overkill here if the string is unicode,
* but who ever has more than a handful of TCON in a trace anyways
*/
- if (!pinfo->fd->flags.visited && si->saved && buf && olb.len) {
+ if (!pinfo->fd->visited && si->saved && buf && olb.len) {
si->saved->extra_info_type = SMB2_EI_TREENAME;
si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
offset += 1;
- if (!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type == SMB2_EI_TREENAME && si->session) {
+ if (!pinfo->fd->visited && si->saved && si->saved->extra_info_type == SMB2_EI_TREENAME && si->session) {
smb2_tid_info_t *tid, tid_key;
tid_key.tid = si->tid;
offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
- if (!pinfo->fd->flags.visited && si->saved && olb.len) {
+ if (!pinfo->fd->visited && si->saved && olb.len) {
si->saved->extra_info_type = SMB2_EI_FINDPATTERN;
- si->saved->extra_info = g_malloc(olb.len+1);
+ si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
}
}
+static void dissect_smb2_id_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
+{
+ int offset = 0;
+ proto_item *item = NULL;
+ proto_tree *tree = NULL;
+ const char *name = NULL;
+ guint16 bc;
+
+ while (tvb_reported_length_remaining(tvb, offset) > 4) {
+ int old_offset = offset;
+ int next_offset;
+ int file_name_len;
+
+ if (parent_tree) {
+ item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
+ tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
+ }
+
+ /* next offset */
+ next_offset = tvb_get_letohl(tvb, offset);
+ proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* file index */
+ proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* create time */
+ offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
+
+ /* last access */
+ offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
+
+ /* last write */
+ offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
+
+ /* last change */
+ offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
+
+ /* end of file */
+ proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ /* allocation size */
+ proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ /* File Attributes */
+ offset = dissect_file_ext_attr(tvb, tree, offset);
+
+ /* file name length */
+ file_name_len = tvb_get_letohl(tvb, offset);
+ proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* ea size */
+ proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* reserved */
+ proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
+ offset += 4;
+
+ /* file id */
+ proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ /* file name */
+ if (file_name_len) {
+ bc = file_name_len;
+ name = get_unicode_or_ascii_string(tvb, &offset,
+ TRUE, &file_name_len, TRUE, TRUE, &bc);
+ if (name) {
+ proto_tree_add_string(tree, hf_smb2_filename, tvb,
+ offset, file_name_len, name);
+ proto_item_append_text(item, ": %s", name);
+
+ }
+ }
+
+ proto_item_set_len(item, offset-old_offset);
+
+ if (next_offset == 0) {
+ return;
+ }
+
+ offset = old_offset+next_offset;
+ if (offset < old_offset) {
+ proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
+ "Invalid offset/length. Malformed packet");
+ return;
+ }
+ }
+}
+
+
typedef struct _smb2_find_dissector_t {
guint32 level;
void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
{SMB2_FIND_BOTH_DIRECTORY_INFO, dissect_smb2_both_directory_info},
{SMB2_FIND_NAME_INFO, dissect_smb2_file_name_info},
{SMB2_FIND_ID_BOTH_DIRECTORY_INFO,dissect_smb2_id_both_directory_info},
+ {SMB2_FIND_ID_FULL_DIRECTORY_INFO,dissect_smb2_id_full_directory_info},
{0, NULL}
};
PROTO_ITEM_SET_GENERATED(item);
}
- if (!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type == SMB2_EI_FINDPATTERN) {
+ if (!pinfo->fd->visited && si->saved && si->saved->extra_info_type == SMB2_EI_FINDPATTERN) {
col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
val_to_str(si->saved->infolevel, smb2_find_info_levels, "(Level:0x%02x)"),
(const char *)si->saved->extra_info);
- g_free(si->saved->extra_info);
+ wmem_free(wmem_file_scope(), si->saved->extra_info);
si->saved->extra_info_type = SMB2_EI_NONE;
si->saved->extra_info = NULL;
}
static int
dissect_smb2_negotiate_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
{
- int start_offset = offset;
guint16 type;
const gchar *type_str;
- guint16 data_length;
+ guint32 i, data_length, salt_length, hash_count, cipher_count;
proto_item *sub_item;
proto_tree *sub_tree;
- tvbuff_t *sub_tvb;
sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_negotiate_context_element, &sub_item, "Negotiate Context");
offset += 2;
/* data length */
- data_length = tvb_get_letohl(tvb, offset);
- proto_tree_add_item(sub_tree, hf_smb2_negotiate_context_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item_ret_uint(sub_tree, hf_smb2_negotiate_context_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &data_length);
offset += 2;
/* reserved */
proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
offset += 4;
- /* data */
- sub_tvb = tvb_new_subset_length(tvb, offset, data_length);
- offset += data_length;
+ switch (type)
+ {
+ case SMB2_PREAUTH_INTEGRITY_CAPABILITIES:
+ proto_tree_add_item_ret_uint(sub_tree, hf_smb2_hash_alg_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &hash_count);
+ offset += 2;
+ proto_tree_add_item_ret_uint(sub_tree, hf_smb2_salt_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &salt_length);
+ offset += 2;
- proto_item_set_len(sub_item, offset - start_offset);
+ for (i = 0; i < hash_count; i++)
+ {
+ proto_tree_add_item(sub_tree, hf_smb2_hash_algorithm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ }
- /*
- * TODO: disssect the context data
- */
- proto_tree_add_item(sub_tree, hf_smb2_unknown, sub_tvb, 0, data_length, ENC_NA);
+ if (salt_length)
+ {
+ proto_tree_add_item(sub_tree, hf_smb2_salt, tvb, offset, salt_length, ENC_NA);
+ offset += salt_length;
+ }
+ break;
+
+ case SMB2_ENCRYPTION_CAPABILITIES:
+ proto_tree_add_item_ret_uint(sub_tree, hf_smb2_cipher_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cipher_count);
+ offset += 2;
+
+ for (i = 0; i < cipher_count; i ++)
+ {
+ proto_tree_add_item(sub_tree, hf_smb2_cipher_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ }
+ break;
+
+ default:
+ proto_tree_add_item(sub_tree, hf_smb2_unknown, tvb, offset, data_length, ENC_NA);
+ offset += data_length;
+ break;
+ }
return offset;
}
return offset;
}
-static int
-dissect_smb2_getinfo_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int size, smb2_info_t *si)
-{
- switch (si->saved->smb2_class) {
- case SMB2_CLASS_QUOTA_INFO:
- dissect_smb2_getinfo_buffer_quota(tvb, pinfo, tree, offset, si);
- break;
- default:
- if (size > 0) {
- proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, size, ENC_NA);
- }
- }
- offset += size;
-
- return offset;
-}
-
static int
dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
{
{
guint32 getinfo_size = 0;
guint32 getinfo_offset = 0;
+ proto_item *offset_item;
/* buffer code */
offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
offset += 4;
/* offset */
- proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN, &getinfo_offset);
- offset += 4;
+ offset_item = proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_input_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN, &getinfo_offset);
+ offset += 2;
+
+ /* reserved */
+ proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
+ offset += 2;
/* size */
- proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &getinfo_size);
+ proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_input_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &getinfo_size);
offset += 4;
/* parameters */
if (si->saved) {
- dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
+ offset = dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
} else {
/* some unknown bytes */
proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, ENC_NA);
+ offset += 8;
}
- offset += 8;
/* fid */
- dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
+ offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
/* buffer */
if (si->saved) {
- dissect_smb2_getinfo_buffer(tvb, pinfo, tree, getinfo_offset, getinfo_size, si);
+ if (getinfo_size != 0) {
+ /*
+ * 2.2.37 says "For quota requests, this MUST be
+ * the length of the contained SMB2_QUERY_QUOTA_INFO
+ * embedded in the request. For FileFullEaInformation
+ * requests, this MUST be set to the length of the
+ * user supplied EA list specified in [MS-FSCC]
+ * section 2.4.15.1. For other information queries,
+ * this field SHOULD be set to 0 and the server MUST
+ * ignore it on receipt.
+ *
+ * This seems to imply that, for requests other
+ * than those to types, we should either completely
+ * ignore a non-zero getinfo_size or should, at
+ * most, add a warning-level expert info at the
+ * protocol level saying that it should be zero,
+ * but not try and interpret it or check its
+ * validity.
+ */
+ if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO ||
+ (si->saved->smb2_class == SMB2_CLASS_FILE_INFO &&
+ si->saved->infolevel == SMB2_FILE_FULL_EA_INFO)) {
+ /*
+ * According to 2.2.37 SMB2 QUERY_INFO
+ * Request in the current MS-SMB2 spec,
+ * these are the only info requests that
+ * have an input buffer.
+ */
+
+ /*
+ * Make sure that the input buffer is after
+ * the fixed-length part of the message.
+ */
+ if (getinfo_offset < (guint)offset) {
+ expert_add_info(pinfo, offset_item, &ei_smb2_invalid_getinfo_offset);
+ return offset;
+ }
+
+ /*
+ * Make sure the input buffer is within the
+ * message, i.e. that it's within the tvbuff.
+ *
+ * We check for offset+length overflowing and
+ * for offset+length being beyond the reported
+ * length of the tvbuff.
+ */
+ if (getinfo_offset + getinfo_size < getinfo_offset ||
+ getinfo_offset + getinfo_size > tvb_reported_length(tvb)) {
+ expert_add_info(pinfo, offset_item, &ei_smb2_invalid_getinfo_size);
+ return offset;
+ }
+
+ if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO) {
+ dissect_smb2_getinfo_buffer_quota(tvb, pinfo, tree, getinfo_offset, si);
+ } else {
+ /*
+ * XXX - handle user supplied EA info.
+ */
+ proto_tree_add_item(tree, hf_smb2_unknown, tvb, getinfo_offset, getinfo_size, ENC_NA);
+ }
+ offset = getinfo_offset + getinfo_size;
+ }
+ } else {
+ /*
+ * The buffer size is 0, meaning it's not present.
+ *
+ * 2.2.37 says "For FileFullEaInformation requests,
+ * the input buffer MUST contain the user supplied
+ * EA list with zero or more FILE_GET_EA_INFORMATION
+ * structures, specified in [MS-FSCC] section
+ * 2.4.15.1.", so it seems that, for a "get full
+ * EA information" request, the size can be zero -
+ * there's no other obvious way for the list to
+ * have zero structures.
+ *
+ * 2.2.37 also says "For quota requests, the input
+ * buffer MUST contain an SMB2_QUERY_QUOTA_INFO,
+ * as specified in section 2.2.37.1."; that seems
+ * to imply that the input buffer must not be empty
+ * in that case.
+ */
+ if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO)
+ expert_add_info(pinfo, offset_item, &ei_smb2_empty_getinfo_buffer);
+ }
}
- offset = getinfo_offset + getinfo_size;
return offset;
}
static gboolean smb2_pipe_reassembly = TRUE;
static reassembly_table smb2_pipe_reassembly_table;
-static void
-smb2_pipe_reassembly_init(void)
-{
- /*
- * XXX - addresses_ports_reassembly_table_functions?
- * Probably correct for SMB-over-NBT and SMB-over-TCP,
- * as stuff from two different connections should
- * probably not be combined, but what about other
- * transports for SMB, e.g. NBF or Netware?
- */
- reassembly_table_init(&smb2_pipe_reassembly_table,
- &addresses_reassembly_table_functions);
-}
-
static int
dissect_file_data_smb2_pipe(tvbuff_t *raw_tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, guint32 datalen, proto_tree *top_tree, void *data)
{
remaining = tvb_captured_length_remaining(raw_tvb, offset);
- tvb = tvb_new_subset(raw_tvb, offset,
+ tvb = tvb_new_subset_length_caplen(raw_tvb, offset,
MIN((int)datalen, remaining),
datalen);
* pdu and if not, check if the dissector wants us
* to reassemble it
*/
- if (!pinfo->fd->flags.visited) {
+ if (!pinfo->fd->visited) {
/*
* This is the first pass.
*
break;
}
+ data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
+
/* data or namedpipe ?*/
if (length) {
int oldoffset = offset;
offset = dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, length, si->top_tree, si);
if (offset != oldoffset) {
/* managed to dissect pipe data */
- return offset;
+ goto out;
}
}
/* just ordinary data */
proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, ENC_NA);
- data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
-
offset += MIN(length,(guint32)tvb_captured_length_remaining(tvb, offset));
offset = dissect_smb2_olb_tvb_max_offset(offset, &c_olb);
+out:
if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
feed_eo_smb2(tvb,pinfo,si,dataoffset,length,off);
proto_tree_add_item(sub_tree, hf_smb2_qfr_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
offset += 8;
- proto_tree_add_item(sub_tree, hf_smb2_qfr_usage, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(sub_tree, hf_smb2_qfr_usage, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
+ offset += 4;
+
+ entry_count--;
+ }
+ }
+}
+
+static void
+dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
+{
+ /* There is no out data */
+ if (!data_in) {
+ return;
+ }
+
+ /* timeout */
+ proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* reserved */
+ proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+}
+
+static void
+dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
+{
+ /* There is no in data */
+ if (data_in) {
+ return;
+ }
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_shared_virtual_disk_support, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_shared_virtual_disk_handle_state, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+}
+
+#define STORAGE_QOS_CONTROL_FLAG_SET_LOGICAL_FLOW_ID 0x00000001
+#define STORAGE_QOS_CONTROL_FLAG_SET_POLICY 0x00000002
+#define STORAGE_QOS_CONTROL_FLAG_PROBE_POLICY 0x00000004
+#define STORAGE_QOS_CONTROL_FLAG_GET_STATUS 0x00000008
+#define STORAGE_QOS_CONTROL_FLAG_UPDATE_COUNTERS 0x00000010
+
+static const value_string smb2_ioctl_sqos_protocol_version_vals[] = {
+ { 0x0100, "Storage QoS Protocol Version 1.0" },
+ { 0x0101, "Storage QoS Protocol Version 1.1" },
+ { 0, NULL }
+};
+
+static const value_string smb2_ioctl_sqos_status_vals[] = {
+ { 0x00, "StorageQoSStatusOk" },
+ { 0x01, "StorageQoSStatusInsufficientThroughput" },
+ { 0x02, "StorageQoSUnknownPolicyId" },
+ { 0x04, "StorageQoSStatusConfigurationMismatch" },
+ { 0x05, "StorageQoSStatusNotAvailable" },
+ { 0, NULL }
+};
+
+static void
+dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, gboolean data_in)
+{
+ static const int * operations[] = {
+ &hf_smb2_ioctl_sqos_op_set_logical_flow_id,
+ &hf_smb2_ioctl_sqos_op_set_policy,
+ &hf_smb2_ioctl_sqos_op_probe_policy,
+ &hf_smb2_ioctl_sqos_op_get_status,
+ &hf_smb2_ioctl_sqos_op_update_counters,
+ NULL
+ };
+
+ gint proto_ver;
+
+ /* Both request and reply have the same common header */
+
+ proto_ver = tvb_get_letohs(tvb, offset);
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_protocol_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_ioctl_sqos_options,
+ ett_smb2_ioctl_sqos_opeations, operations, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_logical_flow_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
+ offset += 16;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_policy_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
+ offset += 16;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_initiator_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
+ offset += 16;
+
+ if (data_in) {
+ offset_length_buffer_t host_olb, node_olb;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reservation, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ offset = dissect_smb2_olb_length_offset(tvb, offset, &host_olb, OLB_O_UINT16_S_UINT16, hf_smb2_ioctl_sqos_initiator_name);
+
+ offset = dissect_smb2_olb_length_offset(tvb, offset, &node_olb, OLB_O_UINT16_S_UINT16, hf_smb2_ioctl_sqos_initiator_node_name);
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_io_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_normalized_io_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_latency_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_lower_latency_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ if (proto_ver > 0x0100) {
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_bandwidth_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_kilobyte_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ /*offset += 8;*/
+ }
+
+ dissect_smb2_olb_string(pinfo, tree, tvb, &host_olb, OLB_TYPE_UNICODE_STRING);
- proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
- offset += 4;
+ dissect_smb2_olb_string(pinfo, tree, tvb, &node_olb, OLB_TYPE_UNICODE_STRING);
+ } else {
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_time_to_live, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- entry_count--;
- }
- }
-}
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
-static void
-dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
-{
- /* There is no out data */
- if (!data_in) {
- return;
- }
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_maximum_io_rate, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- /* timeout */
- proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_minimum_io_rate, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- /* reserved */
- proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
-}
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_base_io_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
-static void
-dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int offset _U_, gboolean data_in _U_)
-{
- /* There is no out data */
- if (!data_in) {
- return;
- }
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reserved2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- /* There is nothing to do here ... */
+ if (proto_ver > 0x0100) {
+ offset += 4;
+ proto_tree_add_item(tree, hf_smb2_ioctl_sqos_maximum_bandwidth, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ }
+ }
}
static void
dissect_smb2_FSCTL_GET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
break;
case 0x00090300: /* FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT */
- if (!data_in)
- dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvb, pinfo, tree, 0, dc);
+ dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvb, pinfo, tree, 0, data_in);
break;
case 0x00090304: /* FSCTL_SVHDX_SYNC_TUNNEL or response */
+ case 0x00090364: /* FSCTL_SVHDX_ASYNC_TUNNEL or response */
call_dissector_with_data(rsvd_handle, tvb, pinfo, top_tree, &data_in);
break;
+ case 0x00090350: /* FSCTL_STORAGE_QOS_CONTROL */
+ dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvb, pinfo, tree, 0, data_in);
+ break;
case 0x0009C040: /* FSCTL_SET_COMPRESSION */
dissect_smb2_FSCTL_SET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
break;
proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
offset += 4;
+ data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
+
/* data or namedpipe ?*/
if (length) {
int oldoffset = offset;
offset = dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, length, si->top_tree, si);
if (offset != oldoffset) {
/* managed to dissect pipe data */
- return offset;
+ goto out;
}
}
/* data */
proto_tree_add_item(tree, hf_smb2_read_data, tvb, offset, length, ENC_NA);
- data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
-
offset += MIN(length,data_tvb_len);
+out:
if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
feed_eo_smb2(tvb,pinfo,si,dataoffset,length,si->saved->file_offset);
* Dissect the MS-RSVD stuff that turns up when HyperV uses SMB3.x
*/
static void
-dissect_smb2_svhdx_open_device_context_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
+dissect_smb2_svhdx_open_device_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
{
- int offset = 0;
+ int offset = 0;
+ guint32 version;
proto_item *item;
proto_item *sub_tree;
sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_svhdx_open_device_context, NULL, "SVHDX OPEN DEVICE CONTEXT");
/* Version */
- proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_version,
- tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item_ret_uint(sub_tree, hf_smb2_svhdx_open_device_context_version,
+ tvb, offset, 4, ENC_LITTLE_ENDIAN, &version);
offset += 4;
/* HasInitiatorId */
/* InitiatorId */
proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_id,
- tvb, offset, 16, ENC_NA);
+ tvb, offset, 16, ENC_LITTLE_ENDIAN);
offset += 16;
/* Flags TODO: Dissect these*/
/* InitiatorHostName */
proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_host_name,
tvb, offset, 126, ENC_ASCII | ENC_NA);
-}
+ offset += 126;
-static void
-dissect_smb2_svhdx_open_device_context_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
-{
- report_create_context_malformed_buffer(tvb, pinfo, tree, "SHVXD OPEN DEVICE CONTEXT Response");
+ if (version == 2) {
+ /* VirtualDiskPropertiesInitialized */
+ proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized,
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* ServerServiceVersion */
+ proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_server_service_version,
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* VirtualSectorSize */
+ proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_sector_size,
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* PhysicalSectorSize */
+ proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_physical_sector_size,
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ /* VirtualSize */
+ proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_size,
+ tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ }
}
static const int *posix_flags_fields[] = {
{ "6aa6bc45-a7ef-4af7-9008-fa462e144d74", "SMB2_CREATE_APP_INSTANCE_ID",
{ dissect_smb2_APP_INSTANCE_buffer_request, dissect_smb2_APP_INSTANCE_buffer_response } },
{ "9ecfcb9c-c104-43e6-980e-158da1f6ec83", "SVHDX_OPEN_DEVICE_CONTEXT",
- { dissect_smb2_svhdx_open_device_context_request, dissect_smb2_svhdx_open_device_context_response} },
+ { dissect_smb2_svhdx_open_device_context, dissect_smb2_svhdx_open_device_context} },
{ "34263501-2921-4912-2586-447794114531", "SMB2_POSIX_V1_CAPS",
{ dissect_smb2_posix_v1_caps_request, dissect_smb2_posix_v1_caps_response } },
{ "AAPL", "SMB2_AAPL_CREATE_CONTEXT",
col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", fname);
/* save the name if it looks sane */
- if (!pinfo->fd->flags.visited) {
+ if (!pinfo->fd->visited) {
if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
- g_free(si->saved->extra_info);
+ wmem_free(wmem_file_scope(), si->saved->extra_info);
si->saved->extra_info = NULL;
si->saved->extra_info_type = SMB2_EI_NONE;
}
- if (si->saved && f_olb.len && f_olb.len<256) {
+ if (si->saved && f_olb.len < 256) {
si->saved->extra_info_type = SMB2_EI_FILENAME;
- si->saved->extra_info = (gchar *)g_malloc(f_olb.len+1);
+ si->saved->extra_info = (gchar *)wmem_alloc(wmem_file_scope(), f_olb.len+1);
g_snprintf((gchar *)si->saved->extra_info, f_olb.len+1, "%s", fname);
}
}
/* free si->saved->extra_info we don't need it any more */
if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
- g_free(si->saved->extra_info);
+ wmem_free(wmem_file_scope(), si->saved->extra_info);
si->saved->extra_info = NULL;
si->saved->extra_info_type = SMB2_EI_NONE;
}
#define ENC_ALG_aes128_ccm 0x0001
static int
-dissect_smb2_transform_header(packet_info *pinfo _U_, proto_tree *tree,
+dissect_smb2_transform_header(packet_info *pinfo, proto_tree *tree,
tvbuff_t *tvb, int offset,
smb2_transform_info_t *sti,
tvbuff_t **enc_tvb, tvbuff_t **plain_tvb)
smb2_sesid_info_t sesid_key;
int sesid_offset;
guint8 *plain_data = NULL;
-#ifdef HAVE_LIBGCRYPT
guint8 *decryption_key = NULL;
-#endif
proto_item *item;
static const int *sf_fields[] = {
offset += 8;
/* now we need to first lookup the uid session */
- sesid_key.sesid = sti->sesid;
+ sesid_key.sesid = 0;//sti->sesid;
sti->session = (smb2_sesid_info_t *)g_hash_table_lookup(sti->conv->sesids, &sesid_key);
if (sti->session != NULL && sti->session->auth_frame != (guint32)-1) {
PROTO_ITEM_SET_GENERATED(item);
}
-#ifdef HAVE_LIBGCRYPT
if (sti->session != NULL && sti->alg == ENC_ALG_aes128_ccm) {
if (pinfo->destport == sti->session->server_port) {
decryption_key = sti->session->server_decryption_key;
decryption_key = sti->session->client_decryption_key;
}
- if (memcmp(decryption_key, zeros, 16) == 0) {
+ if (memcmp(decryption_key, zeros, NTLMSSP_KEY_LEN) == 0) {
decryption_key = NULL;
}
}
if (decryption_key != NULL) {
gcry_cipher_hd_t cipher_hd = NULL;
- guint8 A_1[16] = {
+ guint8 A_1[NTLMSSP_KEY_LEN] = {
3, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1
};
}
/* Set the key and initial value. */
- if (gcry_cipher_setkey(cipher_hd, decryption_key, 16)) {
+ if (gcry_cipher_setkey(cipher_hd, decryption_key, NTLMSSP_KEY_LEN)) {
gcry_cipher_close(cipher_hd);
wmem_free(pinfo->pool, plain_data);
plain_data = NULL;
goto done_decryption;
}
- if (gcry_cipher_setctr(cipher_hd, A_1, 16)) {
+ if (gcry_cipher_setctr(cipher_hd, A_1, NTLMSSP_KEY_LEN)) {
gcry_cipher_close(cipher_hd);
wmem_free(pinfo->pool, plain_data);
plain_data = NULL;
gcry_cipher_close(cipher_hd);
}
done_decryption:
-#endif
*enc_tvb = tvb_new_subset_length(tvb, offset, sti->size);
if (plain_data != NULL) {
sesid_key.sesid = si->sesid;
si->session = (smb2_sesid_info_t *)g_hash_table_lookup(si->conv->sesids, &sesid_key);
if (!si->session) {
- if (si->opcode != 0x03) return offset;
+ guint8 seskey[NTLMSSP_KEY_LEN] = {0, };
+
+ if (si->opcode != 0x03)
+ return offset;
+
/* if we come to a session that is unknown, and the operation is
* a tree connect, we create a dummy sessison, so we can hang the
si->session->sesid = si->sesid;
si->session->auth_frame = (guint32)-1;
si->session->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
+ if (si->flags & SMB2_FLAGS_RESPONSE) {
+ si->session->server_port = pinfo->srcport;
+ } else {
+ si->session->server_port = pinfo->destport;
+ }
+ if (seskey_find_sid_key(si->sesid, seskey)) {
+ smb2_set_session_keys(si->session, seskey);
+ }
+
g_hash_table_insert(si->conv->sesids, si->session, si->session);
return offset;
dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolean first_in_chain)
{
gboolean smb2_transform_header = FALSE;
- proto_item *msg_id_item;
proto_item *item = NULL;
proto_tree *tree = NULL;
proto_item *header_item = NULL;
/* Message ID */
si->msg_id = tvb_get_letoh64(tvb, offset);
ssi_key.msg_id = si->msg_id;
- msg_id_item = proto_tree_add_item(header_tree, hf_smb2_msg_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- if (msg_id_item && (si->msg_id == -1)) {
- proto_item_append_text(msg_id_item, " (unsolicited response)");
- }
+ proto_tree_add_item(header_tree, hf_smb2_msg_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
offset += 8;
/* Tree ID and Session ID */
}
- if (!pinfo->fd->flags.visited) {
+ if (!pinfo->fd->visited) {
/* see if we can find this msg_id in the unmatched table */
ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
{ &hf_smb2_response_to,
{ "Response to", "smb2.response_to", FT_FRAMENUM, BASE_NONE,
- NULL, 0, "This packet is a response to the packet in this frame", HFILL }
+ FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0, "This packet is a response to the packet in this frame", HFILL }
},
{ &hf_smb2_response_in,
{ "Response in", "smb2.response_in", FT_FRAMENUM, BASE_NONE,
- NULL, 0, "The response to this packet is in this packet", HFILL }
+ FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0, "The response to this packet is in this packet", HFILL }
},
{ &hf_smb2_time,
},
{ &hf_smb2_msg_id,
- { "Message ID", "smb2.msg_id", FT_INT64, BASE_DEC,
- NULL, 0, "SMB2 Message ID", HFILL }
+ { "Message ID", "smb2.msg_id", FT_UINT64, BASE_DEC|BASE_VAL64_STRING|BASE_SPECIAL_VALS,
+ VALS64(unique_unsolicited_response), 0, NULL, HFILL }
},
{ &hf_smb2_tid,
{ "Tree Id", "smb2.tid", FT_UINT32, BASE_HEX,
- NULL, 0, "SMB2 Tree Id", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_aid,
{ "Async Id", "smb2.aid", FT_UINT64, BASE_HEX,
- NULL, 0, "SMB2 Async Id", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_sesid,
{ "Session Id", "smb2.sesid", FT_UINT64, BASE_HEX,
- NULL, 0, "SMB2 Session Id", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_previous_sesid,
{ "Previous Session Id", "smb2.previous_sesid", FT_UINT64, BASE_HEX,
- NULL, 0, "SMB2 Previous Session Id", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_chain_offset,
{ "Chain Offset", "smb2.chain_offset", FT_UINT32, BASE_HEX,
- NULL, 0, "SMB2 Chain Offset", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_end_of_file,
{ &hf_smb2_file_id,
{ "File Id", "smb2.file_id", FT_UINT64, BASE_HEX,
- NULL, 0, "SMB2 File Id", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_allocation_size,
{ "Allocation Size", "smb2.allocation_size", FT_UINT64, BASE_DEC,
- NULL, 0, "SMB2 Allocation Size for this object", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_max_response_size,
{ "Max Response Size", "smb2.max_response_size", FT_UINT32, BASE_DEC,
- NULL, 0, "SMB2 Maximum response size", HFILL }
+ NULL, 0, NULL, HFILL }
},
- { &hf_smb2_getinfo_size,
- { "Getinfo Size", "smb2.getinfo_size", FT_UINT32, BASE_DEC,
- NULL, 0, "SMB2 getinfo size", HFILL }
+ { &hf_smb2_getinfo_input_size,
+ { "Getinfo Input Size", "smb2.getinfo_input_size", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }
},
- { &hf_smb2_getinfo_offset,
- { "Getinfo Offset", "smb2.getinfo_offset", FT_UINT16, BASE_HEX,
- NULL, 0, "SMB2 getinfo offset", HFILL }
+ { &hf_smb2_getinfo_input_offset,
+ { "Getinfo Input Offset", "smb2.getinfo_input_offset", FT_UINT16, BASE_HEX,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_getinfo_additional,
{ "Additional Info", "smb2.getinfo_additional", FT_UINT32, BASE_HEX,
- NULL, 0, "SMB2 getinfo additional info", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_getinfo_flags,
{ "Flags", "smb2.getinfo_flags", FT_UINT32, BASE_HEX,
- NULL, 0, "SMB2 getinfo flags", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_setinfo_size,
{ "Setinfo Size", "smb2.setinfo_size", FT_UINT32, BASE_DEC,
- NULL, 0, "SMB2 setinfo size", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_setinfo_offset,
{ "Setinfo Offset", "smb2.setinfo_offset", FT_UINT16, BASE_HEX,
- NULL, 0, "SMB2 setinfo offset", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_max_ioctl_out_size,
{ "Max Ioctl Out Size", "smb2.max_ioctl_out_size", FT_UINT32, BASE_DEC,
- NULL, 0, "SMB2 Maximum ioctl out size", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_max_ioctl_in_size,
{ "Max Ioctl In Size", "smb2.max_ioctl_in_size", FT_UINT32, BASE_DEC,
- NULL, 0, "SMB2 Maximum ioctl out size", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_required_buffer_size,
{ "Required Buffer Size", "smb2.required_size", FT_UINT32, BASE_DEC,
- NULL, 0, "SMB2 required buffer size", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_pid,
{ "Process Id", "smb2.pid", FT_UINT32, BASE_HEX,
- NULL, 0, "SMB2 Process Id", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_filename,
{ "Filename", "smb2.filename", FT_STRING, BASE_NONE,
- NULL, 0, "Name of the file", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_filename_len,
{ "Filename Length", "smb2.filename.len", FT_UINT32, BASE_DEC,
- NULL, 0, "Length of the file name", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_replace_if,
NULL, 0, "Size of EA data", HFILL }
},
+ { &hf_smb2_position_information,
+ { "Position Information", "smb2.position_info", FT_UINT64, BASE_DEC,
+ NULL, 0, "Current file position", HFILL }
+ },
+
+ { &hf_smb2_mode_information,
+ { "Mode Information", "smb2.mode_info", FT_UINT32, BASE_HEX,
+ NULL, 0, "File mode informatino", HFILL }
+ },
+
+ { &hf_smb2_mode_file_write_through,
+ { "FILE_WRITE_THROUGH", "smb2.mode.file_write_through", FT_UINT32, BASE_HEX,
+ NULL, 0x02, NULL, HFILL }
+ },
+
+ { &hf_smb2_mode_file_sequential_only,
+ { "FILE_SEQUENTIAL_ONLY", "smb2.mode.file_sequential_only", FT_UINT32, BASE_HEX,
+ NULL, 0x04, NULL, HFILL }
+ },
+
+ { &hf_smb2_mode_file_no_intermediate_buffering,
+ { "FILE_NO_INTERMEDIATE_BUFFERING", "smb2.mode.file_no_intermediate_buffering", FT_UINT32, BASE_HEX,
+ NULL, 0x08, NULL, HFILL }
+ },
+
+ { &hf_smb2_mode_file_synchronous_io_alert,
+ { "FILE_SYNCHRONOUS_IO_ALERT", "smb2.mode.file_synchronous_io_alert", FT_UINT32, BASE_HEX,
+ NULL, 0x10, NULL, HFILL }
+ },
+
+ { &hf_smb2_mode_file_synchronous_io_nonalert,
+ { "FILE_SYNCHRONOUS_IO_NONALERT", "smb2.mode.file_synchronous_io_nonalert", FT_UINT32, BASE_HEX,
+ NULL, 0x20, NULL, HFILL }
+ },
+
+ { &hf_smb2_mode_file_delete_on_close,
+ { "FILE_DELETE_ON_CLOSE", "smb2.mode.file_delete_on_close", FT_UINT32, BASE_HEX,
+ NULL, 0x1000, NULL, HFILL }
+ },
+
+ { &hf_smb2_alignment_information,
+ { "Alignment Information", "smb2.alignment_info", FT_UINT32, BASE_HEX,
+ VALS(smb2_alignment_vals), 0, "File alignment", HFILL}
+ },
+
{ &hf_smb2_class,
{ "Class", "smb2.class", FT_UINT8, BASE_HEX,
VALS(smb2_class_vals), 0, "Info class", HFILL }
{ &hf_smb2_file_all_info,
{ "SMB2_FILE_ALL_INFO", "smb2.file_all_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_ALL_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_allocation_info,
{ "SMB2_FILE_ALLOCATION_INFO", "smb2.file_allocation_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_ALLOCATION_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_endoffile_info,
{ "SMB2_FILE_ENDOFFILE_INFO", "smb2.file_endoffile_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_ENDOFFILE_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_alternate_name_info,
{ "SMB2_FILE_ALTERNATE_NAME_INFO", "smb2.file_alternate_name_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_ALTERNATE_NAME_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_stream_info,
{ "SMB2_FILE_STREAM_INFO", "smb2.file_stream_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_STREAM_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_pipe_info,
{ "SMB2_FILE_PIPE_INFO", "smb2.file_pipe_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_PIPE_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_compression_info,
{ "SMB2_FILE_COMPRESSION_INFO", "smb2.file_compression_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_COMPRESSION_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_basic_info,
{ "SMB2_FILE_BASIC_INFO", "smb2.file_basic_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_BASIC_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_standard_info,
{ "SMB2_FILE_STANDARD_INFO", "smb2.file_standard_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_STANDARD_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_internal_info,
{ "SMB2_FILE_INTERNAL_INFO", "smb2.file_internal_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_INTERNAL_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_mode_info,
{ "SMB2_FILE_MODE_INFO", "smb2.file_mode_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_MODE_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_alignment_info,
{ "SMB2_FILE_ALIGNMENT_INFO", "smb2.file_alignment_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_ALIGNMENT_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_position_info,
{ "SMB2_FILE_POSITION_INFO", "smb2.file_position_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_POSITION_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_access_info,
{ "SMB2_FILE_ACCESS_INFO", "smb2.file_access_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_ACCESS_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_ea_info,
{ "SMB2_FILE_EA_INFO", "smb2.file_ea_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_EA_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_network_open_info,
{ "SMB2_FILE_NETWORK_OPEN_INFO", "smb2.file_network_open_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_NETWORK_OPEN_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_attribute_tag_info,
{ "SMB2_FILE_ATTRIBUTE_TAG_INFO", "smb2.file_attribute_tag_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_ATTRIBUTE_TAG_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_disposition_info,
{ "SMB2_FILE_DISPOSITION_INFO", "smb2.file_disposition_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_DISPOSITION_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_full_ea_info,
{ "SMB2_FILE_FULL_EA_INFO", "smb2.file_full_ea_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_FULL_EA_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_file_rename_info,
{ "SMB2_FILE_RENAME_INFO", "smb2.file_rename_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FILE_RENAME_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fs_info_01,
- { "SMB2_FS_INFO_01", "smb2.fs_info_01", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FS_INFO_01 structure", HFILL }
+ { "FileFsVolumeInformation", "smb2.fs_volume_info", FT_NONE, BASE_NONE,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fs_info_03,
- { "SMB2_FS_INFO_03", "smb2.fs_info_03", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FS_INFO_03 structure", HFILL }
+ { "FileFsSizeInformation", "smb2.fs_size_info", FT_NONE, BASE_NONE,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fs_info_04,
- { "SMB2_FS_INFO_04", "smb2.fs_info_04", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FS_INFO_04 structure", HFILL }
+ { "FileFsDeviceInformation", "smb2.fs_device_info", FT_NONE, BASE_NONE,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fs_info_05,
- { "SMB2_FS_INFO_05", "smb2.fs_info_05", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FS_INFO_05 structure", HFILL }
+ { "FileFsAttributeInformation", "smb2.fs_attribute_info", FT_NONE, BASE_NONE,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fs_info_06,
- { "SMB2_FS_INFO_06", "smb2.fs_info_06", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FS_INFO_06 structure", HFILL }
+ { "FileFsControlInformation", "smb2.fs_control_info", FT_NONE, BASE_NONE,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fs_info_07,
- { "SMB2_FS_INFO_07", "smb2.fs_info_07", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FS_INFO_07 structure", HFILL }
+ { "FileFsFullSizeInformation", "smb2.fs_full_size_info", FT_NONE, BASE_NONE,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fs_objectid_info,
- { "SMB2_FS_OBJECTID_INFO", "smb2.fs_objectid_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_FS_OBJECTID_INFO structure", HFILL }
+ { "FileFsObjectIdInformation", "smb2.fs_objectid_info", FT_NONE, BASE_NONE,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_sec_info_00,
{ "SMB2_SEC_INFO_00", "smb2.sec_info_00", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_SEC_INFO_00 structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_quota_info,
{ "SMB2_QUOTA_INFO", "smb2.quota_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_QUOTA_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_query_quota_info,
{ "SMB2_QUERY_QUOTA_INFO", "smb2.query_quota_info", FT_NONE, BASE_NONE,
- NULL, 0, "SMB2_QUERY_QUOTA_INFO structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_qq_single,
{ &hf_smb2_FILE_OBJECTID_BUFFER,
{ "FILE_OBJECTID_BUFFER", "smb2.FILE_OBJECTID_BUFFER", FT_NONE, BASE_NONE,
- NULL, 0, "A FILE_OBJECTID_BUFFER structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_lease_key,
{ &hf_smb2_negotiate_context_type,
{ "Type", "smb2.negotiate_context.type", FT_UINT16, BASE_HEX,
- VALS(smb2_negotiate_context_types), 0, "NegotiateContext Type", HFILL }
+ VALS(smb2_negotiate_context_types), 0, NULL, HFILL }
},
{ &hf_smb2_negotiate_context_data_length,
{ "DataLength", "smb2.negotiate_context.data_length", FT_UINT16, BASE_DEC,
- NULL, 0, "NegotiateContext DataLength", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_negotiate_context_offset,
{ "NegotiateContextOffset", "smb2.negotiate_context.offset", FT_UINT16, BASE_HEX,
- NULL, 0, "NegotiateContext Offset", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_negotiate_context_count,
{ "NegotiateContextCount", "smb2.negotiate_context.count", FT_UINT16, BASE_DEC,
- NULL, 0, "NegotiateContext Count", HFILL }
+ NULL, 0, NULL, HFILL }
},
+ { &hf_smb2_hash_alg_count,
+ { "HashAlgorithmCount", "smb2.negotiate_context.hash_alg_count", FT_UINT16, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_smb2_hash_algorithm,
+ { "HashAlgorithm", "smb2.negotiate_context.hash_algorithm", FT_UINT16, BASE_HEX,
+ VALS(smb2_hash_algorithm_types), 0, NULL, HFILL }},
+
+ { &hf_smb2_salt_length,
+ { "SaltLength", "smb2.negotiate_context.salt_length", FT_UINT16, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_smb2_salt,
+ { "Salt", "smb2.negotiate_context.salt", FT_BYTES, BASE_NONE,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_smb2_cipher_count,
+ { "CipherCount", "smb2.negotiate_context.cipher_count", FT_UINT16, BASE_DEC,
+ NULL, 0, NULL, HFILL }},
+
+ { &hf_smb2_cipher_id,
+ { "CipherId", "smb2.negotiate_context.cipher_id", FT_UINT16, BASE_HEX,
+ VALS(smb2_cipher_types), 0, NULL, HFILL }},
+
{ &hf_smb2_current_time,
{ "Current Time", "smb2.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
NULL, 0, "Current Time at server", HFILL }
},
{ &hf_smb2_olb_length,
- { "Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
+ { "Blob Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
NULL, 0, "Length of the buffer", HFILL }
},
{ &hf_smb2_olb_offset,
- { "Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
+ { "Blob Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
NULL, 0, "Offset to the buffer", HFILL }
},
},
{ &hf_smb2_impersonation_level,
- { "Impersonation", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
- VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }
+ { "Impersonation level", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
+ VALS(impersonation_level_vals), 0, NULL, HFILL }
},
{ &hf_smb2_ioctl_function,
{ &hf_smb2_fsctl_odx_token_type,
{ "TokenType", "smb2.fsctl.odx.token.type", FT_UINT32, BASE_HEX,
- NULL, 0, "Token Type", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fsctl_odx_token_idlen,
{ "TokenIdLength", "smb2.fsctl.odx.token.idlen", FT_UINT16, BASE_DEC,
- NULL, 0, "Token ID Length", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fsctl_odx_token_idraw,
{ &hf_smb2_fsctl_odx_file_offset,
{ "FileOffset", "smb2.fsctl.odx.file_offset", FT_UINT64, BASE_DEC,
- NULL, 0, "File offset", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fsctl_odx_copy_length,
{ "CopyLength", "smb2.fsctl.odx.copy_length", FT_UINT64, BASE_DEC,
- NULL, 0, "Copy length", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fsctl_odx_xfer_length,
{ "TransferLength", "smb2.fsctl.odx.xfer_length", FT_UINT64, BASE_DEC,
- NULL, 0, "Length Transfered", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_fsctl_odx_token_offset,
NULL, 0, "Resiliency reserved", HFILL }
},
+ { &hf_smb2_ioctl_shared_virtual_disk_support,
+ { "SharedVirtualDiskSupport", "smb2.ioctl.shared_virtual_disk.support", FT_UINT32, BASE_HEX,
+ VALS(smb2_ioctl_shared_virtual_disk_vals), 0, "Supported shared capabilities", HFILL }
+ },
+
+ { &hf_smb2_ioctl_shared_virtual_disk_handle_state,
+ { "SharedVirtualDiskHandleState", "smb2.ioctl.shared_virtual_disk.handle_state", FT_UINT32, BASE_HEX,
+ VALS(smb2_ioctl_shared_virtual_disk_hstate_vals), 0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_protocol_version,
+ { "ProtocolVersion", "smb2.ioctl.sqos.protocol_version", FT_UINT16, BASE_HEX,
+ VALS(smb2_ioctl_sqos_protocol_version_vals), 0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_reserved,
+ { "Reserved", "smb2.ioctl.sqos.reserved", FT_UINT16, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_options,
+ { "Operations", "smb2.ioctl.sqos.operations", FT_UINT32, BASE_HEX,
+ NULL, 0, "SQOS operations", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_op_set_logical_flow_id,
+ { "Set Logical Flow ID", "smb2.ioctl.sqos.operations.set_logical_flow_id", FT_BOOLEAN, 32,
+ NULL, STORAGE_QOS_CONTROL_FLAG_SET_LOGICAL_FLOW_ID, "Whether Set Logical Flow ID operation is performed", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_op_set_policy,
+ { "Set Policy", "smb2.ioctl.sqos.operations.set_policy", FT_BOOLEAN, 32,
+ NULL, STORAGE_QOS_CONTROL_FLAG_SET_POLICY, "Whether Set Policy operation is performed", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_op_probe_policy,
+ { "Probe Policy", "smb2.ioctl.sqos.operations.probe_policy", FT_BOOLEAN, 32,
+ NULL, STORAGE_QOS_CONTROL_FLAG_PROBE_POLICY, "Whether Probe Policy operation is performed", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_op_get_status,
+ { "Get Status", "smb2.ioctl.sqos.operations.get_status", FT_BOOLEAN, 32,
+ NULL, STORAGE_QOS_CONTROL_FLAG_GET_STATUS, "Whether Get Status operation is performed", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_op_update_counters,
+ { "Update Counters", "smb2.ioctl.sqos.operations.update_counters", FT_BOOLEAN, 32,
+ NULL, STORAGE_QOS_CONTROL_FLAG_UPDATE_COUNTERS, "Whether Update Counters operation is performed", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_logical_flow_id,
+ { "LogicalFlowID", "smb2.ioctl.sqos.logical_flow_id", FT_GUID, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_policy_id,
+ { "PolicyID", "smb2.ioctl.sqos.policy_id", FT_GUID, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_initiator_id,
+ { "InitiatorID", "smb2.ioctl.sqos.initiator_id", FT_GUID, BASE_NONE,
+ NULL, 0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_limit,
+ { "Limit", "smb2.ioctl.sqos.limit", FT_UINT64, BASE_DEC,
+ NULL, 0, "Desired maximum throughput for the logical flow, in normalized IOPS", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_reservation,
+ { "Reservation", "smb2.ioctl.sqos.reservation", FT_UINT64, BASE_DEC,
+ NULL, 0, "Desired minimum throughput for the logical flow, in normalized 8KB IOPS", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_initiator_name,
+ { "InitiatorName", "smb2.ioctl.sqos.initiator_name", FT_STRING, BASE_NONE,
+ NULL, 0x0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_initiator_node_name,
+ { "InitiatorNodeName", "smb2.ioctl.sqos.initiator_node_name", FT_STRING, BASE_NONE,
+ NULL, 0x0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_io_count_increment,
+ { "IoCountIncrement", "smb2.ioctl.sqos.io_count_increment", FT_UINT64, BASE_DEC,
+ NULL, 0, "The total number of I/O requests issued by the initiator on the logical flow", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_normalized_io_count_increment,
+ { "NormalizedIoCountIncrement", "smb2.ioctl.sqos.normalized_io_count_increment", FT_UINT64, BASE_DEC,
+ NULL, 0, "The total number of normalized 8-KB I/O requests issued by the initiator on the logical flow", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_latency_increment,
+ { "LatencyIncrement", "smb2.ioctl.sqos.latency_increment", FT_UINT64, BASE_DEC,
+ NULL, 0, "The total latency (including initiator's queues delays) measured by the initiator", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_lower_latency_increment,
+ { "LowerLatencyIncrement", "smb2.ioctl.sqos.lower_latency_increment", FT_UINT64, BASE_DEC,
+ NULL, 0, "The total latency (excluding initiator's queues delays) measured by the initiator", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_bandwidth_limit,
+ { "BandwidthLimit", "smb2.ioctl.sqos.bandwidth_limit", FT_UINT64, BASE_DEC,
+ NULL, 0, "Desired maximum bandwidth for the logical flow, in kilobytes per second", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_kilobyte_count_increment,
+ { "KilobyteCountIncrement", "smb2.ioctl.sqos.kilobyte_count_increment", FT_UINT64, BASE_DEC,
+ NULL, 0, "The total data transfer length of all I/O requests, in kilobyte units, issued by the initiator on the logical flow", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_time_to_live,
+ { "TimeToLive", "smb2.ioctl.sqos.time_to_live", FT_UINT32, BASE_DEC,
+ NULL, 0, "The expected period of validity of the Status, MaximumIoRate and MinimumIoRate fields, expressed in milliseconds", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_status,
+ { "Status", "smb2.ioctl.sqos.status", FT_UINT32, BASE_HEX,
+ VALS(smb2_ioctl_sqos_status_vals), 0, "The current status of the logical flow", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_maximum_io_rate,
+ { "MaximumIoRate", "smb2.ioctl.sqos.maximum_io_rate", FT_UINT64, BASE_DEC,
+ NULL, 0, "The maximum I/O initiation rate currently assigned to the logical flow, expressed in normalized input/output operations per second (normalized IOPS)", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_minimum_io_rate,
+ { "MinimumIoRate", "smb2.ioctl.sqos.minimum_io_rate", FT_UINT64, BASE_DEC,
+ NULL, 0, "The minimum I/O completion rate currently assigned to the logical flow, expressed in normalized IOPS", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_base_io_size,
+ { "BaseIoSize", "smb2.ioctl.sqos.base_io_size", FT_UINT32, BASE_DEC,
+ NULL, 0, "The base I/O size used to compute the normalized size of an I/O request for the logical flow", HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_reserved2,
+ { "Reserved", "smb2.ioctl.sqos.reserved2", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ },
+
+ { &hf_smb2_ioctl_sqos_maximum_bandwidth,
+ { "MaximumBandwidth", "smb2.ioctl.sqos.maximum_bandwidth", FT_UINT64, BASE_DEC,
+ NULL, 0, "The maximum bandwidth currently assigned to the logical flow, expressed in kilobytes per second", HFILL }
+ },
+
+
{ &hf_windows_sockaddr_family,
{ "Socket Family", "smb2.windows.sockaddr.family", FT_UINT16, BASE_DEC,
NULL, 0, "The socket address family (on windows)", HFILL }
{ &hf_smb2_compression_format,
{ "Compression Format", "smb2.compression_format", FT_UINT16, BASE_DEC,
- VALS(compression_format_vals), 0, "Compression to use", HFILL }
+ VALS(compression_format_vals), 0, NULL, HFILL }
},
{ &hf_smb2_checksum_algorithm,
{ "Checksum Algorithm", "smb2.checksum_algorithm", FT_UINT16, BASE_HEX,
- VALS(checksum_algorithm_vals), 0, "Checksum algorithm to use", HFILL }
+ VALS(checksum_algorithm_vals), 0, NULL, HFILL }
},
{ &hf_smb2_integrity_reserved,
{ "Reserved", "smb2.integrity_reserved", FT_UINT16, BASE_DEC,
- NULL, 0, "Reserved Field", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_integrity_flags,
},
{ &hf_smb2_unknown,
- { "unknown", "smb2.unknown", FT_BYTES, BASE_NONE,
- NULL, 0, "Unknown bytes", HFILL }
+ { "Unknown", "smb2.unknown", FT_BYTES, BASE_NONE,
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_twrp_timestamp,
NULL, SES_FLAGS_NULL, NULL, HFILL }
},
+ { &hf_smb2_ses_flags_encrypt,
+ { "Encrypt", "smb2.ses_flags.encrypt", FT_BOOLEAN, 16,
+ NULL, SES_FLAGS_ENCRYPT, NULL, HFILL }},
+
{ &hf_smb2_secmode_flags_sign_required,
{ "Signing required", "smb2.sec_mode.sign_required", FT_BOOLEAN, 8,
NULL, NEGPROT_SIGN_REQ, "Is signing required", HFILL }
{ &hf_smb2_max_trans_size,
{ "Max Transaction Size", "smb2.max_trans_size", FT_UINT32, BASE_DEC,
- NULL, 0, "Maximum size of a transaction", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_max_read_size,
{ "Max Read Size", "smb2.max_read_size", FT_UINT32, BASE_DEC,
- NULL, 0, "Maximum size of a read", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_max_write_size,
{ "Max Write Size", "smb2.max_write_size", FT_UINT32, BASE_DEC,
- NULL, 0, "Maximum size of a write", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_channel,
{ &hf_smb2_reserved,
{ "Reserved", "smb2.reserved", FT_BYTES, BASE_NONE,
- NULL, 0, "Reserved bytes", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_reserved_random,
{ &hf_smb2_root_directory_mbz,
{ "Root Dir Handle (MBZ)", "smb2.root_directory", FT_BYTES, BASE_NONE,
- NULL, 0, "Root Directory Handle, mbz", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_dhnq_buffer_reserved,
},
{ &hf_smb2_svhdx_open_device_context_initiator_id,
- { "InitiatorId", "smb2.svhdx_open_device_context.initiator_id", FT_BYTES, BASE_NONE,
+ { "InitiatorId", "smb2.svhdx_open_device_context.initiator_id", FT_GUID, BASE_NONE,
NULL, 0, NULL, HFILL }
},
{ &hf_smb2_svhdx_open_device_context_originator_flags,
{ "OriginatorFlags", "smb2.svhdx_open_device_context.originator_flags", FT_UINT32, BASE_HEX,
- VALS(originator_flags_vals), 0, "Originator Flags", HFILL }
+ VALS(originator_flags_vals), 0, NULL, HFILL }
},
{ &hf_smb2_svhdx_open_device_context_open_request_id,
NULL, 0, NULL, HFILL }
},
+ { &hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized,
+ { "VirtualDiskPropertiesInitialized", "smb2.svhdx_open_device_context.virtual_disk_properties_initialized", FT_BOOLEAN, 32,
+ NULL, 0, "Whether VirtualSectorSize, PhysicalSectorSize, and VirtualSize fields are filled", HFILL }
+ },
+
+ { &hf_smb2_svhdx_open_device_context_server_service_version,
+ { "ServerServiceVersion", "smb2.svhdx_open_device_context.server_service_version", FT_UINT32, BASE_DEC,
+ NULL, 0, "The current version of the protocol running on the server", HFILL }
+ },
+
+ { &hf_smb2_svhdx_open_device_context_virtual_sector_size,
+ { "VirtualSectorSize", "smb2.svhdx_open_device_context.virtual_sector_size", FT_UINT32, BASE_DEC,
+ NULL, 0, "The virtual sector size of the virtual disk", HFILL }
+ },
+
+ { &hf_smb2_svhdx_open_device_context_physical_sector_size,
+ { "PhysicalSectorSize", "smb2.svhdx_open_device_context.physical_sector_size", FT_UINT32, BASE_DEC,
+ NULL, 0, "The physical sector size of the virtual disk", HFILL }
+ },
+
+ { &hf_smb2_svhdx_open_device_context_virtual_size,
+ { "VirtualSize", "smb2.svhdx_open_device_context.virtual_size", FT_UINT64, BASE_DEC,
+ NULL, 0, "The current length of the virtual disk, in bytes", HFILL }
+ },
+
{ &hf_smb2_posix_v1_version,
{ "Version", "smb2.posix_v1_version", FT_UINT32, BASE_DEC,
NULL, 0, NULL, HFILL }
},
{ &hf_smb2_aapl_server_query_caps_supports_osx_copyfile,
- { "Supports OS X copyfile", "smb2.aapl.caps.supports_osx_copyfile", FT_BOOLEAN, 64,
+ { "Supports macOS copyfile", "smb2.aapl.caps.supports_osx_copyfile", FT_BOOLEAN, 64,
NULL, SMB2_AAPL_SUPPORTS_OSX_COPYFILE, NULL, HFILL }
},
{ &hf_smb2_pipe_fragment_overlap_conflict,
{ "Conflicting data in fragment overlap", "smb2.pipe.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE,
- NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }
+ NULL, 0x0, NULL, HFILL }
},
{ &hf_smb2_pipe_fragment_multiple_tails,
{ &hf_smb2_pipe_fragment,
{ "Fragment SMB2 Named Pipe", "smb2.pipe.fragment", FT_FRAMENUM, BASE_NONE,
- NULL, 0x0, "SMB2 Named Pipe Fragment", HFILL }
+ NULL, 0x0, NULL, HFILL }
},
{ &hf_smb2_pipe_fragments,
{ "Reassembled SMB2 Named Pipe fragments", "smb2.pipe.fragments", FT_NONE, BASE_NONE,
- NULL, 0x0, "SMB2 Named Pipe Fragments", HFILL }
+ NULL, 0x0, NULL, HFILL }
},
{ &hf_smb2_pipe_reassembled_in,
{ &hf_smb2_symlink_error_response,
{ "Symbolic Link Error Response", "smb2.symlink_error_response", FT_NONE, BASE_NONE,
- NULL, 0, "A Symbolic Link Error Response structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_symlink_length,
{ &hf_smb2_SYMBOLIC_LINK_REPARSE_DATA_BUFFER,
{ "SYMBOLIC_LINK_REPARSE_DATA_BUFFER", "smb2.SYMBOLIC_LINK_REPARSE_DATA_BUFFER", FT_NONE, BASE_NONE,
- NULL, 0, "A SYMBOLIC_LINK_REPARSE_DATA_BUFFER structure", HFILL }
+ NULL, 0, NULL, HFILL }
},
{ &hf_smb2_reparse_tag,
{ "Reparse Tag", "smb2.symlink.reparse_tag", FT_UINT32, BASE_HEX,
&ett_smb2_share_caps,
&ett_smb2_ioctl_flags,
&ett_smb2_ioctl_network_interface,
+ &ett_smb2_ioctl_sqos_opeations,
&ett_smb2_fsctl_range_data,
&ett_windows_sockaddr,
&ett_smb2_close_flags,
static ei_register_info ei[] = {
{ &ei_smb2_invalid_length, { "smb2.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
{ &ei_smb2_bad_response, { "smb2.bad_response", PI_MALFORMED, PI_ERROR, "Bad response", EXPFILL }},
+ { &ei_smb2_invalid_getinfo_offset, { "smb2.invalid_getinfo_offset", PI_MALFORMED, PI_ERROR, "Input buffer offset isn't past the fixed data in the message", EXPFILL }},
+ { &ei_smb2_invalid_getinfo_size, { "smb2.invalid_getinfo_size", PI_MALFORMED, PI_ERROR, "Input buffer length goes past the end of the message", EXPFILL }},
+ { &ei_smb2_empty_getinfo_buffer, { "smb2.empty_getinfo_buffer", PI_PROTOCOL, PI_WARN, "Input buffer length is empty for a quota request", EXPFILL }},
};
expert_module_t* expert_smb2;
+ /* SessionID <=> SessionKey mappings for decryption */
+ uat_t *seskey_uat;
+
+ static uat_field_t seskey_uat_fields[] = {
+ UAT_FLD_BUFFER(seskey_list, id, "Session ID", "The session ID buffer, coded as hex string, as it appears on the wire (LE)."),
+ UAT_FLD_BUFFER(seskey_list, key, "Session Key", "The secret session key buffer, coded as 16-byte hex string as it appears on the wire (LE)."),
+ UAT_END_FIELDS
+ };
+
proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
"SMB2", "smb2");
proto_register_subtree_array(ett, array_length(ett));
"Reassemble Named Pipes over SMB2",
"Whether the dissector should reassemble Named Pipes over SMB2 commands",
&smb2_pipe_reassembly);
+
+ seskey_uat = uat_new("Secret session key to use for decryption",
+ sizeof(smb2_seskey_field_t),
+ "smb2_seskey_list",
+ TRUE,
+ &seskey_list,
+ &num_seskey_list,
+ (UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS),
+ NULL,
+ seskey_list_copy_cb,
+ seskey_list_update_cb,
+ seskey_list_free_cb,
+ NULL,
+ NULL,
+ seskey_uat_fields);
+
+ prefs_register_uat_preference(smb2_module,
+ "seskey_list",
+ "Secret session keys for decryption",
+ "A table of Session ID to Session key mappings used to derive decryption keys.",
+ seskey_uat);
+
smb2_pipe_subdissector_list = register_heur_dissector_list("smb2_pipe_subdissectors", proto_smb2);
- register_init_routine(smb2_pipe_reassembly_init);
+ /*
+ * XXX - addresses_ports_reassembly_table_functions?
+ * Probably correct for SMB-over-NBT and SMB-over-TCP,
+ * as stuff from two different connections should
+ * probably not be combined, but what about other
+ * transports for SMB, e.g. NBF or Netware?
+ */
+ reassembly_table_register(&smb2_pipe_reassembly_table,
+ &addresses_reassembly_table_functions);
smb2_tap = register_tap("smb2");
smb2_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */