Convert the GSM MAP stats to new "generic stat API".

Convert both the MAP statistics and summary. As with the GSM A stats
this are mostly untested.

Change-Id: Ibd3a7346b09d1401e78724c0197ec2a38deb97a3
Reviewed-on: https://code.wireshark.org/review/9883
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
Gerald Combs 2015-08-04 17:42:53 -07:00
parent 05eb9b69b8
commit b7f5eaa524
24 changed files with 969 additions and 554 deletions

View File

@ -48,6 +48,7 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/stat_tap_ui.h>
#include <epan/tap.h>
#include <epan/oids.h>
#include <epan/expert.h>
@ -2143,7 +2144,7 @@ dissect_gsm_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void
if (op_idx != -1) {
tap_rec.invoke = (gsmmap_pdu_type == 1) ? TRUE : FALSE;
tap_rec.opr_code_idx = op_idx;
tap_rec.opcode = opcode;
tap_rec.size = gsm_map_pdu_size;
tap_queue_packet(gsm_map_tap, pinfo, &tap_rec);
@ -2181,7 +2182,7 @@ dissect_gsm_map_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
if (op_idx != -1) {
tap_rec.invoke = (gsmmap_pdu_type == 1) ? TRUE : FALSE;
tap_rec.opr_code_idx = op_idx;
tap_rec.opcode = opcode;
tap_rec.size = gsm_map_pdu_size;
tap_queue_packet(gsm_map_tap, pinfo, &tap_rec);
@ -2456,6 +2457,141 @@ static const value_string chargingcharacteristics_values[] = {
{ 0, NULL }
};
/* TAP STAT INFO */
typedef enum
{
ID_COLUMN,
OP_CODE_COLUMN,
INVOKES_COLUMN,
NUM_BYTES_FWD_COLUMN,
AVG_BYTES_FWD_COLUMN,
RET_RES_COLUMN,
NUM_BYTES_REV_COLUMN,
AVG_BYTES_REV_COLUMN,
TOT_BYTES_COLUMN,
AVG_BYTES_COLUMN
} gsm_a_stat_columns;
static stat_tap_table_item gsm_map_stat_fields[] = {
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "ID", "%d"},
{TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Operation Code", "%-25s"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Invokes", "%d"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Num Bytes", "%d"},
{TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", "%d"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Return Result", "%d"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Num Bytes", "%d"},
{TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", "%d"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Total Bytes", "%d"},
{TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", "%d"},
};
void gsm_map_stat_init(new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
{
int num_fields = sizeof(gsm_map_stat_fields)/sizeof(stat_tap_table_item);
new_stat_tap_table* table;
guint i;
stat_tap_table_item_type items[sizeof(gsm_map_stat_fields)/sizeof(stat_tap_table_item)];
memset(items, 0, sizeof(items));
items[ID_COLUMN].type = TABLE_ITEM_UINT;
items[OP_CODE_COLUMN].type = TABLE_ITEM_STRING;
items[INVOKES_COLUMN].type = TABLE_ITEM_UINT;
items[NUM_BYTES_FWD_COLUMN].type = TABLE_ITEM_UINT;
items[AVG_BYTES_FWD_COLUMN].type = TABLE_ITEM_FLOAT;
items[RET_RES_COLUMN].type = TABLE_ITEM_UINT;
items[NUM_BYTES_REV_COLUMN].type = TABLE_ITEM_UINT;
items[AVG_BYTES_REV_COLUMN].type = TABLE_ITEM_FLOAT;
items[TOT_BYTES_COLUMN].type = TABLE_ITEM_UINT;
items[AVG_BYTES_COLUMN].type = TABLE_ITEM_FLOAT;
table = new_stat_tap_init_table("GSM MAP Operation Statistics", num_fields, 0, NULL, gui_callback, gui_data);
new_stat_tap_add_table(new_stat, table);
/* Add a row for each value type */
for (i = 0; i < GSM_MAP_MAX_NUM_OPR_CODES; i++)
{
const char *ocs = try_val_to_str(i, gsm_map_opr_code_strings);
if (!ocs) ocs = g_strdup_printf("Unknown op code %d", i);
items[ID_COLUMN].value.uint_value = i;
items[OP_CODE_COLUMN].value.string_value = ocs;
new_stat_tap_init_table_row(table, i, num_fields, items);
}
}
static gboolean
gsm_map_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gmtr_ptr)
{
new_stat_data_t* stat_data = (new_stat_data_t*)tapdata;
const gsm_map_tap_rec_t *gmtr = (const gsm_map_tap_rec_t *)gmtr_ptr;
new_stat_tap_table* table;
stat_tap_table_item_type *invoke_data, *fwd_bytes_data, *result_data, *rev_bytes_data, *avg_data;
guint invokes, fwd_bytes, results, rev_bytes;
guint i = 0;
table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, i);
invoke_data = new_stat_tap_get_field_data(table, gmtr->opcode, INVOKES_COLUMN);
fwd_bytes_data = new_stat_tap_get_field_data(table, gmtr->opcode, NUM_BYTES_FWD_COLUMN);
result_data = new_stat_tap_get_field_data(table, gmtr->opcode, RET_RES_COLUMN);
rev_bytes_data = new_stat_tap_get_field_data(table, gmtr->opcode, NUM_BYTES_REV_COLUMN);
if (gmtr->invoke)
{
invoke_data->value.uint_value++;
new_stat_tap_set_field_data(table, gmtr->opcode, INVOKES_COLUMN, invoke_data);
fwd_bytes_data->value.uint_value += gmtr->size;
new_stat_tap_set_field_data(table, gmtr->opcode, NUM_BYTES_FWD_COLUMN, fwd_bytes_data);
}
else
{
result_data->value.uint_value++;
new_stat_tap_set_field_data(table, gmtr->opcode, RET_RES_COLUMN, result_data);
rev_bytes_data->value.uint_value += gmtr->size;
new_stat_tap_set_field_data(table, gmtr->opcode, NUM_BYTES_REV_COLUMN, rev_bytes_data);
}
invokes = invoke_data->value.uint_value;
fwd_bytes = fwd_bytes_data->value.uint_value;
results = result_data->value.uint_value;
rev_bytes = rev_bytes_data->value.uint_value;
if (gmtr->invoke)
{
avg_data = new_stat_tap_get_field_data(table, gmtr->opcode, AVG_BYTES_FWD_COLUMN);
avg_data->value.float_value += (float) fwd_bytes / invokes;
new_stat_tap_set_field_data(table, gmtr->opcode, AVG_BYTES_FWD_COLUMN, avg_data);
}
else
{
avg_data = new_stat_tap_get_field_data(table, gmtr->opcode, AVG_BYTES_REV_COLUMN);
avg_data->value.float_value += (float) rev_bytes / results;
new_stat_tap_set_field_data(table, gmtr->opcode, AVG_BYTES_REV_COLUMN, avg_data);
}
avg_data = new_stat_tap_get_field_data(table, gmtr->opcode, AVG_BYTES_COLUMN);
avg_data->value.float_value += (float) (fwd_bytes + rev_bytes) / (invokes + results);
new_stat_tap_set_field_data(table, gmtr->opcode, AVG_BYTES_COLUMN, avg_data);
return TRUE;
}
static void
gsm_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, INVOKES_COLUMN);
item_data->value.uint_value = 0;
new_stat_tap_set_field_data(table, element, INVOKES_COLUMN, item_data);
}
}
/*--- proto_reg_handoff_gsm_map ---------------------------------------*/
static void range_delete_callback(guint32 ssn)
{
@ -2952,6 +3088,24 @@ void proto_register_gsm_map(void) {
{NULL, NULL, -1}
};
static tap_param gsm_map_stat_params[] = {
{ PARAM_FILTER, "filter", "Filter", NULL, TRUE }
};
static new_stat_tap_ui gsm_map_stat_table = {
REGISTER_STAT_GROUP_TELEPHONY_GSM,
"MAP Operation",
"gsm_map",
"gsm_map,operation",
gsm_map_stat_init,
gsm_map_stat_packet,
gsm_map_stat_reset,
NULL,
NULL,
sizeof(gsm_map_stat_fields)/sizeof(stat_tap_table_item), gsm_map_stat_fields,
sizeof(gsm_map_stat_params)/sizeof(tap_param), gsm_map_stat_params,
NULL
};
/* Register protocol */
proto_gsm_map_dialogue =proto_gsm_map = proto_register_protocol(PNAME, PSNAME, PFNAME);
@ -2996,4 +3150,6 @@ void proto_register_gsm_map(void) {
"Dissect Ericsson proprietary extensions",
"When enabled, dissector will use the non 3GPP standard extensions from Ericsson (that can override the standard ones)",
&pref_ericsson_proprietary_ext);
register_new_stat_tap_ui(&gsm_map_stat_table);
}

