[H248 3GPP] Add dissection of IP transport package.
[metze/wireshark/wip.git] / ui / voip_calls.c
index bdcbb428a83a5b8484b68be26c2c42d3d4b231f9..6cd70d728a767bc6578b161cb8de79aeb4f6e3b5 100644 (file)
 
 #include "epan/epan_dissect.h"
 #include "epan/packet.h"
+#include "epan/proto_data.h"
+#include "epan/to_str.h"
 #include "epan/dissectors/packet-sip.h"
 #include "epan/dissectors/packet-h225.h"
 #include "epan/dissectors/packet-h245.h"
+#include "epan/dissectors/packet-isup.h"
 #include "epan/dissectors/packet-sdp.h"
 #include "epan/dissectors/packet-mgcp.h"
+#include "epan/dissectors/packet-mtp3.h"
 #include "epan/dissectors/packet-actrace.h"
+#include "epan/dissectors/packet-q931.h"
 #include "epan/dissectors/packet-rtp.h"
 #include "epan/dissectors/packet-rtp-events.h"
 #include "epan/dissectors/packet-t38.h"
@@ -122,6 +127,28 @@ enum {
     tap_id_offset_voip_
 };
 
+#define REDRAW_ACTRACE   (1 << tap_id_offset_actrace_)
+#define REDRAW_H225      (1 << tap_id_offset_h225_)
+#define REDRAW_H245DG    (1 << tap_id_offset_h245dg_)
+#define REDRAW_H248      (1 << tap_id_offset_h248_)
+#define REDRAW_IAX2      (1 << tap_id_offset_iax2_)
+#define REDRAW_ISUP      (1 << tap_id_offset_isup_)
+#define REDRAW_M3UA      (1 << tap_id_offset_m3ua_)
+#define REDRAW_MEGACO    (1 << tap_id_offset_megaco_)
+#define REDRAW_MGCP      (1 << tap_id_offset_mgcp_)
+#define REDRAW_MTP3      (1 << tap_id_offset_mtp3_)
+#define REDRAW_Q931      (1 << tap_id_offset_q931_)
+#define REDRAW_RTP       (1 << tap_id_offset_rtp_)
+#define REDRAW_RTP_EVENT (1 << tap_id_offset_rtp_event_)
+#define REDRAW_SCCP      (1 << tap_id_offset_sccp_)
+#define REDRAW_SDP       (1 << tap_id_offset_sdp_)
+#define REDRAW_SIP       (1 << tap_id_offset_sip_)
+#define REDRAW_SKINNY    (1 << tap_id_offset_skinny_)
+#define REDRAW_SUA       (1 << tap_id_offset_sua_)
+#define REDRAW_T38       (1 << tap_id_offset_t38_)
+#define REDRAW_UNISTIM   (1 << tap_id_offset_unistim_)
+#define REDRAW_VOIP      (1 << tap_id_offset_voip_)
+
 static inline void *
 tap_base_to_id(voip_calls_tapinfo_t* tap_base, int offset) {
     return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_base) + offset);
@@ -257,7 +284,7 @@ voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
         g_free(callsinfo->call_id);
         g_free(callsinfo->from_identity);
         g_free(callsinfo->to_identity);
-        g_free((void *)(callsinfo->initial_speaker.data));
+        free_address(&callsinfo->initial_speaker);
         g_free(callsinfo->protocol_name);
         g_free(callsinfo->call_comment);
 
@@ -272,19 +299,13 @@ voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
     if(NULL!=tapinfo->callsinfo_hashtable[SIP_HASH])
         g_hash_table_remove_all (tapinfo->callsinfo_hashtable[SIP_HASH]);
 
-    /* free the graph data items first */
-    if(NULL == tapinfo->graph_analysis) {
-        tapinfo->graph_analysis = sequence_analysis_info_new();
-    }
-
-    sequence_analysis_list_free(tapinfo->graph_analysis);
-
     /* free the strinfo data items first */
     list = g_list_first(tapinfo->rtp_stream_list);
     while(list)
     {
         strinfo = (rtp_stream_info_t *)list->data;
         wmem_free(NULL, strinfo->payload_type_name);
+        wmem_free(NULL, strinfo->ed137_info);
         list = g_list_next(list);
     }
     g_list_free(tapinfo->rtp_stream_list);
