aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>2005-11-12 08:48:02 +0000
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>2005-11-12 08:48:02 +0000
commit87826ddbdb4bd626ad631328b6beb86a79b85978 (patch)
treeed0dad748e84821397035c4c1b74f8fb9feabfd4 /epan/dissectors
parent7c3b0a0d6d82fc27a103e7c93e89b5c77da56a58 (diff)
add initial decode of dcerpc over smb2
it does not yet multiplex between different files but it is better than nothing git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@16484 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-dcerpc.c8
-rw-r--r--epan/dissectors/packet-smb2.c62
-rw-r--r--epan/dissectors/packet-smb2.h12
3 files changed, 74 insertions, 8 deletions
diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c
index ebd0cfda2c..2f19341903 100644
--- a/epan/dissectors/packet-dcerpc.c
+++ b/epan/dissectors/packet-dcerpc.c
@@ -4209,6 +4209,13 @@ dissect_dcerpc_cn_smbpipe (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
return dissect_dcerpc_cn_bs_body(tvb, pinfo, tree);
}
+static gboolean
+dissect_dcerpc_cn_smb2 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ pinfo->dcetransporttype=DCE_TRANSPORT_UNKNOWN;
+ return dissect_dcerpc_cn_bs_body(tvb, pinfo, tree);
+}
+
static void
@@ -5415,6 +5422,7 @@ proto_reg_handoff_dcerpc (void)
heur_dissector_add ("netbios", dissect_dcerpc_cn_pk, proto_dcerpc);
heur_dissector_add ("udp", dissect_dcerpc_dg, proto_dcerpc);
heur_dissector_add ("smb_transact", dissect_dcerpc_cn_smbpipe, proto_dcerpc);
+ heur_dissector_add ("smb2_heur_subdissectors", dissect_dcerpc_cn_smb2, proto_dcerpc);
heur_dissector_add ("http", dissect_dcerpc_cn_bs, proto_dcerpc);
dcerpc_smb_init(proto_dcerpc);
}
diff --git a/epan/dissectors/packet-smb2.c b/epan/dissectors/packet-smb2.c
index 54820cb82e..1c8010686c 100644
--- a/epan/dissectors/packet-smb2.c
+++ b/epan/dissectors/packet-smb2.c
@@ -45,6 +45,7 @@
#include "packet-windows-common.h"
#include "packet-smb-common.h"
#include "packet-dcerpc-nt.h"
+#include <string.h>
@@ -115,6 +116,8 @@ static gint ett_smb2_tid_tree = -1;
static dissector_handle_t gssapi_handle = NULL;
+static heur_dissector_list_t smb2_heur_subdissector_list;
+
#define SMB2_CLASS_FILE_INFO 0x01
#define SMB2_CLASS_FS_INFO 0x02
#define SMB2_CLASS_SEC_INFO 0x03
@@ -614,8 +617,18 @@ dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
}
tid=se_alloc(sizeof(smb2_tid_info_t));
tid->tid=si->tid;
- tid->flags=0;
tid->name=(char *)si->saved->private_data;
+ tid->flags=0;
+ if(strlen(tid->name)>=4){
+ if(!strcmp(tid->name+strlen(tid->name)-4, "IPC$")){
+ tid->flags|=SMB2_FLAGS_TID_IS_IPC;
+ } else {
+ tid->flags|=SMB2_FLAGS_TID_IS_NOT_IPC;
+ }
+ } else {
+ tid->flags|=SMB2_FLAGS_TID_IS_NOT_IPC;
+ }
+
g_hash_table_insert(si->conv->tids, tid, tid);
si->saved->private_data=NULL;
@@ -931,7 +944,26 @@ dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
}
+static int
+dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint32 datalen, smb2_info_t *si)
+{
+ int tvblen;
+ int result;
+
+ tvbuff_t *dcerpc_tvb;
+ tvblen = tvb_length_remaining(tvb, offset);
+ dcerpc_tvb = tvb_new_subset(tvb, offset, MIN(datalen, tvb_length_remaining(tvb, offset)), datalen);
+
+ /* dissect the full PDU */
+ result = dissector_try_heuristic(smb2_heur_subdissector_list, dcerpc_tvb, pinfo, si->top_tree);
+
+ offset += datalen;
+
+ return offset;
+}
+
+
static int
dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
{
@@ -958,7 +990,14 @@ dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
offset += 16;
- /* data */
+
+ /* data or dcerpc ?*/
+ if(length && si->tree && si->tree->flags&SMB2_FLAGS_TID_IS_IPC ){
+ offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si);
+ return offset;
+ }
+
+ /* just ordinary data */
proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, TRUE);
offset += MIN(length,(guint32)tvb_length_remaining(tvb, offset));
@@ -1033,6 +1072,12 @@ dissect_smb2_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, TRUE);
offset += 8;
+ /* data or dcerpc ?*/
+ if(length && si->tree && si->tree->flags&SMB2_FLAGS_TID_IS_IPC ){
+ offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si);
+ return offset;
+ }
+
/* data */
proto_tree_add_item(tree, hf_smb2_read_data, tvb, offset, length, TRUE);
offset += MIN(length,(guint32)tvb_length_remaining(tvb, offset));
@@ -1799,7 +1844,7 @@ dissect_smb2_tid(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
{
proto_item *tid_item=NULL;
proto_tree *tid_tree=NULL;
- smb2_tid_info_t *tid, tid_key;
+ smb2_tid_info_t tid_key;
/* Tree ID */
si->tid=tvb_get_letohl(tvb, offset);
@@ -1810,9 +1855,9 @@ dissect_smb2_tid(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
/* see if we can find the name for this tid */
tid_key.tid=si->tid;
- tid=g_hash_table_lookup(si->conv->tids, &tid_key);
- if(tid){
- proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, offset, 4, tid->name);
+ si->tree=g_hash_table_lookup(si->conv->tids, &tid_key);
+ if(si->tree){
+ proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, offset, 4, si->tree->name);
}
offset += 4;
@@ -1837,7 +1882,8 @@ dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
si=ep_alloc(sizeof(smb2_info_t));
si->conv=NULL;
si->saved=NULL;
-
+ si->tree=NULL;
+ si->top_tree=parent_tree;
/* find which conversation we are part of and get the data for that
* conversation
@@ -2262,6 +2308,8 @@ proto_register_smb2(void)
"SMB2", "smb2");
proto_register_subtree_array(ett, array_length(ett));
proto_register_field_array(proto_smb2, hf, array_length(hf));
+
+ register_heur_dissector_list("smb2_heur_subdissectors", &smb2_heur_subdissector_list);
}
void
diff --git a/epan/dissectors/packet-smb2.h b/epan/dissectors/packet-smb2.h
index 55a5b8e6cb..eb989b6722 100644
--- a/epan/dissectors/packet-smb2.h
+++ b/epan/dissectors/packet-smb2.h
@@ -50,7 +50,15 @@ typedef struct _smb2_saved_info_t {
nstime_t req_time;
} smb2_saved_info_t;
-#define SMB2_FLAGS_TID_IS_IPC 0x00000001
+/* at most one of these two bits may be set.
+ * if ipc$ status is unknown none is set.
+ *
+ * if the tid name ends with "IPC$" we assume that all files on this tid
+ * are dcerpc pipes.
+ */
+#define SMB2_FLAGS_TID_IS_IPC 0x00000001
+#define SMB2_FLAGS_TID_IS_NOT_IPC 0x00000002
+
typedef struct _smb2_tid_info_t {
guint32 tid;
guint32 flags;
@@ -79,6 +87,8 @@ typedef struct _smb2_info_t {
gboolean response; /* is this a response ? */
smb2_conv_info_t *conv;
smb2_saved_info_t *saved;
+ smb2_tid_info_t *tree;
+ proto_tree *top_tree;
} smb2_info_t;
#endif