Service response time statistics for MEGACO (CLI part).
authorBalint Reczey <balint.reczey@ericsson.com>
Wed, 31 Dec 2008 17:47:36 +0000 (17:47 -0000)
committerBalint Reczey <balint.reczey@ericsson.com>
Wed, 31 Dec 2008 17:47:36 +0000 (17:47 -0000)
Refactored GUI part to avoid code duplication.

svn path=/trunk/; revision=27143

Makefile.common
doc/tshark.pod
gtk/megaco_stat.c
tap-megaco-common.c [new file with mode: 0644]
tap-megaco-common.h [new file with mode: 0644]
tap-megacostat.c [new file with mode: 0644]

index 58b4cb1b3cae3651bf4b0e4ee1e3064954cd204a..04274828198f32683523a39d2909ef73b7796417 100644 (file)
@@ -59,6 +59,7 @@ WIRESHARK_COMMON_SRC =        \
        sync_pipe_write.c       \
        timestats.c     \
        util.c  \
+       tap-megaco-common.c     \
        tap-rtp-common.c        \
        version_info.c
 
@@ -103,6 +104,7 @@ TSHARK_TAP_SRC =    \
        tap-iostat.c    \
        tap-iousers.c   \
        tap-mgcpstat.c  \
+       tap-megacostat.c        \
        tap-protocolinfo.c      \
        tap-protohierstat.c     \
        tap-radiusstat.c        \
index b69cfbae8b0d37804f2d01a3fb2a968293a395d4..c62189a395a3b797ca455d44fd81f053729230bb 100644 (file)
@@ -732,6 +732,23 @@ on those calls that match that filter.
 Example: use B<-z "mgcp,rtd,ip.addr==1.2.3.4"> to only collect stats for
 MGCP packets exchanged by the host at IP address 1.2.3.4 .
 
+B<-z> megaco,rtd[I<,filter>]
+
+Collect requests/response RTD (Response Time Delay) data for MEGACO. 
+This is similar to B<-z smb,rtt>). Data collected is number of calls
+for each known MEGACO Type, MinRTD, MaxRTD and AvgRTD.
+Additionally you get the number of duplicate requests/responses, 
+unresponded requests, responses ,which don't match with
+any request. 
+Example: use B<-z megaco,rtd>.
+
+This option can be used multiple times on the command line. 
+
+If the optional filterstring is provided, the stats will only be calculated
+on those calls that match that filter.
+Example: use B<-z "megaco,rtd,ip.addr==1.2.3.4"> to only collect stats for
+MEGACO packets exchanged by the host at IP address 1.2.3.4 .
+
 B<-z> h225,counter[I<,filter>]
 
 Count ITU-T H.225 messages and their reasons. In the first column you get a 
index 246356ab9e896bd5beb1ba0943bcc0fded39a66e..689b95898c9b627a8ecae193e692e644d8b03524 100644 (file)
@@ -1,7 +1,8 @@
 /* megaco_stat.c
  * megaco-statistics for Wireshark
  * Copyright 2003 Lars Roland
- * Copyright 2008  Balint Reczey <balint.reczey@ericsson.com>
+ * Copyright 2008, Ericsson AB
+ * By Balint Reczey <balint.reczey@ericsson.com>
  *
  * $Id$
  *
 #include "gtk/gui_utils.h"
 #include "gtk/main.h"
 
+#include "tap-megaco-common.h"
+
 
-#define NUM_TIMESTATS 11
-
-#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 {
-       GtkWidget *win;
-       GtkWidget *vbox;
-       char *filter;
-       GtkWidget *scrolled_window;
-       GtkCList *table;
-        timestat_t rtd[NUM_TIMESTATS];
-       guint32 open_req_num;
-       guint32 disc_rsp_num;
-       guint32 req_dup_num;
-       guint32 rsp_dup_num;
-} 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"},
-  {  0, NULL}
-};
 
 static void
 megacostat_reset(void *pms)
@@ -135,145 +84,6 @@ megacostat_reset(void *pms)
        ms->rsp_dup_num=0;
 }
 
-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->cmd->msg->framenum != cmd->msg->framenum &&
-                                       cmd_msg != NULL; 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->cmd->msg->framenum != cmd->msg->framenum &&
-                                       cmd_msg != NULL; 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 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=(gcp_cmd_t*)pmi;
-       nstime_t delta;
-       int ret = 0;
-
-       switch (mi->type) {
-
-        GCP_CMD_REQ_CASE
-               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[10]),&delta, pinfo);
-                       }
-
-                       ret = 1;
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       return ret;
-}
-
 static void
 megacostat_draw(void *pms)
 {
@@ -288,7 +98,7 @@ megacostat_draw(void *pms)
        /* clear list before printing */
        gtk_clist_clear(ms->table);
 
