Use the reported length, not the captured length, as the fragment length

when doing reassembly.

In some additional places, use "tvb_bytes_exist()" to check whether we
have enough data to do reassembly, rather than checking to see if the
frame is short (it might be short but we might still have enough data to
do reassembly).

In DCE RPC, use the fragment length from the header as the number of
bytes of fragment data.

There's no need to check "pinfo->fragmented" before doing reassembly in
the DCERPC-over-SMB-pipes code - either we have all the data or we
don't.

In SNA and WTP reassembly, add a check to make sure we have all the data
to be reassembled.

svn path=/trunk/; revision=7282
This commit is contained in:
Guy Harris 2003-03-05 07:17:50 +00:00
parent 72a00f19ca
commit 05c41a279f
6 changed files with 113 additions and 99 deletions

View File

@ -2,7 +2,7 @@
* Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP, * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
* RTMP. * RTMP.
* *
* $Id: packet-atalk.c,v 1.86 2003/01/23 09:39:32 guy Exp $ * $Id: packet-atalk.c,v 1.87 2003/03/05 07:17:49 guy Exp $
* *
* Simon Wilkinson <sxw@dcs.ed.ac.uk> * Simon Wilkinson <sxw@dcs.ed.ac.uk>
* *
@ -848,7 +848,7 @@ dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
hdr = ATP_HDRSIZE -1; hdr = ATP_HDRSIZE -1;
if (frag_number != 0) if (frag_number != 0)
hdr += 4; /* asp header */ hdr += 4; /* asp header */
len = tvb_length_remaining(tvb, hdr); len = tvb_reported_length_remaining(tvb, hdr);
fd_head = fragment_add_seq_check(tvb, hdr, pinfo, tid, fd_head = fragment_add_seq_check(tvb, hdr, pinfo, tid,
atp_fragment_table, atp_fragment_table,
atp_reassembled_table, atp_reassembled_table,

View File

@ -2,7 +2,7 @@
* Routines for DCERPC packet disassembly * Routines for DCERPC packet disassembly
* Copyright 2001, Todd Sabin <tas@webspan.net> * Copyright 2001, Todd Sabin <tas@webspan.net>
* *
* $Id: packet-dcerpc.c,v 1.110 2003/02/24 01:22:20 guy Exp $ * $Id: packet-dcerpc.c,v 1.111 2003/03/05 07:17:50 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com> * By Gerald Combs <gerald@ethereal.com>
@ -2182,7 +2182,7 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
the data in the fragment, just call the handoff directly if the data in the fragment, just call the handoff directly if
this is the first fragment or the PDU isn't fragmented. */ this is the first fragment or the PDU isn't fragmented. */
if( (!dcerpc_reassemble) || PFC_NOT_FRAGMENTED(hdr) || if( (!dcerpc_reassemble) || PFC_NOT_FRAGMENTED(hdr) ||
stub_length > length ){ !tvb_bytes_exist(tvb, offset, stub_length) ){
if(hdr->flags&PFC_FIRST_FRAG){ if(hdr->flags&PFC_FIRST_FRAG){
/* First fragment, possibly the only fragment */ /* First fragment, possibly the only fragment */
pinfo->fragmented = !PFC_NOT_FRAGMENTED(hdr); pinfo->fragmented = !PFC_NOT_FRAGMENTED(hdr);
@ -2197,10 +2197,10 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
" [DCE/RPC fragment]"); " [DCE/RPC fragment]");
} }
if (dcerpc_tree) { if (dcerpc_tree) {
if (length > 0) { if (stub_length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, stub_length,
"Fragment data (%d byte%s)", length, "Fragment data (%d byte%s)", stub_length,
plurality(length, "", "s")); plurality(stub_length, "", "s"));
} }
} }
} }
@ -2210,10 +2210,10 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
of those mean we should attempt reassembly, and the of those mean we should attempt reassembly, and the
third means we can attempt reassembly. */ third means we can attempt reassembly. */
if (dcerpc_tree) { if (dcerpc_tree) {
if (length > 0) { if (stub_length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, stub_length,
"Fragment data (%d byte%s)", length, "Fragment data (%d byte%s)", stub_length,
plurality(length, "", "s")); plurality(stub_length, "", "s"));
} }
} }
if(hdr->flags&PFC_FIRST_FRAG){ /* FIRST fragment */ if(hdr->flags&PFC_FIRST_FRAG){ /* FIRST fragment */
@ -2221,7 +2221,7 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
fragment_add(tvb, offset, pinfo, frame, fragment_add(tvb, offset, pinfo, frame,
dcerpc_co_reassemble_table, dcerpc_co_reassemble_table,
0, 0,
length, stub_length,
TRUE); TRUE);
fragment_set_tot_len(pinfo, frame, fragment_set_tot_len(pinfo, frame,
dcerpc_co_reassemble_table, alloc_hint); dcerpc_co_reassemble_table, alloc_hint);
@ -2241,7 +2241,7 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
frame, frame,
dcerpc_co_reassemble_table, dcerpc_co_reassemble_table,
tot_len-alloc_hint, tot_len-alloc_hint,
length, stub_length,
TRUE); TRUE);
if(fd_head){ if(fd_head){
@ -2274,7 +2274,7 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
fragment_add(tvb, offset, pinfo, frame, fragment_add(tvb, offset, pinfo, frame,
dcerpc_co_reassemble_table, dcerpc_co_reassemble_table,
tot_len-alloc_hint, tot_len-alloc_hint,
length, stub_length,
TRUE); TRUE);
} }
if (check_col(pinfo->cinfo, COL_INFO)) { if (check_col(pinfo->cinfo, COL_INFO)) {
@ -2346,9 +2346,9 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype, conv = find_conversation (&pinfo->src, &pinfo->dst, pinfo->ptype,
pinfo->srcport, pinfo->destport, 0); pinfo->srcport, pinfo->destport, 0);
if (!conv) { if (!conv) {
length = tvb_length_remaining (tvb, offset); length = tvb_reported_length_remaining (tvb, offset);
if (length > 0) { if (length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, -1,
"Stub data (%d byte%s)", length, "Stub data (%d byte%s)", length,
plurality(length, "", "s")); plurality(length, "", "s"));
} }
@ -2423,9 +2423,9 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
hdr, &di, &auth_info, alloc_hint, hdr, &di, &auth_info, alloc_hint,
value->req_frame); value->req_frame);
} else { } else {
length = tvb_length_remaining (tvb, offset); length = tvb_reported_length_remaining (tvb, offset);
if (length > 0) { if (length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, -1,
"Stub data (%d byte%s)", length, "Stub data (%d byte%s)", length,
plurality(length, "", "s")); plurality(length, "", "s"));
} }
@ -2472,9 +2472,9 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
pinfo->srcport, pinfo->destport, 0); pinfo->srcport, pinfo->destport, 0);
if (!conv) { if (!conv) {
/* no point in creating one here, really */ /* no point in creating one here, really */
length = tvb_length_remaining (tvb, offset); length = tvb_reported_length_remaining (tvb, offset);
if (length > 0) { if (length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, -1,
"Stub data (%d byte%s)", length, "Stub data (%d byte%s)", length,
plurality(length, "", "s")); plurality(length, "", "s"));
} }
@ -2532,9 +2532,9 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
hdr, &di, &auth_info, alloc_hint, hdr, &di, &auth_info, alloc_hint,
value->rep_frame); value->rep_frame);
} else { } else {
length = tvb_length_remaining (tvb, offset); length = tvb_reported_length_remaining (tvb, offset);
if (length > 0) { if (length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, -1,
"Stub data (%d byte%s)", length, "Stub data (%d byte%s)", length,
plurality(length, "", "s")); plurality(length, "", "s"));
} }
@ -2650,12 +2650,11 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
reported_length = stub_length; reported_length = stub_length;
/* If we don't have reassembly enabled, or this packet contains /* If we don't have reassembly enabled, or this packet contains
the entire PDU, or if this is a short frame (or a frame the entire PDU, or if we don't have all the data in this
not reassembled at a lower layer) that doesn't include all fragment, just call the handoff directly if this is the
the data in the fragment, just call the handoff directly if first fragment or the PDU isn't fragmented. */
this is the first fragment or the PDU isn't fragmented. */
if( (!dcerpc_reassemble) || PFC_NOT_FRAGMENTED(hdr) || if( (!dcerpc_reassemble) || PFC_NOT_FRAGMENTED(hdr) ||
stub_length > length ){ !tvb_bytes_exist(tvb, offset, stub_length) ){
if(hdr->flags&PFC_FIRST_FRAG){ if(hdr->flags&PFC_FIRST_FRAG){
/* First fragment, possibly the only fragment */ /* First fragment, possibly the only fragment */
/* /*
@ -2669,10 +2668,11 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
* as well, as that might be protocol-specific. * as well, as that might be protocol-specific.
*/ */
if (dcerpc_tree) { if (dcerpc_tree) {
if (length > 0) { if (stub_length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, stub_length,
"Fault stub data (%d byte%s)", length, "Fault stub data (%d byte%s)",
plurality(length, "", "s")); stub_length,
plurality(stub_length, "", "s"));
} }
} }
} else { } else {
@ -2682,10 +2682,11 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
" [DCE/RPC fragment]"); " [DCE/RPC fragment]");
} }
if (dcerpc_tree) { if (dcerpc_tree) {
if (length > 0) { if (stub_length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, stub_length,
"Fragment data (%d byte%s)", length, "Fragment data (%d byte%s)",
plurality(length, "", "s")); stub_length,
plurality(stub_length, "", "s"));
} }
} }
} }
@ -2696,9 +2697,10 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
third means we can attempt reassembly. */ third means we can attempt reassembly. */
if (dcerpc_tree) { if (dcerpc_tree) {
if (length > 0) { if (length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, stub_length,
"Fragment data (%d byte%s)", length, "Fragment data (%d byte%s)",
plurality(length, "", "s")); stub_length,
plurality(stub_length, "", "s"));
} }
} }
if(hdr->flags&PFC_FIRST_FRAG){ /* FIRST fragment */ if(hdr->flags&PFC_FIRST_FRAG){ /* FIRST fragment */
@ -2706,7 +2708,7 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
fragment_add(tvb, offset, pinfo, value->rep_frame, fragment_add(tvb, offset, pinfo, value->rep_frame,
dcerpc_co_reassemble_table, dcerpc_co_reassemble_table,
0, 0,
length, stub_length,
TRUE); TRUE);
fragment_set_tot_len(pinfo, value->rep_frame, fragment_set_tot_len(pinfo, value->rep_frame,
dcerpc_co_reassemble_table, alloc_hint); dcerpc_co_reassemble_table, alloc_hint);
@ -2726,7 +2728,7 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
value->rep_frame, value->rep_frame,
dcerpc_co_reassemble_table, dcerpc_co_reassemble_table,
tot_len-alloc_hint, tot_len-alloc_hint,
length, stub_length,
TRUE); TRUE);
if(fd_head){ if(fd_head){
@ -2751,9 +2753,10 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
*/ */
if (dcerpc_tree) { if (dcerpc_tree) {
if (length > 0) { if (length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, stub_length,
"Fault stub data (%d byte%s)", length, "Fault stub data (%d byte%s)",
plurality(length, "", "s")); stub_length,
plurality(stub_length, "", "s"));
} }
} }
} else { } else {
@ -2773,7 +2776,7 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
fragment_add(tvb, offset, pinfo, value->rep_frame, fragment_add(tvb, offset, pinfo, value->rep_frame,
dcerpc_co_reassemble_table, dcerpc_co_reassemble_table,
tot_len-alloc_hint, tot_len-alloc_hint,
length, stub_length,
TRUE); TRUE);
} }
if (check_col(pinfo->cinfo, COL_INFO)) { if (check_col(pinfo->cinfo, COL_INFO)) {
@ -2852,7 +2855,7 @@ dissect_dcerpc_cn (tvbuff_t *tvb, int offset, packet_info *pinfo,
offset += 4; offset += 4;
if (can_desegment && pinfo->can_desegment if (can_desegment && pinfo->can_desegment
&& hdr.frag_len > tvb_length_remaining (tvb, start_offset)) { && !tvb_bytes_exist(tvb, start_offset, hdr.frag_len)) {
pinfo->desegment_offset = start_offset; pinfo->desegment_offset = start_offset;
pinfo->desegment_len = hdr.frag_len - tvb_length_remaining (tvb, start_offset); pinfo->desegment_len = hdr.frag_len - tvb_length_remaining (tvb, start_offset);
return 0; /* desegmentation required */ return 0; /* desegmentation required */
@ -3239,7 +3242,7 @@ dissect_dcerpc_dg_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
the data in the fragment, just call the handoff directly if the data in the fragment, just call the handoff directly if
this is the first fragment or the PDU isn't fragmented. */ this is the first fragment or the PDU isn't fragmented. */
if( (!dcerpc_reassemble) || !(hdr->flags1 & PFCL1_FRAG) || if( (!dcerpc_reassemble) || !(hdr->flags1 & PFCL1_FRAG) ||
stub_length > length ) { !tvb_bytes_exist(tvb, offset, stub_length) ){
if(hdr->frag_num == 0) { if(hdr->frag_num == 0) {
/* First fragment, possibly the only fragment */ /* First fragment, possibly the only fragment */
@ -3258,10 +3261,11 @@ dissect_dcerpc_dg_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
} }
if (dcerpc_tree) { if (dcerpc_tree) {
if (length > 0) { if (length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, stub_length,
"Fragment data (%d byte%s)", length, "Fragment data (%d byte%s)",
plurality(length, "", "s")); stub_length,
} plurality(stub_length, "", "s"));
}
} }
} }
} else { } else {
@ -3271,15 +3275,16 @@ dissect_dcerpc_dg_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
third means we can attempt reassembly. */ third means we can attempt reassembly. */
if (dcerpc_tree) { if (dcerpc_tree) {
if (length > 0) { if (length > 0) {
proto_tree_add_text (dcerpc_tree, tvb, offset, length, proto_tree_add_text (dcerpc_tree, tvb, offset, stub_length,
"Fragment data (%d byte%s)", length, "Fragment data (%d byte%s)", stub_length,
plurality(length, "", "s")); plurality(stub_length, "", "s"));
} }
} }
fd_head = fragment_add_seq(tvb, offset, pinfo, fd_head = fragment_add_seq(tvb, offset, pinfo,
hdr->seqnum, dcerpc_cl_reassemble_table, hdr->seqnum, dcerpc_cl_reassemble_table,
hdr->frag_num, length, !(hdr->flags1 & PFCL1_LASTFRAG)); hdr->frag_num, stub_length,
!(hdr->flags1 & PFCL1_LASTFRAG));
if (fd_head != NULL) { if (fd_head != NULL) {
/* We completed reassembly */ /* We completed reassembly */
tvbuff_t *next_tvb; tvbuff_t *next_tvb;

View File

@ -8,7 +8,7 @@ XXX Fixme : shouldnt show [malformed frame] for long packets
* significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and * significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and
* Guy Harris 2001 * Guy Harris 2001
* *
* $Id: packet-smb-pipe.c,v 1.88 2003/02/28 03:00:59 guy Exp $ * $Id: packet-smb-pipe.c,v 1.89 2003/03/05 07:17:50 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com> * By Gerald Combs <gerald@ethereal.com>
@ -3203,6 +3203,7 @@ dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree
smb_info_t *smb_priv = (smb_info_t *)pinfo->private_data; smb_info_t *smb_priv = (smb_info_t *)pinfo->private_data;
gboolean result; gboolean result;
gboolean save_fragmented; gboolean save_fragmented;
guint reported_len;
dcerpc_priv.transport_type = DCERPC_TRANSPORT_SMB; dcerpc_priv.transport_type = DCERPC_TRANSPORT_SMB;
dcerpc_priv.data.smb.fid = fid; dcerpc_priv.data.smb.fid = fid;
@ -3210,15 +3211,14 @@ dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree
pinfo->private_data = &dcerpc_priv; pinfo->private_data = &dcerpc_priv;
/* /*
* Offer desegmentation service to DCERPC if this packet * Offer desegmentation service to DCERPC if we have all the
* isn't fragmented or short. Otherwise, reassembly is * data. Otherwise, reassembly is (probably) impossible.
* (probably) impossible.
*/ */
pinfo->can_desegment=0; pinfo->can_desegment=0;
pinfo->desegment_offset = 0; pinfo->desegment_offset = 0;
pinfo->desegment_len = 0; pinfo->desegment_len = 0;
if(smb_dcerpc_reassembly && !pinfo->fragmented && reported_len = tvb_reported_length(d_tvb);
tvb_length(d_tvb) >= tvb_reported_length(d_tvb)){ if(smb_dcerpc_reassembly && tvb_bytes_exist(d_tvb, 0, reported_len)){
pinfo->can_desegment=2; pinfo->can_desegment=2;
} }
@ -3255,10 +3255,10 @@ dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree
if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && pinfo->desegment_len){ if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && pinfo->desegment_len){
fragment_add(d_tvb, 0, pinfo, pinfo->fd->num, fragment_add(d_tvb, 0, pinfo, pinfo->fd->num,
dcerpc_fragment_table, dcerpc_fragment_table,
0, tvb_length(d_tvb), TRUE); 0, reported_len, TRUE);
fragment_set_tot_len(pinfo, pinfo->fd->num, fragment_set_tot_len(pinfo, pinfo->fd->num,
dcerpc_fragment_table, dcerpc_fragment_table,
pinfo->desegment_len+tvb_length(d_tvb)); pinfo->desegment_len+reported_len);
/* since the other fragments are in normal ReadAndX and WriteAndX calls /* since the other fragments are in normal ReadAndX and WriteAndX calls
we must make sure we can map FID values to this defragmentation we must make sure we can map FID values to this defragmentation
session */ session */

View File

@ -3,7 +3,7 @@
* Gilbert Ramirez <gram@alumni.rice.edu> * Gilbert Ramirez <gram@alumni.rice.edu>
* Jochen Friedrich <jochen@scram.de> * Jochen Friedrich <jochen@scram.de>
* *
* $Id: packet-sna.c,v 1.45 2003/03/02 21:47:45 guy Exp $ * $Id: packet-sna.c,v 1.46 2003/03/05 07:17:50 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com> * By Gerald Combs <gerald@ethereal.com>
@ -1681,6 +1681,7 @@ defragment_by_sequence(packet_info *pinfo, tvbuff_t *tvb, int offset, int mpf,
int frag_number = -1; int frag_number = -1;
int more_frags = TRUE; int more_frags = TRUE;
tvbuff_t *rh_tvb = NULL; tvbuff_t *rh_tvb = NULL;
gint frag_len;
/* Determine frag_number and more_frags */ /* Determine frag_number and more_frags */
switch(mpf) { switch(mpf) {
@ -1703,34 +1704,39 @@ defragment_by_sequence(packet_info *pinfo, tvbuff_t *tvb, int offset, int mpf,
/* If sna_defragment is on, and this is a fragment.. */ /* If sna_defragment is on, and this is a fragment.. */
if (frag_number > -1) { if (frag_number > -1) {
/* XXX - check length ??? */ /* XXX - check length ??? */
fd_head = fragment_add_seq(tvb, offset, pinfo, id, frag_len = tvb_reported_length_remaining(tvb, offset);
sna_fragment_table, frag_number, if (tvb_bytes_exist(tvb, offset, frag_len)) {
tvb_length_remaining(tvb, offset), more_frags);
/* We added the LAST segment and reassembly didn't complete. Insert
* a zero-length MIDDLE segment to turn a 2-frame BIU-fragmentation
* into a 3-frame BIU-fragmentation (empty middle frag).
* See above long comment about this trickery. */
if (mpf == MPF_LAST_SEGMENT && !fd_head) {
fd_head = fragment_add_seq(tvb, offset, pinfo, id, fd_head = fragment_add_seq(tvb, offset, pinfo, id,
sna_fragment_table, MIDDLE_FRAG_NUMBER, 0, TRUE); sna_fragment_table, frag_number, frag_len,
} more_frags);
if (fd_head != NULL) { /* We added the LAST segment and reassembly didn't
/* We have the complete reassembled payload. */ * complete. Insert a zero-length MIDDLE segment to
rh_tvb = tvb_new_real_data(fd_head->data, * turn a 2-frame BIU-fragmentation into a 3-frame
fd_head->len, fd_head->len); * BIU-fragmentation (empty middle frag).
* See above long comment about this trickery. */
/* Add the tvbuff to the chain of tvbuffs so that if (mpf == MPF_LAST_SEGMENT && !fd_head) {
* it will get cleaned up too. */ fd_head = fragment_add_seq(tvb, offset, pinfo,
tvb_set_child_real_data_tvbuff(tvb, rh_tvb); id, sna_fragment_table,
MIDDLE_FRAG_NUMBER, 0, TRUE);
}
/* Add the defragmented data to the data source list. */ if (fd_head != NULL) {
add_new_data_source(pinfo, rh_tvb, /* We have the complete reassembled payload. */
"Reassembled SNA BIU"); rh_tvb = tvb_new_real_data(fd_head->data,
fd_head->len, fd_head->len);
/* Add the tvbuff to the chain of tvbuffs
* so that it will get cleaned up too. */
tvb_set_child_real_data_tvbuff(tvb, rh_tvb);
/* Add the defragmented data to the data
* source list. */
add_new_data_source(pinfo, rh_tvb,
"Reassembled SNA BIU");
}
} }
} }
return rh_tvb; return rh_tvb;

View File

@ -1,7 +1,7 @@
/* packet-tcp.c /* packet-tcp.c
* Routines for TCP packet disassembly * Routines for TCP packet disassembly
* *
* $Id: packet-tcp.c,v 1.185 2003/03/04 04:36:44 sharpe Exp $ * $Id: packet-tcp.c,v 1.186 2003/03/05 07:17:50 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com> * By Gerald Combs <gerald@ethereal.com>
@ -1829,7 +1829,6 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint bpos; guint bpos;
guint optlen; guint optlen;
guint32 nxtseq; guint32 nxtseq;
guint len;
guint reported_len; guint reported_len;
vec_t cksum_vec[4]; vec_t cksum_vec[4];
guint32 phdr[2]; guint32 phdr[2];
@ -1896,7 +1895,6 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */ tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
reported_len = tvb_reported_length(tvb); reported_len = tvb_reported_length(tvb);
len = tvb_length(tvb);
/* Compute the length of data in this segment. */ /* Compute the length of data in this segment. */
tcph->th_seglen = reported_len - tcph->th_hlen; tcph->th_seglen = reported_len - tcph->th_hlen;
@ -2000,7 +1998,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*/ */
pinfo->can_desegment = 0; pinfo->can_desegment = 0;
th_sum = tvb_get_ntohs(tvb, offset + 16); th_sum = tvb_get_ntohs(tvb, offset + 16);
if (!pinfo->fragmented && len >= reported_len) { if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
/* The packet isn't part of an un-reassembled fragmented datagram /* The packet isn't part of an un-reassembled fragmented datagram
and isn't truncated. This means we have all the data, and thus and isn't truncated. This means we have all the data, and thus
can checksum it and, unless it's being returned in an error can checksum it and, unless it's being returned in an error
@ -2034,7 +2032,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
g_assert_not_reached(); g_assert_not_reached();
break; break;
} }
cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len); cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
cksum_vec[3].len = reported_len; cksum_vec[3].len = reported_len;
computed_cksum = in_cksum(&cksum_vec[0], 4); computed_cksum = in_cksum(&cksum_vec[0], 4);
if (computed_cksum == 0) { if (computed_cksum == 0) {

View File

@ -2,7 +2,7 @@
* *
* Routines to dissect WTP component of WAP traffic. * Routines to dissect WTP component of WAP traffic.
* *
* $Id: packet-wtp.c,v 1.42 2002/12/19 11:22:38 sahlberg Exp $ * $Id: packet-wtp.c,v 1.43 2003/03/05 07:17:50 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com> * By Gerald Combs <gerald@ethereal.com>
@ -595,15 +595,16 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* Any remaining data ought to be WSP data (if not WTP ACK, NACK * Any remaining data ought to be WSP data (if not WTP ACK, NACK
* or ABORT pdu), so hand off (defragmented) to the WSP dissector * or ABORT pdu), so hand off (defragmented) to the WSP dissector
*/ */
if ((tvb_length_remaining(tvb, offCur + cbHeader + vHeader) > 0) && if ((tvb_reported_length_remaining(tvb, offCur + cbHeader + vHeader) > 0) &&
! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT))) ! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT)))
{ {
int dataOffset = offCur + cbHeader + vHeader; int dataOffset = offCur + cbHeader + vHeader;
guint32 dataLen = tvb_length_remaining(tvb, offCur + cbHeader + vHeader); gint dataLen = tvb_reported_length_remaining(tvb, dataOffset);
gboolean save_fragmented; gboolean save_fragmented;
if ((pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) || if (((pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) ||
(((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR))) (((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR))) &&
tvb_bytes_exist(tvb, dataOffset, dataLen))
{ /* 1st part of segment */ { /* 1st part of segment */
save_fragmented = pinfo->fragmented; save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE; pinfo->fragmented = TRUE;
@ -632,9 +633,13 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
} }
pinfo->fragmented = save_fragmented; pinfo->fragmented = save_fragmented;
} }
else /* Normal packet, call next dissector */ else
{ {
wsp_tvb = tvb_new_subset(tvb, dataOffset, -1, dataLen); /*
* Normal packet, or not all the fragment data is available;
* call next dissector.
*/
wsp_tvb = tvb_new_subset(tvb, dataOffset, -1, -1);
call_dissector(wsp_handle, wsp_tvb, pinfo, tree); call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
} }
} }