diff options
Diffstat (limited to 'ui/gtk')
-rw-r--r-- | ui/gtk/CMakeLists.txt | 1 | ||||
-rw-r--r-- | ui/gtk/Makefile.common | 2 | ||||
-rw-r--r-- | ui/gtk/rtp_analysis.c | 2 | ||||
-rw-r--r-- | ui/gtk/rtp_player.c | 2 | ||||
-rw-r--r-- | ui/gtk/voip_calls.c | 4080 | ||||
-rw-r--r-- | ui/gtk/voip_calls.h | 253 | ||||
-rw-r--r-- | ui/gtk/voip_calls_dlg.c | 42 | ||||
-rw-r--r-- | ui/gtk/voip_calls_dlg.h | 4 |
8 files changed, 35 insertions, 4351 deletions
diff --git a/ui/gtk/CMakeLists.txt b/ui/gtk/CMakeLists.txt index 553f3fb36a..3d008d3837 100644 --- a/ui/gtk/CMakeLists.txt +++ b/ui/gtk/CMakeLists.txt @@ -112,7 +112,6 @@ set(WIRESHARK_GTK_SRC text_page_utils.c time_shift_dlg.c uat_gui.c - voip_calls.c webbrowser.c ${WIRESHARK_CUSTOM_GTK_SRC} ) diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common index 5238d7d27e..5b58c68878 100644 --- a/ui/gtk/Makefile.common +++ b/ui/gtk/Makefile.common @@ -133,7 +133,6 @@ WIRESHARK_GTK_SRC = \ text_page_utils.c \ time_shift_dlg.c \ uat_gui.c \ - voip_calls.c \ webbrowser.c \ extcap_gtk.c \ $(WIRESHARK_CUSTOM_GTK_SRC) @@ -313,7 +312,6 @@ noinst_HEADERS = \ text_page_utils.h \ toolbar_icons.h \ uat_gui.h \ - voip_calls.h \ voip_calls_dlg.h \ webbrowser.h \ wsiconcap.h \ diff --git a/ui/gtk/rtp_analysis.c b/ui/gtk/rtp_analysis.c index ac2673879b..2210121bda 100644 --- a/ui/gtk/rtp_analysis.c +++ b/ui/gtk/rtp_analysis.c @@ -86,8 +86,8 @@ #include "ui/gtk/stock_icons.h" #ifdef HAVE_LIBPORTAUDIO +#include "ui/voip_calls.h" #include "ui/gtk/graph_analysis.h" -#include "ui/gtk/voip_calls.h" #include "ui/gtk/rtp_player.h" #endif /* HAVE_LIBPORTAUDIO */ diff --git a/ui/gtk/rtp_player.c b/ui/gtk/rtp_player.c index ad96bfeee8..13867a2b9e 100644 --- a/ui/gtk/rtp_player.c +++ b/ui/gtk/rtp_player.c @@ -68,12 +68,12 @@ #include "../globals.h" #include "ui/simple_dialog.h" +#include "ui/voip_calls.h" #include "ui/gtk/gui_utils.h" #include "ui/gtk/dlg_utils.h" #include "ui/gtk/graph_analysis.h" #include "ui/gtk/voip_calls_dlg.h" -#include "ui/gtk/voip_calls.h" #include "ui/gtk/gtkglobals.h" #include "ui/gtk/rtp_player.h" #include "ui/gtk/stock_icons.h" diff --git a/ui/gtk/voip_calls.c b/ui/gtk/voip_calls.c deleted file mode 100644 index 0cc89dd3e6..0000000000 --- a/ui/gtk/voip_calls.c +++ /dev/null @@ -1,4080 +0,0 @@ -/* voip_calls.c - * VoIP calls summary addition for Wireshark - * - * Copyright 2004, Ericsson, Spain - * By Francisco Alcoba <francisco.alcoba@ericsson.com> - * - * based on h323_calls.c - * Copyright 2004, Iskratel, Ltd, Kranj - * By Miha Jemec <m.jemec@iskratel.si> - * - * H323, RTP, RTP Event, MGCP, AudioCodes (ISDN PRI and CAS), T38 and Graph Support - * By Alejandro Vaquero, alejandro.vaquero@verso.com - * Copyright 2005, Verso Technologies Inc. - * - * Wireshark - Network traffic analyzer - * By Gerald Combs <gerald@wireshark.org> - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include <stdlib.h> -#include <string.h> - -#include <epan/epan.h> -#include <epan/epan_dissect.h> -#include <epan/packet.h> -#include <epan/tap.h> -#include <epan/tap-voip.h> -#include <epan/dissectors/packet-sip.h> -#include <epan/dissectors/packet-mtp3.h> -#include <epan/dissectors/packet-isup.h> -#include <epan/dissectors/packet-h225.h> -#include <epan/dissectors/packet-h245.h> -#include <epan/dissectors/packet-q931.h> -#include <epan/dissectors/packet-sdp.h> -#include <epan/dissectors/packet-mgcp.h> -#include <epan/dissectors/packet-actrace.h> -#include <epan/dissectors/packet-rtp.h> -#include <epan/dissectors/packet-rtp-events.h> -#include <epan/dissectors/packet-t38.h> -#include <epan/dissectors/packet-t30.h> -#include <epan/dissectors/packet-h248.h> -#include <epan/dissectors/packet-sccp.h> -#include <plugins/unistim/packet-unistim.h> -#include <epan/dissectors/packet-skinny.h> -#include <epan/dissectors/packet-iax2.h> -#include <epan/rtp_pt.h> - -#include "ui/alert_box.h" -#include "ui/simple_dialog.h" -#include "ui/tap-sequence-analysis.h" -#include "ui/ui_util.h" - -#include "ui/gtk/voip_calls.h" -#include "ui/gtk/voip_calls_dlg.h" - -#ifdef HAVE_LIBPORTAUDIO -#include "ui/gtk/rtp_player.h" -#endif /* HAVE_LIBPORTAUDIO */ - -#define DUMP_PTR1(p) printf("#=> %p\n",(void *)p) -#define DUMP_PTR2(p) printf("==> %p\n",(void *)p) - -const char *voip_call_state_name[8]={ - "", - "CALL SETUP", - "RINGING", - "IN CALL", - "CANCELLED", - "COMPLETED", - "REJECTED", - "UNKNOWN" -}; - -/* defines whether we can consider the call active */ -const char *voip_protocol_name[]={ - "SIP", - "ISUP", - "H.323", - "MGCP", - "AC_ISDN", - "AC_CAS", - "T.38", - "H.248", - "SCCP", - "BSSMAP", - "RANAP", - "UNISTIM", - "SKINNY", - "IAX2", - "VoIP" -}; - -/* - * Tap IDs must be unique. Since different taps need to share the - * same voip_calls_tapinfo_t *, make it unique by offsetting its - * value. - */ -enum { - tap_id_offset_actrace_, - tap_id_offset_h225_, - tap_id_offset_h245dg_, - tap_id_offset_h248_, - tap_id_offset_iax2_, - tap_id_offset_isup_, - tap_id_offset_m3ua_, - tap_id_offset_megaco_, - tap_id_offset_mgcp_, - tap_id_offset_mtp3_, - tap_id_offset_q931_, - tap_id_offset_rtp_, - tap_id_offset_rtp_event_, - tap_id_offset_sccp_, - tap_id_offset_sdp_, - tap_id_offset_sip_, - tap_id_offset_skinny_, - tap_id_offset_sua_, - tap_id_offset_t38_, - tap_id_offset_unistim_, - 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); -} - -static inline voip_calls_tapinfo_t * -tap_id_to_base(void* tap_id, int offset) { - return (voip_calls_tapinfo_t *) GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_id) - offset); -} - -typedef struct { - gchar *frame_label; - gchar *comment; -} graph_str; - -#define H245_MAX 6 - -typedef struct _h245_labels { - guint32 frame_num; - gint8 labels_count; - graph_str labels[H245_MAX]; -} h245_labels_t; - -/* defines a RTP stream */ -typedef struct _voip_rtp_stream_info { - address src_addr; - guint16 src_port; - address dest_addr; - guint16 dest_port; - guint32 ssrc; - guint32 pt; - gchar *pt_str; - gboolean is_srtp; - guint32 npackets; - gboolean end_stream; - - guint32 setup_frame_number; /* frame number of setup message */ - /* The frame_data struct holds the frame number and timing information needed. */ - frame_data *start_fd; - nstime_t start_rel_ts; - frame_data *stop_fd; - nstime_t stop_rel_ts; - gint32 rtp_event; -} voip_rtp_stream_info_t; - -static void actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void iax2_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void rtp_event_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void rtp_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void t38_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); -static void voip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base); - -void -voip_calls_init_all_taps(voip_calls_tapinfo_t *tap_id_base) -{ - actrace_calls_init_tap(tap_id_base); - h225_calls_init_tap(tap_id_base); - h245dg_calls_init_tap(tap_id_base); - h248_calls_init_tap(tap_id_base); - iax2_calls_init_tap(tap_id_base); - isup_calls_init_tap(tap_id_base); - mgcp_calls_init_tap(tap_id_base); - mtp3_calls_init_tap(tap_id_base); - q931_calls_init_tap(tap_id_base); - rtp_event_init_tap(tap_id_base); - rtp_init_tap(tap_id_base); - sccp_calls_init_tap(tap_id_base); - sdp_calls_init_tap(tap_id_base); - sip_calls_init_tap(tap_id_base); - skinny_calls_init_tap(tap_id_base); - t38_init_tap(tap_id_base); - /* We don't register this tap, if we don't have the unistim plugin loaded.*/ - if (find_tap_id("unistim")) { - unistim_calls_init_tap(tap_id_base); - } - if (find_tap_id("voip")) { - voip_calls_init_tap(tap_id_base); - } -} - -static void remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_iax2_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_rtp(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_rtp_event(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_sccp_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_skinny_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_unistim_calls(voip_calls_tapinfo_t *tap_id_base); -static void remove_tap_listener_voip_calls(voip_calls_tapinfo_t *tap_id_base); - -void voip_calls_remove_all_tap_listeners(voip_calls_tapinfo_t *tap_id_base) -{ - /* Remove the calls tap listener */ - remove_tap_listener_actrace_calls(tap_id_base); - remove_tap_listener_h225_calls(tap_id_base); - remove_tap_listener_h245dg_calls(tap_id_base); - remove_tap_listener_h248_calls(tap_id_base); - remove_tap_listener_iax2_calls(tap_id_base); - remove_tap_listener_isup_calls(tap_id_base); - remove_tap_listener_mgcp_calls(tap_id_base); - remove_tap_listener_mtp3_calls(tap_id_base); - remove_tap_listener_q931_calls(tap_id_base); - remove_tap_listener_rtp(tap_id_base); - remove_tap_listener_rtp_event(tap_id_base); - remove_tap_listener_sccp_calls(tap_id_base); - remove_tap_listener_sdp_calls(tap_id_base); - remove_tap_listener_sip_calls(tap_id_base); - remove_tap_listener_skinny_calls(tap_id_base); - remove_tap_listener_t38(tap_id_base); - if (find_tap_id("unistim")) { /* The plugin may be missing */ - remove_tap_listener_unistim_calls(tap_id_base); - } - if (find_tap_id("voip")) { - remove_tap_listener_voip_calls(tap_id_base); - } -} - -/****************************************************************************/ -/* when there is a [re]reading of packet's */ -void -voip_calls_reset(voip_calls_tapinfo_t *tapinfo) -{ - voip_calls_info_t *callsinfo; - voip_rtp_stream_info_t *strinfo; - seq_analysis_item_t *graph_item; - GList *list; - - /* free the data items first */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - callsinfo = (voip_calls_info_t *)list->data; - g_free(callsinfo->call_id); - g_free(callsinfo->from_identity); - g_free(callsinfo->to_identity); - g_free((void *)(callsinfo->initial_speaker.data)); - g_free(callsinfo->protocol_name); - g_free(callsinfo->call_comment); - - if (callsinfo->free_prot_info && callsinfo->prot_info) - callsinfo->free_prot_info(callsinfo->prot_info); - - g_free(list->data); - list = g_list_next(list); - } - g_queue_clear(tapinfo->callsinfos); - /* free the SIP_HASH */ - 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->ht) - g_hash_table_remove_all(tapinfo->graph_analysis->ht); - list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0); - while (list) - { - graph_item = (seq_analysis_item_t *)list->data; - g_free(graph_item->frame_label); - g_free(graph_item->comment); - g_free((void *)graph_item->src_addr.data); - g_free((void *)graph_item->dst_addr.data); - g_free(graph_item->time_str); - g_free(list->data); - list = g_list_next(list); - } - g_queue_clear(tapinfo->graph_analysis->items); - - /* free the strinfo data items first */ - list = g_list_first(tapinfo->rtp_stream_list); - while(list) - { - strinfo = (voip_rtp_stream_info_t *)list->data; - g_free(strinfo->pt_str); - list = g_list_next(list); - } - g_list_free(tapinfo->rtp_stream_list); - tapinfo->rtp_stream_list = NULL; - - if (!tapinfo->h245_labels) { - tapinfo->h245_labels = g_new0(h245_labels_t, 1); - } else { - memset(tapinfo->h245_labels, 0, sizeof(h245_labels_t)); - } - - memset(tapinfo, 0, sizeof(voip_calls_tapinfo_t)); - - return; -} - -/****************************************************************************/ -void graph_analysis_data_init(voip_calls_tapinfo_t *tapinfo) { - tapinfo->graph_analysis = (seq_analysis_info_t *)g_malloc(sizeof(seq_analysis_info_t)); - tapinfo->graph_analysis->nconv = 0; - tapinfo->graph_analysis->items = g_queue_new();; - tapinfo->graph_analysis->ht= g_hash_table_new(g_int_hash, g_int_equal); -} - -/****************************************************************************/ -/* Add a new item into the graph */ -static void -add_to_graph(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const gchar *frame_label, const gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style) -{ - seq_analysis_item_t *gai; - gchar time_str[COL_MAX_LEN]; - - gai = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t)); - gai->fd = pinfo->fd; - 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) - gai->frame_label = g_strdup(frame_label); - else - gai->frame_label = g_strdup(""); - - if (comment != NULL) - gai->comment = g_strdup(comment); - else - gai->comment = g_strdup(""); - gai->conv_num=call_num; - gai->line_style=line_style; - set_fd_time(edt->session, gai->fd, time_str); - gai->time_str = g_strdup(time_str); - gai->display=FALSE; - - if(tapinfo->graph_analysis){ - g_queue_push_tail(tapinfo->graph_analysis->items, gai); - g_hash_table_insert(tapinfo->graph_analysis->ht, &gai->fd->num, gai); - } - -} - -/****************************************************************************/ -/* 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) -{ - seq_analysis_item_t *gai=NULL; - gchar *frame_label = NULL; - gchar *comment = NULL; - - if(tapinfo->graph_analysis && NULL!=tapinfo->graph_analysis->ht) - gai=(seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num); - if(gai) { - frame_label = gai->frame_label; - comment = gai->comment; - - if (new_frame_label != NULL) { - gai->frame_label = g_strdup_printf("%s %s", frame_label, new_frame_label); - g_free(frame_label); - } - - if (new_comment != NULL) { - gai->comment = g_strdup_printf("%s %s", comment, new_comment); - g_free(comment); - } - } - - return gai? 1 : 0; -} - -/****************************************************************************/ -/* 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) -{ - seq_analysis_item_t *gai=NULL; - gchar *frame_label = NULL; - gchar *comment = NULL; - - if(tapinfo->graph_analysis && NULL!=tapinfo->graph_analysis->ht) - gai=(seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num); - if(gai) { - frame_label = gai->frame_label; - comment = gai->comment; - - if (new_frame_label != NULL) { - gai->frame_label = g_strdup(new_frame_label); - g_free(frame_label); - } - - if (new_comment != NULL) { - gai->comment = g_strdup(new_comment); - g_free(comment); - } - } - - return gai? 1 : 0; -} - -/****************************************************************************/ -/* 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) -{ - seq_analysis_item_t *gai; - GList *list; - guint items_changed; - - items_changed = 0; - if(tapinfo->graph_analysis){ - list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0); - while (list) - { - gai = (seq_analysis_item_t *)list->data; - if (gai->conv_num == call_num) { - gai->conv_num = new_call_num; - items_changed++; - } - list = g_list_next(list); - } - } - return items_changed; -} - -/****************************************************************************/ -/* Insert the item in the graph list */ -static void insert_to_graph_t38(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const gchar *frame_label, const gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style, guint32 frame_num) -{ - seq_analysis_item_t *gai, *new_gai; - GList *list; - guint item_num; - gboolean inserted; - gchar time_str[COL_MAX_LEN]; - - new_gai = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t)); - new_gai->fd = packet_list_get_row_data(frame_num); - COPY_ADDRESS(&(new_gai->src_addr),src_addr); - COPY_ADDRESS(&(new_gai->dst_addr),dst_addr); - - new_gai->port_src=pinfo->srcport; - new_gai->port_dst=pinfo->destport; - if (frame_label != NULL) - new_gai->frame_label = g_strdup(frame_label); - else - new_gai->frame_label = g_strdup(""); - - if (comment != NULL) - new_gai->comment = g_strdup(comment); - else - new_gai->comment = g_strdup(""); - new_gai->conv_num=call_num; - new_gai->line_style=line_style; - set_fd_time(edt->session, new_gai->fd, time_str); - new_gai->time_str = g_strdup(time_str); - new_gai->display=FALSE; - - item_num = 0; - inserted = FALSE; - if(tapinfo->graph_analysis){ - list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0); - while (list) - { - gai = (seq_analysis_item_t *)list->data; - if (gai->fd->num > frame_num) { - g_queue_insert_before(tapinfo->graph_analysis->items, list, new_gai); - g_hash_table_insert(tapinfo->graph_analysis->ht, &new_gai->fd->num, new_gai); - inserted = TRUE; - break; - } - list = g_list_next(list); - item_num++; - } - - if (!inserted) { - g_queue_push_tail(tapinfo->graph_analysis->items, new_gai); - g_hash_table_insert(tapinfo->graph_analysis->ht, &new_gai->fd->num, new_gai); - } - } -} - -/****************************************************************************/ -/* ***************************TAP for RTP Events*****************************/ -/****************************************************************************/ - -/*static guint32 rtp_evt_setup_frame_num = 0;*/ - -/****************************************************************************/ -/* whenever a rtp event packet is seen by the tap listener */ -static int -rtp_event_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *rtp_event_info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_event_); - const struct _rtp_event_info *pi = (const struct _rtp_event_info *)rtp_event_info; - - /* do not consider RTP events packets without a setup frame */ - if (pi->info_setup_frame_num == 0) { - return 0; - } - - tapinfo->rtp_evt_frame_num = pinfo->fd->num; - tapinfo->rtp_evt = pi->info_rtp_evt; - tapinfo->rtp_evt_end = pi->info_end; - - return 0; -} - -/****************************************************************************/ -void -rtp_event_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("rtpevent", tap_base_to_id(tap_id_base, tap_id_offset_rtp_event_), - NULL, - 0, - NULL, - rtp_event_packet, - NULL - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ - -void -remove_tap_listener_rtp_event(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_rtp_event_)); -} - -/****************************************************************************/ -/* ***************************TAP for RTP **********************************/ -/****************************************************************************/ - -/****************************************************************************/ -/* when there is a [re]reading of RTP packets */ -static void -voip_rtp_reset(void *tap_offset_ptr) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_); - GList *list; - /* free the data items first */ - list = g_list_first(tapinfo->rtp_stream_list); - while (list) - { - g_free(list->data); - list = g_list_next(list); - } - g_list_free(tapinfo->rtp_stream_list); - tapinfo->rtp_stream_list = NULL; - tapinfo->nrtp_streams = 0; - return; -} - -/****************************************************************************/ -/* whenever a RTP packet is seen by the tap listener */ -static int -rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, void const *RTPinfo) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_); - 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 = (const struct _rtp_info *)RTPinfo; - - /* do not consider RTP packets without a setup frame */ - if (pi->info_setup_frame_num == 0) { - return 0; - } - - /* add this RTP for future listening using the RTP Player*/ -#ifdef HAVE_LIBPORTAUDIO - add_rtp_packet(pi, pinfo); -#endif - - /* check whether we already have a RTP stream with this setup frame and ssrc in the list */ - list = g_list_first(tapinfo->rtp_stream_list); - while (list) - { - tmp_listinfo=(voip_rtp_stream_info_t *)list->data; - if ( (tmp_listinfo->setup_frame_number == pi->info_setup_frame_num) - && (tmp_listinfo->ssrc == pi->info_sync_src) && (tmp_listinfo->end_stream == FALSE)) { - /* if the payload type has changed, we mark the stream as finished to create a new one - this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */ - if ( tmp_listinfo->pt != pi->info_payload_type ) { - tmp_listinfo->end_stream = TRUE; - } else { - strinfo = (voip_rtp_stream_info_t*)(list->data); - break; - } - } - list = g_list_next(list); - } - - /* 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)) { - return 0; - } - - /* not in the list? then create a new entry */ - if (strinfo==NULL) { - strinfo = (voip_rtp_stream_info_t *)g_malloc(sizeof(voip_rtp_stream_info_t)); - COPY_ADDRESS(&(strinfo->src_addr), &(pinfo->src)); - strinfo->src_port = pinfo->srcport; - COPY_ADDRESS(&(strinfo->dest_addr), &(pinfo->dst)); - strinfo->dest_port = pinfo->destport; - strinfo->ssrc = pi->info_sync_src; - strinfo->end_stream = FALSE; - strinfo->pt = pi->info_payload_type; - strinfo->pt_str = NULL; - strinfo->is_srtp = pi->info_is_srtp; - /* if it is dynamic payload, let use the conv data to see if it is defined */ - if ( (strinfo->pt >= PT_UNDF_96) && (strinfo->pt <= PT_UNDF_127) ) { - /* Use existing packet info if available */ - p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0); - if (p_conv_data && p_conv_data->rtp_dyn_payload) { - const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->pt); - if (encoding_name) { - strinfo->pt_str = g_strdup(encoding_name); - } - } - } - if (!strinfo->pt_str) strinfo->pt_str = g_strdup(val_to_str_ext(strinfo->pt, &rtp_payload_type_short_vals_ext, "%u")); - strinfo->npackets = 0; - strinfo->start_fd = pinfo->fd; - strinfo->start_rel_ts = pinfo->rel_ts; - strinfo->setup_frame_number = pi->info_setup_frame_num; - strinfo->rtp_event = -1; - tapinfo->rtp_stream_list = g_list_prepend(tapinfo->rtp_stream_list, strinfo); - } - - /* Add the info to the existing RTP stream */ - strinfo->npackets++; - strinfo->stop_fd = pinfo->fd; - strinfo->stop_rel_ts = pinfo->rel_ts; - - /* process RTP Event */ - if (tapinfo->rtp_evt_frame_num == pinfo->fd->num) { - strinfo->rtp_event = tapinfo->rtp_evt; - if (tapinfo->rtp_evt_end == TRUE) { - strinfo->end_stream = TRUE; - } - } - - tapinfo->redraw = TRUE; - - return 1; -} - -/****************************************************************************/ -/* whenever a redraw in the RTP tap listener */ -static void -rtp_packet_draw(void *tap_offset_ptr) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_); - GList *rtp_streams_list; - voip_rtp_stream_info_t *rtp_listinfo; - /* GList *voip_calls_graph_list; */ - seq_analysis_item_t *gai = NULL; - seq_analysis_item_t *new_gai; - guint16 conv_num; - guint32 duration; - gchar time_str[COL_MAX_LEN]; - - /* add each rtp stream to the graph */ - rtp_streams_list = g_list_first(tapinfo->rtp_stream_list); - while (rtp_streams_list) - { - rtp_listinfo = (voip_rtp_stream_info_t *)rtp_streams_list->data; - - /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/ - /* voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); */ - if(tapinfo->graph_analysis){ - gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->setup_frame_number); - } - if(gai != NULL) { - /* Found the setup frame*/ - conv_num = gai->conv_num; - /* if RTP was already in the Graph, just update the comment information */ - gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd->num); - if (gai != NULL) { - duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_ts) - nstime_to_msec(&rtp_listinfo->start_rel_ts)); - g_free(gai->comment); - gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X", - (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets, - duration/1000,(duration%1000), rtp_listinfo->ssrc); - } else { - new_gai = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t)); - new_gai->fd = rtp_listinfo->start_fd; - COPY_ADDRESS(&(new_gai->src_addr),&(rtp_listinfo->src_addr)); - COPY_ADDRESS(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr)); - 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_ts) - nstime_to_msec(&rtp_listinfo->start_rel_ts)); - new_gai->frame_label = g_strdup_printf("%s (%s) %s", - (rtp_listinfo->is_srtp)?"SRTP":"RTP", - rtp_listinfo->pt_str, - (rtp_listinfo->rtp_event == -1)? - "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event")); - new_gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X", - (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets, - duration/1000,(duration%1000), rtp_listinfo->ssrc); - new_gai->conv_num = conv_num; - set_fd_time(tapinfo->session, new_gai->fd, time_str); - new_gai->time_str = g_strdup(time_str); - new_gai->display=FALSE; - new_gai->line_style = 2; /* the arrow line will be 2 pixels width */ - g_queue_push_tail(tapinfo->graph_analysis->items, new_gai); - g_hash_table_insert(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd, new_gai); - } - } - rtp_streams_list = g_list_next(rtp_streams_list); - }/* while (rtp_streams_list) */ -} -#if 0 -static void -rtp_packet_draw(void *tap_offset_ptr) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_); - GList *rtp_streams_list; - voip_rtp_stream_info_t *rtp_listinfo; - GList *voip_calls_graph_list; - guint item; - seq_analysis_item_t *gai; - seq_analysis_item_t *new_gai; - guint16 conv_num; - guint32 duration; - gchar time_str[COL_MAX_LEN]; - - /* add each rtp stream to the graph */ - rtp_streams_list = g_list_first(tapinfo->stream_list); - while (rtp_streams_list) - { - rtp_listinfo = rtp_streams_list->data; - - /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/ - voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); - while (voip_calls_graph_list) - { - gai = voip_calls_graph_list->data; - conv_num = gai->conv_num; - /* if we get the setup frame number, then get the time position to graph the RTP arrow */ - if (rtp_listinfo->setup_frame_number == gai->fd->num) { - /* look again from the beginning because there are cases where the Setup frame is after the RTP */ - voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); - item = 0; - while(voip_calls_graph_list) { - gai = voip_calls_graph_list->data; - /* if RTP was already in the Graph, just update the comment information */ - if (rtp_listinfo->start_fd->num == gai->fd->num) { - duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts)); - g_free(gai->comment); - gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X", - (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets, - duration/1000,(duration%1000), rtp_listinfo->ssrc); - break; - } - - /* we increment the list here to be able to check if it is the last item in this calls, which means the RTP is after so we have to draw it */ - voip_calls_graph_list = g_list_next(voip_calls_graph_list); - if (!voip_calls_graph_list) item++; - - /* add the RTP item to the graph if was not there*/ - if (rtp_listinfo->start_fd->num<gai->fd->num || !voip_calls_graph_list) { - new_gai = g_malloc(sizeof(seq_analysis_item_t)); - new_gai->fd = rtp_listinfo->start_fd; - COPY_ADDRESS(&(new_gai->src_addr),&(rtp_listinfo->src_addr)); - COPY_ADDRESS(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr)); - new_gai->port_src = rtp_listinfo->src_port; - new_gai->port_dst = rtp_listinfo->dest_port; - duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts)); - new_gai->frame_label = g_strdup_printf("%s (%s) %s", - (rtp_listinfo->is_srtp)?"SRTP":"RTP", - rtp_listinfo->pt_str, - (rtp_listinfo->rtp_event == -1)? - "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event")); - new_gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X", - (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets, - duration/1000,(duration%1000), rtp_listinfo->ssrc); - new_gai->conv_num = conv_num; - set_fd_time(cfile.epan, new_gai->fd, time_str); - new_gai->time_str = g_strdup(time_str); - new_gai->display=FALSE; - new_gai->line_style = 2; /* the arrow line will be 2 pixels width */ - tapinfo->graph_analysis->list = g_list_insert(tapinfo->graph_analysis->list, new_gai, item); - break; - } - if (voip_calls_graph_list) item++; - } - break; - } - voip_calls_graph_list = g_list_next(voip_calls_graph_list); - } - rtp_streams_list = g_list_next(rtp_streams_list); - } -} -#endif - -/****************************************************************************/ -void -rtp_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("rtp", tap_base_to_id(tap_id_base, tap_id_offset_rtp_), NULL, - 0, - voip_rtp_reset, - rtp_packet, - rtp_packet_draw - ); - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_rtp(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_rtp_)); -} - -/****************************************************************************/ -/******************************TAP for T38 **********************************/ -/****************************************************************************/ - -/****************************************************************************/ -/* whenever a T38 packet is seen by the tap listener */ -static int -t38_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *T38info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_t38_); - - voip_calls_info_t *callsinfo = NULL; - voip_calls_info_t *tmp_listinfo; - GList *voip_calls_graph_list = NULL; - GList *list; - gchar *frame_label = NULL; - gchar *comment = NULL; - seq_analysis_item_t *tmp_gai, *gai = NULL; - guint16 line_style = 2; - double duration; - int conv_num = -1; - - const t38_packet_info *pi = (const t38_packet_info *)T38info; - - if (pi->setup_frame_number != 0) { - /* using the setup frame number of the T38 packet, we get the call number that it belongs */ - if(tapinfo->graph_analysis){ - voip_calls_graph_list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0); - } - while (voip_calls_graph_list) - { - tmp_gai = (seq_analysis_item_t *)voip_calls_graph_list->data; - if (pi->setup_frame_number == tmp_gai->fd->num) { - gai = tmp_gai; - break; - } - voip_calls_graph_list = g_list_next(voip_calls_graph_list); - } - if (gai) conv_num = (int) gai->conv_num; - } - - /* if setup_frame_number in the t38 packet is 0, it means it was not set using an SDP or H245 sesion, which means we don't - * have the associated Voip calls. It probably means the the packet was decoded using the default t38 port, or using "Decode as.." - * in this case we create a "voip" call that only have t38 media (no signaling) - * OR if we have not found the Setup message in the graph. - */ - if ( (pi->setup_frame_number == 0) || (gai == NULL) ) { - /* check whether we already have a call with these parameters in the list */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if (tmp_listinfo->protocol == MEDIA_T38) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - list = g_list_next (list); - } - - /* not in the list? then create a new entry */ - if (callsinfo==NULL) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_UNKNOWN; - callsinfo->from_identity=g_strdup("T38 Media only"); - callsinfo->to_identity=g_strdup("T38 Media only"); - COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src)); - callsinfo->selected=FALSE; - callsinfo->start_fd = pinfo->fd; - callsinfo->start_rel_ts = pinfo->rel_ts; - callsinfo->protocol=MEDIA_T38; - callsinfo->prot_info=NULL; - callsinfo->free_prot_info = NULL; - callsinfo->npackets = 0; - callsinfo->call_num = tapinfo->ncalls++; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - conv_num = (int) callsinfo->call_num; - } - - /* at this point we should have found the call num for this t38 packets belong */ - if (conv_num == -1) { - return 0; - } - - /* add the item to the graph list */ - if (pi->type_msg == 0) { /* 0=t30-indicator */ - frame_label = g_strdup(val_to_str(pi->t30ind_value, t38_T30_indicator_vals, "Ukn (0x%02X)") ); - comment = g_strdup_printf("t38:t30 Ind:%s",val_to_str(pi->t30ind_value, t38_T30_indicator_vals, "Ukn (0x%02X)") ); - line_style = 1; - } else if (pi->type_msg == 1) { /* 1=data */ - switch(pi->Data_Field_field_type_value) { - case 0: /* hdlc-data */ - break; - case 2: /* hdlc-fcs-OK */ - case 4: /* hdlc-fcs-OK-sig-end */ - frame_label = g_strdup_printf("%s %s", - val_to_str_ext(pi->t30_Facsimile_Control & 0x7F, - &t30_facsimile_control_field_vals_short_ext, - "Ukn (0x%02X)"), - pi->desc); - comment = g_strdup_printf("t38:%s:HDLC:%s", - val_to_str(pi->data_value, - t38_T30_data_vals, - "Ukn (0x%02X)"), - val_to_str_ext(pi->t30_Facsimile_Control & 0x7F, - &t30_facsimile_control_field_vals_ext, - "Ukn (0x%02X)")); - break; - case 3: /* hdlc-fcs-BAD */ - case 5: /* hdlc-fcs-BAD-sig-end */ - frame_label = g_strdup(pi->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end"); - comment = g_strdup_printf("WARNING: received t38:%s:HDLC:%s", - val_to_str(pi->data_value, - t38_T30_data_vals, - "Ukn (0x%02X)"), - pi->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end"); - break; - case 7: /* t4-non-ecm-sig-end */ - duration = nstime_to_sec(&pinfo->rel_ts) - pi->time_first_t4_data; - frame_label = g_strdup_printf("t4-non-ecm-data:%s", - val_to_str(pi->data_value, - t38_T30_data_vals, - "Ukn (0x%02X)") ); - comment = g_strdup_printf("t38:t4-non-ecm-data:%s Duration: %.2fs %s", - val_to_str(pi->data_value, - t38_T30_data_vals, - "Ukn (0x%02X)"), - duration, pi->desc_comment ); - insert_to_graph_t38(tapinfo, pinfo, edt, frame_label, comment, - (guint16)conv_num, &(pinfo->src), &(pinfo->dst), - line_style, pi->frame_num_first_t4_data); - break; - } - } - - if (frame_label && !(pi->Data_Field_field_type_value == 7 && pi->type_msg == 1)) { - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, (guint16)conv_num, &(pinfo->src), &(pinfo->dst), line_style); - } - - g_free(comment); - g_free(frame_label); - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - -/****************************************************************************/ -void -t38_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("t38", tap_base_to_id(tap_id_base, tap_id_offset_t38_), NULL, - 0, - voip_calls_dlg_reset, - t38_packet, - voip_calls_dlg_draw - ); - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_t38_)); -} - - -/****************************************************************************/ -/* ***************************TAP for SIP **********************************/ -/****************************************************************************/ - - -static void free_sip_info(gpointer p) { - sip_calls_info_t *si = (sip_calls_info_t *)p; - - g_free(si->call_identifier); - g_free(si); -} - -/****************************************************************************/ -/* whenever a SIP packet is seen by the tap listener */ -static int -sip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt , const void *SIPinfo) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_); - /* we just take note of the ISUP data here; when we receive the MTP3 part everything will - be compared with existing calls */ - - voip_calls_info_t *callsinfo = NULL; - sip_calls_info_t *tmp_sipinfo = NULL; - address tmp_src, tmp_dst; - gchar *frame_label = NULL; - gchar *comment = NULL; - gchar *old_comment = NULL; - gchar *key=NULL; - - const sip_info_value_t *pi = (const sip_info_value_t *)SIPinfo; - - /* do not consider packets without call_id */ - if (pi->tap_call_id ==NULL) { - return 0; - } - key=pi->tap_call_id; - /* init the hash table */ - if(NULL==tapinfo->callsinfo_hashtable[SIP_HASH]) { - /* TODO: check how efficient g_str_hash is for sip call ids */ - tapinfo->callsinfo_hashtable[SIP_HASH]=g_hash_table_new_full(g_str_hash, - g_str_equal, - NULL, /* key_destroy_func */ - NULL);/* value_destroy_func */ - } - /* search the call information in the SIP_HASH */ - callsinfo = (voip_calls_info_t *)g_hash_table_lookup(tapinfo->callsinfo_hashtable[SIP_HASH], key); - - /* Create a new flow entry if the message is INVITE in case of FLOW_ONLY_INVITES, - Create a new flow entry for all messages which have a method in case of FLOW_ALL. - Flows for REGISTER, OPTIONS, MESSAGE and other SIP methods can be seen. */ - - if ((callsinfo==NULL) && (pi->request_method!=NULL)) { - - /* check VoIPcalls_get_flow_show_option() == FLOW_ALL or FLOW_ONLY_INVITES */ - - if (tapinfo->fs_option == FLOW_ALL || - (tapinfo->fs_option == FLOW_ONLY_INVITES && - strcmp(pi->request_method,"INVITE")==0)) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_CALL_SETUP; - callsinfo->from_identity=g_strdup(pi->tap_from_addr); - callsinfo->to_identity=g_strdup(pi->tap_to_addr); - COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src)); - callsinfo->selected=FALSE; - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - callsinfo->protocol=VOIP_SIP; - callsinfo->prot_info=g_malloc(sizeof(sip_calls_info_t)); - callsinfo->free_prot_info = free_sip_info; - callsinfo->call_id = g_strdup(pi->tap_call_id); - tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info; - tmp_sipinfo->call_identifier = g_strdup(pi->tap_call_id); - tmp_sipinfo->sip_state = SIP_INVITE_SENT; - tmp_sipinfo->invite_cseq = pi->tap_cseq_number; - callsinfo->npackets = 0; - callsinfo->call_num = tapinfo->ncalls++; - - /* show method in comment in conversation list dialog, user can discern different conversation types */ - callsinfo->call_comment=g_strdup(pi->request_method); - - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - /* insert the call information in the SIP_HASH */ - g_hash_table_insert(tapinfo->callsinfo_hashtable[SIP_HASH], - tmp_sipinfo->call_identifier, callsinfo); - } - } - - if (callsinfo!=NULL) { - tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info; - - /* let's analyze the call state */ - - COPY_ADDRESS(&(tmp_src), &(pinfo->src)); - COPY_ADDRESS(&(tmp_dst), &(pinfo->dst)); - - if (pi->request_method == NULL) { - frame_label = g_strdup_printf("%u %s", pi->response_code, pi->reason_phrase ); - comment = g_strdup_printf("SIP Status %u %s", pi->response_code, pi->reason_phrase ); - - if ((tmp_sipinfo && pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(ADDRESSES_EQUAL(&tmp_dst,&(callsinfo->initial_speaker)))) { - if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)) { - tmp_sipinfo->sip_state = SIP_200_REC; - } - else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)) { - callsinfo->call_state = VOIP_REJECTED; - tapinfo->rejected_calls++; - } - - /* UPDATE comment in conversation list dialog with response code and reason. - Multiple code(+reason) may be appended, so skip over intermediate codes (100 trying, 183 ringing, e.t.c.) -TODO: is useful but not perfect, what is appended is truncated when displayed in dialog window */ - if (pi->response_code >= 200) { - old_comment = callsinfo->call_comment; - callsinfo->call_comment=g_strdup_printf("%s %u", - callsinfo->call_comment, - pi->response_code/*, pi->reason_phrase*/); - - g_free(old_comment); - } - - } - - } - else { - frame_label = g_strdup(pi->request_method); - - if ((strcmp(pi->request_method,"INVITE")==0)&&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))) { - tmp_sipinfo->invite_cseq = pi->tap_cseq_number; - callsinfo->call_state = VOIP_CALL_SETUP; - /* TODO: sometimes truncated when displayed in dialog window */ - comment = g_strdup_printf("SIP INVITE From: %s To:%s Call-ID:%s CSeq:%d", - callsinfo->from_identity, callsinfo->to_identity, - callsinfo->call_id, pi->tap_cseq_number); - } - else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq) - &&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC) - &&(callsinfo->call_state == VOIP_CALL_SETUP)) { - callsinfo->call_state = VOIP_IN_CALL; - comment = g_strdup_printf("SIP Request INVITE ACK 200 CSeq:%d", pi->tap_cseq_number); - } - else if (strcmp(pi->request_method,"BYE")==0) { - callsinfo->call_state = VOIP_COMPLETED; - tapinfo->completed_calls++; - comment = g_strdup_printf("SIP Request BYE CSeq:%d", pi->tap_cseq_number); - } - else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq) - &&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))&&(callsinfo->call_state==VOIP_CALL_SETUP)) { - callsinfo->call_state = VOIP_CANCELLED; - tmp_sipinfo->sip_state = SIP_CANCEL_SENT; - 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, - callsinfo->to_identity, pi->tap_cseq_number); - } - } - - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - /* add to the graph */ - 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); - - /* 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); - g_free(tapinfo->sdp_summary); - tapinfo->sdp_summary = NULL; - } - - } - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ - -void -sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("sip", tap_base_to_id(tap_id_base, tap_id_offset_sip_), NULL, - 0, - voip_calls_dlg_reset, - sip_calls_packet, - voip_calls_dlg_draw - ); - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sip_)); -} - -/****************************************************************************/ -/* ***************************TAP for ISUP **********************************/ -/****************************************************************************/ - -/****************************************************************************/ -/* whenever a isup_ packet is seen by the tap listener */ -static int -isup_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *isup_info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_); - voip_calls_info_t *tmp_listinfo; - voip_calls_info_t *callsinfo = NULL; - isup_calls_info_t *tmp_isupinfo; - gboolean found = FALSE; - gboolean forward = FALSE; - gboolean right_pair; - GList *list; - gchar *frame_label = NULL; - gchar *comment = NULL; - - 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) return 0; - - /* check whether we already have a call with these parameters in the list */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - right_pair = TRUE; - tmp_listinfo=(voip_calls_info_t *)list->data; - if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)) { - tmp_isupinfo = (isup_calls_info_t *)tmp_listinfo->prot_info; - if ((tmp_isupinfo->cic == pi->circuit_id)&&(tmp_isupinfo->ni == tapinfo->mtp3_ni)) { - if ((tmp_isupinfo->opc == tapinfo->mtp3_opc)&&(tmp_isupinfo->dpc == tapinfo->mtp3_dpc)) { - forward = TRUE; - } else if ((tmp_isupinfo->dpc == tapinfo->mtp3_opc)&&(tmp_isupinfo->opc == tapinfo->mtp3_dpc)) { - forward = 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) { - found = TRUE; - } else { - tmp_listinfo->call_active_state=VOIP_INACTIVE; - } - } - - if (found) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - } - list = g_list_next (list); - } - - /* not in the list? then create a new entry if the message is IAM - -i.e. if this session is a call*/ - - if ((callsinfo==NULL) &&(pi->message_type==1)) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_UNKNOWN; - COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src)); - callsinfo->selected=FALSE; - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - callsinfo->protocol=VOIP_ISUP; - if (pi->calling_number!=NULL) { - callsinfo->from_identity=g_strdup(pi->calling_number); - } - if (pi->called_number!=NULL) { - callsinfo->to_identity=g_strdup(pi->called_number); - } - callsinfo->prot_info=g_malloc(sizeof(isup_calls_info_t)); - callsinfo->free_prot_info = g_free; - tmp_isupinfo=(isup_calls_info_t *)callsinfo->prot_info; - tmp_isupinfo->opc = tapinfo->mtp3_opc; - tmp_isupinfo->dpc = tapinfo->mtp3_dpc; - tmp_isupinfo->ni = tapinfo->mtp3_ni; - tmp_isupinfo->cic = pi->circuit_id; - callsinfo->npackets = 0; - callsinfo->call_num = tapinfo->ncalls++; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } - - - if (callsinfo!=NULL) { - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - - /* Let's analyze the call state */ - - frame_label = g_strdup(val_to_str_ext_const(pi->message_type, &isup_message_type_value_acro_ext, "Unknown")); - - if (callsinfo->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 (callsinfo->npackets == 2) { /* in the second packet we show the SPs */ - if (forward) { - comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i", - tapinfo->mtp3_ni, tapinfo->mtp3_opc, - tapinfo->mtp3_ni, tapinfo->mtp3_dpc, pi->circuit_id); - } else { - comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i", - tapinfo->mtp3_ni, tapinfo->mtp3_dpc, - tapinfo->mtp3_ni, tapinfo->mtp3_opc, pi->circuit_id); - } - } - - - switch(pi->message_type) { - case 1: /* IAM */ - callsinfo->call_state=VOIP_CALL_SETUP; - break; - case 7: /* CONNECT */ - case 9: /* ANSWER */ - callsinfo->call_state=VOIP_IN_CALL; - break; - case 12: /* RELEASE */ - if (callsinfo->call_state==VOIP_CALL_SETUP) { - if (forward) { - callsinfo->call_state=VOIP_CANCELLED; - } - else { - callsinfo->call_state=VOIP_REJECTED; - tapinfo->rejected_calls++; - } - } - else if (callsinfo->call_state == VOIP_IN_CALL) { - callsinfo->call_state = VOIP_COMPLETED; - tapinfo->completed_calls++; - } - comment = g_strdup_printf("Cause %i - %s", - pi->cause_value, - val_to_str_ext_const(pi->cause_value, &q931_cause_code_vals_ext, "(Unknown)")); - break; - } - - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - g_free(comment); - g_free(frame_label); - } - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - -/****************************************************************************/ - -void -isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("isup", tap_base_to_id(tap_id_base, tap_id_offset_isup_), - NULL, - 0, - voip_calls_dlg_reset, - isup_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ - -void -remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_isup_)); -} - - -/****************************************************************************/ -/* ***************************TAP for MTP3 **********************************/ -/****************************************************************************/ - - -/****************************************************************************/ -/* whenever a mtp3_ packet is seen by the tap listener */ -static int -mtp3_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mtp3_); - const mtp3_tap_rec_t *pi = (const mtp3_tap_rec_t *)mtp3_info; - - /* keep the data in memory to use when the ISUP information arrives */ - - 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; - - return 0; -} - -/****************************************************************************/ - -void -mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("mtp3", tap_base_to_id(tap_id_base, tap_id_offset_mtp3_), - NULL, - 0, - voip_calls_dlg_reset, - mtp3_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } - - error_string = register_tap_listener("m3ua", tap_base_to_id(tap_id_base, tap_id_offset_m3ua_), - NULL, - 0, - voip_calls_dlg_reset, - mtp3_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } - -} - -/****************************************************************************/ - -void -remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mtp3_)); - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_m3ua_)); -} - -/****************************************************************************/ -/* ***************************TAP for Q931 **********************************/ -/****************************************************************************/ -static void h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num); -static const e_guid_t guid_allzero = {0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; -/* defines specific H323 data */ - -/****************************************************************************/ -/* whenever a q931_ packet is seen by the tap listener */ -static int -q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *q931_info) -{ - GList *list,*list2; - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_); - 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 *callsinfo = NULL; - h245_address_t *h245_add = NULL; - gchar *comment; - - const q931_packet_info *pi = (const q931_packet_info *)q931_info; - - /* free previously allocated q931_calling/ed_number */ - g_free(tapinfo->q931_calling_number); - g_free(tapinfo->q931_called_number); - - if (pi->calling_number!=NULL) - tapinfo->q931_calling_number = g_strdup(pi->calling_number); - else - tapinfo->q931_calling_number = g_strdup(""); - - if (pi->called_number!=NULL) - tapinfo->q931_called_number = g_strdup(pi->called_number); - else - tapinfo->q931_called_number = g_strdup(""); - tapinfo->q931_cause_value = pi->cause_value; - tapinfo->q931_frame_num = pinfo->fd->num; - tapinfo->q931_crv = pi->crv; - - - /* add staff to H323 calls */ - if (tapinfo->h225_frame_num == tapinfo->q931_frame_num) { - tmp_h323info = NULL; - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == tapinfo->h225_call_num) ) { - tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info; - callsinfo = (voip_calls_info_t*)(list->data); - - /* Add the CRV to the h323 call */ - if (tmp_h323info->q931_crv == -1) { - tmp_h323info->q931_crv = tapinfo->q931_crv; - } else if (tmp_h323info->q931_crv != tapinfo->q931_crv) { - tmp_h323info->q931_crv2 = tapinfo->q931_crv; - } - break; - } - list = g_list_next (list); - } - - if (callsinfo != NULL) { - comment = NULL; - if (tapinfo->h225_cstype == H225_SETUP) { - /* set te calling and called number from the Q931 packet */ - if (tapinfo->q931_calling_number != NULL) { - g_free(callsinfo->from_identity); - callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number); - } - if (tapinfo->q931_called_number != NULL) { - g_free(callsinfo->to_identity); - callsinfo->to_identity=g_strdup(tapinfo->q931_called_number); - } - - /* check if there is an LRQ/LCF that match this Setup */ - /* TODO: we are just checking the DialedNumer in LRQ/LCF against the Setup - we should also check if the h225 signaling IP and port match the destination - Setup ip and port */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if (tmp_listinfo->protocol == VOIP_H323) { - tmp2_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info; - - /* check if the called number match a LRQ/LCF */ - if ( (strcmp(callsinfo->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 */ - callsinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, callsinfo->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); - DUMP_PTR2(tmp2_h323info->guid); - g_free(tmp2_h323info->guid); - - list2 = g_list_first(tmp2_h323info->h245_list); - while (list2) - { - h245_add=(h245_address_t *)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); - g_queue_unlink(tapinfo->callsinfos, list); - break; - } - } - list = g_list_next (list); - } - - comment = g_strdup_printf("H225 From: %s To:%s TunnH245:%s FS:%s", callsinfo->from_identity, callsinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), - (tapinfo->h225_is_faststart==TRUE?"on":"off")); - } else if (tapinfo->h225_cstype == H225_RELEASE_COMPLET) { - /* get the Q931 Release cause code */ - if (tapinfo->q931_cause_value != 0xFF) { - comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", tapinfo->q931_cause_value, - val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<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, 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 */ - tapinfo->h225_frame_num = 0; - - /* add staff to H245 */ - } else if (tapinfo->h245_labels->frame_num == tapinfo->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_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if (tmp_listinfo->protocol == VOIP_H323) { - tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info; - if ( ((tmp_h323info->q931_crv == tapinfo->q931_crv) || (tmp_h323info->q931_crv2 == tapinfo->q931_crv)) && (tapinfo->q931_crv!=-1)) { - /* if the frame number exists in graph, append to it*/ - if (!append_to_frame_graph(tapinfo, tapinfo->q931_frame_num, NULL, NULL)) { - /* if not exist, add to the graph */ - add_to_graph(tapinfo, pinfo, edt, NULL, NULL, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - ++(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(tapinfo, pinfo->fd->num); - break; - } - } - list = g_list_next (list); - } - - /* add stuff to ACTRACE */ - } else { - address pstn_add; - - comment = NULL; - callsinfo = NULL; - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if ( tmp_listinfo->protocol == VOIP_AC_ISDN ) { - tmp_actrace_isdn_info = (actrace_isdn_calls_info_t *)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 == tapinfo->q931_crv) && (tmp_actrace_isdn_info->trunk == tapinfo->actrace_trunk) ) { - callsinfo = (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 (!callsinfo) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_CALL_SETUP; - callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number); - callsinfo->to_identity=g_strdup(tapinfo->q931_called_number); - COPY_ADDRESS(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src)); - callsinfo->selected=FALSE; - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - callsinfo->protocol=VOIP_AC_ISDN; - callsinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t)); - callsinfo->free_prot_info = g_free; - tmp_actrace_isdn_info=(actrace_isdn_calls_info_t *)callsinfo->prot_info; - tmp_actrace_isdn_info->crv=tapinfo->q931_crv; - tmp_actrace_isdn_info->trunk=tapinfo->actrace_trunk; - callsinfo->npackets = 0; - callsinfo->call_num = tapinfo->ncalls++; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } - - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - switch(pi->message_type) { - case Q931_SETUP: - comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s Called:%s", tapinfo->actrace_trunk, tapinfo->q931_calling_number, tapinfo->q931_called_number); - callsinfo->call_state=VOIP_CALL_SETUP; - break; - case Q931_CONNECT: - callsinfo->call_state=VOIP_IN_CALL; - break; - case Q931_RELEASE_COMPLETE: - case Q931_RELEASE: - case Q931_DISCONNECT: - if (callsinfo->call_state==VOIP_CALL_SETUP) { - if (ADDRESSES_EQUAL(&(callsinfo->initial_speaker), tapinfo->actrace_direction?&pstn_add:&(pinfo->src) )) { /* forward direction */ - callsinfo->call_state=VOIP_CANCELLED; - } - else { /* reverse */ - callsinfo->call_state=VOIP_REJECTED; - tapinfo->rejected_calls++; - } - } else if ( (callsinfo->call_state!=VOIP_CANCELLED) && (callsinfo->call_state!=VOIP_REJECTED) ) { - callsinfo->call_state=VOIP_COMPLETED; - tapinfo->completed_calls++; - } - if (tapinfo->q931_cause_value != 0xFF) { - comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", tapinfo->actrace_trunk, tapinfo->q931_cause_value, - val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>")); - } else { /* Cause not set */ - comment = g_strdup("AC_ISDN No Q931 Rel Cause"); - } - break; - } - - if (!comment) - comment = g_strdup_printf("AC_ISDN trunk:%u", tapinfo->actrace_trunk ); - - add_to_graph(tapinfo, pinfo, edt, val_to_str(pi->message_type, q931_message_type_vals, "<unknown>") , comment, callsinfo->call_num, - tapinfo->actrace_direction?&pstn_add:&(pinfo->src), - tapinfo->actrace_direction?&(pinfo->src):&pstn_add, - 1 ); - - g_free(comment); - g_free((char *)pstn_add.data); - } - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - -/****************************************************************************/ - -void -q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("q931", tap_base_to_id(tap_id_base, tap_id_offset_q931_), - NULL, - 0, - voip_calls_dlg_reset, - q931_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ - -void -remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_q931_)); -} - -/****************************************************************************/ -/****************************TAP for H323 ***********************************/ -/****************************************************************************/ - -static void add_h245_Address(h323_calls_info_t *h323info, h245_address_t *h245_address) -{ - h323info->h245_list = g_list_prepend(h323info->h245_list, h245_address); -} - - -static void free_h225_info(gpointer p) { - h323_calls_info_t *tmp_h323info = (h323_calls_info_t *)p; - - DUMP_PTR2(tmp_h323info->guid); - g_free(tmp_h323info->guid); - - if (tmp_h323info->h245_list) { - GList *list2 = g_list_first(tmp_h323info->h245_list); - while (list2) - { - h245_address_t *h245_add=(h245_address_t *)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); - - } - - g_free(p); -} -/****************************************************************************/ -/* whenever a H225 packet is seen by the tap listener */ -static int -h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H225info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_); - voip_calls_info_t *tmp_listinfo; - voip_calls_info_t *callsinfo = NULL; - h323_calls_info_t *tmp_h323info = NULL; - gchar *frame_label; - gchar *comment; - GList *list; - h245_address_t *h245_add = NULL; - - const h225_packet_info *pi = (const h225_packet_info *)H225info; - - /* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */ - /* 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 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; - - /* check whether we already have a call with this request SeqNum */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - g_assert(tmp_listinfo != NULL); - if (tmp_listinfo->protocol == VOIP_H323) { - tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info; - if (tmp_h323info->requestSeqNum == pi->requestSeqNum) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - list = g_list_next (list); - } - } else { - /* check whether we already have a call with this guid in the list */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if (tmp_listinfo->protocol == VOIP_H323) { - tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info; - g_assert(tmp_h323info != NULL); - if ( (memcmp(tmp_h323info->guid, &guid_allzero, GUID_LEN) != 0) && (memcmp(tmp_h323info->guid, &pi->guid,GUID_LEN)==0) ) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - list = g_list_next (list); - } - } - - tapinfo->h225_cstype = pi->cs_type; - tapinfo->h225_is_faststart = pi->is_faststart; - - /* not in the list? then create a new entry */ - if (callsinfo==NULL) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_UNKNOWN; - callsinfo->from_identity=g_strdup(""); - callsinfo->to_identity=g_strdup(""); - COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src)); - callsinfo->selected=FALSE; - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - callsinfo->protocol=VOIP_H323; - callsinfo->prot_info=g_malloc(sizeof(h323_calls_info_t)); - callsinfo->free_prot_info = free_h225_info; - - tmp_h323info = (h323_calls_info_t *)callsinfo->prot_info; - g_assert(tmp_h323info != NULL); - 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; - tmp_h323info->h245_list = NULL; - tmp_h323info->is_faststart_Setup = FALSE; - tmp_h323info->is_faststart_Proc = FALSE; - tmp_h323info->is_h245Tunneling = FALSE; - tmp_h323info->is_h245 = FALSE; - tmp_h323info->q931_crv = -1; - tmp_h323info->q931_crv2 = -1; - tmp_h323info->requestSeqNum = 0; - callsinfo->call_num = tapinfo->ncalls++; - callsinfo->npackets = 0; - - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } - - tapinfo->h225_frame_num = pinfo->fd->num; - tapinfo->h225_call_num = callsinfo->call_num; - - /* let's analyze the call state */ - - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - - /* XXX: it is supposed to be initialized isn't it? */ - g_assert(tmp_h323info != NULL); - - /* change the status */ - if (pi->msg_type == H225_CS) { - - /* 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); - h245_add->h245_port = pi->h245_port; - add_h245_Address(tmp_h323info, h245_add); - } - - if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling; - - frame_label = g_strdup(pi->frame_label); - - switch(pi->cs_type) { - case H225_SETUP: - tmp_h323info->is_faststart_Setup = pi->is_faststart; - - /* Set the Setup address if it was not set */ - if (tmp_h323info->h225SetupAddr.type == AT_NONE) - COPY_ADDRESS(&(tmp_h323info->h225SetupAddr), &(pinfo->src)); - callsinfo->call_state=VOIP_CALL_SETUP; - 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: - callsinfo->call_state=VOIP_IN_CALL; - if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE; - 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_RELEASE_COMPLET: - if (callsinfo->call_state==VOIP_CALL_SETUP) { - if (ADDRESSES_EQUAL(&(tmp_h323info->h225SetupAddr),&(pinfo->src))) { /* forward direction */ - callsinfo->call_state=VOIP_CANCELLED; - } - else { /* reverse */ - callsinfo->call_state=VOIP_REJECTED; - tapinfo->rejected_calls++; - } - } else { - callsinfo->call_state=VOIP_COMPLETED; - tapinfo->completed_calls++; - } - comment = g_strdup("H225 No Q931 Rel Cause"); - break; - case H225_PROGRESS: - case H225_ALERTING: - case H225_CALL_PROCEDING: - if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE; - comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), - (pi->is_faststart==TRUE?"on":"off")); - break; - default: - comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), - (pi->is_faststart==TRUE?"on":"off")); - - } - } - else if (pi->msg_type == H225_RAS) { - switch(pi->msg_tag) { - case 18: /* LRQ */ - if (!pi->is_duplicate) { - g_free(callsinfo->to_identity); - callsinfo->to_identity=g_strdup(pi->dialedDigits); - tmp_h323info->requestSeqNum = pi->requestSeqNum; - } - case 19: /* LCF */ - if (strlen(pi->dialedDigits)) - comment = g_strdup_printf("H225 RAS dialedDigits: %s", pi->dialedDigits); - else - comment = g_strdup("H225 RAS"); - break; - default: - comment = g_strdup("H225 RAS"); - } - frame_label = g_strdup(val_to_str_const(pi->msg_tag, h225_RasMessage_vals, "<unknown>")); - } else { - frame_label = g_strdup("H225: Unknown"); - comment = NULL; - } - - /* 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 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); - - g_free(frame_label); - g_free(comment); - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ -void -h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("h225", tap_base_to_id(tap_id_base, tap_id_offset_h225_), NULL, - 0, - voip_calls_dlg_reset, - h225_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h225_)); -} - -/* Add the h245 label info to the graph */ -void -h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num) -{ - gint8 n; - - if (new_frame_num != tapinfo->h245_labels->frame_num) return; - - for (n=0; n<tapinfo->h245_labels->labels_count; n++) { - append_to_frame_graph(tapinfo, new_frame_num, tapinfo->h245_labels->labels[n].frame_label, tapinfo->h245_labels->labels[n].comment); - g_free(tapinfo->h245_labels->labels[n].frame_label); - tapinfo->h245_labels->labels[n].frame_label = NULL; - g_free(tapinfo->h245_labels->labels[n].comment); - tapinfo->h245_labels->labels[n].comment = NULL; - } - tapinfo->h245_labels->frame_num = 0; - tapinfo->h245_labels->labels_count = 0; -} - -/* free the h245_labels if the frame number is different */ -static void h245_free_labels(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num) -{ - gint8 n; - - if (new_frame_num == tapinfo->h245_labels->frame_num) return; - - for (n=0; n<tapinfo->h245_labels->labels_count; n++) { - g_free(tapinfo->h245_labels->labels[n].frame_label); - tapinfo->h245_labels->labels[n].frame_label = NULL; - g_free(tapinfo->h245_labels->labels[n].comment); - tapinfo->h245_labels->labels[n].comment = NULL; - } - tapinfo->h245_labels->frame_num = 0; - tapinfo->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(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num, const gchar *frame_label, const gchar *comment) -{ - h245_free_labels(tapinfo, new_frame_num); - - tapinfo->h245_labels->frame_num = new_frame_num; - tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].frame_label = g_strdup(frame_label); - tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].comment = g_strdup(comment); - - if (tapinfo->h245_labels->labels_count < (H245_MAX-1)) - tapinfo->h245_labels->labels_count++; - -} - -/****************************************************************************/ -/* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */ -static int -h245dg_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H245info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_); - voip_calls_info_t *tmp_listinfo; - voip_calls_info_t *callsinfo = NULL; - h323_calls_info_t *tmp_h323info; - GList *list; - GList *list2; - h245_address_t *h245_add = NULL; - - const h245_packet_info *pi = (const h245_packet_info *)H245info; - - /* check if Tunneling is OFF and we have a call with this H245 add */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if (tmp_listinfo->protocol == VOIP_H323) { - tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info; - - list2 = g_list_first(tmp_h323info->h245_list); - while (list2) - { - h245_add=(h245_address_t *)list2->data; - if ( (ADDRESSES_EQUAL(&(h245_add->h245_address),&(pinfo->src)) && (h245_add->h245_port == pinfo->srcport)) - || (ADDRESSES_EQUAL(&(h245_add->h245_address),&(pinfo->dst)) && (h245_add->h245_port == pinfo->destport)) ) { - callsinfo = (voip_calls_info_t*)(list->data); - - ++(callsinfo->npackets); - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - break; - } - list2 = g_list_next(list2); - } - if (callsinfo!=NULL) break; - } - list = g_list_next(list); - } - - /* Tunnel is OFF, and we matched the h245 add so we add it to graph */ - if (callsinfo!=NULL) { - ++(callsinfo->npackets); - /* 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 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); - } - } 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(tapinfo, pinfo->fd->num, (gchar *) pi->frame_label, (gchar *) pi->comment); - } - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ -void -h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("h245dg", tap_base_to_id(tap_id_base, tap_id_offset_h245dg_), NULL, - 0, - voip_calls_dlg_reset, - h245dg_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h245dg_)); -} - -/****************************************************************************/ -/****************************TAP for SDP PROTOCOL ***************************/ -/****************************************************************************/ -/* whenever a SDP packet is seen by the tap listener */ -static int -sdp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SDPinfo) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_); - const sdp_packet_info *pi = (const sdp_packet_info *)SDPinfo; - - /* 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(tapinfo->sdp_summary); - tapinfo->sdp_frame_num = pinfo->fd->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); - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ -void -sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("sdp", tap_base_to_id(tap_id_base, tap_id_offset_sdp_), NULL, - 0, - voip_calls_dlg_reset, - sdp_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sdp_)); -} - - -/****************************************************************************/ -/* ***************************TAP for MGCP **********************************/ -/****************************************************************************/ - -/* - This function will look for a signal/event in the SignalReq/ObsEvent string - and return true if it is found -*/ -static gboolean isSignal(const gchar *signal_str_p, const gchar *signalStr) -{ - gint i; - gchar **resultArray; - - /* if there is no signalStr, just return false */ - if (signalStr == NULL) return FALSE; - - /* if are both "blank" return true */ - if ( (*signal_str_p == '\0') && (*signalStr == '\0') ) return TRUE; - - /* look for signal in signalStr */ - resultArray = g_strsplit(signalStr, ",", 10); - - for (i = 0; resultArray[i]; i++) { - g_strstrip(resultArray[i]); - if (strcmp(resultArray[i], signal_str_p) == 0) return TRUE; - } - - g_strfreev(resultArray); - - return FALSE; -} - -/* - 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") -*/ -static void mgcpCallerID(gchar *signalStr, gchar **callerId) -{ - gchar **arrayStr; - - /* if there is no signalStr, just return false */ - if (signalStr == NULL) return; - - arrayStr = g_strsplit(signalStr, "\"", 3); - - /* look for the ci signal */ - if (g_strv_length(arrayStr) == 3 && strstr(arrayStr[0], "ci(")) { - /* free the previous "From" field of the call, and assign the new */ - g_free(*callerId); - *callerId = g_strdup(arrayStr[1]); - } - g_strfreev(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,#,* -*/ -static void mgcpDialedDigits(gchar *signalStr, gchar **dialedDigits) -{ - gchar *tmpStr; - gchar *resultStr; - gint i,j; - - /* start with 1 for the null-terminator */ - guint resultStrLen = 1; - - /* if there is no signalStr, just return false */ - if (signalStr == NULL) return; - - tmpStr = g_strdup(signalStr); - - for ( i = 0 ; tmpStr[i] ; i++) { - switch (tmpStr[i]) { - case '0' : case '1' : case '2' : case '3' : case '4' : - case '5' : case '6' : case '7' : case '8' : case '9' : - case '#' : case '*' : - resultStrLen++; - break; - default: - tmpStr[i] = '?'; - break; - } - } - - if (resultStrLen == 1) { - g_free(tmpStr); - return; - } - - resultStr = (gchar *)g_malloc(resultStrLen); - - for (i = 0, j = 0; tmpStr[i]; i++) { - if (tmpStr[i] != '?') - resultStr[j++] = tmpStr[i]; - } - resultStr[j] = '\0'; - - g_free(*dialedDigits); - g_free(tmpStr); - - *dialedDigits = resultStr; - - return; -} - - - -/****************************************************************************/ -/* whenever a MGCP packet is seen by the tap listener */ -static int -mgcp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *MGCPinfo) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_); - - voip_calls_info_t *tmp_listinfo; - voip_calls_info_t *callsinfo = NULL; - mgcp_calls_info_t *tmp_mgcpinfo = NULL; - GList *list; - GList *listGraph = NULL; - gchar *frame_label = NULL; - gchar *comment = NULL; - seq_analysis_item_t *gai = NULL; - gboolean newcall = FALSE; - gboolean fromEndpoint = FALSE; /* true for calls originated in Endpoints, false for calls from MGC */ - gdouble diff_time; - - const mgcp_info_t *pi = (const mgcp_info_t *)MGCPinfo; - - - if ((pi->mgcp_type == MGCP_REQUEST) && !pi->is_duplicate ) { - /* check whether we already have a call with this Endpoint and it is active*/ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if ((tmp_listinfo->protocol == VOIP_MGCP) && (tmp_listinfo->call_active_state == VOIP_ACTIVE)) { - tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info; - if (pi->endpointId != NULL) { - if (g_ascii_strcasecmp(tmp_mgcpinfo->endpointId,pi->endpointId) == 0) { - /* - check first if it is an ended call. We can still match packets to this Endpoint 2 seconds - after the call has been released - */ - diff_time = nstime_to_sec(&pinfo->rel_ts) - nstime_to_sec(&tmp_listinfo->stop_rel_ts); - if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) || - (tmp_listinfo->call_state == VOIP_COMPLETED) || - (tmp_listinfo->call_state == VOIP_REJECTED)) && - (diff_time > 2) ) - { - tmp_listinfo->call_active_state = VOIP_INACTIVE; - } else { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - } - } - list = g_list_next (list); - } - - /* there is no call with this Endpoint, lets see if this a new call or not */ - if (callsinfo == NULL) { - if ( (strcmp(pi->code, "NTFY") == 0) && isSignal("hd", pi->observedEvents) ) { /* off hook transition */ - /* this is a new call from the Endpoint */ - fromEndpoint = TRUE; - newcall = TRUE; - } else if (strcmp(pi->code, "CRCX") == 0) { - /* this is a new call from the MGC */ - fromEndpoint = FALSE; - newcall = TRUE; - } - if (!newcall) return 0; - } - } else if ( ((pi->mgcp_type == MGCP_RESPONSE) && pi->request_available) || - ((pi->mgcp_type == MGCP_REQUEST) && pi->is_duplicate) ) { - /* if it is a response OR if it is a duplicated Request, lets look in the Graph to see - if there is a request that matches */ - if(tapinfo->graph_analysis){ - listGraph = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0); - } - while (listGraph) - { - gai = (seq_analysis_item_t *)listGraph->data; - if (gai->fd->num == pi->req_num) { - /* there is a request that match, so look the associated call with this call_num */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if (tmp_listinfo->protocol == VOIP_MGCP) { - if (tmp_listinfo->call_num == gai->conv_num) { - tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info; - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - list = g_list_next (list); - } - if (callsinfo != NULL) break; - } - listGraph = g_list_next(listGraph); - } - /* if there is not a matching request, just return */ - if (callsinfo == NULL) return 0; - } else return 0; - - /* not in the list? then create a new entry */ - if (callsinfo==NULL) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_CALL_SETUP; - if (fromEndpoint) { - callsinfo->from_identity=g_strdup(pi->endpointId); - callsinfo->to_identity=g_strdup(""); - } else { - callsinfo->from_identity=g_strdup(""); - callsinfo->to_identity=g_strdup(pi->endpointId); - } - COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src)); - callsinfo->selected=FALSE; - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - callsinfo->protocol=VOIP_MGCP; - callsinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t)); - callsinfo->free_prot_info = g_free; - tmp_mgcpinfo=(mgcp_calls_info_t *)callsinfo->prot_info; - tmp_mgcpinfo->endpointId = g_strdup(pi->endpointId); - tmp_mgcpinfo->fromEndpoint = fromEndpoint; - callsinfo->npackets = 0; - callsinfo->call_num = tapinfo->ncalls++; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } - - g_assert(tmp_mgcpinfo != NULL); - - /* change call state and add to graph */ - switch (pi->mgcp_type) - { - case MGCP_REQUEST: - if ( (strcmp(pi->code, "NTFY") == 0) && (pi->observedEvents != NULL) ) { - frame_label = g_strdup_printf("%s ObsEvt:%s",pi->code, pi->observedEvents); - - if (tmp_mgcpinfo->fromEndpoint) { - /* use the Dialed digits to fill the "To" for the call, but use the first NTFY */ - if (callsinfo->to_identity[0] == '\0') mgcpDialedDigits(pi->observedEvents, &(callsinfo->to_identity)); - - /* from MGC and the user picked up, the call is connected */ - } else if (isSignal("hd", pi->observedEvents)) - callsinfo->call_state=VOIP_IN_CALL; - - /* hung up signal */ - if (isSignal("hu", pi->observedEvents)) { - if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) { - callsinfo->call_state = VOIP_CANCELLED; - } else { - callsinfo->call_state = VOIP_COMPLETED; - } - } - - } else if (strcmp(pi->code, "RQNT") == 0) { - /* for calls from Endpoint: if there is a "no signal" RQNT and the call was RINGING, we assume this is the CONNECT */ - if ( tmp_mgcpinfo->fromEndpoint && isSignal("", pi->signalReq) && (callsinfo->call_state == VOIP_RINGING) ) { - callsinfo->call_state = VOIP_IN_CALL; - } - - /* if there is ringback or ring tone, change state to ringing */ - if ( isSignal("rg", pi->signalReq) || isSignal("rt", pi->signalReq) ) { - callsinfo->call_state = VOIP_RINGING; - } - - /* if there is a Busy or ReorderTone, and the call was Ringing or Setup the call is Rejected */ - if ( (isSignal("ro", pi->signalReq) || isSignal("bz", pi->signalReq)) && ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) ) { - callsinfo->call_state = VOIP_REJECTED; - } - - if (pi->signalReq != NULL) - frame_label = g_strdup_printf("%s%sSigReq:%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"", pi->signalReq); - else - frame_label = g_strdup_printf("%s%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":""); - - /* use the CallerID info to fill the "From" for the call */ - if (!tmp_mgcpinfo->fromEndpoint) mgcpCallerID(pi->signalReq, &(callsinfo->from_identity)); - - } else if (strcmp(pi->code, "DLCX") == 0) { - /* - if there is a DLCX in a call To an Endpoint and the call was not connected, we use - the DLCX as the end of the call - */ - if (!tmp_mgcpinfo->fromEndpoint) { - if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) { - callsinfo->call_state = VOIP_CANCELLED; - } - } - } - - if (frame_label == NULL) frame_label = g_strdup(pi->code); - break; - case MGCP_RESPONSE: - frame_label = g_strdup_printf("%u (%s)",pi->rspcode, pi->code); - break; - case MGCP_OTHERS: - /* XXX what to do? */ - break; - } - - - comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":""); - - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - g_free(comment); - 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); - g_free(tapinfo->sdp_summary); - tapinfo->sdp_summary = NULL; - } - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ -void -mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - /* - * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree" - * in the MGCP dissector; otherwise, the dissector - * doesn't fill in the info passed to the tap's packet - * routine. - */ - error_string = register_tap_listener("mgcp", - tap_base_to_id(tap_id_base, tap_id_offset_mgcp_), - NULL, - TL_REQUIRES_PROTO_TREE, - voip_calls_dlg_reset, - mgcp_calls_packet, - voip_calls_dlg_draw - ); - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mgcp_)); -} - - -/****************************************************************************/ -/****************************TAP for ACTRACE (AudioCodes trace)**************/ -/****************************************************************************/ - -/* whenever a ACTRACE packet is seen by the tap listener */ -static int -actrace_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *ACTRACEinfo) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_); - const actrace_info_t *pi = (const actrace_info_t *)ACTRACEinfo; - GList *list; - actrace_cas_calls_info_t *tmp_actrace_cas_info; - voip_calls_info_t *tmp_listinfo; - voip_calls_info_t *callsinfo = NULL; - - tapinfo->actrace_frame_num = pinfo->fd->num; - tapinfo->actrace_trunk = pi->trunk; - tapinfo->actrace_direction = pi->direction; - - if (pi->type == 1) { /* is CAS protocol */ - address pstn_add; - gchar *comment = NULL; - - callsinfo = NULL; - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - tmp_listinfo=(voip_calls_info_t *)list->data; - if ( tmp_listinfo->protocol == VOIP_AC_CAS ) { - tmp_actrace_cas_info = (actrace_cas_calls_info_t *)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 == tapinfo->actrace_trunk) ) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - list = g_list_next (list); - } - - SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, "PSTN"); - - /* if it is a new call, add it to the list */ - if (!callsinfo) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_CALL_SETUP; - callsinfo->from_identity=g_strdup("N/A"); - callsinfo->to_identity=g_strdup("N/A"); - COPY_ADDRESS(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src)); - callsinfo->selected=FALSE; - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - callsinfo->protocol=VOIP_AC_CAS; - callsinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t)); - callsinfo->free_prot_info = g_free; - - tmp_actrace_cas_info=(actrace_cas_calls_info_t *)callsinfo->prot_info; - tmp_actrace_cas_info->bchannel=pi->cas_bchannel; - tmp_actrace_cas_info->trunk=tapinfo->actrace_trunk; - callsinfo->npackets = 0; - callsinfo->call_num = tapinfo->ncalls++; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } - - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - comment = g_strdup_printf("AC_CAS trunk:%u", tapinfo->actrace_trunk); - - add_to_graph(tapinfo, pinfo, edt, pi->cas_frame_label, comment, callsinfo->call_num, - tapinfo->actrace_direction?&pstn_add:&(pinfo->src), - tapinfo->actrace_direction?&(pinfo->src):&pstn_add, - 1 ); - - g_free(comment); - } - - tapinfo->redraw = TRUE; - - return 1; /* refresh output */ -} - - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ -void -actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("actrace", tap_base_to_id(tap_id_base, tap_id_offset_actrace_), NULL, - 0, - voip_calls_dlg_reset, - actrace_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_actrace_)); -} - - -/****************************************************************************/ -/**************************** TAP for H248/MEGACO **********************************/ -/****************************************************************************/ - -#define gcp_is_req(type) ( type == GCP_CMD_ADD_REQ || type == GCP_CMD_MOVE_REQ || type == GCP_CMD_MOD_REQ || \ - type == GCP_CMD_SUB_REQ || type == GCP_CMD_AUDITCAP_REQ || type == GCP_CMD_AUDITVAL_REQ || \ - type == GCP_CMD_NOTIFY_REQ || type == GCP_CMD_SVCCHG_REQ || type == GCP_CMD_TOPOLOGY_REQ || \ - type == GCP_CMD_CTX_ATTR_AUDIT_REQ ) - -static int -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_); - const gcp_cmd_t *cmd = (const gcp_cmd_t *)prot_info; - GList *list; - voip_calls_info_t *callsinfo = NULL; - address *mgw; - address *mgc; - gchar mgw_addr[128]; - - if (cmd->ctx->id == NULL_CONTEXT || cmd->ctx->id == ALL_CONTEXTS ) { - return 0; - } - - if ( gcp_is_req(cmd->type) ) { - mgw = &(pinfo->dst); - mgc = &(pinfo->src); - } else { - mgc = &(pinfo->dst); - mgw = &(pinfo->src); - } - - address_to_str_buf(mgw, mgw_addr, 128); - - /* check whether we already have this context in the list */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data; - - if (tmp_listinfo->protocol == TEL_H248) { - if (tmp_listinfo->prot_info == cmd->ctx) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - list = g_list_next (list); - } - - if (callsinfo==NULL) { - - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_state = VOIP_NO_STATE; - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, cmd->ctx->id); - callsinfo->to_identity = g_strdup(""); - callsinfo->prot_info = cmd->ctx; - callsinfo->free_prot_info = NULL; - - callsinfo->npackets = 1; - - COPY_ADDRESS(&(callsinfo->initial_speaker), mgc); - - callsinfo->protocol = TEL_H248; - callsinfo->call_num = tapinfo->ncalls++; - callsinfo->start_fd = pinfo->fd; - callsinfo->start_rel_ts = pinfo->rel_ts; - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - - callsinfo->selected = FALSE; - - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - - } else { - GString *s = g_string_new(""); - gcp_terms_t *ctx_term; - - g_free(callsinfo->from_identity); - callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, ((gcp_ctx_t*)callsinfo->prot_info)->id); - - g_free(callsinfo->to_identity); - - for (ctx_term = ((gcp_ctx_t*)callsinfo->prot_info)->terms.next; - ctx_term; - ctx_term = ctx_term->next ) { - if ( ctx_term->term && ctx_term->term->str) { - g_string_append_printf(s," %s",ctx_term->term->str); - } - } - - callsinfo->to_identity = s->str; - g_string_free(s,FALSE); - - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - } - - add_to_graph(tapinfo, pinfo, edt, cmd->str ? cmd->str : "unknown Msg", - ep_strdup_printf("TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id), - callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - ++(tapinfo->npackets); - - tapinfo->redraw = TRUE; - - return 1; -} - -void h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("megaco", tap_base_to_id(tap_id_base, tap_id_offset_megaco_), - NULL, - 0, - voip_calls_dlg_reset, - h248_calls_packet, - voip_calls_dlg_draw); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } - - error_string = register_tap_listener("h248", tap_base_to_id(tap_id_base, tap_id_offset_h248_), - NULL, - 0, - voip_calls_dlg_reset, - h248_calls_packet, - voip_calls_dlg_draw); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -void -remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h248_)); - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_megaco_)); -} - -/****************************************************************************/ -/**************************** TAP for SCCP and SUA **********************************/ -/**************************** ( RANAP and BSSAP ) **********************************/ -/****************************************************************************/ - -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) -const value_string* sccp_payload_values; - -static int -sccp_calls(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) { - const sccp_msg_info_t* msg = (const sccp_msg_info_t *)prot_info; - sccp_assoc_info_t* assoc = msg->data.co.assoc; - GList *list; - voip_calls_info_t *callsinfo = NULL; - const gchar *label = NULL; - const gchar *comment = NULL; - /* check whether we already have this assoc in the list */ - - for(list = g_queue_peek_nth_link(tapinfo->callsinfos, 0) ; list ; list = g_list_next (list) ) { - if ( ((voip_calls_info_t*)(list->data))->prot_info == assoc ) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - - if (callsinfo==NULL) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_state = VOIP_CALL_SETUP; - callsinfo->call_active_state = VOIP_ACTIVE; - if ( assoc->calling_party ) { - callsinfo->from_identity = g_strdup(assoc->calling_party); - } else { - callsinfo->from_identity = g_strdup("Unknown"); - } - - if ( assoc->called_party ) { - callsinfo->to_identity = g_strdup(assoc->called_party); - } else { - callsinfo->to_identity = g_strdup("Unknown"); - } - - callsinfo->prot_info = (void*)assoc; - callsinfo->free_prot_info = NULL; - - callsinfo->npackets = 1; - - COPY_ADDRESS(&(callsinfo->initial_speaker), &(pinfo->src)); - - callsinfo->protocol = SP2VP(assoc->payload); - /* Store frame data which holds time and frame number */ - callsinfo->start_fd = pinfo->fd; - callsinfo->start_rel_ts = pinfo->rel_ts; - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - - callsinfo->selected = FALSE; - callsinfo->call_num = tapinfo->ncalls++; - - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } else { - - if ( assoc->calling_party ) { - g_free(callsinfo->from_identity); - callsinfo->from_identity = g_strdup(assoc->calling_party); - } - - if ( assoc->called_party ) { - g_free(callsinfo->to_identity); - callsinfo->to_identity = g_strdup(assoc->called_party); - } - - callsinfo->protocol = SP2VP(assoc->payload); - /* Store frame data which holds stop time and frame number */ - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - - switch (msg->type) { - case SCCP_MSG_TYPE_CC: - callsinfo->call_state = VOIP_IN_CALL; - break; - case SCCP_MSG_TYPE_RLC: - callsinfo->call_state = VOIP_COMPLETED; - callsinfo->call_active_state = VOIP_INACTIVE; - break; - default: - break; - } - } - - if (msg->data.co.label) { - label = msg->data.co.label; - } else { - label = val_to_str(msg->type, sccp_payload_values, "Unknown(%d)"); - } - - if (msg->data.co.comment) { - comment = msg->data.co.comment; - } else { - comment = NULL; - } - - add_to_graph(tapinfo, pinfo, edt, label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - ++(tapinfo->npackets); - - tapinfo->redraw = TRUE; - - return 1; -} - -static int -sccp_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_); - - sccp_payload_values = sccp_message_type_acro_values; - return sccp_calls(tapinfo, pinfo, edt, prot_info); -} - - -static int -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_); - - sccp_payload_values = sua_co_class_type_acro_values; - return sccp_calls(tapinfo, pinfo, edt, prot_info); -} - - -void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("sccp", tap_base_to_id(tap_id_base, tap_id_offset_sccp_), - NULL, - 0, - voip_calls_dlg_reset, - sccp_calls_packet, - voip_calls_dlg_draw); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } - - error_string = register_tap_listener("sua", tap_base_to_id(tap_id_base, tap_id_offset_sua_), - NULL, - 0, - voip_calls_dlg_reset, - sua_calls_packet, - voip_calls_dlg_draw); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -void -remove_tap_listener_sccp_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sccp_)); - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sua_)); -} - - -/****************************************************************************/ -/****************************TAP for UNISTIM ********************************/ -/****************************************************************************/ - -static int -unistim_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *unistim_info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_unistim_); - voip_calls_info_t *tmp_listinfo; - voip_calls_info_t *callsinfo = NULL; - unistim_info_t *tmp_unistim_info = NULL; - GList *list = NULL; - GString *g_tmp = NULL; - const gchar *frame_label = NULL; - gchar *comment = NULL; - - /* Fetch specific packet infos */ - const unistim_info_t *pi = (const unistim_info_t *)unistim_info; - - /* Init gstring */ - g_tmp = g_string_new(NULL); - - /* Check to see if this is a dup */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - - while(list) - { - tmp_listinfo = (voip_calls_info_t *)list->data; - - if(tmp_listinfo->protocol == VOIP_UNISTIM) { - - tmp_unistim_info = (unistim_info_t *)tmp_listinfo->prot_info; - - /* Search by termid if possible, otherwise use ni/it ip + port.. */ - if(pi->termid != 0) { - if(tmp_unistim_info->termid == pi->termid) { - /* If the call has ended, then we can reuse it.. */ - if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) { - /* Do nothing */ - } else { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - } else { - /* If no term id use ips / port to find entry */ - if(ADDRESSES_EQUAL(&tmp_unistim_info->it_ip, &pinfo->dst) && ADDRESSES_EQUAL(&tmp_unistim_info->ni_ip,&pinfo->src) && (tmp_unistim_info->it_port == pinfo->destport)) { - if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) { - /* Do nothing previous call */ - } else { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - else if(ADDRESSES_EQUAL(&tmp_unistim_info->it_ip, &pinfo->src) && ADDRESSES_EQUAL(&tmp_unistim_info->ni_ip,&pinfo->dst) && (tmp_unistim_info->it_port == pinfo->srcport)) { - if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) { - /* Do nothing, it ain't our call.. */ - } else { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - } - } - - /* Otherwise, go to the next one.. */ - list = g_list_next(list); - } - - if(pi->payload_type == 2 || pi->payload_type == 1) { - - if(pi->key_state == 1 || pi->hook_state == 1) { - - /* If the user hits a button, - Session will be SETUP */ - - /* If new add to list */ - if (callsinfo==NULL) { - - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_CALL_SETUP; - callsinfo->from_identity=g_strdup_printf("%x",pi->termid); - callsinfo->to_identity=g_strdup("UNKNOWN"); - COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src)); - callsinfo->selected=FALSE; - - /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */ - /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */ - /* Store frame data which holds time and frame number */ - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - - callsinfo->protocol=VOIP_UNISTIM; - callsinfo->prot_info=g_malloc(sizeof(unistim_info_t)); - - tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info; - - /* Clear tap struct */ - tmp_unistim_info->rudp_type = 0; - tmp_unistim_info->payload_type = 0; - tmp_unistim_info->sequence = pi->sequence; - tmp_unistim_info->termid = pi->termid; - tmp_unistim_info->key_val = -1; - tmp_unistim_info->key_state = -1; - tmp_unistim_info->hook_state = -1; - tmp_unistim_info->stream_connect = -1; - tmp_unistim_info->trans_connect = -1; - tmp_unistim_info->set_termid = -1; - tmp_unistim_info->string_data = NULL; - tmp_unistim_info->key_buffer = NULL; - - COPY_ADDRESS(&(tmp_unistim_info->it_ip),&(pi->it_ip)); - COPY_ADDRESS(&(tmp_unistim_info->ni_ip),&(pi->ni_ip)); - tmp_unistim_info->it_port = pi->it_port; - - callsinfo->free_prot_info = g_free; - callsinfo->npackets = 0; - callsinfo->call_num = tapinfo->ncalls++; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - - } else { - - /* Set up call wide info struct */ - tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info; - tmp_unistim_info->sequence = pi->sequence; - } - - /* Each packet COULD BE OUR LAST!!!! */ - /* Store frame data which holds time and frame number */ - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - - /* This is a valid packet so increment counter */ - ++(callsinfo->npackets); - - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - /* Key was depressed.. update key buffer.. */ - if(pi->key_val >= 0 && pi->key_val <= 11) { - - if(tmp_unistim_info->key_buffer != NULL) { - - /* assign to temp variable */ - g_string_assign(g_tmp,tmp_unistim_info->key_buffer); - - /* Manipulate the data */ - if(pi->key_val == 10) { - tmp_unistim_info->key_buffer = g_strdup_printf("%s*",g_tmp->str); - } else if(pi->key_val == 11) { - tmp_unistim_info->key_buffer = g_strdup_printf("%s#",g_tmp->str); - } else { - tmp_unistim_info->key_buffer = g_strdup_printf("%s%d",g_tmp->str,pi->key_val); - } - - } else { - - /* Create new string */ - if(pi->key_val == 10) { - tmp_unistim_info->key_buffer = g_strdup("*"); - } else if(pi->key_val == 11) { - tmp_unistim_info->key_buffer = g_strdup("#"); - } else { - tmp_unistim_info->key_buffer = g_strdup_printf("%d",pi->key_val); - } - - } - - /* Select for non-digit characters */ - if(pi->key_val == 10) { - comment = g_strdup_printf("Key Input Sent: * (%d)", pi->sequence); - } else if(pi->key_val == 11) { - comment = g_strdup_printf("Key Input Sent: # (%d)", pi->sequence); - } else { - comment = g_strdup_printf("Key Input Sent: %d (%d)",pi->key_val, pi->sequence); - } - } else if(pi->key_val == 12) { - /* Set label and comment for graph */ - comment = g_strdup_printf("Key Input Sent: UP (%d)", pi->sequence); - } else if(pi->key_val == 13) { - /* Set label and comment for graph */ - comment = g_strdup_printf("Key Input Sent: DOWN (%d)", pi->sequence); - } else if(pi->key_val == 14) { - /* Set label and comment for graph */ - comment = g_strdup_printf("Key Input Sent: RIGHT (%d)", pi->sequence); - } else if(pi->key_val == 15) { - if(pi->key_buffer != NULL) { - /* Get data */ - g_string_assign(g_tmp,pi->key_buffer); - - /* Manipulate the data */ - g_string_truncate(g_tmp,g_tmp->len-1); - - /* Insert new data */ - tmp_unistim_info->key_buffer = g_strdup(g_tmp->str); - } - - /* Set label and comment for graph */ - comment = g_strdup_printf("Key Input Sent: LEFT (%d)", pi->sequence); - } else if(pi->key_val == 20) { - /* User pressed the soft key 0 probably dial */ - comment = g_strdup_printf("Key Input Sent: S0 (%d)", pi->sequence); - } else if(pi->key_val == 21) { - /* User pressed the soft key 1 */ - comment = g_strdup_printf("Key Input Sent: S1 (%d)", pi->sequence); - } else if(pi->key_val == 22) { - /* User pressed the soft key 2 */ - /* On cs2k phones, soft key 2 is backspace. */ - if(pi->key_buffer != NULL) { - - /* Get data */ - g_string_assign(g_tmp,pi->key_buffer); - - /* Manipulate the data */ - g_string_truncate(g_tmp,g_tmp->len-1); - - /* Insert new data */ - tmp_unistim_info->key_buffer = g_strdup(g_tmp->str); - } - - /* add label and comment */ - comment = g_strdup_printf("Key Input Sent: S2 (%d)", pi->sequence); - } else if(pi->key_val == 28) { - /* User pressed something */ - comment = g_strdup_printf("Key Input Sent: Release (%d)", pi->sequence); - } else if(pi->key_val == 23) { - /* User pressed the soft key 3 */ - /* Cancel on cs2k so clear buffer */ - /* On mcs it's config which will clear the buffer too */ - tmp_unistim_info->key_buffer = g_strdup("\n"); - - /* User pressed something, set labels*/ - comment = g_strdup_printf("Key Input Sent: S3 (%d)", pi->sequence); - } else if(pi->key_val == 27) { - /* User pressed something */ - comment = g_strdup_printf("Key Input Sent: Hold (%d)", pi->sequence); - } else if(pi->key_val == 29) { - /* User pressed something */ - comment = g_strdup_printf("Key Input Sent: Mute (%d)", pi->sequence); - } else if(pi->key_val == 30) { - /* User pressed something */ - comment = g_strdup_printf("Key Input Sent: Headset (%d)", pi->sequence); - } else if(pi->key_val == 31) { - /* Handsfree button */ - comment = g_strdup_printf("Key Input Sent: Handsfree (%d)", pi->sequence); - } else if(pi->key_val >= 32 && pi->key_val <= 56) { - /* Prog. Key X */ - comment = g_strdup_printf("Key Input Sent: Prog%d (%d)", (pi->key_val & 31), pi->sequence); - } - - if(pi->key_val != -1) { - - frame_label = "KEY INPUT"; - - if (comment == NULL) - /* Ouch! What do you do!? */ - /* User pressed something */ - comment = g_strdup_printf("Key Input Sent: UNKNOWN - %d (%d)", pi->key_val, pi->sequence); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - g_free(comment); - } - - if(pi->hook_state == 1) { - - /* Phone is off hook */ - frame_label = "OFF HOOK"; - comment = g_strdup_printf("Off Hook (%d)", pi->sequence); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - g_free(comment); - } else if(pi->hook_state == 0) { - - /* Phone is on hook */ - frame_label = "ON HOOK"; - comment = g_strdup_printf("On Hook (%d)", pi->sequence); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - g_free(comment); - } - } - - /* Open stream was sent from server */ - if(pi->stream_connect == 1 && callsinfo != NULL) { - - /* Open stream */ - /* Signifies the start of the call so set start_sec & start_usec */ - /* Frame data holds the time info */ - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - /* Each packet COULD BE OUR LAST!!!! */ - /* Store frame data which holds time and frame number */ - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - - /* Local packets too */ - ++(callsinfo->npackets); - - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true - Call control protocol, we can only guess at the destination by messing with - key buffers. */ - if(tmp_unistim_info->key_buffer != NULL) { - callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer); - } - - /* change sequence number for ACK detection */ - tmp_unistim_info->sequence = pi->sequence; - - /* State changes too */ - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_IN_CALL; - - /* Add graph data */ - frame_label = "STREAM OPENED"; - comment = g_strdup_printf("Stream Opened (%d)",pi->sequence); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - } else if(pi->stream_connect == 1 && callsinfo == NULL) { - - /* Research indicates some nortel products initiate stream first - * without keypresses. therefore creating this solely on a keypress is - * ineffective. - * Sometimes calls start immediately with open stream. - */ - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_CALL_SETUP; - callsinfo->from_identity=g_strdup("UNKNOWN"); - callsinfo->to_identity=g_strdup("UNKNOWN"); - COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src)); - callsinfo->selected=FALSE; - - /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */ - /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */ - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - - callsinfo->protocol=VOIP_UNISTIM; - callsinfo->prot_info=g_malloc(sizeof(unistim_info_t)); - - tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info; - - /* Clear tap struct */ - tmp_unistim_info->rudp_type = 0; - tmp_unistim_info->payload_type = 0; - tmp_unistim_info->sequence = pi->sequence; - tmp_unistim_info->termid = 0; - tmp_unistim_info->key_val = -1; - tmp_unistim_info->key_state = -1; - tmp_unistim_info->hook_state = -1; - tmp_unistim_info->stream_connect = -1; - tmp_unistim_info->trans_connect = -1; - tmp_unistim_info->set_termid = -1; - tmp_unistim_info->string_data = NULL; - tmp_unistim_info->key_buffer = NULL; - - COPY_ADDRESS(&(tmp_unistim_info->it_ip),&(pi->it_ip)); - COPY_ADDRESS(&(tmp_unistim_info->ni_ip),&(pi->ni_ip)); - tmp_unistim_info->it_port = pi->it_port; - - callsinfo->free_prot_info = g_free; - callsinfo->npackets = 0; - callsinfo->call_num = tapinfo->ncalls++; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - - /* Open stream */ - /* Each packet COULD BE OUR LAST!!!! */ - /* Store frame data which holds time and frame number */ - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - /* Local packets too */ - ++(callsinfo->npackets); - - /* increment the packets counter of all calls */ - ++(tapinfo->npackets); - - /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true - Call control protocol, we can only guess at the destination by messing with - key buffers. */ - if(tmp_unistim_info->key_buffer != NULL) { - callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer); - } - - /* change sequence number for ACK detection */ - tmp_unistim_info->sequence = pi->sequence; - - /* State changes too */ - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->call_state = VOIP_IN_CALL; - - /* Add graph data */ - frame_label = "STREAM OPENED"; - comment = g_strdup_printf("Stream Opened (%d)",pi->sequence); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - } else if(pi->stream_connect == 0 && callsinfo != NULL) { - /* Close Stream */ - - /* Set stop seconds + usec */ - /* frame_data holds the time info */ - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - - tmp_unistim_info->sequence = pi->sequence; - - if(callsinfo->call_state == VOIP_IN_CALL) { - callsinfo->call_active_state = VOIP_INACTIVE; - callsinfo->call_state = VOIP_COMPLETED; - } else { - callsinfo->call_state = VOIP_UNKNOWN; - callsinfo->call_active_state = VOIP_INACTIVE; - } - - frame_label = "STREAM CLOSED"; - comment = g_strdup_printf("Stream Closed (%d)",pi->sequence); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - } else - comment = NULL; - - } else if(pi->rudp_type == 1 && callsinfo != NULL) { - /* ACK */ - /* Only show acks for processed seq #s */ - if(tmp_unistim_info->sequence == pi->sequence) { - - frame_label = "ACK"; - comment = g_strdup_printf("ACK for sequence %d",pi->sequence); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - } - - } else if(pi->rudp_type == 0 && callsinfo != NULL) { - - /* NAK */ - frame_label = "NAK"; - comment = g_strdup_printf("NAK for sequence %d",pi->sequence); - - /* add to the graph */ - add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - } - - /* free data */ - g_free(comment); - - tapinfo->redraw = TRUE; - - return 1; -} - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ -void -unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) { - - GString *error_string; - - error_string = register_tap_listener("unistim", tap_base_to_id(tap_id_base, tap_id_offset_unistim_), - NULL, - 0, - voip_calls_dlg_reset, - unistim_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_unistim_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_unistim_)); -} - -/****************************************************************************/ -/* ***************************TAP for SKINNY **********************************/ -/****************************************************************************/ - -/* Telecaster to tap-voip call state mapping */ -static const voip_call_state skinny_tap_voip_state[] = { - VOIP_NO_STATE, - VOIP_CALL_SETUP, - VOIP_COMPLETED, - VOIP_RINGING, - VOIP_RINGING, - VOIP_IN_CALL, - VOIP_REJECTED, - VOIP_REJECTED, - VOIP_IN_CALL, - VOIP_IN_CALL, - VOIP_COMPLETED, - VOIP_COMPLETED, - VOIP_CALL_SETUP, - VOIP_UNKNOWN, - VOIP_REJECTED -}; - -static int -skinny_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *skinny_info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_skinny_); - GList* list; - voip_calls_info_t *callsinfo = NULL; - address* phone; - const skinny_info_t *si = (const skinny_info_t *)skinny_info; - skinny_calls_info_t *tmp_skinnyinfo; - gchar *comment; - - if (si == NULL || (si->callId == 0 && si->passThruId == 0)) - return 0; - /* check whether we already have this context in the list */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data; - if (tmp_listinfo->protocol == VOIP_SKINNY) { - tmp_skinnyinfo = (skinny_calls_info_t *)tmp_listinfo->prot_info; - if (tmp_skinnyinfo->callId == si->callId || - tmp_skinnyinfo->callId == si->passThruId) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - list = g_list_next (list); - } - - if (si->messId >= 256) - phone = &(pinfo->dst); - else - phone = &(pinfo->src); - - if (callsinfo==NULL) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_state = VOIP_NO_STATE; - callsinfo->call_active_state = VOIP_ACTIVE; - /* callsinfo->from_identity = g_strdup_printf("%s : %.8x", "Skinny", 1); */ - callsinfo->from_identity = g_strdup(""); - callsinfo->to_identity = g_strdup(""); - callsinfo->prot_info = g_malloc(sizeof(skinny_calls_info_t)); - callsinfo->free_prot_info = g_free; - tmp_skinnyinfo = (skinny_calls_info_t *)callsinfo->prot_info; - tmp_skinnyinfo->callId = si->callId ? si->callId : si->passThruId; - callsinfo->npackets = 1; - - COPY_ADDRESS(&(callsinfo->initial_speaker), phone); - - callsinfo->protocol = VOIP_SKINNY; - callsinfo->call_num = tapinfo->ncalls++; - callsinfo->start_fd = pinfo->fd; - callsinfo->start_rel_ts = pinfo->rel_ts; - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - - callsinfo->selected = FALSE; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } else { - if (si->callingParty) { - g_free(callsinfo->from_identity); - callsinfo->from_identity = g_strdup(si->callingParty); - } - if (si->calledParty) { - g_free(callsinfo->to_identity); - callsinfo->to_identity = g_strdup(si->calledParty); - } - if ((si->callState > 0) && (si->callState < (sizeof(skinny_tap_voip_state)/sizeof(skinny_tap_voip_state[0])))) - callsinfo->call_state = skinny_tap_voip_state[si->callState]; - - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - } - - if (si->callId) { - if (si->passThruId) - comment = g_strdup_printf("CallId = %u, PTId = %u", si->callId, si->passThruId); - else - comment = g_strdup_printf("CallId = %u, LineId = %u", si->callId, si->lineId); - } else { - if (si->passThruId) - comment = g_strdup_printf("PTId = %u", si->passThruId); - else - comment = NULL; - } - - add_to_graph(tapinfo, pinfo, edt, si->messageName, comment, - callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - g_free(comment); - - return 1; -} - - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ -void -skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - /* - * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree" - * in the SKINNY dissector; otherwise, the dissector - * doesn't fill in the info passed to the tap's packet - * routine. - */ - error_string = register_tap_listener("skinny", - tap_base_to_id(tap_id_base, tap_id_offset_skinny_), - NULL, - TL_REQUIRES_PROTO_TREE, - voip_calls_dlg_reset, - skinny_calls_packet, - voip_calls_dlg_draw - ); - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_skinny_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_skinny_)); -} - -/****************************************************************************/ -/* ***************************TAP for IAX2 **********************************/ -/****************************************************************************/ - -static void free_iax2_info(gpointer p) { - iax2_info_t *ii = (iax2_info_t *)p; - - g_free(ii); -} - - -/****************************************************************************/ -/* whenever a IAX2 packet is seen by the tap listener */ -static int -iax2_calls_packet( void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *iax2_info) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_iax2_); - GList* list; - voip_calls_info_t *callsinfo = NULL; - address* phone; - const iax2_info_t *ii = (const iax2_info_t *)iax2_info; - iax2_info_t *tmp_iax2info; - - if (ii == NULL || ii->ptype != IAX2_FULL_PACKET || (ii->scallno == 0 && ii->dcallno == 0)) - return 0; - /* check whether we already have this context in the list */ - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) - { - voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data; - if (tmp_listinfo->protocol == VOIP_IAX2) { - tmp_iax2info = (iax2_info_t *)tmp_listinfo->prot_info; - if (tmp_iax2info->scallno == ii->scallno || - tmp_iax2info->scallno == ii->dcallno) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - list = g_list_next (list); - } - phone = &(pinfo->src); - - - if (callsinfo==NULL) { - /* We only care about real calls, i.e., no registration stuff */ - if (ii->ftype != AST_FRAME_IAX || ii->csub != IAX_COMMAND_NEW) - return 0; - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_state = VOIP_NO_STATE; - callsinfo->call_active_state = VOIP_ACTIVE; - callsinfo->prot_info=g_malloc(sizeof(iax2_info_t)); - callsinfo->free_prot_info = free_iax2_info; - tmp_iax2info = (iax2_info_t *)callsinfo->prot_info; - - tmp_iax2info->scallno = ii->scallno; - if (tmp_iax2info->scallno == 0) tmp_iax2info->scallno = ii->dcallno; - tmp_iax2info->callState = ii->callState; - - callsinfo->npackets = 1; - - COPY_ADDRESS(&(callsinfo->initial_speaker), phone); - callsinfo->from_identity = g_strdup(ii->callingParty); - callsinfo->to_identity = g_strdup(ii->calledParty); - - callsinfo->protocol = VOIP_IAX2; - callsinfo->call_num = tapinfo->ncalls++; - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - - callsinfo->selected = FALSE; - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - - } else { - callsinfo->call_state = ii->callState; - - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - } - - add_to_graph(tapinfo, pinfo, edt, ii->messageName, "", - callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1); - - return 1; - -} - - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ -void -iax2_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - /* - * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree" - * in the IAX2 dissector; otherwise, the dissector - * doesn't fill in the info passed to the tap's packet - * routine. - * XXX - that appears to be true of the MGCP and SKINNY - * dissectors, but, unless I've missed something, it doesn't - * appear to be true of the IAX2 dissector. - */ - error_string = register_tap_listener("IAX2", - tap_base_to_id(tap_id_base, tap_id_offset_iax2_), - NULL, - TL_REQUIRES_PROTO_TREE, - voip_calls_dlg_reset, - iax2_calls_packet, - voip_calls_dlg_draw - ); - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", - error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_iax2_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_iax2_)); -} - -/****************************************************************************/ -/* ***************************TAP for OTHER PROTOCOL **********************************/ -/****************************************************************************/ - -static int -voip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *VoIPinfo) -{ - voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_voip_); - voip_calls_info_t *callsinfo = NULL; - voip_calls_info_t *tmp_listinfo; - GList *list = NULL; - const voip_packet_info_t *pi = (const voip_packet_info_t *)VoIPinfo; - - if (pi->call_id) - list = g_queue_peek_nth_link(tapinfo->callsinfos, 0); - while (list) { - tmp_listinfo = (voip_calls_info_t *)list->data; - if ( tmp_listinfo->protocol == VOIP_COMMON ) { - if (!strcmp(pi->call_id, tmp_listinfo->call_id)) { - callsinfo = (voip_calls_info_t*)(list->data); - break; - } - } - list = g_list_next(list); - } - - if (callsinfo == NULL) { - callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t)); - callsinfo->call_active_state = pi->call_active_state; - callsinfo->call_state = pi->call_state; - callsinfo->call_id=g_strdup((pi->call_id)?pi->call_id:""); - callsinfo->from_identity = g_strdup((pi->from_identity)?pi->from_identity:""); - callsinfo->to_identity = g_strdup((pi->to_identity)?pi->to_identity:""); - COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src)); - callsinfo->selected=FALSE; - callsinfo->start_fd=pinfo->fd; - callsinfo->start_rel_ts=pinfo->rel_ts; - callsinfo->protocol=VOIP_COMMON; - callsinfo->protocol_name=g_strdup((pi->protocol_name)?pi->protocol_name:""); - callsinfo->call_comment=g_strdup((pi->call_comment)?pi->call_comment:""); - callsinfo->prot_info=NULL; - callsinfo->free_prot_info = NULL; - - callsinfo->call_num = tapinfo->ncalls++; - callsinfo->npackets = 0; - - g_queue_push_tail(tapinfo->callsinfos, callsinfo); - } - - callsinfo->call_active_state = pi->call_active_state; - if ((callsinfo->call_state != VOIP_COMPLETED) && (pi->call_state == VOIP_COMPLETED)) - tapinfo->completed_calls++; - if (pi->call_state != VOIP_NO_STATE) - callsinfo->call_state = pi->call_state; - if (pi->call_comment) { - g_free(callsinfo->call_comment); - callsinfo->call_comment=g_strdup(pi->call_comment); - } - callsinfo->stop_fd = pinfo->fd; - callsinfo->stop_rel_ts = pinfo->rel_ts; - ++(callsinfo->npackets); - ++(tapinfo->npackets); - - /* 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; - - return 1; -} -/****************************************************************************/ - -void -voip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("voip", tap_base_to_id(tap_id_base, tap_id_offset_voip_), - NULL, - 0, - voip_calls_dlg_reset, - voip_calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} - -/****************************************************************************/ -void -remove_tap_listener_voip_calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_voip_)); -} - -/****************************************************************************/ -/* ***************************TAP for OTHER PROTOCOL **********************************/ -/****************************************************************************/ - -/****************************************************************************/ -/* whenever a prot_ packet is seen by the tap listener */ -/* -static int -prot_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info _U_) -{ - 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_rel = pinfo->rel_ts; - callsinfo->last_frame_num=pinfo->fd->num; - ++(callsinfo->npackets); - ++(tapinfo->npackets); - } - - tapinfo->redraw = TRUE; - - return 1; -} -*/ -/****************************************************************************/ -/* - -void -prot_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) -{ - GString *error_string; - - error_string = register_tap_listener("prot_", tap_base_to_id(tap_id_base, tap_id_offset_prot_), - NULL, - 0, - voip_calls_dlg_reset, - prot__calls_packet, - voip_calls_dlg_draw - ); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s", error_string->str); - g_string_free(error_string, TRUE); - } -} -*/ -/****************************************************************************/ -/* -void -remove_tap_listener_prot__calls(voip_calls_tapinfo_t *tap_id_base) -{ - remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_prot_)); -} -*/ - - -/* - * Editor modelines - https://www.wireshark.org/tools/modelines.html - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/ui/gtk/voip_calls.h b/ui/gtk/voip_calls.h deleted file mode 100644 index eda175535e..0000000000 --- a/ui/gtk/voip_calls.h +++ /dev/null @@ -1,253 +0,0 @@ -/* voip_calls.h - * VoIP calls summary addition for Wireshark - * - * Copyright 2004, Ericsson , Spain - * By Francisco Alcoba <francisco.alcoba@ericsson.com> - * - * based on h323_calls.h - * Copyright 2004, Iskratel, Ltd, Kranj - * By Miha Jemec <m.jemec@iskratel.si> - * - * H323, RTP and Graph Support - * By Alejandro Vaquero, alejandro.vaquero@verso.com - * Copyright 2005, Verso Technologies Inc. - * - * Wireshark - Network traffic analyzer - * By Gerald Combs <gerald@wireshark.org> - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef __VOIP_CALLS_H__ -#define __VOIP_CALLS_H__ - -#include <glib.h> -#include <stdio.h> -#include <epan/address.h> -#include <epan/guid-utils.h> -#include <epan/tap-voip.h> - -/****************************************************************************/ -extern const char *voip_call_state_name[8]; - -typedef enum _voip_protocol { - VOIP_SIP, - VOIP_ISUP, - VOIP_H323, - VOIP_MGCP, - VOIP_AC_ISDN, - VOIP_AC_CAS, - MEDIA_T38, - TEL_H248, - TEL_SCCP, - TEL_BSSMAP, - TEL_RANAP, - VOIP_UNISTIM, - VOIP_SKINNY, - VOIP_IAX2, - VOIP_COMMON -} voip_protocol; - -typedef enum _hash_indexes { - SIP_HASH=0 -} hash_indexes; - -extern const char *voip_protocol_name[]; - -typedef enum _flow_show_options -{ - FLOW_ALL, - FLOW_ONLY_INVITES -} flow_show_options; - -/** defines specific SIP data */ - -typedef enum _sip_call_state { - SIP_INVITE_SENT, - SIP_200_REC, - SIP_CANCEL_SENT -} sip_call_state; - -typedef struct _sip_calls_info { - gchar *call_identifier; - guint32 invite_cseq; - sip_call_state sip_state; -} sip_calls_info_t; - -/** defines specific ISUP data */ -typedef struct _isup_calls_info { - guint16 cic; - guint32 opc, dpc; - guint8 ni; -} isup_calls_info_t; - -/* defines specific H245 data */ -typedef struct _h245_address { - address h245_address; - guint16 h245_port; -} h245_address_t; - -/** defines specific H323 data */ -typedef struct _h323_calls_info { - e_guid_t *guid; /* Call ID to identify a H225 */ - GList* h245_list; /**< list of H245 Address and ports for tunneling off calls*/ - address h225SetupAddr; /**< we use the SETUP H225 IP to determine if packets are forward or reverse */ - gboolean is_h245; - gboolean is_faststart_Setup; /**< if faststart field is included in Setup*/ - gboolean is_faststart_Proc; /**< if faststart field is included in Proce, Alerting, Progress or Connect*/ - gboolean is_h245Tunneling; - gint32 q931_crv; - gint32 q931_crv2; - guint requestSeqNum; -} h323_calls_info_t; - -/**< defines specific MGCP data */ -typedef struct _mgcp_calls_info { - gchar *endpointId; - gboolean fromEndpoint; /**< true if the call was originated from the Endpoint, false for calls from MGC */ -} mgcp_calls_info_t; - -/** defines specific ACTRACE ISDN data */ -typedef struct _actrace_isdn_calls_info { - gint32 crv; - int trunk; -} actrace_isdn_calls_info_t; - -/** defines specific ACTRACE CAS data */ -typedef struct _actrace_cas_calls_info { - gint32 bchannel; - int trunk; -} actrace_cas_calls_info_t; - -/** defines specific SKINNY data */ -typedef struct _skinny_calls_info { - guint32 callId; -} skinny_calls_info_t; - -/** defines a voip call */ -typedef struct _voip_calls_info { - voip_call_state call_state; - voip_call_active_state call_active_state; - gchar *call_id; - gchar *from_identity; - gchar *to_identity; - gpointer prot_info; - void(*free_prot_info)(gpointer); - address initial_speaker; - guint32 npackets; - voip_protocol protocol; - gchar *protocol_name; - gchar *call_comment; - guint16 call_num; - /**> The frame_data struct holds the frame number and timing information needed. */ - frame_data *start_fd; - nstime_t start_rel_ts; - frame_data *stop_fd; - nstime_t stop_rel_ts; - gboolean selected; - -} voip_calls_info_t; - -/** - * structure that holds the information about all detected calls */ -/* struct holding all information of the tap */ -/* - * XXX Most of these are private to voip_calls.c. We might want to - * make them private. - */ -struct _h245_labels; -typedef struct _voip_calls_tapinfo { - int ncalls; /**< number of call */ - GQueue* callsinfos; /**< queue with all calls */ - GHashTable* callsinfo_hashtable[1]; /**< array of hashes per voip protocol; currently only the one for SIP is used */ - int npackets; /**< total number of packets of all calls */ - voip_calls_info_t* filter_calls_fwd; /**< used as filter in some tap modes */ - int start_packets; - int completed_calls; - int rejected_calls; - seq_analysis_info_t* graph_analysis; - epan_t *session; /**< epan session */ - int nrtp_streams; /**< number of rtp streams */ - GList* rtp_stream_list; /**< list with the rtp streams */ - guint32 rtp_evt_frame_num; - guint8 rtp_evt; - gboolean rtp_evt_end; - gchar *sdp_summary; - guint32 sdp_frame_num; - guint32 mtp3_opc; - guint32 mtp3_dpc; - guint8 mtp3_ni; - guint32 mtp3_frame_num; - struct _h245_labels *h245_labels; /**< H.245 labels */ - gchar *q931_calling_number; - gchar *q931_called_number; - guint8 q931_cause_value; - gint32 q931_crv; - guint32 q931_frame_num; - guint32 h225_frame_num; - guint16 h225_call_num; - int h225_cstype; /* XXX actually an enum */ - gboolean h225_is_faststart; - guint32 actrace_frame_num; - gint32 actrace_trunk; - gint32 actrace_direction; - flow_show_options fs_option; - gboolean redraw; -} voip_calls_tapinfo_t; - -/****************************************************************************/ -/* INTERFACE */ - -/** - * Registers the voip_calls tap listeners (if not already done). - * From that point on, the calls list will be updated with every redissection. - * This function is also the entry point for the initialization routine of the tap system. - * So whenever voip_calls.c is added to the list of WIRESHARK_TAP_SRCs, the tap will be registered on startup. - * If not, it will be registered on demand by the voip_calls functions that need it. - */ -void voip_calls_init_all_taps(voip_calls_tapinfo_t *tap_id_base); - -/** - * Removes the voip_calls tap listener (if not already done) - * From that point on, the voip calls list won't be updated any more. - */ -void voip_calls_remove_all_tap_listeners(voip_calls_tapinfo_t *tap_id_base); - -/** - * Cleans up memory of voip calls tap. - */ -void isup_calls_reset(voip_calls_tapinfo_t *tapinfo); -void mtp3_calls_reset(voip_calls_tapinfo_t *tapinfo); -void q931_calls_reset(voip_calls_tapinfo_t *tapinfo); -void voip_calls_reset(voip_calls_tapinfo_t *tapinfo); - -void graph_analysis_data_init(voip_calls_tapinfo_t *tapinfo); - -#endif /* __VOIP_CALLS_H__ */ - -/* - * Editor modelines - https://www.wireshark.org/tools/modelines.html - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ - diff --git a/ui/gtk/voip_calls_dlg.c b/ui/gtk/voip_calls_dlg.c index 80568066f8..ac001570ba 100644 --- a/ui/gtk/voip_calls_dlg.c +++ b/ui/gtk/voip_calls_dlg.c @@ -52,9 +52,10 @@ #include "../globals.h" #include <epan/stat_groups.h> +#include "ui/voip_calls.h" + #include "ui/gtk/graph_analysis.h" #include "ui/gtk/voip_calls_dlg.h" -#include "ui/gtk/voip_calls.h" #include "ui/gtk/gui_stat_menu.h" #include "ui/gtk/dlg_utils.h" #include "ui/gtk/gui_utils.h" @@ -108,6 +109,11 @@ enum NUM_COLS /* The number of columns */ }; +/* functions for tap_listeners in voip_calls.c */ +static void voip_calls_dlg_reset(void *ptr); +static gboolean voip_calls_dlg_packet(void *ptr, packet_info *pinfo, epan_dissect_t *edt, const void *data); +static void voip_calls_dlg_draw(void *ptr); + /****************************************************************************/ /** @@ -119,7 +125,8 @@ voip_calls_get_info(void) { /* the one and only global voip_calls_tapinfo_t structure */ static voip_calls_tapinfo_t the_tapinfo_struct = - {0, NULL, {0}, 0, NULL, 0, 0, 0, NULL, NULL, + {voip_calls_dlg_reset, voip_calls_dlg_packet, voip_calls_dlg_draw, + 0, NULL, {0}, 0, NULL, 0, 0, 0, NULL, NULL, 0, NULL, /* rtp */ 0, 0, FALSE, /* rtp evt */ NULL, 0, /* sdp */ @@ -828,6 +835,24 @@ voip_calls_dlg_update(GList *listx) } /****************************************************************************/ +/* per-packet function for tap listeners */ +#ifdef HAVE_LIBPORTAUDIO +gboolean +voip_calls_dlg_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data) { + /* add this RTP for future listening using the RTP Player*/ + const struct _rtp_info *rtp_info = (const struct _rtp_info *)data; + add_rtp_packet(rtp_info, pinfo); + return TRUE; +} +#else +gboolean +voip_calls_dlg_packet(void *ptr _U_, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *data _U_) { + /* add this RTP for future listening using the RTP Player*/ + return FALSE; +} +#endif + +/****************************************************************************/ /* draw function for tap listeners to keep the window up to date */ void voip_calls_dlg_draw(void *ptr _U_) @@ -871,12 +896,6 @@ voip_calls_dlg_init_taps(const char *dummy _U_, void* userdata _U_) voip_calls_tapinfo_t* tap_id_base = voip_calls_get_info(); tap_id_base->session = cfile.epan; - if (graph_analysis_data == NULL) { - graph_analysis_data_init(tap_id_base); - /* init the Graph Analysys */ - graph_analysis_data = graph_analysis_init(voip_calls_get_info()->graph_analysis); - } - #ifdef HAVE_LIBPORTAUDIO /* reset the RTP player */ reset_rtp_player(); @@ -885,9 +904,14 @@ voip_calls_dlg_init_taps(const char *dummy _U_, void* userdata _U_) /* Clean up memory used by calls tap */ voip_calls_reset(tap_id_base); + if (graph_analysis_data == NULL) { + /* init the Graph Analysys */ + graph_analysis_data = graph_analysis_init(voip_calls_get_info()->graph_analysis); + } + /* Register the tap listeners */ if (!have_voip_calls_tap_listeners) { - voip_calls_init_all_taps(tap_id_base); + voip_calls_init_all_taps(tap_id_base); have_voip_calls_tap_listeners = TRUE; } diff --git a/ui/gtk/voip_calls_dlg.h b/ui/gtk/voip_calls_dlg.h index 39472571ad..6331cef6c0 100644 --- a/ui/gtk/voip_calls_dlg.h +++ b/ui/gtk/voip_calls_dlg.h @@ -43,8 +43,4 @@ */ void voip_calls_dlg_update(GList *list); -/* functions for tap_listeners in voip_calls.c */ -void voip_calls_dlg_draw(void *ptr); -void voip_calls_dlg_reset(void *ptr); - #endif /* __VOIP_CALLS_DLG_H__ */ |