forked from osmocom/wireshark
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>
This commit is contained in:
parent
8c996a2736
commit
0b368ea23f
|
@ -1116,6 +1116,7 @@ if(ENABLE_EXTCAP)
|
|||
endif()
|
||||
|
||||
set(TSHARK_TAP_SRC
|
||||
ui/cli/cli_service_response_time_table.c
|
||||
ui/cli/tap-afpstat.c
|
||||
ui/cli/tap-ansi_astat.c
|
||||
ui/cli/tap-bootpstat.c
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
*/
|
|
@ -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__ */
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
draw_srt_table_data(&ss->trans2_srt_table, FALSE, FALSE);
|
||||
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);
|
||||
}
|
||||
|
||||
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",
|
||||
|
|
Loading…
Reference in New Issue