Refactor RTD stats.

Very similar to the refactoring of SRT stats, it provides more commonality of the stats for all GUI interfaces.  Currently implemented for TShark and GTK.  Affected dissectors: MEGACO, MGCP, Radius

Change-Id: Icb73a7e603dc3502b39bf696227fcaae37d4ed21
Reviewed-on: https://code.wireshark.org/review/8998
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Michael Mann 2015-06-20 12:22:22 -04:00 committed by Anders Broman
parent 8b230eabdd
commit 8f390d4975
27 changed files with 1463 additions and 1955 deletions

View File

@ -1160,13 +1160,11 @@ set(TSHARK_TAP_SRC
ui/cli/tap-iostat.c
ui/cli/tap-iousers.c
ui/cli/tap-macltestat.c
ui/cli/tap-mgcpstat.c
ui/cli/tap-megacostat.c
ui/cli/tap-protocolinfo.c
ui/cli/tap-protohierstat.c
ui/cli/tap-radiusstat.c
ui/cli/tap-rlcltestat.c
ui/cli/tap-rpcprogs.c
ui/cli/tap-rtd.c
ui/cli/tap-rtp.c
ui/cli/tap-rtspstat.c
ui/cli/tap-sctpchunkstat.c

View File

@ -1629,6 +1629,7 @@ set(LIBWIRESHARK_FILES
reassemble.c
reedsolomon.c
req_resp_hdrs.c
rtd_table.c
show_exception.c
sminmpec.c
srt_table.c

View File

@ -79,6 +79,7 @@ LIBWIRESHARK_SRC = \
reassemble.c \
reedsolomon.c \
req_resp_hdrs.c \
rtd_table.c \
show_exception.c \
sminmpec.c \
srt_table.c \
@ -232,6 +233,7 @@ LIBWIRESHARK_INCLUDES = \
reassemble.h \
reedsolomon.h \
req_resp_hdrs.h \
rtd_table.h \
rtp_pt.h \
sctpppids.h \
show_exception.h \

View File

@ -46,6 +46,8 @@
#include <epan/exceptions.h>
#include <epan/gcp.h>
#include <epan/tap.h>
#include <epan/rtd_table.h>
#include <epan/prefs-int.h>
#include "packet-tpkt.h"
#include "packet-h245.h"
#include "packet-ip.h"
@ -201,6 +203,215 @@ static const value_string megaco_context_vals[] = {
static gint megaco_tvb_skip_wsp(tvbuff_t *tvb, gint offset);
static gint megaco_tvb_skip_wsp_return(tvbuff_t *tvb, gint offset);
#define NUM_TIMESTATS 12
static const value_string megaco_message_type[] = {
{ 0, "ADD "},
{ 1, "MOVE"},
{ 2, "MDFY"},
{ 3, "SUBT"},
{ 4, "AUCP"},
{ 5, "AUVL"},
{ 6, "NTFY"},
{ 7, "SVCC"},
{ 8, "TOPO"},
{ 9, "NONE"},
{ 10, "ALL "},
{ 0, NULL}
};
#define GCP_CMD_REPLY_CASE \
case GCP_CMD_ADD_REPLY: \
case GCP_CMD_MOVE_REPLY: \
case GCP_CMD_MOD_REPLY: \
case GCP_CMD_SUB_REPLY: \
case GCP_CMD_AUDITCAP_REPLY: \
case GCP_CMD_AUDITVAL_REPLY: \
case GCP_CMD_NOTIFY_REPLY: \
case GCP_CMD_SVCCHG_REPLY: \
case GCP_CMD_TOPOLOGY_REPLY: \
case GCP_CMD_REPLY:
#define GCP_CMD_REQ_CASE \
case GCP_CMD_ADD_REQ: \
case GCP_CMD_MOVE_REQ: \
case GCP_CMD_MOD_REQ: \
case GCP_CMD_SUB_REQ: \
case GCP_CMD_AUDITCAP_REQ: \
case GCP_CMD_AUDITVAL_REQ: \
case GCP_CMD_NOTIFY_REQ: \
case GCP_CMD_SVCCHG_REQ: \
case GCP_CMD_TOPOLOGY_REQ: \
case GCP_CMD_CTX_ATTR_AUDIT_REQ: \
case GCP_CMD_OTHER_REQ:
static gboolean
megacostat_is_duplicate_reply(const gcp_cmd_t* cmd)
{
switch (cmd->type) {
GCP_CMD_REPLY_CASE
{
gcp_cmd_msg_t *cmd_msg;
/* cycle through commands to find same command in the transaction */
for (cmd_msg = cmd->trx->cmds;
(cmd_msg != NULL) && (cmd_msg->cmd->msg->framenum != cmd->msg->framenum);
cmd_msg = cmd_msg->next) {
if (cmd_msg->cmd->type == cmd->type)
return TRUE;
}
return FALSE;
}
break;
default:
return FALSE;
break;
}
}
static gboolean
megacostat_had_request(const gcp_cmd_t* cmd)
{
switch (cmd->type) {
GCP_CMD_REPLY_CASE
{
gcp_cmd_msg_t *cmd_msg;
/* cycle through commands to find a request in the transaction */
for (cmd_msg = cmd->trx->cmds;
(cmd_msg != NULL) && (cmd_msg->cmd->msg->framenum != cmd->msg->framenum);
cmd_msg = cmd_msg->next) {
switch (cmd_msg->cmd->type) {
GCP_CMD_REQ_CASE
return TRUE;
break;
default:
return FALSE;
break;
}
}
return FALSE;
}
break;
default:
return FALSE;
break;
}
}
static void
megacostat_filtercheck(const char *opt_arg _U_, const char **filter _U_, char** err)
{
pref_t *megaco_ctx_track, *h248_ctx_track;
megaco_ctx_track = prefs_find_preference(prefs_find_module("megaco"), "ctx_info");
h248_ctx_track = prefs_find_preference(prefs_find_module("h248"), "ctx_info");
if (!megaco_ctx_track || !h248_ctx_track) {
/* No such preferences */
return;
}
if (!*megaco_ctx_track->varp.boolp || !*h248_ctx_track->varp.boolp) {
*err = g_strdup_printf("Track Context option at Protocols -> MEGACO and Protocols -> H248 preferences\n"
"has to be set to true to enable measurement of service response times.\n");
}
}
static int
megacostat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pmi)
{
rtd_data_t* rtd_data = (rtd_data_t*)pms;
rtd_stat_table* ms = &rtd_data->stat_table;
const gcp_cmd_t *mi=(const gcp_cmd_t*)pmi;
nstime_t delta;
int ret = 0;
switch (mi->type) {
GCP_CMD_REQ_CASE
if(!mi->trx->initial) {
/* Track Context is probably disabled, we cannot
* measure service response time */
return 0;
}
else if(mi->trx->initial->framenum != mi->msg->framenum){
/* Duplicate is ignored */
ms->time_stats[0].req_dup_num++;
}
else {
ms->time_stats[0].open_req_num++;
}
break;
GCP_CMD_REPLY_CASE
if(megacostat_is_duplicate_reply(mi)){
/* Duplicate is ignored */
ms->time_stats[0].rsp_dup_num++;
}
else if (!megacostat_had_request(mi)) {
/* no request was seen */
ms->time_stats[0].disc_rsp_num++;
}
else {
ms->time_stats[0].open_req_num--;
/* calculate time delta between request and response */
nstime_delta(&delta, &pinfo->fd->abs_ts, &mi->trx->initial->time);
switch(mi->type) {
case GCP_CMD_ADD_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[0]),&delta, pinfo);
break;
case GCP_CMD_MOVE_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[1]),&delta, pinfo);
break;
case GCP_CMD_MOD_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[2]),&delta, pinfo);
break;
case GCP_CMD_SUB_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[3]),&delta, pinfo);
break;
case GCP_CMD_AUDITCAP_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[4]),&delta, pinfo);
break;
case GCP_CMD_AUDITVAL_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[5]),&delta, pinfo);
break;
case GCP_CMD_NOTIFY_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[6]),&delta, pinfo);
break;
case GCP_CMD_SVCCHG_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[7]),&delta, pinfo);
break;
case GCP_CMD_TOPOLOGY_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[8]),&delta, pinfo);
break;
case GCP_CMD_REPLY:
time_stat_update(&(ms->time_stats[0].rtd[9]),&delta, pinfo);
break;
default:
time_stat_update(&(ms->time_stats[0].rtd[11]),&delta, pinfo);
}
time_stat_update(&(ms->time_stats[0].rtd[10]),&delta, pinfo);
ret = 1;
}
break;
default:
break;
}
return ret;
}
/*
* The various functions that either dissect some
* subpart of MEGACO. These aren't really proto dissectors but they
@ -3575,6 +3786,7 @@ proto_register_megaco(void)
ws_mempbrk_compile(&pbrk_whitespace, " \t\r\n");
ws_mempbrk_compile(&pbrk_braces, "{}");
register_rtd_table(proto_megaco, NULL, 1, NUM_TIMESTATS, megaco_message_type, megacostat_packet, megacostat_filtercheck);
}
/* Register all the bits needed with the filtering engine */

View File

@ -42,6 +42,7 @@
#include <epan/prefs.h>
#include <epan/conversation.h>
#include <epan/tap.h>
#include <epan/rtd_table.h>
#include "packet-mgcp.h"
@ -279,6 +280,102 @@ static void dissect_mgcp_localconnectionoptions(proto_tree *parent_tree, tvbuff_
static void mgcp_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
#define NUM_TIMESTATS 11
static const value_string mgcp_mesage_type[] = {
{ 0, "Overall"},
{ 1, "EPCF "},
{ 2, "CRCX "},
{ 3, "MDCX "},
{ 4, "DLCX "},
{ 5, "RQNT "},
{ 6, "NTFY "},
{ 7, "AUEP "},
{ 8, "AUCX "},
{ 9, "RSIP "},
{ 0, NULL}
};
static int
mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pmi)
{
rtd_data_t* rtd_data = (rtd_data_t*)pms;
rtd_stat_table* ms = &rtd_data->stat_table;
const mgcp_info_t *mi = (const mgcp_info_t *)pmi;
nstime_t delta;
int ret = 0;
switch (mi->mgcp_type) {
case MGCP_REQUEST:
if (mi->is_duplicate) {
/* Duplicate is ignored */
ms->time_stats[0].req_dup_num++;
}
else {
ms->time_stats[0].open_req_num++;
}
break;
case MGCP_RESPONSE:
if (mi->is_duplicate) {
/* Duplicate is ignored */
ms->time_stats[0].rsp_dup_num++;
}
else if (!mi->request_available) {
/* no request was seen */
ms->time_stats[0].disc_rsp_num++;
}
else {
ms->time_stats[0].open_req_num--;
/* calculate time delta between request and response */
nstime_delta(&delta, &pinfo->fd->abs_ts, &mi->req_time);
time_stat_update(&(ms->time_stats[0].rtd[0]), &delta, pinfo);
if (g_ascii_strncasecmp(mi->code, "EPCF", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[1]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "CRCX", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[2]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "MDCX", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[3]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "DLCX", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[4]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "RQNT", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[5]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "NTFY", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[6]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "AUEP", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[7]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "AUCX", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[8]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "RSIP", 4) == 0 ) {
time_stat_update(&(ms->time_stats[0].rtd[9]), &delta, pinfo);
}
else {
time_stat_update(&(ms->time_stats[0].rtd[10]), &delta, pinfo);
}
ret = 1;
}
break;
default:
break;
}
return ret;
}
/*
* Some functions which should be moved to a library
* as I think that people may find them of general usefulness.
@ -2258,6 +2355,8 @@ void proto_register_mgcp(void)
&global_mgcp_message_count);
mgcp_tap = register_tap("mgcp");
register_rtd_table(proto_mgcp, NULL, 1, NUM_TIMESTATS, mgcp_mesage_type, mgcpstat_packet, NULL);
}
/* The registration hand-off routine */

View File

@ -63,6 +63,7 @@
#include <epan/sminmpec.h>
#include <epan/conversation.h>
#include <epan/tap.h>
#include <epan/rtd_table.h>
#include <epan/addr_resolv.h>
#include <wsutil/filesystem.h>
#include <wsutil/report_err.h>
@ -212,6 +213,150 @@ static const value_string radius_pkt_type_codes[] =
};
static value_string_ext radius_pkt_type_codes_ext = VALUE_STRING_EXT_INIT(radius_pkt_type_codes);
typedef enum _radius_category {
RADIUS_CAT_OVERALL = 0,
RADIUS_CAT_ACCESS,
RADIUS_CAT_ACCOUNTING,
RADIUS_CAT_PASSWORD,
RADIUS_CAT_RESOURCE_FREE,
RADIUS_CAT_RESOURCE_QUERY,
RADIUS_CAT_NAS_REBOOT,
RADIUS_CAT_EVENT,
RADIUS_CAT_DISCONNECT,
RADIUS_CAT_COA,
RADIUS_CAT_OTHERS,
RADIUS_CAT_NUM_TIMESTATS
} radius_category;
static const value_string radius_message_code[] = {
{ RADIUS_CAT_OVERALL, "Overall"},
{ RADIUS_CAT_ACCESS, "Access"},
{ RADIUS_CAT_ACCOUNTING, "Accounting"},
{ RADIUS_CAT_PASSWORD, "Password"},
{ RADIUS_CAT_RESOURCE_FREE, "Resource Free"},
{ RADIUS_CAT_RESOURCE_QUERY, "Resource Query"},
{ RADIUS_CAT_NAS_REBOOT, "NAS Reboot"},
{ RADIUS_CAT_EVENT, "Event"},
{ RADIUS_CAT_DISCONNECT, "Disconnect"},
{ RADIUS_CAT_COA, "CoA"},
{ RADIUS_CAT_OTHERS, "Other"},
{ 0, NULL}
};
static int
radiusstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pri)
{
rtd_data_t* rtd_data = (rtd_data_t*)prs;
rtd_stat_table* rs = &rtd_data->stat_table;
const radius_info_t *ri=(radius_info_t *)pri;
nstime_t delta;
radius_category radius_cat = RADIUS_CAT_OTHERS;
int ret = 0;
switch (ri->code) {
case RADIUS_PKT_TYPE_ACCESS_REQUEST:
case RADIUS_PKT_TYPE_ACCESS_ACCEPT:
case RADIUS_PKT_TYPE_ACCESS_REJECT:
radius_cat = RADIUS_CAT_ACCESS;
break;
case RADIUS_PKT_TYPE_ACCOUNTING_REQUEST:
case RADIUS_PKT_TYPE_ACCOUNTING_RESPONSE:
radius_cat = RADIUS_CAT_ACCOUNTING;
break;
case RADIUS_PKT_TYPE_PASSWORD_REQUEST:
case RADIUS_PKT_TYPE_PASSWORD_ACK:
case RADIUS_PKT_TYPE_PASSWORD_REJECT:
radius_cat = RADIUS_CAT_PASSWORD;
break;
case RADIUS_PKT_TYPE_RESOURCE_FREE_REQUEST:
case RADIUS_PKT_TYPE_RESOURCE_FREE_RESPONSE:
radius_cat = RADIUS_CAT_RESOURCE_FREE;
break;
case RADIUS_PKT_TYPE_RESOURCE_QUERY_REQUEST:
case RADIUS_PKT_TYPE_RESOURCE_QUERY_RESPONSE:
radius_cat = RADIUS_CAT_RESOURCE_QUERY;
break;
case RADIUS_PKT_TYPE_NAS_REBOOT_REQUEST:
case RADIUS_PKT_TYPE_NAS_REBOOT_RESPONSE:
radius_cat = RADIUS_CAT_NAS_REBOOT;
break;
case RADIUS_PKT_TYPE_EVENT_REQUEST:
case RADIUS_PKT_TYPE_EVENT_RESPONSE:
radius_cat = RADIUS_CAT_EVENT;
break;
case RADIUS_PKT_TYPE_DISCONNECT_REQUEST:
case RADIUS_PKT_TYPE_DISCONNECT_ACK:
case RADIUS_PKT_TYPE_DISCONNECT_NAK:
radius_cat = RADIUS_CAT_DISCONNECT;
break;
case RADIUS_PKT_TYPE_COA_REQUEST:
case RADIUS_PKT_TYPE_COA_ACK:
case RADIUS_PKT_TYPE_COA_NAK:
radius_cat = RADIUS_CAT_COA;
break;
}
switch (ri->code) {
case RADIUS_PKT_TYPE_ACCESS_REQUEST:
case RADIUS_PKT_TYPE_ACCOUNTING_REQUEST:
case RADIUS_PKT_TYPE_PASSWORD_REQUEST:
case RADIUS_PKT_TYPE_EVENT_REQUEST:
case RADIUS_PKT_TYPE_DISCONNECT_REQUEST:
case RADIUS_PKT_TYPE_COA_REQUEST:
if(ri->is_duplicate){
/* Duplicate is ignored */
rs->time_stats[RADIUS_CAT_OVERALL].req_dup_num++;
rs->time_stats[radius_cat].req_dup_num++;
}
else {
rs->time_stats[RADIUS_CAT_OVERALL].open_req_num++;
rs->time_stats[radius_cat].open_req_num++;
}
break;
case RADIUS_PKT_TYPE_ACCESS_ACCEPT:
case RADIUS_PKT_TYPE_ACCESS_REJECT:
case RADIUS_PKT_TYPE_ACCOUNTING_RESPONSE:
case RADIUS_PKT_TYPE_PASSWORD_ACK:
case RADIUS_PKT_TYPE_PASSWORD_REJECT:
case RADIUS_PKT_TYPE_EVENT_RESPONSE:
case RADIUS_PKT_TYPE_DISCONNECT_ACK:
case RADIUS_PKT_TYPE_DISCONNECT_NAK:
case RADIUS_PKT_TYPE_COA_ACK:
case RADIUS_PKT_TYPE_COA_NAK:
if(ri->is_duplicate){
/* Duplicate is ignored */
rs->time_stats[RADIUS_CAT_OVERALL].rsp_dup_num++;
rs->time_stats[radius_cat].rsp_dup_num++;
}
else if (!ri->request_available) {
/* no request was seen */
rs->time_stats[RADIUS_CAT_OVERALL].disc_rsp_num++;
rs->time_stats[radius_cat].disc_rsp_num++;
}
else {
rs->time_stats[RADIUS_CAT_OVERALL].open_req_num--;
rs->time_stats[radius_cat].open_req_num--;
/* calculate time delta between request and response */
nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->req_time);
time_stat_update(&(rs->time_stats[RADIUS_CAT_OVERALL].rtd[0]),&delta, pinfo);
time_stat_update(&(rs->time_stats[radius_cat].rtd[0]),&delta, pinfo);
ret = 1;
}
break;
default:
break;
}
return ret;
}
/*
* Init Hash table stuff for conversation
*/
@ -2130,6 +2275,8 @@ proto_register_radius(void)
dict->vendors_by_id = g_hash_table_new(g_direct_hash,g_direct_equal);
dict->vendors_by_name = g_hash_table_new(g_str_hash,g_str_equal);
dict->tlvs_by_name = g_hash_table_new(g_str_hash,g_str_equal);
register_rtd_table(proto_radius, NULL, RADIUS_CAT_NUM_TIMESTATS, 1, radius_message_code, radiusstat_packet, NULL);
}
void

205
epan/rtd_table.c Normal file
View File

@ -0,0 +1,205 @@
/* rtd_table.c
* Helper routines common to all RTD taps.
* Based on srt_table.c
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <string.h>
#include "packet_info.h"
#include "proto.h"
#include "rtd_table.h"
struct register_rtd {
int proto_id; /* protocol id (0-indexed) */
const char* tap_listen_str; /* string used in register_tap_listener (NULL to use protocol name) */
tap_packet_cb rtd_func; /* function to be called for new incoming packets for RTD */
guint num_tables;
guint num_timestats;
const value_string* vs_type;
rtd_filter_check_cb filter_check;
};
int get_rtd_proto_id(register_rtd_t* rtd)
{
if (!rtd) {
return -1;
}
return rtd->proto_id;
}
const char* get_rtd_tap_listener_name(register_rtd_t* rtd)
{
return rtd->tap_listen_str;
}
tap_packet_cb get_rtd_packet_func(register_rtd_t* rtd)
{
return rtd->rtd_func;
}
const value_string* get_rtd_value_string(register_rtd_t* rtd)
{
return rtd->vs_type;
}
static GSList *registered_rtd_tables = NULL;
static gint
insert_sorted_by_table_name(gconstpointer aparam, gconstpointer bparam)
{
const register_rtd_t *a = (register_rtd_t *)aparam;
const register_rtd_t *b = (register_rtd_t *)bparam;
return g_ascii_strcasecmp(proto_get_protocol_short_name(find_protocol_by_id(a->proto_id)), proto_get_protocol_short_name(find_protocol_by_id(b->proto_id)));
}
void
register_rtd_table(const int proto_id, const char* tap_listener, guint num_tables, guint num_timestats, const value_string* vs_type,
tap_packet_cb rtd_packet_func, rtd_filter_check_cb filter_check_cb)
{
register_rtd_t *table;
DISSECTOR_ASSERT(rtd_packet_func);
table = g_new(register_rtd_t,1);
table->proto_id = proto_id;
if (tap_listener != NULL)
table->tap_listen_str = tap_listener;
else
table->tap_listen_str = proto_get_protocol_filter_name(proto_id);
table->rtd_func = rtd_packet_func;
table->num_tables = num_tables;
table->num_timestats = num_timestats;
table->vs_type = vs_type;
table->filter_check = filter_check_cb;
registered_rtd_tables = g_slist_insert_sorted(registered_rtd_tables, table, insert_sorted_by_table_name);
}
void free_rtd_table(register_rtd_t* rtd _U_, rtd_stat_table* table, rtd_gui_free_cb gui_callback, void *callback_data)
{
guint i;
for (i = 0; i < table->num_rtds; i++)
{
g_free(table->time_stats[i].rtd);
}
g_free(table->time_stats);
/* Give GUI the first crack at it before we clean up */
if (gui_callback)
gui_callback(table, callback_data);
}
void reset_rtd_table(rtd_stat_table* table, rtd_gui_reset_cb gui_callback, void *callback_data)
{
guint i = 0;
for (i = 0; i < table->num_rtds; i++)
memset(table->time_stats[i].rtd, 0, sizeof(timestat_t)*table->time_stats[i].num_timestat);
/* Give GUI the first crack at it before we clean up */
if (gui_callback)
gui_callback(table, callback_data);
}
register_rtd_t* get_rtd_table_by_name(const char* name)
{
guint i, size = g_slist_length(registered_rtd_tables);
register_rtd_t* rtd;
GSList *slist;
for (i = 0; i < size; i++) {
slist = g_slist_nth(registered_rtd_tables, i);
rtd = (register_rtd_t*)slist->data;
if (strcmp(name, proto_get_protocol_filter_name(rtd->proto_id)) == 0)
return rtd;
}
return NULL;
}
gchar* rtd_table_get_tap_string(register_rtd_t* rtd)
{
GString *cmd_str = g_string_new(proto_get_protocol_filter_name(rtd->proto_id));
g_string_append(cmd_str, ",rtd");
return g_string_free(cmd_str, FALSE);
}
void rtd_table_get_filter(register_rtd_t* rtd, const char *opt_arg, const char **filter, char** err)
{
gchar* cmd_str = rtd_table_get_tap_string(rtd);
guint len = strlen(cmd_str);
*filter=NULL;
*err=NULL;
if (!strncmp(opt_arg, cmd_str, len))
{
if (opt_arg[len] == ',')
{
*filter = opt_arg + len+1;
}
}
if (rtd->filter_check)
rtd->filter_check(opt_arg, filter, err);
g_free(cmd_str);
}
void rtd_table_dissector_init(register_rtd_t* rtd, rtd_stat_table* table, rtd_gui_init_cb gui_callback, void *callback_data)
{
guint i;
table->num_rtds = rtd->num_tables;
table->time_stats = g_new0(rtd_timestat, rtd->num_tables);
for (i = 0; i < table->num_rtds; i++)
{
table->time_stats[i].num_timestat = rtd->num_timestats;
table->time_stats[i].rtd = g_new0(timestat_t, rtd->num_timestats);
}
if (gui_callback)
gui_callback(table, callback_data);
}
void rtd_table_iterate_tables(GFunc func, gpointer user_data)
{
g_slist_foreach(registered_rtd_tables, func, user_data);
}
/*
* 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:
*/

183
epan/rtd_table.h Normal file
View File

@ -0,0 +1,183 @@
/* rtd_table.h
* GUI independent helper routines common to all Response Time Delay (RTD) taps.
* Based on srt_table.h
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __RTD_TABLE_H__
#define __RTD_TABLE_H__
#include "tap.h"
#include "timestats.h"
#include "value_string.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _rtd_timestat {
guint num_timestat; /**< number of elements on rtd array */
timestat_t* rtd;
guint32 open_req_num;
guint32 disc_rsp_num;
guint32 req_dup_num;
guint32 rsp_dup_num;
} rtd_timestat;
/** Statistics table */
typedef struct _rtd_stat_table {
char *filter;
guint num_rtds; /**< number of elements on time_stats array */
rtd_timestat* time_stats;
} rtd_stat_table;
/** tap data
*/
typedef struct _rtd_data_t {
rtd_stat_table stat_table; /**< RTD table data */
void *user_data; /**< "GUI" specifics (if necessary) */
} rtd_data_t;
/** Structure for information about a registered service response table */
struct register_rtd;
typedef struct register_rtd register_rtd_t;
typedef void (*rtd_gui_init_cb)(rtd_stat_table* rtd, void* gui_data);
typedef void (*rtd_gui_reset_cb)(rtd_stat_table* rtd, void* gui_data);
typedef void (*rtd_gui_free_cb)(rtd_stat_table* rtd, void* gui_data);
typedef void (*rtd_init_cb)(struct register_rtd* rtd, rtd_gui_init_cb gui_callback, void* gui_data);
typedef void (*rtd_filter_check_cb)(const char *opt_arg, const char **filter, char** err);
/** Register the response time delay table.
*
* @param proto_id is the protocol with conversation
* @param tap_listener string for register_tap_listener (NULL to just use protocol name)
* @param num_timestats number of timestamps in the table
* @param vs_type value_string for the stat types
* @param rtd_packet_func the tap processing function
* @param filter_check_cb callback for verification of filter or other dissector checks
*/
WS_DLL_PUBLIC void register_rtd_table(const int proto_id, const char* tap_listener, guint num_tables, guint num_timestats, const value_string* vs_type,
tap_packet_cb rtd_packet_func, rtd_filter_check_cb filter_check_cb);
/** Get protocol ID from RTD
*
* @param rtd Registered RTD
* @return protocol id of RTD
*/
WS_DLL_PUBLIC int get_rtd_proto_id(register_rtd_t* rtd);
/** Get string for register_tap_listener call. Typically just dissector name
*
* @param rtd Registered RTD
* @return string for register_tap_listener call
*/
WS_DLL_PUBLIC const char* get_rtd_tap_listener_name(register_rtd_t* rtd);
/** Get tap function handler from RTD
*
* @param rtd Registered RTD
* @return tap function handler of RTD
*/
WS_DLL_PUBLIC tap_packet_cb get_rtd_packet_func(register_rtd_t* rtd);
/** Get value_string used for RTD
*
* @param rtd Registered RTD
* @return value_string of RTD
*/
WS_DLL_PUBLIC const value_string* get_rtd_value_string(register_rtd_t* rtd);
/** Get RTD table by its dissector name
*
* @param name dissector name to fetch.
* @return RTD table pointer or NULL.
*/
WS_DLL_PUBLIC register_rtd_t* get_rtd_table_by_name(const char* name);
/** Free the RTD table data.
*
* @param srt Registered RTD
* @param srt_array RTD table array
* @param gui_callback optional callback from GUI
* @param callback_data callback data needed for GUI
*/
WS_DLL_PUBLIC void free_rtd_table(register_rtd_t* rtd, rtd_stat_table* table, rtd_gui_free_cb gui_callback, void *callback_data);
/** Reset table data in the RTD.
*
* @param table RTD table
* @param gui_callback optional callback from GUI
* @param callback_data callback data needed for GUI
*/
WS_DLL_PUBLIC void reset_rtd_table(rtd_stat_table* table, rtd_gui_reset_cb gui_callback, void *callback_data);
/** Interator to walk RTD tables and execute func
* Used for initialization
*
* @param func action to be performed on all converation tables
* @param user_data any data needed to help perform function
*/
WS_DLL_PUBLIC void rtd_table_iterate_tables(GFunc func, gpointer user_data);
/** Return filter used for register_tap_listener
*
* @param srt Registered RTD
* @param opt_arg passed in opt_arg from GUI
* @param filter returned filter string to be used for registering tap
* @param err returned error if opt_arg string can't be successfully handled. Caller must free memory
*/
WS_DLL_PUBLIC void rtd_table_get_filter(register_rtd_t* rtd, const char *opt_arg, const char **filter, char** err);
/** "Common" initialization function for all GUIs
*
* @param srt Registered RTD
* @param table RTD table
* @param gui_callback optional GUI callback function
* @param callback_data optional GUI callback data
*/
WS_DLL_PUBLIC void rtd_table_dissector_init(register_rtd_t* rtd, rtd_stat_table* table, rtd_gui_init_cb gui_callback, void *callback_data);
/** Helper function to get tap string name
* Caller is responsible for freeing returned string
*
* @param srt Registered RTD
* @return RTD tap string
*/
WS_DLL_PUBLIC gchar* rtd_table_get_tap_string(register_rtd_t* rtd);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __RTD_TABLE_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:
*/

View File

@ -105,6 +105,7 @@
#include <epan/stat_tap_ui.h>
#include <epan/conversation_table.h>
#include <epan/srt_table.h>
#include <epan/rtd_table.h>
#include <epan/ex-opt.h>
#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
@ -1217,6 +1218,7 @@ DIAG_ON(cast-qual)
conversation_table_set_gui_info(init_iousers);
hostlist_table_set_gui_info(init_hostlists);
srt_table_iterate_tables(register_srt_tables, NULL);
rtd_table_iterate_tables(register_rtd_tables, NULL);
/* If invoked with the "-G" flag, we dump out information based on
the argument to the "-G" flag; if no argument is specified,

View File

@ -48,7 +48,6 @@ set(COMMON_UI_SRC
software_update.c
ssl_key_export.c
tap_export_pdu.c
tap-megaco-common.c
tap-rtp-common.c
tap-sctp-analysis.c
tap-sequence-analysis.c

View File

@ -69,7 +69,6 @@ WIRESHARK_UI_SRC = \
software_update.c \
ssl_key_export.c \
tap_export_pdu.c \
tap-megaco-common.c \
tap-rtp-common.c \
tap-sctp-analysis.c \
tap-sequence-analysis.c \
@ -112,7 +111,6 @@ noinst_HEADERS = \
software_update.h \
ssl_key_export.h \
tap_export_pdu.h \
tap-megaco-common.h \
tap-rtp-common.h \
tap-sctp-analysis.h \
tap-sequence-analysis.h \

View File

@ -58,13 +58,11 @@ TSHARK_TAP_SRC = \
tap-iostat.c \
tap-iousers.c \
tap-macltestat.c \
tap-megacostat.c \
tap-mgcpstat.c \
tap-protocolinfo.c \
tap-protohierstat.c \
tap-radiusstat.c \
tap-rlcltestat.c \
tap-rpcprogs.c \
tap-rtd.c \
tap-rtp.c \
tap-rtspstat.c \
tap-sctpchunkstat.c \

View File

@ -1,163 +0,0 @@
/* tap-megacostat.c
* mgcpstat 2003 Lars Roland
* Copyright 2008, Ericsson AB
* By Balint Reczey <balint.reczey@ericsson.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "epan/packet_info.h"
#include <epan/tap.h>
#include <epan/stat_tap_ui.h>
#include "epan/value_string.h"
#include "epan/gcp.h"
#include "epan/timestats.h"
#include <epan/prefs-int.h>
#include "ui/tap-megaco-common.h"
void register_tap_listener_megacostat(void);
static void
megacostat_draw(void *pms)
{
megacostat_t *ms = (megacostat_t *)pms;
gchar* tmp_str;
int i;
/* printing results */
printf("\n");
printf("=====================================================================================================\n");
printf("MEGACO Response Time Delay (RTD) Statistics:\n");
printf("Filter for statistics: %s\n", ms->filter ? ms->filter : "");
printf("Duplicate requests: %u\n", ms->req_dup_num);
printf("Duplicate responses: %u\n", ms->rsp_dup_num);
printf("Open requests: %u\n", ms->open_req_num);
printf("Discarded responses: %u\n", ms->disc_rsp_num);
printf(" Type | Messages | Min RTD | Max RTD | Avg RTD | Min in Frame | Max in Frame |\n");
for (i=0; i<NUM_TIMESTATS; i++) {
if (ms->rtd[i].num) {
tmp_str = val_to_str_wmem(NULL, i, megaco_message_type, "Other (%d)");
printf("%5s | %7u | %8.2f msec | %8.2f msec | %8.2f msec | %10u | %10u |\n",
tmp_str, ms->rtd[i].num,
nstime_to_msec(&(ms->rtd[i].min)), nstime_to_msec(&(ms->rtd[i].max)),
get_average(&(ms->rtd[i].tot), ms->rtd[i].num),
ms->rtd[i].min_num, ms->rtd[i].max_num
);
wmem_free(NULL, tmp_str);
}
}
printf("=====================================================================================================\n");
}
static void
megacostat_init(const char *opt_arg, void *userdata _U_)
{
megacostat_t *ms;
int i;
GString *error_string;
pref_t *megaco_ctx_track, *h248_ctx_track;
megaco_ctx_track = prefs_find_preference(prefs_find_module("megaco"), "ctx_info");
h248_ctx_track = prefs_find_preference(prefs_find_module("h248"), "ctx_info");
if (!megaco_ctx_track || !h248_ctx_track) {
/* No such preferences */
return;
}
if (!*megaco_ctx_track->varp.boolp || !*h248_ctx_track->varp.boolp) {
printf("Track Context option at Protocols -> MEGACO and Protocols -> H248 preferences\n");
printf("has to be set to true to enable measurement of service response times.\n");
exit(1);
}
ms = g_new(megacostat_t, 1);
if (!strncmp(opt_arg, "megaco,rtd,", 11)) {
ms->filter = g_strdup(opt_arg+11);
} else {
ms->filter = NULL;
}
for (i=0; i<NUM_TIMESTATS; i++) {
ms->rtd[i].num = 0;
ms->rtd[i].min_num = 0;
ms->rtd[i].max_num = 0;
ms->rtd[i].min.secs = 0;
ms->rtd[i].min.nsecs = 0;
ms->rtd[i].max.secs = 0;
ms->rtd[i].max.nsecs = 0;
ms->rtd[i].tot.secs = 0;
ms->rtd[i].tot.nsecs = 0;
}
ms->open_req_num = 0;
ms->disc_rsp_num = 0;
ms->req_dup_num = 0;
ms->rsp_dup_num = 0;
error_string = register_tap_listener("megaco", ms, ms->filter, 0, NULL, megacostat_packet, megacostat_draw);
if (error_string) {
/* error, we failed to attach to the tap. clean up */
g_free(ms->filter);
g_free(ms);
fprintf(stderr, "tshark: Couldn't register megaco,rtd tap: %s\n",
error_string->str);
g_string_free(error_string, TRUE);
exit(1);
}
}
static stat_tap_ui megacostat_ui = {
REGISTER_STAT_GROUP_GENERIC,
NULL,
"megaco,rtd",
megacostat_init,
0,
NULL
};
void
register_tap_listener_megacostat(void)
{
/* We don't register this tap, if we don't have the megaco plugin loaded.*/
if (find_tap_id("megaco")) {
register_stat_tap_ui(&megacostat_ui, NULL);
}
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -1,248 +0,0 @@
/* tap-mgcpstat.c
* mgcpstat 2003 Lars Roland
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "epan/packet_info.h"
#include <epan/tap.h>
#include <epan/stat_tap_ui.h>
#include "epan/value_string.h"
#include "epan/dissectors/packet-mgcp.h"
#include "epan/timestats.h"
#define NUM_TIMESTATS 11
void register_tap_listener_mgcpstat(void);
/* used to keep track of the statistics for an entire program interface */
typedef struct _mgcpstat_t {
char *filter;
timestat_t rtd[NUM_TIMESTATS];
guint32 open_req_num;
guint32 disc_rsp_num;
guint32 req_dup_num;
guint32 rsp_dup_num;
} mgcpstat_t;
static const value_string mgcp_mesage_type[] = {
{ 0, "Overall"},
{ 1, "EPCF "},
{ 2, "CRCX "},
{ 3, "MDCX "},
{ 4, "DLCX "},
{ 5, "RQNT "},
{ 6, "NTFY "},
{ 7, "AUEP "},
{ 8, "AUCX "},
{ 9, "RSIP "},
{ 0, NULL}
};
static int
mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pmi)
{
mgcpstat_t *ms = (mgcpstat_t *)pms;
const mgcp_info_t *mi = (const mgcp_info_t *)pmi;
nstime_t delta;
int ret = 0;
switch (mi->mgcp_type) {
case MGCP_REQUEST:
if (mi->is_duplicate) {
/* Duplicate is ignored */
ms->req_dup_num++;
}
else {
ms->open_req_num++;
}
break;
case MGCP_RESPONSE:
if (mi->is_duplicate) {
/* Duplicate is ignored */
ms->rsp_dup_num++;
}
else if (!mi->request_available) {
/* no request was seen */
ms->disc_rsp_num++;
}
else {
ms->open_req_num--;
/* calculate time delta between request and response */
nstime_delta(&delta, &pinfo->fd->abs_ts, &mi->req_time);
time_stat_update(&(ms->rtd[0]), &delta, pinfo);
if (g_ascii_strncasecmp(mi->code, "EPCF", 4) == 0 ) {
time_stat_update(&(ms->rtd[1]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "CRCX", 4) == 0 ) {
time_stat_update(&(ms->rtd[2]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "MDCX", 4) == 0 ) {
time_stat_update(&(ms->rtd[3]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "DLCX", 4) == 0 ) {
time_stat_update(&(ms->rtd[4]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "RQNT", 4) == 0 ) {
time_stat_update(&(ms->rtd[5]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "NTFY", 4) == 0 ) {
time_stat_update(&(ms->rtd[6]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "AUEP", 4) == 0 ) {
time_stat_update(&(ms->rtd[7]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "AUCX", 4) == 0 ) {
time_stat_update(&(ms->rtd[8]), &delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "RSIP", 4) == 0 ) {
time_stat_update(&(ms->rtd[9]), &delta, pinfo);
}
else {
time_stat_update(&(ms->rtd[10]), &delta, pinfo);
}
ret = 1;
}
break;
default:
break;
}
return ret;
}
static void
mgcpstat_draw(void *pms)
{
mgcpstat_t *ms = (mgcpstat_t *)pms;
gchar* tmp_str;
int i;
/* printing results */
printf("\n");
printf("=====================================================================================================\n");
printf("MGCP Response Time Delay (RTD) Statistics:\n");
printf("Filter for statistics: %s\n", ms->filter ? ms->filter : "");
printf("Duplicate requests: %u\n", ms->req_dup_num);
printf("Duplicate responses: %u\n", ms->rsp_dup_num);
printf("Open requests: %u\n", ms->open_req_num);
printf("Discarded responses: %u\n", ms->disc_rsp_num);
printf("Type | Messages | Min RTD | Max RTD | Avg RTD | Min in Frame | Max in Frame |\n");
for (i=0; i<NUM_TIMESTATS; i++) {
if (ms->rtd[i].num) {
tmp_str = val_to_str_wmem(NULL, i, mgcp_mesage_type, "Other (%d)");
printf("%s | %7u | %8.2f msec | %8.2f msec | %8.2f msec | %10u | %10u |\n",
tmp_str, ms->rtd[i].num,
nstime_to_msec(&(ms->rtd[i].min)), nstime_to_msec(&(ms->rtd[i].max)),
get_average(&(ms->rtd[i].tot), ms->rtd[i].num),
ms->rtd[i].min_num, ms->rtd[i].max_num
);
wmem_free(NULL, tmp_str);
}
}
printf("=====================================================================================================\n");
}
static void
mgcpstat_init(const char *opt_arg, void *userdata _U_)
{
mgcpstat_t *ms;
int i;
GString *error_string;
ms = g_new(mgcpstat_t, 1);
if (!strncmp(opt_arg, "mgcp,rtd,", 9)) {
ms->filter = g_strdup(opt_arg+9);
} else {
ms->filter = NULL;
}
for (i=0; i<NUM_TIMESTATS; i++) {
ms->rtd[i].num = 0;
ms->rtd[i].min_num = 0;
ms->rtd[i].max_num = 0;
ms->rtd[i].min.secs = 0;
ms->rtd[i].min.nsecs = 0;
ms->rtd[i].max.secs = 0;
ms->rtd[i].max.nsecs = 0;
ms->rtd[i].tot.secs = 0;
ms->rtd[i].tot.nsecs = 0;
}
ms->open_req_num = 0;
ms->disc_rsp_num = 0;
ms->req_dup_num = 0;
ms->rsp_dup_num = 0;
error_string = register_tap_listener("mgcp", ms, ms->filter, 0, NULL, mgcpstat_packet, mgcpstat_draw);
if (error_string) {
/* error, we failed to attach to the tap. clean up */
g_free(ms->filter);
g_free(ms);
fprintf(stderr, "tshark: Couldn't register mgcp,rtd tap: %s\n",
error_string->str);
g_string_free(error_string, TRUE);
exit(1);
}
}
static stat_tap_ui mgcpstat_ui = {
REGISTER_STAT_GROUP_GENERIC,
NULL,
"mgcp,rtd",
mgcpstat_init,
0,
NULL
};
void
register_tap_listener_mgcpstat(void)
{
/* We don't register this tap, if we don't have the mgcp plugin loaded.*/
if (find_tap_id("mgcp")) {
register_stat_tap_ui(&mgcpstat_ui, NULL);
}
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -1,261 +0,0 @@
/* tap-radiusstat.c
* Copyright 2006 Alejandro Vaquero <alejandrovaquero@yahoo.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "epan/packet_info.h"
#include <epan/tap.h>
#include <epan/stat_tap_ui.h>
#include "epan/value_string.h"
#include <epan/dissectors/packet-radius.h>
#include "epan/timestats.h"
void register_tap_listener_radiusstat(void);
typedef enum _radius_category {
RADIUS_CAT_OVERALL = 0,
RADIUS_CAT_ACCESS,
RADIUS_CAT_ACCOUNTING,
RADIUS_CAT_PASSWORD,
RADIUS_CAT_RESOURCE_FREE,
RADIUS_CAT_RESOURCE_QUERY,
RADIUS_CAT_NAS_REBOOT,
RADIUS_CAT_EVENT,
RADIUS_CAT_DISCONNECT,
RADIUS_CAT_COA,
RADIUS_CAT_OTHERS,
RADIUS_CAT_NUM_TIMESTATS
} radius_category;
/* used to keep track of the statistics for an entire program interface */
typedef struct _radiusstat_t {
char *filter;
timestat_t rtd[RADIUS_CAT_NUM_TIMESTATS];
guint32 open_req_num;
guint32 disc_rsp_num;
guint32 req_dup_num;
guint32 rsp_dup_num;
} radiusstat_t;
static const value_string radius_message_code[] = {
{ RADIUS_CAT_OVERALL, "Overall "},
{ RADIUS_CAT_ACCESS, "Access "},
{ RADIUS_CAT_ACCOUNTING, "Accounting "},
{ RADIUS_CAT_PASSWORD, "Password "},
{ RADIUS_CAT_RESOURCE_FREE, "Resource Free "},
{ RADIUS_CAT_RESOURCE_QUERY, "Resource Query"},
{ RADIUS_CAT_NAS_REBOOT, "NAS Reboot "},
{ RADIUS_CAT_EVENT, "Event "},
{ RADIUS_CAT_DISCONNECT, "Disconnect "},
{ RADIUS_CAT_COA, "CoA "},
{ RADIUS_CAT_OTHERS, "Other "},
{ 0, NULL}
};
static int
radiusstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pri)
{
radiusstat_t *rs = (radiusstat_t *)prs;
const radius_info_t *ri = (const radius_info_t *)pri;
nstime_t delta;
int ret = 0;
switch (ri->code) {
case RADIUS_PKT_TYPE_ACCESS_REQUEST:
case RADIUS_PKT_TYPE_ACCOUNTING_REQUEST:
case RADIUS_PKT_TYPE_PASSWORD_REQUEST:
case RADIUS_PKT_TYPE_RESOURCE_FREE_REQUEST:
case RADIUS_PKT_TYPE_RESOURCE_QUERY_REQUEST:
case RADIUS_PKT_TYPE_NAS_REBOOT_REQUEST:
case RADIUS_PKT_TYPE_EVENT_REQUEST:
case RADIUS_PKT_TYPE_DISCONNECT_REQUEST:
case RADIUS_PKT_TYPE_COA_REQUEST:
if (ri->is_duplicate) {
/* Duplicate is ignored */
rs->req_dup_num++;
}
else {
rs->open_req_num++;
}
break;
case RADIUS_PKT_TYPE_ACCESS_ACCEPT:
case RADIUS_PKT_TYPE_ACCESS_REJECT:
case RADIUS_PKT_TYPE_ACCOUNTING_RESPONSE:
case RADIUS_PKT_TYPE_PASSWORD_ACK:
case RADIUS_PKT_TYPE_PASSWORD_REJECT:
case RADIUS_PKT_TYPE_RESOURCE_FREE_RESPONSE:
case RADIUS_PKT_TYPE_RESOURCE_QUERY_RESPONSE:
case RADIUS_PKT_TYPE_NAS_REBOOT_RESPONSE:
case RADIUS_PKT_TYPE_EVENT_RESPONSE:
case RADIUS_PKT_TYPE_DISCONNECT_ACK:
case RADIUS_PKT_TYPE_DISCONNECT_NAK:
case RADIUS_PKT_TYPE_COA_ACK:
case RADIUS_PKT_TYPE_COA_NAK:
if (ri->is_duplicate) {
/* Duplicate is ignored */
rs->rsp_dup_num++;
}
else if (!ri->request_available) {
/* no request was seen */
rs->disc_rsp_num++;
}
else {
rs->open_req_num--;
/* calculate time delta between request and response */
nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->req_time);
time_stat_update(&(rs->rtd[RADIUS_CAT_OVERALL]), &delta, pinfo);
if (ri->code == RADIUS_PKT_TYPE_ACCESS_ACCEPT || ri->code == RADIUS_PKT_TYPE_ACCESS_REJECT) {
time_stat_update(&(rs->rtd[RADIUS_CAT_ACCESS]), &delta, pinfo);
}
else if (ri->code == RADIUS_PKT_TYPE_ACCOUNTING_RESPONSE) {
time_stat_update(&(rs->rtd[RADIUS_CAT_ACCOUNTING]), &delta, pinfo);
}
else {
time_stat_update(&(rs->rtd[RADIUS_CAT_OTHERS]), &delta, pinfo);
}
ret = 1;
}
break;
default:
break;
}
return ret;
}
static void
radiusstat_draw(void *prs)
{
radiusstat_t *rs = (radiusstat_t *)prs;
gchar* tmp_str;
int i;
/* printing results */
printf("\n");
printf("===========================================================================================================\n");
printf("RADIUS Response Time Delay (RTD) Statistics:\n");
printf("Filter for statistics: %s\n", rs->filter ? rs->filter : "");
printf("Duplicate requests: %u\n", rs->req_dup_num);
printf("Duplicate responses: %u\n", rs->rsp_dup_num);
printf("Open requests: %u\n", rs->open_req_num);
printf("Discarded responses: %u\n", rs->disc_rsp_num);
printf("Type | Messages | Min RTD | Max RTD | Avg RTD | Min in Frame | Max in Frame |\n");
for (i=0; i<RADIUS_CAT_NUM_TIMESTATS; i++) {
if (rs->rtd[i].num) {
tmp_str = val_to_str_wmem(NULL, i, radius_message_code, "Other (%d)");
printf("%s | %7u | %8.2f msec | %8.2f msec | %8.2f msec | %10u | %10u |\n",
tmp_str, rs->rtd[i].num,
nstime_to_msec(&(rs->rtd[i].min)), nstime_to_msec(&(rs->rtd[i].max)),
get_average(&(rs->rtd[i].tot), rs->rtd[i].num),
rs->rtd[i].min_num, rs->rtd[i].max_num
);
wmem_free(NULL, tmp_str);
}
}
printf("===========================================================================================================\n");
}
static void
radiusstat_init(const char *opt_arg, void *userdata _U_)
{
radiusstat_t *rs;
int i;
GString *error_string;
rs = g_new(radiusstat_t, 1);
if (!strncmp(opt_arg, "radius,rtd,", 11)) {
rs->filter = g_strdup(opt_arg+11);
} else {
rs->filter = NULL;
}
for (i=0; i<RADIUS_CAT_NUM_TIMESTATS; i++) {
rs->rtd[i].num = 0;
rs->rtd[i].min_num = 0;
rs->rtd[i].max_num = 0;
rs->rtd[i].min.secs = 0;
rs->rtd[i].min.nsecs = 0;
rs->rtd[i].max.secs = 0;
rs->rtd[i].max.nsecs = 0;
rs->rtd[i].tot.secs = 0;
rs->rtd[i].tot.nsecs = 0;
}
rs->open_req_num = 0;
rs->disc_rsp_num = 0;
rs->req_dup_num = 0;
rs->rsp_dup_num = 0;
error_string = register_tap_listener("radius", rs, rs->filter, 0, NULL, radiusstat_packet, radiusstat_draw);
if (error_string) {
/* error, we failed to attach to the tap. clean up */
g_free(rs->filter);
g_free(rs);
fprintf(stderr, "tshark: Couldn't register radius,rtd tap: %s\n",
error_string->str);
g_string_free(error_string, TRUE);
exit(1);
}
}
static stat_tap_ui radiusstat_ui = {
REGISTER_STAT_GROUP_GENERIC,
NULL,
"radius,rtd",
radiusstat_init,
0,
NULL
};
void
register_tap_listener_radiusstat(void)
{
register_stat_tap_ui(&radiusstat_ui, NULL);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

170
ui/cli/tap-rtd.c Normal file
View File

@ -0,0 +1,170 @@
/* tap-rtd.c
*
* Based on tap-srt.c
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <epan/packet.h>
#include <epan/rtd_table.h>
#include <epan/timestamp.h>
#include <epan/stat_tap_ui.h>
#include <ui/cli/tshark-tap.h>
typedef struct _rtd_t {
const char *type;
const char *filter;
const value_string* vs_type;
rtd_data_t rtd;
} rtd_t;
static void
rtd_draw(void *arg)
{
rtd_data_t* rtd_data = (rtd_data_t*)arg;
rtd_t* rtd = (rtd_t*)rtd_data->user_data;
gchar* tmp_str;
guint i, j;
/* printing results */
printf("\n");
printf("=====================================================================================================\n");
printf("%s Response Time Delay (RTD) Statistics:\n", rtd->type);
printf("Filter for statistics: %s\n", rtd->filter ? rtd->filter : "");
if (rtd_data->stat_table.num_rtds == 1)
{
printf("Duplicate requests: %u\n", rtd_data->stat_table.time_stats[0].req_dup_num);
printf("Duplicate responses: %u\n", rtd_data->stat_table.time_stats[0].rsp_dup_num);
printf("Open requests: %u\n", rtd_data->stat_table.time_stats[0].open_req_num);
printf("Discarded responses: %u\n", rtd_data->stat_table.time_stats[0].disc_rsp_num);
printf("Type | Messages | Min RTD | Max RTD | Avg RTD | Min in Frame | Max in Frame |\n");
for (i=0; i<rtd_data->stat_table.time_stats[0].num_timestat; i++) {
if (rtd_data->stat_table.time_stats[0].rtd[i].num) {
tmp_str = val_to_str_wmem(NULL, i, rtd->vs_type, "Other (%d)");
printf("%s | %7u | %8.2f msec | %8.2f msec | %8.2f msec | %10u | %10u |\n",
tmp_str, rtd_data->stat_table.time_stats[0].rtd[i].num,
nstime_to_msec(&(rtd_data->stat_table.time_stats[0].rtd[i].min)), nstime_to_msec(&(rtd_data->stat_table.time_stats[0].rtd[i].max)),
get_average(&(rtd_data->stat_table.time_stats[0].rtd[i].tot), rtd_data->stat_table.time_stats[0].rtd[i].num),
rtd_data->stat_table.time_stats[0].rtd[i].min_num, rtd_data->stat_table.time_stats[0].rtd[i].max_num
);
wmem_free(NULL, tmp_str);
}
}
}
else
{
printf("Type | Messages | Min RTD | Max RTD | Avg RTD | Min in Frame | Max in Frame | Open Requests | Discarded responses | Duplicate requests | Duplicate responses\n");
for (i=0; i<rtd_data->stat_table.num_rtds; i++) {
for (j=0; j<rtd_data->stat_table.time_stats[i].num_timestat; j++) {
if (rtd_data->stat_table.time_stats[i].rtd[j].num) {
tmp_str = val_to_str_wmem(NULL, i, rtd->vs_type, "Other (%d)");
printf("%s | %7u | %8.2f msec | %8.2f msec | %8.2f msec | %10u | %10u | %10u | %10u | %4u (%4.2f%%) | %4u (%4.2f%%) |\n",
tmp_str, rtd_data->stat_table.time_stats[i].rtd[j].num,
nstime_to_msec(&(rtd_data->stat_table.time_stats[i].rtd[j].min)), nstime_to_msec(&(rtd_data->stat_table.time_stats[i].rtd[j].max)),
get_average(&(rtd_data->stat_table.time_stats[i].rtd[j].tot), rtd_data->stat_table.time_stats[i].rtd[j].num),
rtd_data->stat_table.time_stats[i].rtd[j].min_num, rtd_data->stat_table.time_stats[i].rtd[j].max_num,
rtd_data->stat_table.time_stats[i].open_req_num, rtd_data->stat_table.time_stats[i].disc_rsp_num,
rtd_data->stat_table.time_stats[i].req_dup_num,
rtd_data->stat_table.time_stats[i].rtd[j].num?((double)rtd_data->stat_table.time_stats[i].req_dup_num*100)/(double)rtd_data->stat_table.time_stats[i].rtd[j].num:0,
rtd_data->stat_table.time_stats[i].rsp_dup_num,
rtd_data->stat_table.time_stats[i].rtd[j].num?((double)rtd_data->stat_table.time_stats[i].rsp_dup_num*100)/(double)rtd_data->stat_table.time_stats[i].rtd[j].num:0
);
wmem_free(NULL, tmp_str);
}
}
}
}
printf("=====================================================================================================\n");
}
static void
init_rtd_tables(register_rtd_t* rtd, const char *filter)
{
GString *error_string;
rtd_t* ui;
ui = g_new0(rtd_t, 1);
ui->type = proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)));
ui->filter = g_strdup(filter);
ui->vs_type = get_rtd_value_string(rtd);
ui->rtd.user_data = ui;
rtd_table_dissector_init(rtd, &ui->rtd.stat_table, NULL, NULL);
error_string = register_tap_listener(get_rtd_tap_listener_name(rtd), &ui->rtd, filter, 0, NULL, get_rtd_packet_func(rtd), rtd_draw);
if (error_string) {
free_rtd_table(rtd, &ui->rtd.stat_table, NULL, NULL);
fprintf(stderr, "tshark: Couldn't register srt tap: %s\n", error_string->str);
g_string_free(error_string, TRUE);
exit(1);
}
}
static void
dissector_rtd_init(const char *opt_arg, void* userdata)
{
register_rtd_t *rtd = (register_rtd_t*)userdata;
const char *filter=NULL;
char* err = NULL;
rtd_table_get_filter(rtd, opt_arg, &filter, &err);
if (err != NULL)
{
fprintf(stderr, "tshark: %s\n", err);
g_free(err);
exit(1);
}
init_rtd_tables(rtd, filter);
}
/* Set GUI fields for register_rtd list */
void
register_rtd_tables(gpointer data, gpointer user_data _U_)
{
register_rtd_t *rtd = (register_rtd_t*)data;
stat_tap_ui ui_info;
ui_info.group = REGISTER_STAT_GROUP_RESPONSE_TIME;
ui_info.title = NULL; /* construct this from the protocol info? */
ui_info.cli_string = rtd_table_get_tap_string(rtd);
ui_info.tap_init_cb = dissector_rtd_init;
ui_info.nparams = 0;
ui_info.params = NULL;
register_stat_tap_ui(&ui_info, rtd);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

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

View File

@ -98,6 +98,7 @@ set(WIRESHARK_GTK_SRC
proto_hier_tree_model.c
proto_tree_model.c
range_utils.c
response_time_delay_table.c
sctp_byte_graph_dlg.c
sctp_error_dlg.c
sctp_graph_dlg.c
@ -215,11 +216,8 @@ set(WIRESHARK_TAP_SRC
lbm_uimflow_dlg.c
mac_lte_stat_dlg.c
mcast_stream_dlg.c
megaco_stat.c
mgcp_stat.c
mtp3_stat.c
mtp3_summary.c
radius_stat.c
rlc_lte_graph.c
rlc_lte_stat_dlg.c
rpc_progs.c

View File

@ -118,6 +118,7 @@ WIRESHARK_GTK_SRC = \
proto_hier_tree_model.c \
proto_tree_model.c \
range_utils.c \
response_time_delay_table.c \
rtp_player.c \
sctp_byte_graph_dlg.c \
sctp_error_dlg.c \
@ -166,11 +167,8 @@ WIRESHARK_TAP_SRC = \
lbm_uimflow_dlg.c \
mac_lte_stat_dlg.c \
mcast_stream_dlg.c \
megaco_stat.c \
mgcp_stat.c \
mtp3_stat.c \
mtp3_summary.c \
radius_stat.c \
rlc_lte_graph.c \
rlc_lte_stat_dlg.c \
rpc_progs.c \
@ -286,6 +284,7 @@ noinst_HEADERS = \
proto_hier_tree_model.h \
proto_tree_model.h \
range_utils.h \
response_time_delay_table.h \
remote_icons.h \
rtp_player.h \
rtp_stream_dlg.h \

View File

@ -194,6 +194,7 @@
#include "ui/gtk/conversations_table.h"
#include "ui/gtk/hostlist_table.h"
#include "ui/gtk/service_response_time_table.h"
#include "ui/gtk/response_time_delay_table.h"
#include "simple_dialog.h"
#include "ui/gtk/old-gtk-compat.h"
@ -2535,6 +2536,7 @@ DIAG_ON(cast-qual)
conversation_table_set_gui_info(init_conversation_table);
hostlist_table_set_gui_info(init_hostlist_table);
srt_table_iterate_tables(register_service_response_tables, NULL);
rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);

View File

@ -1,240 +0,0 @@
/* megaco_stat.c
* megaco-statistics for Wireshark
* Copyright 2003 Lars Roland
* Copyright 2008, Ericsson AB
* By Balint Reczey <balint.reczey@ericsson.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <string.h>
#include <epan/packet_info.h>
#include <epan/value_string.h>
#include <epan/tap.h>
#include "epan/gcp.h"
#include <epan/prefs-int.h>
#include "epan/timestats.h"
#include "ui/simple_dialog.h"
#include "ui/gtk/gui_stat_util.h"
#include "ui/gtk/dlg_utils.h"
#include "ui/gtk/tap_param_dlg.h"
#include "ui/gtk/gui_utils.h"
#include "ui/gtk/main.h"
#include "ui/tap-megaco-common.h"
void register_tap_listener_gtkmegacostat(void);
static void
megacostat_reset(void *pms)
{
megacostat_t *ms=(megacostat_t *)pms;
int i;
for(i=0;i<NUM_TIMESTATS;i++) {
ms->rtd[i].num=0;
ms->rtd[i].min_num=0;
ms->rtd[i].max_num=0;
ms->rtd[i].min.secs=0;
ms->rtd[i].min.nsecs=0;
ms->rtd[i].max.secs=0;
ms->rtd[i].max.nsecs=0;
ms->rtd[i].tot.secs=0;
ms->rtd[i].tot.nsecs=0;
}
ms->open_req_num=0;
ms->disc_rsp_num=0;
ms->req_dup_num=0;
ms->rsp_dup_num=0;
}
static void
megacostat_draw(void *pms)
{
megacostat_t *ms=(megacostat_t *)pms;
int i;
char str[3][256];
gchar* tmp_str;
GtkListStore *store;
GtkTreeIter iter;
/* clear list before printing */
store = GTK_LIST_STORE(gtk_tree_view_get_model(ms->table));
gtk_list_store_clear(store);
for(i=0;i<NUM_TIMESTATS;i++) {
/* nothing seen, nothing to do */
if(ms->rtd[i].num==0){
continue;
}
g_snprintf(str[0], sizeof(char[256]), "%8.2f msec", nstime_to_msec(&(ms->rtd[i].min)));
g_snprintf(str[1], sizeof(char[256]), "%8.2f msec", nstime_to_msec(&(ms->rtd[i].max)));
g_snprintf(str[2], sizeof(char[256]), "%8.2f msec", get_average(&(ms->rtd[i].tot), ms->rtd[i].num));
tmp_str = val_to_str_wmem(NULL,i,megaco_message_type,"Other (%d)");
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, tmp_str,
1, ms->rtd[i].num,
2, str[0],
3, str[1],
4, str[2],
5, ms->rtd[i].min_num,
6, ms->rtd[i].max_num,
-1);
wmem_free(NULL, tmp_str);
}
}
static void
win_destroy_cb(GtkWindow *win _U_, gpointer data)
{
megacostat_t *ms=(megacostat_t *)data;
remove_tap_listener(ms);
if(ms->filter){
g_free(ms->filter);
ms->filter=NULL;
}
g_free(ms);
}
static const stat_column titles[]={
{G_TYPE_STRING, LEFT, "Type" },
{G_TYPE_UINT, RIGHT, "Messages" },
{G_TYPE_STRING, RIGHT, "Min SRT" },
{G_TYPE_STRING, RIGHT, "Max SRT" },
{G_TYPE_STRING, RIGHT, "Avg SRT" },
{G_TYPE_UINT, RIGHT, "Min in Frame" },
{G_TYPE_UINT, RIGHT, "Max in Frame" }
};
static void
gtk_megacostat_init(const char *opt_arg, void *userdata _U_)
{
megacostat_t *ms;
GString *error_string;
GtkWidget *bt_close;
GtkWidget *bbox;
pref_t *megaco_ctx_track,*h248_ctx_track;
megaco_ctx_track = prefs_find_preference(prefs_find_module("megaco"),"ctx_info");
h248_ctx_track = prefs_find_preference(prefs_find_module("h248"),"ctx_info");
if (!megaco_ctx_track || !h248_ctx_track) {
/* No such preferences */
return;
}
if (!*megaco_ctx_track->varp.boolp || !*h248_ctx_track->varp.boolp) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Track Context option at Protocols -> MEGACO and Protocols -> H248 preferences has to be set to true to enable measurement of service response times.");
return;
}
ms=(megacostat_t *)g_malloc(sizeof(megacostat_t));
if(strncmp(opt_arg,"megaco,srt,",11) == 0){
ms->filter=g_strdup(opt_arg+11);
} else {
ms->filter=NULL;
}
megacostat_reset(ms);
ms->win = dlg_window_new("MEGACO SRT"); /* transient_for top_level */
gtk_window_set_destroy_with_parent (GTK_WINDOW(ms->win), TRUE);
gtk_window_set_default_size(GTK_WINDOW(ms->win), 550, 150);
ms->vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE);
init_main_stat_window(ms->win, ms->vbox, "MEGACO Service Response Time (SRT) Statistics", ms->filter);
/* init a scrolled window*/
ms->scrolled_window = scrolled_window_new(NULL, NULL);
ms->table = create_stat_table(ms->scrolled_window, ms->vbox, 7, titles);
error_string=register_tap_listener("megaco", ms, ms->filter, 0, megacostat_reset, megacostat_packet, megacostat_draw);
if(error_string){
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
g_string_free(error_string, TRUE);
g_free(ms->filter);
g_free(ms);
return;
}
/* Button row. */
bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
gtk_box_pack_start(GTK_BOX(ms->vbox), bbox, FALSE, FALSE, 0);
bt_close = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
window_set_cancel_button(ms->win, bt_close, window_cancel_button_cb);
g_signal_connect(ms->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
g_signal_connect(ms->win, "destroy", G_CALLBACK(win_destroy_cb), ms);
gtk_widget_show_all(ms->win);
window_present(ms->win);
cf_retap_packets(&cfile);
gdk_window_raise(gtk_widget_get_window(ms->win));
}
static tap_param megaco_srt_params[] = {
{ PARAM_FILTER, "filter", "Filter", NULL, TRUE }
};
static tap_param_dlg megaco_srt_dlg = {
"MEGACO Service Response Time (SRT) Statistics",
"megaco,srt",
gtk_megacostat_init,
-1,
G_N_ELEMENTS(megaco_srt_params),
megaco_srt_params
};
void
register_tap_listener_gtkmegacostat(void)
{
register_param_stat(&megaco_srt_dlg, "MEGACO",
REGISTER_STAT_GROUP_RESPONSE_TIME);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -1,328 +0,0 @@
/* mgcp_stat.c
* mgcp-statistics for Wireshark
* Copyright 2003 Lars Roland
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <string.h>
#include <epan/packet_info.h>
#include <epan/value_string.h>
#include <epan/tap.h>
#include "epan/dissectors/packet-mgcp.h"
#include "epan/timestats.h"
#include "ui/simple_dialog.h"
#include "ui/gtk/gui_stat_util.h"
#include "ui/gtk/dlg_utils.h"
#include "ui/gtk/tap_param_dlg.h"
#include "ui/gtk/gui_utils.h"
#include "ui/gtk/main.h"
void register_tap_listener_gtkmgcpstat(void);
#define NUM_TIMESTATS 10
/* used to keep track of the statistics for an entire program interface */
typedef struct _mgcpstat_t {
GtkWidget *win;
GtkWidget *vbox;
char *filter;
GtkWidget *scrolled_window;
GtkTreeView *table;
timestat_t rtd[NUM_TIMESTATS];
guint32 open_req_num;
guint32 disc_rsp_num;
guint32 req_dup_num;
guint32 rsp_dup_num;
} mgcpstat_t;
static const value_string mgcp_mesage_type[] = {
{ 0, "EPCF"},
{ 1, "CRCX"},
{ 2, "MDCX"},
{ 3, "DLCX"},
{ 4, "RQNT"},
{ 5, "NTFY"},
{ 6, "AUEP"},
{ 7, "AUCX"},
{ 8, "RSIP"},
{ 0, NULL}
};
static void
mgcpstat_reset(void *pms)
{
mgcpstat_t *ms=(mgcpstat_t *)pms;
int i;
for(i=0;i<NUM_TIMESTATS;i++) {
ms->rtd[i].num=0;
ms->rtd[i].min_num=0;
ms->rtd[i].max_num=0;
ms->rtd[i].min.secs=0;
ms->rtd[i].min.nsecs=0;
ms->rtd[i].max.secs=0;
ms->rtd[i].max.nsecs=0;
ms->rtd[i].tot.secs=0;
ms->rtd[i].tot.nsecs=0;
}
ms->open_req_num=0;
ms->disc_rsp_num=0;
ms->req_dup_num=0;
ms->rsp_dup_num=0;
}
static int
mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pmi)
{
mgcpstat_t *ms=(mgcpstat_t *)pms;
const mgcp_info_t *mi=(mgcp_info_t *)pmi;
nstime_t delta;
int ret = 0;
switch (mi->mgcp_type) {
case MGCP_REQUEST:
if(mi->is_duplicate){
/* Duplicate is ignored */
ms->req_dup_num++;
}
else {
ms->open_req_num++;
}
break;
case MGCP_RESPONSE:
if(mi->is_duplicate){
/* Duplicate is ignored */
ms->rsp_dup_num++;
}
else if (!mi->request_available) {
/* no request was seen */
ms->disc_rsp_num++;
}
else {
ms->open_req_num--;
/* calculate time delta between request and response */
nstime_delta(&delta, &pinfo->fd->abs_ts, &mi->req_time);
if (g_ascii_strncasecmp(mi->code, "EPCF", 4) == 0 ) {
time_stat_update(&(ms->rtd[0]),&delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "CRCX", 4) == 0 ) {
time_stat_update(&(ms->rtd[1]),&delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "MDCX", 4) == 0 ) {
time_stat_update(&(ms->rtd[2]),&delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "DLCX", 4) == 0 ) {
time_stat_update(&(ms->rtd[3]),&delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "RQNT", 4) == 0 ) {
time_stat_update(&(ms->rtd[4]),&delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "NTFY", 4) == 0 ) {
time_stat_update(&(ms->rtd[5]),&delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "AUEP", 4) == 0 ) {
time_stat_update(&(ms->rtd[6]),&delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "AUCX", 4) == 0 ) {
time_stat_update(&(ms->rtd[7]),&delta, pinfo);
}
else if (g_ascii_strncasecmp(mi->code, "RSIP", 4) == 0 ) {
time_stat_update(&(ms->rtd[8]),&delta, pinfo);
}
else {
time_stat_update(&(ms->rtd[9]),&delta, pinfo);
}
ret = 1;
}
break;
default:
break;
}
return ret;
}
static void
mgcpstat_draw(void *pms)
{
mgcpstat_t *ms=(mgcpstat_t *)pms;
int i;
char str[3][256];
gchar* tmp_str;
GtkListStore *store;
GtkTreeIter iter;
/* clear list before printing */
store = GTK_LIST_STORE(gtk_tree_view_get_model(ms->table));
gtk_list_store_clear(store);
for(i=0;i<NUM_TIMESTATS;i++) {
/* nothing seen, nothing to do */
if(ms->rtd[i].num==0){
continue;
}
g_snprintf(str[0], sizeof(char[256]), "%8.2f msec", nstime_to_msec(&(ms->rtd[i].min)));
g_snprintf(str[1], sizeof(char[256]), "%8.2f msec", nstime_to_msec(&(ms->rtd[i].max)));
g_snprintf(str[2], sizeof(char[256]), "%8.2f msec", get_average(&(ms->rtd[i].tot), ms->rtd[i].num));
tmp_str = val_to_str_wmem(NULL,i,mgcp_mesage_type,"Other (%d)");
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, tmp_str,
1, ms->rtd[i].num,
2, str[0],
3, str[1],
4, str[2],
5, ms->rtd[i].min_num,
6, ms->rtd[i].max_num,
-1);
wmem_free(NULL, tmp_str);
}
}
static void
win_destroy_cb(GtkWindow *win _U_, gpointer data)
{
mgcpstat_t *ms=(mgcpstat_t *)data;
remove_tap_listener(ms);
if(ms->filter){
g_free(ms->filter);
ms->filter=NULL;
}
g_free(ms);
}
static const stat_column titles[]={
{G_TYPE_STRING, LEFT, "Type" },
{G_TYPE_UINT, RIGHT, "Messages" },
{G_TYPE_STRING, RIGHT, "Min SRT" },
{G_TYPE_STRING, RIGHT, "Max SRT" },
{G_TYPE_STRING, RIGHT, "Avg SRT" },
{G_TYPE_UINT, RIGHT, "Min in Frame" },
{G_TYPE_UINT, RIGHT, "Max in Frame" }
};
static void
gtk_mgcpstat_init(const char *opt_arg, void *userdata _U_)
{
mgcpstat_t *ms;
GString *error_string;
GtkWidget *bt_close;
GtkWidget *bbox;
ms=(mgcpstat_t *)g_malloc(sizeof(mgcpstat_t));
if(strncmp(opt_arg,"mgcp,srt,",9) == 0){
ms->filter=g_strdup(opt_arg+9);
} else {
ms->filter=NULL;
}
mgcpstat_reset(ms);
ms->win = dlg_window_new("MGCP SRT"); /* transient_for top_level */
gtk_window_set_destroy_with_parent (GTK_WINDOW(ms->win), TRUE);
gtk_window_set_default_size(GTK_WINDOW(ms->win), 550, 150);
ms->vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
init_main_stat_window(ms->win, ms->vbox, "MGCP Service Response Time (SRT) Statistics", ms->filter);
/* init a scrolled window*/
ms->scrolled_window = scrolled_window_new(NULL, NULL);
ms->table = create_stat_table(ms->scrolled_window, ms->vbox, 7, titles);
error_string=register_tap_listener("mgcp", ms, ms->filter, 0, mgcpstat_reset, mgcpstat_packet, mgcpstat_draw);
if(error_string){
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
g_string_free(error_string, TRUE);
g_free(ms->filter);
g_free(ms);
return;
}
/* Button row. */
bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
gtk_box_pack_start(GTK_BOX(ms->vbox), bbox, FALSE, FALSE, 0);
bt_close = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
window_set_cancel_button(ms->win, bt_close, window_cancel_button_cb);
g_signal_connect(ms->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
g_signal_connect(ms->win, "destroy", G_CALLBACK(win_destroy_cb), ms);
gtk_widget_show_all(ms->win);
window_present(ms->win);
cf_retap_packets(&cfile);
gdk_window_raise(gtk_widget_get_window(ms->win));
}
static tap_param mgcp_srt_params[] = {
{ PARAM_FILTER, "filter", "Filter", NULL, TRUE }
};
static tap_param_dlg mgcp_srt_dlg = {
"MGCP Service Response Time (SRT) Statistics",
"mgcp,srt",
gtk_mgcpstat_init,
-1,
G_N_ELEMENTS(mgcp_srt_params),
mgcp_srt_params
};
void
register_tap_listener_gtkmgcpstat(void)
{
register_param_stat(&mgcp_srt_dlg, "MGCP",
REGISTER_STAT_GROUP_RESPONSE_TIME);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -1,396 +0,0 @@
/* radius_stat.c
* radius-statistics for Wireshark
* Copyright 2006 Alejandro Vaquero <alejandrovaquero@yahoo.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <string.h>
#include <epan/packet_info.h>
#include <epan/value_string.h>
#include <epan/tap.h>
#include <epan/dissectors/packet-radius.h>
#include "epan/timestats.h"
#include "ui/simple_dialog.h"
#include "ui/gtk/gui_stat_util.h"
#include "ui/gtk/dlg_utils.h"
#include "ui/gtk/tap_param_dlg.h"
#include "ui/gtk/gui_utils.h"
#include "ui/gtk/main.h"
void register_tap_listener_gtkradiusstat(void);
#define NUM_COLUMNS 11
typedef enum _radius_category {
RADIUS_CAT_OVERALL = 0,
RADIUS_CAT_ACCESS,
RADIUS_CAT_ACCOUNTING,
RADIUS_CAT_PASSWORD,
RADIUS_CAT_RESOURCE_FREE,
RADIUS_CAT_RESOURCE_QUERY,
RADIUS_CAT_NAS_REBOOT,
RADIUS_CAT_EVENT,
RADIUS_CAT_DISCONNECT,
RADIUS_CAT_COA,
RADIUS_CAT_OTHERS,
RADIUS_CAT_NUM_TIMESTATS
} radius_category;
/* Summary of response-time calculations*/
typedef struct _radius_rtd_t {
guint32 open_req_num;
guint32 disc_rsp_num;
guint32 req_dup_num;
guint32 rsp_dup_num;
timestat_t stats;
} radius_rtd_t;
/* used to keep track of the statistics for an entire program interface */
typedef struct _radiusstat_t {
GtkWidget *win;
GtkWidget *vbox;
char *filter;
GtkWidget *scrolled_window;
GtkTreeView *table;
radius_rtd_t radius_rtd[RADIUS_CAT_NUM_TIMESTATS];
} radiusstat_t;
static const value_string radius_message_code[] = {
{ RADIUS_CAT_OVERALL, "Overall"},
{ RADIUS_CAT_ACCESS, "Access"},
{ RADIUS_CAT_ACCOUNTING, "Accounting"},
{ RADIUS_CAT_PASSWORD, "Password"},
{ RADIUS_CAT_RESOURCE_FREE, "Resource Free"},
{ RADIUS_CAT_RESOURCE_QUERY, "Resource Query"},
{ RADIUS_CAT_NAS_REBOOT, "NAS Reboot"},
{ RADIUS_CAT_EVENT, "Event"},
{ RADIUS_CAT_DISCONNECT, "Disconnect"},
{ RADIUS_CAT_COA, "CoA"},
{ RADIUS_CAT_OTHERS, "Other"},
{ 0, NULL}
};
static void
radiusstat_reset(void *prs)
{
radiusstat_t *rs=(radiusstat_t *)prs;
int i;
for(i=0; i<RADIUS_CAT_NUM_TIMESTATS; i++) {
rs->radius_rtd[i].stats.num=0;
rs->radius_rtd[i].stats.min_num=0;
rs->radius_rtd[i].stats.max_num=0;
rs->radius_rtd[i].stats.min.secs=0;
rs->radius_rtd[i].stats.min.nsecs=0;
rs->radius_rtd[i].stats.max.secs=0;
rs->radius_rtd[i].stats.max.nsecs=0;
rs->radius_rtd[i].stats.tot.secs=0;
rs->radius_rtd[i].stats.tot.nsecs=0;
rs->radius_rtd[i].open_req_num = 0;
rs->radius_rtd[i].disc_rsp_num = 0;
rs->radius_rtd[i].req_dup_num = 0;
rs->radius_rtd[i].rsp_dup_num = 0;
}
}
static int
radiusstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pri)
{
radiusstat_t *rs=(radiusstat_t *)prs;
const radius_info_t *ri=(radius_info_t *)pri;
nstime_t delta;
radius_category radius_cat = RADIUS_CAT_OTHERS;
int ret = 0;
switch (ri->code) {
case RADIUS_PKT_TYPE_ACCESS_REQUEST:
case RADIUS_PKT_TYPE_ACCESS_ACCEPT:
case RADIUS_PKT_TYPE_ACCESS_REJECT:
radius_cat = RADIUS_CAT_ACCESS;
break;
case RADIUS_PKT_TYPE_ACCOUNTING_REQUEST:
case RADIUS_PKT_TYPE_ACCOUNTING_RESPONSE:
radius_cat = RADIUS_CAT_ACCOUNTING;
break;
case RADIUS_PKT_TYPE_PASSWORD_REQUEST:
case RADIUS_PKT_TYPE_PASSWORD_ACK:
case RADIUS_PKT_TYPE_PASSWORD_REJECT:
radius_cat = RADIUS_CAT_PASSWORD;
break;
case RADIUS_PKT_TYPE_RESOURCE_FREE_REQUEST:
case RADIUS_PKT_TYPE_RESOURCE_FREE_RESPONSE:
radius_cat = RADIUS_CAT_RESOURCE_FREE;
break;
case RADIUS_PKT_TYPE_RESOURCE_QUERY_REQUEST:
case RADIUS_PKT_TYPE_RESOURCE_QUERY_RESPONSE:
radius_cat = RADIUS_CAT_RESOURCE_QUERY;
break;
case RADIUS_PKT_TYPE_NAS_REBOOT_REQUEST:
case RADIUS_PKT_TYPE_NAS_REBOOT_RESPONSE:
radius_cat = RADIUS_CAT_NAS_REBOOT;
break;
case RADIUS_PKT_TYPE_EVENT_REQUEST:
case RADIUS_PKT_TYPE_EVENT_RESPONSE:
radius_cat = RADIUS_CAT_EVENT;
break;
case RADIUS_PKT_TYPE_DISCONNECT_REQUEST:
case RADIUS_PKT_TYPE_DISCONNECT_ACK:
case RADIUS_PKT_TYPE_DISCONNECT_NAK:
radius_cat = RADIUS_CAT_DISCONNECT;
break;
case RADIUS_PKT_TYPE_COA_REQUEST:
case RADIUS_PKT_TYPE_COA_ACK:
case RADIUS_PKT_TYPE_COA_NAK:
radius_cat = RADIUS_CAT_COA;
break;
}
switch (ri->code) {
case RADIUS_PKT_TYPE_ACCESS_REQUEST:
case RADIUS_PKT_TYPE_ACCOUNTING_REQUEST:
case RADIUS_PKT_TYPE_PASSWORD_REQUEST:
case RADIUS_PKT_TYPE_EVENT_REQUEST:
case RADIUS_PKT_TYPE_DISCONNECT_REQUEST:
case RADIUS_PKT_TYPE_COA_REQUEST:
if(ri->is_duplicate){
/* Duplicate is ignored */
rs->radius_rtd[RADIUS_CAT_OVERALL].req_dup_num++;
rs->radius_rtd[radius_cat].req_dup_num++;
}
else {
rs->radius_rtd[RADIUS_CAT_OVERALL].open_req_num++;
rs->radius_rtd[radius_cat].open_req_num++;
}
break;
case RADIUS_PKT_TYPE_ACCESS_ACCEPT:
case RADIUS_PKT_TYPE_ACCESS_REJECT:
case RADIUS_PKT_TYPE_ACCOUNTING_RESPONSE:
case RADIUS_PKT_TYPE_PASSWORD_ACK:
case RADIUS_PKT_TYPE_PASSWORD_REJECT:
case RADIUS_PKT_TYPE_EVENT_RESPONSE:
case RADIUS_PKT_TYPE_DISCONNECT_ACK:
case RADIUS_PKT_TYPE_DISCONNECT_NAK:
case RADIUS_PKT_TYPE_COA_ACK:
case RADIUS_PKT_TYPE_COA_NAK:
if(ri->is_duplicate){
/* Duplicate is ignored */
rs->radius_rtd[RADIUS_CAT_OVERALL].rsp_dup_num++;
rs->radius_rtd[radius_cat].rsp_dup_num++;
}
else if (!ri->request_available) {
/* no request was seen */
rs->radius_rtd[RADIUS_CAT_OVERALL].disc_rsp_num++;
rs->radius_rtd[radius_cat].disc_rsp_num++;
}
else {
rs->radius_rtd[RADIUS_CAT_OVERALL].open_req_num--;
rs->radius_rtd[radius_cat].open_req_num--;
/* calculate time delta between request and response */
nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->req_time);
time_stat_update(&(rs->radius_rtd[RADIUS_CAT_OVERALL].stats),&delta, pinfo);
time_stat_update(&(rs->radius_rtd[radius_cat].stats),&delta, pinfo);
ret = 1;
}
break;
default:
break;
}
return ret;
}
static void
radiusstat_draw(void *prs)
{
radiusstat_t *rs=(radiusstat_t *)prs;
int i;
char str[5][256];
gchar* tmp_str;
GtkListStore *store;
GtkTreeIter iter;
/* clear list before printing */
store = GTK_LIST_STORE(gtk_tree_view_get_model(rs->table));
gtk_list_store_clear(store);
for(i=0; i<RADIUS_CAT_NUM_TIMESTATS; i++) {
/* nothing seen, nothing to do */
if(rs->radius_rtd[i].stats.num==0){
continue;
}
g_snprintf(str[0], 256, "%8.2f msec", nstime_to_msec(&(rs->radius_rtd[i].stats.min)));
g_snprintf(str[1], 256, "%8.2f msec", nstime_to_msec(&(rs->radius_rtd[i].stats.max)));
g_snprintf(str[2], 256, "%8.2f msec", get_average(&(rs->radius_rtd[i].stats.tot), rs->radius_rtd[i].stats.num));
g_snprintf(str[3], 256, "%4u (%4.2f%%)", rs->radius_rtd[i].req_dup_num,
rs->radius_rtd[i].stats.num?((double)rs->radius_rtd[i].req_dup_num*100)/(double)rs->radius_rtd[i].stats.num:0);
g_snprintf(str[4], 256, "%4u (%4.2f%%)", rs->radius_rtd[i].rsp_dup_num,
rs->radius_rtd[i].stats.num?((double)rs->radius_rtd[i].rsp_dup_num*100)/(double)rs->radius_rtd[i].stats.num:0);
tmp_str = val_to_str_wmem(NULL,i,radius_message_code,"Other (%d)");
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, tmp_str,
1, rs->radius_rtd[i].stats.num,
2, str[0],
3, str[1],
4, str[2],
5, rs->radius_rtd[i].stats.min_num,
6, rs->radius_rtd[i].stats.max_num,
7, rs->radius_rtd[i].open_req_num,
8, rs->radius_rtd[i].disc_rsp_num,
9, str[3],
10, str[4],
-1);
wmem_free(NULL, tmp_str);
}
}
static void
win_destroy_cb(GtkWindow *win _U_, gpointer data)
{
radiusstat_t *rs=(radiusstat_t *)data;
remove_tap_listener(rs);
if(rs->filter){
g_free(rs->filter);
rs->filter=NULL;
}
g_free(rs);
}
static const stat_column titles[]={
{G_TYPE_STRING, LEFT, "Type" },
{G_TYPE_UINT, RIGHT, "Messages" },
{G_TYPE_STRING, RIGHT, "Min SRT" },
{G_TYPE_STRING, RIGHT, "Max SRT" },
{G_TYPE_STRING, RIGHT, "Avg SRT" },
{G_TYPE_UINT, RIGHT, "Min in Frame" },
{G_TYPE_UINT, RIGHT, "Max in Frame" },
{G_TYPE_UINT, RIGHT, "Open Requests" },
{G_TYPE_UINT, RIGHT, "Discarded Responses" },
{G_TYPE_STRING, RIGHT, "Repeated Requests" },
{G_TYPE_STRING, RIGHT, "Repeated Responses"}
};
static void
gtk_radiusstat_init(const char *opt_arg, void *userdata _U_)
{
radiusstat_t *rs;
GString *error_string;
GtkWidget *bt_close;
GtkWidget *bbox;
rs=(radiusstat_t *)g_malloc(sizeof(radiusstat_t));
if(strncmp(opt_arg,"radius,srt,",11) == 0){
rs->filter=g_strdup(opt_arg+11);
} else {
rs->filter=NULL;
}
radiusstat_reset(rs);
rs->win = dlg_window_new("RADIUS SRT"); /* transient_for top_level */
gtk_window_set_destroy_with_parent (GTK_WINDOW(rs->win), TRUE);
gtk_window_set_default_size(GTK_WINDOW(rs->win), 600, 150);
rs->vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
init_main_stat_window(rs->win, rs->vbox, "RADIUS Service Response Time (SRT) Statistics", rs->filter);
/* init a scrolled window*/
rs->scrolled_window = scrolled_window_new(NULL, NULL);
rs->table = create_stat_table(rs->scrolled_window, rs->vbox, NUM_COLUMNS, titles);
error_string=register_tap_listener("radius", rs, rs->filter, 0, radiusstat_reset, radiusstat_packet, radiusstat_draw);
if(error_string){
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
g_string_free(error_string, TRUE);
g_free(rs->filter);
g_free(rs);
return;
}
/* Button row. */
bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
gtk_box_pack_start(GTK_BOX(rs->vbox), bbox, FALSE, FALSE, 0);
bt_close = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
window_set_cancel_button(rs->win, bt_close, window_cancel_button_cb);
g_signal_connect(rs->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
g_signal_connect(rs->win, "destroy", G_CALLBACK(win_destroy_cb), rs);
gtk_widget_show_all(rs->win);
window_present(rs->win);
cf_retap_packets(&cfile);
gdk_window_raise(gtk_widget_get_window(rs->win));
}
static tap_param radius_stat_params[] = {
{ PARAM_FILTER, "filter", "Filter", NULL, TRUE }
};
static tap_param_dlg radius_srt_dlg = {
"RADIUS Service Response Time (SRT) Statistics",
"radius,srt",
gtk_radiusstat_init,
-1,
G_N_ELEMENTS(radius_stat_params),
radius_stat_params
};
void
register_tap_listener_gtkradiusstat(void)
{
register_param_stat(&radius_srt_dlg, "RADIUS",
REGISTER_STAT_GROUP_RESPONSE_TIME);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -0,0 +1,392 @@
/* response_time_delay_table.c
*
* Based on 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.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "epan/packet_info.h"
#include "epan/proto.h"
#include "ui/simple_dialog.h"
#include "ui/utf8_entities.h"
#include "ui/gtk/filter_utils.h"
#include "ui/gtk/gui_stat_util.h"
#include "ui/gtk/gui_utils.h"
#include "ui/gtk/dlg_utils.h"
#include "ui/gtk/response_time_delay_table.h"
#include "ui/gtk/tap_param_dlg.h"
#include "ui/gtk/main.h"
enum
{
TYPE_COLUMN,
MESSAGES_COLUMN,
MIN_SRT_COLUMN,
MAX_SRT_COLUMN,
AVG_SRT_COLUMN,
MIN_FRAME_COLUMN,
MAX_FRAME_COLUMN,
OPEN_REQUESTS_COLUMN,
DISCARDED_RESPONSES_COLUMN,
REPEATED_REQUESTS_COLUMN,
REPEATED_RESPONSES_COLUMN
};
static const stat_column titles[]={
{G_TYPE_STRING, LEFT, "Type" },
{G_TYPE_UINT, RIGHT, "Messages" },
{G_TYPE_STRING, RIGHT, "Min SRT" },
{G_TYPE_STRING, RIGHT, "Max SRT" },
{G_TYPE_STRING, RIGHT, "Avg SRT" },
{G_TYPE_UINT, RIGHT, "Min in Frame" },
{G_TYPE_UINT, RIGHT, "Max in Frame" }
};
static const stat_column titles_more[]={
{G_TYPE_STRING, LEFT, "Type" },
{G_TYPE_UINT, RIGHT, "Messages" },
{G_TYPE_STRING, RIGHT, "Min SRT" },
{G_TYPE_STRING, RIGHT, "Max SRT" },
{G_TYPE_STRING, RIGHT, "Avg SRT" },
{G_TYPE_UINT, RIGHT, "Min in Frame" },
{G_TYPE_UINT, RIGHT, "Max in Frame" },
{G_TYPE_UINT, RIGHT, "Open Requests" },
{G_TYPE_UINT, RIGHT, "Discarded Responses" },
{G_TYPE_STRING, RIGHT, "Repeated Requests" },
{G_TYPE_STRING, RIGHT, "Repeated Responses"}
};
typedef struct _gtk_rtd_t {
GtkWidget *vbox;
GtkWidget *win;
GtkTreeView *table; /**< Tree view */
GtkWidget *scrolled_window; /**< window widget */
GtkWidget *menu; /**< context menu */
GtkWidget *open_req_label;
GtkWidget *dis_rsp_label;
GtkWidget *repeat_req_label;
GtkWidget *repeat_rsp_label;
} gtk_rtd_t;
typedef struct _rtd_t {
const char *type;
const char *filter;
gtk_rtd_t gtk_data;
register_rtd_t* rtd;
rtd_data_t data;
} rtd_t;
static void
rtd_set_title(rtd_t *rr)
{
gchar *str;
str = g_strdup_printf("%s Service Response Time statistics", proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rr->rtd))));
set_window_title(rr->gtk_data.win, str);
g_free(str);
}
static void
win_destroy_cb(GtkWindow *win _U_, gpointer data)
{
rtd_t *rr = (rtd_t*)data;
remove_tap_listener(&rr->data);
free_rtd_table(rr->rtd, &rr->data.stat_table, NULL, NULL);
g_free(rr);
}
static void
init_gtk_rtd_table(rtd_stat_table* rtd, void* gui_data)
{
gtk_rtd_t* gtk_data = (gtk_rtd_t*)gui_data;
if (rtd->num_rtds == 1)
{
gtk_window_set_default_size(GTK_WINDOW(gtk_data->win), RTD_PREFERRED_WIDTH, 300);
gtk_data->open_req_label = gtk_label_new("Open Requests: 0");
gtk_box_pack_start(GTK_BOX(gtk_data->vbox), gtk_data->open_req_label, FALSE, FALSE, 0);
gtk_widget_show(gtk_data->open_req_label);
gtk_data->dis_rsp_label = gtk_label_new("Discarded Responses: 0");
gtk_box_pack_start(GTK_BOX(gtk_data->vbox), gtk_data->dis_rsp_label, FALSE, FALSE, 0);
gtk_widget_show(gtk_data->dis_rsp_label);
gtk_data->repeat_req_label = gtk_label_new("Repeated Requests: 0");
gtk_box_pack_start(GTK_BOX(gtk_data->vbox), gtk_data->repeat_req_label, FALSE, FALSE, 0);
gtk_widget_show(gtk_data->repeat_req_label);
gtk_data->repeat_rsp_label = gtk_label_new("Repeated Responses: 0");
gtk_box_pack_start(GTK_BOX(gtk_data->vbox), gtk_data->repeat_rsp_label, FALSE, FALSE, 0);
gtk_widget_show(gtk_data->repeat_rsp_label);
gtk_data->table = create_stat_table(gtk_data->scrolled_window, gtk_data->vbox, 7, titles);
}
else
{
gtk_window_set_default_size(GTK_WINDOW(gtk_data->win), RTD_PREFERRED_WIDTH+100, 200);
gtk_data->table = create_stat_table(gtk_data->scrolled_window, gtk_data->vbox, 11, titles_more);
}
}
static void
rtd_draw(void *arg)
{
GtkListStore *store;
rtd_data_t* rtd_data = (rtd_data_t*)arg;
rtd_t* rtd = (rtd_t*)rtd_data->user_data;
rtd_timestat *ms;
GtkTreeIter iter;
char str[5][256];
gchar* tmp_str;
guint i, j;
char label_str[256];
/* clear list before printing */
store = GTK_LIST_STORE(gtk_tree_view_get_model(rtd->gtk_data.table));
gtk_list_store_clear(store);
if (rtd_data->stat_table.num_rtds == 1)
{
ms = &rtd_data->stat_table.time_stats[0];
g_snprintf(label_str, sizeof(char[256]), "Open Requests: %u", ms->open_req_num);
gtk_label_set_text(GTK_LABEL(rtd->gtk_data.open_req_label), label_str);
g_snprintf(label_str, sizeof(char[256]), "Discarded Responses: %u", ms->disc_rsp_num);
gtk_label_set_text(GTK_LABEL(rtd->gtk_data.dis_rsp_label), label_str);
g_snprintf(label_str, sizeof(char[256]), "Repeated Requests: %u", ms->req_dup_num);
gtk_label_set_text(GTK_LABEL(rtd->gtk_data.repeat_req_label), label_str);
g_snprintf(label_str, sizeof(char[256]), "Repeated Responses: %u", ms->rsp_dup_num);
gtk_label_set_text(GTK_LABEL(rtd->gtk_data.repeat_rsp_label), label_str);
for(i=0;i<ms->num_timestat;i++)
{
/* nothing seen, nothing to do */
if(ms->rtd[i].num==0){
continue;
}
g_snprintf(str[0], sizeof(char[256]), "%8.2f msec", nstime_to_msec(&(ms->rtd[i].min)));
g_snprintf(str[1], sizeof(char[256]), "%8.2f msec", nstime_to_msec(&(ms->rtd[i].max)));
g_snprintf(str[2], sizeof(char[256]), "%8.2f msec", get_average(&(ms->rtd[i].tot), ms->rtd[i].num));
tmp_str = val_to_str_wmem(NULL, i, get_rtd_value_string(rtd->rtd), "Other (%d)");
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
TYPE_COLUMN, tmp_str,
MESSAGES_COLUMN, ms->rtd[i].num,
MIN_SRT_COLUMN, str[0],
MAX_SRT_COLUMN, str[1],
AVG_SRT_COLUMN, str[2],
MIN_FRAME_COLUMN, ms->rtd[i].min_num,
MAX_FRAME_COLUMN, ms->rtd[i].max_num,
-1);
wmem_free(NULL, tmp_str);
}
}
else
{
for (i=0; i<rtd_data->stat_table.num_rtds; i++)
{
for (j=0; j<rtd_data->stat_table.time_stats[i].num_timestat; j++)
{
/* nothing seen, nothing to do */
if(rtd_data->stat_table.time_stats[i].rtd[j].num==0){
continue;
}
g_snprintf(str[0], 256, "%8.2f msec", nstime_to_msec(&(rtd_data->stat_table.time_stats[i].rtd[j].min)));
g_snprintf(str[1], 256, "%8.2f msec", nstime_to_msec(&(rtd_data->stat_table.time_stats[i].rtd[j].max)));
g_snprintf(str[2], 256, "%8.2f msec", get_average(&(rtd_data->stat_table.time_stats[i].rtd[j].tot), rtd_data->stat_table.time_stats[i].rtd[j].num));
g_snprintf(str[3], 256, "%4u (%4.2f%%)", rtd_data->stat_table.time_stats[i].req_dup_num,
rtd_data->stat_table.time_stats[i].rtd[j].num?((double)rtd_data->stat_table.time_stats[i].req_dup_num*100)/(double)rtd_data->stat_table.time_stats[i].rtd[j].num:0);
g_snprintf(str[4], 256, "%4u (%4.2f%%)", rtd_data->stat_table.time_stats[i].rsp_dup_num,
rtd_data->stat_table.time_stats[i].rtd[j].num?((double)rtd_data->stat_table.time_stats[i].rsp_dup_num*100)/(double)rtd_data->stat_table.time_stats[i].rtd[j].num:0);
tmp_str = val_to_str_wmem(NULL, i, get_rtd_value_string(rtd->rtd), "Other (%d)");
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
TYPE_COLUMN, tmp_str,
MESSAGES_COLUMN, rtd_data->stat_table.time_stats[i].rtd[j].num,
MIN_SRT_COLUMN, str[0],
MAX_SRT_COLUMN, str[1],
AVG_SRT_COLUMN, str[2],
MIN_FRAME_COLUMN, rtd_data->stat_table.time_stats[i].rtd[j].min_num,
MAX_FRAME_COLUMN, rtd_data->stat_table.time_stats[i].rtd[j].max_num,
OPEN_REQUESTS_COLUMN, rtd_data->stat_table.time_stats[i].open_req_num,
DISCARDED_RESPONSES_COLUMN, rtd_data->stat_table.time_stats[i].disc_rsp_num,
REPEATED_REQUESTS_COLUMN, str[3],
REPEATED_RESPONSES_COLUMN, str[4],
-1);
wmem_free(NULL, tmp_str);
}
}
}
}
static void
reset_table_data(rtd_stat_table* table _U_, void* gui_data)
{
GtkListStore *store;
gtk_rtd_t* gtk_data = (gtk_rtd_t*)gui_data;
store = GTK_LIST_STORE(gtk_tree_view_get_model(gtk_data->table));
gtk_list_store_clear(store);
}
static void
rtd_reset(void *arg)
{
rtd_data_t *rtd = (rtd_data_t*)arg;
rtd_t *rr = (rtd_t *)rtd->user_data;
reset_rtd_table(&rtd->stat_table, reset_table_data, &rr->gtk_data);
rtd_set_title(rr);
}
static void
init_rtd_tables(register_rtd_t* rtd, const char *filter)
{
rtd_t *rr;
gchar *str;
GString *error_string;
GtkWidget *bbox;
GtkWidget *close_bt;
rr = g_new0(rtd_t, 1);
str = g_strdup_printf("%s SRT", proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd))));
rr->gtk_data.win=dlg_window_new(str); /* transient_for top_level */
g_free(str);
gtk_window_set_destroy_with_parent (GTK_WINDOW(rr->gtk_data.win), TRUE);
rr->gtk_data.vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
str = g_strdup_printf("%s Service Response Time statistics", proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd))));
init_main_stat_window(rr->gtk_data.win, rr->gtk_data.vbox, str, filter);
g_free(str);
/* init a scrolled window*/
rr->gtk_data.scrolled_window = scrolled_window_new(NULL, NULL);
rr->type = proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)));
rr->filter = g_strdup(filter);
rr->rtd = rtd;
rr->data.user_data = rr;
rtd_table_dissector_init(rtd, &rr->data.stat_table, init_gtk_rtd_table, &rr->gtk_data);
error_string = register_tap_listener(get_rtd_tap_listener_name(rtd), &rr->data, filter, 0, rtd_reset, get_rtd_packet_func(rtd), rtd_draw);
if(error_string){
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
g_string_free(error_string, TRUE);
free_rtd_table(rr->rtd, &rr->data.stat_table, NULL, NULL);
g_free(rr);
return;
}
/* Button row. */
bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
gtk_box_pack_end(GTK_BOX(rr->gtk_data.vbox), bbox, FALSE, FALSE, 0);
close_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
window_set_cancel_button(rr->gtk_data.win, close_bt, window_cancel_button_cb);
g_signal_connect(rr->gtk_data.win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
g_signal_connect(rr->gtk_data.win, "destroy", G_CALLBACK(win_destroy_cb), rr);
gtk_widget_show_all(rr->gtk_data.win);
window_present(rr->gtk_data.win);
cf_retap_packets(&cfile);
gdk_window_raise(gtk_widget_get_window(rr->gtk_data.win));
}
static void
gtk_rtdstat_init(const char *opt_arg, void *userdata _U_)
{
gchar** dissector_name;
register_rtd_t *rtd;
const char *filter=NULL;
char* err;
/* Use first comma to find dissector name */
dissector_name = g_strsplit(opt_arg, ",", -1);
g_assert(dissector_name[0]);
/* Use dissector name to find SRT table */
rtd = get_rtd_table_by_name(dissector_name[0]);
g_assert(rtd);
rtd_table_get_filter(rtd, opt_arg, &filter, &err);
if (err != NULL)
{
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err);
g_free(err);
return;
}
init_rtd_tables(rtd, filter);
}
static tap_param rtd_stat_params[] = {
{ PARAM_FILTER, "filter", "Filter", NULL, TRUE }
};
void register_response_time_delay_tables(gpointer data, gpointer user_data _U_)
{
register_rtd_t* rtd = (register_rtd_t*)data;
const char* short_name = proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)));
tap_param_dlg* rtd_dlg;
rtd_dlg = g_new(tap_param_dlg, 1);
rtd_dlg->win_title = g_strdup_printf("%s RTD Statistics", short_name);
rtd_dlg->init_string = rtd_table_get_tap_string(rtd);
rtd_dlg->tap_init_cb = gtk_rtdstat_init;
rtd_dlg->index = -1;
rtd_dlg->nparams = G_N_ELEMENTS(rtd_stat_params);
rtd_dlg->params = rtd_stat_params;
register_param_stat(rtd_dlg, short_name, REGISTER_STAT_GROUP_RESPONSE_TIME);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

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

View File

@ -1,198 +0,0 @@
/* megaco_stat.c
* megaco-statistics for Wireshark
* Copyright 2003 Lars Roland
* Copyright 2008 Ericsson AB
* By Balint Reczey <balint.reczey@ericsson.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <string.h>
#include <epan/packet_info.h>
#include <epan/value_string.h>
#include "epan/gcp.h"
#include "epan/timestats.h"
#include "globals.h"
#include "tap-megaco-common.h"
static gboolean
megacostat_is_duplicate_reply(const gcp_cmd_t* cmd)
{
switch (cmd->type) {
GCP_CMD_REPLY_CASE
{
gcp_cmd_msg_t *cmd_msg;
/* cycle through commands to find same command in the transaction */
for (cmd_msg = cmd->trx->cmds;
(cmd_msg != NULL) && (cmd_msg->cmd->msg->framenum != cmd->msg->framenum);
cmd_msg = cmd_msg->next) {
if (cmd_msg->cmd->type == cmd->type)
return TRUE;
}
return FALSE;
}
break;
default:
return FALSE;
break;
}
}
static gboolean
megacostat_had_request(const gcp_cmd_t* cmd)
{
switch (cmd->type) {
GCP_CMD_REPLY_CASE
{
gcp_cmd_msg_t *cmd_msg;
/* cycle through commands to find a request in the transaction */
for (cmd_msg = cmd->trx->cmds;
(cmd_msg != NULL) && (cmd_msg->cmd->msg->framenum != cmd->msg->framenum);
cmd_msg = cmd_msg->next) {
switch (cmd_msg->cmd->type) {
GCP_CMD_REQ_CASE
return TRUE;
break;
default:
return FALSE;
break;
}
}
return FALSE;
}
break;
default:
return FALSE;
break;
}
}
int
megacostat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pmi)
{
megacostat_t *ms=(megacostat_t *)pms;
const gcp_cmd_t *mi=(const gcp_cmd_t*)pmi;
nstime_t delta;
int ret = 0;
switch (mi->type) {
GCP_CMD_REQ_CASE
if(!mi->trx->initial) {
/* Track Context is probably disabled, we cannot
* measure service response time */
return 0;
}
else if(mi->trx->initial->framenum != mi->msg->framenum){
/* Duplicate is ignored */
ms->req_dup_num++;
}
else {
ms->open_req_num++;
}
break;
GCP_CMD_REPLY_CASE
if(megacostat_is_duplicate_reply(mi)){
/* Duplicate is ignored */
ms->rsp_dup_num++;
}
else if (!megacostat_had_request(mi)) {
/* no request was seen */
ms->disc_rsp_num++;
}
else {
ms->open_req_num--;
/* calculate time delta between request and response */
nstime_delta(&delta, &pinfo->fd->abs_ts, &mi->trx->initial->time);
switch(mi->type) {
case GCP_CMD_ADD_REPLY:
time_stat_update(&(ms->rtd[0]),&delta, pinfo);
break;
case GCP_CMD_MOVE_REPLY:
time_stat_update(&(ms->rtd[1]),&delta, pinfo);
break;
case GCP_CMD_MOD_REPLY:
time_stat_update(&(ms->rtd[2]),&delta, pinfo);
break;
case GCP_CMD_SUB_REPLY:
time_stat_update(&(ms->rtd[3]),&delta, pinfo);
break;
case GCP_CMD_AUDITCAP_REPLY:
time_stat_update(&(ms->rtd[4]),&delta, pinfo);
break;
case GCP_CMD_AUDITVAL_REPLY:
time_stat_update(&(ms->rtd[5]),&delta, pinfo);
break;
case GCP_CMD_NOTIFY_REPLY:
time_stat_update(&(ms->rtd[6]),&delta, pinfo);
break;
case GCP_CMD_SVCCHG_REPLY:
time_stat_update(&(ms->rtd[7]),&delta, pinfo);
break;
case GCP_CMD_TOPOLOGY_REPLY:
time_stat_update(&(ms->rtd[8]),&delta, pinfo);
break;
case GCP_CMD_REPLY:
time_stat_update(&(ms->rtd[9]),&delta, pinfo);
break;
default:
time_stat_update(&(ms->rtd[11]),&delta, pinfo);
}
time_stat_update(&(ms->rtd[10]),&delta, pinfo);
ret = 1;
}
break;
default:
break;
}
return ret;
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -1,106 +0,0 @@
/* tap-rtp-common.h
* MEGACO statistics handler functions used by tshark and wireshark
*
* Copyright 2008, Ericsson AB
* By Balint Reczey <balint.reczey@ericsson.com>
*
* most functions are copied from ui/gtk/rtp_stream.c and ui/gtk/rtp_analysis.c
* Copyright 2003, Alcatel Business Systems
* By Lars Ruoff <lars.ruoff@gmx.net>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef TAP_MEGACO_COMMON_H
#define TAP_MEGACO_COMMON_H
#define NUM_TIMESTATS 12
#define GCP_CMD_REPLY_CASE \
case GCP_CMD_ADD_REPLY: \
case GCP_CMD_MOVE_REPLY: \
case GCP_CMD_MOD_REPLY: \
case GCP_CMD_SUB_REPLY: \
case GCP_CMD_AUDITCAP_REPLY: \
case GCP_CMD_AUDITVAL_REPLY: \
case GCP_CMD_NOTIFY_REPLY: \
case GCP_CMD_SVCCHG_REPLY: \
case GCP_CMD_TOPOLOGY_REPLY: \
case GCP_CMD_REPLY:
#define GCP_CMD_REQ_CASE \
case GCP_CMD_ADD_REQ: \
case GCP_CMD_MOVE_REQ: \
case GCP_CMD_MOD_REQ: \
case GCP_CMD_SUB_REQ: \
case GCP_CMD_AUDITCAP_REQ: \
case GCP_CMD_AUDITVAL_REQ: \
case GCP_CMD_NOTIFY_REQ: \
case GCP_CMD_SVCCHG_REQ: \
case GCP_CMD_TOPOLOGY_REQ: \
case GCP_CMD_CTX_ATTR_AUDIT_REQ: \
case GCP_CMD_OTHER_REQ:
/* used to keep track of the statistics for an entire program interface */
typedef struct _megacostat_t {
char *filter;
timestat_t rtd[NUM_TIMESTATS];
guint32 open_req_num;
guint32 disc_rsp_num;
guint32 req_dup_num;
guint32 rsp_dup_num;
#ifdef __GTK_H__
GtkWidget *win;
GtkWidget *vbox;
GtkWidget *scrolled_window;
GtkTreeView *table;
#endif /*__GHTK_H__*/
} megacostat_t;
static const value_string megaco_message_type[] = {
{ 0, "ADD "},
{ 1, "MOVE"},
{ 2, "MDFY"},
{ 3, "SUBT"},
{ 4, "AUCP"},
{ 5, "AUVL"},
{ 6, "NTFY"},
{ 7, "SVCC"},
{ 8, "TOPO"},
{ 9, "NONE"},
{ 10, "ALL "},
{ 0, NULL}
};
int megacostat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pmi);
#endif /*TAP_MEGACO_COMMON_H*/
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/