2002-10-25 01:08:49 +00:00
/* dcerpc_stat.c
* dcerpc_stat 2002 Ronnie Sahlberg
*
2004-01-31 03:22:42 +00:00
* $ Id : dcerpc_stat . c , v 1.46 2004 / 01 / 31 03 : 22 : 39 guy Exp $
2002-10-25 01:08:49 +00:00
*
* 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 .
*/
2003-06-21 01:42:46 +00:00
/* This module provides rpc call/reply SRT statistics to ethereal,
2003-04-23 08:20:06 +00:00
* and displays them graphically .
* It is only used by ethereal and not tethereal
2002-10-25 01:08:49 +00:00
*
* It serves as an example on how to use the tap api .
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include <gtk/gtk.h>
2003-12-13 22:23:18 +00:00
# include <stdio.h>
# include <string.h>
2002-10-25 01:08:49 +00:00
# include "epan/packet_info.h"
2003-09-24 02:36:35 +00:00
# include "epan/epan.h"
2003-12-13 22:23:18 +00:00
# include "menu.h"
2002-10-25 01:08:49 +00:00
# include "simple_dialog.h"
2003-04-24 23:17:43 +00:00
# include "dlg_utils.h"
# include "ui_util.h"
2002-10-25 01:08:49 +00:00
# include "tap.h"
2002-11-06 10:53:36 +00:00
# include "../register.h"
2002-10-25 01:08:49 +00:00
# include "packet-dcerpc.h"
# include "../globals.h"
2003-10-27 01:35:53 +00:00
# include "filter_prefs.h"
2002-11-11 15:39:06 +00:00
# include "compat_macros.h"
2003-06-21 01:42:46 +00:00
# include "service_response_time_table.h"
2002-10-25 01:08:49 +00:00
2003-08-19 10:09:20 +00:00
extern GtkWidget * main_display_filter_widget ;
2002-10-25 01:08:49 +00:00
/* used to keep track of the statistics for an entire program interface */
typedef struct _rpcstat_t {
GtkWidget * win ;
2003-06-21 01:42:46 +00:00
srt_stat_table srt_table ;
2002-10-25 01:08:49 +00:00
char * prog ;
e_uuid_t uuid ;
guint16 ver ;
2003-06-21 01:42:46 +00:00
int num_procedures ;
2002-10-25 01:08:49 +00:00
} rpcstat_t ;
static int
uuid_equal ( e_uuid_t * uuid1 , e_uuid_t * uuid2 )
{
if ( ( uuid1 - > Data1 ! = uuid2 - > Data1 )
| | ( uuid1 - > Data2 ! = uuid2 - > Data2 )
| | ( uuid1 - > Data3 ! = uuid2 - > Data3 )
| | ( uuid1 - > Data4 [ 0 ] ! = uuid2 - > Data4 [ 0 ] )
| | ( uuid1 - > Data4 [ 1 ] ! = uuid2 - > Data4 [ 1 ] )
| | ( uuid1 - > Data4 [ 2 ] ! = uuid2 - > Data4 [ 2 ] )
| | ( uuid1 - > Data4 [ 3 ] ! = uuid2 - > Data4 [ 3 ] )
| | ( uuid1 - > Data4 [ 4 ] ! = uuid2 - > Data4 [ 4 ] )
| | ( uuid1 - > Data4 [ 5 ] ! = uuid2 - > Data4 [ 5 ] )
| | ( uuid1 - > Data4 [ 6 ] ! = uuid2 - > Data4 [ 6 ] )
| | ( uuid1 - > Data4 [ 7 ] ! = uuid2 - > Data4 [ 7 ] ) ) {
return 0 ;
}
return 1 ;
}
2003-09-26 02:09:44 +00:00
2003-10-10 11:24:24 +00:00
static char *
dcerpcstat_gen_title ( rpcstat_t * rs )
{
char * title ;
2004-01-19 23:43:29 +00:00
title = g_strdup_printf ( " DCE-RPC Service Response Time statistics for %s major version %u: %s " , rs - > prog , rs - > ver , cf_get_display_name ( & cfile ) ) ;
2003-10-10 11:24:24 +00:00
return title ;
}
2003-09-26 02:09:44 +00:00
static void
dcerpcstat_set_title ( rpcstat_t * rs )
{
char * title ;
2003-10-10 11:24:24 +00:00
title = dcerpcstat_gen_title ( rs ) ;
2003-09-26 02:09:44 +00:00
gtk_window_set_title ( GTK_WINDOW ( rs - > win ) , title ) ;
g_free ( title ) ;
}
2002-10-25 01:08:49 +00:00
static void
2004-01-19 23:00:12 +00:00
dcerpcstat_reset ( void * rs_arg )
2002-10-25 01:08:49 +00:00
{
2004-01-19 23:00:12 +00:00
rpcstat_t * rs = rs_arg ;
2003-06-21 01:42:46 +00:00
reset_srt_table_data ( & rs - > srt_table ) ;
2003-09-26 02:09:44 +00:00
dcerpcstat_set_title ( rs ) ;
2002-10-25 01:08:49 +00:00
}
static int
2004-01-19 23:00:12 +00:00
dcerpcstat_packet ( void * rs_arg , packet_info * pinfo , epan_dissect_t * edt _U_ , void * ri_arg )
2002-10-25 01:08:49 +00:00
{
2004-01-19 23:00:12 +00:00
rpcstat_t * rs = rs_arg ;
dcerpc_info * ri = ri_arg ;
2002-10-25 01:08:49 +00:00
if ( ! ri - > call_data ) {
return 0 ;
}
if ( ! ri - > call_data - > req_frame ) {
/* we have not seen the request so we dont know the delta*/
return 0 ;
}
if ( ri - > call_data - > opnum > = rs - > num_procedures ) {
/* dont handle this since its outside of known table */
return 0 ;
}
/* we are only interested in reply packets */
if ( ri - > request ) {
return 0 ;
}
/* we are only interested in certain program/versions */
if ( ( ! uuid_equal ( ( & ri - > call_data - > uuid ) , ( & rs - > uuid ) ) )
| | ( ri - > call_data - > ver ! = rs - > ver ) ) {
return 0 ;
}
2003-06-21 01:42:46 +00:00
add_srt_table_data ( & rs - > srt_table , ri - > call_data - > opnum , & ri - > call_data - > req_time , pinfo ) ;
2002-10-25 01:08:49 +00:00
return 1 ;
}
static void
2004-01-19 23:00:12 +00:00
dcerpcstat_draw ( void * rs_arg )
2002-10-25 01:08:49 +00:00
{
2004-01-19 23:00:12 +00:00
rpcstat_t * rs = rs_arg ;
2003-06-21 01:42:46 +00:00
draw_srt_table_data ( & rs - > srt_table ) ;
2002-10-25 01:08:49 +00:00
}
/* since the gtk2 implementation of tap is multithreaded we must protect
* remove_tap_listener ( ) from modifying the list while draw_tap_listener ( )
* is running . the other protected block is in main . c
*
* there should not be any other critical regions in gtk2
*/
void protect_thread_critical_region ( void ) ;
void unprotect_thread_critical_region ( void ) ;
static void
win_destroy_cb ( GtkWindow * win _U_ , gpointer data )
{
rpcstat_t * rs = ( rpcstat_t * ) data ;
protect_thread_critical_region ( ) ;
remove_tap_listener ( rs ) ;
unprotect_thread_critical_region ( ) ;
2003-06-21 01:42:46 +00:00
free_srt_table_data ( & rs - > srt_table ) ;
2002-10-25 01:08:49 +00:00
g_free ( rs ) ;
}
/* When called, this function will create a new instance of gtk-dcerpcstat.
*/
2002-11-06 10:53:36 +00:00
static void
gtk_dcerpcstat_init ( char * optarg )
2002-10-25 01:08:49 +00:00
{
rpcstat_t * rs ;
guint32 i , max_procs ;
2003-10-10 11:24:24 +00:00
char * title_string ;
2002-10-25 01:08:49 +00:00
char filter_string [ 256 ] ;
GtkWidget * vbox ;
GtkWidget * stat_label ;
GtkWidget * filter_label ;
dcerpc_sub_dissector * procs ;
2002-11-06 10:53:36 +00:00
e_uuid_t uuid ;
2004-01-19 18:23:01 +00:00
guint d1 , d2 , d3 , d40 , d41 , d42 , d43 , d44 , d45 , d46 , d47 ;
2002-11-06 10:53:36 +00:00
int major , minor ;
2003-12-15 20:15:03 +00:00
guint16 ver ;
2002-11-06 10:53:36 +00:00
int pos = 0 ;
char * filter = NULL ;
2003-04-23 08:20:06 +00:00
GString * error_string ;
2003-10-10 11:11:37 +00:00
int hf_opnum ;
2002-11-06 10:53:36 +00:00
2004-01-19 23:43:29 +00:00
/*
* XXX - DCE RPC statistics are maintained only by major version ,
* not by major and minor version , so the minor version number is
* ignored .
*
* Should we just stop supporting minor version numbers here ?
* Or should we allow it to be omitted ? Or should we keep
* separate statistics for different minor version numbers ,
* and allow the minor version number to be omitted , and
* report aggregate statistics for all minor version numbers
* if it ' s omitted ?
*/
2003-06-21 01:42:46 +00:00
if ( sscanf ( optarg , " dcerpc,srt,%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x,%d.%d,%n " , & d1 , & d2 , & d3 , & d40 , & d41 , & d42 , & d43 , & d44 , & d45 , & d46 , & d47 , & major , & minor , & pos ) = = 13 ) {
2002-11-06 10:53:36 +00:00
uuid . Data1 = d1 ;
uuid . Data2 = d2 ;
uuid . Data3 = d3 ;
uuid . Data4 [ 0 ] = d40 ;
uuid . Data4 [ 1 ] = d41 ;
uuid . Data4 [ 2 ] = d42 ;
uuid . Data4 [ 3 ] = d43 ;
uuid . Data4 [ 4 ] = d44 ;
uuid . Data4 [ 5 ] = d45 ;
uuid . Data4 [ 6 ] = d46 ;
uuid . Data4 [ 7 ] = d47 ;
if ( pos ) {
filter = optarg + pos ;
} else {
filter = NULL ;
}
} else {
2003-06-21 01:42:46 +00:00
fprintf ( stderr , " ethereal: invalid \" -z dcerpc,srt,<uuid>,<major version>.<minor version>[,<filter>] \" argument \n " ) ;
2002-11-06 10:53:36 +00:00
exit ( 1 ) ;
}
2004-01-19 23:43:29 +00:00
if ( major < 0 | | major > 65535 ) {
fprintf ( stderr , " ethereal: dcerpcstat_init() Major version number %d is invalid - must be positive and <= 65535 \n " , major ) ;
2003-12-15 20:15:03 +00:00
exit ( 1 ) ;
}
2004-01-19 23:43:29 +00:00
if ( minor < 0 | | minor > 65535 ) {
fprintf ( stderr , " ethereal: dcerpcstat_init() Minor version number %d is invalid - must be positive and <= 65535 \n " , minor ) ;
2003-12-15 20:15:03 +00:00
exit ( 1 ) ;
}
2004-01-19 23:43:29 +00:00
ver = major ;
2002-10-25 01:08:49 +00:00
rs = g_malloc ( sizeof ( rpcstat_t ) ) ;
2003-12-15 20:15:03 +00:00
rs - > prog = dcerpc_get_proto_name ( & uuid , ver ) ;
2002-10-25 01:08:49 +00:00
if ( ! rs - > prog ) {
g_free ( rs ) ;
2004-01-19 23:43:29 +00:00
fprintf ( stderr , " ethereal: dcerpcstat_init() Protocol with uuid:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x v%u not supported \n " , uuid . Data1 , uuid . Data2 , uuid . Data3 , uuid . Data4 [ 0 ] , uuid . Data4 [ 1 ] , uuid . Data4 [ 2 ] , uuid . Data4 [ 3 ] , uuid . Data4 [ 4 ] , uuid . Data4 [ 5 ] , uuid . Data4 [ 6 ] , uuid . Data4 [ 7 ] , ver ) ;
2002-10-25 01:08:49 +00:00
exit ( 1 ) ;
}
2003-12-15 20:15:03 +00:00
hf_opnum = dcerpc_get_proto_hf_opnum ( & uuid , ver ) ;
procs = dcerpc_get_proto_sub_dissector ( & uuid , ver ) ;
2002-11-06 10:53:36 +00:00
rs - > uuid = uuid ;
2003-12-15 20:15:03 +00:00
rs - > ver = ver ;
2002-10-25 01:08:49 +00:00
rs - > win = gtk_window_new ( GTK_WINDOW_TOPLEVEL ) ;
2003-06-21 09:50:19 +00:00
gtk_window_set_default_size ( GTK_WINDOW ( rs - > win ) , 550 , 400 ) ;
2003-09-26 02:09:44 +00:00
dcerpcstat_set_title ( rs ) ;
2002-11-11 15:39:06 +00:00
SIGNAL_CONNECT ( rs - > win , " destroy " , win_destroy_cb , rs ) ;
2002-10-25 01:08:49 +00:00
vbox = gtk_vbox_new ( FALSE , 0 ) ;
gtk_container_add ( GTK_CONTAINER ( rs - > win ) , vbox ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( vbox ) , 10 ) ;
gtk_widget_show ( vbox ) ;
2003-10-10 11:24:24 +00:00
title_string = dcerpcstat_gen_title ( rs ) ;
2002-10-25 01:08:49 +00:00
stat_label = gtk_label_new ( title_string ) ;
2003-10-10 11:24:24 +00:00
g_free ( title_string ) ;
2002-10-25 01:08:49 +00:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , stat_label , FALSE , FALSE , 0 ) ;
gtk_widget_show ( stat_label ) ;
snprintf ( filter_string , 255 , " Filter:%s " , filter ? filter : " " ) ;
filter_label = gtk_label_new ( filter_string ) ;
gtk_box_pack_start ( GTK_BOX ( vbox ) , filter_label , FALSE , FALSE , 0 ) ;
gtk_widget_show ( filter_label ) ;
for ( i = 0 , max_procs = 0 ; procs [ i ] . name ; i + + ) {
if ( procs [ i ] . num > max_procs ) {
max_procs = procs [ i ] . num ;
}
}
rs - > num_procedures = max_procs + 1 ;
2003-06-22 04:00:21 +00:00
/* We must display TOP LEVEL Widget before calling init_srt_table() */
gtk_widget_show ( rs - > win ) ;
2003-10-10 11:11:37 +00:00
if ( hf_opnum ! = - 1 ) {
init_srt_table ( & rs - > srt_table , max_procs + 1 , vbox , proto_registrar_get_nth ( hf_opnum ) - > abbrev ) ;
} else {
init_srt_table ( & rs - > srt_table , max_procs + 1 , vbox , NULL ) ;
}
2003-06-21 01:42:46 +00:00
for ( i = 0 ; i < ( max_procs + 1 ) ; i + + ) {
2002-10-25 01:08:49 +00:00
int j ;
char * proc_name ;
proc_name = " unknown " ;
for ( j = 0 ; procs [ j ] . name ; j + + ) {
if ( procs [ j ] . num = = i ) {
proc_name = procs [ j ] . name ;
}
}
2003-06-21 01:42:46 +00:00
init_srt_table_row ( & rs - > srt_table , i , proc_name ) ;
2002-10-25 01:08:49 +00:00
}
2004-01-19 18:23:01 +00:00
error_string = register_tap_listener ( " dcerpc " , rs , filter , dcerpcstat_reset , dcerpcstat_packet , dcerpcstat_draw ) ;
2003-04-23 08:20:06 +00:00
if ( error_string ) {
2002-10-25 01:08:49 +00:00
/* error, we failed to attach to the tap. clean up */
2004-01-31 03:22:42 +00:00
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK , error_string - > str ) ;
2003-04-23 08:20:06 +00:00
g_string_free ( error_string , TRUE ) ;
2003-06-21 01:42:46 +00:00
free_srt_table_data ( & rs - > srt_table ) ;
2002-10-25 01:08:49 +00:00
g_free ( rs ) ;
return ;
}
gtk_widget_show_all ( rs - > win ) ;
2004-01-13 22:49:15 +00:00
retap_packets ( & cfile ) ;
2002-10-25 01:08:49 +00:00
}
static e_uuid_t * dcerpc_uuid_program = NULL ;
static guint16 dcerpc_version ;
2003-09-26 02:09:44 +00:00
static GtkWidget * dlg = NULL ;
static GtkWidget * prog_menu ;
static GtkWidget * vers_opt , * vers_menu ;
static GtkWidget * filter_entry ;
2003-09-05 00:48:58 +00:00
static dcerpc_uuid_key * current_uuid_key = NULL ;
static dcerpc_uuid_value * current_uuid_value = NULL ;
static dcerpc_uuid_key * new_uuid_key = NULL ;
static dcerpc_uuid_value * new_uuid_value = NULL ;
2002-10-25 01:08:49 +00:00
static void
dcerpcstat_start_button_clicked ( GtkWidget * item _U_ , gpointer data _U_ )
{
2003-09-26 02:09:44 +00:00
GString * str ;
2002-10-25 01:08:49 +00:00
char * filter ;
2003-09-26 02:09:44 +00:00
str = g_string_new ( " dcerpc,srt " ) ;
g_string_sprintfa ( str ,
2003-12-15 20:15:03 +00:00
" ,%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x,%u.%u " ,
2003-09-26 02:09:44 +00:00
dcerpc_uuid_program - > Data1 , dcerpc_uuid_program - > Data2 ,
dcerpc_uuid_program - > Data3 ,
dcerpc_uuid_program - > Data4 [ 0 ] , dcerpc_uuid_program - > Data4 [ 1 ] ,
dcerpc_uuid_program - > Data4 [ 2 ] , dcerpc_uuid_program - > Data4 [ 3 ] ,
dcerpc_uuid_program - > Data4 [ 4 ] , dcerpc_uuid_program - > Data4 [ 5 ] ,
dcerpc_uuid_program - > Data4 [ 6 ] , dcerpc_uuid_program - > Data4 [ 7 ] ,
2004-01-19 23:43:29 +00:00
dcerpc_version , 0 ) ;
2002-10-25 01:08:49 +00:00
filter = ( char * ) gtk_entry_get_text ( GTK_ENTRY ( filter_entry ) ) ;
2003-09-26 02:09:44 +00:00
if ( filter [ 0 ] ! = 0 ) {
g_string_sprintfa ( str , " ,%s " , filter ) ;
2002-10-25 01:08:49 +00:00
}
2002-11-06 10:53:36 +00:00
2003-09-26 02:09:44 +00:00
gtk_dcerpcstat_init ( str - > str ) ;
g_string_free ( str , TRUE ) ;
2002-10-25 01:08:49 +00:00
}
static void
dcerpcstat_version_select ( GtkWidget * item _U_ , gpointer key )
{
int vers = ( int ) key ;
dcerpc_version = vers ;
}
static void *
dcerpcstat_find_vers ( gpointer * key , gpointer * value _U_ , gpointer * user_data _U_ )
{
dcerpc_uuid_key * k = ( dcerpc_uuid_key * ) key ;
GtkWidget * menu_item ;
char vs [ 5 ] ;
if ( ! uuid_equal ( ( & k - > uuid ) , dcerpc_uuid_program ) ) {
return NULL ;
}
2004-01-19 23:43:29 +00:00
sprintf ( vs , " %u " , k - > ver ) ;
2002-10-25 01:08:49 +00:00
menu_item = gtk_menu_item_new_with_label ( vs ) ;
2002-11-11 15:39:06 +00:00
SIGNAL_CONNECT ( menu_item , " activate " , dcerpcstat_version_select ,
( ( int ) k - > ver ) ) ;
2002-10-25 01:08:49 +00:00
gtk_widget_show ( menu_item ) ;
gtk_menu_append ( GTK_MENU ( vers_menu ) , menu_item ) ;
if ( dcerpc_version = = 0xffff ) {
dcerpc_version = k - > ver ;
}
return NULL ;
}
static void
dcerpcstat_program_select ( GtkWidget * item _U_ , gpointer key )
{
dcerpc_uuid_key * k = ( dcerpc_uuid_key * ) key ;
dcerpc_uuid_program = & k - > uuid ;
/* change version menu */
dcerpc_version = 0xffff ;
gtk_object_destroy ( GTK_OBJECT ( vers_menu ) ) ;
vers_menu = gtk_menu_new ( ) ;
g_hash_table_foreach ( dcerpc_uuids , ( GHFunc ) dcerpcstat_find_vers , NULL ) ;
gtk_option_menu_set_menu ( GTK_OPTION_MENU ( vers_opt ) , vers_menu ) ;
}
2003-11-10 07:44:47 +00:00
static GtkWidget * program_submenu_menu ;
static GtkWidget * program_submenu_item ;
static GtkWidget * program_submenu_label ;
static int program_subitem_index ;
static char * first_menu_name ;
2003-09-05 00:48:58 +00:00
static void
dcerpcstat_add_program_to_menu ( dcerpc_uuid_key * k , dcerpc_uuid_value * v )
{
GtkWidget * program_menu_item ;
2003-11-10 07:44:47 +00:00
GtkWidget * box ;
char str [ 64 ] ;
switch ( program_subitem_index % 15 ) {
case 0 :
first_menu_name = v - > name ;
snprintf ( str , 63 , " %s ... " , v - > name ) ;
program_submenu_item = gtk_menu_item_new ( ) ;
box = gtk_hbox_new ( TRUE , 0 ) ;
gtk_container_add ( GTK_CONTAINER ( program_submenu_item ) , box ) ;
program_submenu_label = gtk_label_new ( str ) ;
gtk_box_pack_start ( GTK_BOX ( box ) , program_submenu_label , TRUE , TRUE , 0 ) ;
gtk_widget_show ( program_submenu_label ) ;
gtk_widget_show ( box ) ;
gtk_menu_append ( GTK_MENU ( prog_menu ) , program_submenu_item ) ;
gtk_widget_show ( program_submenu_item ) ;
program_submenu_menu = gtk_menu_new ( ) ;
gtk_menu_item_set_submenu ( GTK_MENU_ITEM ( program_submenu_item ) , program_submenu_menu ) ;
break ;
case 14 :
snprintf ( str , 63 , " %s - %s " , first_menu_name , v - > name ) ;
gtk_label_set_text ( GTK_LABEL ( program_submenu_label ) , str ) ;
break ;
/*qqq*/
}
program_subitem_index + + ;
2003-09-05 00:48:58 +00:00
program_menu_item = gtk_menu_item_new_with_label ( v - > name ) ;
SIGNAL_CONNECT ( program_menu_item , " activate " , dcerpcstat_program_select , k ) ;
gtk_widget_show ( program_menu_item ) ;
2003-11-10 07:44:47 +00:00
gtk_menu_append ( GTK_MENU ( program_submenu_menu ) , program_menu_item ) ;
2003-09-05 00:48:58 +00:00
if ( ! dcerpc_uuid_program ) {
dcerpc_uuid_program = & k - > uuid ;
}
return ;
}
2002-10-25 01:08:49 +00:00
static void *
2003-09-05 00:48:58 +00:00
dcerpcstat_find_next_program ( gpointer * key , gpointer * value , gpointer * user_data _U_ )
2002-10-25 01:08:49 +00:00
{
dcerpc_uuid_key * k = ( dcerpc_uuid_key * ) key ;
dcerpc_uuid_value * v = ( dcerpc_uuid_value * ) value ;
2003-09-05 00:48:58 +00:00
/* first time called, just set new_uuid to this one */
if ( ( current_uuid_key = = NULL ) & & ( new_uuid_key = = NULL ) ) {
new_uuid_key = k ;
new_uuid_value = v ;
return NULL ;
}
2002-10-25 01:08:49 +00:00
2003-09-05 00:48:58 +00:00
/* if we havent got a current one yet, just check the new
and scan for the first one alphabetically */
if ( current_uuid_key = = NULL ) {
if ( strcmp ( new_uuid_value - > name , v - > name ) > 0 ) {
new_uuid_key = k ;
new_uuid_value = v ;
return NULL ;
}
return NULL ;
}
2002-10-25 01:08:49 +00:00
2003-09-05 00:48:58 +00:00
/* searching for the next one we are only interested in those
that sorts alphabetically after the current one */
if ( strcmp ( current_uuid_value - > name , v - > name ) > = 0 ) {
/* this one doesnt so just skip it */
return NULL ;
}
/* is it the first potential new entry? */
if ( new_uuid_key = = NULL ) {
new_uuid_key = k ;
new_uuid_value = v ;
return NULL ;
}
/* does it sort before the current new one? */
if ( strcmp ( new_uuid_value - > name , v - > name ) > 0 ) {
new_uuid_key = k ;
new_uuid_value = v ;
return NULL ;
2002-10-25 01:08:49 +00:00
}
return NULL ;
}
static void
dlg_destroy_cb ( void )
{
dlg = NULL ;
}
2003-04-24 23:17:43 +00:00
static void
dlg_cancel_cb ( GtkWidget * cancel_bt _U_ , gpointer parent_w )
{
gtk_widget_destroy ( GTK_WIDGET ( parent_w ) ) ;
}
2003-04-23 05:37:23 +00:00
static void
2002-10-25 01:08:49 +00:00
gtk_dcerpcstat_cb ( GtkWidget * w _U_ , gpointer d _U_ )
{
2003-09-26 02:09:44 +00:00
GtkWidget * dlg_box ;
GtkWidget * prog_box , * prog_label , * prog_opt ;
GtkWidget * vers_label ;
2003-10-27 01:35:53 +00:00
GtkWidget * filter_box , * filter_bt ;
2003-09-26 02:09:44 +00:00
GtkWidget * bbox , * start_button , * cancel_button ;
2003-12-04 00:45:39 +00:00
const char * filter ;
2003-10-27 01:35:53 +00:00
static construct_args_t args = {
" Service Response Time Statistics Filter " ,
2004-01-25 18:39:55 +00:00
FALSE ,
2003-10-27 01:35:53 +00:00
FALSE
} ;
2003-04-24 23:17:43 +00:00
/* if the window is already open, bring it to front and
un - minimize it , as necessary */
2002-10-25 01:08:49 +00:00
if ( dlg ) {
2003-04-24 23:17:43 +00:00
reactivate_window ( dlg ) ;
2002-10-25 01:08:49 +00:00
return ;
}
2003-09-26 02:09:44 +00:00
dlg = dlg_window_new ( " Ethereal: Compute DCE-RPC SRT statistics " ) ;
2002-11-11 15:39:06 +00:00
SIGNAL_CONNECT ( dlg , " destroy " , dlg_destroy_cb , NULL ) ;
2003-09-26 02:09:44 +00:00
dlg_box = gtk_vbox_new ( FALSE , 10 ) ;
gtk_container_border_width ( GTK_CONTAINER ( dlg_box ) , 10 ) ;
2002-10-25 01:08:49 +00:00
gtk_container_add ( GTK_CONTAINER ( dlg ) , dlg_box ) ;
gtk_widget_show ( dlg_box ) ;
2003-09-26 02:09:44 +00:00
/* Program box */
prog_box = gtk_hbox_new ( FALSE , 3 ) ;
2002-10-25 01:08:49 +00:00
/* Program label */
gtk_container_set_border_width ( GTK_CONTAINER ( prog_box ) , 10 ) ;
prog_label = gtk_label_new ( " Program: " ) ;
gtk_box_pack_start ( GTK_BOX ( prog_box ) , prog_label , FALSE , FALSE , 0 ) ;
gtk_widget_show ( prog_label ) ;
/* Program menu */
prog_opt = gtk_option_menu_new ( ) ;
prog_menu = gtk_menu_new ( ) ;
2003-09-05 00:48:58 +00:00
current_uuid_key = NULL ;
current_uuid_value = NULL ;
2003-11-10 07:44:47 +00:00
/*qqq*/
program_submenu_item = NULL ;
program_submenu_menu = NULL ;
program_subitem_index = 0 ;
2003-09-05 00:48:58 +00:00
do {
new_uuid_key = NULL ;
new_uuid_value = NULL ;
g_hash_table_foreach ( dcerpc_uuids , ( GHFunc ) dcerpcstat_find_next_program , NULL ) ;
if ( new_uuid_key ) {
dcerpcstat_add_program_to_menu ( new_uuid_key , new_uuid_value ) ;
}
current_uuid_key = new_uuid_key ;
current_uuid_value = new_uuid_value ;
} while ( new_uuid_key ! = NULL ) ;
2002-10-25 01:08:49 +00:00
gtk_option_menu_set_menu ( GTK_OPTION_MENU ( prog_opt ) , prog_menu ) ;
gtk_box_pack_start ( GTK_BOX ( prog_box ) , prog_opt , TRUE , TRUE , 0 ) ;
gtk_widget_show ( prog_opt ) ;
/* Version label */
gtk_container_set_border_width ( GTK_CONTAINER ( prog_box ) , 10 ) ;
vers_label = gtk_label_new ( " Version: " ) ;
gtk_box_pack_start ( GTK_BOX ( prog_box ) , vers_label , FALSE , FALSE , 0 ) ;
gtk_widget_show ( vers_label ) ;
/* Version menu */
vers_opt = gtk_option_menu_new ( ) ;
vers_menu = gtk_menu_new ( ) ;
dcerpc_version = 0xffff ;
g_hash_table_foreach ( dcerpc_uuids , ( GHFunc ) dcerpcstat_find_vers , NULL ) ;
gtk_option_menu_set_menu ( GTK_OPTION_MENU ( vers_opt ) , vers_menu ) ;
gtk_box_pack_start ( GTK_BOX ( prog_box ) , vers_opt , TRUE , TRUE , 0 ) ;
gtk_widget_show ( vers_opt ) ;
gtk_box_pack_start ( GTK_BOX ( dlg_box ) , prog_box , TRUE , TRUE , 0 ) ;
gtk_widget_show ( prog_box ) ;
2003-09-26 02:09:44 +00:00
/* Filter box */
filter_box = gtk_hbox_new ( FALSE , 3 ) ;
2002-10-25 01:08:49 +00:00
/* Filter label */
2004-01-21 03:54:32 +00:00
filter_bt = BUTTON_NEW_FROM_STOCK ( ETHEREAL_STOCK_DISPLAY_FILTER_ENTRY ) ;
2003-10-27 01:35:53 +00:00
SIGNAL_CONNECT ( filter_bt , " clicked " , display_filter_construct_cb , & args ) ;
gtk_box_pack_start ( GTK_BOX ( filter_box ) , filter_bt , FALSE , FALSE , 0 ) ;
gtk_widget_show ( filter_bt ) ;
/* Filter entry */
filter_entry = gtk_entry_new ( ) ;
2004-01-21 03:54:32 +00:00
WIDGET_SET_SIZE ( filter_entry , 300 , - 1 ) ;
2002-10-25 01:08:49 +00:00
2003-09-26 02:09:44 +00:00
gtk_box_pack_start ( GTK_BOX ( filter_box ) , filter_entry , TRUE , TRUE , 0 ) ;
2003-08-19 10:09:20 +00:00
filter = gtk_entry_get_text ( GTK_ENTRY ( main_display_filter_widget ) ) ;
if ( filter ) {
gtk_entry_set_text ( GTK_ENTRY ( filter_entry ) , filter ) ;
}
2002-10-25 01:08:49 +00:00
gtk_widget_show ( filter_entry ) ;
gtk_box_pack_start ( GTK_BOX ( dlg_box ) , filter_box , TRUE , TRUE , 0 ) ;
gtk_widget_show ( filter_box ) ;
2004-01-25 18:39:55 +00:00
OBJECT_SET_DATA ( filter_bt , E_FILT_TE_PTR_KEY , filter_entry ) ;
2003-09-26 02:09:44 +00:00
/* button box */
2004-01-21 21:19:34 +00:00
bbox = dlg_button_row_new ( ETHEREAL_STOCK_CREATE_STAT , GTK_STOCK_CANCEL , NULL ) ;
2003-09-26 02:09:44 +00:00
gtk_box_pack_start ( GTK_BOX ( dlg_box ) , bbox , FALSE , FALSE , 0 ) ;
2004-01-21 21:19:34 +00:00
gtk_widget_show ( bbox ) ;
2003-04-24 23:17:43 +00:00
2004-01-21 21:19:34 +00:00
start_button = OBJECT_GET_DATA ( bbox , ETHEREAL_STOCK_CREATE_STAT ) ;
gtk_widget_grab_default ( start_button ) ;
2002-11-11 15:39:06 +00:00
SIGNAL_CONNECT_OBJECT ( start_button , " clicked " ,
dcerpcstat_start_button_clicked , NULL ) ;
2002-10-25 01:08:49 +00:00
2004-01-21 21:19:34 +00:00
cancel_button = OBJECT_GET_DATA ( bbox , GTK_STOCK_CANCEL ) ;
2003-04-24 23:17:43 +00:00
SIGNAL_CONNECT ( cancel_button , " clicked " , dlg_cancel_cb , dlg ) ;
/* Catch the "activate" signal on the filter text entry, so that
if the user types Return there , we act as if the " Create Stat "
button had been selected , as happens if Return is typed if some
widget that * doesn ' t * handle the Return key has the input
focus . */
dlg_set_activate ( filter_entry , start_button ) ;
/* Catch the "key_press_event" signal in the window, so that we can
catch the ESC key being pressed and act as if the " Cancel " button
had been selected . */
dlg_set_cancel ( dlg , cancel_button ) ;
/* Give the initial focus to the "Filter" entry box. */
gtk_widget_grab_focus ( filter_entry ) ;
2002-10-25 01:08:49 +00:00
gtk_widget_show_all ( dlg ) ;
}
2002-11-06 10:53:36 +00:00
void
register_tap_listener_gtkdcerpcstat ( void )
{
2003-06-21 01:42:46 +00:00
register_ethereal_tap ( " dcerpc,srt, " , gtk_dcerpcstat_init ) ;
2002-11-06 10:53:36 +00:00
}
2003-04-23 05:37:23 +00:00
void
register_tap_menu_gtkdcerpcstat ( void )
{
2004-01-03 18:05:57 +00:00
register_tap_menu_item ( " _Statistics/Service Response Time/DCE-RPC... " ,
2003-12-17 22:13:08 +00:00
gtk_dcerpcstat_cb , NULL , NULL , NULL ) ;
2003-04-23 05:37:23 +00:00
}