Create very basic "generic" stat tap API to create a "GUI" independent table.

A few sample tap/dissectors (ANSI/A, ANSI MAP) are also included to test the API.  The "GUI output" is a bit raw and could use some "prettying up", but all the basic hooks are there.

Telephony "stat grouping" needs to be better alphabetized to properly populate menu (on GTK, probably Qt)

Change-Id: I98514171f69c4ab3a304dccb26c71d629703c9ab
Reviewed-on: https://code.wireshark.org/review/9110
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Michael Mann 2015-06-23 08:53:17 -04:00
parent 09ea473cee
commit a8ff1e2778
34 changed files with 1249 additions and 1038 deletions

View File

@ -1140,7 +1140,6 @@ if(ENABLE_EXTCAP)
endif()
set(TSHARK_TAP_SRC
ui/cli/tap-ansi_astat.c
ui/cli/tap-bootpstat.c
ui/cli/tap-camelcounter.c
ui/cli/tap-camelsrt.c
@ -1167,6 +1166,7 @@ set(TSHARK_TAP_SRC
ui/cli/tap-rtp.c
ui/cli/tap-rtspstat.c
ui/cli/tap-sctpchunkstat.c
ui/cli/tap-simple_stattable.c
ui/cli/tap-sipstat.c
ui/cli/tap-smbsids.c
ui/cli/tap-srt.c

View File

@ -88,6 +88,7 @@
#include <epan/prefs.h>
#include <epan/expert.h>
#include <epan/tap.h>
#include <epan/stat_tap_ui.h>
#include <epan/asn1.h>
#include "packet-ber.h"
@ -4448,6 +4449,104 @@ static void range_add_callback(guint32 ssn)
}
}
/* TAP STAT INFO */
typedef enum
{
OPCODE_COLUMN = 0,
OPERATION_COLUMN,
COUNT_COLUMN,
TOTAL_BYTES_COLUMN,
AVG_BYTES_COLUMN
} ansi_map_stat_columns;
static stat_tap_table_item stat_fields[] = {{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "OpCode", "0x%02x"}, {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Operation Name", "%-50s"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Count", " %d "}, {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Total Bytes", " %d "},
{TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", " %8.2f "}};
void ansi_map_stat_init(new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
{
int num_fields = sizeof(stat_fields)/sizeof(stat_tap_table_item);
new_stat_tap_table* table = new_stat_tap_init_table("ANSI MAP Operation Statistics", num_fields, 0, "ansi_map.op_code", gui_callback, gui_data);
int i = 0;
stat_tap_table_item_type items[sizeof(stat_fields)/sizeof(stat_tap_table_item)];
new_stat_tap_add_table(new_stat, table);
/* Add a fow for each value type */
while (ansi_map_opr_code_strings[i].strptr)
{
items[OPCODE_COLUMN].type = TABLE_ITEM_UINT;
items[OPCODE_COLUMN].value.uint_value = ansi_map_opr_code_strings[i].value;
items[OPERATION_COLUMN].type = TABLE_ITEM_STRING;
items[OPERATION_COLUMN].value.string_value = ansi_map_opr_code_strings[i].strptr;
items[COUNT_COLUMN].type = TABLE_ITEM_UINT;
items[COUNT_COLUMN].value.uint_value = 0;
items[TOTAL_BYTES_COLUMN].type = TABLE_ITEM_UINT;
items[TOTAL_BYTES_COLUMN].value.uint_value = 0;
items[AVG_BYTES_COLUMN].type = TABLE_ITEM_FLOAT;
items[AVG_BYTES_COLUMN].value.float_value = 0.0;
new_stat_tap_init_table_row(table, ansi_map_opr_code_strings[i].value, num_fields, items);
i++;
}
}
static gboolean
ansi_map_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *data)
{
new_stat_data_t* stat_data = (new_stat_data_t*)tapdata;
const ansi_map_tap_rec_t *data_p = (const ansi_map_tap_rec_t *)data;
new_stat_tap_table* table;
stat_tap_table_item_type* item_data;
guint i = 0, count, total_bytes;
/* Only tracking field values we know */
if (try_val_to_str(data_p->message_type, ansi_map_opr_code_strings) == NULL)
return FALSE;
table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, i);
item_data = new_stat_tap_get_field_data(table, data_p->message_type, COUNT_COLUMN);
item_data->value.uint_value++;
count = item_data->value.uint_value;
new_stat_tap_set_field_data(table, data_p->message_type, COUNT_COLUMN, item_data);
item_data = new_stat_tap_get_field_data(table, data_p->message_type, TOTAL_BYTES_COLUMN);
item_data->value.uint_value += data_p->size;
total_bytes = item_data->value.uint_value;
new_stat_tap_set_field_data(table, data_p->message_type, TOTAL_BYTES_COLUMN, item_data);
item_data = new_stat_tap_get_field_data(table, data_p->message_type, AVG_BYTES_COLUMN);
item_data->value.float_value = (float)total_bytes/(float)count;
new_stat_tap_set_field_data(table, data_p->message_type, AVG_BYTES_COLUMN, item_data);
return TRUE;
}
static void
ansi_map_stat_reset(new_stat_tap_table* table)
{
guint element;
stat_tap_table_item_type* item_data;
for (element = 0; element < table->num_elements; element++)
{
item_data = new_stat_tap_get_field_data(table, element, COUNT_COLUMN);
item_data->value.uint_value = 0;
new_stat_tap_set_field_data(table, element, COUNT_COLUMN, item_data);
item_data = new_stat_tap_get_field_data(table, element, TOTAL_BYTES_COLUMN);
item_data->value.uint_value = 0;
new_stat_tap_set_field_data(table, element, TOTAL_BYTES_COLUMN, item_data);
item_data = new_stat_tap_get_field_data(table, element, AVG_BYTES_COLUMN);
item_data->value.float_value = 0.0;
new_stat_tap_set_field_data(table, element, AVG_BYTES_COLUMN, item_data);
}
}
void
proto_reg_handoff_ansi_map(void)
{
@ -5338,6 +5437,22 @@ void proto_register_ansi_map(void) {
{NULL, NULL, -1}
};
/* TAP STAT INFO */
static new_stat_tap_ui stat_table = {
REGISTER_STAT_GROUP_TELEPHONY,
"ANSI Map Operation Statistics",
"ansi_map",
"ansi_map",
ansi_map_stat_init,
ansi_map_stat_packet,
ansi_map_stat_reset,
NULL,
NULL,
sizeof(stat_fields)/sizeof(stat_tap_table_item), stat_fields,
0, NULL,
NULL
};
/* Register protocol */
proto_ansi_map = proto_register_protocol(PNAME, PSNAME, PFNAME);
/* Register fields and subtrees */
@ -5378,4 +5493,5 @@ void proto_register_ansi_map(void) {
&ansi_map_response_matching_type, ansi_map_response_matching_type_values, FALSE);
register_init_routine(&ansi_map_init_protocol);
register_new_stat_tap_ui(&stat_table);
}

View File

@ -44,6 +44,7 @@
#include <epan/exceptions.h>
#include <epan/prefs.h>
#include <epan/tap.h>
#include <epan/stat_tap_ui.h>
#include <epan/strutil.h>
#include <epan/expert.h>
#include <epan/to_str.h>
@ -10746,6 +10747,135 @@ dissect_sip_dtap_bsmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
/* TAP STAT INFO */
typedef enum
{
IEI_COLUMN = 0,
MESSAGE_NAME_COLUMN,
COUNT_COLUMN
} ansi_a_stat_columns;
static stat_tap_table_item dtap_stat_fields[] = {{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "IEI", "0x%02x "}, {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Message Name", "%-50s"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Count", "%d"}};
void ansi_a_dtap_stat_init(new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
{
int num_fields = sizeof(dtap_stat_fields)/sizeof(stat_tap_table_item);
new_stat_tap_table* table = new_stat_tap_init_table("ANSI A-I/F DTAP Statistics", num_fields, 0, NULL, gui_callback, gui_data);
int i = 0;
stat_tap_table_item_type items[sizeof(dtap_stat_fields)/sizeof(stat_tap_table_item)];
new_stat_tap_add_table(new_stat, table);
/* Add a fow for each value type */
while (ansi_a_dtap_strings[i].strptr)
{
items[IEI_COLUMN].type = TABLE_ITEM_UINT;
items[IEI_COLUMN].value.uint_value = ansi_a_dtap_strings[i].value;
items[MESSAGE_NAME_COLUMN].type = TABLE_ITEM_STRING;
items[MESSAGE_NAME_COLUMN].value.string_value = ansi_a_dtap_strings[i].strptr;
items[COUNT_COLUMN].type = TABLE_ITEM_UINT;
items[COUNT_COLUMN].value.uint_value = 0;
new_stat_tap_init_table_row(table, i, num_fields, items);
i++;
}
}
static gboolean
ansi_a_dtap_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *data)
{
new_stat_data_t* stat_data = (new_stat_data_t*)tapdata;
const ansi_a_tap_rec_t *data_p = (const ansi_a_tap_rec_t *)data;
stat_tap_table_item_type* dtap_data;
new_stat_tap_table* table;
guint i = 0, idx;
if (data_p->pdu_type == BSSAP_PDU_TYPE_DTAP)
{
if (my_try_val_to_str_idx(data_p->message_type, ansi_a_dtap_strings, &idx) == NULL)
return FALSE;
table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, i);
dtap_data = new_stat_tap_get_field_data(table, data_p->message_type, COUNT_COLUMN);
dtap_data->value.uint_value++;
new_stat_tap_set_field_data(table, data_p->message_type, COUNT_COLUMN, dtap_data);
return TRUE;
}
return FALSE;
}
static void
ansi_a_stat_reset(new_stat_tap_table* table)
{
guint element;
stat_tap_table_item_type* item_data;
for (element = 0; element < table->num_elements; element++)
{
item_data = new_stat_tap_get_field_data(table, element, COUNT_COLUMN);
item_data->value.uint_value = 0;
new_stat_tap_set_field_data(table, element, COUNT_COLUMN, item_data);
}
}
static stat_tap_table_item bsmap_stat_fields[] = {{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "IEI", "0x%02x "}, {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Message Name", "%-50s"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Count", "%d"}};
void ansi_a_bsmap_stat_init(new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
{
int num_fields = sizeof(bsmap_stat_fields)/sizeof(stat_tap_table_item);
new_stat_tap_table* table = new_stat_tap_init_table("ANSI A-I/F BSMAP Statistics", num_fields, 0, NULL, gui_callback, gui_data);
int i = 0;
stat_tap_table_item_type items[sizeof(bsmap_stat_fields)/sizeof(stat_tap_table_item)];
new_stat_tap_add_table(new_stat, table);
/* Add a fow for each value type */
while (ansi_a_bsmap_strings[i].strptr)
{
items[IEI_COLUMN].type = TABLE_ITEM_UINT;
items[IEI_COLUMN].value.uint_value = ansi_a_bsmap_strings[i].value;
items[MESSAGE_NAME_COLUMN].type = TABLE_ITEM_STRING;
items[MESSAGE_NAME_COLUMN].value.string_value = ansi_a_bsmap_strings[i].strptr;
items[COUNT_COLUMN].type = TABLE_ITEM_UINT;
items[COUNT_COLUMN].value.uint_value = 0;
new_stat_tap_init_table_row(table, i, num_fields, items);
i++;
}
}
static gboolean
ansi_a_bsmap_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *data)
{
new_stat_data_t* stat_data = (new_stat_data_t*)tapdata;
const ansi_a_tap_rec_t *data_p = (const ansi_a_tap_rec_t *)data;
stat_tap_table_item_type* dtap_data;
new_stat_tap_table* table;
guint i = 0, idx;
if (data_p->pdu_type == BSSAP_PDU_TYPE_BSMAP)
{
if (my_try_val_to_str_idx(data_p->message_type, ansi_a_bsmap_strings, &idx) == NULL)
return FALSE;
table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, i);
dtap_data = new_stat_tap_get_field_data(table, data_p->message_type, COUNT_COLUMN);
dtap_data->value.uint_value++;
new_stat_tap_set_field_data(table, data_p->message_type, COUNT_COLUMN, dtap_data);
return TRUE;
}
return FALSE;
}
/* Register the protocol with Wireshark */
void
proto_register_ansi_a(void)
@ -12729,6 +12859,36 @@ proto_register_ansi_a(void)
gint **ett;
gint ett_len = (NUM_INDIVIDUAL_ELEMS+MAX_NUM_DTAP_MSG+MAX_NUM_BSMAP_MSG+MAX_NUM_ELEM_1+NUM_FWD_MS_INFO_REC+NUM_REV_MS_INFO_REC) * sizeof(gint *);
static new_stat_tap_ui dtap_stat_table = {
REGISTER_STAT_GROUP_TELEPHONY,
"ANSI A-I/F DTAP Statistics",
"ansi_a",
"ansi_a,dtap",
ansi_a_dtap_stat_init,
ansi_a_dtap_stat_packet,
ansi_a_stat_reset,
NULL,
NULL,
sizeof(dtap_stat_fields)/sizeof(stat_tap_table_item), dtap_stat_fields,
0, NULL,
NULL
};
static new_stat_tap_ui bsmap_stat_table = {
REGISTER_STAT_GROUP_TELEPHONY,
"ANSI A-I/F BSMAP Statistics",
"ansi_a",
"ansi_a,bsmap",
ansi_a_bsmap_stat_init,
ansi_a_bsmap_stat_packet,
ansi_a_stat_reset,
NULL,
NULL,
sizeof(bsmap_stat_fields)/sizeof(stat_tap_table_item), bsmap_stat_fields,
0, NULL,
NULL
};
/*
* XXX - at least one version of the HP C compiler apparently doesn't
* recognize constant expressions using the "?" operator as being
@ -12845,6 +13005,9 @@ proto_register_ansi_a(void)
&global_a_info_display);
g_free(ett);
register_new_stat_tap_ui(&dtap_stat_table);
register_new_stat_tap_ui(&bsmap_stat_table);
}

View File

@ -96,6 +96,7 @@
#include <epan/prefs.h>
#include <epan/expert.h>
#include <epan/tap.h>
#include <epan/stat_tap_ui.h>
#include <epan/asn1.h>
#include "packet-ber.h"
@ -883,7 +884,7 @@ static int hf_ansi_map_interSystemSMSDeliveryPointToPointRes = -1; /* InterSyst
static int hf_ansi_map_qualificationRequest2Res = -1; /* QualificationRequest2Res */
/*--- End of included file: packet-ansi_map-hf.c ---*/
#line 327 "../../asn1/ansi_map/packet-ansi_map-template.c"
#line 328 "../../asn1/ansi_map/packet-ansi_map-template.c"
/* Initialize the subtree pointers */
static gint ett_ansi_map = -1;
@ -1143,7 +1144,7 @@ static gint ett_ansi_map_InvokeData = -1;
static gint ett_ansi_map_ReturnData = -1;
/*--- End of included file: packet-ansi_map-ett.c ---*/
#line 359 "../../asn1/ansi_map/packet-ansi_map-template.c"
#line 360 "../../asn1/ansi_map/packet-ansi_map-template.c"
static expert_field ei_ansi_map_nr_not_used = EI_INIT;
static expert_field ei_ansi_map_unknown_invokeData_blob = EI_INIT;
@ -15279,7 +15280,7 @@ dissect_ansi_map_QualificationRequest2Res(gboolean implicit_tag _U_, tvbuff_t *t
/*--- End of included file: packet-ansi_map-fn.c ---*/
#line 3634 "../../asn1/ansi_map/packet-ansi_map-template.c"
#line 3635 "../../asn1/ansi_map/packet-ansi_map-template.c"
/*
* 6.5.2.dk N.S0013-0 v 1.0,X.S0004-550-E v1.0 2.301
@ -16097,6 +16098,104 @@ static void range_add_callback(guint32 ssn)
}
}
/* TAP STAT INFO */
typedef enum
{
OPCODE_COLUMN = 0,
OPERATION_COLUMN,
COUNT_COLUMN,
TOTAL_BYTES_COLUMN,
AVG_BYTES_COLUMN
} ansi_map_stat_columns;
static stat_tap_table_item stat_fields[] = {{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "OpCode", "0x%02x"}, {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Operation Name", "%-50s"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Count", " %d "}, {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Total Bytes", " %d "},
{TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", " %8.2f "}};
void ansi_map_stat_init(new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
{
int num_fields = sizeof(stat_fields)/sizeof(stat_tap_table_item);
new_stat_tap_table* table = new_stat_tap_init_table("ANSI MAP Operation Statistics", num_fields, 0, "ansi_map.op_code", gui_callback, gui_data);
int i = 0;
stat_tap_table_item_type items[sizeof(stat_fields)/sizeof(stat_tap_table_item)];
new_stat_tap_add_table(new_stat, table);
/* Add a fow for each value type */
while (ansi_map_opr_code_strings[i].strptr)
{
items[OPCODE_COLUMN].type = TABLE_ITEM_UINT;
items[OPCODE_COLUMN].value.uint_value = ansi_map_opr_code_strings[i].value;
items[OPERATION_COLUMN].type = TABLE_ITEM_STRING;
items[OPERATION_COLUMN].value.string_value = ansi_map_opr_code_strings[i].strptr;
items[COUNT_COLUMN].type = TABLE_ITEM_UINT;
items[COUNT_COLUMN].value.uint_value = 0;
items[TOTAL_BYTES_COLUMN].type = TABLE_ITEM_UINT;
items[TOTAL_BYTES_COLUMN].value.uint_value = 0;
items[AVG_BYTES_COLUMN].type = TABLE_ITEM_FLOAT;
items[AVG_BYTES_COLUMN].value.float_value = 0.0;
new_stat_tap_init_table_row(table, ansi_map_opr_code_strings[i].value, num_fields, items);
i++;
}
}
static gboolean
ansi_map_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *data)
{
new_stat_data_t* stat_data = (new_stat_data_t*)tapdata;
const ansi_map_tap_rec_t *data_p = (const ansi_map_tap_rec_t *)data;
new_stat_tap_table* table;
stat_tap_table_item_type* item_data;
guint i = 0, count, total_bytes;
/* Only tracking field values we know */
if (try_val_to_str(data_p->message_type, ansi_map_opr_code_strings) == NULL)
return FALSE;
table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, i);
item_data = new_stat_tap_get_field_data(table, data_p->message_type, COUNT_COLUMN);
item_data->value.uint_value++;
count = item_data->value.uint_value;
new_stat_tap_set_field_data(table, data_p->message_type, COUNT_COLUMN, item_data);
item_data = new_stat_tap_get_field_data(table, data_p->message_type, TOTAL_BYTES_COLUMN);
item_data->value.uint_value += data_p->size;
total_bytes = item_data->value.uint_value;
new_stat_tap_set_field_data(table, data_p->message_type, TOTAL_BYTES_COLUMN, item_data);
item_data = new_stat_tap_get_field_data(table, data_p->message_type, AVG_BYTES_COLUMN);
item_data->value.float_value = (float)total_bytes/(float)count;
new_stat_tap_set_field_data(table, data_p->message_type, AVG_BYTES_COLUMN, item_data);
return TRUE;
}
static void
ansi_map_stat_reset(new_stat_tap_table* table)
{
guint element;
stat_tap_table_item_type* item_data;
for (element = 0; element < table->num_elements; element++)
{
item_data = new_stat_tap_get_field_data(table, element, COUNT_COLUMN);
item_data->value.uint_value = 0;
new_stat_tap_set_field_data(table, element, COUNT_COLUMN, item_data);
item_data = new_stat_tap_get_field_data(table, element, TOTAL_BYTES_COLUMN);
item_data->value.uint_value = 0;
new_stat_tap_set_field_data(table, element, TOTAL_BYTES_COLUMN, item_data);
item_data = new_stat_tap_get_field_data(table, element, AVG_BYTES_COLUMN);
item_data->value.float_value = 0.0;
new_stat_tap_set_field_data(table, element, AVG_BYTES_COLUMN, item_data);
}
}
void
proto_reg_handoff_ansi_map(void)
{
@ -19129,7 +19228,7 @@ void proto_register_ansi_map(void) {
NULL, HFILL }},
/*--- End of included file: packet-ansi_map-hfarr.c ---*/
#line 5291 "../../asn1/ansi_map/packet-ansi_map-template.c"
#line 5390 "../../asn1/ansi_map/packet-ansi_map-template.c"
};
/* List of subtrees */
@ -19390,7 +19489,7 @@ void proto_register_ansi_map(void) {
&ett_ansi_map_ReturnData,
/*--- End of included file: packet-ansi_map-ettarr.c ---*/
#line 5324 "../../asn1/ansi_map/packet-ansi_map-template.c"
#line 5423 "../../asn1/ansi_map/packet-ansi_map-template.c"
};
static ei_register_info ei[] = {
@ -19408,6 +19507,22 @@ void proto_register_ansi_map(void) {
{NULL, NULL, -1}
};
/* TAP STAT INFO */
static new_stat_tap_ui stat_table = {
REGISTER_STAT_GROUP_TELEPHONY,
"ANSI Map Operation Statistics",
"ansi_map",
"ansi_map",
ansi_map_stat_init,
ansi_map_stat_packet,
ansi_map_stat_reset,
NULL,
NULL,
sizeof(stat_fields)/sizeof(stat_tap_table_item), stat_fields,
0, NULL,
NULL
};
/* Register protocol */
proto_ansi_map = proto_register_protocol(PNAME, PSNAME, PFNAME);
/* Register fields and subtrees */
@ -19448,4 +19563,5 @@ void proto_register_ansi_map(void) {
&ansi_map_response_matching_type, ansi_map_response_matching_type_values, FALSE);
register_init_routine(&ansi_map_init_protocol);
register_new_stat_tap_ui(&stat_table);
}

View File

@ -128,6 +128,161 @@ start_requested_stats(void)
}
}
static GSList *registered_stat_tables = NULL;
static gint
insert_sorted_by_cli_string(gconstpointer aparam, gconstpointer bparam)
{
const new_stat_tap_ui *a = (new_stat_tap_ui *)aparam;
const new_stat_tap_ui *b = (new_stat_tap_ui *)bparam;
return g_ascii_strcasecmp(a->cli_string, b->cli_string);
}
void register_new_stat_tap_ui(new_stat_tap_ui *ui)
{
registered_stat_tables = g_slist_insert_sorted(registered_stat_tables, ui, insert_sorted_by_cli_string);
}
void new_stat_tap_iterate_tables(GFunc func, gpointer user_data)
{
g_slist_foreach(registered_stat_tables, func, user_data);
}
void new_stat_tap_get_filter(new_stat_tap_ui* new_stat, const char *opt_arg, const char **filter, char** err)
{
guint len = (guint) strlen(new_stat->cli_string);
*filter=NULL;
*err=NULL;
if (!strncmp(opt_arg, new_stat->cli_string, len))
{
if (opt_arg[len] == ',')
{
*filter = opt_arg + len+1;
}
}
if (new_stat->new_stat_filter_check_cb)
new_stat->new_stat_filter_check_cb(opt_arg, filter, err);
}
new_stat_tap_table* new_stat_tap_init_table(const char *name, int num_fields, int num_elements,
const char *filter_string, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
{
new_stat_tap_table* new_table = g_new0(new_stat_tap_table, 1);
new_table->title = name;
new_table->num_elements = num_elements;
new_table->num_fields = num_fields;
new_table->filter_string = filter_string;
new_table->elements = g_new0(stat_tap_table_item_type*, num_elements);
if (gui_callback)
gui_callback(new_table, gui_data);
return new_table;
}
void new_stat_tap_add_table(new_stat_tap_ui* new_stat, new_stat_tap_table* table)
{
if (new_stat->tables == NULL)
new_stat->tables = g_array_new(FALSE, TRUE, sizeof(new_stat_tap_table*));
g_array_insert_val(new_stat->tables, new_stat->tables->len, table);
}
void new_stat_tap_init_table_row(new_stat_tap_table *stat_table, guint table_index, guint num_fields, stat_tap_table_item_type* fields)
{
/* we have discovered a new procedure. Extend the table accordingly */
if(table_index>=stat_table->num_elements){
guint old_num_elements=stat_table->num_elements;
guint i;
stat_table->num_elements=table_index+1;
stat_table->elements = (stat_tap_table_item_type**)g_realloc(stat_table->elements, sizeof(stat_tap_table_item_type*)*(stat_table->num_elements));
for(i=old_num_elements;i<stat_table->num_elements;i++){
stat_table->elements[i] = g_new0(stat_tap_table_item_type, stat_table->num_fields);
}
}
memcpy(stat_table->elements[table_index], fields, num_fields*sizeof(stat_tap_table_item_type));
}
stat_tap_table_item_type* new_stat_tap_get_field_data(new_stat_tap_table *stat_table, guint table_index, guint field_index)
{
stat_tap_table_item_type* field_value;
g_assert(table_index < stat_table->num_elements);
field_value = stat_table->elements[table_index];
g_assert(field_index < stat_table->num_fields);
return &field_value[field_index];
}
void new_stat_tap_set_field_data(new_stat_tap_table *stat_table, guint table_index, guint field_index, stat_tap_table_item_type* field_data)
{
stat_tap_table_item_type* field_value;
g_assert(table_index < stat_table->num_elements);
field_value = stat_table->elements[table_index];
g_assert(field_index < stat_table->num_fields);
field_value[field_index] = *field_data;
}
void reset_stat_table(new_stat_tap_ui* new_stat, new_stat_tap_gui_reset_cb gui_callback, void *callback_data)
{
guint i = 0;
new_stat_tap_table *stat_table;
for (i = 0; i < new_stat->tables->len; i++)
{
stat_table = g_array_index(new_stat->tables, new_stat_tap_table*, i);
/* Give GUI the first crack at it before we clean up */
if (gui_callback)
gui_callback(stat_table, callback_data);
if (new_stat->stat_tap_reset_table_cb)
new_stat->stat_tap_reset_table_cb(stat_table);
}
}
void free_stat_table(new_stat_tap_ui* new_stat, new_stat_tap_gui_free_cb gui_callback, void *callback_data)
{
guint i = 0, element, field_index;
new_stat_tap_table *stat_table;
stat_tap_table_item_type* field_data;
for (i = 0; i < new_stat->tables->len; i++)
{
stat_table = g_array_index(new_stat->tables, new_stat_tap_table*, i);
/* Give GUI the first crack at it before we clean up */
if (gui_callback)
gui_callback(stat_table, callback_data);
for (element = 0; element < stat_table->num_elements; element++)
{
for (field_index = 0; field_index < stat_table->num_fields; field_index++)
{
field_data = new_stat_tap_get_field_data(stat_table, element, field_index);
/* Give dissector a crack at it */
if (new_stat->stat_tap_free_table_item_cb)
new_stat->stat_tap_free_table_item_cb(stat_table, element, field_index, field_data);
}
g_free(stat_table->elements[element]);
}
g_free(stat_table->elements);
}
}
/*
* Editor modelines
*

View File

@ -35,6 +35,8 @@ extern "C" {
#include <epan/params.h>
#include <epan/stat_groups.h>
#include <epan/packet_info.h>
#include <epan/tap.h>
typedef enum {
PARAM_UINT, /* Unused? */
@ -64,6 +66,88 @@ typedef struct _stat_tap_ui {
tap_param *params; /* pointer to table of parameter info */
} stat_tap_ui;
typedef enum {
TABLE_ITEM_NONE = 0,
TABLE_ITEM_UINT,
TABLE_ITEM_INT,
TABLE_ITEM_STRING,
TABLE_ITEM_FLOAT,
TABLE_ITEM_ENUM
} stat_tap_table_item_enum;
typedef struct _stat_tap_table_item_type
{
stat_tap_table_item_enum type;
union
{
guint uint_value;
gint int_value;
const char* string_value;
gfloat float_value;
gint enum_value;
} value;
} stat_tap_table_item_type;
/* Possible alignments */
typedef enum {
TAP_ALIGN_LEFT = 0,
TAP_ALIGN_RIGHT
} tap_alignment_type;
typedef struct _stat_tap_table_item
{
stat_tap_table_item_enum type;
tap_alignment_type align;
const char* column_name;
const char* field_format; /* printf style formating of field */
} stat_tap_table_item;
/* Description of a UI table */
typedef struct _stat_tap_table
{
const char* title;
const char *filter_string; /**< append procedure number (%d) to this string to create a display filter */
guint num_fields;
guint num_elements;
stat_tap_table_item_type **elements;
} new_stat_tap_table;
typedef void (*new_stat_tap_gui_init_cb)(new_stat_tap_table* stat_table, void* gui_data);
typedef void (*new_stat_tap_gui_reset_cb)(new_stat_tap_table* stat_table, void* gui_data);
typedef void (*new_stat_tap_gui_free_cb)(new_stat_tap_table* stat_table, void* gui_data);
/*
* UI information for a tap.
*/
typedef struct _new_stat_tap_ui {
register_stat_group_t group; /* group to which statistic belongs */
const char *title; /* title of statistic */
const char *tap_name;
const char *cli_string; /* initial part of the "-z" argument for statistic */
void (* stat_tap_init_cb)(struct _new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data);
tap_packet_cb packet_func;
void (* stat_tap_reset_table_cb)(new_stat_tap_table* table);
void (* stat_tap_free_table_item_cb)(new_stat_tap_table* table, guint row, guint column, stat_tap_table_item_type* field_data);
void (* new_stat_filter_check_cb)(const char *opt_arg, const char **filter, char** err); /* Dissector chance to reject filter */
size_t nfields; /* number of fields */
stat_tap_table_item* fields;
size_t nparams; /* number of parameters */
tap_param *params; /* pointer to table of parameter info */
GArray *tables; /* An array of new_stat_tap_table* */
} new_stat_tap_ui;
/** tap data
*/
typedef struct _new_stat_data_t {
new_stat_tap_ui *new_stat_tap_data;
void *user_data; /**< "GUI" specifics (if necessary) */
} new_stat_data_t;
/** Register UI information for a tap.
*
* @param ui UI information for the tap.
@ -71,6 +155,20 @@ typedef struct _stat_tap_ui {
*/
WS_DLL_PUBLIC void register_stat_tap_ui(stat_tap_ui *ui, void *userdata);
WS_DLL_PUBLIC void register_new_stat_tap_ui(new_stat_tap_ui *ui);
WS_DLL_PUBLIC void new_stat_tap_iterate_tables(GFunc func, gpointer user_data);
WS_DLL_PUBLIC void new_stat_tap_get_filter(new_stat_tap_ui* new_stat, const char *opt_arg, const char **filter, char** err);
WS_DLL_PUBLIC new_stat_tap_table* new_stat_tap_init_table(const char *name, int num_fields, int num_elements,
const char *filter_string, new_stat_tap_gui_init_cb gui_callback, void* gui_data);
WS_DLL_PUBLIC void new_stat_tap_add_table(new_stat_tap_ui* new_stat, new_stat_tap_table* table);
WS_DLL_PUBLIC void new_stat_tap_init_table_row(new_stat_tap_table *stat_table, guint table_index, guint num_fields, stat_tap_table_item_type* fields);
WS_DLL_PUBLIC stat_tap_table_item_type* new_stat_tap_get_field_data(new_stat_tap_table *stat_table, guint table_index, guint field_index);
WS_DLL_PUBLIC void new_stat_tap_set_field_data(new_stat_tap_table *stat_table, guint table_index, guint field_index, stat_tap_table_item_type* field_data);
WS_DLL_PUBLIC void reset_stat_table(new_stat_tap_ui* new_stat, new_stat_tap_gui_reset_cb gui_callback, void *callback_data);
WS_DLL_PUBLIC void free_stat_table(new_stat_tap_ui* new_stat, new_stat_tap_gui_free_cb gui_callback, void *callback_data);
WS_DLL_PUBLIC gboolean process_stat_cmd_arg(char *optstr);
WS_DLL_PUBLIC void list_stat_cmd_args(void);

View File

@ -1221,6 +1221,7 @@ DIAG_ON(cast-qual)
hostlist_table_set_gui_info(init_hostlists);
srt_table_iterate_tables(register_srt_tables, NULL);
rtd_table_iterate_tables(register_rtd_tables, NULL);
new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
/* If invoked with the "-G" flag, we dump out information based on
the argument to the "-G" flag; if no argument is specified,

View File

@ -38,7 +38,6 @@ GENERATOR_FILES =
# sources for TShark taps
TSHARK_TAP_SRC = \
tap-ansi_astat.c \
tap-bootpstat.c \
tap-camelcounter.c \
tap-camelsrt.c \
@ -65,6 +64,7 @@ TSHARK_TAP_SRC = \
tap-rtp.c \
tap-rtspstat.c \
tap-sctpchunkstat.c \
tap-simple_stattable.c \
tap-sipstat.c \
tap-smbsids.c \
tap-srt.c \

View File

@ -1,182 +0,0 @@
/* tap-ansi_astat.c
*
* Copyright 2003, Michael Lum <mlum [AT] telostech.com>
* In association with Telos Technology Inc.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* This TAP provides statistics for the ANSI A Interface:
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "epan/packet_info.h"
#include "epan/value_string.h"
#include <epan/tap.h>
#include <epan/stat_tap_ui.h>
#include <epan/dissectors/packet-bssap.h>
#include <epan/dissectors/packet-ansi_a.h>
void register_tap_listener_ansi_astat(void);
typedef struct _ansi_a_stat_t {
int bsmap_message_type[0xff];
int dtap_message_type[0xff];
} ansi_a_stat_t;
static int
ansi_a_stat_packet(
void *tapdata,
packet_info *pinfo _U_,
epan_dissect_t *edt _U_,
const void *data)
{
ansi_a_stat_t *stat_p = (ansi_a_stat_t *)tapdata;
const ansi_a_tap_rec_t *tap_p = (const ansi_a_tap_rec_t *)data;
switch (tap_p->pdu_type)
{
case BSSAP_PDU_TYPE_BSMAP:
stat_p->bsmap_message_type[tap_p->message_type]++;
break;
case BSSAP_PDU_TYPE_DTAP:
stat_p->dtap_message_type[tap_p->message_type]++;
break;
default:
/*
* unknown PDU type !!!
*/
return(0);
}
return(1);
}
static void
ansi_a_stat_draw(
void *tapdata)
{
ansi_a_stat_t *stat_p = (ansi_a_stat_t *)tapdata;
guint8 i;
printf("\n");
printf("=========== ANSI A-i/f Statistics ============================\n");
printf("BSMAP\n");
printf("Message (ID)Type Number\n");
i = 0;
while (ansi_a_ios401_bsmap_strings[i].strptr)
{
if (stat_p->bsmap_message_type[ansi_a_ios401_bsmap_strings[i].value] > 0)
{
printf("0x%02x %-50s%d\n",
ansi_a_ios401_bsmap_strings[i].value,
ansi_a_ios401_bsmap_strings[i].strptr,
stat_p->bsmap_message_type[ansi_a_ios401_bsmap_strings[i].value]);
}
i++;
}
printf("\nDTAP\n");
printf("Message (ID)Type Number\n");
i = 0;
while (ansi_a_ios401_dtap_strings[i].strptr)
{
if (stat_p->dtap_message_type[ansi_a_ios401_dtap_strings[i].value] > 0)
{
printf("0x%02x %-50s%d\n",
ansi_a_ios401_dtap_strings[i].value,
ansi_a_ios401_dtap_strings[i].strptr,
stat_p->dtap_message_type[ansi_a_ios401_dtap_strings[i].value]);
}
i++;
}
printf("==============================================================\n");
}
static void
ansi_a_stat_init(const char *opt_arg _U_, void *userdata _U_)
{
ansi_a_stat_t *stat_p;
GString *err_p;
stat_p = (ansi_a_stat_t *)g_malloc(sizeof(ansi_a_stat_t));
memset(stat_p, 0, sizeof(ansi_a_stat_t));
err_p =
register_tap_listener("ansi_a", stat_p, NULL, 0,
NULL,
ansi_a_stat_packet,
ansi_a_stat_draw);
if (err_p != NULL)
{
g_free(stat_p);
g_string_free(err_p, TRUE);
exit(1);
}
}
static stat_tap_ui ansi_a_stat_ui = {
REGISTER_STAT_GROUP_GENERIC,
NULL,
"ansi_a",
ansi_a_stat_init,
0,
NULL
};
void
register_tap_listener_ansi_astat(void)
{
register_stat_tap_ui(&ansi_a_stat_ui, NULL);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -0,0 +1,170 @@
/* tap-simpletable.c
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <epan/packet.h>
#include <epan/timestamp.h>
#include <epan/stat_tap_ui.h>
#include <ui/cli/tshark-tap.h>
typedef struct _table_stat_t {
const char *filter;
new_stat_data_t stats;
} table_stat_t;
static void
simple_draw(void *arg)
{
new_stat_data_t* stat_data = (new_stat_data_t*)arg;
table_stat_t* stats = (table_stat_t*)stat_data->user_data;
size_t i;
guint table_index, element, field_index;
stat_tap_table_item* field;
new_stat_tap_table* table;
stat_tap_table_item_type* field_data;
gchar fmt_string[250];
/* printing results */
printf("\n");
printf("=====================================================================================================\n");
printf("%s:\n", stat_data->new_stat_tap_data->title);
printf("Filter for statistics: %s\n", stats->filter ? stats->filter : "");
for (i = 0, field = stat_data->new_stat_tap_data->fields; i < stat_data->new_stat_tap_data->nfields; i++, field++)
{
printf("%s |", field->column_name);
}
printf("\n");
/* To iterate is human, and to recurse is divine. I am human */
for (table_index = 0; table_index < stat_data->new_stat_tap_data->tables->len; table_index++)
{
table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, table_index);
printf("%s\n", table->title);
for (element = 0; element < table->num_elements; element++)
{
for (field_index = 0, field = stat_data->new_stat_tap_data->fields; field_index < table->num_fields; field_index++, field++)
{
field_data = new_stat_tap_get_field_data(table, element, field_index);
if (field_data->type == TABLE_ITEM_NONE) /* Nothing for us here */
break;
g_snprintf(fmt_string, sizeof(fmt_string), "%s |", field->field_format);
switch(field->type)
{
case TABLE_ITEM_UINT:
printf(fmt_string, field_data->value.uint_value);
break;
case TABLE_ITEM_INT:
printf(fmt_string, field_data->value.int_value);
break;
case TABLE_ITEM_STRING:
printf(fmt_string, field_data->value.string_value);
break;
case TABLE_ITEM_FLOAT:
printf(fmt_string, field_data->value.float_value);
break;
case TABLE_ITEM_ENUM:
printf(fmt_string, field_data->value.enum_value);
break;
case TABLE_ITEM_NONE:
break;
}
}
printf("\n");
}
}
printf("=====================================================================================================\n");
}
static void
init_stat_table(new_stat_tap_ui *new_stat_tap, const char *filter)
{
GString *error_string;
table_stat_t* ui;
ui = g_new0(table_stat_t, 1);
ui->filter = g_strdup(filter);
ui->stats.new_stat_tap_data = new_stat_tap;
ui->stats.user_data = ui;
new_stat_tap->stat_tap_init_cb(new_stat_tap, NULL, NULL);
error_string = register_tap_listener(new_stat_tap->tap_name, &ui->stats, filter, 0, NULL, new_stat_tap->packet_func, simple_draw);
if (error_string) {
/* free_rtd_table(rtd, &ui->rtd.stat_table, NULL, NULL); */
fprintf(stderr, "tshark: Couldn't register tap: %s\n", error_string->str);
g_string_free(error_string, TRUE);
exit(1);
}
}
static void
simple_stat_init(const char *opt_arg, void* userdata)
{
new_stat_tap_ui *new_stat_tap = (new_stat_tap_ui*)userdata;
const char *filter=NULL;
char* err = NULL;
new_stat_tap_get_filter(new_stat_tap, opt_arg, &filter, &err);
if (err != NULL)
{
fprintf(stderr, "tshark: %s\n", err);
g_free(err);
exit(1);
}
init_stat_table(new_stat_tap, filter);
}
void
register_simple_stat_tables(gpointer data, gpointer user_data _U_)
{
new_stat_tap_ui *new_stat_tap = (new_stat_tap_ui*)data;
stat_tap_ui ui_info;
ui_info.group = new_stat_tap->group;
ui_info.title = new_stat_tap->title; /* construct this from the protocol info? */
ui_info.cli_string = new_stat_tap->cli_string;
ui_info.tap_init_cb = simple_stat_init;
ui_info.nparams = new_stat_tap->nparams;
ui_info.params = new_stat_tap->params;
register_stat_tap_ui(&ui_info, new_stat_tap);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -28,5 +28,6 @@ extern void init_iousers(struct register_ct* ct, const char *filter);
extern void init_hostlists(struct register_ct* ct, const char *filter);
extern void register_srt_tables(gpointer data, gpointer user_data);
extern void register_rtd_tables(gpointer data, gpointer user_data);
extern void register_simple_stat_tables(gpointer data, gpointer user_data);
#endif /* __TSHARK_TAP_H__ */

View File

@ -104,6 +104,7 @@ set(WIRESHARK_GTK_SRC
sctp_graph_dlg.c
service_response_time_table.c
simple_dialog.c
simple_stattable.c
stock_icons.c
summary_dlg.c
supported_protos_dlg.c
@ -196,8 +197,6 @@ if(ENABLE_EXTCAP)
endif()
set(WIRESHARK_TAP_SRC
ansi_a_stat.c
ansi_map_stat.c
bootp_stat.c
camel_counter.c
compare_stat.c

View File

@ -125,6 +125,7 @@ WIRESHARK_GTK_SRC = \
sctp_graph_dlg.c \
service_response_time_table.c \
simple_dialog.c \
simple_stattable.c \
stock_icons.c \
summary_dlg.c \
supported_protos_dlg.c \
@ -146,8 +147,6 @@ prefs_layout.c: layouts.h
stock_icons.c: stock_icons.h toolbar_icons.h wsicon.h
WIRESHARK_TAP_SRC = \
ansi_a_stat.c \
ansi_map_stat.c \
bootp_stat.c \
camel_counter.c \
compare_stat.c \
@ -289,11 +288,12 @@ noinst_HEADERS = \
rtp_stream_dlg.h \
sctp_stat_gtk.h \
service_response_time_table.h \
simple_stattable.h \
time_shift_dlg.h \
simple_dialog.h \
stock_icons.h \
summary_dlg.h \
supported_protos_dlg.h \
summary_dlg.h \
supported_protos_dlg.h \
tap_param_dlg.h \
text_page_utils.h \
toolbar_icons.h \

View File

@ -1,382 +0,0 @@
/* ansi_a_stat.c
*
* Copyright 2003, Michael Lum <mlum [AT] telostech.com>
* In association with Telos Technology Inc.
*
* MUCH code modified from service_response_time_table.c.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* This TAP provides statistics for the ANSI A-Interface:
*/
#include "config.h"
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include "epan/packet_info.h"
#include "epan/value_string.h"
#include <epan/tap.h>
#include <epan/dissectors/packet-bssap.h>
#include <epan/dissectors/packet-ansi_a.h>
#include <epan/stat_groups.h>
#include "ui/simple_dialog.h"
#include "ui/gtk/gui_stat_menu.h"
#include "ui/gtk/dlg_utils.h"
#include "ui/gtk/gui_utils.h"
void register_tap_listener_gtkansi_a_stat(void);
enum
{
IEI_COLUMN,
MSG_NAME_COLUMN,
COUNT_COLUMN,
N_COLUMN /* The number of columns */
};
typedef struct _ansi_a_stat_dlg_t {
GtkWidget *win;
GtkWidget *scrolled_win;
GtkWidget *table;
} ansi_a_stat_dlg_t;
typedef struct _ansi_a_stat_t {
int bsmap_message_type[0xff];
int dtap_message_type[0xff];
} ansi_a_stat_t;
static ansi_a_stat_dlg_t dlg_bsmap;
static ansi_a_stat_dlg_t dlg_dtap;
static ansi_a_stat_t ansi_a_stat;
static void
ansi_a_stat_reset(
void *tapdata)
{
ansi_a_stat_t *stat_p = (ansi_a_stat_t *)tapdata;
memset(stat_p, 0, sizeof(ansi_a_stat_t));
}
static gboolean
ansi_a_stat_packet(
void *tapdata,
packet_info *pinfo _U_,
epan_dissect_t *edt _U_,
const void *data)
{
ansi_a_stat_t *stat_p = (ansi_a_stat_t *)tapdata;
const ansi_a_tap_rec_t *data_p = (const ansi_a_tap_rec_t *)data;
switch (data_p->pdu_type)
{
case BSSAP_PDU_TYPE_BSMAP:
stat_p->bsmap_message_type[data_p->message_type]++;
break;
case BSSAP_PDU_TYPE_DTAP:
stat_p->dtap_message_type[data_p->message_type]++;
break;
default:
/*
* unknown PDU type !!!
*/
return(FALSE);
}
return(TRUE);
}
static void
ansi_a_stat_draw(
void *tapdata)
{
ansi_a_stat_t *stat_p = (ansi_a_stat_t *)tapdata;
int i;
GtkListStore *list_store;
GtkTreeIter iter;
if (dlg_bsmap.win && tapdata)
{
list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg_bsmap.table))); /* Get store */
i = 0;
while (ansi_a_bsmap_strings[i].strptr){
/* Creates a new row at position. iter will be changed to point to this new row.
* If position is larger than the number of rows on the list, then the new row will be appended to the list.
* The row will be filled with the values given to this function.
* :
* should generally be preferred when inserting rows in a sorted list store.
*/
gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
IEI_COLUMN, ansi_a_bsmap_strings[i].value,
MSG_NAME_COLUMN, (char *)ansi_a_bsmap_strings[i].strptr,
COUNT_COLUMN, stat_p->bsmap_message_type[ansi_a_bsmap_strings[i].value],
-1);
i++;
}
}
if (dlg_dtap.win && tapdata){
i = 0;
list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg_dtap.table))); /* Get store */
while (ansi_a_dtap_strings[i].strptr){
/* Creates a new row at position. iter will be changed to point to this new row.
* If position is larger than the number of rows on the list, then the new row will be appended to the list.
* The row will be filled with the values given to this function.
* :
* should generally be preferred when inserting rows in a sorted list store.
*/
gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
IEI_COLUMN, ansi_a_dtap_strings[i].value,
MSG_NAME_COLUMN, (char *)ansi_a_dtap_strings[i].strptr,
COUNT_COLUMN, stat_p->dtap_message_type[ansi_a_dtap_strings[i].value],
-1);
i++;
}
}
}
static void
ansi_a_stat_gtk_win_destroy_cb(
GtkWindow *win _U_,
gpointer user_data )
{
memset((void *) user_data, 0, sizeof(ansi_a_stat_dlg_t));
}
/* Create list */
static
GtkWidget* create_list(void)
{
GtkListStore *list_store;
GtkWidget *list;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeSortable *sortable;
GtkTreeView *list_view;
GtkTreeSelection *selection;
/* Create the store */
list_store = gtk_list_store_new(N_COLUMN, /* Total number of columns XXX */
G_TYPE_UINT, /* IEI */
G_TYPE_STRING, /* Message Name */
G_TYPE_UINT); /* Count */
/* Create a view */
list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
list_view = GTK_TREE_VIEW(list);
sortable = GTK_TREE_SORTABLE(list_store);
/* Speed up the list display */
gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
/* Setup the sortable columns */
gtk_tree_sortable_set_sort_column_id(sortable, IEI_COLUMN, GTK_SORT_ASCENDING);
gtk_tree_view_set_headers_clickable(list_view, FALSE);
/* The view now holds a reference. We can get rid of our own reference */
g_object_unref (G_OBJECT (list_store));
/*
* Create the first column packet, associating the "text" attribute of the
* cell_renderer to the first column of the model
*/
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("IEI", renderer,
"text", IEI_COLUMN,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer, present_as_hex_func,
GINT_TO_POINTER(IEI_COLUMN), NULL);
gtk_tree_view_column_set_sort_column_id(column, IEI_COLUMN);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width(column, 50);
/* Add the column to the view. */
gtk_tree_view_append_column (list_view, column);
/* Second column.. Message Name. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Message Name", renderer,
"text", MSG_NAME_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, MSG_NAME_COLUMN);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width(column, 280);
gtk_tree_view_append_column (list_view, column);
/* Third column.. Count. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Count", renderer,
"text", COUNT_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, COUNT_COLUMN);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width(column, 50);
gtk_tree_view_append_column (list_view, column);
/* Now enable the sorting of each column */
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view), TRUE);
gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view), TRUE);
/* Setup the selection handler */
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
return list;
}
static void
ansi_a_stat_gtk_win_create(
ansi_a_stat_dlg_t *dlg_p,
const char *title)
{
GtkWidget *vbox;
GtkWidget *bt_close;
GtkWidget *bbox;
dlg_p->win= dlg_window_new(title); /* transient_for top_level */
gtk_window_set_destroy_with_parent (GTK_WINDOW(dlg_p->win), TRUE);
gtk_window_set_default_size(GTK_WINDOW(dlg_p->win), 480, 450);
vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
gtk_container_add(GTK_CONTAINER(dlg_p->win), vbox);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
dlg_p->scrolled_win = scrolled_window_new(NULL, NULL);
gtk_box_pack_start(GTK_BOX(vbox), dlg_p->scrolled_win, TRUE, TRUE, 0);
dlg_p->table = create_list();
gtk_widget_show(dlg_p->table);
gtk_container_add(GTK_CONTAINER(dlg_p->scrolled_win), dlg_p->table);
/* Button row. */
bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
bt_close = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
window_set_cancel_button(dlg_p->win, bt_close, window_cancel_button_cb);
g_signal_connect(dlg_p->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
g_signal_connect(dlg_p->win, "destroy", G_CALLBACK(ansi_a_stat_gtk_win_destroy_cb), dlg_p);
gtk_widget_show_all(dlg_p->win);
window_present(dlg_p->win);
}
void
ansi_a_stat_gtk_bsmap_cb(GtkAction *action _U_, gpointer user_data _U_)
{
/*
* if the window is already open, bring it to front
*/
if (dlg_bsmap.win)
{
gdk_window_raise(gtk_widget_get_window(dlg_bsmap.win));
return;
}
ansi_a_stat_gtk_win_create(&dlg_bsmap, "ANSI A-I/F BSMAP Statistics");
ansi_a_stat_draw(&ansi_a_stat);
}
void
ansi_a_stat_gtk_dtap_cb(GtkAction *action _U_, gpointer user_data _U_)
{
/*
* if the window is already open, bring it to front
*/
if (dlg_dtap.win)
{
gdk_window_raise(gtk_widget_get_window(dlg_dtap.win));
return;
}
ansi_a_stat_gtk_win_create(&dlg_dtap, "ANSI A-I/F DTAP Statistics");
ansi_a_stat_draw(&ansi_a_stat);
}
void
register_tap_listener_gtkansi_a_stat(void)
{
GString *err_p;
memset((void *) &ansi_a_stat, 0, sizeof(ansi_a_stat_t));
err_p =
register_tap_listener("ansi_a", &ansi_a_stat, NULL, 0,
ansi_a_stat_reset,
ansi_a_stat_packet,
ansi_a_stat_draw);
if (err_p != NULL)
{
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_p->str);
g_string_free(err_p, TRUE);
exit(1);
}
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -1,393 +0,0 @@
/* ansi_map_stat.c
*
* Copyright 2003, Michael Lum <mlum [AT] telostech.com>
* In association with Telos Technology Inc.
*
* MUCH code modified from service_response_time_table.c.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* This TAP provides statistics for ANSI MAP:
*/
#include "config.h"
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <epan/packet_info.h>
#include <epan/value_string.h>
#include <epan/stat_tap_ui.h>
#include <epan/tap.h>
#include <epan/dissectors/packet-ansi_map.h>
#include "ui/simple_dialog.h"
#include "ui/gtk/gui_stat_menu.h"
#include "ui/gtk/dlg_utils.h"
#include "ui/gtk/gui_utils.h"
void register_tap_listener_gtkansi_map_stat(void);
enum
{
OP_CODE_COLUMN,
OP_CODE_NAME_COLUMN,
COUNT_COLUMN,
TOT_BYTES_COLUMN,
AVG_BYTES_COLUMN,
N_COLUMN /* The number of columns */
};
typedef struct _ansi_map_stat_dlg_t {
GtkWidget *win;
GtkWidget *scrolled_win;
GtkWidget *table;
} ansi_map_stat_dlg_t;
typedef struct _ansi_map_stat_t {
int message_type[ANSI_MAP_MAX_NUM_MESSAGE_TYPES];
double size[ANSI_MAP_MAX_NUM_MESSAGE_TYPES];
} ansi_map_stat_t;
static ansi_map_stat_dlg_t dlg;
static ansi_map_stat_t ansi_a_stat;
/* Create list */
static
GtkWidget* create_list(void)
{
GtkListStore *list_store;
GtkWidget *list;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeSortable *sortable;
GtkTreeView *list_view;
GtkTreeSelection *selection;
/* Create the store */
list_store = gtk_list_store_new(N_COLUMN, /* Total number of columns XXX*/
G_TYPE_UINT, /* Op Code */
G_TYPE_STRING, /* Operation Name */
G_TYPE_UINT, /* Count */
G_TYPE_UINT, /* Total Bytes */
G_TYPE_FLOAT); /* Avg Bytes */
/* Create a view */
list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
list_view = GTK_TREE_VIEW(list);
sortable = GTK_TREE_SORTABLE(list_store);
/* Speed up the list display */
gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
/* Setup the sortable columns */
gtk_tree_sortable_set_sort_column_id(sortable, OP_CODE_COLUMN, GTK_SORT_ASCENDING);
gtk_tree_view_set_headers_clickable(list_view, FALSE);
/* The view now holds a reference. We can get rid of our own reference */
g_object_unref (G_OBJECT (list_store));
/*
* Create the first column packet, associating the "text" attribute of the
* cell_renderer to the first column of the model
*/
/* 1:st column */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Op Code", renderer,
"text", OP_CODE_COLUMN,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer, present_as_hex_func,
GINT_TO_POINTER(OP_CODE_COLUMN), NULL);
gtk_tree_view_column_set_sort_column_id(column, OP_CODE_COLUMN);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width(column, 60);
/* Add the column to the view. */
gtk_tree_view_append_column (list_view, column);
/* 2:nd column... */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Operation Name", renderer,
"text", OP_CODE_NAME_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, OP_CODE_NAME_COLUMN);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width(column, 290);
gtk_tree_view_append_column (list_view, column);
/* 3:d column... */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Count", renderer,
"text", COUNT_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, COUNT_COLUMN);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width(column, 50);
gtk_tree_view_append_column (list_view, column);
/* 4:th column... */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Total Bytes", renderer,
"text", TOT_BYTES_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, TOT_BYTES_COLUMN);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width(column, 100);
gtk_tree_view_append_column (list_view, column);
/* 10:th column.. Avg Bytes. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer,
"text", AVG_BYTES_COLUMN,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func,
GINT_TO_POINTER(AVG_BYTES_COLUMN), NULL);
gtk_tree_view_column_set_sort_column_id(column, AVG_BYTES_COLUMN);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width(column, 50);
gtk_tree_view_append_column (list_view, column);
/* Now enable the sorting of each column */
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view), TRUE);
gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view), TRUE);
/* Setup the selection handler */
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
return list;
}
static void
ansi_map_stat_reset(
void *tapdata)
{
ansi_map_stat_t *stat_p = (ansi_map_stat_t *)tapdata;
memset(stat_p, 0, sizeof(ansi_map_stat_t));
}
static gboolean
ansi_map_stat_packet(
void *tapdata,
packet_info *pinfo _U_,
epan_dissect_t *edt _U_,
const void *data)
{
ansi_map_stat_t *stat_p = (ansi_map_stat_t *)tapdata;
const ansi_map_tap_rec_t *data_p = (const ansi_map_tap_rec_t *)data;
#if 0 /* always false because message_type is 8 bit value */
if (data_p->message_type >= ANSI_MAP_MAX_NUM_MESSAGE_TYPES)
{
/*
* unknown PDU type !!!
*/
return(FALSE);
}
#endif
stat_p->message_type[data_p->message_type]++;
stat_p->size[data_p->message_type] += data_p->size;
return(TRUE);
}
static void
ansi_map_stat_draw(
void *tapdata)
{
ansi_map_stat_t *stat_p = (ansi_map_stat_t *)tapdata;
int i;
float avg;
GtkListStore *list_store;
GtkTreeIter iter;
if (dlg.win && tapdata)
{
i = 0;
list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg.table))); /* Get store */
while (ansi_map_opr_code_strings[i].strptr)
{
avg = 0.0f;
if (stat_p->message_type[ansi_map_opr_code_strings[i].value] !=0 ){
avg = (float)stat_p->size[ansi_map_opr_code_strings[i].value]/(float)stat_p->message_type[ansi_map_opr_code_strings[i].value];
}
/* Creates a new row at position. iter will be changed to point to this new row.
* If position is larger than the number of rows on the list, then the new row will be appended to the list.
* The row will be filled with the values given to this function.
* :
* should generally be preferred when inserting rows in a sorted list store.
*/
gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
OP_CODE_COLUMN, ansi_map_opr_code_strings[i].value,
OP_CODE_NAME_COLUMN, ansi_map_opr_code_strings[i].strptr,
COUNT_COLUMN, (guint)stat_p->message_type[ansi_map_opr_code_strings[i].value],
TOT_BYTES_COLUMN, (guint)stat_p->size[ansi_map_opr_code_strings[i].value],
AVG_BYTES_COLUMN, avg,
-1);
i++;
}
}
}
static void
ansi_map_stat_gtk_win_destroy_cb(
GtkWindow *win _U_,
gpointer user_data)
{
memset((void *) user_data, 0, sizeof(ansi_map_stat_dlg_t));
}
static void
ansi_map_stat_gtk_win_create(
ansi_map_stat_dlg_t *dlg_p,
const char *title)
{
GtkWidget *vbox;
GtkWidget *bt_close;
GtkWidget *bbox;
dlg_p->win= dlg_window_new(title); /* transient_for top_level */
gtk_window_set_destroy_with_parent (GTK_WINDOW(dlg_p->win), TRUE);
gtk_window_set_default_size(GTK_WINDOW(dlg_p->win), 500, 450);
vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
gtk_container_add(GTK_CONTAINER(dlg_p->win), vbox);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
dlg_p->scrolled_win = scrolled_window_new(NULL, NULL);
gtk_box_pack_start(GTK_BOX(vbox), dlg_p->scrolled_win, TRUE, TRUE, 0);
dlg_p->table = create_list();
gtk_container_add(GTK_CONTAINER(dlg_p->scrolled_win), dlg_p->table);
/* Button row. */
bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
bt_close = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
window_set_cancel_button(dlg_p->win, bt_close, window_cancel_button_cb);
g_signal_connect(dlg_p->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
g_signal_connect(dlg_p->win, "destroy", G_CALLBACK(ansi_map_stat_gtk_win_destroy_cb), dlg_p);
gtk_widget_show_all(dlg_p->win);
window_present(dlg_p->win);
}
void
ansi_map_stat_gtk_cb(GtkAction *action _U_, gpointer user_data _U_)
{
/*
* if the window is already open, bring it to front
*/
if (dlg.win){
gdk_window_raise(gtk_widget_get_window(dlg.win));
return;
}
ansi_map_stat_gtk_win_create(&dlg, "ANSI MAP Operation Statistics");
ansi_map_stat_draw(&ansi_a_stat);
}
static void
ansi_map_stat_gtk_init(
const char *opt_arg _U_,
void* userdata _U_ )
{
ansi_map_stat_gtk_cb(NULL, NULL);
}
static stat_tap_ui ansi_map_ui = {
REGISTER_STAT_GROUP_GENERIC,
NULL,
"ansi_map",
ansi_map_stat_gtk_init,
0,
NULL
};
void
register_tap_listener_gtkansi_map_stat(void)
{
GString *err_p;
memset((void *) &ansi_a_stat, 0, sizeof(ansi_map_stat_t));
err_p =
register_tap_listener("ansi_map", &ansi_a_stat, NULL, 0,
ansi_map_stat_reset,
ansi_map_stat_packet,
ansi_map_stat_draw);
if (err_p != NULL)
{
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_p->str);
g_string_free(err_p, TRUE);
exit(1);
}
register_stat_tap_ui(&ansi_map_ui, NULL);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -259,7 +259,8 @@ static tap_param_dlg dhcp_stat_dlg = {
dhcpstat_init,
-1,
G_N_ELEMENTS(bootp_stat_params),
bootp_stat_params
bootp_stat_params,
NULL
};
void

View File

@ -136,8 +136,8 @@ static void win_destroy_cb(GtkWindow *win _U_, gpointer data)
}
static const stat_column titles[]={
{G_TYPE_STRING, LEFT, "Message Type or Reason"},
{G_TYPE_UINT, RIGHT, "Count" }
{G_TYPE_STRING, TAP_ALIGN_LEFT, "Message Type or Reason"},
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Count" }
};
static void gtk_camelcounter_init(const char *opt_arg, void *userdata _U_)
@ -214,7 +214,8 @@ static tap_param_dlg camel_counter_dlg = {
gtk_camelcounter_init,
-1,
G_N_ELEMENTS(camel_counter_params),
camel_counter_params
camel_counter_params,
NULL
};
void /* Next line mandatory */

View File

@ -24,8 +24,8 @@
#include "config.h"
#include "ui/gtk/gui_stat_util.h"
#include <epan/stat_tap_ui.h>
/* init a main window for stats, set title and display used filter in window */
@ -80,12 +80,15 @@ create_stat_table(GtkWidget *scrolled_window, GtkWidget *vbox, int columns, cons
/* create table */
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
table = GTK_TREE_VIEW(tree);
g_object_unref (G_OBJECT (store));
gtk_tree_view_set_headers_clickable(table, FALSE);
for (i = 0; i < columns; i++) {
renderer = gtk_cell_renderer_text_new ();
if (headers[i].align == RIGHT) {
if (headers[i].align == TAP_ALIGN_RIGHT) {
/* right align */
g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
}
@ -94,13 +97,14 @@ create_stat_table(GtkWidget *scrolled_window, GtkWidget *vbox, int columns, cons
i, NULL);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_append_column (table, column);
gtk_tree_view_column_set_sort_column_id(column, i);
}
gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET (table));
gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
/* configure TreeView */
gtk_tree_view_set_rules_hint(table, FALSE);
gtk_tree_view_set_headers_clickable(table, FALSE);
gtk_tree_view_set_rules_hint(table, TRUE);
gtk_tree_view_set_headers_clickable(table, TRUE);
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(table));
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);

View File

@ -31,9 +31,6 @@
* Utilities for statistics.
*/
#define LEFT 0
#define RIGHT 1
/** Columns definition
*/
typedef struct {

View File

@ -53,7 +53,8 @@ static tap_param_dlg h225_counter_dlg = {
gtk_h225counter_init,
-1,
G_N_ELEMENTS(h225_counter_params),
h225_counter_params
h225_counter_params,
NULL
};
/* following values represent the size of their valuestring arrays */
@ -509,8 +510,8 @@ win_destroy_cb(GtkWindow *win _U_, gpointer data)
}
static const stat_column titles[]={
{G_TYPE_STRING, LEFT, "Message Type or Reason"},
{G_TYPE_UINT, RIGHT, "Count" }
{G_TYPE_STRING, TAP_ALIGN_LEFT, "Message Type or Reason"},
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Count" }
};
static void

View File

@ -1411,7 +1411,8 @@ static tap_param_dlg mac_lte_stat_dlg = {
gtk_mac_lte_stat_init,
-1,
G_N_ELEMENTS(mac_lte_stat_params),
mac_lte_stat_params
mac_lte_stat_params,
NULL
};

View File

@ -195,6 +195,7 @@
#include "ui/gtk/hostlist_table.h"
#include "ui/gtk/service_response_time_table.h"
#include "ui/gtk/response_time_delay_table.h"
#include "ui/gtk/simple_stattable.h"
#include "simple_dialog.h"
#include "ui/gtk/old-gtk-compat.h"
@ -2537,6 +2538,7 @@ DIAG_ON(cast-qual)
hostlist_table_set_gui_info(init_hostlist_table);
srt_table_iterate_tables(register_service_response_tables, NULL);
rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);

View File

@ -1075,11 +1075,6 @@ static const char *ui_desc_menubar =
" <separator/>\n"
" </menu>\n"
" <menu name= 'TelephonyMenu' action='/Telephony'>\n"
" <menu name= 'ANSI' action='/Telephony/ANSI'>\n"
" <menuitem name='BSMAP' action='/Telephony/ANSI/BSMAP'/>\n"
" <menuitem name='DTAP' action='/Telephony/ANSI/DTAP'/>\n"
" <menuitem name='MAP-OP' action='/Telephony/ANSI/MAP-OP'/>\n"
" </menu>\n"
" <menu name= 'GSM' action='/Telephony/GSM'>\n"
" <menuitem name='BSSMAP' action='/Telephony/GSM/BSSMAP'/>\n"
" <menu name='GSM-DTAP' action='/Telephony/GSM/DTAP'>\n"
@ -1515,11 +1510,6 @@ static const GtkActionEntry main_menu_bar_entries[] = {
{ "/Statistics/IOGraphs", WIRESHARK_STOCK_GRAPHS, "_IO Graph", NULL, NULL, G_CALLBACK(gui_iostat_cb) },
{ "/Statistics/plen", NULL, "Packet Lengths...", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
{ "/Telephony/ANSI", NULL, "_ANSI", NULL, NULL, NULL },
{ "/Telephony/ANSI/BSMAP", NULL, "A-Interface BSMAP", NULL, NULL, G_CALLBACK(ansi_a_stat_gtk_bsmap_cb) },
{ "/Telephony/ANSI/DTAP", NULL, "A-Interface DTAP", NULL, NULL, G_CALLBACK(ansi_a_stat_gtk_dtap_cb) },
{ "/Telephony/ANSI/MAP-OP", NULL, "MAP Operation", NULL, NULL, G_CALLBACK(ansi_map_stat_gtk_cb) },
{ "/Telephony/GSM", NULL, "_GSM", NULL, NULL, NULL },
{ "/Telephony/GSM/BSSMAP", NULL, "A-Interface BSSMAP", NULL, NULL, G_CALLBACK(gsm_a_stat_gtk_bssmap_cb) },

View File

@ -27,6 +27,7 @@
#include "epan/packet_info.h"
#include "epan/proto.h"
#include <epan/stat_tap_ui.h>
#include "ui/simple_dialog.h"
#include "ui/utf8_entities.h"
@ -55,27 +56,27 @@ enum
};
static const stat_column titles[]={
{G_TYPE_STRING, LEFT, "Type" },
{G_TYPE_UINT, RIGHT, "Messages" },
{G_TYPE_STRING, RIGHT, "Min SRT" },
{G_TYPE_STRING, RIGHT, "Max SRT" },
{G_TYPE_STRING, RIGHT, "Avg SRT" },
{G_TYPE_UINT, RIGHT, "Min in Frame" },
{G_TYPE_UINT, RIGHT, "Max in Frame" }
{G_TYPE_STRING, TAP_ALIGN_LEFT, "Type" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Messages" },
{G_TYPE_STRING, TAP_ALIGN_RIGHT, "Min SRT" },
{G_TYPE_STRING, TAP_ALIGN_RIGHT, "Max SRT" },
{G_TYPE_STRING, TAP_ALIGN_RIGHT, "Avg SRT" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Min in Frame" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Max in Frame" }
};
static const stat_column titles_more[]={
{G_TYPE_STRING, LEFT, "Type" },
{G_TYPE_UINT, RIGHT, "Messages" },
{G_TYPE_STRING, RIGHT, "Min SRT" },
{G_TYPE_STRING, RIGHT, "Max SRT" },
{G_TYPE_STRING, RIGHT, "Avg SRT" },
{G_TYPE_UINT, RIGHT, "Min in Frame" },
{G_TYPE_UINT, RIGHT, "Max in Frame" },
{G_TYPE_UINT, RIGHT, "Open Requests" },
{G_TYPE_UINT, RIGHT, "Discarded Responses" },
{G_TYPE_STRING, RIGHT, "Repeated Requests" },
{G_TYPE_STRING, RIGHT, "Repeated Responses"}
{G_TYPE_STRING, TAP_ALIGN_LEFT, "Type" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Messages" },
{G_TYPE_STRING, TAP_ALIGN_RIGHT, "Min SRT" },
{G_TYPE_STRING, TAP_ALIGN_RIGHT, "Max SRT" },
{G_TYPE_STRING, TAP_ALIGN_RIGHT, "Avg SRT" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Min in Frame" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Max in Frame" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Open Requests" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Discarded Responses" },
{G_TYPE_STRING, TAP_ALIGN_RIGHT, "Repeated Requests" },
{G_TYPE_STRING, TAP_ALIGN_RIGHT, "Repeated Responses"}
};
typedef struct _gtk_rtd_t {
@ -374,6 +375,7 @@ void register_response_time_delay_tables(gpointer data, gpointer user_data _U_)
rtd_dlg->nparams = G_N_ELEMENTS(rtd_stat_params);
rtd_dlg->params = rtd_stat_params;
rtd_dlg->user_data = rtd; /* TODO: Actually use this */
register_param_stat(rtd_dlg, short_name, REGISTER_STAT_GROUP_RESPONSE_TIME);
}

View File

@ -1656,7 +1656,8 @@ static tap_param_dlg rlc_lte_stat_dlg = {
gtk_rlc_lte_stat_init,
-1,
G_N_ELEMENTS(rlc_lte_stat_params),
rlc_lte_stat_params
rlc_lte_stat_params,
NULL
};

View File

@ -54,7 +54,8 @@ static tap_param_dlg sctp_stat_dlg = {
sctpstat_init,
-1,
G_N_ELEMENTS(sctp_stat_params),
sctp_stat_params
sctp_stat_params,
NULL
};
typedef struct sctp_ep {
@ -234,26 +235,26 @@ win_destroy_cb(GtkWindow *win _U_, gpointer data)
static const stat_column titles[]={
{G_TYPE_STRING, LEFT, "Source IP" },
{G_TYPE_UINT, RIGHT, "Source Port" },
{G_TYPE_STRING, LEFT, "Dest IP" },
{G_TYPE_UINT, RIGHT, "Dest Port" },
{G_TYPE_UINT, RIGHT, "DATA" },
{G_TYPE_UINT, RIGHT, "SACK" },
{G_TYPE_UINT, RIGHT, "HBEAT" },
{G_TYPE_UINT, RIGHT, "HBEAT-ACK" },
{G_TYPE_UINT, RIGHT, "INIT" },
{G_TYPE_UINT, RIGHT, "INIT-ACK" },
{G_TYPE_UINT, RIGHT, "COOKIE" },
{G_TYPE_UINT, RIGHT, "COOKIE-ACK" },
{G_TYPE_UINT, RIGHT, "ABORT" },
{G_TYPE_UINT, RIGHT, "ERROR" },
{G_TYPE_UINT, RIGHT, "NR-SACK" },
{G_TYPE_UINT, RIGHT, "ASCONF-ACK" },
{G_TYPE_UINT, RIGHT, "PKTDROP" },
{G_TYPE_UINT, RIGHT, "FORWARD-TSN" },
{G_TYPE_UINT, RIGHT, "ASCONF" },
{G_TYPE_UINT, RIGHT, "Others" }
{G_TYPE_STRING, TAP_ALIGN_LEFT, "Source IP" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Source Port" },
{G_TYPE_STRING, TAP_ALIGN_LEFT, "Dest IP" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Dest Port" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "DATA" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "SACK" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "HBEAT" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "HBEAT-ACK" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "INIT" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "INIT-ACK" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "COOKIE" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "COOKIE-ACK" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "ABORT" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "ERROR" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "NR-SACK" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "ASCONF-ACK" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "PKTDROP" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "FORWARD-TSN" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "ASCONF" },
{G_TYPE_UINT, TAP_ALIGN_RIGHT, "Others" }
};
static void

View File

@ -856,6 +856,7 @@ void register_service_response_tables(gpointer data, gpointer user_data _U_)
srt_dlg->init_string = srt_table_get_tap_string(srt);
srt_dlg->tap_init_cb = gtk_srtstat_init;
srt_dlg->index = -1;
srt_dlg->user_data = srt; /* TODO: Actually use this */
if (get_srt_proto_id(srt) == proto_get_id_by_filter_name("scsi"))
{
srt_dlg->nparams = G_N_ELEMENTS(scsi_stat_params);

298
ui/gtk/simple_stattable.c Normal file
View File

@ -0,0 +1,298 @@
/* simple_stattable.c
*
* Based on response_time_delay_table.c
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "epan/packet_info.h"
#include "epan/proto.h"
#include <epan/stat_tap_ui.h>
#include "ui/simple_dialog.h"
#include "ui/utf8_entities.h"
#include "ui/gtk/filter_utils.h"
#include "ui/gtk/gui_stat_util.h"
#include "ui/gtk/gui_utils.h"
#include "ui/gtk/dlg_utils.h"
#include "ui/gtk/simple_stattable.h"
#include "ui/gtk/tap_param_dlg.h"
#include "ui/gtk/main.h"
typedef struct _gtk_simplestat_t {
GtkWidget *vbox;
GtkWidget *win;
GtkTreeView *table; /**< Tree view */
GtkWidget *scrolled_window; /**< window widget */
GtkWidget *menu; /**< context menu */
} gtk_simplestat_t_t;
typedef struct _simple_stat_t {
const char *filter;
gtk_simplestat_t_t gtk_data;
new_stat_tap_ui *new_stat_tap;
new_stat_data_t data;
} simple_stat_t;
static void
win_destroy_cb(GtkWindow *win _U_, gpointer data)
{
simple_stat_t *ss = (simple_stat_t*)data;
remove_tap_listener(&ss->data);
free_stat_table(ss->new_stat_tap, NULL, NULL);
g_free(ss);
}
static void
init_gtk_simple_stat_table(new_stat_tap_table* stat_table, void* gui_data)
{
guint i;
new_stat_data_t* stat_data = (new_stat_data_t*)gui_data;
simple_stat_t *ss = (simple_stat_t*)stat_data->user_data;
stat_column *start_columns = g_new(stat_column, stat_table->num_fields),
*columns;
stat_tap_table_item* field;
GType gtk_type;
/* XXX - Use # columns/fields, etc to compute a better value */
gtk_window_set_default_size(GTK_WINDOW(ss->gtk_data.win), 600, 300);
for (i = 0, columns = start_columns, field = stat_data->new_stat_tap_data->fields;
i < stat_table->num_fields;
i++, columns++, field++)
{
switch(field->type)
{
case TABLE_ITEM_UINT:
gtk_type = G_TYPE_UINT;
break;
case TABLE_ITEM_INT:
gtk_type = G_TYPE_INT;
break;
case TABLE_ITEM_STRING:
gtk_type = G_TYPE_STRING;
break;
case TABLE_ITEM_FLOAT:
gtk_type = G_TYPE_FLOAT;
break;
case TABLE_ITEM_ENUM:
gtk_type = G_TYPE_ENUM;
break;
default:
g_assert(FALSE);
return;
}
columns->type = gtk_type;
columns->align = field->align;
columns->title = field->column_name;
}
ss->gtk_data.table = create_stat_table(ss->gtk_data.scrolled_window, ss->gtk_data.vbox, stat_table->num_fields, start_columns);
g_free(start_columns);
}
static void
simple_stat_draw(void *arg)
{
GtkListStore *store;
new_stat_data_t *stats = (new_stat_data_t*)arg;
simple_stat_t *ss = (simple_stat_t*)stats->user_data;
new_stat_tap_table* table;
stat_tap_table_item* field;
stat_tap_table_item_type* field_data;
GtkTreeIter iter;
guint table_index = 0, element, field_index;
/* clear list before printing */
store = GTK_LIST_STORE(gtk_tree_view_get_model(ss->gtk_data.table));
gtk_list_store_clear(store);
/* XXX - Only support a single table at the moment */
table = g_array_index(stats->new_stat_tap_data->tables, new_stat_tap_table*, table_index);
for (element = 0; element < table->num_elements; element++)
{
field_index = 0;
field_data = new_stat_tap_get_field_data(table, element, field_index);
if (field_data->type == TABLE_ITEM_NONE) /* Nothing for us here */
continue;
gtk_list_store_append(store, &iter);
for (field = stats->new_stat_tap_data->fields; field_index < table->num_fields; field_index++, field++)
{
field_data = new_stat_tap_get_field_data(table, element, field_index);
switch(field_data->type)
{
case TABLE_ITEM_UINT:
gtk_list_store_set(store, &iter, field_index, field_data->value.uint_value, -1);
break;
case TABLE_ITEM_INT:
gtk_list_store_set(store, &iter, field_index, field_data->value.int_value, -1);
break;
case TABLE_ITEM_STRING:
gtk_list_store_set(store, &iter, field_index, field_data->value.string_value, -1);
break;
case TABLE_ITEM_FLOAT:
gtk_list_store_set(store, &iter, field_index, field_data->value.float_value, -1);
break;
case TABLE_ITEM_ENUM:
gtk_list_store_set(store, &iter, field_index, field_data->value.enum_value, -1);
break;
case TABLE_ITEM_NONE:
break;
}
}
}
}
static void
reset_table_data(new_stat_tap_table* table _U_, void* gui_data)
{
GtkListStore *store;
gtk_simplestat_t_t* gtk_data = (gtk_simplestat_t_t*)gui_data;
store = GTK_LIST_STORE(gtk_tree_view_get_model(gtk_data->table));
gtk_list_store_clear(store);
}
static void
simple_stat_reset(void *arg)
{
new_stat_data_t *stats = (new_stat_data_t*)arg;
simple_stat_t *ss = (simple_stat_t*)stats->user_data;
reset_stat_table(stats->new_stat_tap_data, reset_table_data, &ss->gtk_data);
set_window_title(ss->gtk_data.win, ss->new_stat_tap->title);
}
static void
init_simple_stat_tables(new_stat_tap_ui *new_stat_tap, const char *filter)
{
simple_stat_t *ss;
GString *error_string;
GtkWidget *bbox;
GtkWidget *close_bt;
ss = g_new0(simple_stat_t, 1);
ss->gtk_data.win=dlg_window_new(new_stat_tap->title); /* transient_for top_level */
gtk_window_set_destroy_with_parent (GTK_WINDOW(ss->gtk_data.win), TRUE);
ss->gtk_data.vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
init_main_stat_window(ss->gtk_data.win, ss->gtk_data.vbox, new_stat_tap->title, filter);
/* init a scrolled window*/
ss->gtk_data.scrolled_window = scrolled_window_new(NULL, NULL);
ss->filter = g_strdup(filter);
ss->new_stat_tap = new_stat_tap;
ss->data.new_stat_tap_data = new_stat_tap;
ss->data.user_data = ss;
new_stat_tap->stat_tap_init_cb(new_stat_tap, init_gtk_simple_stat_table, &ss->data);
error_string = register_tap_listener(new_stat_tap->tap_name, &ss->data, filter, 0, simple_stat_reset, new_stat_tap->packet_func, simple_stat_draw);
if(error_string){
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
g_string_free(error_string, TRUE);
free_stat_table(ss->new_stat_tap, NULL, NULL);
g_free(ss);
return;
}
/* Button row. */
bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
gtk_box_pack_end(GTK_BOX(ss->gtk_data.vbox), bbox, FALSE, FALSE, 0);
close_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
window_set_cancel_button(ss->gtk_data.win, close_bt, window_cancel_button_cb);
g_signal_connect(ss->gtk_data.win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
g_signal_connect(ss->gtk_data.win, "destroy", G_CALLBACK(win_destroy_cb), ss);
gtk_widget_show_all(ss->gtk_data.win);
window_present(ss->gtk_data.win);
cf_retap_packets(&cfile);
gdk_window_raise(gtk_widget_get_window(ss->gtk_data.win));
}
static void
gtk_simple_stat_init(const char *opt_arg, void *userdata)
{
new_stat_tap_ui *new_stat_tap = (new_stat_tap_ui*)userdata;
const char *filter=NULL;
char* err;
new_stat_tap_get_filter(new_stat_tap, opt_arg, &filter, &err);
if (err != NULL)
{
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err);
g_free(err);
return;
}
init_simple_stat_tables(new_stat_tap, filter);
}
void register_simple_stat_tables(gpointer data, gpointer user_data _U_)
{
new_stat_tap_ui *new_stat_tap = (new_stat_tap_ui*)data;
tap_param_dlg* stat_dlg;
stat_dlg = g_new(tap_param_dlg, 1);
stat_dlg->win_title = new_stat_tap->title;
stat_dlg->init_string = new_stat_tap->cli_string;
stat_dlg->tap_init_cb = gtk_simple_stat_init;
stat_dlg->index = -1;
stat_dlg->nparams = new_stat_tap->nparams;
stat_dlg->params = new_stat_tap->params;
stat_dlg->user_data = new_stat_tap;
register_param_stat(stat_dlg, new_stat_tap->title, new_stat_tap->group);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

37
ui/gtk/simple_stattable.h Normal file
View File

@ -0,0 +1,37 @@
/* simple_stattable.h
*
* Based on response_time_delay_table.h
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __SIMPLE_STAT_TABLE_H__
#define __SIMPLE_STAT_TABLE_H__
#include <gtk/gtk.h>
#include "epan/stat_tap_ui.h"
/** Register function to register dissectors that support a "simple" statistics table.
*
* @param data new_stat_tap_ui* representing dissetor stat table
* @param user_data is unused
*/
void register_simple_stat_tables(gpointer data, gpointer user_data);
#endif /* __SIMPLE_STAT_TABLE_H__ */

View File

@ -680,7 +680,8 @@ static tap_param_dlg sip_stat_dlg = {
gtk_sipstat_init,
-1,
G_N_ELEMENTS(sip_stat_params),
sip_stat_params
sip_stat_params,
NULL
};
/* Register this tap listener and add menu item. */

View File

@ -557,6 +557,7 @@ register_gtk_stats_tree_tap (gpointer k _U_, gpointer v, gpointer p _U_)
cfg->pr->stat_dlg->index = -1;
cfg->pr->stat_dlg->nparams = G_N_ELEMENTS(tree_stat_params);
cfg->pr->stat_dlg->params = tree_stat_params;
cfg->pr->stat_dlg->user_data = NULL;
g_free(display_name);
}

View File

@ -183,7 +183,7 @@ tap_param_dlg_start_button_clicked(GtkWidget *item _U_, gpointer dialog_data)
break;
}
}
(dlg_data->cont.tap_init_cb)(params->str,NULL);
(dlg_data->cont.tap_init_cb)(params->str, dlg_data->cont.user_data);
g_string_free(params, TRUE);
}
@ -222,6 +222,7 @@ tap_param_dlg_cb(GtkAction *action _U_, gpointer data)
end_dlg_list->cont.tap_init_cb = dlg_data->tap_init_cb;
end_dlg_list->cont.nparams = dlg_data->nparams;
end_dlg_list->cont.params = dlg_data->params;
end_dlg_list->cont.user_data = dlg_data->user_data;
end_dlg_list->args.title = g_strdup_printf("%s Filter", dlg_data->win_title);
end_dlg_list->args.wants_apply_button = TRUE;
end_dlg_list->args.activate_on_ok = FALSE;
@ -248,6 +249,13 @@ tap_param_dlg_cb(GtkAction *action _U_, gpointer data)
return;
}
/* If we don't have any parameters, just launch the stat dialog */
if (current_dlg->cont.nparams == 0)
{
tap_param_dlg_start_button_clicked(NULL, current_dlg);
return;
}
display_name = cf_get_display_name(&cfile);
title = g_strdup_printf("Wireshark: %s: %s", current_dlg->cont.win_title , display_name);
g_free(display_name);

View File

@ -71,6 +71,7 @@ typedef struct _tap_param_dlg {
gint index; /* initiate this value always with "-1" */
size_t nparams; /* number of parameters */
tap_param *params; /* pointer to table of parameter info */
gpointer user_data; /* Optional "dialog specific" data */
} tap_param_dlg;
/*

View File

@ -405,7 +405,8 @@ static tap_param_dlg wsp_stat_dlg = {
gtk_wspstat_init,
-1,
G_N_ELEMENTS(wsp_stat_params),
wsp_stat_params
wsp_stat_params,
NULL
};
void