aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2015-06-16 17:07:04 -0400
committerMichael Mann <mmann78@netscape.net>2015-06-21 03:35:13 +0000
commit6de6f7f0f8f8b79c4fc7473c7e54dad433c7b61b (patch)
tree20b4b81b49467f5685f51c6b75e240c41ca6cb32 /epan/dissectors
parent2895d58dc38321a72c82e1bf77d165ef4acbc73a (diff)
Further refactor SRT stats.
Create "common" SRT tap data collection intended for all GUIs. Refactor/merge functionality of existing dissectors that have SRT support (AFP, DCERPC, Diameter, FC, GTP, LDAP, NCP, RPC, SCIS, SMB, and SMB2) for both TShark and GTK. SMB and DCERPC "tap packet filtering" were different between TShark and GTK, so I went with GTK filter logic. CAMEL "tap packet filtering" was different between TShark and GTK, so GTK filtering logic was pushed to the dissector and the TShark tap was left alone. Change-Id: I7d6eaad0673fe628ef337f9165d7ed94f4a5e1cc Reviewed-on: https://code.wireshark.org/review/8894 Petri-Dish: Michael Mann <mmann78@netscape.net> Reviewed-by: Gerald Combs <gerald@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-afp.c42
-rw-r--r--epan/dissectors/packet-camel.c60
-rw-r--r--epan/dissectors/packet-dcerpc.c160
-rw-r--r--epan/dissectors/packet-dcerpc.h8
-rw-r--r--epan/dissectors/packet-diameter.c64
-rw-r--r--epan/dissectors/packet-fc.c43
-rw-r--r--epan/dissectors/packet-gtp.c58
-rw-r--r--epan/dissectors/packet-ldap.c67
-rw-r--r--epan/dissectors/packet-ncp.c250
-rw-r--r--epan/dissectors/packet-rpc.c128
-rw-r--r--epan/dissectors/packet-rpc.h8
-rw-r--r--epan/dissectors/packet-scsi.c108
-rw-r--r--epan/dissectors/packet-smb.c72
-rw-r--r--epan/dissectors/packet-smb2.c49
14 files changed, 1100 insertions, 17 deletions
diff --git a/epan/dissectors/packet-afp.c b/epan/dissectors/packet-afp.c
index 2f89b82f20..e317af7b10 100644
--- a/epan/dissectors/packet-afp.c
+++ b/epan/dissectors/packet-afp.c
@@ -32,6 +32,7 @@
#include <epan/to_str.h>
#include <epan/conversation.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/expert.h>
#include "packet-afp.h"
@@ -1094,6 +1095,45 @@ static const value_string afp_server_addr_type_vals[] = {
{0, NULL } };
value_string_ext afp_server_addr_type_vals_ext = VALUE_STRING_EXT_INIT(afp_server_addr_type_vals);
+#define AFP_NUM_PROCEDURES 256
+
+static void
+afpstat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ srt_stat_table *afp_srt_table;
+ guint32 i;
+
+ afp_srt_table = init_srt_table("AFP Commands", NULL, srt_array, AFP_NUM_PROCEDURES, NULL, "afp.command", gui_callback, gui_data, 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(afp_srt_table, i, tmp_str);
+ wmem_free(NULL, tmp_str);
+ }
+}
+
+static int
+afpstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *afp_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const afp_request_val *request_val = (const afp_request_val *)prv;
+
+ /* if we haven't seen the request, just ignore it */
+ if (!request_val) {
+ return 0;
+ }
+
+ afp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+
+ add_srt_table_data(afp_srt_table, request_val->command, &request_val->req_time, pinfo);
+
+ return 1;
+}
+
+
+
#define hash_init_count 20
/* Forward declarations */
@@ -7232,6 +7272,8 @@ proto_register_afp(void)
new_register_dissector("afp_spotlight", dissect_spotlight, proto_afp);
afp_tap = register_tap("afp");
+
+ register_srt_table(proto_afp, NULL, 1, afpstat_packet, afpstat_init, NULL);
}
void
diff --git a/epan/dissectors/packet-camel.c b/epan/dissectors/packet-camel.c
index 74f917ddf8..80fbdcbde6 100644
--- a/epan/dissectors/packet-camel.c
+++ b/epan/dissectors/packet-camel.c
@@ -47,6 +47,7 @@
#include <epan/prefs.h>
#include <epan/oids.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/asn1.h>
#include <epan/expert.h>
@@ -605,7 +606,7 @@ static int hf_camel_present = -1; /* INTEGER */
static int hf_camel_InvokeId_present = -1; /* InvokeId_present */
/*--- End of included file: packet-camel-hf.c ---*/
-#line 112 "../../asn1/camel/packet-camel-template.c"
+#line 113 "../../asn1/camel/packet-camel-template.c"
static struct camelsrt_info_t * gp_camelsrt_info;
@@ -835,7 +836,7 @@ static gint ett_camel_T_problem = -1;
static gint ett_camel_InvokeId = -1;
/*--- End of included file: packet-camel-ett.c ---*/
-#line 143 "../../asn1/camel/packet-camel-template.c"
+#line 144 "../../asn1/camel/packet-camel-template.c"
static expert_field ei_camel_unknown_invokeData = EI_INIT;
static expert_field ei_camel_unknown_returnResultData = EI_INIT;
@@ -1180,7 +1181,7 @@ static const value_string camel_ectTreatmentIndicator_values[] = {
#define noInvokeId NULL
/*--- End of included file: packet-camel-val.h ---*/
-#line 303 "../../asn1/camel/packet-camel-template.c"
+#line 304 "../../asn1/camel/packet-camel-template.c"
/*--- Included file: packet-camel-table.c ---*/
@@ -1270,7 +1271,7 @@ static const value_string camel_err_code_string_vals[] = {
/*--- End of included file: packet-camel-table.c ---*/
-#line 305 "../../asn1/camel/packet-camel-template.c"
+#line 306 "../../asn1/camel/packet-camel-template.c"
/*
* DEBUG fonctions
@@ -1294,6 +1295,45 @@ static void dbg(guint level, char *fmt, ...) {
}
#endif
+static void
+camelstat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ srt_stat_table *camel_srt_table;
+ gchar* tmp_str;
+ guint32 i;
+
+ camel_srt_table = init_srt_table("CAMEL Commands", NULL, srt_array, NB_CAMELSRT_CATEGORY, NULL, NULL, gui_callback, gui_data, NULL);
+ for (i = 0; i < NB_CAMELSRT_CATEGORY; i++)
+ {
+ tmp_str = val_to_str_wmem(NULL,i,camelSRTtype_naming,"Unknown (%d)");
+ init_srt_table_row(camel_srt_table, i, tmp_str);
+ wmem_free(NULL, tmp_str);
+ }
+}
+
+static int
+camelstat_packet(void *pcamel, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi)
+{
+ guint idx = 0;
+ srt_stat_table *camel_srt_table;
+ const struct camelsrt_info_t * pi=(const struct camelsrt_info_t *)psi;
+ srt_data_t *data = (srt_data_t *)pcamel;
+ int i;
+
+ for (i=1; i<NB_CAMELSRT_CATEGORY; i++) {
+ if ( pi->bool_msginfo[i] &&
+ pi->msginfo[i].is_delta_time
+ && pi->msginfo[i].request_available
+ && !pi->msginfo[i].is_duplicate )
+ {
+ camel_srt_table = g_array_index(data->srt_array, srt_stat_table*, idx);
+ add_srt_table_data(camel_srt_table, i, &pi->msginfo[i].req_time, pinfo);
+ }
+ } /* category */
+ return 1;
+}
+
+
static char camel_number_to_char(int number)
{
if (number < 10)
@@ -7071,7 +7111,7 @@ static int dissect_CAP_U_ABORT_REASON_PDU(tvbuff_t *tvb _U_, packet_info *pinfo
/*--- End of included file: packet-camel-fn.c ---*/
-#line 374 "../../asn1/camel/packet-camel-template.c"
+#line 414 "../../asn1/camel/packet-camel-template.c"
/*--- Included file: packet-camel-table2.c ---*/
@@ -7278,7 +7318,7 @@ static int dissect_returnErrorData(proto_tree *tree, tvbuff_t *tvb, int offset,a
/*--- End of included file: packet-camel-table2.c ---*/
-#line 376 "../../asn1/camel/packet-camel-template.c"
+#line 416 "../../asn1/camel/packet-camel-template.c"
/*
* Functions needed for Hash-Table
@@ -8130,7 +8170,7 @@ void proto_reg_handoff_camel(void) {
/*--- End of included file: packet-camel-dis-tab.c ---*/
-#line 1220 "../../asn1/camel/packet-camel-template.c"
+#line 1260 "../../asn1/camel/packet-camel-template.c"
} else {
range_foreach(ssn_range, range_delete_callback);
g_free(ssn_range);
@@ -10244,7 +10284,7 @@ void proto_register_camel(void) {
"InvokeId_present", HFILL }},
/*--- End of included file: packet-camel-hfarr.c ---*/
-#line 1393 "../../asn1/camel/packet-camel-template.c"
+#line 1433 "../../asn1/camel/packet-camel-template.c"
};
/* List of subtrees */
@@ -10460,7 +10500,7 @@ void proto_register_camel(void) {
&ett_camel_InvokeId,
/*--- End of included file: packet-camel-ettarr.c ---*/
-#line 1410 "../../asn1/camel/packet-camel-template.c"
+#line 1450 "../../asn1/camel/packet-camel-template.c"
};
static ei_register_info ei[] = {
@@ -10525,5 +10565,7 @@ void proto_register_camel(void) {
/* Routine for statistic */
register_init_routine(&camelsrt_init_routine);
camel_tap=register_tap(PSNAME);
+
+ register_srt_table(proto_camel, "CAMEL", 1, camelstat_packet, camelstat_init, NULL);
}
diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c
index 72acdedb37..8c64e46984 100644
--- a/epan/dissectors/packet-dcerpc.c
+++ b/epan/dissectors/packet-dcerpc.c
@@ -29,12 +29,13 @@
#include "config.h"
-
+#include <stdio.h>
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <epan/prefs.h>
#include <epan/reassemble.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/expert.h>
#include <epan/addr_resolv.h>
#include <epan/show_exception.h>
@@ -1479,6 +1480,161 @@ dcerpc_matched_hash(gconstpointer k)
return key->frame;
}
+static gboolean
+uuid_equal(e_guid_t *uuid1, e_guid_t *uuid2)
+{
+ if( (uuid1->data1 != uuid2->data1)
+ ||(uuid1->data2 != uuid2->data2)
+ ||(uuid1->data3 != uuid2->data3)
+ ||(uuid1->data4[0] != uuid2->data4[0])
+ ||(uuid1->data4[1] != uuid2->data4[1])
+ ||(uuid1->data4[2] != uuid2->data4[2])
+ ||(uuid1->data4[3] != uuid2->data4[3])
+ ||(uuid1->data4[4] != uuid2->data4[4])
+ ||(uuid1->data4[5] != uuid2->data4[5])
+ ||(uuid1->data4[6] != uuid2->data4[6])
+ ||(uuid1->data4[7] != uuid2->data4[7]) ){
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+dcerpcstat_init(struct register_srt* srt, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ dcerpcstat_tap_data_t* tap_data = (dcerpcstat_tap_data_t*)get_srt_table_param_data(srt);
+ srt_stat_table *dcerpc_srt_table;
+ int i, hf_opnum;
+ dcerpc_sub_dissector *procs;
+
+ DISSECTOR_ASSERT(tap_data);
+
+ hf_opnum = dcerpc_get_proto_hf_opnum(&tap_data->uuid, tap_data->ver);
+ procs = dcerpc_get_proto_sub_dissector(&tap_data->uuid, tap_data->ver);
+
+ if(hf_opnum != -1){
+ dcerpc_srt_table = init_srt_table(tap_data->prog, NULL, srt_array, tap_data->num_procedures, NULL, proto_registrar_get_nth(hf_opnum)->abbrev, gui_callback, gui_data, tap_data);
+ } else {
+ dcerpc_srt_table = init_srt_table(tap_data->prog, NULL, srt_array, tap_data->num_procedures, NULL, NULL, gui_callback, gui_data, tap_data);
+ }
+
+ for(i=0;i<tap_data->num_procedures;i++){
+ int j;
+ const char *proc_name;
+
+ proc_name = "unknown";
+ for(j=0;procs[j].name;j++)
+ {
+ if (procs[j].num == i)
+ {
+ proc_name = procs[j].name;
+ }
+ }
+
+ init_srt_table_row(dcerpc_srt_table, i, proc_name);
+ }
+}
+
+static int
+dcerpcstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *dcerpc_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const dcerpc_info *ri = (dcerpc_info *)prv;
+ dcerpcstat_tap_data_t* tap_data;
+
+ dcerpc_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ tap_data = (dcerpcstat_tap_data_t*)dcerpc_srt_table->table_specific_data;
+
+ if(!ri->call_data){
+ return 0;
+ }
+ if(!ri->call_data->req_frame){
+ /* we have not seen the request so we don't know the delta*/
+ return 0;
+ }
+ if(ri->call_data->opnum >= tap_data->num_procedures){
+ /* don't handle this since it's outside of known table */
+ return 0;
+ }
+
+ /* we are only interested in reply packets */
+ if(ri->ptype != PDU_RESP){
+ return 0;
+ }
+
+ /* we are only interested in certain program/versions */
+ if( (!uuid_equal( (&ri->call_data->uuid), (&tap_data->uuid)))
+ ||(ri->call_data->ver != tap_data->ver)){
+ return 0;
+ }
+
+ add_srt_table_data(dcerpc_srt_table, ri->call_data->opnum, &ri->call_data->req_time, pinfo);
+
+ return 1;
+}
+
+static guint
+dcerpcstat_param(register_srt_t* srt, const char* opt_arg, char** err)
+{
+ guint pos = 0;
+ guint32 i, max_procs;
+ dcerpcstat_tap_data_t* tap_data;
+ guint d1,d2,d3,d40,d41,d42,d43,d44,d45,d46,d47;
+ int major, minor;
+ guint16 ver;
+ dcerpc_sub_dissector *procs;
+
+ if (sscanf(opt_arg, ",%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x,%d.%d,%n",
+ &d1,&d2,&d3,&d40,&d41,&d42,&d43,&d44,&d45,&d46,&d47,&major,&minor,&pos) == 13)
+ {
+ if ((major < 0) || (major > 65535)) {
+ *err = g_strdup_printf("dcerpcstat_init() Major version number %d is invalid - must be positive and <= 65535", major);
+ return pos;
+ }
+ if ((minor < 0) || (minor > 65535)) {
+ *err = g_strdup_printf("dcerpcstat_init() Minor version number %d is invalid - must be positive and <= 65535", minor);
+ return pos;
+ }
+ ver = major;
+
+ tap_data = g_new0(dcerpcstat_tap_data_t, 1);
+
+ tap_data->uuid.data1 = d1;
+ tap_data->uuid.data2 = d2;
+ tap_data->uuid.data3 = d3;
+ tap_data->uuid.data4[0] = d40;
+ tap_data->uuid.data4[1] = d41;
+ tap_data->uuid.data4[2] = d42;
+ tap_data->uuid.data4[3] = d43;
+ tap_data->uuid.data4[4] = d44;
+ tap_data->uuid.data4[5] = d45;
+ tap_data->uuid.data4[6] = d46;
+ tap_data->uuid.data4[7] = d47;
+
+ procs = dcerpc_get_proto_sub_dissector(&tap_data->uuid, ver);
+ tap_data->prog = dcerpc_get_proto_name(&tap_data->uuid, ver);
+ tap_data->ver = ver;
+
+ for(i=0,max_procs=0;procs[i].name;i++)
+ {
+ if(procs[i].num>max_procs)
+ {
+ max_procs = procs[i].num;
+ }
+ }
+ tap_data->num_procedures = max_procs+1;
+
+ set_srt_table_param_data(srt, tap_data);
+ }
+ else
+ {
+ *err = g_strdup_printf("<uuid>,<major version>.<minor version>[,<filter>]");
+ }
+
+ return pos;
+}
/*
@@ -6384,6 +6540,8 @@ proto_register_dcerpc(void)
dcerpc_tap = register_tap("dcerpc");
register_decode_as(&dcerpc_da);
+
+ register_srt_table(proto_dcerpc, NULL, 1, dcerpcstat_packet, dcerpcstat_init, dcerpcstat_param);
}
void
diff --git a/epan/dissectors/packet-dcerpc.h b/epan/dissectors/packet-dcerpc.h
index 2db4d8e5ab..c9222bfb9c 100644
--- a/epan/dissectors/packet-dcerpc.h
+++ b/epan/dissectors/packet-dcerpc.h
@@ -108,6 +108,14 @@ typedef struct _dcerpc_auth_info {
tvbuff_t *auth_data;
} dcerpc_auth_info;
+typedef struct dcerpcstat_tap_data
+{
+ const char *prog;
+ e_guid_t uuid;
+ guint16 ver;
+ int num_procedures;
+} dcerpcstat_tap_data_t;
+
/* Private data passed to subdissectors from the main DCERPC dissector.
* One unique instance of this structure is created for each
* DCERPC request/response transaction when we see the initial request
diff --git a/epan/dissectors/packet-diameter.c b/epan/dissectors/packet-diameter.c
index 8f2045170c..b4e3e4a4ae 100644
--- a/epan/dissectors/packet-diameter.c
+++ b/epan/dissectors/packet-diameter.c
@@ -48,6 +48,7 @@
#include <epan/sminmpec.h>
#include <epan/expert.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/exported_pdu.h>
#include <epan/diam_dict.h>
#include <epan/sctpppids.h>
@@ -365,6 +366,67 @@ compare_avps(const void *a, const void *b)
return 0;
}
+static GHashTable* diameterstat_cmd_str_hash = NULL;
+#define DIAMETER_NUM_PROCEDURES 1
+
+static void
+diameterstat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ srt_stat_table *diameter_srt_table;
+ int* idx;
+
+ /* XXX - This is a hack/workaround support so reseting/freeing parameters at the dissector
+ level doesn't need to be supported. */
+ if (diameterstat_cmd_str_hash != NULL)
+ {
+ g_hash_table_destroy(diameterstat_cmd_str_hash);
+ }
+
+ idx = (int *)g_malloc(sizeof(int));
+ *idx = 0;
+ diameterstat_cmd_str_hash = g_hash_table_new(g_str_hash,g_str_equal);
+ g_hash_table_insert(diameterstat_cmd_str_hash, (gchar *)"Unknown", idx);
+
+ /** @todo the filter to use in stead of NULL is "diameter.cmd.code"
+ * to enable the filter popup in the service response time dalouge
+ * Note to make it work the command code must be stored rather than the
+ * index.
+ */
+ diameter_srt_table = init_srt_table("Diameter Requests", NULL, srt_array, DIAMETER_NUM_PROCEDURES, NULL, NULL, gui_callback, gui_data, NULL);
+ init_srt_table_row(diameter_srt_table, 0, "Unknown");
+}
+
+static int
+diameterstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *diameter_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const diameter_req_ans_pair_t *diameter=(const diameter_req_ans_pair_t *)prv;
+ int* idx = NULL;
+
+ /* Process only answers where corresponding request is found.
+ * Unpaired daimeter messages are currently not supported by statistics.
+ * Return 0, since redraw is not needed. */
+ if(!diameter || diameter->processing_request || !diameter->req_frame)
+ return 0;
+
+ diameter_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+
+ idx = (int*) g_hash_table_lookup(diameterstat_cmd_str_hash, diameter->cmd_str);
+ if (idx == NULL) {
+ idx = (int *)g_malloc(sizeof(int));
+ *idx = (int) g_hash_table_size(diameterstat_cmd_str_hash);
+ g_hash_table_insert(diameterstat_cmd_str_hash, (gchar*) diameter->cmd_str, idx);
+ init_srt_table_row(diameter_srt_table, *idx, (const char*) diameter->cmd_str);
+ }
+
+ add_srt_table_data(diameter_srt_table, *idx, &diameter->req_time, pinfo);
+
+ return 1;
+}
+
+
/* Special decoding of some AVPs */
static int
@@ -2200,6 +2262,8 @@ real_proto_register_diameter(void)
/* Register tap */
diameter_tap = register_tap("diameter");
+
+ register_srt_table(proto_diameter, NULL, 1, diameterstat_packet, diameterstat_init, NULL);
}
void
diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c
index 900a19ac47..a4c3ef2307 100644
--- a/epan/dissectors/packet-fc.c
+++ b/epan/dissectors/packet-fc.c
@@ -33,6 +33,7 @@
#include <epan/reassemble.h>
#include <epan/conversation_table.h>
#include <epan/etypes.h>
+#include <epan/srt_table.h>
#include "packet-fc.h"
#include "packet-fclctl.h"
#include "packet-fcbls.h"
@@ -253,6 +254,47 @@ fc_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const
return 1;
}
+#define FC_NUM_PROCEDURES 256
+
+static void
+fcstat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ srt_stat_table *fc_srt_table;
+ guint32 i;
+
+ fc_srt_table = init_srt_table("Fibre Channel Types", NULL, srt_array, FC_NUM_PROCEDURES, NULL, NULL, gui_callback, gui_data, NULL);
+ for (i = 0; i < FC_NUM_PROCEDURES; i++)
+ {
+ gchar* tmp_str = val_to_str_wmem(NULL, i, fc_fc4_val, "Unknown(0x%02x)");
+ init_srt_table_row(fc_srt_table, i, tmp_str);
+ wmem_free(NULL, tmp_str);
+ }
+}
+
+static int
+fcstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *fc_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const fc_hdr *fc=(const fc_hdr *)prv;
+
+ /* we are only interested in reply packets */
+ if(!(fc->fctl&FC_FCTL_EXCHANGE_RESPONDER)){
+ return 0;
+ }
+ /* if we havnt seen the request, just ignore it */
+ if ( (!fc->fc_ex) || (fc->fc_ex->first_exchange_frame==0) ){
+ return 0;
+ }
+
+ fc_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ add_srt_table_data(fc_srt_table, fc->type, &fc->fc_ex->fc_time, pinfo);
+
+ return 1;
+}
+
+
const value_string fc_fc4_val[] = {
{FC_TYPE_BLS, "Basic Link Svc"},
{FC_TYPE_ELS, "Ext Link Svc"},
@@ -1544,6 +1586,7 @@ proto_register_fc(void)
fcsof_handle = register_dissector("fcsof", dissect_fcsof, proto_fcsof);
register_conversation_table(proto_fc, TRUE, fc_conversation_packet, fc_hostlist_packet);
+ register_srt_table(proto_fc, NULL, 1, fcstat_packet, fcstat_init, NULL);
}
diff --git a/epan/dissectors/packet-gtp.c b/epan/dissectors/packet-gtp.c
index 5270cf93bf..37de190955 100644
--- a/epan/dissectors/packet-gtp.c
+++ b/epan/dissectors/packet-gtp.c
@@ -59,6 +59,7 @@
#include <epan/sminmpec.h>
#include <epan/asn1.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/to_str.h>
#include "packet-ppp.h"
#include "packet-radius.h"
@@ -1767,6 +1768,61 @@ static const value_string tft_code_type[] = {
{0, NULL}
};
+static void
+gtpstat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ srt_stat_table *gtp_srt_table;
+
+ gtp_srt_table = init_srt_table("GTP Requests", NULL, srt_array, 4, NULL, NULL, gui_callback, gui_data, NULL);
+ init_srt_table_row(gtp_srt_table, 0, "Echo");
+ init_srt_table_row(gtp_srt_table, 1, "Create PDP context");
+ init_srt_table_row(gtp_srt_table, 2, "Update PDP context");
+ init_srt_table_row(gtp_srt_table, 3, "Delete PDP context");
+}
+
+static int
+gtpstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *gtp_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const gtp_msg_hash_t *gtp=(const gtp_msg_hash_t *)prv;
+ int idx=0;
+
+ /* we are only interested in reply packets */
+ if(gtp->is_request){
+ return 0;
+ }
+ /* if we have not seen the request, just ignore it */
+ if(!gtp->req_frame){
+ return 0;
+ }
+
+ /* Only use the commands we know how to handle, this is not a comprehensive list */
+ /* Redoing the message indexing is bit reduntant, */
+ /* but using message type as such would yield a long gtp_srt_table. */
+ /* Only a fraction of the messages are matchable req/resp pairs, */
+ /* it just doesn't feel feasible. */
+
+ switch(gtp->msgtype){
+ case GTP_MSG_ECHO_REQ: idx=0;
+ break;
+ case GTP_MSG_CREATE_PDP_REQ: idx=1;
+ break;
+ case GTP_MSG_UPDATE_PDP_REQ: idx=2;
+ break;
+ case GTP_MSG_DELETE_PDP_REQ: idx=3;
+ break;
+ default:
+ return 0;
+ }
+
+ gtp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ add_srt_table_data(gtp_srt_table, idx, &gtp->req_time, pinfo);
+
+ return 1;
+}
+
static dissector_handle_t ip_handle;
static dissector_handle_t ipv6_handle;
@@ -9734,6 +9790,8 @@ proto_register_gtp(void)
register_init_routine(gtp_reinit);
gtp_tap = register_tap("gtp");
gtpv1_tap = register_tap("gtpv1");
+
+ register_srt_table(proto_gtp, NULL, 1, gtpstat_packet, gtpstat_init, NULL);
}
/* TS 132 295 V9.0.0 (2010-02)
* 5.1.3 Port usage
diff --git a/epan/dissectors/packet-ldap.c b/epan/dissectors/packet-ldap.c
index 1533178f25..7366cb31d3 100644
--- a/epan/dissectors/packet-ldap.c
+++ b/epan/dissectors/packet-ldap.c
@@ -95,6 +95,7 @@
#include <epan/conversation.h>
#include <epan/prefs.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/oids.h>
#include <epan/strutil.h>
#include <epan/show_exception.h>
@@ -342,7 +343,7 @@ static int hf_ldap_graceAuthNsRemaining = -1; /* INTEGER_0_maxInt */
static int hf_ldap_error = -1; /* T_error */
/*--- End of included file: packet-ldap-hf.c ---*/
-#line 192 "../../asn1/ldap/packet-ldap-template.c"
+#line 193 "../../asn1/ldap/packet-ldap-template.c"
/* Initialize the subtree pointers */
static gint ett_ldap = -1;
@@ -414,7 +415,7 @@ static gint ett_ldap_PasswordPolicyResponseValue = -1;
static gint ett_ldap_T_warning = -1;
/*--- End of included file: packet-ldap-ett.c ---*/
-#line 204 "../../asn1/ldap/packet-ldap-template.c"
+#line 205 "../../asn1/ldap/packet-ldap-template.c"
static expert_field ei_ldap_exceeded_filter_length = EI_INIT;
static expert_field ei_ldap_too_many_filter_elements = EI_INIT;
@@ -513,6 +514,59 @@ static const value_string netlogon_opcode_vals[] = {
{ 0, NULL }
};
+#define LDAP_NUM_PROCEDURES 24
+
+static void
+ldapstat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ srt_stat_table *ldap_srt_table;
+ guint32 i;
+
+ ldap_srt_table = init_srt_table("LDAP Commands", NULL, srt_array, LDAP_NUM_PROCEDURES, NULL, "ldap.protocolOp", gui_callback, gui_data, NULL);
+ for (i = 0; i < LDAP_NUM_PROCEDURES; i++)
+ {
+ init_srt_table_row(ldap_srt_table, i, val_to_str_const(i, ldap_procedure_names, "<unknown>"));
+ }
+}
+
+static int
+ldapstat_packet(void *pldap, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi)
+{
+ guint i = 0;
+ srt_stat_table *ldap_srt_table;
+ const ldap_call_response_t *ldap=(const ldap_call_response_t *)psi;
+ srt_data_t *data = (srt_data_t *)pldap;
+
+ /* we are only interested in reply packets */
+ if(ldap->is_request){
+ return 0;
+ }
+ /* if we havnt seen the request, just ignore it */
+ if(!ldap->req_frame){
+ return 0;
+ }
+
+ /* only use the commands we know how to handle */
+ switch(ldap->protocolOpTag){
+ case LDAP_REQ_BIND:
+ case LDAP_REQ_SEARCH:
+ case LDAP_REQ_MODIFY:
+ case LDAP_REQ_ADD:
+ case LDAP_REQ_DELETE:
+ case LDAP_REQ_MODRDN:
+ case LDAP_REQ_COMPARE:
+ case LDAP_REQ_EXTENDED:
+ break;
+ default:
+ return 0;
+ }
+
+ ldap_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+
+ add_srt_table_data(ldap_srt_table, ldap->protocolOpTag, &ldap->req_time, pinfo);
+ return 1;
+}
+
/*
* Data structure attached to a conversation, giving authentication
* information from a bind request.
@@ -3781,7 +3835,7 @@ static int dissect_PasswordPolicyResponseValue_PDU(tvbuff_t *tvb _U_, packet_inf
/*--- End of included file: packet-ldap-fn.c ---*/
-#line 866 "../../asn1/ldap/packet-ldap-template.c"
+#line 920 "../../asn1/ldap/packet-ldap-template.c"
static int dissect_LDAPMessage_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ldap_conv_info_t *ldap_info) {
int offset = 0;
@@ -5647,7 +5701,7 @@ void proto_register_ldap(void) {
NULL, HFILL }},
/*--- End of included file: packet-ldap-hfarr.c ---*/
-#line 2163 "../../asn1/ldap/packet-ldap-template.c"
+#line 2217 "../../asn1/ldap/packet-ldap-template.c"
};
/* List of subtrees */
@@ -5721,7 +5775,7 @@ void proto_register_ldap(void) {
&ett_ldap_T_warning,
/*--- End of included file: packet-ldap-ettarr.c ---*/
-#line 2177 "../../asn1/ldap/packet-ldap-template.c"
+#line 2231 "../../asn1/ldap/packet-ldap-template.c"
};
/* UAT for header fields */
static uat_field_t custom_attribute_types_uat_fields[] = {
@@ -5796,6 +5850,7 @@ void proto_register_ldap(void) {
ldap_name_dissector_table = register_dissector_table("ldap.name", "LDAP Attribute Type Dissectors", FT_STRING, BASE_NONE);
+ register_srt_table(proto_ldap, NULL, 1, ldapstat_packet, ldapstat_init, NULL);
}
@@ -5887,7 +5942,7 @@ proto_reg_handoff_ldap(void)
/*--- End of included file: packet-ldap-dis-tab.c ---*/
-#line 2326 "../../asn1/ldap/packet-ldap-template.c"
+#line 2381 "../../asn1/ldap/packet-ldap-template.c"
}
diff --git a/epan/dissectors/packet-ncp.c b/epan/dissectors/packet-ncp.c
index 85ebe0b3a8..3caabaedea 100644
--- a/epan/dissectors/packet-ncp.c
+++ b/epan/dissectors/packet-ncp.c
@@ -45,6 +45,7 @@
#include <epan/packet.h>
#include <epan/prefs.h>
+#include <epan/srt_table.h>
#include "packet-ipx.h"
#include "packet-tcp.h"
#include "packet-ncp-int.h"
@@ -190,6 +191,253 @@ static const value_string ncp_oplock_vals[] = {
{ 0, NULL }
};
+enum ncp_table_values
+{
+ NCP_NCP_SRT_TABLE_INDEX = 0,
+ NCP_NDS_SRT_TABLE_INDEX,
+ NCP_FUNC_SRT_TABLE_INDEX,
+ NCP_SSS_SRT_TABLE_INDEX,
+ NCP_NMAS_SRT_TABLE_INDEX,
+ NCP_SUB17_SRT_TABLE_INDEX,
+ NCP_SUB21_SRT_TABLE_INDEX,
+ NCP_SUB22_SRT_TABLE_INDEX,
+ NCP_SUB23_SRT_TABLE_INDEX,
+ NCP_SUB32_SRT_TABLE_INDEX,
+ NCP_SUB34_SRT_TABLE_INDEX,
+ NCP_SUB35_SRT_TABLE_INDEX,
+ NCP_SUB36_SRT_TABLE_INDEX,
+ NCP_SUB86_SRT_TABLE_INDEX,
+ NCP_SUB87_SRT_TABLE_INDEX,
+ NCP_SUB89_SRT_TABLE_INDEX,
+ NCP_SUB90_SRT_TABLE_INDEX,
+ NCP_SUB92_SRT_TABLE_INDEX,
+ NCP_SUB94_SRT_TABLE_INDEX,
+ NCP_SUB104_SRT_TABLE_INDEX,
+ NCP_SUB111_SRT_TABLE_INDEX,
+ NCP_SUB114_SRT_TABLE_INDEX,
+ NCP_SUB123_SRT_TABLE_INDEX,
+ NCP_SUB131_SRT_TABLE_INDEX,
+
+};
+
+#define NCP_NUM_PROCEDURES 0
+
+static void
+ncpstat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ /* Initialize all of the SRT tables with 0 rows. That way we can "filter" the drawing
+ function to only output tables with rows > 0 */
+
+ init_srt_table("NCP", "Groups", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.group", gui_callback, gui_data, NULL);
+
+ /* NDS Verbs */
+ init_srt_table("NDS Verbs", "NDS", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.ndsverb", gui_callback, gui_data, NULL);
+
+ /* NCP Functions */
+ init_srt_table("NCP Functions without Subfunctions", "Functions", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func", gui_callback, gui_data, NULL);
+
+ /* Secret Store Verbs */
+ init_srt_table("Secret Store Verbs", "SSS", srt_array, NCP_NUM_PROCEDURES, NULL, "sss.subverb", gui_callback, gui_data, NULL);
+
+ /* NMAS Verbs */
+ init_srt_table("NMAS Verbs", "NMAS", srt_array, NCP_NUM_PROCEDURES, NULL, "nmas.subverb", gui_callback, gui_data, NULL);
+
+ /* NCP Subfunctions */
+ init_srt_table("Subfunctions for NCP 17", "17", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==17 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 21", "21", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==21 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 22", "22", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==22 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 23", "23", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==23 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 32", "32", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==32 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 34", "34", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==34 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 35", "35", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==35 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 36", "36", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==36 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 86", "86", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==86 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 87", "87", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==87 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 89 (Extended NCP's with UTF8 Support)", "89", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==89 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 90", "90", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==90 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 92 (Secret Store Services)", "92", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==92 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 94 (Novell Modular Authentication Services)", "94", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==94 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 104", "104", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==104 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 111", "111", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==111 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 114", "114", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==114 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 123", "123", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==123 && ncp.subfunc", gui_callback, gui_data, NULL);
+ init_srt_table("Subfunctions for NCP 131", "131", srt_array, NCP_NUM_PROCEDURES, NULL, "ncp.func==131 && ncp.subfunc", gui_callback, gui_data, NULL);
+}
+
+static int
+ncpstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *ncp_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const ncp_req_hash_value *request_val=(const ncp_req_hash_value *)prv;
+ gchar* tmp_str;
+
+ /* if we haven't seen the request, just ignore it */
+ if(!request_val || request_val->ncp_rec==0){
+ return 0;
+ }
+
+ /* By Group */
+ tmp_str = val_to_str_wmem(NULL, request_val->ncp_rec->group, ncp_group_vals, "Unknown(%u)");
+ i = NCP_NCP_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, request_val->ncp_rec->group, tmp_str);
+ wmem_free(NULL, tmp_str);
+ add_srt_table_data(ncp_srt_table, request_val->ncp_rec->group, &request_val->req_frame_time, pinfo);
+ /* By NCP number without subfunction*/
+ if (request_val->ncp_rec->subfunc==0) {
+ i = NCP_FUNC_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, request_val->ncp_rec->func, request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, request_val->ncp_rec->func, &request_val->req_frame_time, pinfo);
+ }
+ /* By Subfunction number */
+ if(request_val->ncp_rec->subfunc!=0){
+ if (request_val->ncp_rec->func==17) {
+ i = NCP_SUB17_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==21) {
+ i = NCP_SUB21_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==22) {
+ i = NCP_SUB22_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==23) {
+ i = NCP_SUB23_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==32) {
+ i = NCP_SUB32_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==34) {
+ i = NCP_SUB34_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==35) {
+ i = NCP_SUB35_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==36) {
+ i = NCP_SUB36_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==86) {
+ i = NCP_SUB86_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==87) {
+ i = NCP_SUB87_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==89) {
+ i = NCP_SUB89_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==90) {
+ i = NCP_SUB90_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==92) {
+ i = NCP_SUB92_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==94) {
+ i = NCP_SUB94_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==104) {
+ i = NCP_SUB104_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==111) {
+ i = NCP_SUB111_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==114) {
+ i = NCP_SUB114_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==123) {
+ i = NCP_SUB123_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ if (request_val->ncp_rec->func==131) {
+ i = NCP_SUB131_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->ncp_rec->subfunc), request_val->ncp_rec->name);
+ add_srt_table_data(ncp_srt_table, (request_val->ncp_rec->subfunc), &request_val->req_frame_time, pinfo);
+ }
+ }
+ /* By NDS verb */
+ if (request_val->ncp_rec->func==0x68) {
+ tmp_str = val_to_str_wmem(NULL, request_val->nds_request_verb, ncp_nds_verb_vals, "Unknown(%u)");
+ i = NCP_NDS_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->nds_request_verb), tmp_str);
+ add_srt_table_data(ncp_srt_table, (request_val->nds_request_verb), &request_val->req_frame_time, pinfo);
+ wmem_free(NULL, tmp_str);
+ }
+ if (request_val->ncp_rec->func==0x5c) {
+ tmp_str = val_to_str_wmem(NULL, request_val->req_nds_flags, sss_verb_enum, "Unknown(%u)");
+ i = NCP_SSS_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->req_nds_flags), tmp_str);
+ add_srt_table_data(ncp_srt_table, (request_val->req_nds_flags), &request_val->req_frame_time, pinfo);
+ wmem_free(NULL, tmp_str);
+ }
+ if (request_val->ncp_rec->func==0x5e) {
+ tmp_str = val_to_str_wmem(NULL, request_val->req_nds_flags, nmas_subverb_enum, "Unknown(%u)");
+ i = NCP_NMAS_SRT_TABLE_INDEX;
+ ncp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ init_srt_table_row(ncp_srt_table, (request_val->req_nds_flags), tmp_str);
+ add_srt_table_data(ncp_srt_table, (request_val->req_nds_flags), &request_val->req_frame_time, pinfo);
+ wmem_free(NULL, tmp_str);
+ }
+ return 1;
+}
+
+
/* Conversation Struct so we can detect NCP server sessions */
typedef struct {
@@ -1091,6 +1339,7 @@ proto_register_ncp(void)
expert_module_t* expert_ncp;
proto_ncp = proto_register_protocol("NetWare Core Protocol", "NCP", "ncp");
+
proto_register_field_array(proto_ncp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_ncp = expert_register_protocol(proto_ncp);
@@ -1137,6 +1386,7 @@ proto_register_ncp(void)
register_postseq_cleanup_routine(&mncp_postseq_cleanup);
register_conversation_table(proto_ncp, FALSE, ncp_conversation_packet, ncp_hostlist_packet);
+ register_srt_table(proto_ncp, "ncp_srt", 24, ncpstat_packet, ncpstat_init, NULL);
}
void
diff --git a/epan/dissectors/packet-rpc.c b/epan/dissectors/packet-rpc.c
index e8004870e4..5df6cb0d8a 100644
--- a/epan/dissectors/packet-rpc.c
+++ b/epan/dissectors/packet-rpc.c
@@ -25,7 +25,7 @@
#include "config.h"
-
+#include <stdio.h>
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/exceptions.h>
@@ -33,6 +33,7 @@
#include <epan/prefs.h>
#include <epan/reassemble.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/strutil.h>
#include <epan/show_exception.h>
@@ -312,6 +313,129 @@ static void dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
guint32 rpc_rm, fragment_head *ipfd_head, packet_info *pinfo);
+
+static guint32 rpc_program = 0;
+static guint32 rpc_version = 0;
+static gint32 rpc_min_proc = -1;
+static gint32 rpc_max_proc = -1;
+
+static void *
+rpcstat_find_procs(gpointer *key, gpointer *value _U_, gpointer *user_data _U_)
+{
+ rpc_proc_info_key *k = (rpc_proc_info_key *)key;
+
+ if (k->prog != rpc_program) {
+ return NULL;
+ }
+ if (k->vers != rpc_version) {
+ return NULL;
+ }
+ if (rpc_min_proc == -1) {
+ rpc_min_proc = k->proc;
+ rpc_max_proc = k->proc;
+ }
+ if ((gint32)k->proc < rpc_min_proc) {
+ rpc_min_proc = k->proc;
+ }
+ if ((gint32)k->proc > rpc_max_proc) {
+ rpc_max_proc = k->proc;
+ }
+
+ return NULL;
+}
+
+static void
+rpcstat_init(struct register_srt* srt, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ rpcstat_tap_data_t* tap_data = (rpcstat_tap_data_t*)get_srt_table_param_data(srt);
+ srt_stat_table *rpc_srt_table;
+ int i, hf_index;
+ header_field_info *hfi;
+ static char table_name[100];
+
+ DISSECTOR_ASSERT(tap_data);
+
+ hf_index=rpc_prog_hf(tap_data->program, tap_data->version);
+ hfi=proto_registrar_get_nth(hf_index);
+
+ g_snprintf(table_name, sizeof(table_name), "%s Version %u", tap_data->prog, tap_data->version);
+ rpc_srt_table = init_srt_table(table_name, NULL, srt_array, tap_data->num_procedures, NULL, hfi->abbrev, gui_callback, gui_data, tap_data);
+ for (i = 0; i < rpc_srt_table->num_procs; i++)
+ {
+ init_srt_table_row(rpc_srt_table, i, rpc_proc_name(tap_data->program, tap_data->version, i));
+ }
+}
+
+static int
+rpcstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *rpc_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const rpc_call_info_value *ri = (const rpc_call_info_value *)prv;
+ rpcstat_tap_data_t* tap_data;
+
+ rpc_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ tap_data = (rpcstat_tap_data_t*)rpc_srt_table->table_specific_data;
+
+ if ((int)ri->proc >= rpc_srt_table->num_procs) {
+ /* don't handle this since its outside of known table */
+ return 0;
+ }
+ /* we are only interested in reply packets */
+ if (ri->request) {
+ return 0;
+ }
+ /* we are only interested in certain program/versions */
+ if ( (ri->prog != tap_data->program) || (ri->vers != tap_data->version) ) {
+ return 0;
+ }
+
+ add_srt_table_data(rpc_srt_table, ri->proc, &ri->req_time, pinfo);
+ return 1;
+
+}
+
+static guint
+rpcstat_param(register_srt_t* srt, const char* opt_arg, char** err)
+{
+ guint pos = 0;
+ int program, version;
+ rpcstat_tap_data_t* tap_data;
+
+ if (sscanf(opt_arg, ",%d,%d,%n", &program, &version, &pos) == 2)
+ {
+ tap_data = g_new0(rpcstat_tap_data_t, 1);
+
+ tap_data->prog = rpc_prog_name(program);
+ tap_data->program = program;
+ tap_data->version = version;
+
+ set_srt_table_param_data(srt, tap_data);
+
+ rpc_program = tap_data->program;
+ rpc_version = tap_data->version;
+ rpc_min_proc = -1;
+ rpc_max_proc = -1;
+ g_hash_table_foreach(rpc_procs, (GHFunc)rpcstat_find_procs, NULL);
+
+ tap_data->num_procedures = rpc_max_proc+1;
+ if (rpc_min_proc == -1) {
+ *err = g_strdup_printf("Program:%u version:%u isn't supported", rpc_program, rpc_version);
+ }
+ }
+ else
+ {
+ *err = g_strdup_printf("<program>,<version>[,<filter>]");
+ }
+
+ return pos;
+}
+
+
+
+
+
/***********************************/
/* Hash array with procedure names */
/***********************************/
@@ -4030,6 +4154,8 @@ proto_register_rpc(void)
new_register_dissector("rpc-tcp", dissect_rpc_tcp, proto_rpc);
rpc_tap = register_tap("rpc");
+ register_srt_table(proto_rpc, NULL, 1, rpcstat_packet, rpcstat_init, rpcstat_param);
+
/*
* Init the hash tables. Dissectors for RPC protocols must
* have a "handoff registration" routine that registers the
diff --git a/epan/dissectors/packet-rpc.h b/epan/dissectors/packet-rpc.h
index ffe41686cb..187445fe32 100644
--- a/epan/dissectors/packet-rpc.h
+++ b/epan/dissectors/packet-rpc.h
@@ -222,5 +222,13 @@ typedef struct _rpc_proc_info_value {
*/
WS_DLL_PUBLIC GHashTable *rpc_procs;
+typedef struct rpcstat_tap_data
+{
+ const char *prog;
+ guint32 program;
+ guint32 version;
+ int num_procedures;
+} rpcstat_tap_data_t;
+
#endif /* packet-rpc.h */
diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c
index de1ce6f09e..137d39644f 100644
--- a/epan/dissectors/packet-scsi.c
+++ b/epan/dissectors/packet-scsi.c
@@ -79,11 +79,13 @@
*/
#include "config.h"
+#include <stdio.h>
#include <epan/packet.h>
#include <epan/to_str.h>
#include <epan/prefs.h>
#include <epan/conversation.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/reassemble.h>
#include <epan/expert.h>
#include "packet-scsi.h"
@@ -936,6 +938,110 @@ static const value_string scsi_log_pc_val[] = {
{0, NULL},
};
+#define SCSI_NUM_PROCEDURES 256
+typedef struct scsistat_tap_data
+{
+ guint8 cmdset;
+ const char *prog;
+ value_string_ext *cdbnames_ext;
+ const char *hf_name;
+} scsistat_tap_data_t;
+
+static void
+scsistat_init(struct register_srt* srt, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ scsistat_tap_data_t* tap_data = (scsistat_tap_data_t*)get_srt_table_param_data(srt);
+ srt_stat_table *scsi_srt_table;
+ guint32 i;
+
+ DISSECTOR_ASSERT(tap_data);
+
+ scsi_srt_table = init_srt_table(tap_data->prog, NULL, srt_array, SCSI_NUM_PROCEDURES, NULL, tap_data->hf_name, gui_callback, gui_data, tap_data);
+ for (i = 0; i < SCSI_NUM_PROCEDURES; i++)
+ {
+ init_srt_table_row(scsi_srt_table, i, val_to_str_ext_const(i, tap_data->cdbnames_ext, "Unknown-0x%02x"));
+ }
+}
+
+static int
+scsistat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *scsi_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const scsi_task_data_t *ri = (const scsi_task_data_t *)prv;
+ scsistat_tap_data_t* tap_data;
+
+ scsi_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ tap_data = (scsistat_tap_data_t*)scsi_srt_table->table_specific_data;
+
+ /* we are only interested in response packets */
+ if (ri->type != SCSI_PDU_TYPE_RSP) {
+ return 0;
+ }
+ /* we are only interested in a specific commandset */
+ if ( (!ri->itl) || ((ri->itl->cmdset&SCSI_CMDSET_MASK) != tap_data->cmdset) ) {
+ return 0;
+ }
+ /* check that the opcode looks sane */
+ if ( (!ri->itlq) || (ri->itlq->scsi_opcode > 255) ) {
+ return 0;
+ }
+
+ add_srt_table_data(scsi_srt_table, ri->itlq->scsi_opcode, &ri->itlq->fc_time, pinfo);
+ return 1;
+}
+
+static guint
+scsistat_param(register_srt_t* srt, const char* opt_arg, char** err)
+{
+ guint pos = 0;
+ int program;
+ scsistat_tap_data_t* tap_data;
+
+ if (sscanf(opt_arg, ",%d,%n", &program, &pos) == 1)
+ {
+ tap_data = g_new0(scsistat_tap_data_t, 1);
+ tap_data->cmdset = (guint8)program;
+
+ switch(program){
+ case SCSI_DEV_SBC:
+ tap_data->prog = "SBC (disk)";
+ tap_data->cdbnames_ext = &scsi_sbc_vals_ext;
+ tap_data->hf_name = "scsi_sbc.opcode";
+ break;
+ case SCSI_DEV_SSC:
+ tap_data->prog = "SSC (tape)";
+ tap_data->cdbnames_ext = &scsi_ssc_vals_ext;
+ tap_data->hf_name = "scsi_ssc.opcode";
+ break;
+ case SCSI_DEV_CDROM:
+ tap_data->prog = "MMC (cd/dvd)";
+ tap_data->cdbnames_ext = &scsi_mmc_vals_ext;
+ tap_data->hf_name = "scsi_mmc.opcode";
+ break;
+ case SCSI_DEV_SMC:
+ tap_data->prog = "SMC (tape robot)";
+ tap_data->cdbnames_ext = &scsi_smc_vals_ext;
+ tap_data->hf_name = "scsi_smc.opcode";
+ break;
+ case SCSI_DEV_OSD:
+ tap_data->prog = "OSD (object based)";
+ tap_data->cdbnames_ext = &scsi_osd_vals_ext;
+ tap_data->hf_name = "scsi_osd.opcode";
+ break;
+ }
+
+ set_srt_table_param_data(srt, tap_data);
+ }
+ else
+ {
+ *err = g_strdup_printf("<cmdset>[,<filter>]");
+ }
+
+ return pos;
+}
+
/* TapeAlert page : read warning flag */
static void
log_parameter_2e_0001(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
@@ -7567,6 +7673,8 @@ proto_register_scsi(void)
"Whether fragmented SCSI DATA IN/OUT transfers should be reassembled",
&scsi_defragment);
register_init_routine(scsi_defragment_init);
+
+ register_srt_table(proto_scsi, NULL, 1, scsistat_packet, scsistat_init, scsistat_param);
}
void
diff --git a/epan/dissectors/packet-smb.c b/epan/dissectors/packet-smb.c
index 614cf0900b..1f1286a1a4 100644
--- a/epan/dissectors/packet-smb.c
+++ b/epan/dissectors/packet-smb.c
@@ -32,6 +32,7 @@
#include <epan/prefs.h>
#include <epan/reassemble.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/expert.h>
#include <epan/to_str.h>
@@ -883,6 +884,75 @@ static proto_tree *top_tree_global = NULL; /* ugly */
static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu, smb_info_t *si);
+#define SMB_NUM_PROCEDURES 256
+#define SMB_SRT_TABLE_INDEX 0
+#define TRANS2_SRT_TABLE_INDEX 1
+#define NT_SRT_TABLE_INDEX 2
+
+static void
+smbstat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ srt_stat_table *smb_srt_table;
+ srt_stat_table *trans2_srt_table;
+ srt_stat_table *nt_srt_table;
+ guint32 i;
+
+ smb_srt_table = init_srt_table("SMB Commands", NULL, srt_array, SMB_NUM_PROCEDURES, "Commands", "smb.cmd", gui_callback, gui_data, NULL);
+ trans2_srt_table = init_srt_table("Transaction2 Sub-Commands", NULL, srt_array, SMB_NUM_PROCEDURES, "Transaction2 Commands", "smb.trans2.cmd", gui_callback, gui_data, NULL);
+ nt_srt_table = init_srt_table("NT Transaction Sub-Commands", NULL, srt_array, SMB_NUM_PROCEDURES, "NT Transaction Sub-Commands", "smb.nt.function", gui_callback, gui_data, NULL);
+ for (i = 0; i < SMB_NUM_PROCEDURES; i++)
+ {
+ init_srt_table_row(smb_srt_table, i, val_to_str_ext_const(i, &smb_cmd_vals_ext, "<unknown>"));
+ init_srt_table_row(trans2_srt_table, i, val_to_str_ext_const(i, &trans2_cmd_vals_ext, "<unknown>"));
+ init_srt_table_row(nt_srt_table, i, val_to_str_ext_const(i, &nt_cmd_vals_ext, "<unknown>"));
+ }
+}
+
+static int
+smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *smb_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const smb_info_t *si = (const smb_info_t *)prv;
+
+ /* we are only interested in reply packets */
+ if (si->request) {
+ return 0;
+ }
+ /* if we havnt seen the request, just ignore it */
+ if (!si->sip) {
+ return 0;
+ }
+
+ if (si->cmd == 0xA0 && si->sip->extra_info_type == SMB_EI_NTI) {
+ smb_nt_transact_info_t *sti = (smb_nt_transact_info_t *)si->sip->extra_info;
+
+ /*nt transaction*/
+ if (sti) {
+ i = NT_SRT_TABLE_INDEX;
+ smb_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ add_srt_table_data(smb_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) {
+ i = TRANS2_SRT_TABLE_INDEX;
+ smb_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ add_srt_table_data(smb_srt_table, st2i->subcmd, &si->sip->req_time, pinfo);
+ }
+ } else {
+ i = SMB_SRT_TABLE_INDEX;
+ smb_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ add_srt_table_data(smb_srt_table, si->cmd, &si->sip->req_time, pinfo);
+ }
+
+ return 1;
+
+}
+
/*
* Macros for use in the main dissector routines for an SMB.
*/
@@ -20463,6 +20533,8 @@ proto_register_smb(void)
smb_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
register_dissector("smb", dissect_smb, proto_smb);
+
+ register_srt_table(proto_smb, NULL, 3, smbstat_packet, smbstat_init, NULL);
}
void
diff --git a/epan/dissectors/packet-smb2.c b/epan/dissectors/packet-smb2.c
index 0d8c749b08..c5afb95ce0 100644
--- a/epan/dissectors/packet-smb2.c
+++ b/epan/dissectors/packet-smb2.c
@@ -35,6 +35,7 @@
#include <epan/prefs.h>
#include <epan/expert.h>
#include <epan/tap.h>
+#include <epan/srt_table.h>
#include <epan/aftypes.h>
#include <epan/to_str.h>
#include <epan/asn1.h>
@@ -578,6 +579,53 @@ static const value_string smb2_negotiate_context_types[] = {
{ 0, NULL }
};
+#define SMB2_NUM_PROCEDURES 256
+
+static void
+smb2stat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
+{
+ srt_stat_table *smb2_srt_table;
+ guint32 i;
+
+ smb2_srt_table = init_srt_table("SMB2", NULL, srt_array, SMB2_NUM_PROCEDURES, "Commands", "smb2.cmd", gui_callback, gui_data, NULL);
+ for (i = 0; i < SMB2_NUM_PROCEDURES; i++)
+ {
+ init_srt_table_row(smb2_srt_table, i, val_to_str_ext_const(i, &smb2_cmd_vals_ext, "<unknown>"));
+ }
+}
+
+static int
+smb2stat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+ guint i = 0;
+ srt_stat_table *smb2_srt_table;
+ srt_data_t *data = (srt_data_t *)pss;
+ const smb2_info_t *si=(const smb2_info_t *)prv;
+
+ /* we are only interested in response packets */
+ if(!(si->flags&SMB2_FLAGS_RESPONSE)){
+ return 0;
+ }
+ /* if we haven't seen the request, just ignore it */
+ if(!si->saved){
+ return 0;
+ }
+
+ /* SMB2 SRT can be very inaccurate in the presence of retransmissions. Retransmitted responses
+ * not only add additional (bogus) transactions but also the latency associated with them.
+ * This can greatly inflate the maximum and average SRT stats especially in the case of
+ * retransmissions triggered by the expiry of the rexmit timer (RTOs). Only calculating SRT
+ * for the last received response accomplishes this goal without requiring the TCP pref
+ * "Do not call subdissectors for error packets" to be set. */
+ if ((si->saved->frame_req == 0) || (si->saved->frame_res != pinfo->fd->num))
+ return 0;
+
+ smb2_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ add_srt_table_data(smb2_srt_table, si->opcode, &si->saved->req_time, pinfo);
+ return 1;
+}
+
+
static const gint8 zeros[NTLMSSP_KEY_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/* ExportObject preferences variable */
@@ -8724,6 +8772,7 @@ proto_register_smb2(void)
smb2_tap = register_tap("smb2");
smb2_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
+ register_srt_table(proto_smb2, NULL, 1, smb2stat_packet, smb2stat_init, NULL);
}
void