I have captures with w2k speaking DCERPC without using the normal
Transaction named pipes SMBs.
Instead DCERPC is just implemented ontop of ordinary read/write calls.
The smb dissector now examines TreeConnectAndX and stores the conversation/tid/type-of-share in a table for later access.
All SMB requests examine that hash table to find out if TID in the header refers
to a normal share or an IPC$ share.
Initial support in read/write SMB calls to detect if the operations are for an
IPC share and thus it assumes it must be DCERPC commands in the payload.
Desegmentation/Reassembly of these types of calls are not implemented yet.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@4952
f5534014-38df-0310-8fa8-
9805f1628bb7
* significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and
* Guy Harris 2001
*
* significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and
* Guy Harris 2001
*
- * $Id: packet-smb-pipe.c,v 1.70 2002/03/15 08:59:52 sahlberg Exp $
+ * $Id: packet-smb-pipe.c,v 1.71 2002/03/16 04:39:28 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
static heur_dissector_list_t smb_transact_heur_subdissector_list;
static heur_dissector_list_t smb_transact_heur_subdissector_list;
dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
proto_tree *tree, guint32 fid)
{
dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
proto_tree *tree, guint32 fid)
{
* Declarations of routines for SMB named pipe packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
* Declarations of routines for SMB named pipe packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
- * $Id: packet-smb-pipe.h,v 1.9 2001/11/19 11:41:51 guy Exp $
+ * $Id: packet-smb-pipe.h,v 1.10 2002/03/16 04:39:28 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
packet_info *pinfo, proto_tree *tree);
dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
packet_info *pinfo, proto_tree *tree);
+gboolean
+dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
+ proto_tree *tree, guint32 fid);
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
* 2001 Rewrite by Ronnie Sahlberg and Guy Harris
*
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
* 2001 Rewrite by Ronnie Sahlberg and Guy Harris
*
- * $Id: packet-smb.c,v 1.219 2002/03/15 19:47:03 sharpe Exp $
+ * $Id: packet-smb.c,v 1.220 2002/03/16 04:39:29 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
guint32 ofs=0;
dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
guint32 ofs=0;
- guint16 cnt=0, bc, fid;
+ guint16 cnt=0, bc, fid=0;
+ smb_info_t *si = (smb_info_t *)pinfo->private_data;
COUNT_BYTES(2);
if (bc != 0) {
COUNT_BYTES(2);
if (bc != 0) {
- /* file data */
- offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
+ if( (si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
+ tvbuff_t *dcerpc_tvb;
+ /* dcerpc call */
+ dcerpc_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), bc);
+ dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree,
+ tree, fid);
+ } else {
+ /* ordinary file data */
+ offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
+ }
guint8 wc, cmd=0xff;
guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
smb_info_t *si = (smb_info_t *)pinfo->private_data;
guint8 wc, cmd=0xff;
guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
smb_info_t *si = (smb_info_t *)pinfo->private_data;
/* If we have seen the request, then print which FID this refers to */
/* first check if we have seen the request */
if(si->sip != NULL && si->sip->frame_req>0){
/* If we have seen the request, then print which FID this refers to */
/* first check if we have seen the request */
if(si->sip != NULL && si->sip->frame_req>0){
- add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
+ fid=(int)si->sip->extra_info;
+ add_fid(tvb, pinfo, tree, 0, 0, fid);
- /* file data */
- offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
- bc = 0;
+ /* another way to transport DCERPC over SMB is to skip Transaction completely and just
+ read write */
+ if(bc){
+ if(si->sip->flags&SMB_SIF_TID_IS_IPC){
+ tvbuff_t *dcerpc_tvb;
+ /* dcerpc call */
+ dcerpc_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), bc);
+ dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree,
+ tree, fid);
+ } else {
+ /* ordinary file data */
+ offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
+ }
+ bc = 0;
+ }
offset, an_len, an);
COUNT_BYTES(an_len);
offset, an_len, an);
COUNT_BYTES(an_len);
+ /* Now when we know the service type, store it so that we know it for later commands down
+ this tree */
+ if(!pinfo->fd->flags.visited){
+ smb_info_t *si = (smb_info_t *)pinfo->private_data;
+ /* Remove any previous entry for this TID */
+ if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
+ g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
+ }
+ if(!strcmp(an,"IPC")){
+ g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
+ } else {
+ g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
+ }
+ }
+
+
if(wc==3){
if (bc != 0) {
/*
if(wc==3){
if (bc != 0) {
/*
g_hash_table_destroy(ct->matched);
if (ct->dcerpc_fid_to_frame)
g_hash_table_destroy(ct->dcerpc_fid_to_frame);
g_hash_table_destroy(ct->matched);
if (ct->dcerpc_fid_to_frame)
g_hash_table_destroy(ct->dcerpc_fid_to_frame);
+ if (ct->tid_service)
+ g_hash_table_destroy(ct->tid_service);
guint32 nt_status = 0;
guint8 errclass = 0;
guint16 errcode = 0;
guint32 nt_status = 0;
guint8 errclass = 0;
guint16 errcode = 0;
- guint16 uid, pid, tid, mid;
guint32 pid_mid;
conversation_t *conversation;
guint32 pid_mid;
conversation_t *conversation;
} else {
si.unicode = FALSE;
}
} else {
si.unicode = FALSE;
}
- tid = tvb_get_letohs(tvb, offset+24);
- pid = tvb_get_letohs(tvb, offset+26);
- uid = tvb_get_letohs(tvb, offset+28);
- mid = tvb_get_letohs(tvb, offset+30);
- pid_mid = (pid << 16) | mid;
+ si.tid = tvb_get_letohs(tvb, offset+24);
+ si.pid = tvb_get_letohs(tvb, offset+26);
+ si.uid = tvb_get_letohs(tvb, offset+28);
+ si.mid = tvb_get_letohs(tvb, offset+30);
+ pid_mid = (si.pid << 16) | si.mid;
si.info_level = -1;
si.info_count = -1;
si.info_level = -1;
si.info_count = -1;
si.ct->dcerpc_fid_to_frame=g_hash_table_new(
smb_saved_info_hash_unmatched,
smb_saved_info_equal_unmatched);
si.ct->dcerpc_fid_to_frame=g_hash_table_new(
smb_saved_info_hash_unmatched,
smb_saved_info_equal_unmatched);
+ si.ct->tid_service=g_hash_table_new(
+ smb_saved_info_hash_unmatched,
+ smb_saved_info_equal_unmatched);
conversation_add_proto_data(conversation, proto_smb, si.ct);
}
if( (si.request)
conversation_add_proto_data(conversation, proto_smb, si.ct);
}
if( (si.request)
- && (mid==0)
- && (uid==0)
- && (pid==0)
- && (tid==0) ){
+ && (si.mid==0)
+ && (si.uid==0)
+ && (si.pid==0)
+ && (si.tid==0) ){
/* this is a broadcast SMB packet, there will not be a reply.
We dont need to do anything
*/
/* this is a broadcast SMB packet, there will not be a reply.
We dont need to do anything
*/
sip = g_mem_chunk_alloc(smb_saved_info_chunk);
sip->frame_req = pinfo->fd->num;
sip->frame_res = 0;
sip = g_mem_chunk_alloc(smb_saved_info_chunk);
sip->frame_req = pinfo->fd->num;
sip->frame_res = 0;
+ sip->flags = 0;
+ if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)){
+ sip->flags |= SMB_SIF_TID_IS_IPC;
+ }
sip->cmd = si.cmd;
sip->extra_info = NULL;
g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
sip->cmd = si.cmd;
sip->extra_info = NULL;
g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
- proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, tid);
+ proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
- proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, pid);
+ proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
- proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, uid);
+ proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
- proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, mid);
+ proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
offset += 2;
pinfo->private_data = &si;
offset += 2;
pinfo->private_data = &si;
* Defines for smb packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
* Defines for smb packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
- * $Id: smb.h,v 1.35 2002/03/15 08:59:53 sahlberg Exp $
+ * $Id: smb.h,v 1.36 2002/03/16 04:39:29 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* The information we need to save about a request in order to show the
* frame number of the request in the dissection of the reply.
*/
* The information we need to save about a request in order to show the
* frame number of the request in the dissection of the reply.
*/
+#define SMB_SIF_TID_IS_IPC 0x0001
typedef struct {
guint32 frame_req, frame_res;
typedef struct {
guint32 frame_req, frame_res;
int cmd;
void *extra_info;
} smb_saved_info_t;
int cmd;
void *extra_info;
} smb_saved_info_t;
#define TRANSACTION_PIPE 0
#define TRANSACTION_MAILSLOT 1
#define TRANSACTION_PIPE 0
#define TRANSACTION_MAILSLOT 1
+/* these are defines used to represent different types of TIDs.
+ dont use the value 0 for any of these */
+#define TID_NORMAL 1
+#define TID_IPC 2
+
/* this is the structure which is associated with each conversation */
typedef struct conv_tables {
/* these two tables are used to match requests with responses */
/* this is the structure which is associated with each conversation */
typedef struct conv_tables {
/* these two tables are used to match requests with responses */
GHashTable *matched;
/* this tables is used by DCERPC over SMB reassembly*/
GHashTable *dcerpc_fid_to_frame;
GHashTable *matched;
/* this tables is used by DCERPC over SMB reassembly*/
GHashTable *dcerpc_fid_to_frame;
+ /* This table is used to track TID->services for a conversation */
+ GHashTable *tid_service;
} conv_tables_t;
typedef struct smb_info {
int cmd;
} conv_tables_t;
typedef struct smb_info {
int cmd;
+ int tid, pid, uid, mid;
gboolean unicode; /* Are strings in this SMB Unicode? */
gboolean request; /* Is this a request? */
gboolean unidir;
gboolean unicode; /* Are strings in this SMB Unicode? */
gboolean request; /* Is this a request? */
gboolean unidir;