aboutsummaryrefslogtreecommitdiffstats
path: root/epan/srt_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/srt_table.c')
-rw-r--r--epan/srt_table.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/epan/srt_table.c b/epan/srt_table.c
new file mode 100644
index 0000000000..2fe4bafb35
--- /dev/null
+++ b/epan/srt_table.c
@@ -0,0 +1,322 @@
+/* srt_table.c
+ * Helper routines common to all SRT taps.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "packet_info.h"
+#include "proto.h"
+#include "srt_table.h"
+
+struct register_srt {
+ int proto_id; /* protocol id (0-indexed) */
+ const char* tap_listen_str; /* string used in register_tap_listener (NULL to use protocol name) */
+ int max_tables; /* Maximum number of tables expected (used by GUI to determine how to display tables) */
+ tap_packet_cb srt_func; /* function to be called for new incoming packets for SRT */
+ srt_init_cb srt_init; /* function to create dissector SRT tables */
+ srt_param_handler_cb param_cb; /* function to parse parameters of optional arguments of tap string */
+ void* param_data; /* Storage for tap parameter data */
+};
+
+int get_srt_proto_id(register_srt_t* srt)
+{
+ if (!srt) {
+ return -1;
+ }
+ return srt->proto_id;
+}
+
+const char* get_srt_tap_listener_name(register_srt_t* srt)
+{
+ return srt->tap_listen_str;
+}
+
+int get_srt_max_tables(register_srt_t* srt)
+{
+ return srt->max_tables;
+}
+
+tap_packet_cb get_srt_packet_func(register_srt_t* srt)
+{
+ return srt->srt_func;
+}
+
+void set_srt_table_param_data(register_srt_t* srt, void* data)
+{
+ srt->param_data = data;
+}
+
+void* get_srt_table_param_data(register_srt_t* srt)
+{
+ return srt->param_data;
+}
+
+void
+free_srt_table_data(srt_stat_table *rst)
+{
+ int i;
+
+ for(i=0;i<rst->num_procs;i++){
+ g_free(rst->procedures[i].procedure);
+ rst->procedures[i].procedure=NULL;
+ }
+ g_free(rst->filter_string);
+ rst->filter_string=NULL;
+ g_free(rst->procedures);
+ rst->procedures=NULL;
+ rst->num_procs=0;
+}
+
+void free_srt_table(register_srt_t *srt, GArray* srt_array, srt_gui_free_cb gui_callback, void *callback_data)
+{
+ guint i = 0;
+ srt_stat_table *srt_table;
+
+ for (i = 0; i < srt_array->len; i++)
+ {
+ srt_table = g_array_index(srt_array, srt_stat_table*, i);
+
+ /* Give GUI the first crack at it before we clean up */
+ if (gui_callback)
+ gui_callback(srt_table, callback_data);
+
+ free_srt_table_data(srt_table);
+ }
+
+ /* Clear the tables */
+ g_array_set_size(srt_array, 0);
+
+ /* Clear out any possible parameter data */
+ g_free(srt->param_data);
+ srt->param_data = NULL;
+}
+
+static void reset_srt_table_data(srt_stat_table *rst)
+{
+ int i;
+
+ for(i=0;i<rst->num_procs;i++){
+ time_stat_init(&rst->procedures[i].stats);
+ }
+}
+
+void reset_srt_table(GArray* srt_array, srt_gui_reset_cb gui_callback, void *callback_data)
+{
+ guint i = 0;
+ srt_stat_table *srt_table;
+
+ for (i = 0; i < srt_array->len; i++)
+ {
+ srt_table = g_array_index(srt_array, srt_stat_table*, i);
+
+ /* Give GUI the first crack at it before we clean up */
+ if (gui_callback)
+ gui_callback(srt_table, callback_data);
+
+ reset_srt_table_data(srt_table);
+ }
+}
+
+static GSList *registered_srt_tables = NULL;
+
+register_srt_t* get_srt_table_by_name(const char* name)
+{
+ guint i, size = g_slist_length(registered_srt_tables);
+ register_srt_t* srt;
+ GSList *slist;
+
+ for (i = 0; i < size; i++) {
+ slist = g_slist_nth(registered_srt_tables, i);
+ srt = (register_srt_t*)slist->data;
+
+ if (strcmp(name, proto_get_protocol_filter_name(srt->proto_id)) == 0)
+ return srt;
+ }
+
+ return NULL;
+}
+
+gchar* srt_table_get_tap_string(register_srt_t* srt)
+{
+ GString *cmd_str = g_string_new(proto_get_protocol_filter_name(srt->proto_id));
+ g_string_append(cmd_str, ",srt");
+ return g_string_free(cmd_str, FALSE);
+}
+
+void srt_table_get_filter(register_srt_t* srt, const char *opt_arg, const char **filter, char** err)
+{
+ gchar* cmd_str = srt_table_get_tap_string(srt);
+ guint len = strlen(cmd_str);
+ guint pos = len;
+ *filter=NULL;
+ *err = NULL;
+
+ if(!strncmp(opt_arg, cmd_str, len))
+ {
+ if (srt->param_cb != NULL)
+ {
+ pos = srt->param_cb(srt, opt_arg + len, err);
+ if (*err != NULL)
+ return;
+
+ if (pos > 0)
+ pos += len;
+ }
+ else
+ {
+ pos++; /* Adjust for comma */
+ }
+
+ if (opt_arg[pos] == ',')
+ {
+ *filter = opt_arg + pos;
+ }
+ }
+
+ g_free(cmd_str);
+}
+
+void srt_table_dissector_init(register_srt_t* srt, GArray* srt_array, srt_gui_init_cb gui_callback, void *callback_data)
+{
+ srt->srt_init(srt, srt_array, gui_callback, callback_data);
+}
+
+static gint
+insert_sorted_by_table_name(gconstpointer aparam, gconstpointer bparam)
+{
+ const register_srt_t *a = (register_srt_t *)aparam;
+ const register_srt_t *b = (register_srt_t *)bparam;
+
+ return g_ascii_strcasecmp(proto_get_protocol_short_name(find_protocol_by_id(a->proto_id)), proto_get_protocol_short_name(find_protocol_by_id(b->proto_id)));
+}
+
+void
+register_srt_table(const int proto_id, const char* tap_listener, int max_tables, tap_packet_cb srt_packet_func, srt_init_cb init_cb, srt_param_handler_cb param_cb)
+{
+ register_srt_t *table;
+ DISSECTOR_ASSERT(init_cb);
+ DISSECTOR_ASSERT(srt_packet_func);
+
+ table = g_new(register_srt_t,1);
+
+ table->proto_id = proto_id;
+ if (tap_listener != NULL)
+ table->tap_listen_str = tap_listener;
+ else
+ table->tap_listen_str = proto_get_protocol_filter_name(proto_id);
+ table->max_tables = max_tables;
+ table->srt_func = srt_packet_func;
+ table->srt_init = init_cb;
+ table->param_cb = param_cb;
+ table->param_data = NULL;
+
+ registered_srt_tables = g_slist_insert_sorted(registered_srt_tables, table, insert_sorted_by_table_name);
+}
+
+void srt_table_iterate_tables(GFunc func, gpointer user_data)
+{
+ g_slist_foreach(registered_srt_tables, func, user_data);
+}
+
+srt_stat_table*
+init_srt_table(const char *name, const char *short_name, GArray *srt_array, int num_procs, const char* proc_column_name,
+ const char *filter_string, srt_gui_init_cb gui_callback, void* gui_data, void* table_specific_data)
+{
+ int i;
+ srt_stat_table *table = g_new(srt_stat_table, 1);
+
+ if(filter_string){
+ table->filter_string=g_strdup(filter_string);
+ } else {
+ table->filter_string=NULL;
+ }
+
+ table->name = name;
+ table->short_name = short_name;
+ table->proc_column_name = proc_column_name;
+ table->num_procs=num_procs;
+ table->procedures=(srt_procedure_t *)g_malloc(sizeof(srt_procedure_t)*num_procs);
+ for(i=0;i<num_procs;i++){
+ time_stat_init(&table->procedures[i].stats);
+ table->procedures[i].index = 0;
+ table->procedures[i].procedure = NULL;
+ }
+
+ g_array_insert_val(srt_array, srt_array->len, table);
+
+ table->table_specific_data = table_specific_data;
+
+ if (gui_callback)
+ gui_callback(table, gui_data);
+
+ return table;
+}
+
+void
+init_srt_table_row(srt_stat_table *rst, int indx, const char *procedure)
+{
+ /* we have discovered a new procedure. Extend the table accordingly */
+ if(indx>=rst->num_procs){
+ int old_num_procs=rst->num_procs;
+ int i;
+
+ rst->num_procs=indx+1;
+ rst->procedures=(srt_procedure_t *)g_realloc(rst->procedures, sizeof(srt_procedure_t)*(rst->num_procs));
+ for(i=old_num_procs;i<rst->num_procs;i++){
+ time_stat_init(&rst->procedures[i].stats);
+ rst->procedures[i].index = i;
+ rst->procedures[i].procedure=NULL;
+ }
+ }
+ rst->procedures[indx].index = indx;
+ rst->procedures[indx].procedure=g_strdup(procedure);
+}
+
+void
+add_srt_table_data(srt_stat_table *rst, int indx, const nstime_t *req_time, packet_info *pinfo)
+{
+ srt_procedure_t *rp;
+ nstime_t t, delta;
+
+ g_assert(indx >= 0 && indx < rst->num_procs);
+ rp=&rst->procedures[indx];
+
+ /* calculate time delta between request and reply */
+ t=pinfo->fd->abs_ts;
+ nstime_delta(&delta, &t, req_time);
+
+ time_stat_update(&rp->stats, &delta, pinfo);
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */