Ethereal-dev: [Ethereal-dev] Re: New dissectors: H.223 and friends
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Richard van der Hoff <richardv@xxxxxxxxxxxxx>
Date: Tue, 04 Oct 2005 20:21:35 +0100
Hi, Anders Broman wrote:
Hi, I checked in the stream part I had to do some changes to make it compile under Windows can you check that I didn't break anything.
yup, that seems fine. Sorry again for overlooking these - it's quite hard to spot them with a compiler that doesn't complain :(.
However, I've spotted a bug in the new desegmentation in iax2, which means that higher-level PDUs aren't dissected when they ought to be, but tend to be grouped together in later packets - I've attached a patch against svn r16110 to fix this; it also makes the code a bit clearer...
Thanks very much for your help with this, Anders. Just so we're on the same page, here's a list of files which I think still need patching in svn.
configure.in asn1/h245/h245.cnf asn1/h245/packet-h245-template.c asn1/h245/packet-h245-template.h epan/dissectors/packet-h245.c epan/dissectors/packet-h245.h epan/dissectors/packet-iax2.c plugins/Makefile.am plugins/Makefile.nmake plugins/h223/golay.h plugins/h223/packet-srp.c plugins/h223/packet-srp.h Richard -- Richard van der Hoff <richardv@xxxxxxxxxxxxx> Systems Analyst Tel: +44 (0) 845 666 7778 http://www.mxtelecom.com
Index: epan/dissectors/packet-iax2.c =================================================================== RCS file: /cvs/ethereal/epan/dissectors/packet-iax2.c,v retrieving revision 1.1.1.5 retrieving revision 1.19 diff -u -r1.1.1.5 -r1.19 --- epan/dissectors/packet-iax2.c 4 Oct 2005 11:53:51 -0000 1.1.1.5 +++ epan/dissectors/packet-iax2.c 4 Oct 2005 19:03:00 -0000 1.19 @@ -1685,16 +1685,23 @@ guint32 codec = iax_packet -> codec; iax_call_data *iax_call = iax_packet -> call_data; +#ifdef DEBUG_DESEGMENT + g_message("calling process_iax_pdu; len = %u\n", tvb_reported_length(tvb)); +#endif + if( !video && iax_call && iax_call->subdissector ) { call_dissector(iax_call->subdissector, tvb, pinfo, tree); - return; + }else if( codec != 0 && dissector_try_port(iax2_codec_dissector_table, codec, tvb, pinfo, tree )) { + /* codec dissector handled our data */ + }else { + /* we don't know how to dissect our data: dissect it as data */ + call_dissector(data_handle,tvb, pinfo, tree); } - if( codec != 0 && dissector_try_port(iax2_codec_dissector_table, codec, tvb, pinfo, tree )) - return; - - /* we don't know how to dissect our data: dissect it as data */ - call_dissector(data_handle,tvb, pinfo, tree); +#ifdef DEBUG_DESEGMENT + g_message("called process_iax_pdu; pinfo->desegment_len=%u; pinfo->desegment_offset=%u\n", + pinfo->desegment_len, pinfo->desegment_offset); +#endif } static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tree, @@ -1704,17 +1711,18 @@ iax_call_data *iax_call = iax_packet -> call_data; iax_call_dirdata *dirdata; gpointer unused,value; - guint32 fid,frag_len,offset,tot_len,frag_offset,nbytes,deseg_offset; - gint32 old_len; + guint32 frag_len,tot_len,frag_offset,nbytes,deseg_offset; fragment_data *fd_head; - tvbuff_t *next_tvb; gboolean complete = FALSE, called_dissector = FALSE, must_desegment = FALSE; - proto_item *frag_tree_item, *iax_tree_item; pinfo->desegment_offset = 0; pinfo->desegment_len = 0; deseg_offset = 0; +#ifdef DEBUG_DESEGMENT + g_message("dissecting packet %u\n", pinfo->fd->num); +#endif + if( iax_call ) dirdata = &(iax_call->dirdata[!!(iax_packet->reversed)]); else { @@ -1726,25 +1734,30 @@ ((!pinfo->fd->flags.visited && dirdata->in_frag) || g_hash_table_lookup_extended(iax_call->fid_table, GUINT_TO_POINTER(pinfo->fd->num), &unused, &value) ) ) { + guint32 fid = 0; + /* then we are continuing an already-started pdu */ frag_len = tvb_reported_length( tvb ); - offset = 0; if(!pinfo->fd->flags.visited) { fid = dirdata->current_frag_id; tot_len = GPOINTER_TO_UINT(g_hash_table_lookup(iax_call->totlen_table, GUINT_TO_POINTER(fid))); g_hash_table_insert( iax_call->fid_table, GUINT_TO_POINTER(pinfo->fd->num), GUINT_TO_POINTER(fid) ); frag_offset = dirdata->current_frag_bytes; - complete = dirdata->current_frag_bytes > tot_len; dirdata->current_frag_bytes += frag_len; + complete = dirdata->current_frag_bytes > tot_len; +#ifdef DEBUG_DESEGMENT + g_message("in_frag: %i; hash: %u->%u; frag_offset: %u; c_f_b: %u\n", dirdata->in_frag, + pinfo->fd->num, fid, frag_offset, dirdata->current_frag_bytes ); +#endif } else { fid = GPOINTER_TO_UINT(value); - /* these values are unused by fragmen_add if pinfo->fd->flags.visited */ + /* these values are unused by fragment_add if pinfo->fd->flags.visited */ dirdata->current_frag_bytes = 0; complete = FALSE; } /* fragment_add checks for already-added */ - fd_head = fragment_add( tvb, offset, pinfo, fid, + fd_head = fragment_add( tvb, 0, pinfo, fid, iax_call->fragment_table, frag_offset, frag_len, !complete ); @@ -1752,32 +1765,22 @@ if(pinfo->fd->flags.visited) complete = (fd_head && (pinfo->fd->num == fd_head->reassembled_in)); - } else { - fid=offset=0; /* initialise them here aswell to get rid of compiler warnings */ - if(iax_call) - pinfo->can_desegment = 2; - else - pinfo->can_desegment = 0; - process_iax_pdu(tvb,pinfo,tree,video,iax_packet); - called_dissector = TRUE; - if(pinfo->desegment_len) { - must_desegment = TRUE; - deseg_offset = pinfo->desegment_offset; - } - fd_head = NULL; - } - - /* do we have a completely desegmented datagram? */ - if (fd_head) { - /* we've got sometheing dissectable.. but is this the last segment of it? */ - if(complete) { /* this will always be true, since frags are added in seq. */ - next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen, fd_head->datalen); + if(complete) { + gint32 old_len; + tvbuff_t *next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen, fd_head->datalen); tvb_set_child_real_data_tvbuff(tvb, next_tvb); add_new_data_source(pinfo, next_tvb, "Reassembled IAX2"); pinfo->can_desegment = 2; + process_iax_pdu(next_tvb,pinfo,tree,video,iax_packet); called_dissector = TRUE; - old_len = (gint32)(tvb_reported_length(next_tvb) - tvb_reported_length_remaining(tvb,offset)); + + /* calculate the amount of data which was available to the higher-level + dissector before we added this segment; if the returned offset is + within that section, the higher-level dissector was unable to find any + pdus; if it's after that, it found one or more complete PDUs. + */ + old_len = (gint32)(tvb_reported_length(next_tvb) - tvb_reported_length(tvb)); if( pinfo->desegment_len && pinfo->desegment_offset < old_len ) { /* @@ -1785,8 +1788,9 @@ */ fragment_set_partial_reassembly(pinfo, fid, iax_call->fragment_table); g_hash_table_insert(iax_call->totlen_table, GUINT_TO_POINTER(fid), - GUINT_TO_POINTER(tvb_reported_length(next_tvb) + pinfo->desegment_len) ); + GUINT_TO_POINTER(tvb_reported_length(next_tvb) + pinfo->desegment_len) ); } else { + proto_item *iax_tree_item, *frag_tree_item; nbytes = tvb_reported_length( tvb ); show_fragment_tree(fd_head, &iax2_fragment_items, tree, pinfo, next_tvb, &frag_tree_item); iax_tree_item = proto_tree_get_parent( iax2_tree ); @@ -1796,20 +1800,43 @@ proto_tree_move_item( tree, iax_tree_item, frag_tree_item ); dirdata->in_frag = FALSE; if( pinfo->desegment_len ) { - /* - * .. but not everything - */ + /* there's a bit of data left to desegment */ must_desegment = TRUE; - /* make desegment_offset relative to the tvb */ + /* make desegment_offset relative to our tvb */ deseg_offset = pinfo->desegment_offset - (tvb_reported_length( next_tvb ) - tvb_reported_length( tvb )); } } } + } else { + /* This segment was not found in our table, so it doesn't + contain a continuation of a higher-level PDU. + Call the normal subdissector. + */ + if(iax_call) + pinfo->can_desegment = 2; + else + pinfo->can_desegment = 0; + + process_iax_pdu(tvb,pinfo,tree,video,iax_packet); + + called_dissector = TRUE; + + if(pinfo->desegment_len) { + /* the higher-level dissector has asked for some more data - ie, + the end of this segment does not coincide with the end of a + higher-level PDU. */ + must_desegment = TRUE; + deseg_offset = pinfo->desegment_offset; + } + fd_head = NULL; } - if(must_desegment) { - fid = pinfo->fd->num; + /* must_desegment is set if the end of this segment (or the whole of it) + * contained the start of a higher-level PDU; we must add whatever is left of + * this segment (after deseg_offset) to a fragment table for disassembly. */ + if(iax_call && must_desegment) { + guint32 fid = pinfo->fd->num; if(pinfo->fd->flags.visited) { fd_head = fragment_get( pinfo, fid, iax_call->fragment_table ); } else { @@ -1817,27 +1844,34 @@ dirdata->current_frag_id = fid; dirdata->current_frag_bytes = frag_len; dirdata->in_frag = TRUE; - offset = deseg_offset; complete = FALSE; - fd_head = fragment_add(tvb, offset, pinfo, fid, + fd_head = fragment_add(tvb, deseg_offset, pinfo, fid, iax_call->fragment_table, 0, frag_len, !complete ); g_hash_table_insert(iax_call->totlen_table, GUINT_TO_POINTER(fid), GUINT_TO_POINTER( frag_len + pinfo->desegment_len) ); +#ifdef DEBUG_DESEGMENT + g_message("Start offset of undissected bytes: %u; " + "Bytes remaining in this segment: %u; min required bytes: %u\n", + deseg_offset, frag_len, frag_len + pinfo->desegment_len); +#endif } } if( !called_dissector || pinfo->desegment_len != 0 ) { - if( fd_head != NULL && fd_head->reassembled_in != 0 && - !(fd_head->flags & FD_PARTIAL_REASSEMBLY) ) { - iax_tree_item = proto_tree_add_uint( tree, hf_iax2_reassembled_in, - tvb, deseg_offset, tvb_reported_length_remaining(tvb,deseg_offset), - fd_head->reassembled_in); - PROTO_ITEM_SET_GENERATED(iax_tree_item); - } else if(fd_head && (fd_head->reassembled_in != 0 || (fd_head->flags & FD_PARTIAL_REASSEMBLY)) ) { - /* this fragment is never reassembled */ - proto_tree_add_text( tree, tvb, deseg_offset, -1, - "IAX2 fragment, unfinished"); + if( fd_head != NULL ) { + if( fd_head->reassembled_in != 0 && + !(fd_head->flags & FD_PARTIAL_REASSEMBLY) ) { + proto_item *iax_tree_item; + iax_tree_item = proto_tree_add_uint( tree, hf_iax2_reassembled_in, + tvb, deseg_offset, tvb_reported_length_remaining(tvb,deseg_offset), + fd_head->reassembled_in); + PROTO_ITEM_SET_GENERATED(iax_tree_item); + } else { + /* this fragment is never reassembled */ + proto_tree_add_text( tree, tvb, deseg_offset, -1, + "IAX2 fragment, unfinished"); + } } if( pinfo->desegment_offset == 0 ) {
- Follow-Ups:
- Re: [Ethereal-dev] Re: New dissectors: H.223 and friends
- From: Guy Harris
- Re: [Ethereal-dev] Re: New dissectors: H.223 and friends
- From: Guy Harris
- Re: [Ethereal-dev] Re: New dissectors: H.223 and friends
- Prev by Date: [Ethereal-dev] buildbot failure in Windows 2003 (IA32)
- Next by Date: [Ethereal-dev] HTTP body reassembly?
- Previous by thread: Re: [Ethereal-dev] Re: pinfo->can_desegment Handling (was [Ethereal-cvs] rev 16099: /trunk/epan/dissectors/: packet-iax2.c)
- Next by thread: Re: [Ethereal-dev] Re: New dissectors: H.223 and friends
- Index(es):