@@ -294,6 +315,11 @@ voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
         memset(tapinfo->h245_labels, 0, sizeof(h245_labels_t));
     }
 
+    tapinfo->ncalls = 0;
+    tapinfo->start_packets = 0;
+    tapinfo->completed_calls = 0;
+    tapinfo->rejected_calls = 0;
+
     return;
 }
 
@@ -310,7 +336,7 @@ add_to_graph(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *
     }
 
     gai = (seq_analysis_item_t *)g_malloc0(sizeof(seq_analysis_item_t));
-    gai->frame_number = pinfo->fd->num;
+    gai->frame_number = pinfo->num;
     copy_address(&(gai->src_addr),src_addr);
     copy_address(&(gai->dst_addr),dst_addr);
 
@@ -341,7 +367,7 @@ add_to_graph(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *
 /****************************************************************************/
 /* Append str to frame_label and comment in a graph item */
 /* return 0 if the frame_num is not in the graph list */
-static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
+static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
 {
     seq_analysis_item_t *gai=NULL;
     gchar *frame_label = NULL;
@@ -370,7 +396,7 @@ static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 fram
 /****************************************************************************/
 /* Change the frame_label and comment in a graph item if not NULL*/
 /* return 0 if the frame_num is not in the graph list */
-static int change_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
+static int change_frame_graph(voip_calls_tapinfo_t *tapinfo, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
 {
     seq_analysis_item_t *gai=NULL;
     gchar *frame_label = NULL;
@@ -398,7 +424,7 @@ static int change_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_n
 
 /****************************************************************************/
 /* Change all the graph items with call_num to new_call_num */
-static guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo _U_, guint16 call_num, guint16 new_call_num)
+static guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo, guint16 call_num, guint16 new_call_num)
 {
     seq_analysis_item_t *gai;
     GList *list;
@@ -449,7 +475,7 @@ static void insert_to_graph_t38(voip_calls_tapinfo_t *tapinfo, packet_info *pinf
         new_gai->comment = g_strdup("");
     new_gai->conv_num=call_num;
     new_gai->line_style=line_style;
-    set_fd_time(edt->session, packet_list_get_row_data(frame_num), time_str);
+    set_fd_time(edt->session, pinfo->fd, time_str);
     new_gai->time_str = g_strdup(time_str);
     new_gai->display=FALSE;
 
@@ -496,7 +522,7 @@ rtp_event_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _
         return FALSE;
     }
 
-    tapinfo->rtp_evt_frame_num = pinfo->fd->num;
+    tapinfo->rtp_evt_frame_num = pinfo->num;
     tapinfo->rtp_evt = pi->info_rtp_evt;
     tapinfo->rtp_evt_end = pi->info_end;
 
@@ -595,6 +621,14 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
                this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */
             if ( tmp_listinfo->payload_type != rtp_info->info_payload_type ) {
                 tmp_listinfo->end_stream = TRUE;
+            } else if ( ( ( tmp_listinfo->ed137_info == NULL ) && (rtp_info->info_ed137_info != NULL) ) ||
+                        ( ( tmp_listinfo->ed137_info != NULL ) && (rtp_info->info_ed137_info == NULL) ) ||
+                        ( ( tmp_listinfo->ed137_info != NULL ) && (rtp_info->info_ed137_info != NULL) &&
+                          ( 0!=strcmp(tmp_listinfo->ed137_info, rtp_info->info_ed137_info) )
+                        )
+                      ) {
+            /* if ed137_info has changed, create new stream */
+                tmp_listinfo->end_stream = TRUE;
             } else {
                 strinfo = (rtp_stream_info_t*)(list->data);
                 break;
@@ -604,7 +638,7 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
     }
 
     /* if this is a duplicated RTP Event End, just return */
-    if ((tapinfo->rtp_evt_frame_num == pinfo->fd->num) && !strinfo && (tapinfo->rtp_evt_end == TRUE)) {
+    if ((tapinfo->rtp_evt_frame_num == pinfo->num) && !strinfo && (tapinfo->rtp_evt_end == TRUE)) {
         return FALSE;
     }
 
@@ -635,22 +669,28 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
         strinfo->setup_frame_number = rtp_info->info_setup_frame_num;
         strinfo->call_num = -1;
         strinfo->rtp_event = -1;
+        if (rtp_info->info_ed137_info != NULL) {
+            strinfo->ed137_info = wmem_strdup(NULL, rtp_info->info_ed137_info);
+        } else {
+            strinfo->ed137_info = NULL;
+        }
         tapinfo->rtp_stream_list = g_list_prepend(tapinfo->rtp_stream_list, strinfo);
     }
 
     /* Add the info to the existing RTP stream */
     strinfo->packet_count++;
     strinfo->stop_fd = pinfo->fd;
+    strinfo->stop_rel_time = pinfo->rel_ts;
 
     /* process RTP Event */
-    if (tapinfo->rtp_evt_frame_num == pinfo->fd->num) {
+    if (tapinfo->rtp_evt_frame_num == pinfo->num) {
         strinfo->rtp_event = tapinfo->rtp_evt;
         if (tapinfo->rtp_evt_end == TRUE) {
             strinfo->end_stream = TRUE;
         }
     }
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_RTP;
 
     return FALSE;
 }
@@ -701,11 +741,14 @@ rtp_draw(void *tap_offset_ptr)
                 new_gai->port_src = rtp_listinfo->src_port;
                 new_gai->port_dst = rtp_listinfo->dest_port;
                 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
-                new_gai->frame_label = g_strdup_printf("%s (%s) %s",
+                new_gai->frame_label = g_strdup_printf("%s (%s) %s%s%s",
                         (rtp_listinfo->is_srtp)?"SRTP":"RTP",
                         rtp_listinfo->payload_type_name,
                         (rtp_listinfo->rtp_event == -1)?
-                        "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
+                        "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"),
+                        (rtp_listinfo->ed137_info!=NULL?" ":""),
+                        (rtp_listinfo->ed137_info!=NULL?rtp_listinfo->ed137_info:"")
+                );
                 new_gai->comment = g_strdup_printf(comment_fmt,
                         (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
                         duration/1000,(duration%1000), rtp_listinfo->ssrc);
@@ -721,8 +764,9 @@ rtp_draw(void *tap_offset_ptr)
         rtp_streams_list = g_list_next(rtp_streams_list);
     } /* while (rtp_streams_list) */
 
-    if (tapinfo->tap_draw) {
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_RTP)) {
         tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_RTP;
     }
 }
 #if 0
@@ -989,11 +1033,23 @@ t38_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const
     g_free(comment);
     g_free(frame_label);
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_T38;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+t38_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_t38_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_T38)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_T38;
+    }
+}
+
 /****************************************************************************/
 void
 t38_init_tap(voip_calls_tapinfo_t *tap_id_base)
@@ -1004,7 +1060,7 @@ t38_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             t38_packet,
-            NULL
+            t38_draw
             );
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -1052,7 +1108,7 @@ sip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt ,
 
     const sip_info_value_t *pi = (const sip_info_value_t *)SIPinfo;
 
-    tapinfo->sip_frame_num = pinfo->fd->num;
+    tapinfo->sip_frame_num = pinfo->num;
 
     /* do not consider packets without call_id */
     if (pi->tap_call_id ==NULL) {
@@ -1176,8 +1232,6 @@ TODO: is useful but not perfect, what is appended is truncated when displayed in
                 comment = g_strdup_printf("SIP Request CANCEL CSeq:%d", pi->tap_cseq_number);
             } else {
                 /* comment = g_strdup_printf("SIP %s", pi->request_method); */
-                tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
-                callsinfo->call_state = VOIP_CALL_SETUP;
                 comment = g_strdup_printf("SIP %s From: %s To:%s CSeq:%d",
                         pi->request_method,
                         callsinfo->from_identity,
@@ -1195,23 +1249,35 @@ TODO: is useful but not perfect, what is appended is truncated when displayed in
         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
         g_free(comment);
         g_free(frame_label);
-        g_free((void *)tmp_src.data);
-        g_free((void *)tmp_dst.data);
+        free_address(&tmp_src);
+        free_address(&tmp_dst);
 
         /* add SDP info if apply */
-        if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->fd->num) ) {
-            append_to_frame_graph(tapinfo, pinfo->fd->num, tapinfo->sdp_summary, NULL);
+        if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->num) ) {
+            append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
             g_free(tapinfo->sdp_summary);
             tapinfo->sdp_summary = NULL;
         }
 
     }
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_SIP;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+sip_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SIP)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_SIP;
+    }
+}
+
 /****************************************************************************/
 /* TAP INTERFACE */
 /****************************************************************************/
