/* 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;
/* 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;
* 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++){
* !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;
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;
}
rp->tot.nsecs-=1000000000;
rp->tot.secs++;
}
+
rp->num++;
return 1;
* 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;
/* 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);
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);
}
*
*/
- 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);
+}