diff options
author | Michael Mann <mmann78@netscape.net> | 2015-04-26 12:26:05 -0400 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2015-04-28 07:37:14 +0000 |
commit | 0b368ea23ff86d1895f6c8572a1014490b574d31 (patch) | |
tree | 51cc1bd8b05b309d2017659ab8b3cffa188a5309 /ui/cli | |
parent | 8c996a2736504aa727899213597805574c09981a (diff) | |
download | wireshark-0b368ea23ff86d1895f6c8572a1014490b574d31.tar.gz wireshark-0b368ea23ff86d1895f6c8572a1014490b574d31.tar.bz2 wireshark-0b368ea23ff86d1895f6c8572a1014490b574d31.zip |
Add service_response_time_table for TShark srt stats.
This is a "refactoring part 1" of the srt stats. This first step is using the service_response_time_table for all (possible) TShark srt stats. Next step will be combining the GTK and TShark service_response_time_table, so there is more code reuse and the "shared structure names" between GTK and TShark service_response_time_table won't seem as bad.
Maybe it can even go one step farther and handle a dynamic number of columns so this refactoring can apply to all srt stats.
Change-Id: Ief28e7e55f7dbbf4f2d9bb6f1a1592b87b866137
Reviewed-on: https://code.wireshark.org/review/8210
Reviewed-by: Michael Mann <mmann78@netscape.net>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'ui/cli')
-rw-r--r-- | ui/cli/Makefile.common | 4 | ||||
-rw-r--r-- | ui/cli/cli_service_response_time_table.c | 166 | ||||
-rw-r--r-- | ui/cli/cli_service_response_time_table.h | 97 | ||||
-rw-r--r-- | ui/cli/tap-afpstat.c | 79 | ||||
-rw-r--r-- | ui/cli/tap-ldapstat.c | 67 | ||||
-rw-r--r-- | ui/cli/tap-rpcstat.c | 146 | ||||
-rw-r--r-- | ui/cli/tap-scsistat.c | 151 | ||||
-rw-r--r-- | ui/cli/tap-smbstat.c | 167 |
8 files changed, 359 insertions, 518 deletions
diff --git a/ui/cli/Makefile.common b/ui/cli/Makefile.common index 185739adc8..d74abfef36 100644 --- a/ui/cli/Makefile.common +++ b/ui/cli/Makefile.common @@ -38,6 +38,7 @@ GENERATOR_FILES = # sources for TShark taps TSHARK_TAP_SRC = \ + cli_service_response_time_table.c \ tap-afpstat.c \ tap-ansi_astat.c \ tap-bootpstat.c \ @@ -82,4 +83,5 @@ TSHARK_TAP_SRC = \ tap-wspstat.c noinst_HEADERS = \ - tshark-tap.h + tshark-tap.h \ + cli_service_response_time_table.h diff --git a/ui/cli/cli_service_response_time_table.c b/ui/cli/cli_service_response_time_table.c new file mode 100644 index 0000000000..d061069c88 --- /dev/null +++ b/ui/cli/cli_service_response_time_table.c @@ -0,0 +1,166 @@ +/* cli_service_response_time_table.c + * TShark service_response_time_table based on GTK version by Ronnie Sahlberg + * Helper routines common to all service response time statistics + * tap. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <stdio.h> + +#include "epan/packet_info.h" +#include "epan/value_string.h" + +#include "ui/cli/cli_service_response_time_table.h" + +#define NANOSECS_PER_SEC 1000000000 + + +void +init_srt_table(const char *name, srt_stat_table *rst, int num_procs, const char* proc_column_name, const char *filter_string) +{ + int i; + + if(filter_string){ + rst->filter_string=g_strdup(filter_string); + } else { + rst->filter_string=NULL; + } + + rst->name = name; + rst->proc_column_name = proc_column_name; + rst->num_procs=num_procs; + rst->procedures=(srt_procedure_t *)g_malloc(sizeof(srt_procedure_t)*num_procs); + for(i=0;i<num_procs;i++){ + time_stat_init(&rst->procedures[i].stats); + rst->procedures[i].index = 0; + rst->procedures[i].procedure = NULL; + } +} + +void +init_srt_table_row(srt_stat_table *rst, int indx, const char *procedure) +{ + /* we have discovered a new procedure. Extend the table accordingly */ + if(indx>=rst->num_procs){ + int old_num_procs=rst->num_procs; + int i; + + rst->num_procs=indx+1; + rst->procedures=(srt_procedure_t *)g_realloc(rst->procedures, sizeof(srt_procedure_t)*(rst->num_procs)); + for(i=old_num_procs;i<rst->num_procs;i++){ + time_stat_init(&rst->procedures[i].stats); + rst->procedures[i].index = i; + rst->procedures[i].procedure=NULL; + } + } + rst->procedures[indx].index = indx; + rst->procedures[indx].procedure=g_strdup(procedure); +} + +void +add_srt_table_data(srt_stat_table *rst, int indx, const nstime_t *req_time, packet_info *pinfo) +{ + srt_procedure_t *rp; + nstime_t t, delta; + + g_assert(indx >= 0 && indx < rst->num_procs); + rp=&rst->procedures[indx]; + + /* calculate time delta between request and reply */ + t=pinfo->fd->abs_ts; + nstime_delta(&delta, &t, req_time); + + time_stat_update(&rp->stats, &delta, pinfo); +} + +void +draw_srt_table_data(srt_stat_table *rst, gboolean draw_header, gboolean draw_footer) +{ + int i; + guint64 td; + guint64 sum; + + if (draw_header) { + printf("\n"); + printf("===================================================================\n"); + printf("%s SRT Statistics:\n", rst->name); + printf("Filter: %s\n", rst->filter_string ? rst->filter_string : ""); + } + + printf("Index %-22s Calls Min SRT Max SRT Avg SRT Sum SRT\n", (rst->proc_column_name != NULL) ? rst->proc_column_name : "Procedure"); + for(i=0;i<rst->num_procs;i++){ + /* ignore procedures with no calls (they don't have rows) */ + if(rst->procedures[i].stats.num==0){ + continue; + } + /* Scale the average SRT in units of 1us and round to the nearest us. + tot.secs is a time_t which may be 32 or 64 bits (or even floating) + depending uon the platform. After casting tot.secs to 64 bits, it + would take a capture with a duration of over 136 *years* to + overflow the secs portion of td. */ + td = ((guint64)(rst->procedures[i].stats.tot.secs))*NANOSECS_PER_SEC + rst->procedures[i].stats.tot.nsecs; + sum = (td + 500) / 1000; + td = ((td / rst->procedures[i].stats.num) + 500) / 1000; + + printf("%5u %-22s %6u %3d.%06d %3d.%06d %3d.%06d %3d.%06d\n", + i, rst->procedures[i].procedure, + rst->procedures[i].stats.num, + (int)rst->procedures[i].stats.min.secs, (rst->procedures[i].stats.min.nsecs+500)/1000, + (int)rst->procedures[i].stats.max.secs, (rst->procedures[i].stats.max.nsecs+500)/1000, + (int)(td/1000000), (int)(td%1000000), + (int)(sum/1000000), (int)(sum%1000000) + ); + } + + if (draw_footer) + printf("==================================================================\n"); +} + +void +free_srt_table_data(srt_stat_table *rst) +{ + int i; + + for(i=0;i<rst->num_procs;i++){ + g_free(rst->procedures[i].procedure); + rst->procedures[i].procedure=NULL; + } + g_free(rst->filter_string); + rst->filter_string=NULL; + g_free(rst->procedures); + rst->procedures=NULL; + rst->num_procs=0; +} + + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=8 tabstop=8 noexpandtab: + * :indentSize=8:tabSize=8:noTabs=false: + */ diff --git a/ui/cli/cli_service_response_time_table.h b/ui/cli/cli_service_response_time_table.h new file mode 100644 index 0000000000..d0f4cd6057 --- /dev/null +++ b/ui/cli/cli_service_response_time_table.h @@ -0,0 +1,97 @@ +/* cli_service_response_time_table.h + * TShark service_response_time_table based on GTK version by Ronnie Sahlberg + * Helper routines common to all service response time statistics + * tap. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CLI_SERVICE_RESPONSE_TIME_TABLE_H__ +#define __CLI_SERVICE_RESPONSE_TIME_TABLE_H__ + +#include "wsutil/nstime.h" +#include "epan/timestats.h" + +/** @file + * Helper routines common to all service response time statistics tap. + */ + +/** Procedure data */ +typedef struct _srt_procedure_t { + int index; + timestat_t stats; /**< stats */ + char *procedure; /**< column entries */ +} srt_procedure_t; + +/** Statistics table */ +typedef struct _srt_stat_table { + const char *name; /**< table name */ + char *filter_string; /**< append procedure number (%d) to this string + to create a display filter */ + int num_procs; /**< number of elements on procedures array */ + const char *proc_column_name; /**< procedure column name (if different from default) */ + srt_procedure_t *procedures;/**< the procedures array */ +} srt_stat_table; + +/** Init an srt table data structure. + * + * @param name the table name + * @param rst the srt table to init + * @param num_procs number of procedures + * @param proc_column_name procedure column name (if different from "Procedure") + * @param filter_string filter string or NULL + */ +void init_srt_table(const char *name, srt_stat_table *rst, int num_procs, const char* proc_column_name, const char *filter_string); + +/** Init an srt table row data structure. + * + * @param rst the srt table + * @param index number of procedure + * @param procedure the procedures name + */ +void init_srt_table_row(srt_stat_table *rst, int index, const char *procedure); + +/** Add srt response to table row data. This will not draw the data! + * + * @param rst the srt table + * @param index number of procedure + * @param req_time the time of the corresponding request + * @param pinfo current packet info + */ +void add_srt_table_data(srt_stat_table *rst, int index, const nstime_t *req_time, packet_info *pinfo); + +/** Draw the srt table data. + * + * @param rst the srt table + */ +void draw_srt_table_data(srt_stat_table *rst, gboolean draw_header, gboolean draw_footer); + +/** Reset the srt table data. + * + * @param rst the srt table + */ +void reset_srt_table_data(srt_stat_table *rst); + +/** Free the srt table data. + * + * @param rst the srt table + */ +void free_srt_table_data(srt_stat_table *rst); + +#endif /* __CLI_SERVICE_RESPONSE_TIME_TABLE_H__ */ diff --git a/ui/cli/tap-afpstat.c b/ui/cli/tap-afpstat.c index 67536e4213..afb8b12e47 100644 --- a/ui/cli/tap-afpstat.c +++ b/ui/cli/tap-afpstat.c @@ -30,16 +30,18 @@ #include <epan/packet_info.h> #include <epan/tap.h> #include <epan/stat_tap_ui.h> +#include <ui/cli/cli_service_response_time_table.h> #include <epan/value_string.h> #include <epan/dissectors/packet-afp.h> #include "epan/timestats.h" void register_tap_listener_afpstat(void); +#define AFP_NUM_PROCEDURES 256 + /* used to keep track of the statistics for an entire program interface */ typedef struct _afpstat_t { - char *filter; - timestat_t proc[256]; + srt_stat_table afp_srt_table; } afpstat_t; static int @@ -47,23 +49,13 @@ afpstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const voi { afpstat_t *ss = (afpstat_t *)pss; const afp_request_val *request_val = (const afp_request_val *)prv; - nstime_t t, deltat; - timestat_t *sp = NULL; /* if we havnt seen the request, just ignore it */ if (!request_val) { return 0; } - sp = &(ss->proc[request_val->command]); - - /* calculate time delta between request and reply */ - t = pinfo->fd->abs_ts; - nstime_delta(&deltat, &t, &request_val->req_time); - - if (sp) { - time_stat_update(sp, &deltat, pinfo); - } + add_srt_table_data(&ss->afp_srt_table, request_val->command, &request_val->req_time, pinfo); return 1; } @@ -72,40 +64,8 @@ static void afpstat_draw(void *pss) { afpstat_t *ss = (afpstat_t *)pss; - guint32 i; - guint64 td; - gchar* tmp_str; - printf("\n"); - printf("===================================================================\n"); - printf("AFP SRT Statistics:\n"); - printf("Filter: %s\n", ss->filter ? ss->filter : ""); - printf("Commands Calls Min SRT Max SRT Avg SRT\n"); - for (i=0; i<256; i++) { - /* nothing seen, nothing to do */ - if (ss->proc[i].num == 0) { - continue; - } - - /* scale it to units of 10us.*/ - td = ss->proc[i].tot.secs; - td = td*100000+(int)ss->proc[i].tot.nsecs/10000; - if (ss->proc[i].num) { - td /= ss->proc[i].num; - } else { - td = 0; - } - - tmp_str = val_to_str_ext_wmem(NULL, i, &CommandCode_vals_ext, "Unknown (%u)"); - printf("%-25s %6u %3d.%05d %3d.%05d %3" G_GINT64_MODIFIER "u.%05" G_GINT64_MODIFIER "u\n", - tmp_str, - ss->proc[i].num, - (int)ss->proc[i].min.secs, ss->proc[i].min.nsecs/10000, - (int)ss->proc[i].max.secs, ss->proc[i].max.nsecs/10000, - td/100000, td%100000 - ); - wmem_free(NULL, tmp_str); - } - printf("===================================================================\n"); + + draw_srt_table_data(&ss->afp_srt_table, TRUE, TRUE); } @@ -119,33 +79,22 @@ afpstat_init(const char *opt_arg, void *userdata _U_) if (!strncmp(opt_arg, "afp,srt,", 8)) { filter = opt_arg+8; - } else { - filter = NULL; } ss = g_new(afpstat_t, 1); - if (filter) { - ss->filter = g_strdup(filter); - } else { - ss->filter = NULL; - } - for (i=0; i<256; i++) { - ss->proc[i].num = 0; - ss->proc[i].min_num = 0; - ss->proc[i].max_num = 0; - ss->proc[i].min.secs = 0; - ss->proc[i].min.nsecs = 0; - ss->proc[i].max.secs = 0; - ss->proc[i].max.nsecs = 0; - ss->proc[i].tot.secs = 0; - ss->proc[i].tot.nsecs = 0; + init_srt_table("AFP", &ss->afp_srt_table, AFP_NUM_PROCEDURES, NULL, filter ? g_strdup(filter) : NULL); + for (i = 0; i < AFP_NUM_PROCEDURES; i++) + { + gchar* tmp_str = val_to_str_ext_wmem(NULL, i, &CommandCode_vals_ext, "Unknown(%u)"); + init_srt_table_row(&ss->afp_srt_table, i, tmp_str); + wmem_free(NULL, tmp_str); } error_string = register_tap_listener("afp", ss, filter, 0, NULL, afpstat_packet, afpstat_draw); if (error_string) { /* error, we failed to attach to the tap. clean up */ - g_free(ss->filter); + free_srt_table_data(&ss->afp_srt_table); g_free(ss); fprintf(stderr, "tshark: Couldn't register afp,srt tap: %s\n", diff --git a/ui/cli/tap-ldapstat.c b/ui/cli/tap-ldapstat.c index 1f82b1189d..8fb5d101ab 100644 --- a/ui/cli/tap-ldapstat.c +++ b/ui/cli/tap-ldapstat.c @@ -30,6 +30,7 @@ #include <epan/packet_info.h> #include <epan/tap.h> #include <epan/stat_tap_ui.h> +#include <ui/cli/cli_service_response_time_table.h> #include <epan/value_string.h> #include <epan/dissectors/packet-ldap.h> #include "epan/timestats.h" @@ -38,12 +39,9 @@ void register_tap_listener_ldapstat(void); #define LDAP_NUM_PROCEDURES 24 -#define NANOSECS_PER_SEC G_GUINT64_CONSTANT(1000000000) - /* used to keep track of the statistics for an entire program interface */ typedef struct _ldapstat_t { - char *filter; - timestat_t proc[LDAP_NUM_PROCEDURES]; + srt_stat_table ldap_srt_table; } ldapstat_t; static int @@ -51,8 +49,6 @@ ldapstat_packet(void *pldap, packet_info *pinfo, epan_dissect_t *edt _U_, const { const ldap_call_response_t *ldap=(const ldap_call_response_t *)psi; ldapstat_t *fs=(ldapstat_t *)pldap; - timestat_t *sp = NULL; - nstime_t t, deltat; /* we are only interested in reply packets */ if(ldap->is_request){ @@ -78,15 +74,7 @@ ldapstat_packet(void *pldap, packet_info *pinfo, epan_dissect_t *edt _U_, const return 0; } - sp = &(fs->proc[ldap->protocolOpTag]); - - /* calculate time delta between request and reply */ - t = pinfo->fd->abs_ts; - nstime_delta(&deltat, &t, &ldap->req_time); - - if (sp) { - time_stat_update(sp, &deltat, pinfo); - } + add_srt_table_data(&fs->ldap_srt_table, ldap->protocolOpTag, &ldap->req_time, pinfo); return 1; } @@ -94,41 +82,8 @@ static void ldapstat_draw(void *pss) { ldapstat_t *ss = (ldapstat_t *)pss; - guint32 i; - guint64 td, sum; - gchar* tmp_str; - printf("\n"); - printf("===================================================================\n"); - printf("LDAP SRT Statistics:\n"); - printf("Filter: %s\n", ss->filter ? ss->filter : ""); - printf("Index Procedure Calls Min SRT Max SRT Avg SRT Sum SRT\n"); - for (i=0; i<LDAP_NUM_PROCEDURES; i++) { - /* nothing seen, nothing to do */ - if (ss->proc[i].num == 0) { - continue; - } - - /* Scale the average SRT in units of 1us and round to the nearest us. - tot.secs is a time_t which may be 32 or 64 bits (or even floating) - depending uon the platform. After casting tot.secs to 64 bits, it - would take a capture with a duration of over 136 *years* to - overflow the secs portion of td. */ - td = ((guint64)(ss->proc[i].tot.secs))*NANOSECS_PER_SEC + ss->proc[i].tot.nsecs; - sum = (td + 500) / 1000; - td = ((td / ss->proc[i].num) + 500) / 1000; - - tmp_str = val_to_str_wmem(NULL, i, ldap_procedure_names, "Unknown (%u)"); - printf("%5u %-20s %6u %3d.%06d %3d.%06d %3d.%06d %3d.%06d\n", - i, tmp_str, - ss->proc[i].num, - (int)ss->proc[i].min.secs, (ss->proc[i].min.nsecs+500)/1000, - (int)ss->proc[i].max.secs, (ss->proc[i].max.nsecs+500)/1000, - (int)(td/1000000), (int)(td%1000000), - (int)(sum/1000000), (int)(sum%1000000) - ); - wmem_free(NULL, tmp_str); - } - printf("===================================================================\n"); + + draw_srt_table_data(&ss->ldap_srt_table, TRUE, TRUE); } @@ -138,20 +93,24 @@ ldapstat_init(const char *opt_arg, void *userdata _U_) ldapstat_t *ldap; const char *filter = NULL; GString *error_string; + int i; if (!strncmp(opt_arg, "ldap,srt,", 8)) { filter = opt_arg+8; } - ldap=(ldapstat_t *)g_malloc0(sizeof(ldapstat_t)); - if (filter) { - ldap->filter = g_strdup(filter); + ldap = g_new(ldapstat_t,1); + + init_srt_table("LDAP", &ldap->ldap_srt_table, LDAP_NUM_PROCEDURES, NULL, filter ? g_strdup(filter) : NULL); + for (i = 0; i < LDAP_NUM_PROCEDURES; i++) + { + init_srt_table_row(&ldap->ldap_srt_table, i, val_to_str_const(i, ldap_procedure_names, "<unknown>")); } error_string = register_tap_listener("ldap", ldap, filter, 0, NULL, ldapstat_packet, ldapstat_draw); if (error_string) { /* error, we failed to attach to the tap. clean up */ - g_free(ldap->filter); + free_srt_table_data(&ldap->ldap_srt_table); g_free(ldap); fprintf(stderr, "tshark: Couldn't register ldap,srt tap: %s\n", diff --git a/ui/cli/tap-rpcstat.c b/ui/cli/tap-rpcstat.c index 006b39cbbf..61dbaadb4f 100644 --- a/ui/cli/tap-rpcstat.c +++ b/ui/cli/tap-rpcstat.c @@ -36,61 +36,22 @@ #include <epan/tap.h> #include <epan/stat_tap_ui.h> #include <epan/dissectors/packet-rpc.h> +#include <ui/cli/cli_service_response_time_table.h> -#define MICROSECS_PER_SEC 1000000 -#define NANOSECS_PER_SEC 1000000000 void register_tap_listener_rpcstat(void); -/* used to keep track of statistics for a specific procedure */ -typedef struct _rpc_procedure_t { - const char *proc; - int num; - nstime_t min; - nstime_t max; - nstime_t tot; -} rpc_procedure_t; /* used to keep track of the statistics for an entire program interface */ typedef struct _rpcstat_t { const char *prog; - char *filter; guint32 program; guint32 version; - guint32 num_procedures; - rpc_procedure_t *procedures; + srt_stat_table rpc_srt_table; } rpcstat_t; -/* This callback is never used by tshark but it is here for completeness. - * When registering below, we could just have left this function as NULL. - * - * When used by wireshark, this function will be called whenever we would need - * to reset all state, such as when wireshark opens a new file, when it - * starts a new capture, when it rescans the packetlist after some prefs have - * changed etc. - * - * So if your application has some state it needs to clean up in those - * situations, here is a good place to put that code. - */ -static void -rpcstat_reset(void *prs) -{ - rpcstat_t *rs = (rpcstat_t *)prs; - guint32 i; - - for (i=0; i<rs->num_procedures; i++) { - rs->procedures[i].num = 0; - rs->procedures[i].min.secs = 0; - rs->procedures[i].min.nsecs = 0; - rs->procedures[i].max.secs = 0; - rs->procedures[i].max.nsecs = 0; - rs->procedures[i].tot.secs = 0; - rs->procedures[i].tot.nsecs = 0; - } -} - /* This callback is invoked whenever the tap system has seen a packet we might * be interested in. The function is to be used to only update internal state @@ -124,10 +85,8 @@ rpcstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const voi { rpcstat_t *rs = (rpcstat_t *)prs; const rpc_call_info_value *ri = (const rpc_call_info_value *)pri; - nstime_t delta; - rpc_procedure_t *rp; - if (ri->proc >= rs->num_procedures) { + if ((int)ri->proc >= rs->rpc_srt_table.num_procs) { /* don't handle this since its outside of known table */ return 0; } @@ -140,44 +99,7 @@ rpcstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const voi return 0; } - rp = &(rs->procedures[ri->proc]); - - /* calculate time delta between request and reply */ - nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->req_time); - - if (rp->num == 0) { - rp->max.secs = delta.secs; - rp->max.nsecs = delta.nsecs; - } - - if (rp->num == 0) { - rp->min.secs = delta.secs; - rp->min.nsecs = delta.nsecs; - } - - if ( (delta.secs < rp->min.secs) - || ( (delta.secs == rp->min.secs) - && (delta.nsecs < rp->min.nsecs) ) ) { - rp->min.secs = delta.secs; - rp->min.nsecs = delta.nsecs; - } - - if ( (delta.secs > rp->max.secs) - || ( (delta.secs == rp->max.secs) - && (delta.nsecs > rp->max.nsecs) ) ) { - rp->max.secs = delta.secs; - rp->max.nsecs = delta.nsecs; - } - - rp->tot.secs += delta.secs; - rp->tot.nsecs += delta.nsecs; - if (rp->tot.nsecs > NANOSECS_PER_SEC) { - rp->tot.nsecs -= NANOSECS_PER_SEC; - rp->tot.secs++; - } - - rp->num++; - + add_srt_table_data(&rs->rpc_srt_table, ri->proc, &ri->req_time, pinfo); return 1; } @@ -195,31 +117,8 @@ static void rpcstat_draw(void *prs) { rpcstat_t *rs = (rpcstat_t *)prs; - guint32 i; - guint64 td; - printf("\n"); - printf("==================================================================\n"); - printf("%s Version %u SRT Statistics:\n", rs->prog, rs->version); - printf("Filter: %s\n", rs->filter ? rs->filter : ""); - printf("Procedure Calls Min SRT Max SRT Avg SRT Total\n"); - for (i=0; i<rs->num_procedures; i++) { - if (rs->procedures[i].num == 0) { - continue; - } - /* Scale the average SRT in units of 1us and round to the nearest us. */ - td = ((guint64)(rs->procedures[i].tot.secs)) * NANOSECS_PER_SEC + rs->procedures[i].tot.nsecs; - td = ((td / rs->procedures[i].num) + 500) / 1000; - - printf("%-15s %6d %3d.%06d %3d.%06d %3" G_GINT64_MODIFIER "u.%06" G_GINT64_MODIFIER "u %3d.%06d\n", - rs->procedures[i].proc, - rs->procedures[i].num, - (int)(rs->procedures[i].min.secs), (rs->procedures[i].min.nsecs+500)/1000, - (int)(rs->procedures[i].max.secs), (rs->procedures[i].max.nsecs+500)/1000, - td/MICROSECS_PER_SEC, td%MICROSECS_PER_SEC, - (int)(rs->procedures[i].tot.secs), (rs->procedures[i].tot.nsecs+500)/1000 - ); - } - printf("==================================================================\n"); + + draw_srt_table_data(&rs->rpc_srt_table, TRUE, TRUE); } static guint32 rpc_program = 0; @@ -266,17 +165,16 @@ static void rpcstat_init(const char *opt_arg, void *userdata _U_) { rpcstat_t *rs; - guint32 i; + int i; int program, version; int pos = 0; const char *filter = NULL; GString *error_string; + static char table_name[100]; if (sscanf(opt_arg, "rpc,srt,%d,%d,%n", &program, &version, &pos) == 2) { if (pos) { filter = opt_arg+pos; - } else { - filter = NULL; } } else { fprintf(stderr, "tshark: invalid \"-z rpc,srt,<program>,<version>[,<filter>]\" argument\n"); @@ -287,11 +185,7 @@ rpcstat_init(const char *opt_arg, void *userdata _U_) rs->prog = rpc_prog_name(program); rs->program = program; rs->version = version; - if (filter) { - rs->filter = g_strdup(filter); - } else { - rs->filter = NULL; - } + rpc_program = program; rpc_version = version; rpc_min_proc = -1; @@ -303,18 +197,11 @@ rpcstat_init(const char *opt_arg, void *userdata _U_) exit(1); } - - rs->num_procedures = rpc_max_proc+1; - rs->procedures = g_new(rpc_procedure_t, rs->num_procedures+1); - for (i=0; i<rs->num_procedures; i++) { - rs->procedures[i].proc = rpc_proc_name(program, version, i); - rs->procedures[i].num = 0; - rs->procedures[i].min.secs = 0; - rs->procedures[i].min.nsecs = 0; - rs->procedures[i].max.secs = 0; - rs->procedures[i].max.nsecs = 0; - rs->procedures[i].tot.secs = 0; - rs->procedures[i].tot.nsecs = 0; + g_snprintf(table_name, sizeof(table_name), "%s Version %u", rs->prog, rs->version); + init_srt_table(table_name, &rs->rpc_srt_table, rpc_max_proc+1, NULL, filter ? g_strdup(filter) : NULL); + for (i = 0; i < rs->rpc_srt_table.num_procs; i++) + { + init_srt_table_row(&rs->rpc_srt_table, i, rpc_proc_name(program, version, i)); } /* It is possible to create a filter and attach it to the callbacks. Then the @@ -328,11 +215,10 @@ rpcstat_init(const char *opt_arg, void *userdata _U_) * (Perhaps the user only wants the stats for nis+ traffic for certain objects?) */ - error_string = register_tap_listener("rpc", rs, filter, 0, rpcstat_reset, rpcstat_packet, rpcstat_draw); + error_string = register_tap_listener("rpc", rs, filter, 0, NULL, 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); + free_srt_table_data(&rs->rpc_srt_table); g_free(rs); fprintf(stderr, "tshark: Couldn't register rpc,srt tap: %s\n", diff --git a/ui/cli/tap-scsistat.c b/ui/cli/tap-scsistat.c index ce0a58f4b3..4465919793 100644 --- a/ui/cli/tap-scsistat.c +++ b/ui/cli/tap-scsistat.c @@ -26,6 +26,7 @@ #include <string.h> #include <epan/packet_info.h> #include <epan/stat_tap_ui.h> +#include <ui/cli/cli_service_response_time_table.h> #include <epan/tap.h> #include <epan/conversation.h> #include <epan/dissectors/packet-scsi.h> @@ -37,54 +38,20 @@ void register_tap_listener_scsistat(void); -static guint8 scsi_program = 0; - -/* used to keep track of statistics for a specific procedure */ -typedef struct _scsi_procedure_t { - char *proc; - int num; - nstime_t min; - nstime_t max; - nstime_t tot; -} scsi_procedure_t; +#define SCSI_NUM_PROCEDURES 256 /* used to keep track of the statistics for an entire program interface */ typedef struct _scsistat_t { guint8 cmdset; - char *filter; - value_string_ext *cdbnames_ext; const char *prog; -#define MAX_PROCEDURES 256 - scsi_procedure_t *procedures; + srt_stat_table scsi_srt_table; } scsistat_t; -#define MICROSECS_PER_SEC 1000000 -#define NANOSECS_PER_SEC 1000000000 - -static void -scsistat_reset(void *prs) -{ - scsistat_t *rs = (scsistat_t *)prs; - guint32 i; - - for(i = 0; i < MAX_PROCEDURES; i++) { - rs->procedures[i].num = 0; - rs->procedures[i].min.secs = 0; - rs->procedures[i].min.nsecs = 0; - rs->procedures[i].max.secs = 0; - rs->procedures[i].max.nsecs = 0; - rs->procedures[i].tot.secs = 0; - rs->procedures[i].tot.nsecs = 0; - } -} - static int scsistat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pri) { scsistat_t *rs = (scsistat_t *)prs; const scsi_task_data_t *ri = (const scsi_task_data_t *)pri; - nstime_t delta; - scsi_procedure_t *rp; /* we are only interested in response packets */ if (ri->type != SCSI_PDU_TYPE_RSP) { @@ -99,38 +66,7 @@ scsistat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const vo return 0; } - rp = &(rs->procedures[ri->itlq->scsi_opcode]); - - /* calculate time delta between request and reply */ - nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->itlq->fc_time); - - if (rp->num == 0) { - rp->max.secs = delta.secs; - rp->max.nsecs = delta.nsecs; - } - if (rp->num == 0) { - rp->min.secs = delta.secs; - rp->min.nsecs = delta.nsecs; - } - if ( (delta.secs < rp->min.secs) - || ( (delta.secs == rp->min.secs) - && (delta.nsecs < rp->min.nsecs) ) ) { - rp->min.secs = delta.secs; - rp->min.nsecs = delta.nsecs; - } - if ( (delta.secs > rp->max.secs) - || ( (delta.secs == rp->max.secs) - && (delta.nsecs > rp->max.nsecs) ) ) { - rp->max.secs = delta.secs; - rp->max.nsecs= delta.nsecs; - } - rp->tot.secs += delta.secs; - rp->tot.nsecs += delta.nsecs; - if (rp->tot.nsecs > NANOSECS_PER_SEC) { - rp->tot.nsecs -= NANOSECS_PER_SEC; - rp->tot.secs++; - } - rp->num++; + add_srt_table_data(&rs->scsi_srt_table, ri->itlq->scsi_opcode, &ri->itlq->fc_time, pinfo); return 1; } @@ -138,33 +74,8 @@ static void scsistat_draw(void *prs) { scsistat_t *rs = (scsistat_t *)prs; - guint32 i; - guint64 td; - - printf("\n"); - printf("===========================================================\n"); - printf("SCSI %s SRT Statistics:\n", rs->prog); - printf("Filter: %s\n", rs->filter ? rs->filter : ""); - printf("Procedure Calls Min SRT Max SRT Avg SRT\n"); - for(i=0; i < MAX_PROCEDURES; i++) { - if (rs->procedures[i].num == 0) { - continue; - } - /* scale it to units of 1us.*/ - td = ((guint64)(rs->procedures[i].tot.secs)) * NANOSECS_PER_SEC + rs->procedures[i].tot.nsecs; - td = ((td / rs->procedures[i].num) + 500) / 1000; - printf("%-19s %6d %3d.%06d %3d.%06d %3" G_GINT64_MODIFIER "u.%06" G_GINT64_MODIFIER "u\n", - rs->procedures[i].proc, - rs->procedures[i].num, - (int)(rs->procedures[i].min.secs), - (rs->procedures[i].min.nsecs+500)/1000, - (int)(rs->procedures[i].max.secs), - (rs->procedures[i].max.nsecs+500)/1000, - (td/MICROSECS_PER_SEC), (td%MICROSECS_PER_SEC) - ); - } - printf("===========================================================\n"); + draw_srt_table_data(&rs->scsi_srt_table, TRUE, TRUE); } static void @@ -174,76 +85,68 @@ scsistat_init(const char *opt_arg, void* userdata _U_) guint32 i; int program, pos; const char *filter = NULL; + value_string_ext *cdbnames_ext; GString *error_string; + const char *table_name; pos = 0; if (sscanf(opt_arg, "scsi,srt,%d,%n", &program, &pos) == 1) { if (pos) { filter = opt_arg+pos; - } else { - filter = NULL; } } else { fprintf(stderr, "tshark: invalid \"-z scsi,srt,<cmdset>[,<filter>]\" argument\n"); exit(1); } - scsi_program = program; rs = g_new(scsistat_t,1); - if (filter) { - rs->filter = g_strdup(filter); - } else { - rs->filter = NULL; - } rs->cmdset = program; switch(program) { case SCSI_DEV_SBC: rs->prog = "SBC (disk)"; - rs->cdbnames_ext = &scsi_sbc_vals_ext; + table_name = "SCSI SBC (disk)"; + cdbnames_ext = &scsi_sbc_vals_ext; break; case SCSI_DEV_SSC: rs->prog = "SSC (tape)"; - rs->cdbnames_ext = &scsi_ssc_vals_ext; + table_name = "SCSI SSC (tape)"; + cdbnames_ext = &scsi_ssc_vals_ext; break; case SCSI_DEV_CDROM: rs->prog = "MMC (cd/dvd)"; - rs->cdbnames_ext = &scsi_mmc_vals_ext; + table_name = "SCSI MMC (cd/dvd)"; + cdbnames_ext = &scsi_mmc_vals_ext; break; case SCSI_DEV_SMC: rs->prog = "SMC (tape robot)"; - rs->cdbnames_ext = &scsi_smc_vals_ext; + table_name = "SCSI SMC (tape robot)"; + cdbnames_ext = &scsi_smc_vals_ext; break; case SCSI_DEV_OSD: rs->prog = "OSD (object based)"; - rs->cdbnames_ext = &scsi_osd_vals_ext; + table_name = "SCSI OSD (object based)"; + cdbnames_ext = &scsi_osd_vals_ext; break; default: /* Default to the SBC (disk), since this is what EMC SCSI seem to always be */ rs->cmdset = 0; rs->prog = "SBC (disk)"; - rs->cdbnames_ext = &scsi_sbc_vals_ext; + table_name = "SCSI SBC (disk)"; + cdbnames_ext = &scsi_sbc_vals_ext; break; } - rs->procedures = g_new(scsi_procedure_t,MAX_PROCEDURES); - for(i=0; i < MAX_PROCEDURES; i++) { - rs->procedures[i].proc = val_to_str_ext_wmem(NULL, i, rs->cdbnames_ext, "Unknown-0x%02x"); - rs->procedures[i].num = 0; - rs->procedures[i].min.secs = 0; - rs->procedures[i].min.nsecs = 0; - rs->procedures[i].max.secs = 0; - rs->procedures[i].max.nsecs = 0; - rs->procedures[i].tot.secs = 0; - rs->procedures[i].tot.nsecs = 0; + + init_srt_table(table_name, &rs->scsi_srt_table, SCSI_NUM_PROCEDURES, NULL, filter ? g_strdup(filter) : NULL); + for (i = 0; i < SCSI_NUM_PROCEDURES; i++) + { + init_srt_table_row(&rs->scsi_srt_table, i, val_to_str_ext_const(i, cdbnames_ext, "<unknown>")); } - error_string = register_tap_listener("scsi", rs, filter, 0, scsistat_reset, scsistat_packet, scsistat_draw); + + error_string = register_tap_listener("scsi", rs, filter, 0, NULL, scsistat_packet, scsistat_draw); if (error_string) { /* error, we failed to attach to the tap. clean up */ - for(i=0; i < MAX_PROCEDURES; i++) { - wmem_free(NULL, rs->procedures[i].proc); - } - g_free(rs->procedures); - g_free(rs->filter); + free_srt_table_data(&rs->scsi_srt_table); g_free(rs); fprintf(stderr, "tshark: Couldn't register scsi,srt tap: %s\n", diff --git a/ui/cli/tap-smbstat.c b/ui/cli/tap-smbstat.c index 161ea9fbac..d5f9150c2d 100644 --- a/ui/cli/tap-smbstat.c +++ b/ui/cli/tap-smbstat.c @@ -30,31 +30,26 @@ #include <epan/tap.h> #include <epan/stat_tap_ui.h> #include "epan/value_string.h" +#include <ui/cli/cli_service_response_time_table.h> #include <epan/dissectors/packet-smb.h> #include "epan/timestats.h" -#define MICROSECS_PER_SEC 1000000 -#define NANOSECS_PER_SEC 1000000000 - void register_tap_listener_smbstat(void); +#define SMB_NUM_PROCEDURES 256 + /* used to keep track of the statistics for an entire program interface */ typedef struct _smbstat_t { - char *filter; - timestat_t proc[256]; - timestat_t trans2[256]; - timestat_t nt_trans[256]; + srt_stat_table smb_srt_table; + srt_stat_table trans2_srt_table; + srt_stat_table nt_srt_table; } smbstat_t; - - static int smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi) { smbstat_t *ss = (smbstat_t *)pss; const smb_info_t *si = (const smb_info_t *)psi; - nstime_t t, deltat; - timestat_t *sp = NULL; /* we are only interested in reply packets */ if (si->request) { @@ -70,25 +65,17 @@ smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const voi /*nt transaction*/ if (sti) { - sp = &(ss->nt_trans[sti->subcmd]); + add_srt_table_data(&ss->nt_srt_table, sti->subcmd, &si->sip->req_time, pinfo); } } else if (si->cmd == 0x32 && si->sip->extra_info_type == SMB_EI_T2I) { smb_transact2_info_t *st2i = (smb_transact2_info_t *)si->sip->extra_info; /*transaction2*/ if (st2i) { - sp = &(ss->trans2[st2i->subcmd]); + add_srt_table_data(&ss->trans2_srt_table, st2i->subcmd, &si->sip->req_time, pinfo); } } else { - sp = &(ss->proc[si->cmd]); - } - - /* calculate time delta between request and reply */ - t = pinfo->fd->abs_ts; - nstime_delta(&deltat, &t, &si->sip->req_time); - - if (sp) { - time_stat_update(sp, &deltat, pinfo); + add_srt_table_data(&ss->smb_srt_table,si->cmd, &si->sip->req_time, pinfo); } return 1; @@ -98,93 +85,12 @@ static void smbstat_draw(void *pss) { smbstat_t *ss = (smbstat_t *)pss; - guint32 i; - guint64 td; - gchar* tmp_str; + draw_srt_table_data(&ss->smb_srt_table, TRUE, FALSE); printf("\n"); - printf("=================================================================\n"); - printf("SMB SRT Statistics:\n"); - printf("Filter: %s\n", ss->filter ? ss->filter : ""); - printf("Commands Calls Min SRT Max SRT Avg SRT\n"); - for (i=0; i<256; i++) { - /* nothing seen, nothing to do */ - if (ss->proc[i].num == 0) { - continue; - } - - /* we deal with transaction2 later */ - if (i == 0x32) { - continue; - } - - /* we deal with nt transaction later */ - if (i == 0xA0) { - continue; - } - - /* Scale the average SRT in units of 1us and round to the nearest us. */ - td = ((guint64)(ss->proc[i].tot.secs)) * NANOSECS_PER_SEC + ss->proc[i].tot.nsecs; - - td = ((td / ss->proc[i].num) + 500) / 1000; - - tmp_str = val_to_str_ext_wmem(NULL, i, &smb_cmd_vals_ext, "Unknown (0x%02x)"); - printf("%-25s %6u %3d.%06d %3d.%06d %3" G_GINT64_MODIFIER "u.%06" G_GINT64_MODIFIER "u\n", - tmp_str, - ss->proc[i].num, - (int)(ss->proc[i].min.secs), (ss->proc[i].min.nsecs+500)/1000, - (int)(ss->proc[i].max.secs), (ss->proc[i].max.nsecs+500)/1000, - td/MICROSECS_PER_SEC, td%MICROSECS_PER_SEC - ); - wmem_free(NULL, tmp_str); - } - - printf("\n"); - printf("Transaction2 Commands Calls Min SRT Max SRT Avg SRT\n"); - for (i=0; i<256; i++) { - /* nothing seen, nothing to do */ - if (ss->trans2[i].num == 0) { - continue; - } - - /* Scale the average SRT in units of 1us and round to the nearest us. */ - td = ((guint64)(ss->trans2[i].tot.secs)) * NANOSECS_PER_SEC + ss->trans2[i].tot.nsecs; - td = ((td / ss->trans2[i].num) + 500) / 1000; - - tmp_str = val_to_str_ext_wmem(NULL, i, &trans2_cmd_vals_ext, "Unknown (0x%02x)"); - printf("%-25s %6d %3d.%06d %3d.%06d %3" G_GINT64_MODIFIER "u.%06" G_GINT64_MODIFIER "u\n", - tmp_str, - ss->trans2[i].num, - (int)(ss->trans2[i].min.secs), (ss->trans2[i].min.nsecs+500)/1000, - (int)(ss->trans2[i].max.secs), (ss->trans2[i].max.nsecs+500)/1000, - td/MICROSECS_PER_SEC, td%MICROSECS_PER_SEC - ); - wmem_free(NULL, tmp_str); - } - + draw_srt_table_data(&ss->trans2_srt_table, FALSE, FALSE); printf("\n"); - printf("NT Transaction Commands Calls Min SRT Max SRT Avg SRT\n"); - for (i=0; i<256; i++) { - /* nothing seen, nothing to do */ - if (ss->nt_trans[i].num == 0) { - continue; - } - /* Scale the average SRT in units of 1us and round to the nearest us. */ - td = ((guint64)(ss->nt_trans[i].tot.secs)) * NANOSECS_PER_SEC + ss->nt_trans[i].tot.nsecs; - td = ((td / ss->nt_trans[i].num) + 500) / 1000; - - tmp_str = val_to_str_ext_wmem(NULL, i, &nt_cmd_vals_ext, "Unknown (0x%02x)"); - printf("%-25s %6d %3d.%06d %3d.%06d %3" G_GINT64_MODIFIER "u.%06" G_GINT64_MODIFIER "u\n", - tmp_str, - ss->nt_trans[i].num, - (int)(ss->nt_trans[i].min.secs), (ss->nt_trans[i].min.nsecs+500)/1000, - (int)(ss->nt_trans[i].max.secs), (ss->nt_trans[i].max.nsecs+500)/1000, - td/MICROSECS_PER_SEC, td%MICROSECS_PER_SEC - ); - wmem_free(NULL, tmp_str); - } - - printf("=================================================================\n"); + draw_srt_table_data(&ss->nt_srt_table, FALSE, TRUE); } @@ -198,53 +104,26 @@ smbstat_init(const char *opt_arg, void *userdata _U_) if (!strncmp(opt_arg, "smb,srt,", 8)) { filter = opt_arg + 8; - } else { - filter = NULL; } ss = g_new(smbstat_t, 1); - if (filter) { - ss->filter = g_strdup(filter); - } else { - ss->filter = NULL; - } - - for (i=0; i<256; i++) { - ss->proc[i].num = 0; - ss->proc[i].min_num = 0; - ss->proc[i].max_num = 0; - ss->proc[i].min.secs = 0; - ss->proc[i].min.nsecs = 0; - ss->proc[i].max.secs = 0; - ss->proc[i].max.nsecs = 0; - ss->proc[i].tot.secs = 0; - ss->proc[i].tot.nsecs = 0; - - ss->trans2[i].num = 0; - ss->trans2[i].min_num = 0; - ss->trans2[i].max_num = 0; - ss->trans2[i].min.secs = 0; - ss->trans2[i].min.nsecs = 0; - ss->trans2[i].max.secs = 0; - ss->trans2[i].max.nsecs = 0; - ss->trans2[i].tot.secs = 0; - ss->trans2[i].tot.nsecs = 0; - ss->nt_trans[i].num = 0; - ss->nt_trans[i].min_num = 0; - ss->nt_trans[i].max_num = 0; - ss->nt_trans[i].min.secs = 0; - ss->nt_trans[i].min.nsecs = 0; - ss->nt_trans[i].max.secs = 0; - ss->nt_trans[i].max.nsecs = 0; - ss->nt_trans[i].tot.secs = 0; - ss->nt_trans[i].tot.nsecs = 0; + init_srt_table("SMB", &ss->smb_srt_table, SMB_NUM_PROCEDURES, "Commands", filter ? g_strdup(filter) : NULL); + init_srt_table("SMB", &ss->trans2_srt_table, SMB_NUM_PROCEDURES, "Transaction2 Commands", filter ? g_strdup(filter) : NULL); + init_srt_table("SMB", &ss->nt_srt_table, SMB_NUM_PROCEDURES, "NT Transaction Commands", filter ? g_strdup(filter) : NULL); + for (i = 0; i < SMB_NUM_PROCEDURES; i++) + { + init_srt_table_row(&ss->smb_srt_table, i, val_to_str_ext_const(i, &smb_cmd_vals_ext, "<unknown>")); + init_srt_table_row(&ss->trans2_srt_table, i, val_to_str_ext_const(i, &trans2_cmd_vals_ext, "<unknown>")); + init_srt_table_row(&ss->nt_srt_table, i, val_to_str_ext_const(i, &nt_cmd_vals_ext, "<unknown>")); } error_string = register_tap_listener("smb", ss, filter, 0, NULL, smbstat_packet, smbstat_draw); if (error_string) { /* error, we failed to attach to the tap. clean up */ - g_free(ss->filter); + free_srt_table_data(&ss->smb_srt_table); + free_srt_table_data(&ss->trans2_srt_table); + free_srt_table_data(&ss->nt_srt_table); g_free(ss); fprintf(stderr, "tshark: Couldn't register smb,srt tap: %s\n", |