diff options
-rw-r--r-- | asn1/gsm_map/packet-gsm_map-template.c | 160 | ||||
-rw-r--r-- | asn1/gsm_map/packet-gsm_map-template.h | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_map.c | 176 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_map.h | 2 | ||||
-rw-r--r-- | ui/gtk/CMakeLists.txt | 1 | ||||
-rw-r--r-- | ui/gtk/Makefile.common | 2 | ||||
-rw-r--r-- | ui/gtk/gsm_map_stat.c | 494 | ||||
-rw-r--r-- | ui/gtk/gsm_map_summary.c | 75 | ||||
-rw-r--r-- | ui/gtk/main_menubar.c | 2 | ||||
-rw-r--r-- | ui/qt/CMakeLists.txt | 3 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 2 | ||||
-rw-r--r-- | ui/qt/Wireshark.pro | 3 | ||||
-rw-r--r-- | ui/qt/capture_file_properties_dialog.cpp | 19 | ||||
-rw-r--r-- | ui/qt/capture_file_properties_dialog.h | 1 | ||||
-rw-r--r-- | ui/qt/gsm_map_summary_dialog.cpp | 408 | ||||
-rw-r--r-- | ui/qt/gsm_map_summary_dialog.h (renamed from ui/gtk/gsm_map_stat.h) | 58 | ||||
-rw-r--r-- | ui/qt/gsm_map_summary_dialog.ui | 71 | ||||
-rw-r--r-- | ui/qt/main_window.cpp | 4 | ||||
-rw-r--r-- | ui/qt/main_window.h | 1 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 8 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 7 | ||||
-rw-r--r-- | ui/qt/qt_ui_utils.cpp | 8 | ||||
-rw-r--r-- | ui/qt/qt_ui_utils.h | 8 |
24 files changed, 966 insertions, 551 deletions
diff --git a/asn1/gsm_map/packet-gsm_map-template.c b/asn1/gsm_map/packet-gsm_map-template.c index 1bdeb7f9e3..54ba888c47 100644 --- a/asn1/gsm_map/packet-gsm_map-template.c +++ b/asn1/gsm_map/packet-gsm_map-template.c @@ -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); } diff --git a/asn1/gsm_map/packet-gsm_map-template.h b/asn1/gsm_map/packet-gsm_map-template.h index 9f7ccd1324..3b1386ea69 100644 --- a/asn1/gsm_map/packet-gsm_map-template.h +++ b/asn1/gsm_map/packet-gsm_map-template.h @@ -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; diff --git a/epan/dissectors/packet-gsm_map.c b/epan/dissectors/packet-gsm_map.c index 9735f47d71..366d95a01f 100644 --- a/epan/dissectors/packet-gsm_map.c +++ b/epan/dissectors/packet-gsm_map.c @@ -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); } diff --git a/epan/dissectors/packet-gsm_map.h b/epan/dissectors/packet-gsm_map.h index 3c42c19876..081be0a989 100644 --- a/epan/dissectors/packet-gsm_map.h +++ b/epan/dissectors/packet-gsm_map.h @@ -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; diff --git a/ui/gtk/CMakeLists.txt b/ui/gtk/CMakeLists.txt index 29952eafc3..fa0a7a9019 100644 --- a/ui/gtk/CMakeLists.txt +++ b/ui/gtk/CMakeLists.txt @@ -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 diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common index 9245cca297..143a6e1b78 100644 --- a/ui/gtk/Makefile.common +++ b/ui/gtk/Makefile.common @@ -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 \ diff --git a/ui/gtk/gsm_map_stat.c b/ui/gtk/gsm_map_stat.c deleted file mode 100644 index af5102e033..0000000000 --- a/ui/gtk/gsm_map_stat.c +++ /dev/null @@ -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: - */ diff --git a/ui/gtk/gsm_map_summary.c b/ui/gtk/gsm_map_summary.c index 13d79a4ba1..6aa693a34c 100644 --- a/ui/gtk/gsm_map_summary.c +++ b/ui/gtk/gsm_map_summary.c @@ -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); + } } /* diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c index d3fa216093..ad916efa5f 100644 --- a/ui/gtk/main_menubar.c +++ b/ui/gtk/main_menubar.c @@ -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 }, diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index bda0bd541b..8d4bd77c0a 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -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 diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index a6d1021d75..7da36f93b5 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -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 diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common index ed7140f552..731148b1a9 100644 --- a/ui/qt/Makefile.common +++ b/ui/qt/Makefile.common @@ -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 \ diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro index eba443cd5a..1a899cff80 100644 --- a/ui/qt/Wireshark.pro +++ b/ui/qt/Wireshark.pro @@ -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 \ diff --git a/ui/qt/capture_file_properties_dialog.cpp b/ui/qt/capture_file_properties_dialog.cpp index 6cd62539f3..1cb3d4741c 100644 --- a/ui/qt/capture_file_properties_dialog.cpp +++ b/ui/qt/capture_file_properties_dialog.cpp @@ -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) diff --git a/ui/qt/capture_file_properties_dialog.h b/ui/qt/capture_file_properties_dialog.h index 0581a80686..d4159ff576 100644 --- a/ui/qt/capture_file_properties_dialog.h +++ b/ui/qt/capture_file_properties_dialog.h @@ -69,7 +69,6 @@ protected slots: private: Ui::CaptureFilePropertiesDialog *ui; - QString timeToString(time_t ti_time); QString summaryToHtml(); private slots: diff --git a/ui/qt/gsm_map_summary_dialog.cpp b/ui/qt/gsm_map_summary_dialog.cpp new file mode 100644 index 0000000000..dbb0a83781 --- /dev/null +++ b/ui/qt/gsm_map_summary_dialog.cpp @@ -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: + */ diff --git a/ui/gtk/gsm_map_stat.h b/ui/qt/gsm_map_summary_dialog.h index cc7fda9f65..0fc2a3c8ca 100644 --- a/ui/gtk/gsm_map_stat.h +++ b/ui/qt/gsm_map_summary_dialog.h @@ -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 -/** 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]; +public: + explicit GsmMapSummaryDialog(QWidget &parent, CaptureFile& capture_file); + ~GsmMapSummaryDialog(); - int opr_code_rr[GSM_MAP_MAX_NUM_OPR_CODES]; - int size_rr[GSM_MAP_MAX_NUM_OPR_CODES]; -} gsm_map_stat_t; +private: + Ui::GsmMapSummaryDialog *ui; -/** Global gsm map statistic data */ -extern gsm_map_stat_t gsm_map_stat; + QString summaryToHtml(); -#endif /* __GSM_MAP_STAT_H__ */ +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: + */ diff --git a/ui/qt/gsm_map_summary_dialog.ui b/ui/qt/gsm_map_summary_dialog.ui new file mode 100644 index 0000000000..925db6c943 --- /dev/null +++ b/ui/qt/gsm_map_summary_dialog.ui @@ -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> diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp index 9bcf2b95d7..96c3be0564 100644 --- a/ui/qt/main_window.cpp +++ b/ui/qt/main_window.cpp @@ -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 diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index 92b46c144e..c61bc66500 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -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(); diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index 0eb120af46..dda94a9e5e 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -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>&VoIP Calls</string> diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 50866ec1c9..4f8ab8a437 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -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"); diff --git a/ui/qt/qt_ui_utils.cpp b/ui/qt/qt_ui_utils.cpp index 4ad8ead236..aae0581268 100644 --- a/ui/qt/qt_ui_utils.cpp +++ b/ui/qt/qt_ui_utils.cpp @@ -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) diff --git a/ui/qt/qt_ui_utils.h b/ui/qt/qt_ui_utils.h index a5c80e297f..531018eb41 100644 --- a/ui/qt/qt_ui_utils.h +++ b/ui/qt/qt_ui_utils.h @@ -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. |