@@ -1225,7 +1291,7 @@ sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             sip_calls_packet,
-            NULL
+            sip_calls_draw
             );
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -1264,7 +1330,7 @@ isup_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
     const isup_tap_rec_t *pi = (const isup_tap_rec_t *)isup_info;
 
     /* check if the lower layer is MTP matching the frame number */
-    if (tapinfo->mtp3_frame_num != pinfo->fd->num)
+    if (tapinfo->mtp3_frame_num != pinfo->num)
         return FALSE;
 
     /* check whether we already have a call with these parameters in the list */
@@ -1400,11 +1466,23 @@ isup_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
         g_free(frame_label);
     }
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_ISUP;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+isup_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_ISUP)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_ISUP;
+    }
+}
+
 /****************************************************************************/
 
 void
@@ -1417,7 +1495,7 @@ isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             isup_calls_packet,
-            NULL
+            isup_calls_draw
             );
 
     if (error_string != NULL) {
@@ -1453,7 +1531,7 @@ mtp3_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt
     tapinfo->mtp3_opc = pi->addr_opc.pc;
     tapinfo->mtp3_dpc = pi->addr_dpc.pc;
     tapinfo->mtp3_ni = pi->addr_opc.ni;
-    tapinfo->mtp3_frame_num = pinfo->fd->num;
+    tapinfo->mtp3_frame_num = pinfo->num;
 
     return FALSE;
 }
@@ -1541,7 +1619,7 @@ q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
     else
         tapinfo->q931_called_number = g_strdup("");
     tapinfo->q931_cause_value = pi->cause_value;
-    tapinfo->q931_frame_num = pinfo->fd->num;
+    tapinfo->q931_frame_num = pinfo->num;
     tapinfo->q931_crv = pi->crv;
 
 
@@ -1607,7 +1685,7 @@ q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
                             while (list2)
                             {
                                 h245_add=(h245_address_t *)list2->data;
-                                g_free((void *)h245_add->h245_address.data);
+                                free_address(&h245_add->h245_address);
                                 g_free(list2->data);
                                 list2 = g_list_next(list2);
                             }
@@ -1663,7 +1741,7 @@ q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
                     }
 
                     /* Add the H245 info if exists to the Graph */
-                    h245_add_to_graph(tapinfo, pinfo->fd->num);
+                    h245_add_to_graph(tapinfo, pinfo->num);
                     break;
                 }
             }
@@ -1766,14 +1844,26 @@ q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
         wmem_free(NULL, tmp_str);
 
         g_free(comment);
-        g_free((char *)pstn_add.data);
+        free_address(&pstn_add);
     }
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_Q931;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+q931_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_Q931)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_Q931;
+    }
+}
+
 /****************************************************************************/
 
 void
@@ -1786,7 +1876,7 @@ q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             q931_calls_packet,
-            NULL
+            q931_calls_draw
             );
 
     if (error_string != NULL) {
@@ -1827,7 +1917,7 @@ free_h225_info(gpointer p) {
         while (list2)
         {
             h245_address_t *h245_add=(h245_address_t *)list2->data;
-            g_free((void *)h245_add->h245_address.data);
+            free_address(&h245_add->h245_address);
             g_free(list2->data);
             list2 = g_list_next(list2);
         }
@@ -1921,8 +2011,7 @@ h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
         tmp_h323info->guid = (e_guid_t *)g_memdup(&pi->guid, sizeof pi->guid);
         DUMP_PTR1(tmp_h323info->guid);
 
-        tmp_h323info->h225SetupAddr.type = AT_NONE;
-        tmp_h323info->h225SetupAddr.len = 0;
+        clear_address(&tmp_h323info->h225SetupAddr);
         tmp_h323info->h245_list = NULL;
         tmp_h323info->is_faststart_Setup = FALSE;
         tmp_h323info->is_faststart_Proc = FALSE;
@@ -1937,7 +2026,7 @@ h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
     }
 
-    tapinfo->h225_frame_num = pinfo->fd->num;
+    tapinfo->h225_frame_num = pinfo->num;
     tapinfo->h225_call_num = callsinfo->call_num;
 
     /* let's analyze the call state */
@@ -1958,10 +2047,7 @@ h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
         /* this is still IPv4 only, because the dissector is */
         if (pi->is_h245 == TRUE) {
             h245_add = (h245_address_t *)g_malloc(sizeof (h245_address_t));
-            h245_add->h245_address.type=AT_IPv4;
-            h245_add->h245_address.len=4;
-            h245_add->h245_address.data = g_malloc(sizeof(pi->h245_address));
-            memcpy((void *)(h245_add->h245_address.data), &(pi->h245_address), 4);
+            alloc_address_wmem(NULL, &h245_add->h245_address, AT_IPv4, 4, &pi->h245_address);
             h245_add->h245_port = pi->h245_port;
             add_h245_Address(tmp_h323info, h245_add);
         }
@@ -2042,22 +2128,33 @@ h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
     /* add to graph analysis */
 
     /* if the frame number exists in graph, append to it*/
-    if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, comment)) {
+    if (!append_to_frame_graph(tapinfo, pinfo->num, pi->frame_label, comment)) {
         /* if not exist, add to the graph */
         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
     }
 
     /* Add the H245 info if exists to the Graph */
-    h245_add_to_graph(tapinfo, pinfo->fd->num);
+    h245_add_to_graph(tapinfo, pinfo->num);
 
     g_free(frame_label);
     g_free(comment);
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_H225;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+h225_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H225)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_H225;
+    }
+}
 
 /****************************************************************************/
 /* TAP INTERFACE */
@@ -2071,7 +2168,7 @@ h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             h225_calls_packet,
-            NULL
+            h225_calls_draw
             );
 
     if (error_string != NULL) {
@@ -2190,7 +2287,7 @@ h245dg_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *ed
         /* increment the packets counter of all calls */
         ++(tapinfo->npackets);
         /* if the frame number exists in graph, append to it*/
-        if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, pi->comment)) {
+        if (!append_to_frame_graph(tapinfo, pinfo->num, pi->frame_label, pi->comment)) {
             /* if not exist, add to the graph */
             add_to_graph(tapinfo, pinfo, edt, pi->frame_label, pi->comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
         }
@@ -2199,14 +2296,25 @@ h245dg_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *ed
            tunnel OFF but we did not matched the h245 add, in this case nobady will set this label
            since the frame_num will not match */
 
-        h245_add_label(tapinfo, pinfo->fd->num, (gchar *) pi->frame_label, (gchar *) pi->comment);
+        h245_add_label(tapinfo, pinfo->num, (gchar *) pi->frame_label, (gchar *) pi->comment);
     }
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_H245DG;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+h245dg_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H245DG)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_H245DG;
+    }
+}
 
 /****************************************************************************/
 /* TAP INTERFACE */
@@ -2224,7 +2332,7 @@ h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             h245dg_calls_packet,
-            NULL
+            h245dg_calls_draw
             );
 
     if (error_string != NULL) {
@@ -2260,16 +2368,27 @@ sdp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _
        to use it later
      */
     g_free(tapinfo->sdp_summary);
-    tapinfo->sdp_frame_num = pinfo->fd->num;
+    tapinfo->sdp_frame_num = pinfo->num;
     /* Append to graph the SDP summary if the packet exists */
     tapinfo->sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
-    append_to_frame_graph(tapinfo, pinfo->fd->num, tapinfo->sdp_summary, NULL);
+    append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_SDP;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+sdp_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SDP)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_SDP;
+    }
+}
 
 /****************************************************************************/
 /* TAP INTERFACE */
@@ -2283,7 +2402,7 @@ sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             sdp_calls_packet,
-            NULL
+            sdp_calls_draw
             );
 
     if (error_string != NULL) {
@@ -2622,17 +2741,28 @@ mgcp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
     g_free(frame_label);
 
     /* add SDP info if apply */
-    if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->fd->num) ) {
-        append_to_frame_graph(tapinfo, pinfo->fd->num, tapinfo->sdp_summary, NULL);
+    if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->num) ) {
+        append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
         g_free(tapinfo->sdp_summary);
         tapinfo->sdp_summary = NULL;
     }
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_MGCP;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+mgcp_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_MGCP)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_MGCP;
+    }
+}
 
 /****************************************************************************/
 /* TAP INTERFACE */
@@ -2654,7 +2784,7 @@ mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             TL_REQUIRES_PROTO_TREE,
             NULL,
             mgcp_calls_packet,
