2003-09-24 07:48:12 +00:00
/* rtp_stream_dlg.c
2006-05-22 07:29:40 +00:00
* RTP streams summary addition for Wireshark
2003-09-24 07:48:12 +00:00
*
2004-07-18 00:24:25 +00:00
* $ Id $
2003-09-24 07:48:12 +00:00
*
* Copyright 2003 , Alcatel Business Systems
* By Lars Ruoff < lars . ruoff @ gmx . net >
*
2006-05-21 05:12:17 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2003-09-24 07:48:12 +00:00
* 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
2008-04-13 03:32:24 +00:00
# include <string.h>
# include <locale.h>
2003-09-24 07:48:12 +00:00
2008-04-13 03:32:24 +00:00
# include <epan/rtp_pt.h>
# include <epan/address.h>
# include <epan/addr_resolv.h>
# include <epan/strutil.h>
2003-09-24 07:48:12 +00:00
# include "epan/filesystem.h"
2008-04-13 03:32:24 +00:00
# include "../globals.h"
2005-08-21 09:48:27 +00:00
# include "../stat_menu.h"
2008-04-13 03:32:24 +00:00
# include "gtk/rtp_stream_dlg.h"
# include "gtk/gui_stat_menu.h"
# include "gtk/dlg_utils.h"
# include "gtk/file_dlg.h"
# include "gtk/gui_utils.h"
# include "gtk/gtkglobals.h"
# include "gtk/rtp_stream.h"
# include "gtk/rtp_analysis.h"
2003-09-24 07:48:12 +00:00
2004-01-26 19:16:30 +00:00
# include "image/clist_ascend.xpm"
# include "image/clist_descend.xpm"
2003-09-24 07:48:12 +00:00
static const gchar FWD_LABEL_TEXT [ ] = " Select a forward stream with left mouse button " ;
static const gchar REV_LABEL_TEXT [ ] = " Select a reverse stream with SHIFT + left mouse button " ;
/****************************************************************************/
/* pointer to the one and only dialog window */
static GtkWidget * rtp_stream_dlg = NULL ;
/* save as dialog box */
static GtkWidget * rtpstream_save_dlg = NULL ;
static GtkWidget * clist = NULL ;
2004-06-30 21:17:55 +00:00
static GtkWidget * top_label = NULL ;
2003-09-24 07:48:12 +00:00
static GtkWidget * label_fwd = NULL ;
static GtkWidget * label_rev = NULL ;
static rtp_stream_info_t * selected_stream_fwd = NULL ; /* current selection */
static rtp_stream_info_t * selected_stream_rev = NULL ; /* current selection for reversed */
static GList * last_list = NULL ;
2004-06-30 21:17:55 +00:00
static guint32 streams_nb = 0 ; /* number of displayed streams */
2003-09-24 07:48:12 +00:00
2005-02-16 09:24:52 +00:00
# define NUM_COLS 12
2005-03-21 01:24:19 +00:00
static const gchar * titles [ NUM_COLS ] = { " Src IP addr " , " Src port " , " Dest IP addr " , " Dest port " , " SSRC " , " Payload " , " Packets " , " Lost " , " Max Delta (ms) " , " Max Jitter (ms) " , " Mean Jitter (ms) " , " Pb? " } ;
2005-02-16 09:24:52 +00:00
2003-09-24 07:48:12 +00:00
/****************************************************************************/
/* append a line to clist */
static void add_to_clist ( rtp_stream_info_t * strinfo )
{
2004-06-30 21:17:55 +00:00
gchar label_text [ 256 ] ;
2003-09-24 07:48:12 +00:00
gint added_row ;
2005-02-16 09:24:52 +00:00
gchar * data [ NUM_COLS ] ;
guint32 expected ;
gint32 lost ;
double perc ;
2005-02-24 05:42:03 +00:00
int i ;
2005-03-21 01:24:19 +00:00
char * savelocale ;
/* save the current locale */
savelocale = setlocale ( LC_NUMERIC , NULL ) ;
/* switch to "C" locale to avoid problems with localized decimal separators
in g_snprintf ( " %f " ) functions */
setlocale ( LC_NUMERIC , " C " ) ;
2005-02-24 05:42:03 +00:00
2005-03-02 01:24:18 +00:00
data [ 0 ] = g_strdup ( get_addr_name ( & ( strinfo - > src_addr ) ) ) ;
2005-02-24 05:42:03 +00:00
data [ 1 ] = g_strdup_printf ( " %u " , strinfo - > src_port ) ;
2005-03-02 01:24:18 +00:00
data [ 2 ] = g_strdup ( get_addr_name ( & ( strinfo - > dest_addr ) ) ) ;
2005-02-24 05:42:03 +00:00
data [ 3 ] = g_strdup_printf ( " %u " , strinfo - > dest_port ) ;
2007-05-31 18:41:25 +00:00
data [ 4 ] = g_strdup_printf ( " 0x%X " , strinfo - > ssrc ) ;
2007-04-10 18:58:18 +00:00
if ( strinfo - > pt > 95 ) {
if ( strinfo - > info_payload_type_str ! = NULL ) {
data [ 5 ] = g_strdup ( strinfo - > info_payload_type_str ) ;
} else {
data [ 5 ] = g_strdup_printf ( " Unknown(%u) " , strinfo - > pt ) ;
}
} else {
data [ 5 ] = g_strdup ( val_to_str ( strinfo - > pt , rtp_payload_type_vals ,
" Unknown (%u) " ) ) ;
}
2005-02-24 05:42:03 +00:00
data [ 6 ] = g_strdup_printf ( " %u " , strinfo - > npackets ) ;
2005-02-16 09:24:52 +00:00
expected = ( strinfo - > rtp_stats . stop_seq_nr + strinfo - > rtp_stats . cycles * 65536 )
- strinfo - > rtp_stats . start_seq_nr + 1 ;
lost = expected - strinfo - > rtp_stats . total_nr ;
if ( expected ) {
perc = ( double ) ( lost * 100 ) / ( double ) expected ;
} else {
perc = 0 ;
}
2005-02-24 05:42:03 +00:00
data [ 7 ] = g_strdup_printf ( " %d (%.1f%%) " , lost , perc ) ;
data [ 8 ] = g_strdup_printf ( " %.2f " , strinfo - > rtp_stats . max_delta * 1000 ) ;
data [ 9 ] = g_strdup_printf ( " %.2f " , strinfo - > rtp_stats . max_jitter * 1000 ) ;
data [ 10 ] = g_strdup_printf ( " %.2f " , strinfo - > rtp_stats . mean_jitter * 1000 ) ;
2005-02-16 09:24:52 +00:00
if ( strinfo - > problem )
2005-02-24 05:42:03 +00:00
data [ 11 ] = g_strdup ( " X " ) ;
2005-02-16 09:24:52 +00:00
else
2005-02-24 05:42:03 +00:00
data [ 11 ] = g_strdup ( " " ) ;
2003-09-24 07:48:12 +00:00
2005-03-21 01:24:19 +00:00
/* restore previous locale setting */
setlocale ( LC_NUMERIC , savelocale ) ;
2003-09-24 07:48:12 +00:00
added_row = gtk_clist_append ( GTK_CLIST ( clist ) , data ) ;
2005-02-24 05:42:03 +00:00
for ( i = 0 ; i < NUM_COLS ; i + + )
g_free ( data [ i ] ) ;
2003-09-24 07:48:12 +00:00
/* set data pointer of last row to point to user data for that row */
gtk_clist_set_row_data ( GTK_CLIST ( clist ) , added_row , strinfo ) ;
2004-06-30 21:17:55 +00:00
/* Update the top label with the number of detected streams */
2008-02-01 01:07:58 +00:00
g_snprintf ( label_text , 256 ,
2004-06-30 21:17:55 +00:00
" Detected %d RTP streams. Choose one for forward and reverse direction for analysis " ,
+ + streams_nb ) ;
gtk_label_set ( GTK_LABEL ( top_label ) , label_text ) ;
2003-09-24 07:48:12 +00:00
}
/****************************************************************************/
static void save_stream_destroy_cb ( GtkWidget * win _U_ , gpointer user_data _U_ )
{
/* Note that we no longer have a Save voice info dialog box. */
rtpstream_save_dlg = NULL ;
}
/****************************************************************************/
/* save in a file */
2009-02-22 19:02:02 +00:00
static void save_stream_ok_cb ( GtkWidget * ok_bt _U_ , gpointer fs _U_ )
2003-09-24 07:48:12 +00:00
{
gchar * g_dest ;
if ( ! selected_stream_fwd )
return ;
2009-02-22 19:02:02 +00:00
g_dest = g_strdup ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER ( fs ) ) ) ;
2003-09-24 07:48:12 +00:00
/* Perhaps the user specified a directory instead of a file.
Check whether they did . */
if ( test_for_directory ( g_dest ) = = EISDIR ) {
/* It's a directory - set the file selection box to display it. */
set_last_open_dir ( g_dest ) ;
g_free ( g_dest ) ;
2004-06-01 17:33:37 +00:00
file_selection_set_current_folder ( rtpstream_save_dlg , get_last_open_dir ( ) ) ;
2003-09-24 07:48:12 +00:00
return ;
}
2004-01-25 02:24:44 +00:00
/*
* Don ' t dismiss the dialog box if the save operation fails .
*/
if ( ! rtpstream_save ( selected_stream_fwd , g_dest ) )
return ;
2003-09-24 07:48:12 +00:00
2004-05-26 03:49:24 +00:00
window_destroy ( GTK_WIDGET ( rtpstream_save_dlg ) ) ;
2003-09-24 07:48:12 +00:00
}
/****************************************************************************/
/* CALLBACKS */
/****************************************************************************/
static void
rtpstream_on_destroy ( GtkObject * object _U_ ,
gpointer user_data _U_ )
{
2003-11-20 23:34:31 +00:00
/* Remove the stream tap listener */
remove_tap_listener_rtp_stream ( ) ;
2003-09-24 07:48:12 +00:00
/* Is there a save voice window open? */
if ( rtpstream_save_dlg ! = NULL )
2004-05-26 03:49:24 +00:00
window_destroy ( rtpstream_save_dlg ) ;
2003-09-24 07:48:12 +00:00
2003-11-20 23:34:31 +00:00
/* Clean up memory used by stream tap */
rtpstream_reset ( ( rtpstream_tapinfo_t * ) rtpstream_get_info ( ) ) ;
/* Note that we no longer have a "RTP Streams" dialog box. */
2003-09-24 07:48:12 +00:00
rtp_stream_dlg = NULL ;
}
/****************************************************************************/
static void
rtpstream_on_unselect ( GtkButton * button _U_ ,
gpointer user_data _U_ )
{
selected_stream_fwd = NULL ;
selected_stream_rev = NULL ;
gtk_clist_unselect_all ( GTK_CLIST ( clist ) ) ;
gtk_label_set_text ( GTK_LABEL ( label_fwd ) , FWD_LABEL_TEXT ) ;
gtk_label_set_text ( GTK_LABEL ( label_rev ) , REV_LABEL_TEXT ) ;
}
2004-01-26 19:16:30 +00:00
/****************************************************************************/
2005-08-20 14:02:00 +00:00
static gint rtp_stream_info_cmp_reverse ( gconstpointer aa , gconstpointer bb )
2004-01-26 19:16:30 +00:00
{
const struct _rtp_stream_info * a = aa ;
const struct _rtp_stream_info * b = bb ;
if ( a = = NULL | | b = = NULL )
return 1 ;
2004-12-01 11:54:41 +00:00
if ( ( ADDRESSES_EQUAL ( & ( a - > src_addr ) , & ( b - > dest_addr ) ) )
2004-01-26 19:16:30 +00:00
& & ( a - > src_port = = b - > dest_port )
2004-12-01 11:54:41 +00:00
& & ( ADDRESSES_EQUAL ( & ( a - > dest_addr ) , & ( b - > src_addr ) ) )
2004-01-26 19:16:30 +00:00
& & ( a - > dest_port = = b - > src_port ) )
return 0 ;
else
return 1 ;
}
/****************************************************************************/
static void
rtpstream_on_findrev ( GtkButton * button _U_ ,
gpointer user_data _U_ )
{
gint row ;
gint start_row ;
rtp_stream_info_t * pstream = NULL ;
if ( selected_stream_fwd = = NULL )
return ;
if ( selected_stream_rev = = NULL ) {
pstream = selected_stream_fwd ;
}
else {
pstream = selected_stream_rev ;
}
start_row = gtk_clist_find_row_from_data ( GTK_CLIST ( clist ) , pstream ) ;
row = start_row + 1 ;
for ( row = start_row + 1 ;
( pstream = gtk_clist_get_row_data ( GTK_CLIST ( clist ) , row ) ) ;
row + + ) {
if ( rtp_stream_info_cmp_reverse ( selected_stream_fwd , pstream ) = = 0 ) {
gtk_clist_select_row ( GTK_CLIST ( clist ) , row , 0 ) ;
gtk_clist_moveto ( GTK_CLIST ( clist ) , row , 0 , 0.5 , 0 ) ;
return ;
}
}
2004-06-30 21:17:55 +00:00
2004-01-26 19:16:30 +00:00
/* wrap around */
for ( row = 0 ;
( pstream = gtk_clist_get_row_data ( GTK_CLIST ( clist ) , row ) ) & & row < start_row ;
row + + ) {
if ( rtp_stream_info_cmp_reverse ( selected_stream_fwd , pstream ) = = 0 ) {
gtk_clist_select_row ( GTK_CLIST ( clist ) , row , 0 ) ;
gtk_clist_moveto ( GTK_CLIST ( clist ) , row , 0 , 0.5 , 0 ) ;
return ;
}
}
/* if we didnt find another stream, highlight the current reverse stream */
if ( selected_stream_rev ! = NULL ) {
gtk_clist_select_row ( GTK_CLIST ( clist ) , row , 0 ) ;
gtk_clist_moveto ( GTK_CLIST ( clist ) , row , 0 , 0.5 , 0 ) ;
}
}
2003-09-24 07:48:12 +00:00
/****************************************************************************/
/*
static void
rtpstream_on_goto ( GtkButton * button _U_ ,
gpointer user_data _U_ )
{
if ( selected_stream_fwd )
{
2005-02-04 18:44:44 +00:00
cf_goto_frame ( & cfile , selected_stream_fwd - > first_frame_num ) ;
2003-09-24 07:48:12 +00:00
}
}
*/
/****************************************************************************/
static void
rtpstream_on_save ( GtkButton * button _U_ ,
gpointer data _U_ )
{
2009-02-22 19:32:15 +00:00
/* XX - not neded?
2003-09-24 07:48:12 +00:00
rtpstream_tapinfo_t * tapinfo = data ;
2009-02-22 19:32:15 +00:00
*/
2003-09-24 07:48:12 +00:00
if ( ! selected_stream_fwd )
return ;
if ( rtpstream_save_dlg ! = NULL ) {
/* There's already a Save dialog box; reactivate it. */
reactivate_window ( rtpstream_save_dlg ) ;
return ;
}
2009-02-22 19:02:02 +00:00
rtpstream_save_dlg = gtk_file_chooser_dialog_new ( " Wireshark: Save selected stream in rtpdump ('-F dump') format " , GTK_WINDOW ( rtp_stream_dlg ) , GTK_FILE_CHOOSER_ACTION_SAVE ,
GTK_STOCK_OK , GTK_RESPONSE_ACCEPT ,
GTK_STOCK_CANCEL , GTK_RESPONSE_CANCEL ,
NULL ) ;
2003-09-24 07:48:12 +00:00
2008-04-11 23:16:06 +00:00
g_signal_connect ( rtpstream_save_dlg , " delete_event " , G_CALLBACK ( window_delete_event_cb ) , NULL ) ;
g_signal_connect ( rtpstream_save_dlg , " destroy " , G_CALLBACK ( save_stream_destroy_cb ) ,
2004-06-30 21:17:55 +00:00
NULL ) ;
2003-09-24 07:48:12 +00:00
gtk_widget_show ( rtpstream_save_dlg ) ;
2004-06-30 21:17:55 +00:00
window_present ( rtpstream_save_dlg ) ;
2009-02-22 19:02:02 +00:00
if ( gtk_dialog_run ( GTK_DIALOG ( rtpstream_save_dlg ) ) = = GTK_RESPONSE_ACCEPT ) {
save_stream_ok_cb ( rtpstream_save_dlg , rtpstream_save_dlg ) ;
} else {
window_destroy ( rtpstream_save_dlg ) ;
}
2003-09-24 07:48:12 +00:00
}
/****************************************************************************/
static void
rtpstream_on_mark ( GtkButton * button _U_ ,
gpointer user_data _U_ )
{
if ( selected_stream_fwd = = NULL & & selected_stream_rev = = NULL )
return ;
rtpstream_mark ( selected_stream_fwd , selected_stream_rev ) ;
}
/****************************************************************************/
static void
rtpstream_on_filter ( GtkButton * button _U_ ,
gpointer user_data _U_ )
{
2004-03-14 14:04:39 +00:00
gchar * filter_string = NULL ;
gchar * filter_string_fwd = NULL ;
gchar * filter_string_rev = NULL ;
2004-12-01 11:54:41 +00:00
gchar ip_version [ 3 ] ;
2003-09-24 07:48:12 +00:00
if ( selected_stream_fwd = = NULL & & selected_stream_rev = = NULL )
return ;
if ( selected_stream_fwd )
{
2004-12-01 11:54:41 +00:00
if ( selected_stream_fwd - > src_addr . type = = AT_IPv6 ) {
2008-02-29 13:33:37 +00:00
g_strlcpy ( ip_version , " v6 " , 3 ) ;
2004-12-01 11:54:41 +00:00
}
else {
2008-02-29 13:33:37 +00:00
ip_version [ 0 ] = ' \0 ' ;
2004-12-01 11:54:41 +00:00
}
2004-03-13 12:09:27 +00:00
filter_string_fwd = g_strdup_printf (
2007-05-31 18:41:25 +00:00
" (ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u && rtp.ssrc==0x%X) " ,
2004-12-01 11:54:41 +00:00
ip_version ,
2005-03-02 01:24:18 +00:00
address_to_str ( & ( selected_stream_fwd - > src_addr ) ) ,
2003-09-24 07:48:12 +00:00
selected_stream_fwd - > src_port ,
2004-12-01 11:54:41 +00:00
ip_version ,
2005-03-02 01:24:18 +00:00
address_to_str ( & ( selected_stream_fwd - > dest_addr ) ) ,
2003-09-24 07:48:12 +00:00
selected_stream_fwd - > dest_port ,
selected_stream_fwd - > ssrc ) ;
2004-03-13 12:09:27 +00:00
filter_string = filter_string_fwd ;
2003-09-24 07:48:12 +00:00
}
if ( selected_stream_rev )
{
2004-12-01 11:54:41 +00:00
if ( selected_stream_fwd - > src_addr . type = = AT_IPv6 ) {
2008-02-29 13:33:37 +00:00
g_strlcpy ( ip_version , " v6 " , 3 ) ;
2004-12-01 11:54:41 +00:00
}
else {
2008-02-29 13:33:37 +00:00
ip_version [ 0 ] = ' \0 ' ;
2004-12-01 11:54:41 +00:00
}
2004-03-13 12:09:27 +00:00
filter_string_rev = g_strdup_printf (
2007-05-31 18:41:25 +00:00
" (ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u && rtp.ssrc==0x%X) " ,
2004-12-01 11:54:41 +00:00
ip_version ,
2005-03-02 01:24:18 +00:00
address_to_str ( & ( selected_stream_rev - > src_addr ) ) ,
2003-09-24 07:48:12 +00:00
selected_stream_rev - > src_port ,
2004-12-01 11:54:41 +00:00
ip_version ,
2005-03-02 01:24:18 +00:00
address_to_str ( & ( selected_stream_rev - > dest_addr ) ) ,
2003-09-24 07:48:12 +00:00
selected_stream_rev - > dest_port ,
selected_stream_rev - > ssrc ) ;
2004-12-01 11:54:41 +00:00
filter_string = filter_string_rev ;
2004-03-13 12:09:27 +00:00
if ( selected_stream_fwd )
{
filter_string = g_strdup_printf ( " %s || %s " , filter_string , filter_string_rev ) ;
g_free ( filter_string_fwd ) ;
g_free ( filter_string_rev ) ;
}
}
gtk_entry_set_text ( GTK_ENTRY ( main_display_filter_widget ) , filter_string ) ;
g_free ( filter_string ) ;
2003-09-24 07:48:12 +00:00
/*
2004-02-23 22:48:52 +00:00
main_filter_packets ( & cfile , filter_string , FALSE ) ;
2003-09-24 07:48:12 +00:00
rtpstream_dlg_update ( rtpstream_get_info ( ) - > strinfo_list ) ;
*/
}
2005-03-21 01:24:19 +00:00
/****************************************************************************/
static void
rtpstream_on_copy_as_csv ( GtkWindow * win _U_ , gpointer data _U_ )
{
int i , j ;
gchar * table_entry ;
GString * CSV_str ;
GtkClipboard * cb ;
CSV_str = g_string_sized_new ( 240 * ( GTK_CLIST ( clist ) - > rows + 1 ) ) ;
/* Add the column headers to the CSV data */
for ( j = 0 ; j < NUM_COLS ; j + + ) {
g_string_append ( CSV_str , titles [ j ] ) ;
g_string_append ( CSV_str , " , " ) ;
}
g_string_append ( CSV_str , " \n " ) ;
/* Add the column values to the CSV data */
for ( i = 0 ; i < GTK_CLIST ( clist ) - > rows ; i + + ) {
for ( j = 0 ; j < NUM_COLS ; j + + ) {
gtk_clist_get_text ( GTK_CLIST ( clist ) , i , j , & table_entry ) ;
g_string_append ( CSV_str , table_entry ) ;
g_string_append ( CSV_str , " , " ) ;
}
g_string_append ( CSV_str , " \n " ) ;
}
/* Now that we have the CSV data, copy it into the default clipboard */
cb = gtk_clipboard_get ( GDK_SELECTION_CLIPBOARD ) ;
gtk_clipboard_set_text ( cb , CSV_str - > str , CSV_str - > len ) ;
g_string_free ( CSV_str , TRUE ) ;
}
2003-09-24 07:48:12 +00:00
/****************************************************************************/
static void
rtpstream_on_analyse ( GtkButton * button _U_ ,
gpointer user_data _U_ )
2004-12-01 11:54:41 +00:00
{
address ip_src_fwd ;
2003-09-24 07:48:12 +00:00
guint16 port_src_fwd = 0 ;
2004-12-01 11:54:41 +00:00
address ip_dst_fwd ;
2003-09-24 07:48:12 +00:00
guint16 port_dst_fwd = 0 ;
guint32 ssrc_fwd = 0 ;
2004-12-01 11:54:41 +00:00
address ip_src_rev ;
2003-09-24 07:48:12 +00:00
guint16 port_src_rev = 0 ;
2004-12-01 11:54:41 +00:00
address ip_dst_rev ;
2003-09-24 07:48:12 +00:00
guint16 port_dst_rev = 0 ;
guint32 ssrc_rev = 0 ;
2005-02-27 12:45:07 +00:00
if ( ! ( selected_stream_fwd | | selected_stream_rev ) )
{
return ;
}
2004-12-01 11:54:41 +00:00
SET_ADDRESS ( & ip_src_fwd , AT_NONE , 0 , NULL ) ;
SET_ADDRESS ( & ip_dst_fwd , AT_NONE , 0 , NULL ) ;
SET_ADDRESS ( & ip_src_rev , AT_NONE , 0 , NULL ) ;
SET_ADDRESS ( & ip_dst_rev , AT_NONE , 0 , NULL ) ;
2003-09-24 07:48:12 +00:00
if ( selected_stream_fwd ) {
2004-12-01 11:54:41 +00:00
COPY_ADDRESS ( & ( ip_src_fwd ) , & ( selected_stream_fwd - > src_addr ) ) ;
2003-09-24 07:48:12 +00:00
port_src_fwd = selected_stream_fwd - > src_port ;
2004-12-01 11:54:41 +00:00
COPY_ADDRESS ( & ( ip_dst_fwd ) , & ( selected_stream_fwd - > dest_addr ) ) ;
2003-09-24 07:48:12 +00:00
port_dst_fwd = selected_stream_fwd - > dest_port ;
ssrc_fwd = selected_stream_fwd - > ssrc ;
}
if ( selected_stream_rev ) {
2004-12-01 11:54:41 +00:00
COPY_ADDRESS ( & ( ip_src_rev ) , & ( selected_stream_rev - > src_addr ) ) ;
2003-09-24 07:48:12 +00:00
port_src_rev = selected_stream_rev - > src_port ;
2004-12-01 11:54:41 +00:00
COPY_ADDRESS ( & ( ip_dst_rev ) , & ( selected_stream_rev - > dest_addr ) ) ;
2003-09-24 07:48:12 +00:00
port_dst_rev = selected_stream_rev - > dest_port ;
ssrc_rev = selected_stream_rev - > ssrc ;
}
rtp_analysis (
2004-12-01 11:54:41 +00:00
& ip_src_fwd ,
2003-09-24 07:48:12 +00:00
port_src_fwd ,
2004-12-01 11:54:41 +00:00
& ip_dst_fwd ,
2003-09-24 07:48:12 +00:00
port_dst_fwd ,
ssrc_fwd ,
2004-12-01 11:54:41 +00:00
& ip_src_rev ,
2003-09-24 07:48:12 +00:00
port_src_rev ,
2004-12-01 11:54:41 +00:00
& ip_dst_rev ,
2003-09-24 07:48:12 +00:00
port_dst_rev ,
ssrc_rev
) ;
2003-11-20 23:34:31 +00:00
2003-09-24 07:48:12 +00:00
}
/****************************************************************************/
/* when the user selects a row in the stream list */
static void
rtpstream_on_select_row ( GtkCList * clist ,
gint row _U_ ,
gint column _U_ ,
GdkEventButton * event _U_ ,
gpointer user_data _U_ )
{
gchar label_text [ 80 ] ;
/* update the labels */
2004-01-26 19:16:30 +00:00
if ( event = = NULL | | event - > state & GDK_SHIFT_MASK ) {
2003-09-24 07:48:12 +00:00
selected_stream_rev = gtk_clist_get_row_data ( GTK_CLIST ( clist ) , row ) ;
2007-05-31 18:41:25 +00:00
g_snprintf ( label_text , 80 , " Reverse: %s:%u -> %s:%u, SSRC=0x%X " ,
2005-03-02 01:24:18 +00:00
get_addr_name ( & ( selected_stream_rev - > src_addr ) ) ,
2003-09-24 07:48:12 +00:00
selected_stream_rev - > src_port ,
2005-03-02 01:24:18 +00:00
get_addr_name ( & ( selected_stream_rev - > dest_addr ) ) ,
2003-09-24 07:48:12 +00:00
selected_stream_rev - > dest_port ,
selected_stream_rev - > ssrc
) ;
gtk_label_set_text ( GTK_LABEL ( label_rev ) , label_text ) ;
}
else {
selected_stream_fwd = gtk_clist_get_row_data ( GTK_CLIST ( clist ) , row ) ;
2007-05-31 18:41:25 +00:00
g_snprintf ( label_text , 80 , " Forward: %s:%u -> %s:%u, SSRC=0x%X " ,
2005-03-02 01:24:18 +00:00
get_addr_name ( & ( selected_stream_fwd - > src_addr ) ) ,
2003-09-24 07:48:12 +00:00
selected_stream_fwd - > src_port ,
2005-03-02 01:24:18 +00:00
get_addr_name ( & ( selected_stream_fwd - > dest_addr ) ) ,
2003-09-24 07:48:12 +00:00
selected_stream_fwd - > dest_port ,
selected_stream_fwd - > ssrc
) ;
gtk_label_set_text ( GTK_LABEL ( label_fwd ) , label_text ) ;
}
/*
gtk_widget_set_sensitive ( save_bt , TRUE ) ;
gtk_widget_set_sensitive ( filter_bt , TRUE ) ;
gtk_widget_set_sensitive ( mark_bt , TRUE ) ;
*/
/* TODO: activate other buttons when implemented */
}
2004-01-26 19:16:30 +00:00
/****************************************************************************/
typedef struct column_arrows {
GtkWidget * table ;
GtkWidget * ascend_pm ;
GtkWidget * descend_pm ;
} column_arrows ;
/****************************************************************************/
static void
rtpstream_click_column_cb ( GtkCList * clist , gint column , gpointer data )
{
column_arrows * col_arrows = ( column_arrows * ) data ;
int i ;
gtk_clist_freeze ( clist ) ;
for ( i = 0 ; i < NUM_COLS ; i + + ) {
gtk_widget_hide ( col_arrows [ i ] . ascend_pm ) ;
gtk_widget_hide ( col_arrows [ i ] . descend_pm ) ;
}
if ( column = = clist - > sort_column ) {
if ( clist - > sort_type = = GTK_SORT_ASCENDING ) {
clist - > sort_type = GTK_SORT_DESCENDING ;
gtk_widget_show ( col_arrows [ column ] . descend_pm ) ;
} else {
clist - > sort_type = GTK_SORT_ASCENDING ;
gtk_widget_show ( col_arrows [ column ] . ascend_pm ) ;
}
} else {
clist - > sort_type = GTK_SORT_ASCENDING ;
gtk_widget_show ( col_arrows [ column ] . ascend_pm ) ;
gtk_clist_set_sort_column ( clist , column ) ;
}
gtk_clist_thaw ( clist ) ;
gtk_clist_sort ( clist ) ;
}
/****************************************************************************/
static gint
rtpstream_sort_column ( GtkCList * clist , gconstpointer ptr1 , gconstpointer ptr2 )
{
char * text1 = NULL ;
char * text2 = NULL ;
int i1 , i2 ;
const GtkCListRow * row1 = ( const GtkCListRow * ) ptr1 ;
const GtkCListRow * row2 = ( const GtkCListRow * ) ptr2 ;
text1 = GTK_CELL_TEXT ( row1 - > cell [ clist - > sort_column ] ) - > text ;
text2 = GTK_CELL_TEXT ( row2 - > cell [ clist - > sort_column ] ) - > text ;
switch ( clist - > sort_column ) {
case 0 :
case 2 :
case 5 :
2005-02-16 09:24:52 +00:00
case 11 :
2004-01-26 19:16:30 +00:00
return strcmp ( text1 , text2 ) ;
case 1 :
case 3 :
case 4 :
case 6 :
2005-02-16 09:24:52 +00:00
case 7 :
case 8 :
case 9 :
case 10 :
2004-01-26 19:16:30 +00:00
i1 = atoi ( text1 ) ;
i2 = atoi ( text2 ) ;
return i1 - i2 ;
}
g_assert_not_reached ( ) ;
return 0 ;
}
2003-09-24 07:48:12 +00:00
/****************************************************************************/
/* INTERFACE */
/****************************************************************************/
static void rtpstream_dlg_create ( void )
{
2005-03-21 01:24:19 +00:00
GtkWidget * rtpstream_dlg_w ;
GtkWidget * main_vb ;
GtkWidget * scrolledwindow ;
GtkWidget * hbuttonbox ;
/* GtkWidget *bt_goto;*/
GtkWidget * bt_unselect ;
GtkWidget * bt_findrev ;
GtkWidget * bt_save ;
GtkWidget * bt_mark ;
GtkWidget * bt_filter ;
GtkWidget * bt_analyze ;
GtkWidget * bt_close ;
GtkWidget * bt_copy ;
2004-10-03 16:29:40 +00:00
GtkTooltips * tooltips = gtk_tooltips_new ( ) ;
2004-01-26 19:16:30 +00:00
2005-03-21 01:24:19 +00:00
column_arrows * col_arrows ;
GtkWidget * column_lb ;
int i ;
2006-05-22 07:29:40 +00:00
rtpstream_dlg_w = dlg_window_new ( " Wireshark: RTP Streams " ) ;
2005-03-21 01:24:19 +00:00
gtk_window_set_default_size ( GTK_WINDOW ( rtpstream_dlg_w ) , 620 , 200 ) ;
main_vb = gtk_vbox_new ( FALSE , 0 ) ;
gtk_container_add ( GTK_CONTAINER ( rtpstream_dlg_w ) , main_vb ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( main_vb ) , 12 ) ;
top_label = gtk_label_new ( " Detected 0 RTP streams. Choose one for forward and reverse direction for analysis " ) ;
gtk_box_pack_start ( GTK_BOX ( main_vb ) , top_label , FALSE , FALSE , 8 ) ;
scrolledwindow = scrolled_window_new ( NULL , NULL ) ;
gtk_box_pack_start ( GTK_BOX ( main_vb ) , scrolledwindow , TRUE , TRUE , 0 ) ;
clist = gtk_clist_new ( NUM_COLS ) ;
gtk_container_add ( GTK_CONTAINER ( scrolledwindow ) , clist ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 0 , 88 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 1 , 44 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 2 , 88 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 3 , 44 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 4 , 64 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 5 , 96 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 6 , 50 ) ;
2007-05-31 18:41:25 +00:00
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 7 , 64 ) ;
2005-03-21 01:24:19 +00:00
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 8 , 80 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 9 , 80 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 10 , 80 ) ;
gtk_clist_set_column_width ( GTK_CLIST ( clist ) , 11 , 40 ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 0 , GTK_JUSTIFY_CENTER ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 1 , GTK_JUSTIFY_CENTER ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 2 , GTK_JUSTIFY_CENTER ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 3 , GTK_JUSTIFY_CENTER ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 4 , GTK_JUSTIFY_CENTER ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 5 , GTK_JUSTIFY_LEFT ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 6 , GTK_JUSTIFY_RIGHT ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 7 , GTK_JUSTIFY_RIGHT ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 8 , GTK_JUSTIFY_RIGHT ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 9 , GTK_JUSTIFY_RIGHT ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 10 , GTK_JUSTIFY_RIGHT ) ;
gtk_clist_set_column_justification ( GTK_CLIST ( clist ) , 11 , GTK_JUSTIFY_LEFT ) ;
gtk_clist_column_titles_show ( GTK_CLIST ( clist ) ) ;
gtk_clist_set_compare_func ( GTK_CLIST ( clist ) , rtpstream_sort_column ) ;
gtk_clist_set_sort_column ( GTK_CLIST ( clist ) , 0 ) ;
gtk_clist_set_sort_type ( GTK_CLIST ( clist ) , GTK_SORT_ASCENDING ) ;
gtk_widget_show ( rtpstream_dlg_w ) ;
/* sort by column feature */
col_arrows = ( column_arrows * ) g_malloc ( sizeof ( column_arrows ) * NUM_COLS ) ;
for ( i = 0 ; i < NUM_COLS ; i + + ) {
col_arrows [ i ] . table = gtk_table_new ( 2 , 2 , FALSE ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( col_arrows [ i ] . table ) , 5 ) ;
column_lb = gtk_label_new ( titles [ i ] ) ;
gtk_table_attach ( GTK_TABLE ( col_arrows [ i ] . table ) , column_lb , 0 , 1 , 0 , 2 , GTK_SHRINK , GTK_SHRINK , 0 , 0 ) ;
gtk_widget_show ( column_lb ) ;
col_arrows [ i ] . ascend_pm = xpm_to_widget ( clist_ascend_xpm ) ;
gtk_table_attach ( GTK_TABLE ( col_arrows [ i ] . table ) , col_arrows [ i ] . ascend_pm , 1 , 2 , 1 , 2 , GTK_SHRINK , GTK_SHRINK , 0 , 0 ) ;
col_arrows [ i ] . descend_pm = xpm_to_widget ( clist_descend_xpm ) ;
gtk_table_attach ( GTK_TABLE ( col_arrows [ i ] . table ) , col_arrows [ i ] . descend_pm , 1 , 2 , 0 , 1 , GTK_SHRINK , GTK_SHRINK , 0 , 0 ) ;
/* make src-ip be the default sort order */
if ( i = = 0 ) {
gtk_widget_show ( col_arrows [ i ] . ascend_pm ) ;
}
gtk_clist_set_column_widget ( GTK_CLIST ( clist ) , i , col_arrows [ i ] . table ) ;
gtk_widget_show ( col_arrows [ i ] . table ) ;
}
2004-01-26 19:16:30 +00:00
2008-04-11 23:16:06 +00:00
g_signal_connect ( clist , " click-column " , G_CALLBACK ( rtpstream_click_column_cb ) , col_arrows ) ;
2004-01-26 19:16:30 +00:00
2005-03-21 01:24:19 +00:00
label_fwd = gtk_label_new ( FWD_LABEL_TEXT ) ;
gtk_box_pack_start ( GTK_BOX ( main_vb ) , label_fwd , FALSE , FALSE , 0 ) ;
2004-06-30 21:17:55 +00:00
2005-03-21 01:24:19 +00:00
label_rev = gtk_label_new ( REV_LABEL_TEXT ) ;
gtk_box_pack_start ( GTK_BOX ( main_vb ) , label_rev , FALSE , FALSE , 0 ) ;
2004-06-30 21:17:55 +00:00
2004-05-26 03:49:24 +00:00
/* button row */
2005-03-21 01:24:19 +00:00
hbuttonbox = gtk_hbutton_box_new ( ) ;
gtk_box_pack_start ( GTK_BOX ( main_vb ) , hbuttonbox , FALSE , FALSE , 0 ) ;
gtk_button_box_set_layout ( GTK_BUTTON_BOX ( hbuttonbox ) , GTK_BUTTONBOX_END ) ;
2008-07-08 02:43:40 +00:00
gtk_box_set_spacing ( GTK_BOX ( hbuttonbox ) , 0 ) ;
2004-06-30 21:17:55 +00:00
2005-03-21 01:24:19 +00:00
bt_unselect = gtk_button_new_with_label ( " Unselect " ) ;
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_unselect ) ;
2004-10-03 16:29:40 +00:00
gtk_tooltips_set_tip ( tooltips , bt_unselect , " Undo stream selection " , NULL ) ;
2004-01-26 19:16:30 +00:00
2005-03-21 01:24:19 +00:00
bt_findrev = gtk_button_new_with_label ( " Find Reverse " ) ;
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_findrev ) ;
2004-10-03 16:29:40 +00:00
gtk_tooltips_set_tip ( tooltips , bt_findrev , " Find the reverse stream matching the selected forward stream " , NULL ) ;
2004-06-30 21:17:55 +00:00
/*
2008-04-11 18:58:19 +00:00
bt_goto = gtk_button_new_from_stock ( GTK_STOCK_JUMP_TO ) ;
2005-03-21 01:24:19 +00:00
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_goto ) ;
2004-06-30 21:17:55 +00:00
*/
2008-04-11 18:58:19 +00:00
bt_save = gtk_button_new_from_stock ( GTK_STOCK_SAVE_AS ) ;
2005-03-21 01:24:19 +00:00
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_save ) ;
2004-10-03 16:29:40 +00:00
gtk_tooltips_set_tip ( tooltips , bt_save , " Save stream payload in rtpdump format " , NULL ) ;
2004-06-30 21:17:55 +00:00
2005-03-21 01:24:19 +00:00
bt_mark = gtk_button_new_with_label ( " Mark Packets " ) ;
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_mark ) ;
2004-10-03 16:29:40 +00:00
gtk_tooltips_set_tip ( tooltips , bt_mark , " Mark packets of the selected stream(s) " , NULL ) ;
2004-06-30 21:17:55 +00:00
2005-03-21 01:24:19 +00:00
bt_filter = gtk_button_new_with_label ( " Prepare Filter " ) ;
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_filter ) ;
2004-10-03 16:29:40 +00:00
gtk_tooltips_set_tip ( tooltips , bt_filter , " Prepare a display filter of the selected stream(s) " , NULL ) ;
2004-06-30 21:17:55 +00:00
2005-03-21 01:24:19 +00:00
/* XXX - maybe we want to have a "Copy as CSV" stock button here? */
/*bt_copy = gtk_button_new_with_label ("Copy content to clipboard as CSV");*/
2008-04-11 18:58:19 +00:00
bt_copy = gtk_button_new_from_stock ( GTK_STOCK_COPY ) ;
2005-03-21 01:24:19 +00:00
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_copy ) ;
gtk_tooltips_set_tip ( tooltips , bt_copy ,
2008-12-20 01:39:16 +00:00
" Copy all statistical values of this page to the clipboard in CSV (Comma Separated Values) format. " , NULL ) ;
2005-03-21 01:24:19 +00:00
bt_analyze = gtk_button_new_with_label ( " Analyze " ) ;
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_analyze ) ;
2004-10-03 16:29:40 +00:00
gtk_tooltips_set_tip ( tooltips , bt_analyze , " Open an analyze window of the selected stream(s) " , NULL ) ;
2004-06-30 21:17:55 +00:00
2008-04-11 18:58:19 +00:00
bt_close = gtk_button_new_from_stock ( GTK_STOCK_CLOSE ) ;
2005-03-21 01:24:19 +00:00
gtk_container_add ( GTK_CONTAINER ( hbuttonbox ) , bt_close ) ;
2004-10-03 16:29:40 +00:00
gtk_tooltips_set_tip ( tooltips , bt_close , " Close this dialog " , NULL ) ;
2005-03-21 01:24:19 +00:00
GTK_WIDGET_SET_FLAGS ( bt_close , GTK_CAN_DEFAULT ) ;
2004-04-12 18:01:27 +00:00
2008-04-11 23:16:06 +00:00
g_signal_connect ( clist , " select_row " , G_CALLBACK ( rtpstream_on_select_row ) , NULL ) ;
g_signal_connect ( bt_unselect , " clicked " , G_CALLBACK ( rtpstream_on_unselect ) , NULL ) ;
g_signal_connect ( bt_findrev , " clicked " , G_CALLBACK ( rtpstream_on_findrev ) , NULL ) ;
2003-09-24 07:48:12 +00:00
/*
2008-04-11 23:16:06 +00:00
g_signal_connect ( bt_goto , " clicked " , G_CALLBACK ( rtpstream_on_goto ) , NULL ) ;
2003-09-24 07:48:12 +00:00
*/
2008-04-11 23:16:06 +00:00
g_signal_connect ( bt_save , " clicked " , G_CALLBACK ( rtpstream_on_save ) , NULL ) ;
g_signal_connect ( bt_mark , " clicked " , G_CALLBACK ( rtpstream_on_mark ) , NULL ) ;
g_signal_connect ( bt_filter , " clicked " , G_CALLBACK ( rtpstream_on_filter ) , NULL ) ;
g_signal_connect ( bt_copy , " clicked " , G_CALLBACK ( rtpstream_on_copy_as_csv ) , NULL ) ;
g_signal_connect ( bt_analyze , " clicked " , G_CALLBACK ( rtpstream_on_analyse ) , NULL ) ;
2004-05-26 03:49:24 +00:00
2005-03-21 01:24:19 +00:00
window_set_cancel_button ( rtpstream_dlg_w , bt_close , window_cancel_button_cb ) ;
2004-05-26 03:49:24 +00:00
2008-04-11 23:16:06 +00:00
g_signal_connect ( rtpstream_dlg_w , " delete_event " , G_CALLBACK ( window_delete_event_cb ) , NULL ) ;
g_signal_connect ( rtpstream_dlg_w , " destroy " , G_CALLBACK ( rtpstream_on_destroy ) , NULL ) ;
2004-05-26 03:49:24 +00:00
2005-03-21 01:24:19 +00:00
gtk_widget_show_all ( rtpstream_dlg_w ) ;
window_present ( rtpstream_dlg_w ) ;
2004-06-30 21:17:55 +00:00
2005-03-21 01:24:19 +00:00
rtpstream_on_unselect ( NULL , NULL ) ;
2003-09-24 07:48:12 +00:00
2005-03-21 01:24:19 +00:00
rtp_stream_dlg = rtpstream_dlg_w ;
2003-09-24 07:48:12 +00:00
}
/****************************************************************************/
2004-01-26 19:16:30 +00:00
/* PUBLIC */
2003-09-24 07:48:12 +00:00
/****************************************************************************/
/****************************************************************************/
/* update the contents of the dialog box clist */
/* list: pointer to list of rtp_stream_info_t* */
void rtpstream_dlg_update ( GList * list )
{
if ( rtp_stream_dlg ! = NULL ) {
gtk_clist_clear ( GTK_CLIST ( clist ) ) ;
2004-06-30 21:17:55 +00:00
streams_nb = 0 ;
2003-09-24 07:48:12 +00:00
list = g_list_first ( list ) ;
while ( list )
{
add_to_clist ( ( rtp_stream_info_t * ) ( list - > data ) ) ;
list = g_list_next ( list ) ;
}
rtpstream_on_unselect ( NULL , NULL ) ;
}
last_list = list ;
}
/****************************************************************************/
/* update the contents of the dialog box clist */
/* list: pointer to list of rtp_stream_info_t* */
void rtpstream_dlg_show ( GList * list )
{
if ( rtp_stream_dlg ! = NULL ) {
/* There's already a dialog box; reactivate it. */
reactivate_window ( rtp_stream_dlg ) ;
/* Another list since last call? */
if ( list ! = last_list ) {
rtpstream_dlg_update ( list ) ;
}
}
else {
/* Create and show the dialog box */
rtpstream_dlg_create ( ) ;
rtpstream_dlg_update ( list ) ;
}
}
/****************************************************************************/
/* entry point when called via the GTK menu */
2005-08-20 14:02:00 +00:00
static void rtpstream_launch ( GtkWidget * w _U_ , gpointer data _U_ )
2003-09-24 07:48:12 +00:00
{
2003-11-20 23:34:31 +00:00
/* Register the tap listener */
register_tap_listener_rtp_stream ( ) ;
/* Scan for RTP streams (redissect all packets) */
rtpstream_scan ( ) ;
/* Show the dialog box with the list of streams */
2003-09-24 07:48:12 +00:00
rtpstream_dlg_show ( rtpstream_get_info ( ) - > strinfo_list ) ;
2003-11-20 23:34:31 +00:00
/* Tap listener will be removed and cleaned up in rtpstream_on_destroy */
2003-09-24 07:48:12 +00:00
}
/****************************************************************************/
void
2004-02-22 18:47:04 +00:00
register_tap_listener_rtp_stream_dlg ( void )
2003-09-24 07:48:12 +00:00
{
2005-08-21 10:29:47 +00:00
register_stat_menu_item ( " RTP/Show All Streams " , REGISTER_STAT_GROUP_TELEPHONY ,
2003-12-17 22:13:08 +00:00
rtpstream_launch , NULL , NULL , NULL ) ;
2003-09-24 07:48:12 +00:00
}