update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / epan / stat_tap_ui.c
blob2d8f9a20dbc11eb434640b7116ab080aea63f3ed
1 /* stat_tap_ui.c
2 * Routines to register UI information for stats
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
13 #include <stdio.h>
15 #include <string.h>
17 #include <glib.h>
19 #include <epan/stat_tap_ui.h>
20 #include <wsutil/ws_assert.h>
22 /* structure to keep track of what stats have registered command-line
23 arguments.
25 typedef struct _stat_cmd_arg {
26 stat_tap_ui *ui;
27 const char *cmd;
28 void (*func)(const char *arg, void* userdata);
29 void* userdata;
30 } stat_cmd_arg;
32 static wmem_list_t *stat_cmd_arg_list;
34 /* structure to keep track of what stats have been specified on the
35 command line.
37 typedef struct {
38 stat_cmd_arg *sca;
39 char *arg;
40 } stat_requested;
41 static GSList *stats_requested;
43 /* **********************************************************************
44 * Function called from stat to register the stat's command-line argument
45 * and initialization routine
46 * ********************************************************************** */
47 static int
48 search_duplicate(const void *a, const void *b)
50 return strcmp(((const stat_cmd_arg *)a)->cmd, (const char *)b);
53 static int
54 sort_by_name(const void *a, const void *b)
56 return strcmp(((const stat_cmd_arg *)a)->cmd, ((const stat_cmd_arg *)b)->cmd);
59 void
60 register_stat_tap_ui(stat_tap_ui *ui, void *userdata)
62 stat_cmd_arg *newsca;
64 if (stat_cmd_arg_list == NULL)
65 stat_cmd_arg_list = wmem_list_new(wmem_epan_scope());
67 /* Key is already present */
68 if (wmem_list_find_custom(stat_cmd_arg_list, ui->cli_string, search_duplicate))
69 return;
71 newsca = wmem_new(wmem_epan_scope(), stat_cmd_arg);
72 newsca->cmd= wmem_strdup(wmem_epan_scope(), ui->cli_string);
73 newsca->func=ui->tap_init_cb;
74 newsca->userdata=userdata;
76 wmem_list_insert_sorted(stat_cmd_arg_list, newsca, sort_by_name);
79 /* **********************************************************************
80 * Function called for a stat command-line argument
81 * ********************************************************************** */
82 bool
83 process_stat_cmd_arg(const char *optstr)
85 wmem_list_frame_t *entry;
86 stat_cmd_arg *sca;
87 stat_requested *tr;
88 char *stat_command = g_strdup(optstr);
90 /* Renamed in Wireshark 3.0, backwards compatibility. */
91 if (!strncmp(stat_command, "follow,ssl", strlen("follow,ssl"))) {
92 memcpy(stat_command + 7, "tls", 3);
95 /* The strings "ipx" or "ipv6" must be tested before "ip" to select the
96 right tap so the sorting does matter. And it's also why the list is
97 walked backwards */
98 for (entry = wmem_list_tail(stat_cmd_arg_list); entry; entry = wmem_list_frame_prev(entry)) {
99 sca = (stat_cmd_arg*)wmem_list_frame_data(entry);
100 if (!strncmp(sca->cmd, stat_command, strlen(sca->cmd))) {
101 tr=g_new(stat_requested, 1);
102 tr->sca = sca;
103 tr->arg = stat_command;
104 stats_requested = g_slist_append(stats_requested, tr);
105 return true;
108 g_free(stat_command);
109 return false;
112 /* **********************************************************************
113 * Function to list all possible tap command-line arguments
114 * ********************************************************************** */
115 static void
116 list_stat_cmd_args_func(void *data, void *userdata _U_)
118 fprintf(stderr," %s\n", ((stat_cmd_arg*)data)->cmd);
121 void
122 list_stat_cmd_args(void)
124 wmem_list_foreach(stat_cmd_arg_list, list_stat_cmd_args_func, NULL);
127 /* **********************************************************************
128 * Function to process stats requested with command-line arguments
129 * ********************************************************************** */
130 void
131 start_requested_stats(void)
133 stat_requested *sr;
135 while(stats_requested){
136 sr=(stat_requested *)stats_requested->data;
137 (*sr->sca->func)(sr->arg,sr->sca->userdata);
138 stats_requested=g_slist_remove(stats_requested, sr);
139 g_free(sr->arg);
140 g_free(sr);
144 static wmem_tree_t *registered_stat_tables;
146 void register_stat_tap_table_ui(stat_tap_table_ui *ui)
148 if (registered_stat_tables == NULL)
149 registered_stat_tables = wmem_tree_new(wmem_epan_scope());
151 wmem_tree_insert_string(registered_stat_tables, ui->cli_string, ui, 0);
154 stat_tap_table_ui *stat_tap_by_name(const char *name)
156 return (stat_tap_table_ui *) wmem_tree_lookup_string(registered_stat_tables, name, 0);
159 void stat_tap_iterate_tables(wmem_foreach_func func, void *user_data)
161 wmem_tree_foreach(registered_stat_tables, func, user_data);
164 void stat_tap_get_filter(stat_tap_table_ui* new_stat, const char *opt_arg, const char **filter, char** err)
166 unsigned len = (unsigned) strlen(new_stat->cli_string);
167 *filter=NULL;
168 *err=NULL;
170 if (!strncmp(opt_arg, new_stat->cli_string, len))
172 if (opt_arg[len] == ',')
174 *filter = opt_arg + len+1;
178 if (new_stat->stat_filter_check_cb)
179 new_stat->stat_filter_check_cb(opt_arg, filter, err);
182 stat_tap_table* stat_tap_init_table(const char *name, int num_fields, int num_elements,
183 const char *filter_string)
185 stat_tap_table* new_table = g_new0(stat_tap_table, 1);
187 new_table->title = name;
188 new_table->num_elements = num_elements;
189 new_table->num_fields = num_fields;
190 new_table->filter_string = filter_string;
191 new_table->elements = g_new0(stat_tap_table_item_type*, num_elements);
193 return new_table;
196 stat_tap_table *stat_tap_find_table(stat_tap_table_ui *ui, const char *name)
198 unsigned i = 0;
199 stat_tap_table *stat_table;
201 if (ui->tables == NULL)
202 return NULL;
204 for (i = 0; i < ui->tables->len; i++) {
205 stat_table = g_array_index(ui->tables, stat_tap_table *, i);
206 if (!g_strcmp0(stat_table->title, name)) {
207 return stat_table;
211 return NULL;
214 void stat_tap_add_table(stat_tap_table_ui* new_stat, stat_tap_table* table)
216 if (new_stat->tables == NULL)
217 new_stat->tables = g_array_new(false, true, sizeof(stat_tap_table*));
219 g_array_insert_val(new_stat->tables, new_stat->tables->len, table);
222 void stat_tap_init_table_row(stat_tap_table *stat_table, unsigned table_index, unsigned num_fields, const stat_tap_table_item_type* fields)
224 /* we have discovered a new procedure. Extend the table accordingly */
225 if(table_index>=stat_table->num_elements){
226 unsigned old_num_elements=stat_table->num_elements;
227 unsigned i;
229 stat_table->num_elements=table_index+1;
230 stat_table->elements = (stat_tap_table_item_type**)g_realloc(stat_table->elements, sizeof(stat_tap_table_item_type*)*(stat_table->num_elements));
231 for(i=old_num_elements;i<stat_table->num_elements;i++){
232 stat_table->elements[i] = g_new0(stat_tap_table_item_type, stat_table->num_fields);
235 memcpy(stat_table->elements[table_index], fields, num_fields*sizeof(stat_tap_table_item_type));
239 stat_tap_table_item_type* stat_tap_get_field_data(const stat_tap_table *stat_table, unsigned table_index, unsigned field_index)
241 stat_tap_table_item_type* field_value;
242 ws_assert(table_index < stat_table->num_elements);
244 field_value = stat_table->elements[table_index];
246 ws_assert(field_index < stat_table->num_fields);
248 return &field_value[field_index];
251 void stat_tap_set_field_data(stat_tap_table *stat_table, unsigned table_index, unsigned field_index, stat_tap_table_item_type* field_data)
253 stat_tap_table_item_type* field_value;
254 ws_assert(table_index < stat_table->num_elements);
256 field_value = stat_table->elements[table_index];
258 ws_assert(field_index < stat_table->num_fields);
260 field_value[field_index] = *field_data;
263 void reset_stat_table(stat_tap_table_ui* new_stat)
265 unsigned i = 0;
266 stat_tap_table *stat_table;
268 for (i = 0; i < new_stat->tables->len; i++)
270 stat_table = g_array_index(new_stat->tables, stat_tap_table*, i);
272 if (new_stat->stat_tap_reset_table_cb)
273 new_stat->stat_tap_reset_table_cb(stat_table);
277 void free_stat_tables(stat_tap_table_ui* new_stat)
279 unsigned i = 0, element, field_index;
280 stat_tap_table *stat_table;
281 stat_tap_table_item_type* field_data;
283 for (i = 0; i < new_stat->tables->len; i++)
285 stat_table = g_array_index(new_stat->tables, stat_tap_table*, i);
287 for (element = 0; element < stat_table->num_elements; element++)
289 for (field_index = 0; field_index < stat_table->num_fields; field_index++)
291 field_data = stat_tap_get_field_data(stat_table, element, field_index);
292 /* Give dissector a crack at it */
293 /* XXX Should this be per-row instead? */
294 if (new_stat->stat_tap_free_table_item_cb)
295 new_stat->stat_tap_free_table_item_cb(stat_table, element, field_index, field_data);
297 g_free(stat_table->elements[element]);
299 g_free(stat_table->elements);
300 g_free(stat_table);
302 g_array_set_size(new_stat->tables, 0);
307 * Editor modelines
309 * Local Variables:
310 * c-basic-offset: 4
311 * tab-width: 8
312 * indent-tabs-mode: nil
313 * End:
315 * ex: set shiftwidth=4 tabstop=8 expandtab:
316 * :indentSize=4:tabSize=8:noTabs=true: