diff options
-rw-r--r-- | epan/dissectors/packet-iax2.c | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/epan/dissectors/packet-iax2.c b/epan/dissectors/packet-iax2.c index a98bd7cbab..12e89c1983 100644 --- a/epan/dissectors/packet-iax2.c +++ b/epan/dissectors/packet-iax2.c @@ -1854,11 +1854,11 @@ dissect_minipacket (tvbuff_t * tvb, guint32 offset, guint16 scallno, packet_info } -static guint32 dissect_trunkcall_ts (tvbuff_t * tvb, guint32 offset, proto_tree * iax2_tree) +static guint32 dissect_trunkcall_ts (tvbuff_t * tvb, guint32 offset, proto_tree * iax2_tree, guint16 * scallno) { proto_item *call_item; proto_tree *call_tree; - guint16 datalen, rlen, ts, scallno; + guint16 datalen, rlen, ts; /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data Length (in octets) |R| Source Call Number | @@ -1871,13 +1871,13 @@ static guint32 dissect_trunkcall_ts (tvbuff_t * tvb, guint32 offset, proto_tree +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ datalen = tvb_get_ntohs(tvb, offset); - scallno = tvb_get_ntohs(tvb, offset + 2); + *scallno = tvb_get_ntohs(tvb, offset + 2); ts = tvb_get_ntohs(tvb, offset + 4); rlen = MIN(tvb_length(tvb) - offset - 6, datalen); if( iax2_tree ) { - call_item = proto_tree_add_text(iax2_tree, tvb, offset, rlen + 6, "Trunk call from %u, ts: %u", scallno, ts); + call_item = proto_tree_add_text(iax2_tree, tvb, offset, rlen + 6, "Trunk call from %u, ts: %u", *scallno, ts); call_tree = proto_item_add_subtree(call_item, ett_iax2_trunk_call); proto_tree_add_item(call_tree, hf_iax2_trunk_call_len, tvb, offset, 2, ENC_BIG_ENDIAN); @@ -1890,11 +1890,11 @@ static guint32 dissect_trunkcall_ts (tvbuff_t * tvb, guint32 offset, proto_tree return offset; } -static guint32 dissect_trunkcall_nots (tvbuff_t * tvb, guint32 offset, proto_tree * iax2_tree) +static guint32 dissect_trunkcall_nots (tvbuff_t * tvb, guint32 offset, proto_tree * iax2_tree, guint16 * scallno) { proto_item *call_item; proto_tree *call_tree; - guint16 datalen, rlen, scallno; + guint16 datalen, rlen; /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |R| Source Call Number | Data Length (in octets) | @@ -1904,13 +1904,13 @@ static guint32 dissect_trunkcall_nots (tvbuff_t * tvb, guint32 offset, proto_tre | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - scallno = tvb_get_ntohs(tvb, offset); + *scallno = tvb_get_ntohs(tvb, offset); datalen = tvb_get_ntohs(tvb, offset + 2); rlen = MIN(tvb_length(tvb) - offset - 4, datalen); if( iax2_tree ) { - call_item = proto_tree_add_text(iax2_tree, tvb, offset, rlen + 6, "Trunk call from %u", scallno); + call_item = proto_tree_add_text(iax2_tree, tvb, offset, rlen + 6, "Trunk call from %u", *scallno); call_tree = proto_item_add_subtree(call_item, ett_iax2_trunk_call); proto_tree_add_item(call_tree, hf_iax2_trunk_call_scallno, tvb, offset, 2, ENC_BIG_ENDIAN); @@ -1922,16 +1922,58 @@ static guint32 dissect_trunkcall_nots (tvbuff_t * tvb, guint32 offset, proto_tre return offset; } +typedef struct _call_list { + guint16 scallno; + struct _call_list *next; +} call_list; + +static call_list *call_list_append(call_list *list, guint16 scallno) +{ + call_list *node = ep_alloc0(sizeof(call_list)); + + node->scallno = scallno; + + if (list) { + call_list *cur = list; + while (cur->next) { + cur = cur->next; + } + cur->next = node; + return list; + } else { + return node; + } +} + +static gboolean call_list_find(call_list *list, guint16 scallno) +{ + for (; list; list = list->next) { + if (list->scallno == scallno) { + return TRUE; + } + } + return FALSE; +} + +static guint call_list_length(call_list *list) +{ + guint count = 0; + for (; list; list = list->next) { + count++; + } + return count; +} static guint32 dissect_trunkpacket (tvbuff_t * tvb, guint32 offset, guint16 scallno _U_, packet_info * pinfo, proto_tree * iax2_tree, proto_tree *main_tree _U_) { guint8 cmddata, trunkts; - int ncalls = 0; + guint nframes = 0, ncalls = 0; /*iax_packet_data *iax_packet;*/ proto_item *cd, *nc = NULL; proto_tree *field_tree = NULL; + call_list *calls = NULL; cmddata = tvb_get_guint8(tvb, offset + 1); trunkts = cmddata & IAX2_TRUNK_TS; @@ -1965,25 +2007,37 @@ static guint32 dissect_trunkpacket (tvbuff_t * tvb, guint32 offset, if( trunkts ) { /* Trunk calls with timestamp */ while(tvb_length_remaining(tvb, offset) >= 6) { - offset = dissect_trunkcall_ts (tvb, offset, iax2_tree); - ncalls++; - } + guint16 scallno; + offset = dissect_trunkcall_ts (tvb, offset, iax2_tree, &scallno); + if (!call_list_find (calls, scallno)) { + calls = call_list_append (calls, scallno); + } + nframes++; + } } else { /* Trunk calls without timestamp */ while(tvb_length_remaining(tvb, offset) >= 4) { - offset = dissect_trunkcall_nots (tvb, offset, iax2_tree); - ncalls++; + guint16 scallno; + offset = dissect_trunkcall_nots (tvb, offset, iax2_tree, &scallno); + if (!call_list_find (calls, scallno)) { + calls = call_list_append (calls, scallno); + } + nframes++; } } + ncalls = call_list_length (calls); + if( iax2_tree ) { /* number of items */ nc = proto_tree_add_uint(iax2_tree, hf_iax2_trunk_ncalls, NULL, 0, 0, ncalls); PROTO_ITEM_SET_GENERATED(nc); } - col_add_fstr (pinfo->cinfo, COL_INFO, "Trunk packet with %d calls", ncalls); + col_add_fstr (pinfo->cinfo, COL_INFO, "Trunk packet with %d media frame%s for %d call%s", + nframes, plurality(nframes, "", "s"), + ncalls, plurality(ncalls, "", "s")); return offset; } |