-            NULL
+            mgcp_calls_draw
             );
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -2685,7 +2815,7 @@ actrace_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *e
     voip_calls_info_t        *tmp_listinfo;
     voip_calls_info_t        *callsinfo = NULL;
 
-    tapinfo->actrace_frame_num = pinfo->fd->num;
+    tapinfo->actrace_frame_num = pinfo->num;
     tapinfo->actrace_trunk = pi->trunk;
     tapinfo->actrace_direction = pi->direction;
 
@@ -2750,11 +2880,22 @@ actrace_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *e
         g_free(comment);
     }
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_ACTRACE;
 
     return TRUE;  /* refresh output */
 }
 
+/****************************************************************************/
+static void
+actrace_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_ACTRACE)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_ACTRACE;
+    }
+}
 
 /****************************************************************************/
 /* TAP INTERFACE */
@@ -2768,7 +2909,7 @@ actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             actrace_calls_packet,
-            NULL
+            actrace_calls_draw
             );
 
     if (error_string != NULL) {
@@ -2797,7 +2938,7 @@ remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base)
 
 
 static gboolean
-h248_calls_packet_common(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
+h248_calls_packet_common(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info, guint32 redraw_bit) {
     const gcp_cmd_t      *cmd       = (const gcp_cmd_t *)prot_info;
     GList                *list;
     voip_calls_info_t    *callsinfo = NULL;
@@ -2889,7 +3030,7 @@ h248_calls_packet_common(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan
 
     ++(tapinfo->npackets);
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= redraw_bit;
 
     return TRUE;
 }
@@ -2898,14 +3039,36 @@ static gboolean
 h248_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
 
-    return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info);
+    return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info, REDRAW_H248);
+}
+
+static void
+h248_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H248)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_H248;
+    }
 }
 
 static gboolean
 megaco_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_megaco_);
 
-    return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info);
+    return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info, REDRAW_MEGACO);
+}
+
+static void
+megaco_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_megaco_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_MEGACO)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_MEGACO;
+    }
 }
 
 void
@@ -2918,7 +3081,7 @@ h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             megaco_calls_packet,
-            NULL);
+            megaco_calls_draw);
 
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -2931,7 +3094,7 @@ h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             h248_calls_packet,
-            NULL);
+            h248_calls_draw);
 
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -2961,7 +3124,7 @@ static const voip_protocol sccp_proto_map[] = {
 const value_string* sccp_payload_values;
 
 static gboolean
-sccp_calls(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
+sccp_calls(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info, guint32 redraw_bit) {
     const sccp_msg_info_t*  msg       = (const sccp_msg_info_t *)prot_info;
     sccp_assoc_info_t*      assoc     = msg->data.co.assoc;
     GList                  *list;
@@ -3059,7 +3222,7 @@ sccp_calls(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *ed
 
     ++(tapinfo->npackets);
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= redraw_bit;
 
     return TRUE;
 }
@@ -3069,16 +3232,37 @@ sccp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
 
     sccp_payload_values = sccp_message_type_acro_values;
-    return sccp_calls(tapinfo, pinfo, edt, prot_info);
+    return sccp_calls(tapinfo, pinfo, edt, prot_info, REDRAW_SCCP);
 }
 
+static void
+sccp_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SCCP)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_SCCP;
+    }
+}
 
 static gboolean
 sua_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
-    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sua_);
 
     sccp_payload_values = sua_co_class_type_acro_values;
-    return sccp_calls(tapinfo, pinfo, edt, prot_info);
+    return sccp_calls(tapinfo, pinfo, edt, prot_info, REDRAW_SUA);
+}
+
+static void
+sua_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sua_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SUA)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_SUA;
+    }
 }
 
 void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
@@ -3090,7 +3274,7 @@ void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             sccp_calls_packet,
-            NULL);
+            sccp_calls_draw);
 
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -3103,7 +3287,7 @@ void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             sua_calls_packet,
-            NULL);
+            sua_calls_draw);
 
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -3583,11 +3767,23 @@ unistim_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *e
     /* free data */
     g_free(comment);
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_UNISTIM;
 
     return TRUE;
 }
 
+/****************************************************************************/
+static void
+unistim_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_unistim_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_UNISTIM)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_UNISTIM;
+    }
+}
+
 /****************************************************************************/
 /* TAP INTERFACE */
 /****************************************************************************/
