aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gtk/voip_calls.c200
-rw-r--r--gtk/voip_calls.h9
-rw-r--r--gtk/voip_calls_dlg.c3
3 files changed, 185 insertions, 27 deletions
diff --git a/gtk/voip_calls.c b/gtk/voip_calls.c
index 66022ae02e..31765c1542 100644
--- a/gtk/voip_calls.c
+++ b/gtk/voip_calls.c
@@ -60,6 +60,7 @@
#include <epan/dissectors/packet-rtp-events.h>
#include <epan/dissectors/packet-t38.h>
#include <epan/dissectors/packet-h248.h>
+#include <epan/dissectors/packet-sccp.h>
#include <epan/conversation.h>
#include <epan/rtp_pt.h>
#include <epan/ws_strsplit.h>
@@ -73,7 +74,8 @@
#endif /* GTK_MAJOR_VERSION >= 2 */
#endif /* HAVE_LIBPORTAUDIO */
-const char *voip_call_state_name[7]={
+const char *voip_call_state_name[8]={
+ "",
"CALL SETUP",
"RINGING",
"IN CALL",
@@ -92,7 +94,10 @@ const char *voip_protocol_name[]={
"AC_ISDN",
"AC_CAS",
"T.38",
- "H.248"
+ "H.248",
+ "SCCP",
+ "BSSMAP",
+ "RANAP"
};
typedef struct {
@@ -113,7 +118,7 @@ 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, 0, 0, 0, 0};
+ {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 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 =
@@ -1065,11 +1070,10 @@ isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
/*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; unused */
const isup_tap_rec_t *pi = isup_info;
-
-
+
/* check if the lower layer is MTP matching the frame number */
if (mtp3_frame_num != pinfo->fd->num) return 0;
-
+
/* check whether we already have a call with these parameters in the list */
list = g_list_first(tapinfo->strinfo_list);
while (list)
@@ -1081,26 +1085,24 @@ isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
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 == mtp3_opc)&&(tmp_isupinfo->opc == mtp3_dpc)){
+ } else if ((tmp_isupinfo->dpc == mtp3_opc)&&(tmp_isupinfo->opc == mtp3_dpc)){
forward = FALSE;
- }
- else{
- right_pair = FALSE;
- }
+ } else{
+ right_pair = FALSE;
+ }
+
if (right_pair){
/* if there is an IAM for a call that is not in setup state, that means the previous call in the same
cic is no longer active */
if (tmp_listinfo->call_state == VOIP_CALL_SETUP){
found = TRUE;
- }
- else if (pi->message_type != 1){
+ } else if (pi->message_type != 1){
found = TRUE;
- }
- else{
+ } else{
tmp_listinfo->call_active_state=VOIP_INACTIVE;
}
}
+
if (found){
strinfo = (voip_calls_info_t*)(list->data);
break;
@@ -1115,7 +1117,6 @@ isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
if ((strinfo==NULL) &&(pi->message_type==1)){
-
strinfo = g_malloc(sizeof(voip_calls_info_t));
strinfo->call_active_state = VOIP_ACTIVE;
strinfo->call_state = VOIP_UNKNOWN;
@@ -1143,6 +1144,7 @@ isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
}
+
if (strinfo!=NULL){
strinfo->stop_sec=pinfo->fd->rel_ts.secs;
strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
@@ -1162,26 +1164,24 @@ isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, co
}
if (strinfo->npackets == 1){ /* this is the first packet, that must be an IAM */
+
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 */
+ } 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",
mtp3_ni, mtp3_opc,
mtp3_ni, mtp3_dpc, pinfo->circuit_id);
-
- }
- else{
+ } else {
comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
mtp3_ni, mtp3_dpc,
mtp3_ni, mtp3_opc, pinfo->circuit_id);
-
}
}
+
switch(pi->message_type){
case 1: /* IAM */
strinfo->call_state=VOIP_CALL_SETUP;
@@ -2773,7 +2773,7 @@ static int h248_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *
if (strinfo==NULL){
strinfo = g_malloc(sizeof(voip_calls_info_t));
- strinfo->call_state = VOIP_UNKNOWN;
+ strinfo->call_state = VOIP_NO_STATE;
strinfo->call_active_state = VOIP_ACTIVE;
strinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, cmd->ctx->id);
strinfo->to_identity = g_strdup("");
@@ -2821,12 +2821,13 @@ static int h248_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *
strinfo->stop_usec=pinfo->fd->rel_ts.nsecs;
strinfo->last_frame_num=pinfo->fd->num;
++(strinfo->npackets);
- ++(tapinfo->npackets);
}
add_to_graph(tapinfo, pinfo, cmd->str,
- ep_strdup_printf("TrxId = %d, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
+ ep_strdup_printf("TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
strinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
+
+ ++(tapinfo->npackets);
tapinfo->redraw = TRUE;
@@ -2866,6 +2867,153 @@ remove_tap_listener_h248_calls(void)
have_h248_tap_listener=FALSE;
}
+/**************************** TAP for SCCP **********************************/
+static gboolean have_sccp_tap_listener = FALSE;
+
+static const voip_protocol sccp_proto_map[] = {
+ TEL_SCCP,
+ TEL_BSSMAP,
+ TEL_RANAP
+};
+#define SP2VP(ap) ((ap) < SCCP_PLOAD_NUM_PLOADS ? sccp_proto_map[(ap)] : TEL_SCCP)
+
+static int sccp_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info) {
+ voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
+ const sccp_msg_info_t* msg = prot_info;
+ sccp_assoc_info_t* assoc = msg->assoc;
+ GList* list;
+ voip_calls_info_t *strinfo = NULL;
+ const gchar* label = NULL;
+ const gchar* comment = NULL;
+ /* check whether we already have this assoc in the list */
+
+ for(list = g_list_first(tapinfo->strinfo_list) ; list ; list = g_list_next (list) ) {
+ if ( ((voip_calls_info_t*)(list->data))->prot_info == assoc ){
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+
+ if (strinfo==NULL){
+ strinfo = g_malloc(sizeof(voip_calls_info_t));
+ strinfo->call_state = VOIP_CALL_SETUP;
+ strinfo->call_active_state = VOIP_ACTIVE;
+ if ( assoc->calling_party ) {
+ strinfo->from_identity = g_strdup(assoc->calling_party);
+ } else {
+ strinfo->from_identity = g_strdup("Unknown");
+ }
+
+ if ( assoc->called_party ) {
+ strinfo->to_identity = g_strdup(assoc->called_party);
+ } else {
+ strinfo->to_identity = g_strdup("Unknown");
+ }
+
+ strinfo->prot_info = (void*)assoc;
+ strinfo->free_prot_info = NULL;
+
+ strinfo->npackets = 1;
+ strinfo->first_frame_num=pinfo->fd->num;
+ strinfo->last_frame_num=pinfo->fd->num;
+
+ COPY_ADDRESS(&(strinfo->initial_speaker), &(pinfo->src));
+
+ strinfo->protocol = SP2VP(assoc->proto);
+ strinfo->start_sec=pinfo->fd->rel_ts.secs;
+ strinfo->start_usec=pinfo->fd->rel_ts.nsecs;
+ strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+ strinfo->stop_usec=pinfo->fd->rel_ts.nsecs;
+
+ strinfo->selected = FALSE;
+ strinfo->call_num = tapinfo->ncalls++;
+
+ tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+ } else {
+
+ if ( assoc->calling_party ) {
+ if (strinfo->from_identity) g_free(strinfo->from_identity );
+ strinfo->from_identity = g_strdup(assoc->calling_party);
+ }
+
+ if ( assoc->called_party ) {
+ if (strinfo->to_identity) g_free(strinfo->to_identity );
+ strinfo->to_identity = g_strdup(assoc->called_party);
+ }
+
+ strinfo->protocol = SP2VP(assoc->proto);
+ strinfo->stop_sec=pinfo->fd->rel_ts.secs;
+ strinfo->stop_usec=pinfo->fd->rel_ts.nsecs;
+ strinfo->last_frame_num=pinfo->fd->num;
+ ++(strinfo->npackets);
+
+ switch (msg->type) {
+ case SCCP_MSG_TYPE_CC:
+ strinfo->call_state = VOIP_IN_CALL;
+ break;
+ case SCCP_MSG_TYPE_RLC:
+ strinfo->call_state = VOIP_COMPLETED;
+ strinfo->call_active_state = VOIP_INACTIVE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (msg->label) {
+ label = msg->label;
+ } else {
+ label = val_to_str(msg->type, sccp_message_type_acro_values, "Unknown(%d)");
+ }
+
+ if (msg->comment) {
+ comment = msg->comment;
+ } else {
+ comment = "";
+ }
+
+ add_to_graph(tapinfo, pinfo, label,(void*) comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
+
+ ++(tapinfo->npackets);
+
+ tapinfo->redraw = TRUE;
+
+ return 1;
+}
+
+void sccp_calls_init_tap(void)
+{
+ GString *error_string;
+
+ if(have_sccp_tap_listener==FALSE)
+ {
+ error_string = register_tap_listener("sccp", &(the_tapinfo_struct.sccp_dummy),
+ NULL,
+ voip_calls_dlg_reset,
+ sccp_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_sccp_tap_listener=TRUE;
+ }
+}
+
+void
+remove_tap_listener_sccp_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&(the_tapinfo_struct.sccp_dummy));
+ unprotect_thread_critical_region();
+
+ have_sccp_tap_listener=FALSE;
+}
+
/****************************************************************************/
/* ***************************TAP for OTHER PROTOCOL **********************************/
diff --git a/gtk/voip_calls.h b/gtk/voip_calls.h
index 6e2724b226..02bf1464d5 100644
--- a/gtk/voip_calls.h
+++ b/gtk/voip_calls.h
@@ -44,6 +44,7 @@
/****************************************************************************/
/* defines voip call state */
typedef enum _voip_call_state {
+ VOIP_NO_STATE,
VOIP_CALL_SETUP,
VOIP_RINGING,
VOIP_IN_CALL,
@@ -53,7 +54,7 @@ typedef enum _voip_call_state {
VOIP_UNKNOWN
} voip_call_state;
-extern const char *voip_call_state_name[7];
+extern const char *voip_call_state_name[8];
typedef enum _voip_call_active_state {
VOIP_ACTIVE,
@@ -69,6 +70,9 @@ typedef enum _voip_protocol {
VOIP_AC_CAS,
MEDIA_T38,
TEL_H248,
+ TEL_SCCP,
+ TEL_BSSMAP,
+ TEL_RANAP
} voip_protocol;
extern const char *voip_protocol_name[];
@@ -181,6 +185,7 @@ typedef struct _voip_calls_tapinfo {
int actrace_dummy;
int t38_dummy;
int h248_dummy;
+ int sccp_dummy;
} voip_calls_tapinfo_t;
@@ -238,6 +243,7 @@ void mgcp_calls_init_tap(void);
void actrace_calls_init_tap(void);
void t38_init_tap(void);
void h248_calls_init_tap(void);
+void sccp_calls_init_tap(void);
/*
* Removes the voip_calls tap listener (if not already done)
@@ -256,6 +262,7 @@ void remove_tap_listener_mgcp_calls(void);
void remove_tap_listener_actrace_calls(void);
void remove_tap_listener_t38(void);
void remove_tap_listener_h248_calls(void);
+void remove_tap_listener_sccp_calls(void);
/*
* Retrieves a constant reference to the unique info structure of the voip_calls tap listener.
diff --git a/gtk/voip_calls_dlg.c b/gtk/voip_calls_dlg.c
index 40ba204616..531d17efbf 100644
--- a/gtk/voip_calls_dlg.c
+++ b/gtk/voip_calls_dlg.c
@@ -209,6 +209,7 @@ static void voip_calls_remove_tap_listener(void)
remove_tap_listener_h245dg_calls();
remove_tap_listener_q931_calls();
remove_tap_listener_h248_calls();
+ remove_tap_listener_sccp_calls();
remove_tap_listener_sdp_calls();
remove_tap_listener_rtp();
remove_tap_listener_rtp_event();
@@ -363,6 +364,7 @@ voip_calls_on_filter (GtkButton *button _U_,
gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), ep_strdup_printf("h248.ctx == 0x%x", ctx->id ));
break;
}
+ case TEL_SCCP:
case VOIP_MGCP:
case VOIP_AC_ISDN:
case VOIP_AC_CAS:
@@ -829,6 +831,7 @@ voip_calls_init_tap(const char *dummy _U_, void* userdata _U_)
h245dg_calls_init_tap();
q931_calls_init_tap();
h248_calls_init_tap();
+ sccp_calls_init_tap();
sdp_calls_init_tap();
rtp_init_tap();
rtp_event_init_tap();