diff options
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-afp.c | 42 | ||||
-rw-r--r-- | epan/dissectors/packet-camel.c | 60 | ||||
-rw-r--r-- | epan/dissectors/packet-dcerpc.c | 160 | ||||
-rw-r--r-- | epan/dissectors/packet-dcerpc.h | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-diameter.c | 64 | ||||
-rw-r--r-- | epan/dissectors/packet-fc.c | 43 | ||||
-rw-r--r-- | epan/dissectors/packet-gtp.c | 58 | ||||
-rw-r--r-- | epan/dissectors/packet-ldap.c | 67 | ||||
-rw-r--r-- | epan/dissectors/packet-ncp.c | 250 | ||||
-rw-r--r-- | epan/dissectors/packet-rpc.c | 128 | ||||
-rw-r--r-- | epan/dissectors/packet-rpc.h | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.c | 108 | ||||
-rw-r--r-- | epan/dissectors/packet-smb.c | 72 | ||||
-rw-r--r-- | epan/dissectors/packet-smb2.c | 49 |
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, >p->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 |