@@ -3601,7 +3797,7 @@ unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) {
             0,
             NULL,
             unistim_calls_packet,
-            NULL
+            unistim_calls_draw
             );
 
     if (error_string != NULL) {
@@ -3732,9 +3928,22 @@ skinny_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *ed
             callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
     g_free(comment);
 
+    tapinfo->redraw |= REDRAW_SKINNY;
+
     return TRUE;
 }
 
+/****************************************************************************/
+static void
+skinny_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_skinny_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SKINNY)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_SKINNY;
+    }
+}
 
 /****************************************************************************/
 /* TAP INTERFACE */
@@ -3756,7 +3965,7 @@ skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             TL_REQUIRES_PROTO_TREE,
             NULL,
             skinny_calls_packet,
-            NULL
+            skinny_calls_draw
             );
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -3857,10 +4066,23 @@ iax2_calls_packet( void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt
     add_to_graph(tapinfo, pinfo, edt, ii->messageName, "",
             callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
 
+    tapinfo->redraw |= REDRAW_IAX2;
+
     return TRUE;
 
 }
 
+/****************************************************************************/
+static void
+iax2_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_iax2_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_IAX2)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_IAX2;
+    }
+}
 
 /****************************************************************************/
 /* TAP INTERFACE */
@@ -3885,7 +4107,7 @@ iax2_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             TL_REQUIRES_PROTO_TREE,
             NULL,
             iax2_calls_packet,
-            NULL
+            iax2_calls_draw
             );
     if (error_string != NULL) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
@@ -3915,7 +4137,7 @@ voip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
     GList *list = NULL;
     const voip_packet_info_t *pi = (const voip_packet_info_t *)VoIPinfo;
 
-    /* VOIP_CALLS_DEBUG("num %u", pinfo->fd->num); */
+    /* VOIP_CALLS_DEBUG("num %u", pinfo->num); */
     if (pi->call_id)
         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
     while (list) {
@@ -3969,11 +4191,23 @@ voip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt,
     /* add to the graph */
     add_to_graph(tapinfo, pinfo, edt, (pi->frame_label)?pi->frame_label:"VoIP msg", pi->frame_comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw |= REDRAW_VOIP;
 
     return TRUE;
 }
 
+/****************************************************************************/
+static void
+voip_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_voip_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_VOIP)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_VOIP;
+    }
+}
+
 /****************************************************************************/
 
 void
@@ -3986,7 +4220,7 @@ voip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
             0,
             NULL,
             voip_calls_packet,
-            NULL
+            voip_calls_draw
             );
 
     if (error_string != NULL) {
@@ -4015,21 +4249,31 @@ prot_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt
 {
     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_prot_);
     if (callsinfo!=NULL) {
-        callsinfo->stop_abs = pinfo->fd->abs_ts;
+        callsinfo->stop_abs = pinfo->abs_ts;
         callsinfo->stop_rel = pinfo->rel_ts;
-        callsinfo->last_frame_num=pinfo->fd->num;
+        callsinfo->last_frame_num=pinfo->num;
         ++(callsinfo->npackets);
         ++(tapinfo->npackets);
     }
 
-    tapinfo->redraw = TRUE;
+    tapinfo->redraw = REDRAW_PROT;
 
     return TRUE;
 }
-#endif
 
 /****************************************************************************/
-#if 0
+static void
+prot_calls_draw(void *tap_offset_ptr)
+{
+    voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_prot_);
+
+    if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_PROT)) {
+        tapinfo->tap_draw(tapinfo);
+        tapinfo->redraw &= ~REDRAW_PROT;
+    }
+}
+
+/****************************************************************************/
 void
 prot_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
 {
@@ -4039,8 +4283,8 @@ prot_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
                                          NULL,
                                          0,
                                          NULL,
-                                         prot__calls_packet,
-                                         NULL
+                                         prot_calls_packet,
+                                         prot_calls_draw
         );
 
     if (error_string != NULL) {
@@ -4049,10 +4293,8 @@ prot_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
         g_string_free(error_string, TRUE);
     }
 }
-#endif
 
 /****************************************************************************/
-#if 0
 void
 remove_tap_listener_prot__calls(voip_calls_tapinfo_t *tap_id_base)
 {