aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-megaco.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2015-06-20 12:22:22 -0400
committerAnders Broman <a.broman58@gmail.com>2015-06-22 15:13:39 +0000
commit8f390d497577937dee7311f345b77c840ba42e15 (patch)
treed59679646ab38e4c22d7773cd00003719be028e7 /epan/dissectors/packet-megaco.c
parent8b230eabddf11becf4ae895fba17f43a3415716e (diff)
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>
Diffstat (limited to 'epan/dissectors/packet-megaco.c')
-rw-r--r--epan/dissectors/packet-megaco.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/epan/dissectors/packet-megaco.c b/epan/dissectors/packet-megaco.c
index ac6e23ae1d..e822245059 100644
--- a/epan/dissectors/packet-megaco.c
+++ b/epan/dissectors/packet-megaco.c
@@ -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 */