View File

@ -31,7 +31,7 @@
typedef struct _gsm_map_tap_rec_t {
gboolean invoke;
guint8 opr_code_idx;
guint32 opcode;
guint16 size;
} gsm_map_tap_rec_t;

View File

@ -56,6 +56,7 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/stat_tap_ui.h>
#include <epan/tap.h>
#include <epan/oids.h>
#include <epan/expert.h>
@ -1898,7 +1899,7 @@ static int hf_NokiaMAP_Extensions_AccessSubscriptionListExt_item = -1; /* Acces
static int hf_NokiaMAP_Extensions_AllowedServiceData_amr_wb_allowed = -1;
/*--- End of included file: packet-gsm_map-hf.c ---*/
#line 150 "../../asn1/gsm_map/packet-gsm_map-template.c"
#line 151 "../../asn1/gsm_map/packet-gsm_map-template.c"
/* Initialize the subtree pointers */
static gint ett_gsm_map = -1;
@ -2611,7 +2612,7 @@ static gint ett_NokiaMAP_Extensions_AccessSubscriptionListExt = -1;
static gint ett_NokiaMAP_Extensions_AllowedServiceData = -1;
/*--- End of included file: packet-gsm_map-ett.c ---*/
#line 182 "../../asn1/gsm_map/packet-gsm_map-template.c"
#line 183 "../../asn1/gsm_map/packet-gsm_map-template.c"
static expert_field ei_gsm_map_unknown_sequence3 = EI_INIT;
static expert_field ei_gsm_map_unknown_sequence = EI_INIT;
@ -20410,7 +20411,7 @@ dissect_NokiaMAP_Extensions_AllowedServiceData(gboolean implicit_tag _U_, tvbuff
/*--- End of included file: packet-gsm_map-fn.c ---*/
#line 829 "../../asn1/gsm_map/packet-gsm_map-template.c"
#line 830 "../../asn1/gsm_map/packet-gsm_map-template.c"
/* Specific translation for MAP V3 */
const value_string gsm_map_V1V2_opr_code_strings[] = {
@ -20632,7 +20633,7 @@ const value_string gsm_map_opr_code_strings[] = {
/* Unknown or empty loop list OPERATION */
/*--- End of included file: packet-gsm_map-table.c ---*/
#line 840 "../../asn1/gsm_map/packet-gsm_map-template.c"
#line 841 "../../asn1/gsm_map/packet-gsm_map-template.c"
{ 0, NULL }
};
@ -20849,7 +20850,7 @@ static const value_string gsm_map_err_code_string_vals[] = {
/* Unknown or empty loop list OPERATION */
/*--- End of included file: packet-gsm_map-table.c ---*/
#line 846 "../../asn1/gsm_map/packet-gsm_map-template.c"
#line 847 "../../asn1/gsm_map/packet-gsm_map-template.c"
{ 0, NULL }
};
#endif
@ -22150,7 +22151,7 @@ dissect_gsm_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void
if (op_idx != -1) {
tap_rec.invoke = (gsmmap_pdu_type == 1) ? TRUE : FALSE;
tap_rec.opr_code_idx = op_idx;
tap_rec.opcode = opcode;
tap_rec.size = gsm_map_pdu_size;
tap_queue_packet(gsm_map_tap, pinfo, &tap_rec);
@ -22188,7 +22189,7 @@ dissect_gsm_map_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
if (op_idx != -1) {
tap_rec.invoke = (gsmmap_pdu_type == 1) ? TRUE : FALSE;
tap_rec.opr_code_idx = op_idx;
tap_rec.opcode = opcode;
tap_rec.size = gsm_map_pdu_size;
tap_queue_packet(gsm_map_tap, pinfo, &tap_rec);
@ -22463,6 +22464,141 @@ static const value_string chargingcharacteristics_values[] = {
{ 0, NULL }
};
/* TAP STAT INFO */
typedef enum
{
ID_COLUMN,
OP_CODE_COLUMN,
INVOKES_COLUMN,
NUM_BYTES_FWD_COLUMN,
AVG_BYTES_FWD_COLUMN,
RET_RES_COLUMN,
NUM_BYTES_REV_COLUMN,
AVG_BYTES_REV_COLUMN,
TOT_BYTES_COLUMN,
AVG_BYTES_COLUMN
} gsm_a_stat_columns;
static stat_tap_table_item gsm_map_stat_fields[] = {
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "ID", "%d"},
{TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Operation Code", "%-25s"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Invokes", "%d"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Num Bytes", "%d"},
{TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", "%d"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Return Result", "%d"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Num Bytes", "%d"},
{TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", "%d"},
{TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Total Bytes", "%d"},
{TABLE_ITEM_FLOAT, TAP_ALIGN_RIGHT, "Avg Bytes", "%d"},
};
void gsm_map_stat_init(new_stat_tap_ui* new_stat, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
{
int num_fields = sizeof(gsm_map_stat_fields)/sizeof(stat_tap_table_item);
new_stat_tap_table* table;
guint i;
stat_tap_table_item_type items[sizeof(gsm_map_stat_fields)/sizeof(stat_tap_table_item)];
memset(items, 0, sizeof(items));
items[ID_COLUMN].type = TABLE_ITEM_UINT;
items[OP_CODE_COLUMN].type = TABLE_ITEM_STRING;
items[INVOKES_COLUMN].type = TABLE_ITEM_UINT;
items[NUM_BYTES_FWD_COLUMN].type = TABLE_ITEM_UINT;
items[AVG_BYTES_FWD_COLUMN].type = TABLE_ITEM_FLOAT;
items[RET_RES_COLUMN].type = TABLE_ITEM_UINT;
items[NUM_BYTES_REV_COLUMN].type = TABLE_ITEM_UINT;
items[AVG_BYTES_REV_COLUMN].type = TABLE_ITEM_FLOAT;
items[TOT_BYTES_COLUMN].type = TABLE_ITEM_UINT;
items[AVG_BYTES_COLUMN].type = TABLE_ITEM_FLOAT;
table = new_stat_tap_init_table("GSM MAP Operation Statistics", num_fields, 0, NULL, gui_callback, gui_data);
new_stat_tap_add_table(new_stat, table);
/* Add a row for each value type */
for (i = 0; i < GSM_MAP_MAX_NUM_OPR_CODES; i++)
{
const char *ocs = try_val_to_str(i, gsm_map_opr_code_strings);
if (!ocs) ocs = g_strdup_printf("Unknown op code %d", i);
items[ID_COLUMN].value.uint_value = i;
items[OP_CODE_COLUMN].value.string_value = ocs;
new_stat_tap_init_table_row(table, i, num_fields, items);
}
}
static gboolean
gsm_map_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *gmtr_ptr)
{
new_stat_data_t* stat_data = (new_stat_data_t*)tapdata;
const gsm_map_tap_rec_t *gmtr = (const gsm_map_tap_rec_t *)gmtr_ptr;
new_stat_tap_table* table;
stat_tap_table_item_type *invoke_data, *fwd_bytes_data, *result_data, *rev_bytes_data, *avg_data;
guint invokes, fwd_bytes, results, rev_bytes;
guint i = 0;
table = g_array_index(stat_data->new_stat_tap_data->tables, new_stat_tap_table*, i);
invoke_data = new_stat_tap_get_field_data(table, gmtr->opcode, INVOKES_COLUMN);
fwd_bytes_data = new_stat_tap_get_field_data(table, gmtr->opcode, NUM_BYTES_FWD_COLUMN);
result_data = new_stat_tap_get_field_data(table, gmtr->opcode, RET_RES_COLUMN);
rev_bytes_data = new_stat_tap_get_field_data(table, gmtr->opcode, NUM_BYTES_REV_COLUMN);
if (gmtr->invoke)
{
invoke_data->value.uint_value++;
new_stat_tap_set_field_data(table, gmtr->opcode, INVOKES_COLUMN, invoke_data);
fwd_bytes_data->value.uint_value += gmtr->size;
new_stat_tap_set_field_data(table, gmtr->opcode, NUM_BYTES_FWD_COLUMN, fwd_bytes_data);
}
else
{
result_data->value.uint_value++;
new_stat_tap_set_field_data(table, gmtr->opcode, RET_RES_COLUMN, result_data);
rev_bytes_data->value.uint_value += gmtr->size;
new_stat_tap_set_field_data(table, gmtr->opcode, NUM_BYTES_REV_COLUMN, rev_bytes_data);
}
invokes = invoke_data->value.uint_value;
fwd_bytes = fwd_bytes_data->value.uint_value;
results = result_data->value.uint_value;
rev_bytes = rev_bytes_data->value.uint_value;
if (gmtr->invoke)
{
avg_data = new_stat_tap_get_field_data(table, gmtr->opcode, AVG_BYTES_FWD_COLUMN);
avg_data->value.float_value += (float) fwd_bytes / invokes;
new_stat_tap_set_field_data(table, gmtr->opcode, AVG_BYTES_FWD_COLUMN, avg_data);
}
else
{
avg_data = new_stat_tap_get_field_data(table, gmtr->opcode, AVG_BYTES_REV_COLUMN);
avg_data->value.float_value += (float) rev_bytes / results;
new_stat_tap_set_field_data(table, gmtr->opcode, AVG_BYTES_REV_COLUMN, avg_data);
}
avg_data = new_stat_tap_get_field_data(table, gmtr->opcode, AVG_BYTES_COLUMN);
avg_data->value.float_value += (float) (fwd_bytes + rev_bytes) / (invokes + results);
new_stat_tap_set_field_data(table, gmtr->opcode, AVG_BYTES_COLUMN, avg_data);
return TRUE;
}
static void
gsm_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, INVOKES_COLUMN);
item_data->value.uint_value = 0;
new_stat_tap_set_field_data(table, element, INVOKES_COLUMN, item_data);
}
}
/*--- proto_reg_handoff_gsm_map ---------------------------------------*/
static void range_delete_callback(guint32 ssn)
{
@ -29704,7 +29840,7 @@ void proto_register_gsm_map(void) {
NULL, HFILL }},
/*--- End of included file: packet-gsm_map-hfarr.c ---*/
#line 2903 "../../asn1/gsm_map/packet-gsm_map-template.c"
#line 3039 "../../asn1/gsm_map/packet-gsm_map-template.c"
};
/* List of subtrees */
@ -30419,7 +30555,7 @@ void proto_register_gsm_map(void) {
&ett_NokiaMAP_Extensions_AllowedServiceData,
/*--- End of included file: packet-gsm_map-ettarr.c ---*/
#line 2937 "../../asn1/gsm_map/packet-gsm_map-template.c"
#line 3073 "../../asn1/gsm_map/packet-gsm_map-template.c"
};
static ei_register_info ei[] = {
@ -30438,6 +30574,24 @@ void proto_register_gsm_map(void) {
{NULL, NULL, -1}
};
static tap_param gsm_map_stat_params[] = {
{ PARAM_FILTER, "filter", "Filter", NULL, TRUE }
};
static new_stat_tap_ui gsm_map_stat_table = {
REGISTER_STAT_GROUP_TELEPHONY_GSM,
"MAP Operation",
"gsm_map",
"gsm_map,operation",
gsm_map_stat_init,
gsm_map_stat_packet,
gsm_map_stat_reset,
NULL,
NULL,
sizeof(gsm_map_stat_fields)/sizeof(stat_tap_table_item), gsm_map_stat_fields,
sizeof(gsm_map_stat_params)/sizeof(tap_param), gsm_map_stat_params,
NULL
};
/* Register protocol */
proto_gsm_map_dialogue =proto_gsm_map = proto_register_protocol(PNAME, PSNAME, PFNAME);
@ -30523,7 +30677,7 @@ void proto_register_gsm_map(void) {
/*--- End of included file: packet-gsm_map-dis-tab.c ---*/
#line 2975 "../../asn1/gsm_map/packet-gsm_map-template.c"
#line 3129 "../../asn1/gsm_map/packet-gsm_map-template.c"
oid_add_from_string("ericsson-gsm-Map-Ext","1.2.826.0.1249.58.1.0" );
oid_add_from_string("accessTypeNotAllowed-id","1.3.12.2.1107.3.66.1.2");
/*oid_add_from_string("map-ac networkLocUp(1) version3(3)","0.4.0.0.1.0.1.3" );
@ -30548,4 +30702,6 @@ void proto_register_gsm_map(void) {
"Dissect Ericsson proprietary extensions",
"When enabled, dissector will use the non 3GPP standard extensions from Ericsson (that can override the standard ones)",
&pref_ericsson_proprietary_ext);
register_new_stat_tap_ui(&gsm_map_stat_table);
}

View File

@ -39,7 +39,7 @@
typedef struct _gsm_map_tap_rec_t {
gboolean invoke;
guint8 opr_code_idx;
guint32 opcode;
guint16 size;
} gsm_map_tap_rec_t;

View File

@ -202,7 +202,6 @@ set(WIRESHARK_TAP_SRC
expert_comp_dlg.c
flow_graph.c
funnel_stat.c
gsm_map_stat.c
gsm_map_summary.c
iax2_analysis.c
io_stat.c

View File

@ -153,7 +153,6 @@ WIRESHARK_TAP_SRC = \
export_pdu_dlg.c \
flow_graph.c \
funnel_stat.c \
gsm_map_stat.c \
gsm_map_summary.c \
iax2_analysis.c \
io_stat.c \
@ -225,7 +224,6 @@ noinst_HEADERS = \
font_utils.h \
goto_dlg.h \
graph_analysis.h \
gsm_map_stat.h \
gtk_iface_monitor.h \
gtkglobals.h \
gui_stat_menu.h \

View File

@ -1,494 +0,0 @@
/* gsm_map_stat.c
*
* Copyright 2004, 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 GSM MAP Operations:
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <epan/packet.h>
#include <epan/value_string.h>
#include <epan/stat_tap_ui.h>
#include <epan/tap.h>
#include <epan/asn1.h>
#include <epan/dissectors/packet-gsm_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"
#include "ui/gtk/gsm_map_stat.h"
void register_tap_listener_gtkgsm_map_stat(void);
enum
{
ID_COLUMN,
OP_CODE_COLUMN,
INVOKES_COLUMN,
NUM_BYTES_FWD_COLUMN,
AVG_BYTES_FWD_COLUMN,
RET_RES_COLUMN,
NUM_BYTES_REV_COLUMN,
AVG_BYTES_REV_COLUMN,
TOT_BYTES_COLUMN,
AVG_BYTES_COLUMN,
N_COLUMN /* The number of columns */
};
/* 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, /* ID */
G_TYPE_STRING, /* Operation Code */
G_TYPE_INT, /* Invokes */
G_TYPE_INT, /* Num Bytes */
G_TYPE_FLOAT, /* Avg Bytes */
G_TYPE_INT, /* RetResult */
G_TYPE_INT, /* Num Bytes */
G_TYPE_FLOAT, /* Avg Bytes */
G_TYPE_INT, /* 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, ID_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 ("ID", renderer,
"text", ID_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, ID_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, 40);
/* Add the column to the view. */
gtk_tree_view_append_column (list_view, column);
/* 2:nd column..Operation Code. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Operation Code", renderer,
"text", 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, 210);
gtk_tree_view_append_column (list_view, column);
/* 3:d column..Invokes. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Invokes", renderer,
"text", INVOKES_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, INVOKES_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);
gtk_tree_view_append_column (list_view, column);
/* 4:th column.. Num Bytes. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Num Bytes", renderer,
"text", NUM_BYTES_FWD_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_FWD_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);
/* 5:th column.. Avg Bytes. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer,
"text", AVG_BYTES_FWD_COLUMN,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func,
GINT_TO_POINTER(AVG_BYTES_FWD_COLUMN), NULL);
gtk_tree_view_column_set_sort_column_id(column, AVG_BYTES_FWD_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, 80);
gtk_tree_view_append_column (list_view, column);
/* 6:d column..Invokes. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("ReturnResult", renderer,
"text", RET_RES_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, RET_RES_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);
gtk_tree_view_append_column (list_view, column);
/* 7:th column.. Num Bytes. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Num Bytes", renderer,
"text", NUM_BYTES_REV_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id(column, NUM_BYTES_FWD_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);
/* 8:th column.. Avg Bytes. */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Avg Bytes", renderer,
"text", AVG_BYTES_REV_COLUMN,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func,
GINT_TO_POINTER(AVG_BYTES_REV_COLUMN), NULL);
gtk_tree_view_column_set_sort_column_id(column, AVG_BYTES_REV_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, 80);
gtk_tree_view_append_column (list_view, column);
/* 9:th column.. Total Bytes. */
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, NUM_BYTES_FWD_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, 60);
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;
}
typedef struct _gsm_map_stat_dlg_t {
GtkWidget *win;
GtkWidget *scrolled_win;
GtkWidget *table;
} gsm_map_stat_dlg_t;
static gsm_map_stat_dlg_t dlg;
/*
* used by gsm_map_summary.c
*/
gsm_map_stat_t gsm_map_stat;
static void
gsm_map_stat_reset(
void *tapdata)
{
gsm_map_stat_t *stat_p = (gsm_map_stat_t *)tapdata;
memset(stat_p, 0, sizeof(gsm_map_stat_t));
}
static gboolean
gsm_map_stat_packet(
void *tapdata,
packet_info *pinfo _U_,
epan_dissect_t *edt _U_,
const void *data)
{
gsm_map_stat_t *stat_p = (gsm_map_stat_t *)tapdata;
const gsm_map_tap_rec_t *data_p = (const gsm_map_tap_rec_t *)data;
#if 0 /* always false because message_type is 8 bit value */
if (data_p->opr_code_idx > sizeof(stat_p->opr_code))
{
/*
* unknown message type !!!
*/
return(FALSE);
}
#endif
if (data_p->invoke)
{
stat_p->opr_code[data_p->opr_code_idx]++;
stat_p->size[data_p->opr_code_idx] += data_p->size;
}
else
{
stat_p->opr_code_rr[data_p->opr_code_idx]++;
stat_p->size_rr[data_p->opr_code_idx] += data_p->size;
}
return(TRUE);
}
static void
gsm_map_stat_draw(
void *tapdata)
{
gsm_map_stat_t *stat_p = (gsm_map_stat_t *)tapdata;
int i;
GtkListStore *list_store;
GtkTreeIter iter;
if (dlg.win && tapdata)
{
list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg.table))); /* Get store */
i = 0;
while (gsm_map_opr_code_strings[i].strptr){
float avrage_bytes_fwd;
float avrage_bytes_rev;
float avrage_bytes_tot;
if (stat_p->opr_code[i] >0){
avrage_bytes_fwd =(float)stat_p->size[i]/(float)stat_p->opr_code[i];
}else{
avrage_bytes_fwd = 0;
}
if (stat_p->opr_code_rr[i] >0){
avrage_bytes_rev = (float)stat_p->size_rr[i]/(float)stat_p->opr_code_rr[i];
}else{
avrage_bytes_rev = 0;
}
if ((stat_p->opr_code[i] + stat_p->opr_code_rr[i])>0){
avrage_bytes_tot = (float)(stat_p->size[i] +stat_p->size_rr[i])/(float)(stat_p->opr_code[i] + stat_p->opr_code_rr[i]);
}else{
avrage_bytes_tot = 0;
}
/* 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,
ID_COLUMN, gsm_map_opr_code_strings[i].value,
OP_CODE_COLUMN, (char*)gsm_map_opr_code_strings[i].strptr,
INVOKES_COLUMN, stat_p->opr_code[i],
NUM_BYTES_FWD_COLUMN, (gint)stat_p->size[i],
AVG_BYTES_FWD_COLUMN, avrage_bytes_fwd,
RET_RES_COLUMN, stat_p->opr_code_rr[i],
NUM_BYTES_REV_COLUMN, stat_p->size_rr[i],
AVG_BYTES_REV_COLUMN, avrage_bytes_rev,
TOT_BYTES_COLUMN, stat_p->size[i] + stat_p->size_rr[i],
AVG_BYTES_COLUMN, avrage_bytes_tot,
-1);
i++;
}
}
}
static void
gsm_map_stat_gtk_win_destroy_cb(
GtkWindow *win _U_,
gpointer user_data)
{
memset((void *) user_data, 0, sizeof(gsm_map_stat_dlg_t));
}
static void
gsm_map_stat_gtk_win_create(
gsm_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), 560, 390);
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(gsm_map_stat_gtk_win_destroy_cb), dlg_p);
gtk_widget_show_all(dlg_p->win);
window_present(dlg_p->win);
}
void
gsm_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;
}
gsm_map_stat_gtk_win_create(&dlg, "GSM MAP Operation Statistics");
gsm_map_stat_draw(&gsm_map_stat);
}
static void
gsm_map_stat_gtk_init(const char *opt_arg _U_,
void* userdata _U_)
{
gsm_map_stat_gtk_cb(NULL, NULL);
}
static stat_tap_ui gsm_map_stat_ui = {
REGISTER_STAT_GROUP_GENERIC,
NULL,
"gsm_map",
gsm_map_stat_gtk_init,
0,
NULL
};
void
register_tap_listener_gtkgsm_map_stat(void)
{
GString *err_p;
memset((void *) &gsm_map_stat, 0, sizeof(gsm_map_stat_t));
err_p =
register_tap_listener("gsm_map", &gsm_map_stat, NULL, 0,
gsm_map_stat_reset,
gsm_map_stat_packet,
gsm_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(&gsm_map_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

@ -29,25 +29,33 @@
#include <gtk/gtk.h>
#include <epan/packet.h>
#include <epan/value_string.h>
#include <epan/tap.h>
#include <epan/asn1.h>
#include <epan/dissectors/packet-gsm_map.h>
#include <epan/stat_groups.h>
#include "../globals.h"
#include "../summary.h"
#include "globals.h"
#include "summary.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"
#include "ui/gtk/gsm_map_stat.h"
/** Gsm map statistic data */
typedef struct _gsm_map_stat_t {
int opr_code[GSM_MAP_MAX_NUM_OPR_CODES];
int size[GSM_MAP_MAX_NUM_OPR_CODES];
int opr_code_rr[GSM_MAP_MAX_NUM_OPR_CODES];
int size_rr[GSM_MAP_MAX_NUM_OPR_CODES];
} gsm_map_stat_t;
gsm_map_stat_t gsm_map_stat;
#define SUM_STR_MAX 1024
void register_tap_listener_gtkgsm_map_summary(void);
void register_tap_listener_gtk_gsm_map_summary(void);
static void
add_string_to_box(gchar *str, GtkWidget *box)
@ -347,10 +355,59 @@ void gsm_map_stat_gtk_sum_cb(GtkAction *action _U_, gpointer user_data _U_)
window_present(sum_open_w);
}
static void
gsm_map_summary_reset(void *tapdata)
{
gsm_map_stat_t *stat_p = (gsm_map_stat_t *)tapdata;
memset(stat_p, 0, sizeof(gsm_map_stat_t));
}
static gboolean
gsm_map_summary_packet(
void *tapdata,
packet_info *pinfo _U_,
epan_dissect_t *edt _U_,
const void *data)
{
gsm_map_stat_t *stat_p = (gsm_map_stat_t *)tapdata;
const gsm_map_tap_rec_t *data_p = (const gsm_map_tap_rec_t *)data;
if (data_p->invoke)
{
stat_p->opr_code[data_p->opcode]++;
stat_p->size[data_p->opcode] += data_p->size;
}
else
{
stat_p->opr_code_rr[data_p->opcode]++;
stat_p->size_rr[data_p->opcode] += data_p->size;
}
return(FALSE); /* We have no draw callback */
}
void
register_tap_listener_gtkgsm_map_summary(void)
register_tap_listener_gtk_gsm_map_summary(void)
{
GString *err_p;
memset((void *) &gsm_map_stat, 0, sizeof(gsm_map_stat_t));
err_p =
register_tap_listener("gsm_map", &gsm_map_stat, NULL, 0,
gsm_map_summary_reset,
gsm_map_summary_packet,
NULL);
if (err_p != NULL)
{
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_p->str);
g_string_free(err_p, TRUE);
exit(1);
}
}
/*

View File

@ -1078,7 +1078,6 @@ static const char *ui_desc_menubar =
" <menu name= 'ANSImenu' action='/Telephony/ANSI'>\n"
" </menu>\n"
" <menu name= 'GSM' action='/Telephony/GSM'>\n"
" <menuitem name='MAP-OP' action='/Telephony/GSM/MAP-OP'/>\n"
" <menuitem name='MAP-Summary' action='/Telephony/GSM/MAPSummary'/>\n"
" </menu>\n"
" <menu name= 'IAX2menu' action='/Telephony/IAX2'>\n"
@ -1502,7 +1501,6 @@ static const GtkActionEntry main_menu_bar_entries[] = {
{ "/Telephony/ANSI", NULL, "_ANSI", NULL, NULL, NULL },
{ "/Telephony/GSM", NULL, "_GSM", NULL, NULL, NULL },
{ "/Telephony/GSM/MAP-OP", NULL, "MAP Operation", NULL, NULL, G_CALLBACK(gsm_map_stat_gtk_cb) },
{ "/Telephony/GSM/MAPSummary", NULL, "MAP Summary", NULL, NULL, G_CALLBACK(gsm_map_stat_gtk_sum_cb) },
{ "/Telephony/IAX2", NULL, "IA_X2", NULL, NULL, NULL },

View File

@ -68,6 +68,7 @@ set(WIRESHARK_QT_HEADERS
funnel_string_dialog.h
funnel_text_dialog.h
funnel_statistics.h
gsm_map_summary_dialog.h
import_text_dialog.h
interface_tree.h
io_graph_dialog.h
@ -284,6 +285,7 @@ set(WIRESHARK_QT_TAP_SRC
conversation_dialog.cpp
endpoint_dialog.cpp
funnel_statistics.cpp
gsm_map_summary_dialog.cpp
io_graph_dialog.cpp
stats_tree_dialog.cpp
)
@ -319,6 +321,7 @@ set(WIRESHARK_QT_UI
font_color_preferences_frame.ui
funnel_string_dialog.ui
funnel_text_dialog.ui
gsm_map_summary_dialog.ui
import_text_dialog.ui
io_graph_dialog.ui
layout_preferences_frame.ui

View File

@ -180,6 +180,8 @@ funnel_string_dialog.$(OBJEXT): ui_funnel_string_dialog.h
funnel_text_dialog.$(OBJEXT): ui_funnel_text_dialog.h
gsm_map_summary_dialog.$(OBJEXT): ui_gsm_map_summary_dialog.h
import_text_dialog.$(OBJEXT): ui_import_text_dialog.h
io_graph_dialog.$(OBJEXT): ui_io_graph_dialog.h

View File

@ -181,6 +181,7 @@ MOC_HDRS = \
funnel_string_dialog.h \
funnel_text_dialog.h \
funnel_statistics.h \
gsm_map_summary_dialog.h \
import_text_dialog.h \
interface_tree.h \
io_graph_dialog.h \
@ -418,6 +419,7 @@ WIRESHARK_QT_SRC = \
funnel_string_dialog.cpp \
funnel_text_dialog.cpp \
funnel_statistics.cpp \
gsm_map_summary_dialog.cpp \
import_text_dialog.cpp \
interface_tree.cpp \
io_graph_dialog.cpp \

View File

@ -231,6 +231,7 @@ FORMS += \
font_color_preferences_frame.ui \
funnel_string_dialog.ui \
funnel_text_dialog.ui \
gsm_map_summary_dialog.ui \
import_text_dialog.ui \
io_graph_dialog.ui \
layout_preferences_frame.ui \
@ -311,6 +312,7 @@ HEADERS += $$HEADERS_WS_C \
funnel_string_dialog.h \
funnel_text_dialog.h \
funnel_statistics.h \
gsm_map_summary_dialog.h \
layout_preferences_frame.h \
lbm_lbtrm_transport_dialog.h \
lbm_lbtru_transport_dialog.h \
@ -685,6 +687,7 @@ SOURCES += \
funnel_string_dialog.cpp \
funnel_text_dialog.cpp \
funnel_statistics.cpp \
gsm_map_summary_dialog.cpp \
import_text_dialog.cpp \
interface_tree.cpp \
io_graph_dialog.cpp \

View File

@ -32,7 +32,6 @@
#include "qt_ui_utils.h"
#include "wireshark_application.h"
#include <QDateTime>
#include <QPushButton>
#include <QTextStream>
@ -103,13 +102,6 @@ void CaptureFilePropertiesDialog::updateWidgets()
ui->commentsTextEdit->setText(cf_read_shb_comment(cap_file_.capFile()));
}
QString CaptureFilePropertiesDialog::timeToString(time_t ti_time)
{
QDateTime date_time = QDateTime::fromTime_t(ti_time);
QString time_str = date_time.toLocalTime().toString("yyyy-MM-dd hh:mm:ss");
return time_str;
}
QString CaptureFilePropertiesDialog::summaryToHtml()
{
summary_tally summary;
@ -189,6 +181,13 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
<< table_data_tmpl.arg(encaps_str)
<< table_row_end;
if (summary.has_snap) {
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Snapshot length"))
<< table_data_tmpl.arg(summary.snap)
<< table_row_end;
}
out << table_end;
// Time Section
@ -201,13 +200,13 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
// start time
out << table_row_begin
<< table_vheader_tmpl.arg(tr("First packet"))
<< table_data_tmpl.arg(timeToString((time_t)summary.start_time))
<< table_data_tmpl.arg(time_t_to_qstring((time_t)summary.start_time))
<< table_row_end;
// stop time
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Last packet"))
<< table_data_tmpl.arg(timeToString((time_t)summary.stop_time))
<< table_data_tmpl.arg(time_t_to_qstring((time_t)summary.stop_time))
<< table_row_end;
// elapsed seconds (capture duration)

View File

@ -69,7 +69,6 @@ protected slots:
private:
Ui::CaptureFilePropertiesDialog *ui;
QString timeToString(time_t ti_time);
QString summaryToHtml();
private slots:

View File

@ -0,0 +1,408 @@
/* gsm_map_summary_dialog.cpp
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* 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 "gsm_map_summary_dialog.h"
#include "ui_gsm_map_summary_dialog.h"
#include "config.h"
#include <glib.h>
#include "globals.h"
#include "summary.h"
#include <epan/packet.h>
#include <epan/tap.h>
#include <epan/asn1.h>
#include <epan/dissectors/packet-gsm_map.h>
#include "ui/capture_globals.h"
#include "ui/simple_dialog.h"
#include "qt_ui_utils.h"
#include "wireshark_application.h"
#include <QTextStream>
/** Gsm map statistic data */
typedef struct _gsm_map_stat_t {
int opr_code[GSM_MAP_MAX_NUM_OPR_CODES];
int size[GSM_MAP_MAX_NUM_OPR_CODES];
int opr_code_rr[GSM_MAP_MAX_NUM_OPR_CODES];
int size_rr[GSM_MAP_MAX_NUM_OPR_CODES];
} gsm_map_stat_t;
gsm_map_stat_t gsm_map_stat;
void register_tap_listener_qt_gsm_map_summary(void);
GsmMapSummaryDialog::GsmMapSummaryDialog(QWidget &parent, CaptureFile &capture_file) :
WiresharkDialog(parent, capture_file),
ui(new Ui::GsmMapSummaryDialog)
{
ui->setupUi(this);
setWindowSubtitle(tr("GSM MAP Summary"));
updateWidgets();
}
GsmMapSummaryDialog::~GsmMapSummaryDialog()
{
delete ui;
}
// Copied from capture_file_properties_dialog.cpp
QString GsmMapSummaryDialog::summaryToHtml()
{
summary_tally summary;
memset(&summary, 0, sizeof(summary_tally));
QString section_tmpl;
QString table_begin, table_end;
QString table_row_begin, table_ul_row_begin, table_row_end;
QString table_vheader_tmpl, table_hheader20_tmpl, table_hheader25_tmpl;
QString table_data_tmpl;
section_tmpl = "<p><strong>%1</strong></p>\n";
table_begin = "<p><table>\n";
table_end = "</table></p>\n";
table_row_begin = "<tr>\n";
table_ul_row_begin = "<tr style=\"border-bottom: 1px solid gray;\">\n";
table_row_end = "</tr>\n";
table_vheader_tmpl = "<td width=\"50%\">%1:</td>"; // <th align="left"> looked odd
table_hheader20_tmpl = "<td width=\"20%\"><u>%1</u></td>";
table_hheader25_tmpl = "<td width=\"25%\"><u>%1</u></td>";
table_data_tmpl = "<td>%1</td>";
if (!file_closed_) {
/* initial computations */
summary_fill_in(cap_file_.capFile(), &summary);
#ifdef HAVE_LIBPCAP
summary_fill_in_capture(cap_file_.capFile(), &global_capture_opts, &summary);
#endif
}
QString summary_str;
QTextStream out(&summary_str);
// File Section
out << section_tmpl.arg(tr("File"));
out << table_begin;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Name"))
<< table_data_tmpl.arg(summary.filename)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Length"))
<< table_data_tmpl.arg(file_size_to_qstring(summary.file_length))
<< table_row_end;
QString format_str = wtap_file_type_subtype_string(summary.file_type);
if (summary.iscompressed) {
format_str.append(tr(" (gzip compressed)"));
}
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Format"))
<< table_data_tmpl.arg(format_str)
<< table_row_end;
if (summary.has_snap) {
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Snapshot length"))
<< table_data_tmpl.arg(summary.snap)
<< table_row_end;
}
out << table_end;
// Data Section
out << section_tmpl.arg(tr("Data"));
out << table_begin;
if (summary.packet_count_ts == summary.packet_count &&
summary.packet_count >= 1)
{
// start time
out << table_row_begin
<< table_vheader_tmpl.arg(tr("First packet"))
<< table_data_tmpl.arg(time_t_to_qstring((time_t)summary.start_time))
<< table_row_end;
// stop time
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Last packet"))
<< table_data_tmpl.arg(time_t_to_qstring((time_t)summary.stop_time))
<< table_row_end;
// elapsed seconds (capture duration)
if (summary.packet_count_ts > 1)
{
/* elapsed seconds */
QString elapsed_str;
unsigned int elapsed_time = (unsigned int)summary.elapsed_time;
if (elapsed_time/86400)
{
elapsed_str = QString("%1 days ").arg(elapsed_time / 86400);
}
elapsed_str += QString("%1:%2:%3")
.arg(elapsed_time % 86400 / 3600, 2, 10, QChar('0'))
.arg(elapsed_time % 3600 / 60, 2, 10, QChar('0'))
.arg(elapsed_time % 60, 2, 10, QChar('0'));
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Elapsed"))
<< table_data_tmpl.arg(elapsed_str)
<< table_row_end;
}
}
// count
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Packets"))
<< table_data_tmpl.arg(summary.packet_count)
<< table_row_end;
out << table_end;
// TRANSLATOR Abbreviation for "not applicable"
QString n_a = tr("N/A");
QString invoke_rate_str, result_rate_str, total_rate_str;
QString invoke_avg_size_str, result_avg_size_str, total_avg_size_str;
// Message averages
invoke_rate_str = result_rate_str = total_rate_str = n_a;
invoke_avg_size_str = result_avg_size_str = total_avg_size_str = n_a;
double seconds = summary.stop_time - summary.start_time;
int invoke_count = 0, invoke_bytes = 0;
int result_count = 0, result_bytes = 0;
for (int i = 0; i < GSM_MAP_MAX_NUM_OPR_CODES; i++) {
invoke_count += gsm_map_stat.opr_code[i];
invoke_bytes += gsm_map_stat.size[i];
}
for (int i = 0; i < GSM_MAP_MAX_NUM_OPR_CODES; i++) {
result_count += gsm_map_stat.opr_code_rr[i];
result_bytes += gsm_map_stat.size_rr[i];
}
int total_count = invoke_count + result_count;
int total_bytes = invoke_bytes + result_bytes;
/*
* We must have no un-time-stamped packets (i.e., the number of
* time-stamped packets must be the same as the number of packets),
* and at least two time-stamped packets, in order for the elapsed
* time to be valid.
*/
if (summary.packet_count_ts > 1 && seconds > 0.0) {
/* Total number of invokes per second */
invoke_rate_str = QString("%1").arg(invoke_count / seconds, 1, 'f', 1);
result_rate_str = QString("%1").arg(result_count / seconds, 1, 'f', 1);
total_rate_str = QString("%1").arg((total_count) / seconds, 1, 'f', 1);
}
/* Average message sizes */
if (invoke_count > 0) {
invoke_avg_size_str = QString("%1").arg((double) invoke_bytes / invoke_count, 1, 'f', 1);
}
if (result_count > 0) {
result_avg_size_str = QString("%1").arg((double) result_bytes / result_count, 1, 'f', 1);
}
if (total_count > 0) {
total_avg_size_str = QString("%1").arg((double) total_bytes / total_count, 1, 'f', 1);
}
// Invoke Section
out << section_tmpl.arg(tr("Invokes"));
out << table_begin;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Total number of Invokes"))
<< table_data_tmpl.arg(invoke_count)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Average number of Invokes per second"))
<< table_data_tmpl.arg(invoke_rate_str)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Total number of bytes for Invokes"))
<< table_data_tmpl.arg(invoke_bytes)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Average number of bytes per Invoke"))
<< table_data_tmpl.arg(invoke_avg_size_str)
<< table_row_end;
out << table_end;
// Return Result Section
out << section_tmpl.arg(tr("Return Results"));
out << table_begin;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Total number of Return Results"))
<< table_data_tmpl.arg(result_count)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Average number of Return Results per second"))
<< table_data_tmpl.arg(result_rate_str)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Total number of bytes for Return Results"))
<< table_data_tmpl.arg(result_bytes)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Average number of bytes per Return Result"))
<< table_data_tmpl.arg(result_avg_size_str)
<< table_row_end;
out << table_end;
// Total Section
out << section_tmpl.arg(tr("Totals"));
out << table_begin;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Total number of GSM MAP messages"))
<< table_data_tmpl.arg(total_count)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Average number of GSM MAP messages per second"))
<< table_data_tmpl.arg(total_rate_str)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Total number of bytes for GSM MAP messages"))
<< table_data_tmpl.arg(total_bytes)
<< table_row_end;
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Average number of bytes per GSM MAP message"))
<< table_data_tmpl.arg(total_avg_size_str)
<< table_row_end;
out << table_end;
return summary_str;
}
void GsmMapSummaryDialog::updateWidgets()
{
// QPushButton *refresh_bt = ui->buttonBox->button(QDialogButtonBox::Reset);
// QPushButton *save_bt = ui->buttonBox->button(QDialogButtonBox::Save);
// if (file_closed_) {
// if (refresh_bt) {
// refresh_bt->setEnabled(false);
// }
// ui->commentsTextEdit->setReadOnly(true);
// if (save_bt) {
// save_bt->setEnabled(false);
// }
// return;
// }
ui->summaryTextEdit->setHtml(summaryToHtml());
}
extern "C" {
static void
gsm_map_summary_reset(void *tapdata)
{
gsm_map_stat_t *gm_stat = (gsm_map_stat_t *)tapdata;
memset(gm_stat, 0, sizeof(gsm_map_stat_t));
}
static gboolean
gsm_map_summary_packet(void *tapdata, packet_info *, epan_dissect_t *, const void *gmtr_ptr)
{
gsm_map_stat_t *gm_stat = (gsm_map_stat_t *)tapdata;
const gsm_map_tap_rec_t *gm_tap_rec = (const gsm_map_tap_rec_t *)gmtr_ptr;
if (gm_tap_rec->invoke)
{
gm_stat->opr_code[gm_tap_rec->opcode]++;
gm_stat->size[gm_tap_rec->opcode] += gm_tap_rec->size;
}
else
{
gm_stat->opr_code_rr[gm_tap_rec->opcode]++;
gm_stat->size_rr[gm_tap_rec->opcode] += gm_tap_rec->size;
}
return(FALSE); /* We have no draw callback */
}
void
register_tap_listener_gtk_gsm_map_summary(void)
{
GString *err_p;
memset((void *) &gsm_map_stat, 0, sizeof(gsm_map_stat_t));
err_p =
register_tap_listener("gsm_map", &gsm_map_stat, NULL, 0,
gsm_map_summary_reset,
gsm_map_summary_packet,
NULL);
if (err_p != NULL)
{
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_p->str);
g_string_free(err_p, TRUE);
exit(1);
}
}
} // extern "C"
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -1,7 +1,8 @@
/* gsm_map_stat.h
/* gsm_map_summary_dialog.h
*
* Copyright 2004, 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
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
@ -22,23 +23,44 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __GSM_MAP_STAT_H__
#define __GSM_MAP_STAT_H__
#ifndef GSM_MAP_SUMMARY_DIALOG_H
#define GSM_MAP_SUMMARY_DIALOG_H
/** @file
* Statistics for GSM MAP Operations.
#include "wireshark_dialog.h"
namespace Ui {
class GsmMapSummaryDialog;
}
class GsmMapSummaryDialog : public WiresharkDialog
{
Q_OBJECT
public:
explicit GsmMapSummaryDialog(QWidget &parent, CaptureFile& capture_file);
~GsmMapSummaryDialog();
private:
Ui::GsmMapSummaryDialog *ui;
QString summaryToHtml();
private slots:
void updateWidgets();
};
#endif // GSM_MAP_SUMMARY_DIALOG_H
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/
/** Gsm map statistic data */
typedef struct _gsm_map_stat_t {
int opr_code[GSM_MAP_MAX_NUM_OPR_CODES];
int size[GSM_MAP_MAX_NUM_OPR_CODES];
int opr_code_rr[GSM_MAP_MAX_NUM_OPR_CODES];
int size_rr[GSM_MAP_MAX_NUM_OPR_CODES];
} gsm_map_stat_t;
/** Global gsm map statistic data */
extern gsm_map_stat_t gsm_map_stat;
#endif /* __GSM_MAP_STAT_H__ */

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GsmMapSummaryDialog</class>
<widget class="QDialog" name="GsmMapSummaryDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>540</width>
<height>420</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextEdit" name="summaryTextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GsmMapSummaryDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GsmMapSummaryDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1966,6 +1966,10 @@ void MainWindow::setForCaptureInProgress(gboolean capture_in_progress)
void MainWindow::addDynamicMenus()
{
// Manual additions
wsApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY_GSM, main_ui_->actionTelephonyGsmMapSummary);
// Fill in each menu
QList<register_stat_group_t> menu_groups = QList<register_stat_group_t>()
<< REGISTER_ANALYZE_GROUP_UNSORTED
<< REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER

View File

@ -512,6 +512,7 @@ private slots:
void openVoipCallsDialog(bool all_flows = false);
void on_actionTelephonyVoipCalls_triggered();
void on_actionTelephonyGsmMapSummary_triggered();
void on_actionTelephonyISUPMessages_triggered();
void on_actionTelephonyRTPStreams_triggered();
void on_actionTelephonyRTPStreamAnalysis_triggered();

View File

@ -2333,6 +2333,14 @@
<string>Copy packet bytes as application/octet-stream MIME data.</string>
</property>
</action>
<action name="actionTelephonyGsmMapSummary">
<property name="text">
<string>MAP Summary</string>
</property>
<property name="toolTip">
<string>GSM MAP summary statistics</string>
</property>
</action>
<action name="actionTelephonyVoipCalls">
<property name="text">
<string>&amp;VoIP Calls</string>

View File

@ -94,6 +94,7 @@
#include "extcap_options_dialog.h"
#endif
#include "filter_dialog.h"
#include "gsm_map_summary_dialog.h"
#include "io_graph_dialog.h"
#include "lbm_stream_dialog.h"
#include "lbm_uimflow_dialog.h"
@ -2858,6 +2859,12 @@ void MainWindow::on_actionTelephonyVoipCalls_triggered()
openVoipCallsDialog();
}
void MainWindow::on_actionTelephonyGsmMapSummary_triggered()
{
GsmMapSummaryDialog *gms_dialog = new GsmMapSummaryDialog(*this, capture_file_);
gms_dialog->show();
}
void MainWindow::on_actionTelephonyISUPMessages_triggered()
{
openStatisticsTreeDialog("isup_msg");

View File

@ -36,6 +36,7 @@
#include <wsutil/str_util.h>
#include <QAction>
#include <QDateTime>
#include <QFontDatabase>
/* Make the format_size_flags_e enum usable in C++ */
@ -155,6 +156,13 @@ const QString file_size_to_qstring(const gint64 size)
format_size(size, format_size_unit_bytes|format_size_prefix_si));
}
const QString time_t_to_qstring(time_t ti_time)
{
QDateTime date_time = QDateTime::fromTime_t(ti_time);
QString time_str = date_time.toLocalTime().toString("yyyy-MM-dd hh:mm:ss");
return time_str;
}
void smooth_font_size(QFont &font) {
QFontDatabase fdb;
#if QT_VERSION < QT_VERSION_CHECK(4, 8, 0)

View File

@ -153,6 +153,14 @@ const QString bits_s_to_qstring(const double bits_s);
*/
const QString file_size_to_qstring(const gint64 size);
/** Convert a time_t value to a human-readable QString using QDateTime.
*
* @param ti_time The value to convert.
*
* @return A QString representation of the file size in SI units.
*/
const QString time_t_to_qstring(time_t ti_time);
/**
* Round the current size of a font up to its next "smooth" size.
* If a smooth size can't be found the font is left unchanged.