2005-02-01 12:12:35 +00:00
/* voip_calls.c
* VoIP calls summary addition for ethereal
*
* $ Id $
*
* 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 and Graph Support
* By Alejandro Vaquero , alejandro . vaquero @ verso . com
* Copyright 2005 , Verso Technologies Inc .
*
* Ethereal - Network traffic analyzer
* By Gerald Combs < gerald @ ethereal . com >
* 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 . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "graph_analysis.h"
# include "voip_calls.h"
# include "voip_calls_dlg.h"
# include "rtp_stream.h"
# include "globals.h"
# include <epan/tap.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-rtp.h>
# include "rtp_pt.h"
# include "alert_box.h"
# include "simple_dialog.h"
# ifdef HAVE_FCNTL_H
# include <fcntl.h>
# endif
# ifdef HAVE_SYS_TYPES_H
# include <sys / types.h>
# endif
# include <string.h>
char * voip_call_state_name [ 6 ] = {
" CALL SETUP " ,
" IN CALL " ,
" CANCELLED " ,
" COMPLETED " ,
" REJECTED " ,
" UNKNOWN "
} ;
/* defines whether we can consider the call active */
char * voip_protocol_name [ 3 ] = {
" SIP " ,
" ISUP " ,
" H323 "
} ;
/****************************************************************************/
/* the one and only global voip_calls_tapinfo_t structure */
static voip_calls_tapinfo_t the_tapinfo_struct =
2005-02-02 01:02:09 +00:00
{ 0 , NULL , 0 , NULL , 0 , 0 , 0 , 0 , NULL , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
2005-02-01 12:12:35 +00:00
/* static voip_calls_tapinfo_t the_tapinfo_struct;
*/
/****************************************************************************/
/* when there is a [re]reading of packet's */
void voip_calls_reset ( voip_calls_tapinfo_t * tapinfo )
{
voip_calls_info_t * strinfo ;
sip_calls_info_t * tmp_sipinfo ;
h323_calls_info_t * tmp_h323info ;
graph_analysis_item_t * graph_item ;
GList * list ;
GList * list2 ;
/* free the data items first */
list = g_list_first ( tapinfo - > strinfo_list ) ;
while ( list )
{
strinfo = list - > data ;
g_free ( strinfo - > from_identity ) ;
g_free ( strinfo - > to_identity ) ;
if ( strinfo - > protocol = = VOIP_SIP ) {
tmp_sipinfo = strinfo - > prot_info ;
g_free ( tmp_sipinfo - > call_identifier ) ;
}
if ( strinfo - > protocol = = VOIP_H323 ) {
tmp_h323info = strinfo - > prot_info ;
g_free ( tmp_h323info - > guid ) ;
/* free the H245 list address */
list2 = g_list_first ( tmp_h323info - > h245_list ) ;
while ( list2 )
{
g_free ( list2 - > data ) ;
list2 = g_list_next ( list2 ) ;
}
g_list_free ( tmp_h323info - > h245_list ) ;
tmp_h323info - > h245_list = NULL ;
}
g_free ( strinfo - > prot_info ) ;
g_free ( list - > data ) ;
list = g_list_next ( list ) ;
}
g_list_free ( tapinfo - > strinfo_list ) ;
tapinfo - > strinfo_list = NULL ;
tapinfo - > ncalls = 0 ;
tapinfo - > npackets = 0 ;
tapinfo - > start_packets = 0 ;
tapinfo - > completed_calls = 0 ;
tapinfo - > rejected_calls = 0 ;
/* free the graph data items first */
list = g_list_first ( tapinfo - > graph_analysis - > list ) ;
while ( list )
{
graph_item = list - > data ;
g_free ( graph_item - > frame_label ) ;
g_free ( graph_item - > comment ) ;
g_free ( list - > data ) ;
list = g_list_next ( list ) ;
}
g_list_free ( tapinfo - > graph_analysis - > list ) ;
tapinfo - > graph_analysis - > nconv = 0 ;
tapinfo - > graph_analysis - > list = NULL ;
+ + ( tapinfo - > launch_count ) ;
return ;
}
/****************************************************************************/
2005-02-02 09:08:42 +00:00
void graph_analysis_data_init ( void ) {
2005-02-01 12:12:35 +00:00
the_tapinfo_struct . graph_analysis = g_malloc ( sizeof ( graph_analysis_info_t ) ) ;
the_tapinfo_struct . graph_analysis - > nconv = 0 ;
the_tapinfo_struct . graph_analysis - > list = NULL ;
}
/****************************************************************************/
/* Add the RTP streams into the graph data */
2005-02-02 01:02:09 +00:00
/**
* TODO :
* - reimplement this function
* This function does not work with VoIP taps
* which keep the window up to date .
* Either make rtp_stream ( ) work without redissection or
* add an additional tap listener for rtp to this file .
* The second solution is cleaner and probably easier to implement ,
* leaving the current rtp analysis feature untouched .
*/
2005-02-02 09:08:42 +00:00
void add_rtp_streams_graph ( void )
2005-02-01 12:12:35 +00:00
{
rtp_stream_info_t * strinfo ;
GList * strinfo_list ;
guint nfound ;
guint item ;
GList * voip_calls_graph_list ;
graph_analysis_item_t * gai ;
graph_analysis_item_t * new_gai ;
guint16 conv_num ;
guint32 duration ;
/* Scan for rtpstream */
rtpstream_scan ( ) ;
/* assigne the RTP streams to calls */
nfound = 0 ;
strinfo_list = g_list_first ( rtpstream_get_info ( ) - > strinfo_list ) ;
while ( strinfo_list )
{
strinfo = ( rtp_stream_info_t * ) ( strinfo_list - > data ) ;
/* look in the voip calls graph list if there is a match for this RTP stream */
voip_calls_graph_list = g_list_first ( the_tapinfo_struct . graph_analysis - > list ) ;
item = 0 ;
while ( voip_calls_graph_list )
{
gai = voip_calls_graph_list - > data ;
conv_num = gai - > conv_num ;
if ( strinfo - > setup_frame_number = = gai - > frame_num ) {
while ( voip_calls_graph_list ) {
gai = voip_calls_graph_list - > data ;
/* add the RTP item to the graph */
if ( strinfo - > first_frame_num < gai - > frame_num ) {
new_gai = g_malloc ( sizeof ( graph_analysis_item_t ) ) ;
new_gai - > frame_num = strinfo - > first_frame_num ;
new_gai - > time = ( double ) strinfo - > start_rel_sec + ( double ) strinfo - > start_rel_usec / 1000000 ;
g_memmove ( & new_gai - > ip_src , strinfo - > src_addr . data , 4 ) ;
g_memmove ( & new_gai - > ip_dst , strinfo - > dest_addr . data , 4 ) ;
new_gai - > port_src = strinfo - > src_port ;
new_gai - > port_dst = strinfo - > dest_port ;
duration = ( strinfo - > stop_rel_sec * 1000000 + strinfo - > stop_rel_usec ) - ( strinfo - > start_rel_sec * 1000000 + strinfo - > start_rel_usec ) ;
new_gai - > frame_label = g_strdup_printf ( " RTP (%s) " , val_to_str ( strinfo - > pt , rtp_payload_type_short_vals , " %u " ) ) ;
new_gai - > comment = g_strdup_printf ( " RTP Num packets:%d Duration:%d.%03ds ssrc:%d " , strinfo - > npackets , duration / 1000000 , ( duration % 1000000 ) / 1000 , strinfo - > ssrc ) ;
new_gai - > conv_num = conv_num ;
new_gai - > display = FALSE ;
new_gai - > line_style = 2 ; /* the arrow line will be 2 pixels width */
the_tapinfo_struct . graph_analysis - > list = g_list_insert ( the_tapinfo_struct . graph_analysis - > list , new_gai , item ) ;
break ;
}
voip_calls_graph_list = g_list_next ( voip_calls_graph_list ) ;
item + + ;
}
break ;
}
voip_calls_graph_list = g_list_next ( voip_calls_graph_list ) ;
item + + ;
}
strinfo_list = g_list_next ( strinfo_list ) ;
}
}
/****************************************************************************/
/* Add a new item into the graph */
int add_to_graph ( voip_calls_tapinfo_t * tapinfo _U_ , packet_info * pinfo , gchar * frame_label , gchar * comment , guint16 call_num )
{
graph_analysis_item_t * gai ;
gai = g_malloc ( sizeof ( graph_analysis_item_t ) ) ;
gai - > frame_num = pinfo - > fd - > num ;
gai - > time = ( double ) pinfo - > fd - > rel_secs + ( double ) pinfo - > fd - > rel_usecs / 1000000 ;
g_memmove ( & gai - > ip_src , pinfo - > src . data , 4 ) ;
g_memmove ( & gai - > ip_dst , pinfo - > dst . data , 4 ) ;
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 = 1 ;
gai - > display = FALSE ;
tapinfo - > graph_analysis - > list = g_list_append ( tapinfo - > graph_analysis - > list , gai ) ;
return 1 ;
}
/****************************************************************************/
/* Append str to frame_label and comment in a graph item */
/* return 0 if the frame_num is not in the graph list */
2005-02-02 01:02:09 +00:00
int append_to_frame_graph ( voip_calls_tapinfo_t * tapinfo _U_ , guint32 frame_num , const gchar * new_frame_label , const gchar * new_comment )
2005-02-01 12:12:35 +00:00
{
graph_analysis_item_t * gai ;
GList * list ;
gchar * tmp_str = NULL ;
gchar * tmp_str2 = NULL ;
list = g_list_first ( tapinfo - > graph_analysis - > list ) ;
while ( list )
{
gai = list - > data ;
if ( gai - > frame_num = = frame_num ) {
tmp_str = gai - > frame_label ;
tmp_str2 = gai - > comment ;
if ( new_frame_label ! = NULL ) {
gai - > frame_label = g_strdup_printf ( " %s %s " , gai - > frame_label , new_frame_label ) ;
g_free ( tmp_str ) ;
}
if ( new_comment ! = NULL ) {
gai - > comment = g_strdup_printf ( " %s %s " , gai - > comment , new_comment ) ;
g_free ( tmp_str2 ) ;
}
break ;
}
list = g_list_next ( list ) ;
}
if ( tmp_str = = NULL ) return 0 ; /* it is not in the list */
return 1 ;
}
/****************************************************************************/
/* ***************************TAP for SIP **********************************/
/****************************************************************************/
/****************************************************************************/
/* whenever a SIP packet is seen by the tap listener */
2005-02-02 01:02:09 +00:00
static int
SIPcalls_packet ( void * ptr _U_ , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * SIPinfo )
2005-02-01 12:12:35 +00:00
{
2005-02-02 01:02:09 +00:00
voip_calls_tapinfo_t * tapinfo = & the_tapinfo_struct ;
2005-02-01 12:12:35 +00:00
/* 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 * tmp_listinfo ;
voip_calls_info_t * strinfo = NULL ;
sip_calls_info_t * tmp_sipinfo ;
GList * list ;
guint32 tmp_src , tmp_dst ;
gchar * frame_label = NULL ;
gchar * comment = NULL ;
2005-02-02 01:02:09 +00:00
const sip_info_value_t * pi = SIPinfo ;
2005-02-01 12:12:35 +00:00
/* do not consider packets without call_id */
if ( pi - > tap_call_id = = NULL ) {
return 0 ;
}
/* check wether we already have a call with these parameters in the list */
list = g_list_first ( tapinfo - > strinfo_list ) ;
while ( list )
{
tmp_listinfo = list - > data ;
if ( tmp_listinfo - > protocol = = VOIP_SIP ) {
tmp_sipinfo = tmp_listinfo - > prot_info ;
if ( strcmp ( tmp_sipinfo - > call_identifier , pi - > tap_call_id ) = = 0 ) {
strinfo = ( 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 INVITE -i.e. if this session is a call*/
if ( ( strinfo = = NULL ) & & ( pi - > request_method ! = NULL ) ) {
if ( strcmp ( pi - > request_method , " INVITE " ) = = 0 ) {
strinfo = g_malloc ( sizeof ( voip_calls_info_t ) ) ;
strinfo - > call_active_state = VOIP_ACTIVE ;
strinfo - > call_state = VOIP_CALL_SETUP ;
strinfo - > from_identity = g_strdup ( pi - > tap_from_addr ) ;
strinfo - > to_identity = g_strdup ( pi - > tap_to_addr ) ;
g_memmove ( & ( strinfo - > initial_speaker ) , pinfo - > src . data , 4 ) ;
strinfo - > first_frame_num = pinfo - > fd - > num ;
strinfo - > selected = FALSE ;
strinfo - > start_sec = pinfo - > fd - > rel_secs ;
strinfo - > start_usec = pinfo - > fd - > rel_usecs ;
strinfo - > protocol = VOIP_SIP ;
strinfo - > prot_info = g_malloc ( sizeof ( sip_calls_info_t ) ) ;
tmp_sipinfo = strinfo - > prot_info ;
tmp_sipinfo - > call_identifier = strdup ( pi - > tap_call_id ) ;
tmp_sipinfo - > sip_state = SIP_INVITE_SENT ;
tmp_sipinfo - > invite_cseq = pi - > tap_cseq_number ;
strinfo - > npackets = 0 ;
strinfo - > call_num = tapinfo - > ncalls + + ;
tapinfo - > strinfo_list = g_list_append ( tapinfo - > strinfo_list , strinfo ) ;
}
}
g_free ( pi - > tap_from_addr ) ;
g_free ( pi - > tap_to_addr ) ;
g_free ( pi - > tap_call_id ) ;
if ( strinfo ! = NULL ) {
/* let's analyze the call state */
g_memmove ( & ( tmp_src ) , pinfo - > src . data , 4 ) ;
g_memmove ( & ( tmp_dst ) , pinfo - > dst . data , 4 ) ;
if ( pi - > request_method = = NULL ) {
frame_label = g_strdup_printf ( " %d %s " , pi - > response_code , pi - > reason_phrase ) ;
comment = g_strdup_printf ( " SIP Status " ) ;
if ( ( pi - > tap_cseq_number = = tmp_sipinfo - > invite_cseq ) & & ( tmp_dst = = strinfo - > 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 ) ) {
strinfo - > call_state = VOIP_REJECTED ;
tapinfo - > rejected_calls + + ;
}
}
}
else {
frame_label = g_strdup ( pi - > request_method ) ;
if ( ( strcmp ( pi - > request_method , " INVITE " ) = = 0 ) & & ( tmp_src = = strinfo - > initial_speaker ) ) {
tmp_sipinfo - > invite_cseq = pi - > tap_cseq_number ;
comment = g_strdup_printf ( " SIP From: %s To:%s " , strinfo - > from_identity , strinfo - > to_identity ) ;
}
else if ( ( strcmp ( pi - > request_method , " ACK " ) = = 0 ) & & ( pi - > tap_cseq_number = = tmp_sipinfo - > invite_cseq )
& & ( tmp_src = = strinfo - > initial_speaker ) & & ( tmp_sipinfo - > sip_state = = SIP_200_REC ) ) {
strinfo - > call_state = VOIP_IN_CALL ;
comment = g_strdup_printf ( " SIP Request " ) ;
}
else if ( strcmp ( pi - > request_method , " BYE " ) = = 0 ) {
strinfo - > call_state = VOIP_COMPLETED ;
tapinfo - > completed_calls + + ;
comment = g_strdup_printf ( " SIP Request " ) ;
}
else if ( ( strcmp ( pi - > request_method , " CANCEL " ) = = 0 ) & & ( pi - > tap_cseq_number = = tmp_sipinfo - > invite_cseq )
& & ( tmp_src = = strinfo - > initial_speaker ) & & ( strinfo - > call_state = = VOIP_CALL_SETUP ) ) {
strinfo - > call_state = VOIP_CANCELLED ;
tmp_sipinfo - > sip_state = SIP_CANCEL_SENT ;
comment = g_strdup_printf ( " SIP Request " ) ;
} else {
comment = g_strdup_printf ( " SIP Request " ) ;
}
}
strinfo - > stop_sec = pinfo - > fd - > rel_secs ;
strinfo - > stop_usec = pinfo - > fd - > rel_usecs ;
strinfo - > last_frame_num = pinfo - > fd - > num ;
+ + ( strinfo - > npackets ) ;
/* increment the packets counter of all calls */
+ + ( tapinfo - > npackets ) ;
/* add to the graph */
add_to_graph ( tapinfo , pinfo , frame_label , comment , strinfo - > call_num ) ;
g_free ( comment ) ;
g_free ( frame_label ) ;
}
return 1 ; /* refresh output */
}
/****************************************************************************/
const voip_calls_tapinfo_t * voip_calls_get_info ( void )
{
return & the_tapinfo_struct ;
}
/****************************************************************************/
/* TAP INTERFACE */
/****************************************************************************/
static gboolean have_SIP_tap_listener = FALSE ;
/****************************************************************************/
void
sip_calls_init_tap ( void )
{
GString * error_string ;
if ( have_SIP_tap_listener = = FALSE )
{
/* don't register tap listener, if we have it already */
2005-02-02 01:02:09 +00:00
error_string = register_tap_listener ( " sip " , & ( the_tapinfo_struct . sip_dummy ) , NULL ,
voip_calls_dlg_reset ,
SIPcalls_packet ,
voip_calls_dlg_draw
) ;
2005-02-01 12:12:35 +00:00
if ( error_string ! = NULL ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK ,
error_string - > str ) ;
g_string_free ( error_string , TRUE ) ;
exit ( 1 ) ;
}
have_SIP_tap_listener = TRUE ;
}
}
/* XXX just copied from gtk/rpc_stat.c */
void protect_thread_critical_region ( void ) ;
void unprotect_thread_critical_region ( void ) ;
/****************************************************************************/
void
remove_tap_listener_sip_calls ( void )
{
protect_thread_critical_region ( ) ;
2005-02-02 01:02:09 +00:00
remove_tap_listener ( & ( the_tapinfo_struct . sip_dummy ) ) ;
2005-02-01 12:12:35 +00:00
unprotect_thread_critical_region ( ) ;
have_SIP_tap_listener = FALSE ;
}
/****************************************************************************/
/* ***************************TAP for ISUP **********************************/
/****************************************************************************/
static gchar isup_called_number [ 255 ] , isup_calling_number [ 255 ] ;
static guint16 isup_cic ;
static guint8 isup_message_type ;
2005-02-03 21:50:19 +00:00
static guint8 isup_cause_value ;
2005-02-01 12:12:35 +00:00
/****************************************************************************/
/* whenever a isup_ packet is seen by the tap listener */
2005-02-02 01:02:09 +00:00
static int
isup_calls_packet ( void * ptr _U_ , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * isup_info _U_ )
2005-02-01 12:12:35 +00:00
{
2005-02-02 01:02:09 +00:00
voip_calls_tapinfo_t * tapinfo = & the_tapinfo_struct ;
const isup_tap_rec_t * pi = isup_info ;
2005-02-01 12:12:35 +00:00
if ( pi - > calling_number ! = NULL ) {
strcpy ( isup_calling_number , pi - > calling_number ) ;
}
if ( pi - > called_number ! = NULL ) {
strcpy ( isup_called_number , pi - > called_number ) ;
}
isup_message_type = pi - > message_type ;
2005-02-03 21:50:19 +00:00
isup_cause_value = pi - > cause_value ;
2005-02-01 12:12:35 +00:00
isup_cic = pinfo - > circuit_id ;
return 0 ;
}
/****************************************************************************/
static gboolean have_isup_tap_listener = FALSE ;
void
isup_calls_init_tap ( void )
{
GString * error_string ;
if ( have_isup_tap_listener = = FALSE )
{
2005-02-02 01:02:09 +00:00
error_string = register_tap_listener ( " isup " , & ( the_tapinfo_struct . isup_dummy ) ,
2005-02-01 12:12:35 +00:00
NULL ,
2005-02-02 01:02:09 +00:00
voip_calls_dlg_reset ,
isup_calls_packet ,
voip_calls_dlg_draw
) ;
2005-02-01 12:12:35 +00:00
if ( error_string ! = NULL ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK ,
error_string - > str ) ;
g_string_free ( error_string , TRUE ) ;
exit ( 1 ) ;
}
have_isup_tap_listener = TRUE ;
}
}
/****************************************************************************/
void
remove_tap_listener_isup_calls ( void )
{
protect_thread_critical_region ( ) ;
2005-02-02 01:02:09 +00:00
remove_tap_listener ( & ( the_tapinfo_struct . isup_dummy ) ) ;
2005-02-01 12:12:35 +00:00
unprotect_thread_critical_region ( ) ;
have_isup_tap_listener = FALSE ;
}
/****************************************************************************/
/* ***************************TAP for MTP3 **********************************/
/****************************************************************************/
/****************************************************************************/
/* whenever a mtp3_ packet is seen by the tap listener */
2005-02-02 01:02:09 +00:00
static int
mtp3_calls_packet ( void * ptr _U_ , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * mtp3_info _U_ )
2005-02-01 12:12:35 +00:00
{
2005-02-02 01:02:09 +00:00
voip_calls_tapinfo_t * tapinfo = & the_tapinfo_struct ;
2005-02-01 12:12:35 +00:00
voip_calls_info_t * tmp_listinfo ;
voip_calls_info_t * strinfo = NULL ;
isup_calls_info_t * tmp_isupinfo ;
gboolean found = FALSE ;
gboolean forward ;
gboolean right_pair = TRUE ;
GList * list ;
2005-02-03 21:50:19 +00:00
gchar * frame_label = NULL ;
gchar * comment = NULL ;
int i ;
2005-02-01 12:12:35 +00:00
2005-02-02 01:02:09 +00:00
const mtp3_tap_rec_t * pi = mtp3_info ;
2005-02-01 12:12:35 +00:00
/* check wether we already have a call with these parameters in the list */
list = g_list_first ( tapinfo - > strinfo_list ) ;
while ( list )
{
tmp_listinfo = list - > data ;
if ( ( tmp_listinfo - > protocol = = VOIP_ISUP ) & & ( tmp_listinfo - > call_active_state = = VOIP_ACTIVE ) ) {
tmp_isupinfo = tmp_listinfo - > prot_info ;
if ( ( tmp_isupinfo - > cic = = isup_cic ) & & ( tmp_isupinfo - > ni = = pi - > addr_opc . ni ) ) {
if ( ( tmp_isupinfo - > opc = = pi - > addr_opc . pc ) & & ( tmp_isupinfo - > dpc = = pi - > addr_dpc . pc ) ) {
forward = TRUE ;
}
else if ( ( tmp_isupinfo - > dpc = = pi - > addr_opc . pc ) & & ( tmp_isupinfo - > opc = = pi - > addr_dpc . pc ) ) {
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 ( isup_message_type ! = 1 ) {
found = TRUE ;
}
else {
tmp_listinfo - > call_active_state = VOIP_INACTIVE ;
}
}
if ( found ) {
strinfo = ( 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 ( ( strinfo = = NULL ) & & ( isup_message_type = = 1 ) ) {
strinfo = g_malloc ( sizeof ( voip_calls_info_t ) ) ;
strinfo - > call_active_state = VOIP_ACTIVE ;
strinfo - > call_state = VOIP_UNKNOWN ;
g_memmove ( & ( strinfo - > initial_speaker ) , pinfo - > src . data , 4 ) ;
strinfo - > selected = FALSE ;
strinfo - > first_frame_num = pinfo - > fd - > num ;
strinfo - > start_sec = pinfo - > fd - > rel_secs ;
strinfo - > start_usec = pinfo - > fd - > rel_usecs ;
strinfo - > protocol = VOIP_ISUP ;
strinfo - > from_identity = g_strdup ( isup_calling_number ) ;
strinfo - > to_identity = g_strdup ( isup_called_number ) ;
strinfo - > prot_info = g_malloc ( sizeof ( isup_calls_info_t ) ) ;
tmp_isupinfo = strinfo - > prot_info ;
tmp_isupinfo - > opc = pi - > addr_opc . pc ;
tmp_isupinfo - > dpc = pi - > addr_dpc . pc ;
tmp_isupinfo - > ni = pi - > addr_opc . ni ;
tmp_isupinfo - > cic = pinfo - > circuit_id ;
strinfo - > npackets = 0 ;
strinfo - > call_num = tapinfo - > ncalls + + ;
tapinfo - > strinfo_list = g_list_append ( tapinfo - > strinfo_list , strinfo ) ;
}
if ( strinfo ! = NULL ) {
strinfo - > stop_sec = pinfo - > fd - > rel_secs ;
strinfo - > stop_usec = pinfo - > fd - > rel_usecs ;
strinfo - > last_frame_num = pinfo - > fd - > num ;
+ + ( strinfo - > npackets ) ;
/* Let's analyze the call state */
2005-02-03 21:50:19 +00:00
for ( i = 0 ; ( isup_message_type_value [ i ] . strptr ! = NULL ) & & ( isup_message_type_value [ i ] . value ! = isup_message_type ) ; i + + ) ;
if ( isup_message_type_value [ i ] . value = = isup_message_type ) {
frame_label = g_strdup ( isup_message_type_value_acro [ i ] . strptr ) ;
}
else {
frame_label = g_strdup_printf ( " Unknown " ) ;
}
if ( strinfo - > npackets = = 1 ) { /* this is the first packet, that must be an IAM */
comment = g_strdup_printf ( " Call from %s to %s " ,
isup_calling_number , isup_called_number ) ;
}
else if ( strinfo - > npackets = = 2 ) { /* in the second packet we show the SPs */
if ( forward ) {
comment = g_strdup_printf ( " %i-%i -> %i-%i. Cic:%i " ,
pi - > addr_opc . ni , pi - > addr_opc . pc ,
pi - > addr_opc . ni , pi - > addr_dpc . pc , pinfo - > circuit_id ) ;
}
else {
comment = g_strdup_printf ( " %i-%i -> %i-%i. Cic:%i " ,
pi - > addr_opc . ni , pi - > addr_dpc . pc ,
pi - > addr_opc . ni , pi - > addr_opc . pc , pinfo - > circuit_id ) ;
}
}
2005-02-01 12:12:35 +00:00
switch ( isup_message_type ) {
case 1 : /* IAM */
strinfo - > call_state = VOIP_CALL_SETUP ;
break ;
case 7 : /* CONNECT */
case 9 : /* ANSWER */
strinfo - > call_state = VOIP_IN_CALL ;
break ;
case 12 : /* RELEASE */
if ( strinfo - > call_state = = VOIP_CALL_SETUP ) {
if ( forward ) {
strinfo - > call_state = VOIP_CANCELLED ;
}
else {
strinfo - > call_state = VOIP_REJECTED ;
tapinfo - > rejected_calls + + ;
}
}
else if ( strinfo - > call_state = = VOIP_IN_CALL ) {
strinfo - > call_state = VOIP_COMPLETED ;
tapinfo - > completed_calls + + ;
}
2005-02-03 21:50:19 +00:00
for ( i = 0 ; ( q931_cause_code_vals [ i ] . strptr ! = NULL ) & & ( q931_cause_code_vals [ i ] . value ! = isup_cause_value ) ; i + + ) ;
if ( q931_cause_code_vals [ i ] . value = = isup_cause_value ) {
comment = g_strdup_printf ( " Cause %i - %s " , isup_cause_value , q931_cause_code_vals [ i ] . strptr ) ;
}
else {
comment = g_strdup_printf ( " Cause %i " , isup_cause_value ) ;
}
2005-02-01 12:12:35 +00:00
break ;
}
/* increment the packets counter of all calls */
+ + ( tapinfo - > npackets ) ;
2005-02-03 21:50:19 +00:00
/* add to the graph */
add_to_graph ( tapinfo , pinfo , frame_label , comment , strinfo - > call_num ) ;
g_free ( comment ) ;
g_free ( frame_label ) ;
2005-02-01 12:12:35 +00:00
}
return 1 ;
}
/****************************************************************************/
static gboolean have_mtp3_tap_listener = FALSE ;
void
mtp3_calls_init_tap ( void )
{
GString * error_string ;
if ( have_mtp3_tap_listener = = FALSE )
{
2005-02-02 01:02:09 +00:00
error_string = register_tap_listener ( " mtp3 " , & ( the_tapinfo_struct . mtp3_dummy ) ,
2005-02-01 12:12:35 +00:00
NULL ,
2005-02-02 01:02:09 +00:00
voip_calls_dlg_reset ,
mtp3_calls_packet ,
voip_calls_dlg_draw
) ;
2005-02-01 12:12:35 +00:00
if ( error_string ! = NULL ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK ,
error_string - > str ) ;
g_string_free ( error_string , TRUE ) ;
exit ( 1 ) ;
}
have_mtp3_tap_listener = TRUE ;
}
}
/****************************************************************************/
void
remove_tap_listener_mtp3_calls ( void )
{
protect_thread_critical_region ( ) ;
2005-02-02 01:02:09 +00:00
remove_tap_listener ( & ( the_tapinfo_struct . mtp3_dummy ) ) ;
2005-02-01 12:12:35 +00:00
unprotect_thread_critical_region ( ) ;
have_mtp3_tap_listener = FALSE ;
}
/****************************************************************************/
/* ***************************TAP for Q931 **********************************/
/****************************************************************************/
static gchar * q931_calling_number ;
static gchar * q931_called_number ;
static guint8 q931_cause_value ;
static gint32 q931_crv ;
static guint32 q931_frame_num ;
/****************************************************************************/
/* whenever a q931_ packet is seen by the tap listener */
2005-02-02 01:02:09 +00:00
static int
q931_calls_packet ( void * ptr _U_ , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * q931_info _U_ )
2005-02-01 12:12:35 +00:00
{
2005-02-02 01:02:09 +00:00
voip_calls_tapinfo_t * tapinfo = & the_tapinfo_struct ;
const q931_packet_info * pi = q931_info ;
2005-02-01 12:12:35 +00:00
/* free previously allocated q931_calling/ed_number */
g_free ( q931_calling_number ) ;
g_free ( q931_called_number ) ;
if ( pi - > calling_number ! = NULL )
q931_calling_number = g_strdup ( pi - > calling_number ) ;
else
q931_calling_number = g_strdup ( " " ) ;
if ( pi - > called_number ! = NULL )
q931_called_number = g_strdup ( pi - > called_number ) ;
else
q931_called_number = g_strdup ( " " ) ;
q931_cause_value = pi - > cause_value ;
q931_frame_num = pinfo - > fd - > num ;
q931_crv = pi - > crv ;
return 0 ;
}
/****************************************************************************/
static gboolean have_q931_tap_listener = FALSE ;
void
q931_calls_init_tap ( void )
{
GString * error_string ;
if ( have_q931_tap_listener = = FALSE )
{
2005-02-02 01:02:09 +00:00
error_string = register_tap_listener ( " q931 " , & ( the_tapinfo_struct . q931_dummy ) ,
2005-02-01 12:12:35 +00:00
NULL ,
2005-02-02 01:02:09 +00:00
voip_calls_dlg_reset ,
q931_calls_packet ,
voip_calls_dlg_draw
) ;
2005-02-01 12:12:35 +00:00
if ( error_string ! = NULL ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK ,
error_string - > str ) ;
g_string_free ( error_string , TRUE ) ;
exit ( 1 ) ;
}
have_q931_tap_listener = TRUE ;
}
}
/****************************************************************************/
void
remove_tap_listener_q931_calls ( void )
{
protect_thread_critical_region ( ) ;
2005-02-02 01:02:09 +00:00
remove_tap_listener ( & ( the_tapinfo_struct . q931_dummy ) ) ;
2005-02-01 12:12:35 +00:00
unprotect_thread_critical_region ( ) ;
have_q931_tap_listener = FALSE ;
}
/****************************************************************************/
/****************************TAP for H323 ***********************************/
/****************************************************************************/
# define GUID_LEN 16
static const guint8 guid_allzero [ GUID_LEN ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
/* defines specific H323 data */
void add_h245_Address ( h323_calls_info_t * h323info , guint32 h245_address , guint16 h245_port )
{
h245_address_t * h245_add = NULL ;
h245_add = g_malloc ( sizeof ( h245_address_t ) ) ;
h245_add - > h245_address = h245_address ;
h245_add - > h245_port = h245_port ;
h323info - > h245_list = g_list_append ( h323info - > h245_list , h245_add ) ;
}
/****************************************************************************/
/* whenever a H225 packet is seen by the tap listener */
2005-02-02 01:02:09 +00:00
static int
H225calls_packet ( void * ptr _U_ , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * H225info )
2005-02-01 12:12:35 +00:00
{
2005-02-02 01:02:09 +00:00
voip_calls_tapinfo_t * tapinfo = & the_tapinfo_struct ;
2005-02-01 12:12:35 +00:00
voip_calls_info_t * tmp_listinfo ;
voip_calls_info_t * strinfo = NULL ;
h323_calls_info_t * tmp_h323info ;
gchar * frame_label ;
gchar * comment ;
GList * list ;
guint32 tmp_src , tmp_dst ;
2005-02-02 01:02:09 +00:00
const h225_packet_info * pi = H225info ;
2005-02-01 12:12:35 +00:00
/* if not guid and RAS return because did not belong to a call */
if ( ( memcmp ( pi - > guid , guid_allzero , GUID_LEN ) = = 0 ) & & ( pi - > msg_type = = H225_RAS ) )
return 0 ;
if ( ( memcmp ( pi - > guid , guid_allzero , GUID_LEN ) = = 0 ) & & ( q931_frame_num = = pinfo - > fd - > num ) ) {
/* check wether we already have a call with this Q931 CRV */
list = g_list_first ( tapinfo - > strinfo_list ) ;
while ( list )
{
tmp_listinfo = list - > data ;
if ( tmp_listinfo - > protocol = = VOIP_H323 ) {
tmp_h323info = tmp_listinfo - > prot_info ;
if ( ( ( tmp_h323info - > q931_crv = = q931_crv ) | | ( tmp_h323info - > q931_crv2 = = q931_crv ) ) & & ( q931_crv ! = - 1 ) ) {
strinfo = ( voip_calls_info_t * ) ( list - > data ) ;
break ;
}
}
list = g_list_next ( list ) ;
}
if ( strinfo = = NULL ) return 0 ;
} else {
/* check wether we already have a call with this guid in the list */
list = g_list_first ( tapinfo - > strinfo_list ) ;
while ( list )
{
tmp_listinfo = list - > data ;
if ( tmp_listinfo - > protocol = = VOIP_H323 ) {
tmp_h323info = tmp_listinfo - > prot_info ;
if ( memcmp ( tmp_h323info - > guid , pi - > guid , GUID_LEN ) = = 0 ) {
strinfo = ( voip_calls_info_t * ) ( list - > data ) ;
break ;
}
}
list = g_list_next ( list ) ;
}
}
/* not in the list? then create a new entry */
if ( ( strinfo = = NULL ) ) {
strinfo = g_malloc ( sizeof ( voip_calls_info_t ) ) ;
strinfo - > call_active_state = VOIP_ACTIVE ;
strinfo - > call_state = VOIP_UNKNOWN ;
strinfo - > from_identity = g_strdup ( " " ) ;
strinfo - > to_identity = g_strdup ( " " ) ;
g_memmove ( & ( strinfo - > initial_speaker ) , pinfo - > src . data , 4 ) ;
strinfo - > selected = FALSE ;
strinfo - > first_frame_num = pinfo - > fd - > num ;
strinfo - > start_sec = pinfo - > fd - > rel_secs ;
strinfo - > start_usec = pinfo - > fd - > rel_usecs ;
strinfo - > protocol = VOIP_H323 ;
strinfo - > prot_info = g_malloc ( sizeof ( h323_calls_info_t ) ) ;
tmp_h323info = strinfo - > prot_info ;
tmp_h323info - > guid = ( guint8 * ) g_memdup ( pi - > guid , GUID_LEN ) ;
tmp_h323info - > h225SetupAddr = 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 ;
strinfo - > call_num = tapinfo - > ncalls + + ;
strinfo - > npackets = 0 ;
tapinfo - > strinfo_list = g_list_append ( tapinfo - > strinfo_list , strinfo ) ;
}
if ( strinfo ! = NULL ) {
/* let's analyze the call state */
g_memmove ( & ( tmp_src ) , pinfo - > src . data , 4 ) ;
g_memmove ( & ( tmp_dst ) , pinfo - > dst . data , 4 ) ;
strinfo - > stop_sec = pinfo - > fd - > rel_secs ;
strinfo - > stop_usec = pinfo - > fd - > rel_usecs ;
strinfo - > last_frame_num = pinfo - > fd - > num ;
+ + ( strinfo - > npackets ) ;
/* increment the packets counter of all calls */
+ + ( tapinfo - > npackets ) ;
/* change the status */
if ( pi - > msg_type = = H225_CS ) {
if ( tmp_h323info - > q931_crv = = - 1 ) {
tmp_h323info - > q931_crv = q931_crv ;
} else if ( tmp_h323info - > q931_crv ! = q931_crv ) {
tmp_h323info - > q931_crv2 = q931_crv ;
}
if ( pi - > is_h245 = = TRUE ) {
add_h245_Address ( tmp_h323info , pi - > h245_address , pi - > h245_port ) ;
}
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 te calling and called number from the Q931 packet */
if ( q931_frame_num = = pinfo - > fd - > num ) {
if ( q931_calling_number ! = NULL ) {
g_free ( strinfo - > from_identity ) ;
strinfo - > from_identity = g_strdup ( q931_calling_number ) ;
}
if ( q931_called_number ! = NULL ) {
g_free ( strinfo - > to_identity ) ;
strinfo - > to_identity = g_strdup ( q931_called_number ) ;
}
}
if ( tmp_h323info - > h225SetupAddr = = 0 ) g_memmove ( & ( tmp_h323info - > h225SetupAddr ) , pinfo - > src . data , 4 ) ;
strinfo - > call_state = VOIP_CALL_SETUP ;
comment = g_strdup_printf ( " H225 From: %s To:%s TunnH245:%s FS:%s " , strinfo - > from_identity , strinfo - > to_identity , ( tmp_h323info - > is_h245Tunneling = = TRUE ? " on " : " off " ) ,
( pi - > is_faststart = = TRUE ? " on " : " off " ) ) ;
break ;
case H225_CONNECT :
strinfo - > 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 :
g_memmove ( & ( tmp_src ) , pinfo - > src . data , 4 ) ;
if ( strinfo - > call_state = = VOIP_CALL_SETUP ) {
if ( tmp_h323info - > h225SetupAddr = = tmp_src ) { /* forward direction */
strinfo - > call_state = VOIP_CANCELLED ;
}
else { /* reverse */
strinfo - > call_state = VOIP_REJECTED ;
tapinfo - > rejected_calls + + ;
}
}
else if ( strinfo - > call_state = = VOIP_IN_CALL ) {
strinfo - > call_state = VOIP_COMPLETED ;
tapinfo - > completed_calls + + ;
}
/* get the Q931 Release cause code */
2005-02-02 08:08:53 +00:00
if ( q931_frame_num = = pinfo - > fd - > num & &
q931_cause_value ! = 0xFF ) {
comment = g_strdup_printf ( " H225 Q931 Rel Cause (%i):%s " , q931_cause_value , val_to_str ( q931_cause_value , q931_cause_code_vals , " <unknown> " ) ) ;
} else { /* Cause not set */
comment = g_strdup ( " H225 No Q931 Rel Cause " ) ;
2005-02-01 12:12:35 +00:00
}
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 ) {
frame_label = g_strdup_printf ( " %s " , val_to_str ( pi - > msg_tag , RasMessage_vals , " <unknown> " ) ) ;
comment = g_strdup ( " H225 RAS " ) ;
} else {
frame_label = g_strdup ( " H225: Unknown " ) ;
comment = g_strdup ( " " ) ;
}
/* add to graph analysis */
if ( ! append_to_frame_graph ( tapinfo , pinfo - > fd - > num , pi - > frame_label , comment ) ) /* if the frame number exists in graph, append to it*/
add_to_graph ( tapinfo , pinfo , frame_label , comment , strinfo - > call_num ) ; /* if not exist, add to the graph */
g_free ( frame_label ) ;
g_free ( comment ) ;
}
return 1 ; /* refresh output */
}
/****************************************************************************/
/* TAP INTERFACE */
/****************************************************************************/
static gboolean have_H225_tap_listener = FALSE ;
/****************************************************************************/
void
h225_calls_init_tap ( void )
{
GString * error_string ;
if ( have_H225_tap_listener = = FALSE )
{
/* don't register tap listener, if we have it already */
2005-02-02 01:02:09 +00:00
error_string = register_tap_listener ( " h225 " , & ( the_tapinfo_struct . h225_dummy ) , NULL ,
voip_calls_dlg_reset ,
H225calls_packet ,
voip_calls_dlg_draw
) ;
2005-02-01 12:12:35 +00:00
if ( error_string ! = NULL ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK ,
error_string - > str ) ;
g_string_free ( error_string , TRUE ) ;
exit ( 1 ) ;
}
have_H225_tap_listener = TRUE ;
}
}
/* XXX just copied from gtk/rpc_stat.c */
void protect_thread_critical_region ( void ) ;
void unprotect_thread_critical_region ( void ) ;
/****************************************************************************/
void
remove_tap_listener_h225_calls ( void )
{
protect_thread_critical_region ( ) ;
2005-02-02 01:02:09 +00:00
remove_tap_listener ( & ( the_tapinfo_struct . h225_dummy ) ) ;
2005-02-01 12:12:35 +00:00
unprotect_thread_critical_region ( ) ;
have_H225_tap_listener = FALSE ;
}
/****************************************************************************/
/* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
2005-02-02 01:02:09 +00:00
static int
H245dgcalls_packet ( void * ptr _U_ , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * H245info )
2005-02-01 12:12:35 +00:00
{
2005-02-02 01:02:09 +00:00
voip_calls_tapinfo_t * tapinfo = & the_tapinfo_struct ;
2005-02-01 12:12:35 +00:00
voip_calls_info_t * tmp_listinfo ;
voip_calls_info_t * strinfo = NULL ;
h323_calls_info_t * tmp_h323info ;
gchar * frame_label ;
gchar * comment ;
GList * list ;
GList * list2 ;
guint32 tmp_src , tmp_dst ;
h245_address_t * h245_add = NULL ;
2005-02-02 01:02:09 +00:00
const h245_packet_info * pi = H245info ;
2005-02-01 12:12:35 +00:00
/* if H245 tunneling is on, append to graph */
if ( append_to_frame_graph ( tapinfo , pinfo - > fd - > num , pi - > frame_label , pi - > comment ) ) return 1 ;
/* it is not Tunneling or it is not in the list. So check if there is no tunneling
and there is a call with this H245 address */
list = g_list_first ( tapinfo - > strinfo_list ) ;
while ( list )
{
tmp_listinfo = list - > data ;
if ( tmp_listinfo - > protocol = = VOIP_H323 ) {
tmp_h323info = tmp_listinfo - > prot_info ;
g_memmove ( & ( tmp_src ) , pinfo - > src . data , 4 ) ;
g_memmove ( & ( tmp_dst ) , pinfo - > dst . data , 4 ) ;
list2 = g_list_first ( tmp_h323info - > h245_list ) ;
while ( list2 )
{
h245_add = list2 - > data ;
if ( ( ( h245_add - > h245_address = = tmp_src ) & & ( h245_add - > h245_port = = pinfo - > srcport ) )
| | ( ( h245_add - > h245_address = = tmp_dst ) & & ( h245_add - > h245_port = = pinfo - > destport ) ) ) {
strinfo = ( voip_calls_info_t * ) ( list - > data ) ;
+ + ( strinfo - > npackets ) ;
/* increment the packets counter of all calls */
+ + ( tapinfo - > npackets ) ;
break ;
}
list2 = g_list_next ( list2 ) ;
}
if ( strinfo ! = NULL ) break ;
}
list = g_list_next ( list ) ;
}
if ( strinfo ! = NULL ) {
frame_label = g_strdup ( pi - > frame_label ) ;
comment = g_strdup ( pi - > comment ) ;
add_to_graph ( tapinfo , pinfo , frame_label , comment , strinfo - > call_num ) ;
g_free ( frame_label ) ;
g_free ( comment ) ;
}
return 1 ; /* refresh output */
}
/****************************************************************************/
/* TAP INTERFACE */
/****************************************************************************/
static gboolean have_H245dg_tap_listener = FALSE ;
/****************************************************************************/
void
h245dg_calls_init_tap ( void )
{
GString * error_string ;
if ( have_H245dg_tap_listener = = FALSE )
{
/* don't register tap listener, if we have it already */
2005-02-02 01:02:09 +00:00
error_string = register_tap_listener ( " h245dg " , & ( the_tapinfo_struct . h245dg_dummy ) , NULL ,
voip_calls_dlg_reset ,
H245dgcalls_packet ,
voip_calls_dlg_draw
) ;
2005-02-01 12:12:35 +00:00
if ( error_string ! = NULL ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK ,
error_string - > str ) ;
g_string_free ( error_string , TRUE ) ;
exit ( 1 ) ;
}
have_H245dg_tap_listener = TRUE ;
}
}
/* XXX just copied from gtk/rpc_stat.c */
void protect_thread_critical_region ( void ) ;
void unprotect_thread_critical_region ( void ) ;
/****************************************************************************/
void
remove_tap_listener_h245dg_calls ( void )
{
protect_thread_critical_region ( ) ;
2005-02-02 01:02:09 +00:00
remove_tap_listener ( & ( the_tapinfo_struct . h245dg_dummy ) ) ;
2005-02-01 12:12:35 +00:00
unprotect_thread_critical_region ( ) ;
have_H245dg_tap_listener = FALSE ;
}
/****************************************************************************/
/****************************TAP for SDP PROTOCOL ***************************/
/****************************************************************************/
/* whenever a SDP packet is seen by the tap listener */
2005-02-02 01:02:09 +00:00
static int
SDPcalls_packet ( void * ptr _U_ , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * SDPinfo )
2005-02-01 12:12:35 +00:00
{
2005-02-02 01:02:09 +00:00
voip_calls_tapinfo_t * tapinfo = & the_tapinfo_struct ;
const sdp_packet_info * pi = SDPinfo ;
char summary_str [ 50 ] ;
2005-02-01 12:12:35 +00:00
/* Append to graph the SDP summary if the packet exists */
2005-02-02 01:02:09 +00:00
g_snprintf ( summary_str , 50 , " SDP (%s) " , pi - > summary_str ) ;
append_to_frame_graph ( tapinfo , pinfo - > fd - > num , summary_str , NULL ) ;
2005-02-01 12:12:35 +00:00
return 1 ; /* refresh output */
}
/****************************************************************************/
/* TAP INTERFACE */
/****************************************************************************/
static gboolean have_sdp_tap_listener = FALSE ;
/****************************************************************************/
void
sdp_calls_init_tap ( void )
{
GString * error_string ;
if ( have_sdp_tap_listener = = FALSE )
{
/* don't register tap listener, if we have it already */
2005-02-02 01:02:09 +00:00
error_string = register_tap_listener ( " sdp " , & ( the_tapinfo_struct . sdp_dummy ) , NULL ,
voip_calls_dlg_reset ,
SDPcalls_packet ,
voip_calls_dlg_draw
) ;
2005-02-01 12:12:35 +00:00
if ( error_string ! = NULL ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK ,
error_string - > str ) ;
g_string_free ( error_string , TRUE ) ;
exit ( 1 ) ;
}
have_sdp_tap_listener = TRUE ;
}
}
/* XXX just copied from gtk/rpc_stat.c */
void protect_thread_critical_region ( void ) ;
void unprotect_thread_critical_region ( void ) ;
/****************************************************************************/
void
remove_tap_listener_sdp_calls ( void )
{
protect_thread_critical_region ( ) ;
2005-02-02 01:02:09 +00:00
remove_tap_listener ( & ( the_tapinfo_struct . sdp_dummy ) ) ;
2005-02-01 12:12:35 +00:00
unprotect_thread_critical_region ( ) ;
have_sdp_tap_listener = FALSE ;
}
/****************************************************************************/
/* ***************************TAP for OTHER PROTOCOL **********************************/
/****************************************************************************/
/****************************************************************************/
/* whenever a prot_ packet is seen by the tap listener */
2005-02-02 01:02:09 +00:00
/*
static int
prot_calls_packet ( void * ptr _U_ , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * prot_info _U_ )
2005-02-01 12:12:35 +00:00
{
2005-02-02 01:02:09 +00:00
voip_calls_tapinfo_t * tapinfo = & the_tapinfo_struct ;
2005-02-01 12:12:35 +00:00
if ( strinfo ! = NULL ) {
strinfo - > stop_sec = pinfo - > fd - > rel_secs ;
strinfo - > stop_usec = pinfo - > fd - > rel_usecs ;
strinfo - > last_frame_num = pinfo - > fd - > num ;
+ + ( strinfo - > npackets ) ;
+ + ( tapinfo - > npackets ) ;
}
return 1 ;
}
*/
/****************************************************************************/
/*
static gboolean have_prot__tap_listener = FALSE ;
void
prot_calls_init_tap ( void )
{
GString * error_string ;
if ( have_prot__tap_listener = = FALSE )
{
2005-02-02 01:02:09 +00:00
error_string = register_tap_listener ( " prot_ " , & ( the_tapinfo_struct . prot__dummy ) ,
2005-02-01 12:12:35 +00:00
NULL ,
2005-02-02 01:02:09 +00:00
voip_calls_dlg_reset ,
prot__calls_packet ,
voip_calls_dlg_draw
) ;
2005-02-01 12:12:35 +00:00
if ( error_string ! = NULL ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK ,
error_string - > str ) ;
g_string_free ( error_string , TRUE ) ;
exit ( 1 ) ;
}
have_prot__tap_listener = TRUE ;
}
}
*/
/****************************************************************************/
/*
void
remove_tap_listener_prot__calls ( void )
{
protect_thread_critical_region ( ) ;
2005-02-02 01:02:09 +00:00
remove_tap_listener ( & ( the_tapinfo_struct . prot__dummy ) ) ;
2005-02-01 12:12:35 +00:00
unprotect_thread_critical_region ( ) ;
have_prot__tap_listener = FALSE ;
}
*/