Added show_fragment_tree() to reassemble. This function will do the common

task of creating a fregment tree for the fragmented packets.
Having this identical code to create this tree in every dissector that does
PDU reassembly is a huge waste and duplication of code.

Updated IP, SMB and DCERPC to use the new function.

svn path=/trunk/; revision=5626
This commit is contained in:
Ronnie Sahlberg 2002-06-05 11:21:49 +00:00
parent 230ac0da7a
commit 31823cb851
5 changed files with 192 additions and 203 deletions

View File

@ -2,7 +2,7 @@
* Routines for DCERPC packet disassembly
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
* $Id: packet-dcerpc.c,v 1.53 2002/06/04 07:03:44 guy Exp $
* $Id: packet-dcerpc.c,v 1.54 2002/06/05 11:21:47 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -222,6 +222,19 @@ static gint ett_dcerpc_pointer_data = -1;
static gint ett_dcerpc_fragments = -1;
static gint ett_dcerpc_fragment = -1;
fragment_items dcerpc_frag_items = {
&ett_dcerpc_fragments,
&ett_dcerpc_fragment,
&hf_dcerpc_fragments,
&hf_dcerpc_fragment,
&hf_dcerpc_fragment_overlap,
&hf_dcerpc_fragment_overlap_conflict,
&hf_dcerpc_fragment_multiple_tails,
&hf_dcerpc_fragment_too_long_fragment,
&hf_dcerpc_fragment_error
};
/* try to desegment big DCE/RPC packets over TCP? */
static gboolean dcerpc_cn_desegment = TRUE;
@ -1619,62 +1632,14 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
TRUE);
if(ipfd_head){
fragment_data *ipfd;
proto_tree *ft=NULL;
proto_item *fi=NULL;
tvbuff_t *next_tvb;
next_tvb = tvb_new_real_data(ipfd_head->data, ipfd_head->datalen, ipfd_head->datalen);
tvb_set_child_real_data_tvbuff(tvb, next_tvb);
add_new_data_source(pinfo, next_tvb, "Reassembled DCE/RPC");
pinfo->fragmented=FALSE;
fi = proto_tree_add_item(dcerpc_tree, hf_dcerpc_fragments, next_tvb, 0, -1, FALSE);
ft = proto_item_add_subtree(fi, ett_dcerpc_fragments);
for (ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
if (ipfd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
proto_tree *fet=NULL;
proto_item *fei=NULL;
int hf;
show_fragment_tree(ipfd_head, &dcerpc_frag_items,
dcerpc_tree, pinfo, next_tvb);
if (ipfd->flags & (FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
hf = hf_dcerpc_fragment_error;
} else {
hf = hf_dcerpc_fragment;
}
fei = proto_tree_add_none_format(ft, hf,
next_tvb, ipfd->offset, ipfd->len,
"Frame:%u payload:%u-%u",
ipfd->frame,
ipfd->offset,
ipfd->offset+ipfd->len-1);
fet = proto_item_add_subtree(fei, ett_dcerpc_fragment);
if (ipfd->flags&FD_OVERLAP) {
proto_tree_add_boolean(fet, hf_dcerpc_fragment_overlap, next_tvb, 0, 0, TRUE);
}
if (ipfd->flags&FD_OVERLAPCONFLICT) {
proto_tree_add_boolean(fet, hf_dcerpc_fragment_overlap_conflict, next_tvb, 0, 0, TRUE);
}
if (ipfd->flags&FD_MULTIPLETAILS) {
proto_tree_add_boolean(fet, hf_dcerpc_fragment_multiple_tails, next_tvb, 0, 0, TRUE);
}
if (ipfd->flags&FD_TOOLONGFRAGMENT) {
proto_tree_add_boolean(fet, hf_dcerpc_fragment_too_long_fragment, next_tvb, 0, 0, TRUE);
}
} else {
proto_tree_add_none_format(ft, hf_dcerpc_fragment,
next_tvb, ipfd->offset, ipfd->len,
"Frame:%u payload:%u-%u",
ipfd->frame,
ipfd->offset,
ipfd->offset+ipfd->len-1
);
}
}
if (ipfd_head->flags & (FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
if (check_col(pinfo->cinfo, COL_INFO)) {
col_set_str(pinfo->cinfo, COL_INFO, "[Illegal fragments]");
}
}
dcerpc_try_handoff (pinfo, tree, dcerpc_tree,
next_tvb,
0, opnum, TRUE, hdr->drep, &di,
@ -1842,62 +1807,14 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr
TRUE);
if(ipfd_head){
fragment_data *ipfd;
proto_tree *ft=NULL;
proto_item *fi=NULL;
tvbuff_t *next_tvb;
next_tvb = tvb_new_real_data(ipfd_head->data, ipfd_head->datalen, ipfd_head->datalen);
tvb_set_child_real_data_tvbuff(tvb, next_tvb);
add_new_data_source(pinfo, next_tvb, "Reassembled DCE/RPC");
pinfo->fragmented=FALSE;
fi = proto_tree_add_item(dcerpc_tree, hf_dcerpc_fragments, next_tvb, 0, -1, FALSE);
ft = proto_item_add_subtree(fi, ett_dcerpc_fragments);
for (ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
if (ipfd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
proto_tree *fet=NULL;
proto_item *fei=NULL;
int hf;
show_fragment_tree(ipfd_head, &dcerpc_frag_items,
dcerpc_tree, pinfo, next_tvb);
if (ipfd->flags & (FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
hf = hf_dcerpc_fragment_error;
} else {
hf = hf_dcerpc_fragment;
}
fei = proto_tree_add_none_format(ft, hf,
next_tvb, ipfd->offset, ipfd->len,
"Frame:%u payload:%u-%u",
ipfd->frame,
ipfd->offset,
ipfd->offset+ipfd->len-1);
fet = proto_item_add_subtree(fei, ett_dcerpc_fragment);
if (ipfd->flags&FD_OVERLAP) {
proto_tree_add_boolean(fet, hf_dcerpc_fragment_overlap, next_tvb, 0, 0, TRUE);
}
if (ipfd->flags&FD_OVERLAPCONFLICT) {
proto_tree_add_boolean(fet, hf_dcerpc_fragment_overlap_conflict, next_tvb, 0, 0, TRUE);
}
if (ipfd->flags&FD_MULTIPLETAILS) {
proto_tree_add_boolean(fet, hf_dcerpc_fragment_multiple_tails, next_tvb, 0, 0, TRUE);
}
if (ipfd->flags&FD_TOOLONGFRAGMENT) {
proto_tree_add_boolean(fet, hf_dcerpc_fragment_too_long_fragment, next_tvb, 0, 0, TRUE);
}
} else {
proto_tree_add_none_format(ft, hf_dcerpc_fragment,
next_tvb, ipfd->offset, ipfd->len,
"Frame:%u payload:%u-%u",
ipfd->frame,
ipfd->offset,
ipfd->offset+ipfd->len-1
);
}
}
if (ipfd_head->flags & (FD_OVERLAPCONFLICT|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
if (check_col(pinfo->cinfo, COL_INFO)) {
col_set_str(pinfo->cinfo, COL_INFO, "[Illegal fragments]");
}
}
dcerpc_try_handoff (pinfo, tree, dcerpc_tree,
next_tvb,
0, value->opnum, FALSE, hdr->drep, &di,

View File

@ -1,7 +1,7 @@
/* packet-ip.c
* Routines for IP and miscellaneous IP protocol packet disassembly
*
* $Id: packet-ip.c,v 1.167 2002/06/04 07:03:45 guy Exp $
* $Id: packet-ip.c,v 1.168 2002/06/05 11:21:47 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -113,6 +113,18 @@ static gint ett_ip_option_timestamp = -1;
static gint ett_ip_fragments = -1;
static gint ett_ip_fragment = -1;
fragment_items ip_frag_items = {
&ett_ip_fragment,
&ett_ip_fragments,
&hf_ip_fragments,
&hf_ip_fragment,
&hf_ip_fragment_overlap,
&hf_ip_fragment_overlap_conflict,
&hf_ip_fragment_multiple_tails,
&hf_ip_fragment_too_long_fragment,
&hf_ip_fragment_error
};
/* Used by IPv6 as well, so not static */
dissector_table_t ip_dissector_table;
@ -983,10 +995,6 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
iph.ip_off & IP_MF);
if (ipfd_head != NULL) {
fragment_data *ipfd;
proto_tree *ft=NULL;
proto_item *fi=NULL;
/* OK, we have the complete reassembled payload.
Allocate a new tvbuff, referring to the reassembled payload. */
next_tvb = tvb_new_real_data(ipfd_head->data, ipfd_head->datalen,
@ -1000,75 +1008,9 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Add the defragmented data to the data source list. */
add_new_data_source(pinfo, next_tvb, "Reassembled IPv4");
/* It's not fragmented. */
pinfo->fragmented = FALSE;
/* show all fragments */
fi = proto_tree_add_item(ip_tree, hf_ip_fragments,
next_tvb, 0, -1, FALSE);
ft = proto_item_add_subtree(fi, ett_ip_fragments);
for (ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
if (ipfd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
/* this fragment has some flags set, create a subtree
* for it and display the flags.
*/
proto_tree *fet=NULL;
proto_item *fei=NULL;
int hf;
update_col_info = !show_fragment_tree(ipfd_head, &ip_frag_items, ip_tree, pinfo, next_tvb);
if (ipfd->flags & (FD_OVERLAPCONFLICT
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
hf = hf_ip_fragment_error;
} else {
hf = hf_ip_fragment;
}
fei = proto_tree_add_none_format(ft, hf,
next_tvb, ipfd->offset, ipfd->len,
"Frame:%u payload:%u-%u",
ipfd->frame,
ipfd->offset,
ipfd->offset+ipfd->len-1
);
fet = proto_item_add_subtree(fei, ett_ip_fragment);
if (ipfd->flags&FD_OVERLAP) {
proto_tree_add_boolean(fet,
hf_ip_fragment_overlap, next_tvb, 0, 0,
TRUE);
}
if (ipfd->flags&FD_OVERLAPCONFLICT) {
proto_tree_add_boolean(fet,
hf_ip_fragment_overlap_conflict, next_tvb, 0, 0,
TRUE);
}
if (ipfd->flags&FD_MULTIPLETAILS) {
proto_tree_add_boolean(fet,
hf_ip_fragment_multiple_tails, next_tvb, 0, 0,
TRUE);
}
if (ipfd->flags&FD_TOOLONGFRAGMENT) {
proto_tree_add_boolean(fet,
hf_ip_fragment_too_long_fragment, next_tvb, 0, 0,
TRUE);
}
} else {
/* nothing of interest for this fragment */
proto_tree_add_none_format(ft, hf_ip_fragment,
next_tvb, ipfd->offset, ipfd->len,
"Frame:%u payload:%u-%u",
ipfd->frame,
ipfd->offset,
ipfd->offset+ipfd->len-1
);
}
}
if (ipfd_head->flags & (FD_OVERLAPCONFLICT
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
if (check_col(pinfo->cinfo, COL_INFO)) {
col_set_str(pinfo->cinfo, COL_INFO, "[Illegal fragments]");
update_col_info = FALSE;
}
}
} else {
/* We don't have the complete reassembled payload. */
next_tvb = NULL;

View File

@ -3,7 +3,7 @@
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
* 2001 Rewrite by Ronnie Sahlberg and Guy Harris
*
* $Id: packet-smb.c,v 1.268 2002/06/04 07:03:45 guy Exp $
* $Id: packet-smb.c,v 1.269 2002/06/05 11:21:47 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -575,6 +575,13 @@ static int hf_smb_user_quota_used = -1;
static int hf_smb_user_quota_offset = -1;
static int hf_smb_nt_rename_level = -1;
static int hf_smb_cluster_count = -1;
static int hf_smb_segments = -1;
static int hf_smb_segment = -1;
static int hf_smb_segment_overlap = -1;
static int hf_smb_segment_overlap_conflict = -1;
static int hf_smb_segment_multiple_tails = -1;
static int hf_smb_segment_too_long_fragment = -1;
static int hf_smb_segment_error = -1;
static gint ett_smb = -1;
static gint ett_smb_hdr = -1;
@ -641,6 +648,7 @@ static gint ett_smb_ff2_data = -1;
static gint ett_smb_device_characteristics = -1;
static gint ett_smb_fs_attributes = -1;
static gint ett_smb_segments = -1;
static gint ett_smb_segment = -1;
static gint ett_smb_sec_desc = -1;
static gint ett_smb_sid = -1;
static gint ett_smb_acl = -1;
@ -649,6 +657,20 @@ static gint ett_smb_ace_flags = -1;
static gint ett_smb_sec_desc_type = -1;
static gint ett_smb_quotaflags = -1;
fragment_items smb_frag_items = {
&ett_smb_segment,
&ett_smb_segments,
&hf_smb_segments,
&hf_smb_segment,
&hf_smb_segment_overlap,
&hf_smb_segment_overlap_conflict,
&hf_smb_segment_multiple_tails,
&hf_smb_segment_too_long_fragment,
&hf_smb_segment_error,
};
proto_tree *top_tree=NULL; /* ugly */
static char *decode_smb_name(unsigned char);
@ -8297,24 +8319,12 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
must create pd_tvb from it
*/
if(r_fd){
proto_tree *tr;
proto_item *it;
fragment_data *fd;
pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
r_fd->datalen);
tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
pinfo->fragmented = FALSE;
it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
tr = proto_item_add_subtree(it, ett_smb_segments);
for(fd=r_fd->next;fd;fd=fd->next){
proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
"Frame:%u Data:%u-%u",
fd->frame, fd->offset,
fd->offset+fd->len-1);
}
show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
}
@ -12830,24 +12840,11 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
create pd_tvb from it
*/
if(r_fd){
proto_tree *tr;
proto_item *it;
fragment_data *fd;
pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
r_fd->datalen);
tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
pinfo->fragmented = FALSE;
it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
tr = proto_item_add_subtree(it, ett_smb_segments);
for(fd=r_fd->next;fd;fd=fd->next){
proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
"Frame:%u Data:%u-%u",
fd->frame, fd->offset,
fd->offset+fd->len-1);
}
show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
}
@ -17550,6 +17547,33 @@ proto_register_smb(void)
{ "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
{ &hf_smb_segment_overlap,
{ "Fragment overlap", "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"Fragment overlaps with other fragments", HFILL }},
{ &hf_smb_segment_overlap_conflict,
{ "Conflicting data in fragment overlap", "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"Overlapping fragments contained conflicting data", HFILL }},
{ &hf_smb_segment_multiple_tails,
{ "Multiple tail fragments found", "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"Several tails were found when defragmenting the packet", HFILL }},
{ &hf_smb_segment_too_long_fragment,
{ "Fragment too long", "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"Fragment contained data past end of packet", HFILL }},
{ &hf_smb_segment_error,
{ "Defragmentation error", "smb.segment.error", FT_NONE, BASE_NONE, NULL, 0x0,
"Defragmentation error due to illegal fragments", HFILL }},
{ &hf_smb_segment,
{ "SMB Segment", "smb.segment", FT_NONE, BASE_NONE, NULL, 0x0,
"SMB Segment", HFILL }},
{ &hf_smb_segments,
{ "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
"SMB Segments", HFILL }},
};
static gint *ett[] = {
&ett_smb,
@ -17617,6 +17641,7 @@ proto_register_smb(void)
&ett_smb_device_characteristics,
&ett_smb_fs_attributes,
&ett_smb_segments,
&ett_smb_segment,
&ett_smb_sec_desc,
&ett_smb_sid,
&ett_smb_acl,

View File

@ -1,7 +1,7 @@
/* reassemble.c
* Routines for {fragment,segment} reassembly
*
* $Id: reassemble.c,v 1.18 2002/05/24 11:51:14 sahlberg Exp $
* $Id: reassemble.c,v 1.19 2002/06/05 11:21:48 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -32,6 +32,7 @@
#include "reassemble.h"
typedef struct _fragment_key {
address src;
address dst;
@ -248,6 +249,7 @@ reassemble_init(void)
sizeof(fragment_data),
fragment_init_count * sizeof(fragment_data),
G_ALLOC_ONLY);
}
/* This function cleans up the stored state and removes the reassembly data and
@ -1100,3 +1102,90 @@ fragment_add_seq_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
return NULL;
}
}
/* This function will build the fragment subtree
function will return TRUE if there were fragmentation errors
or FALSE if fragmentation was ok.
*/
int
show_fragment_tree(fragment_data *ipfd_head, fragment_items *fit, proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb)
{
fragment_data *ipfd;
proto_tree *ft=NULL;
proto_item *fi=NULL;
/* It's not fragmented. */
pinfo->fragmented = FALSE;
fi = proto_tree_add_item(tree, *(fit->hf_fragments),
tvb, 0, -1, FALSE);
ft = proto_item_add_subtree(fi, *(fit->ett_fragments));
for (ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
if (ipfd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
/* this fragment has some flags set, create a subtree
* for it and display the flags.
*/
proto_tree *fet=NULL;
proto_item *fei=NULL;
int hf;
if (ipfd->flags & (FD_OVERLAPCONFLICT
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
hf = *(fit->hf_fragment_error);
} else {
hf = *(fit->hf_fragment);
}
fei = proto_tree_add_none_format(ft, hf,
tvb, ipfd->offset, ipfd->len,
"Frame:%u payload:%u-%u",
ipfd->frame,
ipfd->offset,
ipfd->offset+ipfd->len-1);
fet = proto_item_add_subtree(fei, *(fit->ett_fragment));
if (ipfd->flags&FD_OVERLAP) {
proto_tree_add_boolean(fet,
*(fit->hf_fragment_overlap), tvb, 0, 0,
TRUE);
}
if (ipfd->flags&FD_OVERLAPCONFLICT) {
proto_tree_add_boolean(fet,
*(fit->hf_fragment_overlap_conflict),
tvb, 0, 0,
TRUE);
}
if (ipfd->flags&FD_MULTIPLETAILS) {
proto_tree_add_boolean(fet,
*(fit->hf_fragment_multiple_tails), tvb, 0, 0,
TRUE);
}
if (ipfd->flags&FD_TOOLONGFRAGMENT) {
proto_tree_add_boolean(fet,
*(fit->hf_fragment_too_long_fragment),
tvb, 0, 0,
TRUE);
}
} else {
/* nothing of interest for this fragment */
proto_tree_add_none_format(ft, *(fit->hf_fragment),
tvb, ipfd->offset, ipfd->len,
"Frame:%u payload:%u-%u",
ipfd->frame,
ipfd->offset,
ipfd->offset+ipfd->len-1
);
}
}
if (ipfd_head->flags & (FD_OVERLAPCONFLICT
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
if (check_col(pinfo->cinfo, COL_INFO)) {
col_set_str(pinfo->cinfo, COL_INFO,
"[Illegal fragments]");
return TRUE;
}
}
return FALSE;
}

View File

@ -1,7 +1,7 @@
/* reassemble.h
* Declarations of outines for {fragment,segment} reassembly
*
* $Id: reassemble.h,v 1.7 2002/05/24 11:51:14 sahlberg Exp $
* $Id: reassemble.h,v 1.8 2002/06/05 11:21:49 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -171,3 +171,19 @@ fragment_get(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
*/
unsigned char *
fragment_delete(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
typedef struct _fragment_items {
gint *ett_fragment;
gint *ett_fragments;
int *hf_fragments;
int *hf_fragment;
int *hf_fragment_overlap;
int *hf_fragment_overlap_conflict;
int *hf_fragment_multiple_tails;
int *hf_fragment_too_long_fragment;
int *hf_fragment_error;
} fragment_items;
int
show_fragment_tree(fragment_data *ipfd_head, fragment_items *fit, proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb);