forked from osmocom/wireshark
![Michael Mann](/assets/img/avatar_default.png)
Change-Id: Ib9d8f23faa7a9f83a975396a1be8f85078223feb Reviewed-on: https://code.wireshark.org/review/20024 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
301 lines
8.3 KiB
C
301 lines
8.3 KiB
C
/* 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 "proto.h"
|
|
#include "packet_info.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 wmem_tree_t *registered_srt_tables = NULL;
|
|
|
|
register_srt_t* get_srt_table_by_name(const char* name)
|
|
{
|
|
return (register_srt_t*)wmem_tree_lookup_string(registered_srt_tables, name, 0);
|
|
}
|
|
|
|
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 = (guint32)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;
|
|
}
|
|
|
|
if (opt_arg[pos] == ',')
|
|
{
|
|
*filter = opt_arg + pos+1;
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 = wmem_new(wmem_epan_scope(), register_srt_t);
|
|
|
|
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;
|
|
|
|
if (registered_srt_tables == NULL)
|
|
registered_srt_tables = wmem_tree_new(wmem_epan_scope());
|
|
|
|
wmem_tree_insert_string(registered_srt_tables, proto_get_protocol_filter_name(proto_id), table, 0);
|
|
}
|
|
|
|
void srt_table_iterate_tables(wmem_foreach_func func, gpointer user_data)
|
|
{
|
|
wmem_tree_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].proc_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].proc_index = i;
|
|
rst->procedures[i].procedure=NULL;
|
|
}
|
|
}
|
|
rst->procedures[indx].proc_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->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:
|
|
*/
|