diff options
Diffstat (limited to 'epan/dissectors/packet-megaco.c')
-rw-r--r-- | epan/dissectors/packet-megaco.c | 212 |
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 */ |