from todd s
update to reassembly of dg style dcerpc svn path=/trunk/; revision=11227
This commit is contained in:
parent
479f535db3
commit
48643ea768
142
packet-dcerpc.c
142
packet-dcerpc.c
|
@ -3,7 +3,7 @@
|
|||
* Copyright 2001, Todd Sabin <tas@webspan.net>
|
||||
* Copyright 2003, Tim Potter <tpot@samba.org>
|
||||
*
|
||||
* $Id: packet-dcerpc.c,v 1.179 2004/06/09 09:24:06 sahlberg Exp $
|
||||
* $Id: packet-dcerpc.c,v 1.180 2004/06/24 07:43:24 sahlberg Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -489,7 +489,7 @@ static void
|
|||
dcerpc_reassemble_init(void)
|
||||
{
|
||||
fragment_table_init(&dcerpc_co_reassemble_table);
|
||||
fragment_table_init(&dcerpc_cl_reassemble_table);
|
||||
dcerpc_fragment_table_init(&dcerpc_cl_reassemble_table);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -782,35 +782,66 @@ dcerpc_bind_hash (gconstpointer k)
|
|||
* To keep track of callid mappings. Should really use some generic
|
||||
* conversation support instead.
|
||||
*/
|
||||
static GHashTable *dcerpc_calls=NULL;
|
||||
static GHashTable *dcerpc_cn_calls=NULL;
|
||||
static GHashTable *dcerpc_dg_calls=NULL;
|
||||
|
||||
typedef struct _dcerpc_call_key {
|
||||
typedef struct _dcerpc_cn_call_key {
|
||||
conversation_t *conv;
|
||||
guint32 call_id;
|
||||
guint16 smb_fid;
|
||||
} dcerpc_call_key;
|
||||
} dcerpc_cn_call_key;
|
||||
|
||||
static GMemChunk *dcerpc_call_key_chunk=NULL;
|
||||
typedef struct _dcerpc_dg_call_key {
|
||||
conversation_t *conv;
|
||||
guint32 seqnum;
|
||||
e_uuid_t act_id ;
|
||||
} dcerpc_dg_call_key;
|
||||
|
||||
static GMemChunk *dcerpc_cn_call_key_chunk=NULL;
|
||||
|
||||
static GMemChunk *dcerpc_dg_call_key_chunk=NULL;
|
||||
|
||||
static GMemChunk *dcerpc_call_value_chunk=NULL;
|
||||
|
||||
|
||||
static gint
|
||||
dcerpc_call_equal (gconstpointer k1, gconstpointer k2)
|
||||
dcerpc_cn_call_equal (gconstpointer k1, gconstpointer k2)
|
||||
{
|
||||
const dcerpc_call_key *key1 = (const dcerpc_call_key *)k1;
|
||||
const dcerpc_call_key *key2 = (const dcerpc_call_key *)k2;
|
||||
const dcerpc_cn_call_key *key1 = (const dcerpc_cn_call_key *)k1;
|
||||
const dcerpc_cn_call_key *key2 = (const dcerpc_cn_call_key *)k2;
|
||||
return (key1->conv == key2->conv
|
||||
&& key1->call_id == key2->call_id
|
||||
&& key1->smb_fid == key2->smb_fid);
|
||||
}
|
||||
|
||||
static guint
|
||||
dcerpc_call_hash (gconstpointer k)
|
||||
static gint
|
||||
dcerpc_dg_call_equal (gconstpointer k1, gconstpointer k2)
|
||||
{
|
||||
const dcerpc_call_key *key = (const dcerpc_call_key *)k;
|
||||
const dcerpc_dg_call_key *key1 = (const dcerpc_dg_call_key *)k1;
|
||||
const dcerpc_dg_call_key *key2 = (const dcerpc_dg_call_key *)k2;
|
||||
return (key1->conv == key2->conv
|
||||
&& key1->seqnum == key2->seqnum
|
||||
&& (memcmp (&key1->act_id, &key2->act_id, sizeof (e_uuid_t)) == 0));
|
||||
}
|
||||
|
||||
static guint
|
||||
dcerpc_cn_call_hash (gconstpointer k)
|
||||
{
|
||||
const dcerpc_cn_call_key *key = (const dcerpc_cn_call_key *)k;
|
||||
return ((guint32)key->conv) + key->call_id + key->smb_fid;
|
||||
}
|
||||
|
||||
static guint
|
||||
dcerpc_dg_call_hash (gconstpointer k)
|
||||
{
|
||||
const dcerpc_dg_call_key *key = (const dcerpc_dg_call_key *)k;
|
||||
return (((guint32)key->conv) + key->seqnum + key->act_id.Data1
|
||||
+ (key->act_id.Data2 << 16) + key->act_id.Data3
|
||||
+ (key->act_id.Data4[0] << 24) + (key->act_id.Data4[1] << 16)
|
||||
+ (key->act_id.Data4[2] << 8) + (key->act_id.Data4[3] << 0)
|
||||
+ (key->act_id.Data4[4] << 24) + (key->act_id.Data4[5] << 16)
|
||||
+ (key->act_id.Data4[6] << 8) + (key->act_id.Data4[7] << 0));
|
||||
}
|
||||
|
||||
/* to keep track of matched calls/responses
|
||||
this one uses the same value struct as calls, but the key is the frame id
|
||||
|
@ -2846,20 +2877,20 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
|
||||
if((bind_value=g_hash_table_lookup(dcerpc_binds, &bind_key)) ){
|
||||
if(!(hdr->flags&PFC_FIRST_FRAG)){
|
||||
dcerpc_call_key call_key;
|
||||
dcerpc_cn_call_key call_key;
|
||||
dcerpc_call_value *call_value;
|
||||
|
||||
call_key.conv=conv;
|
||||
call_key.call_id=hdr->call_id;
|
||||
call_key.smb_fid=get_transport_salt(pinfo, transport_type);
|
||||
if((call_value=g_hash_table_lookup(dcerpc_calls, &call_key))){
|
||||
if((call_value=g_hash_table_lookup(dcerpc_cn_calls, &call_key))){
|
||||
new_matched_key = g_mem_chunk_alloc(dcerpc_matched_key_chunk);
|
||||
*new_matched_key = matched_key;
|
||||
g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
|
||||
value = call_value;
|
||||
}
|
||||
} else {
|
||||
dcerpc_call_key *call_key;
|
||||
dcerpc_cn_call_key *call_key;
|
||||
dcerpc_call_value *call_value;
|
||||
|
||||
/* We found the binding and it is the first fragment
|
||||
|
@ -2867,15 +2898,15 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
the call to both the call table and the
|
||||
matched table
|
||||
*/
|
||||
call_key=g_mem_chunk_alloc (dcerpc_call_key_chunk);
|
||||
call_key=g_mem_chunk_alloc (dcerpc_cn_call_key_chunk);
|
||||
call_key->conv=conv;
|
||||
call_key->call_id=hdr->call_id;
|
||||
call_key->smb_fid=get_transport_salt(pinfo, transport_type);
|
||||
|
||||
/* if there is already a matching call in the table
|
||||
remove it so it is replaced with the new one */
|
||||
if(g_hash_table_lookup(dcerpc_calls, call_key)){
|
||||
g_hash_table_remove(dcerpc_calls, call_key);
|
||||
if(g_hash_table_lookup(dcerpc_cn_calls, call_key)){
|
||||
g_hash_table_remove(dcerpc_cn_calls, call_key);
|
||||
}
|
||||
|
||||
call_value=g_mem_chunk_alloc (dcerpc_call_value_chunk);
|
||||
|
@ -2888,7 +2919,7 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
call_value->rep_frame=0;
|
||||
call_value->max_ptr=0;
|
||||
call_value->private_data = NULL;
|
||||
g_hash_table_insert (dcerpc_calls, call_key, call_value);
|
||||
g_hash_table_insert (dcerpc_cn_calls, call_key, call_value);
|
||||
|
||||
new_matched_key = g_mem_chunk_alloc(dcerpc_matched_key_chunk);
|
||||
*new_matched_key = matched_key;
|
||||
|
@ -2976,14 +3007,14 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
matched_key.call_id = hdr->call_id;
|
||||
value=g_hash_table_lookup(dcerpc_matched, &matched_key);
|
||||
if(!value){
|
||||
dcerpc_call_key call_key;
|
||||
dcerpc_cn_call_key call_key;
|
||||
dcerpc_call_value *call_value;
|
||||
|
||||
call_key.conv=conv;
|
||||
call_key.call_id=hdr->call_id;
|
||||
call_key.smb_fid=get_transport_salt(pinfo, transport_type);
|
||||
|
||||
if((call_value=g_hash_table_lookup(dcerpc_calls, &call_key))){
|
||||
if((call_value=g_hash_table_lookup(dcerpc_cn_calls, &call_key))){
|
||||
new_matched_key = g_mem_chunk_alloc(dcerpc_matched_key_chunk);
|
||||
*new_matched_key = matched_key;
|
||||
g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
|
||||
|
@ -3088,14 +3119,14 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
matched_key.call_id = hdr->call_id;
|
||||
value=g_hash_table_lookup(dcerpc_matched, &matched_key);
|
||||
if(!value){
|
||||
dcerpc_call_key call_key;
|
||||
dcerpc_cn_call_key call_key;
|
||||
dcerpc_call_value *call_value;
|
||||
|
||||
call_key.conv=conv;
|
||||
call_key.call_id=hdr->call_id;
|
||||
call_key.smb_fid=get_transport_salt(pinfo, transport_type);
|
||||
|
||||
if((call_value=g_hash_table_lookup(dcerpc_calls, &call_key))){
|
||||
if((call_value=g_hash_table_lookup(dcerpc_cn_calls, &call_key))){
|
||||
new_matched_key = g_mem_chunk_alloc(dcerpc_matched_key_chunk);
|
||||
*new_matched_key = matched_key;
|
||||
g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
|
||||
|
@ -3836,10 +3867,8 @@ dissect_dcerpc_dg_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
}
|
||||
}
|
||||
|
||||
fd_head = fragment_add_seq(tvb, offset, pinfo,
|
||||
/* XXX - simply adding the activity id to the sequence number might be unique enough
|
||||
* to build a meaningful hash value here?! */
|
||||
hdr->seqnum + dcerpc_uuid_hash(&hdr->act_id), dcerpc_cl_reassemble_table,
|
||||
fd_head = fragment_add_dcerpc(tvb, offset, pinfo,
|
||||
hdr->seqnum, &hdr->act_id, dcerpc_cl_reassemble_table,
|
||||
hdr->frag_num, stub_length,
|
||||
!(hdr->flags1 & PFCL1_LASTFRAG));
|
||||
if (fd_head != NULL) {
|
||||
|
@ -3881,8 +3910,7 @@ dissect_dcerpc_dg_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
static void
|
||||
dissect_dcerpc_dg_rqst (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
proto_tree *dcerpc_tree, proto_tree *tree,
|
||||
e_dce_dg_common_hdr_t *hdr, conversation_t *conv,
|
||||
int transport_type)
|
||||
e_dce_dg_common_hdr_t *hdr, conversation_t *conv)
|
||||
{
|
||||
dcerpc_info *di;
|
||||
dcerpc_call_value *value, v;
|
||||
|
@ -3892,12 +3920,12 @@ dissect_dcerpc_dg_rqst (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
di=get_next_di();
|
||||
if(!(pinfo->fd->flags.visited)){
|
||||
dcerpc_call_value *call_value;
|
||||
dcerpc_call_key *call_key;
|
||||
dcerpc_dg_call_key *call_key;
|
||||
|
||||
call_key=g_mem_chunk_alloc (dcerpc_call_key_chunk);
|
||||
call_key=g_mem_chunk_alloc (dcerpc_dg_call_key_chunk);
|
||||
call_key->conv=conv;
|
||||
call_key->call_id=hdr->seqnum;
|
||||
call_key->smb_fid=get_transport_salt(pinfo, transport_type);
|
||||
call_key->seqnum=hdr->seqnum;
|
||||
call_key->act_id=hdr->act_id;
|
||||
|
||||
call_value=g_mem_chunk_alloc (dcerpc_call_value_chunk);
|
||||
call_value->uuid = hdr->if_id;
|
||||
|
@ -3909,7 +3937,7 @@ dissect_dcerpc_dg_rqst (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
call_value->rep_frame=0;
|
||||
call_value->max_ptr=0;
|
||||
call_value->private_data = NULL;
|
||||
g_hash_table_insert (dcerpc_calls, call_key, call_value);
|
||||
g_hash_table_insert (dcerpc_dg_calls, call_key, call_value);
|
||||
|
||||
new_matched_key = g_mem_chunk_alloc(dcerpc_matched_key_chunk);
|
||||
new_matched_key->frame = pinfo->fd->num;
|
||||
|
@ -3948,8 +3976,7 @@ dissect_dcerpc_dg_rqst (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
static void
|
||||
dissect_dcerpc_dg_resp (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
proto_tree *dcerpc_tree, proto_tree *tree,
|
||||
e_dce_dg_common_hdr_t *hdr, conversation_t *conv,
|
||||
int transport_type)
|
||||
e_dce_dg_common_hdr_t *hdr, conversation_t *conv)
|
||||
{
|
||||
dcerpc_info *di;
|
||||
dcerpc_call_value *value, v;
|
||||
|
@ -3959,13 +3986,13 @@ dissect_dcerpc_dg_resp (tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
di=get_next_di();
|
||||
if(!(pinfo->fd->flags.visited)){
|
||||
dcerpc_call_value *call_value;
|
||||
dcerpc_call_key call_key;
|
||||
dcerpc_dg_call_key call_key;
|
||||
|
||||
call_key.conv=conv;
|
||||
call_key.call_id=hdr->seqnum;
|
||||
call_key.smb_fid=get_transport_salt(pinfo, transport_type);
|
||||
call_key.seqnum=hdr->seqnum;
|
||||
call_key.act_id=hdr->act_id;
|
||||
|
||||
if((call_value=g_hash_table_lookup(dcerpc_calls, &call_key))){
|
||||
if((call_value=g_hash_table_lookup(dcerpc_dg_calls, &call_key))){
|
||||
new_matched_key = g_mem_chunk_alloc(dcerpc_matched_key_chunk);
|
||||
new_matched_key->frame = pinfo->fd->num;
|
||||
new_matched_key->call_id = hdr->seqnum;
|
||||
|
@ -4030,7 +4057,6 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
int auth_level;
|
||||
char uuid_str[DCERPC_UUID_STR_LEN];
|
||||
int uuid_str_len;
|
||||
int transport_type=DCE_TRANSPORT_UNKNOWN;
|
||||
|
||||
/*
|
||||
* Check if this looks like a CL DCERPC call. All dg packets
|
||||
|
@ -4343,11 +4369,11 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
break;
|
||||
|
||||
case PDU_REQ:
|
||||
dissect_dcerpc_dg_rqst (tvb, offset, pinfo, dcerpc_tree, tree, &hdr, conv, transport_type);
|
||||
dissect_dcerpc_dg_rqst (tvb, offset, pinfo, dcerpc_tree, tree, &hdr, conv);
|
||||
break;
|
||||
|
||||
case PDU_RESP:
|
||||
dissect_dcerpc_dg_resp (tvb, offset, pinfo, dcerpc_tree, tree, &hdr, conv, transport_type);
|
||||
dissect_dcerpc_dg_resp (tvb, offset, pinfo, dcerpc_tree, tree, &hdr, conv);
|
||||
break;
|
||||
|
||||
/* these requests have no body */
|
||||
|
@ -4385,17 +4411,29 @@ dcerpc_init_protocol (void)
|
|||
200 * sizeof (dcerpc_bind_value),
|
||||
G_ALLOC_ONLY);
|
||||
/* structures and data for CALL */
|
||||
if (dcerpc_calls){
|
||||
g_hash_table_destroy (dcerpc_calls);
|
||||
if (dcerpc_cn_calls){
|
||||
g_hash_table_destroy (dcerpc_cn_calls);
|
||||
}
|
||||
dcerpc_calls = g_hash_table_new (dcerpc_call_hash, dcerpc_call_equal);
|
||||
if (dcerpc_call_key_chunk){
|
||||
g_mem_chunk_destroy (dcerpc_call_key_chunk);
|
||||
dcerpc_cn_calls = g_hash_table_new (dcerpc_cn_call_hash, dcerpc_cn_call_equal);
|
||||
if (dcerpc_dg_calls){
|
||||
g_hash_table_destroy (dcerpc_dg_calls);
|
||||
}
|
||||
dcerpc_call_key_chunk = g_mem_chunk_new ("dcerpc_call_key_chunk",
|
||||
sizeof (dcerpc_call_key),
|
||||
200 * sizeof (dcerpc_call_key),
|
||||
G_ALLOC_ONLY);
|
||||
dcerpc_dg_calls = g_hash_table_new (dcerpc_dg_call_hash, dcerpc_dg_call_equal);
|
||||
if (dcerpc_cn_call_key_chunk){
|
||||
g_mem_chunk_destroy (dcerpc_cn_call_key_chunk);
|
||||
}
|
||||
dcerpc_cn_call_key_chunk = g_mem_chunk_new ("dcerpc_cn_call_key_chunk",
|
||||
sizeof (dcerpc_cn_call_key),
|
||||
200 * sizeof (dcerpc_cn_call_key),
|
||||
G_ALLOC_ONLY);
|
||||
if (dcerpc_dg_call_key_chunk){
|
||||
g_mem_chunk_destroy (dcerpc_dg_call_key_chunk);
|
||||
}
|
||||
dcerpc_dg_call_key_chunk = g_mem_chunk_new ("dcerpc_dg_call_key_chunk",
|
||||
sizeof (dcerpc_dg_call_key),
|
||||
200 * sizeof (dcerpc_dg_call_key),
|
||||
G_ALLOC_ONLY);
|
||||
|
||||
if (dcerpc_call_value_chunk){
|
||||
g_mem_chunk_destroy (dcerpc_call_value_chunk);
|
||||
}
|
||||
|
|
143
reassemble.c
143
reassemble.c
|
@ -1,7 +1,7 @@
|
|||
/* reassemble.c
|
||||
* Routines for {fragment,segment} reassembly
|
||||
*
|
||||
* $Id: reassemble.c,v 1.49 2004/06/20 19:20:55 guy Exp $
|
||||
* $Id: reassemble.c,v 1.50 2004/06/24 07:43:24 sahlberg Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "reassemble.h"
|
||||
|
||||
#include "packet-dcerpc.h"
|
||||
|
||||
typedef struct _fragment_key {
|
||||
address src;
|
||||
|
@ -39,7 +40,15 @@ typedef struct _fragment_key {
|
|||
guint32 id;
|
||||
} fragment_key;
|
||||
|
||||
typedef struct _dcerpc_fragment_key {
|
||||
address src;
|
||||
address dst;
|
||||
guint32 id;
|
||||
e_uuid_t act_id;
|
||||
} dcerpc_fragment_key;
|
||||
|
||||
static GMemChunk *fragment_key_chunk = NULL;
|
||||
static GMemChunk *dcerpc_fragment_key_chunk = NULL;
|
||||
static GMemChunk *fragment_data_chunk = NULL;
|
||||
static int fragment_init_count = 200;
|
||||
|
||||
|
@ -97,6 +106,39 @@ fragment_hash(gconstpointer k)
|
|||
return hash_val;
|
||||
}
|
||||
|
||||
static gint
|
||||
dcerpc_fragment_equal(gconstpointer k1, gconstpointer k2)
|
||||
{
|
||||
const dcerpc_fragment_key* key1 = (const dcerpc_fragment_key*) k1;
|
||||
const dcerpc_fragment_key* key2 = (const dcerpc_fragment_key*) k2;
|
||||
|
||||
/*key.id is the first item to compare since item is most
|
||||
likely to differ between sessions, thus shortcircuiting
|
||||
the comparasion of addresses.
|
||||
*/
|
||||
return (((key1->id == key2->id)
|
||||
&& (ADDRESSES_EQUAL(&key1->src, &key2->src))
|
||||
&& (ADDRESSES_EQUAL(&key1->dst, &key2->dst))
|
||||
&& (memcmp (&key1->act_id, &key2->act_id, sizeof (e_uuid_t)) == 0))
|
||||
? TRUE : FALSE);
|
||||
}
|
||||
|
||||
static guint
|
||||
dcerpc_fragment_hash(gconstpointer k)
|
||||
{
|
||||
const dcerpc_fragment_key* key = (const dcerpc_fragment_key*) k;
|
||||
guint hash_val;
|
||||
|
||||
hash_val = 0;
|
||||
|
||||
hash_val += key->id;
|
||||
hash_val += key->act_id.Data1;
|
||||
hash_val += key->act_id.Data2 << 16;
|
||||
hash_val += key->act_id.Data3;
|
||||
|
||||
return hash_val;
|
||||
}
|
||||
|
||||
typedef struct _reassembled_key {
|
||||
guint32 id;
|
||||
guint32 frame;
|
||||
|
@ -214,6 +256,26 @@ fragment_table_init(GHashTable **fragment_table)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
dcerpc_fragment_table_init(GHashTable **fragment_table)
|
||||
{
|
||||
if (*fragment_table != NULL) {
|
||||
/*
|
||||
* The fragment hash table exists.
|
||||
*
|
||||
* Remove all entries and free fragment data for
|
||||
* each entry. (The key and value data is freed
|
||||
* by "reassemble_init()".)
|
||||
*/
|
||||
g_hash_table_foreach_remove(*fragment_table,
|
||||
free_all_fragments, NULL);
|
||||
} else {
|
||||
/* The fragment table does not exist. Create it */
|
||||
*fragment_table = g_hash_table_new(dcerpc_fragment_hash,
|
||||
dcerpc_fragment_equal);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a reassembled-packet table.
|
||||
*/
|
||||
|
@ -246,6 +308,8 @@ reassemble_init(void)
|
|||
{
|
||||
if (fragment_key_chunk != NULL)
|
||||
g_mem_chunk_destroy(fragment_key_chunk);
|
||||
if (dcerpc_fragment_key_chunk != NULL)
|
||||
g_mem_chunk_destroy(fragment_key_chunk);
|
||||
if (fragment_data_chunk != NULL)
|
||||
g_mem_chunk_destroy(fragment_data_chunk);
|
||||
if (reassembled_key_chunk != NULL)
|
||||
|
@ -254,6 +318,10 @@ reassemble_init(void)
|
|||
sizeof(fragment_key),
|
||||
fragment_init_count * sizeof(fragment_key),
|
||||
G_ALLOC_AND_FREE);
|
||||
dcerpc_fragment_key_chunk = g_mem_chunk_new("dcerpc_fragment_key_chunk",
|
||||
sizeof(dcerpc_fragment_key),
|
||||
fragment_init_count * sizeof(dcerpc_fragment_key),
|
||||
G_ALLOC_AND_FREE);
|
||||
fragment_data_chunk = g_mem_chunk_new("fragment_data_chunk",
|
||||
sizeof(fragment_data),
|
||||
fragment_init_count * sizeof(fragment_data),
|
||||
|
@ -1221,6 +1289,79 @@ fragment_add_seq(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
|
|||
}
|
||||
}
|
||||
|
||||
fragment_data *
|
||||
fragment_add_dcerpc(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
|
||||
void *v_act_id,
|
||||
GHashTable *fragment_table, guint32 frag_number,
|
||||
guint32 frag_data_len, gboolean more_frags)
|
||||
{
|
||||
dcerpc_fragment_key key, *new_key;
|
||||
fragment_data *fd_head;
|
||||
e_uuid_t *act_id = (e_uuid_t *)v_act_id;
|
||||
|
||||
/* create key to search hash with */
|
||||
key.src = pinfo->src;
|
||||
key.dst = pinfo->dst;
|
||||
key.id = id;
|
||||
key.act_id = *act_id;
|
||||
|
||||
fd_head = g_hash_table_lookup(fragment_table, &key);
|
||||
|
||||
/* have we already seen this frame ?*/
|
||||
if (pinfo->fd->flags.visited) {
|
||||
if (fd_head != NULL && fd_head->flags & FD_DEFRAGMENTED) {
|
||||
return fd_head;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (fd_head==NULL){
|
||||
/* not found, this must be the first snooped fragment for this
|
||||
* packet. Create list-head.
|
||||
*/
|
||||
fd_head=g_mem_chunk_alloc(fragment_data_chunk);
|
||||
|
||||
/* head/first structure in list only holds no other data than
|
||||
* 'datalen' then we don't have to change the head of the list
|
||||
* even if we want to keep it sorted
|
||||
*/
|
||||
fd_head->next=NULL;
|
||||
fd_head->datalen=0;
|
||||
fd_head->offset=0;
|
||||
fd_head->len=0;
|
||||
fd_head->flags=FD_BLOCKSEQUENCE;
|
||||
fd_head->data=NULL;
|
||||
fd_head->reassembled_in=0;
|
||||
|
||||
/*
|
||||
* We're going to use the key to insert the fragment,
|
||||
* so allocate a structure for it, and copy the
|
||||
* addresses, allocating new buffers for the address
|
||||
* data.
|
||||
*/
|
||||
new_key = g_mem_chunk_alloc(dcerpc_fragment_key_chunk);
|
||||
COPY_ADDRESS(&new_key->src, &key.src);
|
||||
COPY_ADDRESS(&new_key->dst, &key.dst);
|
||||
new_key->id = key.id;
|
||||
new_key->act_id = key.act_id;
|
||||
g_hash_table_insert(fragment_table, new_key, fd_head);
|
||||
}
|
||||
|
||||
if (fragment_add_seq_work(fd_head, tvb, offset, pinfo,
|
||||
frag_number, frag_data_len, more_frags)) {
|
||||
/*
|
||||
* Reassembly is complete.
|
||||
*/
|
||||
return fd_head;
|
||||
} else {
|
||||
/*
|
||||
* Reassembly isn't complete.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This does the work for "fragment_add_seq_check()" and
|
||||
* "fragment_add_seq_next()".
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* reassemble.h
|
||||
* Declarations of outines for {fragment,segment} reassembly
|
||||
*
|
||||
* $Id: reassemble.h,v 1.21 2003/12/20 03:21:20 guy Exp $
|
||||
* $Id: reassemble.h,v 1.22 2004/06/24 07:43:24 sahlberg Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -68,6 +68,7 @@ typedef struct _fragment_data {
|
|||
* Initialize a fragment table.
|
||||
*/
|
||||
extern void fragment_table_init(GHashTable **fragment_table);
|
||||
extern void dcerpc_fragment_table_init(GHashTable **fragment_table);
|
||||
|
||||
/*
|
||||
* Initialize a reassembled-packet table.
|
||||
|
@ -108,6 +109,12 @@ extern fragment_data *fragment_add_seq(tvbuff_t *tvb, int offset, packet_info *p
|
|||
guint32 id, GHashTable *fragment_table, guint32 frag_number,
|
||||
guint32 frag_data_len, gboolean more_frags);
|
||||
|
||||
extern fragment_data *
|
||||
fragment_add_dcerpc(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
|
||||
void *act_id,
|
||||
GHashTable *fragment_table, guint32 frag_number,
|
||||
guint32 frag_data_len, gboolean more_frags);
|
||||
|
||||
/*
|
||||
* These functions add a new fragment to the fragment hash table.
|
||||
* If this is the first fragment seen for this datagram, a new
|
||||
|
|
Loading…
Reference in New Issue