-       for(i=0;i<NUM_TIMESTATS;i++) {
+       for(i=0;i<NUM_TIMESTATS-1;i++) {
                /* nothing seen, nothing to do */
                if(ms->rtd[i].num==0){
                        continue;
diff --git a/tap-megaco-common.c b/tap-megaco-common.c
new file mode 100644 (file)
index 0000000..9518063
--- /dev/null
@@ -0,0 +1,200 @@
+/* megaco_stat.c
+ * megaco-statistics for Wireshark
+ * Copyright 2003 Lars Roland
+ * Copyright 2008 Ericsson AB
+ * By Balint Reczey <balint.reczey@ericsson.com>
+ *
+ * $Id$
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <epan/packet_info.h>
+#include <epan/epan.h>
+#include <epan/value_string.h>
+#include <epan/tap.h>
+#include "epan/gcp.h"
+
+#include "../register.h"
+#include "../timestats.h"
+#include "../simple_dialog.h"
+#include "../file.h"
+#include "../globals.h"
+#include "../stat_menu.h"
+
+#include "gtk/gui_stat_util.h"
+#include "gtk/dlg_utils.h"
+#include "gtk/tap_dfilter_dlg.h"
+#include "gtk/gui_utils.h"
+#include "gtk/main.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->cmd->msg->framenum != cmd->msg->framenum &&
+                                       cmd_msg != NULL; 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->cmd->msg->framenum != cmd->msg->framenum &&
+                                       cmd_msg != NULL; 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=(gcp_cmd_t*)pmi;
+       nstime_t delta;
+       int ret = 0;
+
+       switch (mi->type) {
+
+        GCP_CMD_REQ_CASE
+               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;
+}
+
diff --git a/tap-megaco-common.h b/tap-megaco-common.h
new file mode 100644 (file)
index 0000000..133f3f2
--- /dev/null
@@ -0,0 +1,95 @@
+/* tap-rtp-common.h
+ * MEGACO statistics handler functions used by tshark and wireshark
+ *
+ * $Id: tap-megaco-common.h 26244 2008-09-21 14:50:05Z morriss $
+ *
+ * Copyright 2008, Ericsson AB
+ * By Balint Reczey <balint.reczey@ericsson.com>
+ *
+ * most functions are copied from gtk/rtp_stream.c and gtk/rtp_analisys.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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;
+       GtkCList *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*/
diff --git a/tap-megacostat.c b/tap-megacostat.c
new file mode 100644 (file)
index 0000000..efd431a
--- /dev/null
@@ -0,0 +1,136 @@
+/* tap-megacostat.c
+ * mgcpstat   2003 Lars Roland
+ * Copyright 2008, Ericsson AB
+ * By Balint Reczey <balint.reczey@ericsson.com>
+ *
+ * $Id$
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <string.h>
+#include "epan/packet_info.h"
+#include <epan/tap.h>
+#include <epan/stat_cmd_args.h>
+#include "epan/value_string.h"
+#include "register.h"
+#include "epan/gcp.h"
+#include "timestats.h"
+
+#include "tap-megaco-common.h"
+
+
+
+static void
+megacostat_draw(void *pms)
+{
+       megacostat_t *ms=(megacostat_t *)pms;
+       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) {
+                       printf("%5s   | %7u    | %8.2f msec | %8.2f msec | %8.2f msec |  %10u  |  %10u  |\n",
+                               val_to_str(i,megaco_message_type,"Other"),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
+                       );
+               }
+       }
+        printf("=====================================================================================================\n");
+}
+
+
+static void
+megacostat_init(const char *optarg, void* userdata _U_)
+{
+       megacostat_t *ms;
+       int i;
+       const char *filter=NULL;
+       GString *error_string;
+
+       if(!strncmp(optarg,"megaco,rtd,",11)){
+               filter=optarg+11;
+       } else {
+               filter="";
+       }
+
+       ms=g_malloc(sizeof(megacostat_t));
+       ms->filter=g_strdup(filter);
+
+       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, filter, 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);
+       }
+}
+
+
+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_cmd_arg("megaco,rtd", megacostat_init, NULL);
+       }
+}
+