Move the stats.[ch] stuff into epan, so plugins can use it.
[obnox/wireshark/wip.git] / tap-rpcstat.c
index 373afbe0905ef48f34d7c47773ea72adca076f71..ab9d82a06d842b5363209bbaba6282168f285371 100644 (file)
@@ -1,7 +1,7 @@
 /* tap-rpcstat.c
  * rpcstat   2002 Ronnie Sahlberg
  *
- * $Id: tap-rpcstat.c,v 1.3 2002/09/27 11:06:59 sahlberg Exp $
+ * $Id$
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 
 #include <string.h>
 #include "epan/packet_info.h"
-#include "tap.h"
-#include "tap-rpcstat.h"
-#include "packet-rpc.h"
-
+#include <epan/tap.h>
+#include <epan/stat.h>
+#include <epan/dissectors/packet-rpc.h>
+#include "register.h"
 
 /* used to keep track of statistics for a specific procedure */
 typedef struct _rpc_procedure_t {
-       char *proc;
+       const char *proc;
        int num;
        nstime_t min;
        nstime_t max;
@@ -56,7 +56,7 @@ typedef struct _rpc_procedure_t {
 
 /* used to keep track of the statistics for an entire program interface */
 typedef struct _rpcstat_t {
-       char *prog;
+       const char *prog;
        char *filter;
        guint32 program;
        guint32 version;
@@ -77,8 +77,9 @@ typedef struct _rpcstat_t {
  * situations, here is a good place to put that code.
  */
 static void
-rpcstat_reset(rpcstat_t *rs)
+rpcstat_reset(void *prs)
 {
+       rpcstat_t *rs=prs;
        guint32 i;
 
        for(i=0;i<rs->num_procedures;i++){
@@ -124,8 +125,10 @@ rpcstat_reset(rpcstat_t *rs)
  * !0: state has changed, call (*draw) sometime later
  */
 static int
-rpcstat_packet(rpcstat_t *rs, packet_info *pinfo, rpc_call_info_value *ri)
+rpcstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pri)
 {
+       rpcstat_t *rs=prs;
+       const rpc_call_info_value *ri=pri;
        nstime_t delta;
        rpc_procedure_t *rp;
 
@@ -152,14 +155,12 @@ rpcstat_packet(rpcstat_t *rs, packet_info *pinfo, rpc_call_info_value *ri)
                delta.secs--;
        }
 
-       if((rp->max.secs==0)
-       && (rp->max.nsecs==0) ){
+       if(rp->num==0){
                rp->max.secs=delta.secs;
                rp->max.nsecs=delta.nsecs;
        }
 
-       if((rp->min.secs==0)
-       && (rp->min.nsecs==0) ){
+       if(rp->num==0){
                rp->min.secs=delta.secs;
                rp->min.nsecs=delta.nsecs;
        }
@@ -184,6 +185,7 @@ rpcstat_packet(rpcstat_t *rs, packet_info *pinfo, rpc_call_info_value *ri)
                rp->tot.nsecs-=1000000000;
                rp->tot.secs++;
        }
+
        rp->num++;
 
        return 1;
@@ -201,8 +203,9 @@ rpcstat_packet(rpcstat_t *rs, packet_info *pinfo, rpc_call_info_value *ri)
  * beneath us. Beware.
  */
 static void
-rpcstat_draw(rpcstat_t *rs)
+rpcstat_draw(void *prs)
 {
+       rpcstat_t *rs=prs;
        guint32 i;
 #ifdef G_HAVE_UINT64
        guint64 td;
@@ -270,15 +273,30 @@ rpcstat_find_procs(gpointer *key, gpointer *value _U_, gpointer *user_data _U_)
 /* When called, this function will create a new instance of rpcstat.
  * program and version are whick onc-rpc program/version we want to
  * collect statistics for.
- * This function is called from tethereal when it parses the -Z rpc, arguments
+ * This function is called from tethereal when it parses the -z rpc, arguments
  * and it creates a new instance to store statistics in and registers this
  * new instance for the rpc tap.
  */
-void
-rpcstat_init(guint32 program, guint32 version, char *filter)
+static void
+rpcstat_init(const char *optarg)
 {
        rpcstat_t *rs;
        guint32 i;
+       int program, version;
+       int pos=0;
+       const char *filter=NULL;
+       GString *error_string;
+
+       if(sscanf(optarg,"rpc,rtt,%d,%d,%n",&program,&version,&pos)==2){
+               if(pos){
+                       filter=optarg+pos;
+               } else {
+                       filter=NULL;
+               }
+       } else {
+               fprintf(stderr, "tethereal: invalid \"-z rpc,rtt,<program>,<version>[,<filter>]\" argument\n");
+               exit(1);
+       }
 
        rs=g_malloc(sizeof(rpcstat_t));
        rs->prog=rpc_prog_name(program);
@@ -296,8 +314,8 @@ rpcstat_init(guint32 program, guint32 version, char *filter)
        rpc_max_proc=-1;
        g_hash_table_foreach(rpc_procs, (GHFunc)rpcstat_find_procs, NULL);
        if(rpc_min_proc==-1){
-               fprintf(stderr,"tethereal: Invalid -Z rpc,rrt,%d,%d\n",rpc_program,rpc_version);
-               fprintf(stderr,"   Program:%d version:%d is not supported by tethereal.\n", rpc_program, rpc_version);
+               fprintf(stderr,"tethereal: Invalid -z rpc,rrt,%d,%d\n",rpc_program,rpc_version);
+               fprintf(stderr,"   Program:%d version:%d isn't supported by tethereal.\n", rpc_program, rpc_version);
                exit(1);
        }
 
@@ -325,17 +343,24 @@ rpcstat_init(guint32 program, guint32 version, char *filter)
  *
  */
 
-       if(register_tap_listener("rpc", rs, filter, (void*)rpcstat_reset, (void*)rpcstat_packet, (void*)rpcstat_draw)){
+       error_string=register_tap_listener("rpc", rs, filter, rpcstat_reset, rpcstat_packet, rpcstat_draw);
+       if(error_string){
                /* error, we failed to attach to the tap. clean up */
                g_free(rs->procedures);
                g_free(rs->filter);
                g_free(rs);
 
-               fprintf(stderr,"tethereal: rpcstat_init() failed to attach to tap.\n");
+               fprintf(stderr, "tethereal: Couldn't register rpc,rtt tap: %s\n",
+                   error_string->str);
+               g_string_free(error_string, TRUE);
                exit(1);
        }
 }
 
 
-
+void
+register_tap_listener_rpcstat(void)
+{
+       register_stat_cmd_arg("rpc,rtt,", rpcstat_init);
+}