* Copyright 2004, Iskratel, Ltd, Kranj
* By Miha Jemec <m.jemec@iskratel.si>
*
- * H323, RTP, MGCP and Graph Support
+ * H323, RTP, RTP Event, MGCP, AudioCodes (ISDN PRI and CAS) and Graph Support
* By Alejandro Vaquero, alejandro.vaquero@verso.com
* Copyright 2005, Verso Technologies Inc.
*
#include <epan/dissectors/packet-q931.h>
#include <epan/dissectors/packet-sdp.h>
#include <plugins/mgcp/packet-mgcp.h>
+#include <epan/dissectors/packet-actrace.h>
#include <epan/dissectors/packet-rtp.h>
+#include <epan/dissectors/packet-rtp-events.h>
+#include <epan/conversation.h>
#include "rtp_pt.h"
#include "alert_box.h"
#include "simple_dialog.h"
-char *voip_call_state_name[7]={
+const char *voip_call_state_name[7]={
"CALL SETUP",
"RINGING",
"IN CALL",
};
/* defines whether we can consider the call active */
-char *voip_protocol_name[4]={
+const char *voip_protocol_name[6]={
"SIP",
"ISUP",
"H323",
- "MGCP"
+ "MGCP",
+ "AC_ISDN",
+ "AC_CAS"
};
+typedef struct {
+ gchar *frame_label;
+ gchar *comment;
+} graph_str;
+
+#define H245_MAX 6
+
+typedef struct {
+ guint32 frame_num;
+ gint8 labels_count;
+ graph_str labels[H245_MAX];
+} h245_labels_t;
+static h245_labels_t h245_labels;
/****************************************************************************/
/* the one and only global voip_calls_tapinfo_t structure */
static voip_calls_tapinfo_t the_tapinfo_struct =
- {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0};
+ {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/* the one and only global voip_rtp_tapinfo_t structure */
static voip_rtp_tapinfo_t the_tapinfo_rtp_struct =
- {0, NULL, 0};
+ {0, NULL, 0, 0};
/****************************************************************************/
/* when there is a [re]reading of packet's */
/****************************************************************************/
/* Add a new item into the graph */
-int add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, gchar *frame_label, gchar *comment, guint16 call_num)
+static int add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, const gchar *frame_label, gchar *comment, guint16 call_num, address *src_addr, address *dst_addr)
{
graph_analysis_item_t *gai;
gai = g_malloc(sizeof(graph_analysis_item_t));
gai->frame_num = pinfo->fd->num;
- gai->time= (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000;
- COPY_ADDRESS(&(gai->src_addr),&(pinfo->src));
- COPY_ADDRESS(&(gai->dst_addr),&(pinfo->dst));
+ gai->time= nstime_to_sec(&pinfo->fd->rel_ts);
+ COPY_ADDRESS(&(gai->src_addr),src_addr);
+ COPY_ADDRESS(&(gai->dst_addr),dst_addr);
+
gai->port_src=pinfo->srcport;
gai->port_dst=pinfo->destport;
if (frame_label != NULL)
/****************************************************************************/
/* Append str to frame_label and comment in a graph item */
/* return 0 if the frame_num is not in the graph list */
-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 _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
{
graph_analysis_item_t *gai;
GList* list;
}
+/****************************************************************************/
+/* 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)
+{
+ graph_analysis_item_t *gai;
+ GList* list;
+ gchar *tmp_str = NULL;
+ gchar *tmp_str2 = NULL;
+
+ list = g_list_first(tapinfo->graph_analysis->list);
+ while (list)
+ {
+ gai = list->data;
+ if (gai->frame_num == frame_num){
+ tmp_str = gai->frame_label;
+ tmp_str2 = gai->comment;
+
+ if (new_frame_label != NULL){
+ gai->frame_label = g_strdup(new_frame_label);
+ g_free(tmp_str);
+ }
+
+ if (new_comment != NULL){
+ gai->comment = g_strdup(new_comment);
+ g_free(tmp_str2);
+ }
+ break;
+ }
+ list = g_list_next (list);
+ }
+ if (tmp_str == NULL) return 0; /* it is not in the list */
+ return 1;
+
+}
+
/****************************************************************************/
/* Change all the graph items with call_num to new_call_num */
-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 _U_, guint16 call_num, guint16 new_call_num)
{
graph_analysis_item_t *gai;
GList* list;
return items_changed;
}
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+/* ***************************TAP for RTP Events*****************************/
+/****************************************************************************/
+
+/****************************************************************************/
+/* whenever a rtp event packet is seen by the tap listener */
+static int
+rtp_event_packet(void *ptr _U_, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *rtp_event_info)
+{
+ const struct _rtp_event_info *pi = rtp_event_info;
+ voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
+ voip_rtp_stream_info_t *tmp_listinfo;
+ voip_rtp_stream_info_t *strinfo = NULL;
+ GList* list;
+
+ /* do not consider RTP events packets without a setup frame */
+ if (pi->info_setup_frame_num == 0){
+ return 0;
+ }
+
+ /* check wether we already have a RTP stream with this setup frame in the list */
+ list = g_list_first(tapinfo->list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if ( (tmp_listinfo->setup_frame_number == pi->info_setup_frame_num)
+ && (tmp_listinfo->end_stream == FALSE) && (tmp_listinfo->rtp_event == -1)){
+ strinfo = (voip_rtp_stream_info_t*)(list->data);
+ strinfo->rtp_event = pi->info_rtp_evt;
+ break;
+ }
+ list = g_list_next (list);
+ }
+
+
+ return 0;
+}
+
+/****************************************************************************/
+static gboolean have_rtp_event_tap_listener=FALSE;
+
+void
+rtp_event_init_tap(void)
+{
+ GString *error_string;
+
+
+ if(have_rtp_event_tap_listener==FALSE)
+ {
+ error_string = register_tap_listener("rtpevent", &(the_tapinfo_rtp_struct.rtp_event_dummy),
+ NULL,
+ NULL,
+ rtp_event_packet,
+ NULL
+ );
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_rtp_event_tap_listener=TRUE;
+ }
+}
+
+/****************************************************************************/
+
+void
+remove_tap_listener_rtp_event(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&(the_tapinfo_rtp_struct.rtp_event_dummy));
+ unprotect_thread_critical_region();
+
+ have_rtp_event_tap_listener=FALSE;
+}
+
/****************************************************************************/
/* ***************************TAP for RTP **********************************/
/****************************************************************************/
/****************************************************************************/
/* when there is a [re]reading of RTP packet's */
-void voip_rtp_reset(void *ptr _U_)
+static void voip_rtp_reset(void *ptr _U_)
{
voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
GList* list;
voip_rtp_stream_info_t *tmp_listinfo;
voip_rtp_stream_info_t *strinfo = NULL;
GList* list;
+ struct _rtp_conversation_info *p_conv_data = NULL;
const struct _rtp_info *pi = RTPinfo;
strinfo->ssrc = pi->info_sync_src;
strinfo->end_stream = FALSE;
strinfo->pt = pi->info_payload_type;
+ strinfo->pt_str = NULL;
+ /* if it is dynamic payload, let use the conv data to see if it is defined */
+ if ( (strinfo->pt>95) && (strinfo->pt<128) ) {
+ /* Use existing packet info if available */
+ p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
+ if (p_conv_data)
+ strinfo->pt_str = g_strdup(g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &strinfo->pt));
+ }
+ if (!strinfo->pt_str) strinfo->pt_str = g_strdup(val_to_str(strinfo->pt, rtp_payload_type_short_vals, "%u"));
strinfo->npackets = 0;
strinfo->first_frame_num = pinfo->fd->num;
- strinfo->start_rel_sec = pinfo->fd->rel_secs;
- strinfo->start_rel_usec = pinfo->fd->rel_usecs;
+ strinfo->start_rel_sec = pinfo->fd->rel_ts.secs;
+ strinfo->start_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
strinfo->setup_frame_number = pi->info_setup_frame_num;
+ strinfo->rtp_event = -1;
tapinfo->list = g_list_append(tapinfo->list, strinfo);
}
if (strinfo!=NULL){
/* Add the info to the existing RTP stream */
strinfo->npackets++;
- strinfo->stop_rel_sec = pinfo->fd->rel_secs;
- strinfo->stop_rel_usec = pinfo->fd->rel_usecs;
+ strinfo->stop_rel_sec = pinfo->fd->rel_ts.secs;
+ strinfo->stop_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
}
+
+ the_tapinfo_struct.redraw = TRUE;
+
return 1;
}
/****************************************************************************/
/* whenever a redraw in the RTP tap listener */
-void RTP_packet_draw(void *prs _U_)
+static void RTP_packet_draw(void *prs _U_)
{
voip_rtp_tapinfo_t *rtp_tapinfo = &the_tapinfo_rtp_struct;
GList* rtp_streams_list;
new_gai->port_src = rtp_listinfo->src_port;
new_gai->port_dst = rtp_listinfo->dest_port;
duration = (rtp_listinfo->stop_rel_sec*1000000 + rtp_listinfo->stop_rel_usec) - (rtp_listinfo->start_rel_sec*1000000 + rtp_listinfo->start_rel_usec);
- new_gai->frame_label = g_strdup_printf("RTP (%s)", val_to_str(rtp_listinfo->pt, rtp_payload_type_short_vals, "%u"));
+ new_gai->frame_label = g_strdup_printf("RTP (%s) %s", rtp_listinfo->pt_str, (rtp_listinfo->rtp_event == -1)?"":val_to_str(rtp_listinfo->rtp_event, rtp_event_type_values, "Uknown RTP Event"));
+ g_free(rtp_listinfo->pt_str);
new_gai->comment = g_strdup_printf("RTP Num packets:%d Duration:%d.%03ds ssrc:%d", rtp_listinfo->npackets, duration/1000000,(duration%1000000)/1000, rtp_listinfo->ssrc);
new_gai->conv_num = conv_num;
new_gai->display=FALSE;
}
}
-
-
-/* XXX just copied from gtk/rpc_stat.c */
-void protect_thread_critical_region(void);
-void unprotect_thread_critical_region(void);
-
/****************************************************************************/
void
remove_tap_listener_rtp(void)
have_RTP_tap_listener=FALSE;
}
+/****************************************************************************/
+static gchar *sdp_summary = NULL;
+static guint32 sdp_frame_num = 0;
+
/****************************************************************************/
/* ***************************TAP for SIP **********************************/
/****************************************************************************/
COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
strinfo->first_frame_num=pinfo->fd->num;
strinfo->selected=FALSE;
- strinfo->start_sec=pinfo->fd->rel_secs;
- strinfo->start_usec=pinfo->fd->rel_usecs;
+ strinfo->start_sec=pinfo->fd->rel_ts.secs;
+ strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
strinfo->protocol=VOIP_SIP;
strinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
tmp_sipinfo=strinfo->prot_info;
}
}
- g_free(pi->tap_from_addr);
- g_free(pi->tap_to_addr);
- g_free(pi->tap_call_id);
-
if (strinfo!=NULL){
/* let's analyze the call state */
}
}
- strinfo->stop_sec=pinfo->fd->rel_secs;
- strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+ strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
strinfo->last_frame_num=pinfo->fd->num;
++(strinfo->npackets);
/* increment the packets counter of all calls */
++(tapinfo->npackets);
/* add to the graph */
- add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));
g_free(comment);
g_free(frame_label);
g_free((void *)tmp_src.data);
g_free((void *)tmp_dst.data);
+
+ /* add SDP info if apply */
+ if ( (sdp_summary != NULL) && (sdp_frame_num == pinfo->fd->num) ){
+ append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
+ g_free(sdp_summary);
+ sdp_summary = NULL;
+ }
}
+
+ tapinfo->redraw = TRUE;
+
return 1; /* refresh output */
}
/****************************************************************************/
-const voip_calls_tapinfo_t* voip_calls_get_info(void)
+voip_calls_tapinfo_t* voip_calls_get_info(void)
{
return &the_tapinfo_struct;
}
/* ***************************TAP for ISUP **********************************/
/****************************************************************************/
-static gchar isup_called_number[255], isup_calling_number[255];
-static guint16 isup_cic;
-static guint8 isup_message_type;
-static guint8 isup_cause_value;
-static guint32 isup_frame_num;
+static guint32 mtp3_opc, mtp3_dpc;
+static guint8 mtp3_ni;
+static guint32 mtp3_frame_num;
+
/****************************************************************************/
/* whenever a isup_ packet is seen by the tap listener */
static int
isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *isup_info _U_)
-{
- /*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; unused */
- const isup_tap_rec_t *pi = isup_info;
-
- if (pi->calling_number!=NULL){
- strcpy(isup_calling_number, pi->calling_number);
- }
- if (pi->called_number!=NULL){
- strcpy(isup_called_number, pi->called_number);
- }
- isup_message_type = pi->message_type;
- isup_cause_value = pi->cause_value;
- isup_cic = pinfo->circuit_id;
-
- isup_frame_num = pinfo->fd->num;
-
- return 0;
-}
-
-/****************************************************************************/
-
-static gboolean have_isup_tap_listener=FALSE;
-
-void
-isup_calls_init_tap(void)
-{
- GString *error_string;
-
-
- if(have_isup_tap_listener==FALSE)
- {
- error_string = register_tap_listener("isup", &(the_tapinfo_struct.isup_dummy),
- NULL,
- voip_calls_dlg_reset,
- isup_calls_packet,
- voip_calls_dlg_draw
- );
-
- if (error_string != NULL) {
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- error_string->str);
- g_string_free(error_string, TRUE);
- exit(1);
- }
- have_isup_tap_listener=TRUE;
- }
-}
-
-/****************************************************************************/
-
-void
-remove_tap_listener_isup_calls(void)
-{
- protect_thread_critical_region();
- remove_tap_listener(&(the_tapinfo_struct.isup_dummy));
- unprotect_thread_critical_region();
-
- have_isup_tap_listener=FALSE;
-}
-
-
-/****************************************************************************/
-/* ***************************TAP for MTP3 **********************************/
-/****************************************************************************/
-
-
-/****************************************************************************/
-/* whenever a mtp3_ packet is seen by the tap listener */
-static int
-mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info _U_)
{
voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
voip_calls_info_t *tmp_listinfo;
isup_calls_info_t *tmp_isupinfo;
gboolean found = FALSE;
gboolean forward = FALSE;
- gboolean right_pair = TRUE;
+ gboolean right_pair;
GList* list;
gchar *frame_label = NULL;
gchar *comment = NULL;
int i;
- const mtp3_tap_rec_t *pi = mtp3_info;
+ /*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; unused */
+ const isup_tap_rec_t *pi = isup_info;
+
- /* check if the upper layer is ISUP matching the frame number */
- if (isup_frame_num != pinfo->fd->num) return 0;
+ /* check if the lower layer is MTP matching the frame number */
+ if (mtp3_frame_num != pinfo->fd->num) return 0;
/* check wether we already have a call with these parameters in the list */
list = g_list_first(tapinfo->strinfo_list);
while (list)
{
+ right_pair = TRUE;
tmp_listinfo=list->data;
if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)){
tmp_isupinfo = tmp_listinfo->prot_info;
- if ((tmp_isupinfo->cic == isup_cic)&&(tmp_isupinfo->ni == pi->addr_opc.ni)) {
- if ((tmp_isupinfo->opc == pi->addr_opc.pc)&&(tmp_isupinfo->dpc == pi->addr_dpc.pc)){
+ if ((tmp_isupinfo->cic == pinfo->circuit_id)&&(tmp_isupinfo->ni == mtp3_ni)) {
+ if ((tmp_isupinfo->opc == mtp3_opc)&&(tmp_isupinfo->dpc == mtp3_dpc)){
forward = TRUE;
}
- else if ((tmp_isupinfo->dpc == pi->addr_opc.pc)&&(tmp_isupinfo->opc == pi->addr_dpc.pc)){
+ else if ((tmp_isupinfo->dpc == mtp3_opc)&&(tmp_isupinfo->opc == mtp3_dpc)){
forward = FALSE;
}
else{
- /* XXX: what about forward is it FALSE as declared or should it be true */
right_pair = FALSE;
}
if (right_pair){
if (tmp_listinfo->call_state == VOIP_CALL_SETUP){
found = TRUE;
}
- else if (isup_message_type != 1){
+ else if (pi->message_type != 1){
found = TRUE;
}
else{
-i.e. if this session is a call*/
- if ((strinfo==NULL) &&(isup_message_type==1)){
+ if ((strinfo==NULL) &&(pi->message_type==1)){
strinfo = g_malloc(sizeof(voip_calls_info_t));
strinfo->call_active_state = VOIP_ACTIVE;
COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
strinfo->selected=FALSE;
strinfo->first_frame_num=pinfo->fd->num;
- strinfo->start_sec=pinfo->fd->rel_secs;
- strinfo->start_usec=pinfo->fd->rel_usecs;
+ strinfo->start_sec=pinfo->fd->rel_ts.secs;
+ strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
strinfo->protocol=VOIP_ISUP;
- strinfo->from_identity=g_strdup(isup_calling_number);
- strinfo->to_identity=g_strdup(isup_called_number);
+ if (pi->calling_number!=NULL){
+ strinfo->from_identity=g_strdup(pi->calling_number);
+ }
+ if (pi->called_number!=NULL){
+ strinfo->to_identity=g_strdup(pi->called_number);
+ }
strinfo->prot_info=g_malloc(sizeof(isup_calls_info_t));
tmp_isupinfo=strinfo->prot_info;
- tmp_isupinfo->opc = pi->addr_opc.pc;
- tmp_isupinfo->dpc = pi->addr_dpc.pc;
- tmp_isupinfo->ni = pi->addr_opc.ni;
+ tmp_isupinfo->opc = mtp3_opc;
+ tmp_isupinfo->dpc = mtp3_dpc;
+ tmp_isupinfo->ni = mtp3_ni;
tmp_isupinfo->cic = pinfo->circuit_id;
strinfo->npackets = 0;
strinfo->call_num = tapinfo->ncalls++;
}
if (strinfo!=NULL){
- strinfo->stop_sec=pinfo->fd->rel_secs;
- strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+ strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
strinfo->last_frame_num=pinfo->fd->num;
++(strinfo->npackets);
/* Let's analyze the call state */
- for (i=0;(isup_message_type_value[i].strptr!=NULL)&& (isup_message_type_value[i].value!=isup_message_type);i++);
+ for (i=0;(isup_message_type_value[i].strptr!=NULL)&& (isup_message_type_value[i].value!=pi->message_type);i++);
- if (isup_message_type_value[i].value==isup_message_type){
+ if (isup_message_type_value[i].value==pi->message_type){
frame_label = g_strdup(isup_message_type_value_acro[i].strptr);
}
else{
}
if (strinfo->npackets == 1){ /* this is the first packet, that must be an IAM */
- comment = g_strdup_printf("Call from %s to %s",
- isup_calling_number, isup_called_number);
+ if ((pi->calling_number!=NULL)&&(pi->called_number !=NULL)){
+ comment = g_strdup_printf("Call from %s to %s",
+ pi->calling_number, pi->called_number);
+ }
}
else if (strinfo->npackets == 2){ /* in the second packet we show the SPs */
if (forward){
comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
- pi->addr_opc.ni, pi->addr_opc.pc,
- pi->addr_opc.ni, pi->addr_dpc.pc, pinfo->circuit_id);
+ mtp3_ni, mtp3_opc,
+ mtp3_ni, mtp3_dpc, pinfo->circuit_id);
}
else{
comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
- pi->addr_opc.ni, pi->addr_dpc.pc,
- pi->addr_opc.ni, pi->addr_opc.pc, pinfo->circuit_id);
+ mtp3_ni, mtp3_dpc,
+ mtp3_ni, mtp3_opc, pinfo->circuit_id);
}
}
- switch(isup_message_type){
+ switch(pi->message_type){
case 1: /* IAM */
strinfo->call_state=VOIP_CALL_SETUP;
break;
strinfo->call_state = VOIP_COMPLETED;
tapinfo->completed_calls++;
}
- for (i=0;(q931_cause_code_vals[i].strptr!=NULL)&& (q931_cause_code_vals[i].value!=isup_cause_value);i++);
- if (q931_cause_code_vals[i].value==isup_cause_value){
- comment = g_strdup_printf("Cause %i - %s",isup_cause_value, q931_cause_code_vals[i].strptr);
+ for (i=0;(q931_cause_code_vals[i].strptr!=NULL)&& (q931_cause_code_vals[i].value!=pi->cause_value);i++);
+ if (q931_cause_code_vals[i].value==pi->cause_value){
+ comment = g_strdup_printf("Cause %i - %s",pi->cause_value, q931_cause_code_vals[i].strptr);
}
else{
- comment = g_strdup_printf("Cause %i",isup_cause_value);
+ comment = g_strdup_printf("Cause %i",pi->cause_value);
}
break;
}
++(tapinfo->npackets);
/* add to the graph */
- add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));
g_free(comment);
g_free(frame_label);
}
+ tapinfo->redraw = TRUE;
- return 1;
+ return 1; /* refresh output */
+}
+
+/****************************************************************************/
+
+static gboolean have_isup_tap_listener=FALSE;
+
+void
+isup_calls_init_tap(void)
+{
+ GString *error_string;
+
+
+ if(have_isup_tap_listener==FALSE)
+ {
+ error_string = register_tap_listener("isup", &(the_tapinfo_struct.isup_dummy),
+ NULL,
+ voip_calls_dlg_reset,
+ isup_calls_packet,
+ voip_calls_dlg_draw
+ );
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_isup_tap_listener=TRUE;
+ }
+}
+
+/****************************************************************************/
+
+void
+remove_tap_listener_isup_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&(the_tapinfo_struct.isup_dummy));
+ unprotect_thread_critical_region();
+
+ have_isup_tap_listener=FALSE;
+}
+
+
+/****************************************************************************/
+/* ***************************TAP for MTP3 **********************************/
+/****************************************************************************/
+
+
+/****************************************************************************/
+/* whenever a mtp3_ packet is seen by the tap listener */
+static int
+mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info _U_)
+{
+ const mtp3_tap_rec_t *pi = mtp3_info;
+
+ /* keep the data in memory to use when the ISUP information arrives */
+
+ mtp3_opc = pi->addr_opc.pc;
+ mtp3_dpc = pi->addr_dpc.pc;
+ mtp3_ni = pi->addr_opc.ni;
+ mtp3_frame_num = pinfo->fd->num;
+
+ return 0;
}
/****************************************************************************/
}
}
-/****************************************************************************/
+/****************************************************************************/
+
+void
+remove_tap_listener_mtp3_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&(the_tapinfo_struct.mtp3_dummy));
+ unprotect_thread_critical_region();
+
+ have_mtp3_tap_listener=FALSE;
+}
+
+/****************************************************************************/
+/* ***************************TAP for Q931 **********************************/
+/****************************************************************************/
+void h245_add_to_graph(guint32 new_frame_num);
+#define GUID_LEN 16
+static const guint8 guid_allzero[GUID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+/* defines specific H323 data */
+
+static gchar *q931_calling_number;
+static gchar *q931_called_number;
+static guint8 q931_cause_value;
+static gint32 q931_crv;
+static guint32 q931_frame_num;
+
+static guint32 h225_frame_num = 0;
+static guint16 h225_call_num = 0;
+static h225_cs_type h225_cstype = H225_OTHER;
+static gboolean h225_is_faststart;
+
+static guint32 actrace_frame_num = 0;
+static gint32 actrace_trunk = 0;
+static gint32 actrace_direction = 0;
+
+
+/****************************************************************************/
+/* whenever a q931_ packet is seen by the tap listener */
+static int
+q931_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *q931_info _U_)
+{
+ GList *list,*list2;
+ voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
+ h323_calls_info_t *tmp_h323info,*tmp2_h323info;
+ actrace_isdn_calls_info_t *tmp_actrace_isdn_info;
+ voip_calls_info_t *tmp_listinfo;
+ voip_calls_info_t *strinfo = NULL;
+ h245_address_t *h245_add = NULL;
+ gchar *comment;
+
+ const q931_packet_info *pi = q931_info;
+
+ /* free previously allocated q931_calling/ed_number */
+ g_free(q931_calling_number);
+ g_free(q931_called_number);
+
+ if (pi->calling_number!=NULL)
+ q931_calling_number = g_strdup(pi->calling_number);
+ else
+ q931_calling_number = g_strdup("");
+
+ if (pi->called_number!=NULL)
+ q931_called_number = g_strdup(pi->called_number);
+ else
+ q931_called_number = g_strdup("");
+ q931_cause_value = pi->cause_value;
+ q931_frame_num = pinfo->fd->num;
+ q931_crv = pi->crv;
+
+
+ /* add staff to H323 calls */
+ if (h225_frame_num == q931_frame_num) {
+ tmp_h323info = NULL;
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == h225_call_num) ){
+ tmp_h323info = tmp_listinfo->prot_info;
+ strinfo = (voip_calls_info_t*)(list->data);
+
+ /* Add the CRV to the h323 call */
+ if (tmp_h323info->q931_crv == -1) {
+ tmp_h323info->q931_crv = q931_crv;
+ } else if (tmp_h323info->q931_crv != q931_crv) {
+ tmp_h323info->q931_crv2 = q931_crv;
+ }
+ break;
+ }
+ list = g_list_next (list);
+ }
+
+ if (strinfo != NULL) {
+ comment = NULL;
+ if (h225_cstype == H225_SETUP) {
+ /* set te calling and called number from the Q931 packet */
+ if (q931_calling_number != NULL){
+ g_free(strinfo->from_identity);
+ strinfo->from_identity=g_strdup(q931_calling_number);
+ }
+ if (q931_called_number != NULL){
+ g_free(strinfo->to_identity);
+ strinfo->to_identity=g_strdup(q931_called_number);
+ }
+
+ /* check if there is an LRQ/LCF that match this Setup */
+ /* TODO: we are just checking the DialedNumer in LRQ/LCF agains the Setup
+ we should also check if the h225 signaling IP and port match the destination
+ Setup ip and port */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if (tmp_listinfo->protocol == VOIP_H323){
+ tmp2_h323info = tmp_listinfo->prot_info;
+
+ /* check if the called number match a LRQ/LCF */
+ if ( (strcmp(strinfo->to_identity, tmp_listinfo->to_identity)==0)
+ && (memcmp(tmp2_h323info->guid, guid_allzero, GUID_LEN) == 0) ){
+ /* change the call graph to the LRQ/LCF to belong to this call */
+ strinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, strinfo->call_num);
+
+ /* remove this LRQ/LCF call entry because we have found the Setup that match them */
+ g_free(tmp_listinfo->from_identity);
+ g_free(tmp_listinfo->to_identity);
+ g_free(tmp2_h323info->guid);
+
+ list2 = g_list_first(tmp2_h323info->h245_list);
+ while (list2)
+ {
+ h245_add=list2->data;
+ g_free((void *)h245_add->h245_address.data);
+ g_free(list2->data);
+ list2 = g_list_next(list2);
+ }
+ g_list_free(tmp_h323info->h245_list);
+ tmp_h323info->h245_list = NULL;
+ g_free(tmp_listinfo->prot_info);
+ tapinfo->strinfo_list = g_list_remove(tapinfo->strinfo_list, tmp_listinfo);
+ break;
+ }
+ }
+ list = g_list_next (list);
+ }
+
+ comment = g_strdup_printf("H225 From: %s To:%s TunnH245:%s FS:%s", strinfo->from_identity, strinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
+ (h225_is_faststart==TRUE?"on":"off"));
+ } else if (h225_cstype == H225_RELEASE_COMPLET) {
+ /* get the Q931 Release cause code */
+ if (q931_cause_value != 0xFF){
+ comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
+ } else { /* Cause not set */
+ comment = g_strdup("H225 No Q931 Rel Cause");
+ }
+ }
+ /* change the graph comment for this new one */
+ if (comment != NULL) {
+ change_frame_graph(tapinfo, h225_frame_num, NULL, comment);
+ g_free(comment);
+ }
+ }
+ /* we reset the h225_frame_num to 0 because there could be empty h225 in the same frame
+ as non empty h225 (e.g connect), so we don't have to be here twice */
+ h225_frame_num = 0;
+
+ /* add staff to H245 */
+ } else if (h245_labels.frame_num == q931_frame_num) {
+ /* there are empty H225 frames that don't have guid (guaid=0) but they have h245 info,
+ so the only way to match those frames is with the Q931 CRV number */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if (tmp_listinfo->protocol == VOIP_H323){
+ tmp_h323info = tmp_listinfo->prot_info;
+ if ( ((tmp_h323info->q931_crv == q931_crv) || (tmp_h323info->q931_crv2 == q931_crv)) && (q931_crv!=-1)){
+
+ comment = g_strdup("");
+
+ /* if the frame number exists in graph, append to it*/
+ if (!append_to_frame_graph(tapinfo, q931_frame_num, "", comment)) {
+ /* if not exist, add to the graph */
+ add_to_graph(tapinfo, pinfo, "", comment, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst));
+ ++(tmp_listinfo->npackets);
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
+ }
+
+ /* Add the H245 info if exists to the Graph */
+ h245_add_to_graph(pinfo->fd->num);
+ g_free(comment);
+ break;
+ }
+ }
+ list = g_list_next (list);
+ }
+
+ /* add staff to ACTRACE */
+ } else if (actrace_frame_num == q931_frame_num) {
+ address pstn_add;
+ gchar *comment = NULL;
+
+ strinfo = NULL;
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if ( tmp_listinfo->protocol == VOIP_AC_ISDN ){
+ tmp_actrace_isdn_info = tmp_listinfo->prot_info;
+ /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
+ if ( (tmp_actrace_isdn_info->crv == q931_crv) && (tmp_actrace_isdn_info->trunk == actrace_trunk) ) {
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+ list = g_list_next (list);
+ }
+
+ SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
-void
-remove_tap_listener_mtp3_calls(void)
-{
- protect_thread_critical_region();
- remove_tap_listener(&(the_tapinfo_struct.mtp3_dummy));
- unprotect_thread_critical_region();
+ /* if it is a new call, add it to the list */
+ if (!strinfo) {
+ strinfo = g_malloc(sizeof(voip_calls_info_t));
+ strinfo->call_active_state = VOIP_ACTIVE;
+ strinfo->call_state = VOIP_CALL_SETUP;
+ strinfo->from_identity=g_strdup(q931_calling_number);
+ strinfo->to_identity=g_strdup(q931_called_number);
+ COPY_ADDRESS(&(strinfo->initial_speaker),actrace_direction?&pstn_add:&(pinfo->src));
+ strinfo->first_frame_num=pinfo->fd->num;
+ strinfo->selected=FALSE;
+ strinfo->start_sec=pinfo->fd->rel_ts.secs;
+ strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
+ strinfo->protocol=VOIP_AC_ISDN;
+ strinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t));
+ tmp_actrace_isdn_info=strinfo->prot_info;
+ tmp_actrace_isdn_info->crv=q931_crv;
+ tmp_actrace_isdn_info->trunk=actrace_trunk;
+ strinfo->npackets = 0;
+ strinfo->call_num = tapinfo->ncalls++;
+ tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+ }
- have_mtp3_tap_listener=FALSE;
-}
+ strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+ strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
+ strinfo->last_frame_num=pinfo->fd->num;
+ ++(strinfo->npackets);
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
-/****************************************************************************/
-/* ***************************TAP for Q931 **********************************/
-/****************************************************************************/
+ switch(pi->message_type){
+ case Q931_SETUP:
+ comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s Called:%s", actrace_trunk, q931_calling_number, q931_called_number);
+ strinfo->call_state=VOIP_CALL_SETUP;
+ break;
+ case Q931_CONNECT:
+ strinfo->call_state=VOIP_IN_CALL;
+ break;
+ case Q931_RELEASE_COMPLETE:
+ case Q931_RELEASE:
+ case Q931_DISCONNECT:
+ if (strinfo->call_state==VOIP_CALL_SETUP){
+ if (ADDRESSES_EQUAL(&(strinfo->initial_speaker), actrace_direction?&pstn_add:&(pinfo->src) )){ /* forward direction */
+ strinfo->call_state=VOIP_CANCELLED;
+ }
+ else{ /* reverse */
+ strinfo->call_state=VOIP_REJECTED;
+ tapinfo->rejected_calls++;
+ }
+ } else if ( (strinfo->call_state!=VOIP_CANCELLED) && (strinfo->call_state!=VOIP_REJECTED) ){
+ strinfo->call_state=VOIP_COMPLETED;
+ tapinfo->completed_calls++;
+ }
+ if (q931_cause_value != 0xFF){
+ comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", actrace_trunk, q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
+ } else { /* Cause not set */
+ comment = g_strdup("AC_ISDN No Q931 Rel Cause");
+ }
+ break;
+ }
-static gchar *q931_calling_number;
-static gchar *q931_called_number;
-static guint8 q931_cause_value;
-static gint32 q931_crv;
-static guint32 q931_frame_num;
+ if (!comment)
+ comment = g_strdup_printf("AC_ISDN trunk:%u", actrace_trunk );
-/****************************************************************************/
-/* whenever a q931_ packet is seen by the tap listener */
-static int
-q931_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *q931_info _U_)
-{
- /*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; */
- const q931_packet_info *pi = q931_info;
+ add_to_graph(tapinfo, pinfo, val_to_str(pi->message_type, q931_message_type_vals, "<unknown>") , comment, strinfo->call_num,
+ actrace_direction?&pstn_add:&(pinfo->src),
+ actrace_direction?&(pinfo->src):&pstn_add);
- /* free previously allocated q931_calling/ed_number */
- g_free(q931_calling_number);
- g_free(q931_called_number);
-
- if (pi->calling_number!=NULL)
- q931_calling_number = g_strdup(pi->calling_number);
- else
- q931_calling_number = g_strdup("");
+ g_free(comment);
+ g_free((char *)pstn_add.data);
+ }
- if (pi->called_number!=NULL)
- q931_called_number = g_strdup(pi->called_number);
- else
- q931_called_number = g_strdup("");
- q931_cause_value = pi->cause_value;
- q931_frame_num = pinfo->fd->num;
- q931_crv = pi->crv;
+ tapinfo->redraw = TRUE;
- return 0;
+ return 1; /* refresh output */
}
/****************************************************************************/
/****************************TAP for H323 ***********************************/
/****************************************************************************/
-#define GUID_LEN 16
-static const guint8 guid_allzero[GUID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-/* defines specific H323 data */
-
-
-void add_h245_Address(h323_calls_info_t *h323info, h245_address_t *h245_address)
+static void add_h245_Address(h323_calls_info_t *h323info, h245_address_t *h245_address)
{
h323info->h245_list = g_list_append(h323info->h245_list, h245_address);
}
voip_calls_info_t *tmp_listinfo;
voip_calls_info_t *strinfo = NULL;
h323_calls_info_t *tmp_h323info = NULL;
- h323_calls_info_t *tmp2_h323info;
gchar *frame_label;
gchar *comment;
- GList *list, *list2;
+ GList *list;
address tmp_src, tmp_dst;
h245_address_t *h245_add = NULL;
- guint foo;
const h225_packet_info *pi = H225info;
/* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */
- if ((memcmp(pi->guid, guid_allzero, GUID_LEN) == 0) && (pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20)))
- return 0;
+ /* OR, if not guid and is H225 return because doesn't belong to a call */
+ if ((memcmp(pi->guid, guid_allzero, GUID_LEN) == 0))
+ if ( ((pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20))) || (pi->msg_type != H225_RAS) )
+ return 0;
-
- if ( (memcmp(pi->guid, guid_allzero, GUID_LEN) == 0) && (q931_frame_num == pinfo->fd->num) ){
- /* check wether we already have a call with this Q931 CRV */
- list = g_list_first(tapinfo->strinfo_list);
- while (list)
- {
- tmp_listinfo=list->data;
- if (tmp_listinfo->protocol == VOIP_H323){
- tmp_h323info = tmp_listinfo->prot_info;
- if ( ((tmp_h323info->q931_crv == q931_crv) || (tmp_h323info->q931_crv2 == q931_crv)) && (q931_crv!=-1)){
- strinfo = (voip_calls_info_t*)(list->data);
- break;
- }
- }
- list = g_list_next (list);
- }
- if (strinfo==NULL) return 0;
- } else if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) { /* RAS LCF or LRJ*/
+ /* if it is RAS LCF or LRJ*/
+ if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) {
/* if the LCF/LRJ doesn't match to a LRQ, just return */
if (!pi->request_available) return 0;
}
}
+ h225_cstype = pi->cs_type;
+ h225_is_faststart = pi->is_faststart;
+
/* not in the list? then create a new entry */
if ((strinfo==NULL)){
strinfo = g_malloc(sizeof(voip_calls_info_t));
COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
strinfo->selected=FALSE;
strinfo->first_frame_num=pinfo->fd->num;
- strinfo->start_sec=pinfo->fd->rel_secs;
- strinfo->start_usec=pinfo->fd->rel_usecs;
+ strinfo->start_sec=pinfo->fd->rel_ts.secs;
+ strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
strinfo->protocol=VOIP_H323;
strinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
tmp_h323info = strinfo->prot_info;
if (strinfo!=NULL){
+ h225_frame_num = pinfo->fd->num;
+ h225_call_num = strinfo->call_num;
+
/* let's analyze the call state */
COPY_ADDRESS(&(tmp_src),&(pinfo->src));
COPY_ADDRESS(&(tmp_dst),&(pinfo->dst));
- strinfo->stop_sec=pinfo->fd->rel_secs;
- strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+ strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
strinfo->last_frame_num=pinfo->fd->num;
++(strinfo->npackets);
/* increment the packets counter of all calls */
/* change the status */
if (pi->msg_type == H225_CS){
- if (tmp_h323info->q931_crv == -1) {
- tmp_h323info->q931_crv = q931_crv;
- } else if (tmp_h323info->q931_crv != q931_crv) {
- tmp_h323info->q931_crv2 = q931_crv;
- }
/* this is still IPv4 only, because the dissector is */
if (pi->is_h245 == TRUE){
switch(pi->cs_type){
case H225_SETUP:
tmp_h323info->is_faststart_Setup = pi->is_faststart;
- /* set te calling and called number from the Q931 packet */
- if (q931_frame_num == pinfo->fd->num){
- if (q931_calling_number != NULL){
- g_free(strinfo->from_identity);
- strinfo->from_identity=g_strdup(q931_calling_number);
- }
- if (q931_called_number != NULL){
- g_free(strinfo->to_identity);
- strinfo->to_identity=g_strdup(q931_called_number);
- }
- }
- /* check if there is an LRQ/LCF that match this Setup */
- /* TODO: we are just checking the DialedNumer in LRQ/LCF agains the Setup
- we should also check if the h225 signaling IP and port match the destination
- Setup ip and port */
- list = g_list_first(tapinfo->strinfo_list);
- foo= g_list_length(list);
- while (list)
- {
- tmp_listinfo=list->data;
- if (tmp_listinfo->protocol == VOIP_H323){
- tmp2_h323info = tmp_listinfo->prot_info;
-
- /* check if there called number match a LRQ/LCF */
- if ( (strcmp(strinfo->to_identity, tmp_listinfo->to_identity)==0)
- && (memcmp(tmp2_h323info->guid, guid_allzero, GUID_LEN) == 0) ){
- /* change the call graph to the LRQ/LCF to belong to this call */
- strinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, strinfo->call_num);
-
- /* remove this LRQ/LCF call entry because we have found the Setup that match them */
- g_free(tmp_listinfo->from_identity);
- g_free(tmp_listinfo->to_identity);
- g_free(tmp2_h323info->guid);
-
- list2 = g_list_first(tmp2_h323info->h245_list);
- while (list2)
- {
- h245_add=list2->data;
- g_free((void *)h245_add->h245_address.data);
- g_free(list2->data);
- list2 = g_list_next(list2);
- }
- g_list_free(tmp_h323info->h245_list);
- tmp_h323info->h245_list = NULL;
- g_free(tmp_listinfo->prot_info);
- tapinfo->strinfo_list = g_list_remove(tapinfo->strinfo_list, tmp_listinfo);
- break;
- }
- }
- list = g_list_next (list);
- }
- foo = g_list_length(list);
+
/* Set the Setup address if it was not set */
if (tmp_h323info->h225SetupAddr.type == AT_NONE)
COPY_ADDRESS(&(tmp_h323info->h225SetupAddr), &(pinfo->src));
strinfo->call_state=VOIP_CALL_SETUP;
- comment = g_strdup_printf("H225 From: %s To:%s TunnH245:%s FS:%s", strinfo->from_identity, strinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
+ comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
(pi->is_faststart==TRUE?"on":"off"));
break;
case H225_CONNECT:
strinfo->call_state=VOIP_COMPLETED;
tapinfo->completed_calls++;
}
- /* get the Q931 Release cause code */
- if (q931_frame_num == pinfo->fd->num &&
- q931_cause_value != 0xFF){
- comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
- } else { /* Cause not set */
- comment = g_strdup("H225 No Q931 Rel Cause");
- }
+ comment = g_strdup("H225 No Q931 Rel Cause");
break;
case H225_PROGRESS:
case H225_ALERTING:
comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
(pi->is_faststart==TRUE?"on":"off"));
- } /* switch pi->cs_type*/
- } /* if pi->msg_type == H225_CS */
+ }
+ }
else if (pi->msg_type == H225_RAS){
switch(pi->msg_tag){
case 18: /* LRQ */
/* if the frame number exists in graph, append to it*/
if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, comment)) {
/* if not exist, add to the graph */
- add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));
g_free((void *)tmp_src.data);
g_free((void *)tmp_dst.data);
}
+ /* Add the H245 info if exists to the Graph */
+ h245_add_to_graph(pinfo->fd->num);
+
g_free(frame_label);
g_free(comment);
- } /* if strinfo!=NULL */
+ }
+ tapinfo->redraw = TRUE;
+
return 1; /* refresh output */
}
have_H225_tap_listener=FALSE;
}
+/* Add the h245 label info to the graph */
+void h245_add_to_graph(guint32 new_frame_num)
+{
+ gint8 n;
+
+ if (new_frame_num != h245_labels.frame_num) return;
+
+ for (n=0; n<h245_labels.labels_count; n++) {
+ append_to_frame_graph(&the_tapinfo_struct, new_frame_num, h245_labels.labels[n].frame_label, h245_labels.labels[n].comment);
+ g_free(h245_labels.labels[n].frame_label);
+ h245_labels.labels[n].frame_label = NULL;
+ g_free(h245_labels.labels[n].comment);
+ h245_labels.labels[n].comment = NULL;
+ }
+ h245_labels.frame_num = 0;
+ h245_labels.labels_count = 0;
+}
+
+/* free the h245_labels if the frame number is different */
+static void h245_free_labels(guint32 new_frame_num)
+{
+ gint8 n;
+
+ if (new_frame_num == h245_labels.frame_num) return;
+
+ for (n=0; n<h245_labels.labels_count; n++) {
+ g_free(h245_labels.labels[n].frame_label);
+ h245_labels.labels[n].frame_label = NULL;
+ g_free(h245_labels.labels[n].comment);
+ h245_labels.labels[n].comment = NULL;
+ }
+ h245_labels.frame_num = 0;
+ h245_labels.labels_count = 0;
+}
+
+/* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */
+static void h245_add_label(guint32 new_frame_num, gchar *frame_label, gchar *comment)
+{
+ h245_free_labels(new_frame_num);
+
+ h245_labels.frame_num = new_frame_num;
+ h245_labels.labels[h245_labels.labels_count].frame_label = g_strdup(frame_label);
+ h245_labels.labels[h245_labels.labels_count].comment = g_strdup(comment);
+
+ if (h245_labels.labels_count < (H245_MAX-1))
+ h245_labels.labels_count++;
+
+}
/****************************************************************************/
/* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
const h245_packet_info *pi = H245info;
- /* if H245 tunneling is on, append to graph */
- if (append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, pi->comment)) return 1;
-
-
- /* it is not Tunneling or it is not in the list. So check if there is no tunneling
- and there is a call with this H245 address */
+ /* check if Tunneling is OFF and we have a call with this H245 add */
list = g_list_first(tapinfo->strinfo_list);
while (list)
{
list = g_list_next(list);
}
+ /* Tunnel is OFF, and we matched the h245 add so we add it to graph */
if (strinfo!=NULL){
+ ++(strinfo->npackets);
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
frame_label = g_strdup(pi->frame_label);
comment = g_strdup(pi->comment);
- add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+ /* if the frame number exists in graph, append to it*/
+ if (!append_to_frame_graph(tapinfo, pinfo->fd->num, frame_label, comment)) {
+ /* if not exist, add to the graph */
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));
+ }
g_free(frame_label);
g_free(comment);
+ } else {
+ /* Tunnel is ON, so we save the label info to use it into h225 or q931 tap. OR may be
+ 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(pinfo->fd->num, (gchar *) pi->frame_label, (gchar *) pi->comment);
}
+ tapinfo->redraw = TRUE;
+
return 1; /* refresh output */
}
have_H245dg_tap_listener=FALSE;
}
-static gchar *sdp_summary = NULL;
-static guint32 sdp_frame_num = 0;
-
/****************************************************************************/
/****************************TAP for SDP PROTOCOL ***************************/
/****************************************************************************/
voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
const sdp_packet_info *pi = SDPinfo;
- /* There are protocols like MGCP where the SDP is called before the tap for the
- MGCP packet, in those cases we assign the SPD summary to global lastSDPsummary
+ /* There are protocols like MGCP/SIP where the SDP is called before the tap for the
+ MGCP/SIP packet, in those cases we assign the SPD summary to global lastSDPsummary
to use it later
*/
g_free(sdp_summary);
sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
+ tapinfo->redraw = TRUE;
+
return 1; /* refresh output */
}
This function will look for a signal/event in the SignalReq/ObsEvent string
and return true if it is found
*/
-gboolean isSignal(gchar *signal, gchar *signalStr)
+static gboolean isSignal(const gchar *signal, const gchar *signalStr)
{
gint i;
gchar **resultArray;
This function will get the Caller ID info and replace the current string
This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
*/
-void mgcpCallerID(gchar *signalStr, gchar **callerId)
+static void mgcpCallerID(gchar *signalStr, gchar **callerId)
{
gchar **arrayStr;
This function will get the Dialed Digits and replace the current string
This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
*/
-void mgcpDialedDigits(gchar *signalStr, gchar **dialedDigits)
+static void mgcpDialedDigits(gchar *signalStr, gchar **dialedDigits)
{
gchar *tmpStr;
gchar resultStr[50];
check first if it is an ended call. We consider an ended call after 1sec we don't
get a packet in this Endpoint and the call has been released
*/
- diff_time = (pinfo->fd->rel_secs + (double)pinfo->fd->rel_secs/1000000) - (tmp_listinfo->stop_sec + (double)tmp_listinfo->stop_usec/1000000);
+ diff_time = nstime_to_sec(&pinfo->fd->rel_ts) - tmp_listinfo->stop_sec + (double)tmp_listinfo->stop_usec/1000000;
if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) || (tmp_listinfo->call_state == VOIP_COMPLETED) || (tmp_listinfo->call_state == VOIP_REJECTED)) && (diff_time > 1) ){
tmp_listinfo->call_active_state = VOIP_INACTIVE;
} else {
COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
strinfo->first_frame_num=pinfo->fd->num;
strinfo->selected=FALSE;
- strinfo->start_sec=pinfo->fd->rel_secs;
- strinfo->start_usec=pinfo->fd->rel_usecs;
+ strinfo->start_sec=pinfo->fd->rel_ts.secs;
+ strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
strinfo->protocol=VOIP_MGCP;
strinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
tmp_mgcpinfo=strinfo->prot_info;
comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
- strinfo->stop_sec=pinfo->fd->rel_secs;
- strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+ strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
strinfo->last_frame_num=pinfo->fd->num;
++(strinfo->npackets);
/* increment the packets counter of all calls */
++(tapinfo->npackets);
/* add to the graph */
- add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst));
g_free(comment);
g_free(frame_label);
sdp_summary = NULL;
}
+ tapinfo->redraw = TRUE;
+
return 1; /* refresh output */
}
}
+/****************************************************************************/
+/****************************TAP for ACTRACE (AudioCodes trace)**************/
+/****************************************************************************/
+
+/* whenever a ACTRACE packet is seen by the tap listener */
+static int
+ACTRACEcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *ACTRACEinfo)
+{
+ voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
+ const actrace_info_t *pi = ACTRACEinfo;
+ GList *list;
+ actrace_cas_calls_info_t *tmp_actrace_cas_info;
+ voip_calls_info_t *tmp_listinfo;
+ voip_calls_info_t *strinfo = NULL;
+
+
+ actrace_frame_num = pinfo->fd->num;
+ actrace_trunk = pi->trunk;
+ actrace_direction = pi->direction;
+
+ if (pi->type == 1){ /* is CAS protocol */
+ address pstn_add;
+ gchar *comment = NULL;
+
+ strinfo = NULL;
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if ( tmp_listinfo->protocol == VOIP_AC_CAS ){
+ tmp_actrace_cas_info = tmp_listinfo->prot_info;
+ /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
+ if ( (tmp_actrace_cas_info->bchannel == pi->cas_bchannel) && (tmp_actrace_cas_info->trunk == actrace_trunk) ) {
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+ list = g_list_next (list);
+ }
+
+ SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
+
+ /* if it is a new call, add it to the list */
+ if (!strinfo) {
+ strinfo = g_malloc(sizeof(voip_calls_info_t));
+ strinfo->call_active_state = VOIP_ACTIVE;
+ strinfo->call_state = VOIP_CALL_SETUP;
+ strinfo->from_identity=g_strdup("N/A");
+ strinfo->to_identity=g_strdup("N/A");
+ COPY_ADDRESS(&(strinfo->initial_speaker),actrace_direction?&pstn_add:&(pinfo->src));
+ strinfo->first_frame_num=pinfo->fd->num;
+ strinfo->selected=FALSE;
+ strinfo->start_sec=pinfo->fd->rel_ts.secs;
+ strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
+ strinfo->protocol=VOIP_AC_CAS;
+ strinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t));
+ tmp_actrace_cas_info=strinfo->prot_info;
+ tmp_actrace_cas_info->bchannel=pi->cas_bchannel;
+ tmp_actrace_cas_info->trunk=actrace_trunk;
+ strinfo->npackets = 0;
+ strinfo->call_num = tapinfo->ncalls++;
+ tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+ }
+
+ strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+ strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
+ strinfo->last_frame_num=pinfo->fd->num;
+ ++(strinfo->npackets);
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
+
+ if (!comment)
+ comment = g_strdup_printf("AC_CAS trunk:%u", actrace_trunk );
+
+ add_to_graph(tapinfo, pinfo, pi->cas_frame_label , comment, strinfo->call_num,
+ actrace_direction?&pstn_add:&(pinfo->src),
+ actrace_direction?&(pinfo->src):&pstn_add);
+
+ g_free(comment);
+ g_free((char *)pstn_add.data);
+ }
+
+ tapinfo->redraw = TRUE;
+
+ return 1; /* refresh output */
+}
+
+
+/****************************************************************************/
+/* TAP INTERFACE */
+/****************************************************************************/
+static gboolean have_actrace_tap_listener=FALSE;
+/****************************************************************************/
+void
+actrace_calls_init_tap(void)
+{
+ GString *error_string;
+
+ if(have_actrace_tap_listener==FALSE)
+ {
+ /* don't register tap listener, if we have it already */
+ error_string = register_tap_listener("actrace", &(the_tapinfo_struct.actrace_dummy), NULL,
+ voip_calls_dlg_reset,
+ ACTRACEcalls_packet,
+ voip_calls_dlg_draw
+ );
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_actrace_tap_listener=TRUE;
+ }
+}
+
+
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+void
+remove_tap_listener_actrace_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&(the_tapinfo_struct.actrace_dummy));
+ unprotect_thread_critical_region();
+
+ have_actrace_tap_listener=FALSE;
+}
/****************************************************************************/
/* ***************************TAP for OTHER PROTOCOL **********************************/
++(tapinfo->npackets);
}
+ tapinfo->redraw = TRUE;
+
return 1;
}
*/
have_prot__tap_listener=FALSE;
}
*/
-