lua: fix reload with -Xlua_script
[metze/wireshark/wip.git] / epan / srt_table.c
1 /* srt_table.c
2  * Helper routines common to all SRT taps.
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include "proto.h"
28 #include "packet_info.h"
29 #include "srt_table.h"
30
31 struct register_srt {
32     int proto_id;              /* protocol id (0-indexed) */
33     const char* tap_listen_str;      /* string used in register_tap_listener (NULL to use protocol name) */
34     int max_tables;            /* Maximum number of tables expected (used by GUI to determine how to display tables) */
35     tap_packet_cb srt_func;    /* function to be called for new incoming packets for SRT */
36     srt_init_cb srt_init;      /* function to create dissector SRT tables */
37     srt_param_handler_cb param_cb; /* function to parse parameters of optional arguments of tap string */
38     void* param_data;          /* Storage for tap parameter data */
39 };
40
41 int get_srt_proto_id(register_srt_t* srt)
42 {
43     if (!srt) {
44         return -1;
45     }
46     return srt->proto_id;
47 }
48
49 const char* get_srt_tap_listener_name(register_srt_t* srt)
50 {
51     return srt->tap_listen_str;
52 }
53
54 int get_srt_max_tables(register_srt_t* srt)
55 {
56     return srt->max_tables;
57 }
58
59 tap_packet_cb get_srt_packet_func(register_srt_t* srt)
60 {
61     return srt->srt_func;
62 }
63
64 void set_srt_table_param_data(register_srt_t* srt, void* data)
65 {
66     srt->param_data = data;
67 }
68
69 void* get_srt_table_param_data(register_srt_t* srt)
70 {
71     return srt->param_data;
72 }
73
74 void
75 free_srt_table_data(srt_stat_table *rst)
76 {
77     int i;
78
79     for(i=0;i<rst->num_procs;i++){
80         g_free(rst->procedures[i].procedure);
81         rst->procedures[i].procedure=NULL;
82     }
83     g_free(rst->filter_string);
84     rst->filter_string=NULL;
85     g_free(rst->procedures);
86     rst->procedures=NULL;
87     rst->num_procs=0;
88 }
89
90 void free_srt_table(register_srt_t *srt, GArray* srt_array, srt_gui_free_cb gui_callback, void *callback_data)
91 {
92     guint i = 0;
93     srt_stat_table *srt_table;
94
95     for (i = 0; i < srt_array->len; i++)
96     {
97         srt_table = g_array_index(srt_array, srt_stat_table*, i);
98
99         /* Give GUI the first crack at it before we clean up */
100         if (gui_callback)
101             gui_callback(srt_table, callback_data);
102
103         free_srt_table_data(srt_table);
104     }
105
106     /* Clear the tables */
107     g_array_set_size(srt_array, 0);
108
109     /* Clear out any possible parameter data */
110     g_free(srt->param_data);
111     srt->param_data = NULL;
112 }
113
114 static void reset_srt_table_data(srt_stat_table *rst)
115 {
116     int i;
117
118     for(i=0;i<rst->num_procs;i++){
119         time_stat_init(&rst->procedures[i].stats);
120     }
121 }
122
123 void reset_srt_table(GArray* srt_array, srt_gui_reset_cb gui_callback, void *callback_data)
124 {
125     guint i = 0;
126     srt_stat_table *srt_table;
127
128     for (i = 0; i < srt_array->len; i++)
129     {
130         srt_table = g_array_index(srt_array, srt_stat_table*, i);
131
132         /* Give GUI the first crack at it before we clean up */
133         if (gui_callback)
134             gui_callback(srt_table, callback_data);
135
136         reset_srt_table_data(srt_table);
137     }
138 }
139
140 static GSList *registered_srt_tables = NULL;
141
142 register_srt_t* get_srt_table_by_name(const char* name)
143 {
144     guint i, size = g_slist_length(registered_srt_tables);
145     register_srt_t* srt;
146     GSList   *slist;
147
148     for (i = 0; i < size; i++) {
149         slist = g_slist_nth(registered_srt_tables, i);
150         srt = (register_srt_t*)slist->data;
151
152         if (strcmp(name, proto_get_protocol_filter_name(srt->proto_id)) == 0)
153             return srt;
154     }
155
156     return NULL;
157 }
158
159 gchar* srt_table_get_tap_string(register_srt_t* srt)
160 {
161     GString *cmd_str = g_string_new(proto_get_protocol_filter_name(srt->proto_id));
162     g_string_append(cmd_str, ",srt");
163     return g_string_free(cmd_str, FALSE);
164 }
165
166 void srt_table_get_filter(register_srt_t* srt, const char *opt_arg, const char **filter, char** err)
167 {
168     gchar* cmd_str = srt_table_get_tap_string(srt);
169     guint len = (guint32)strlen(cmd_str);
170     guint pos = len;
171     *filter=NULL;
172     *err = NULL;
173
174     if(!strncmp(opt_arg, cmd_str, len))
175     {
176         if (srt->param_cb != NULL)
177         {
178             pos = srt->param_cb(srt, opt_arg + len, err);
179             if (*err != NULL)
180                 return;
181
182             if (pos > 0)
183                 pos += len;
184         }
185
186         if (opt_arg[pos] == ',')
187         {
188            *filter = opt_arg + pos+1;
189         }
190     }
191
192     g_free(cmd_str);
193 }
194
195 void srt_table_dissector_init(register_srt_t* srt, GArray* srt_array, srt_gui_init_cb gui_callback, void *callback_data)
196 {
197     srt->srt_init(srt, srt_array, gui_callback, callback_data);
198 }
199
200 static gint
201 insert_sorted_by_table_name(gconstpointer aparam, gconstpointer bparam)
202 {
203     const register_srt_t *a = (const register_srt_t *)aparam;
204     const register_srt_t *b = (const register_srt_t *)bparam;
205
206     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)));
207 }
208
209 void
210 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)
211 {
212     register_srt_t *table;
213     DISSECTOR_ASSERT(init_cb);
214     DISSECTOR_ASSERT(srt_packet_func);
215
216     table = g_new(register_srt_t,1);
217
218     table->proto_id      = proto_id;
219     if (tap_listener != NULL)
220         table->tap_listen_str = tap_listener;
221     else
222         table->tap_listen_str = proto_get_protocol_filter_name(proto_id);
223     table->max_tables    = max_tables;
224     table->srt_func      = srt_packet_func;
225     table->srt_init      = init_cb;
226     table->param_cb      = param_cb;
227     table->param_data    = NULL;
228
229     registered_srt_tables = g_slist_insert_sorted(registered_srt_tables, table, insert_sorted_by_table_name);
230 }
231
232 void srt_table_iterate_tables(GFunc func, gpointer user_data)
233 {
234     g_slist_foreach(registered_srt_tables, func, user_data);
235 }
236
237 srt_stat_table*
238 init_srt_table(const char *name, const char *short_name, GArray *srt_array, int num_procs, const char* proc_column_name,
239                 const char *filter_string, srt_gui_init_cb gui_callback, void* gui_data, void* table_specific_data)
240 {
241     int i;
242     srt_stat_table *table = g_new(srt_stat_table, 1);
243
244     if(filter_string){
245         table->filter_string=g_strdup(filter_string);
246     } else {
247         table->filter_string=NULL;
248     }
249
250     table->name = name;
251     table->short_name = short_name;
252     table->proc_column_name = proc_column_name;
253     table->num_procs=num_procs;
254     table->procedures=(srt_procedure_t *)g_malloc(sizeof(srt_procedure_t)*num_procs);
255     for(i=0;i<num_procs;i++){
256         time_stat_init(&table->procedures[i].stats);
257         table->procedures[i].index = 0;
258         table->procedures[i].procedure = NULL;
259     }
260
261     g_array_insert_val(srt_array, srt_array->len, table);
262
263     table->table_specific_data = table_specific_data;
264
265     if (gui_callback)
266         gui_callback(table, gui_data);
267
268     return table;
269 }
270
271 void
272 init_srt_table_row(srt_stat_table *rst, int indx, const char *procedure)
273 {
274     /* we have discovered a new procedure. Extend the table accordingly */
275     if(indx>=rst->num_procs){
276         int old_num_procs=rst->num_procs;
277         int i;
278
279         rst->num_procs=indx+1;
280         rst->procedures=(srt_procedure_t *)g_realloc(rst->procedures, sizeof(srt_procedure_t)*(rst->num_procs));
281         for(i=old_num_procs;i<rst->num_procs;i++){
282             time_stat_init(&rst->procedures[i].stats);
283             rst->procedures[i].index = i;
284             rst->procedures[i].procedure=NULL;
285         }
286     }
287     rst->procedures[indx].index = indx;
288     rst->procedures[indx].procedure=g_strdup(procedure);
289 }
290
291 void
292 add_srt_table_data(srt_stat_table *rst, int indx, const nstime_t *req_time, packet_info *pinfo)
293 {
294     srt_procedure_t *rp;
295     nstime_t t, delta;
296
297     g_assert(indx >= 0 && indx < rst->num_procs);
298     rp=&rst->procedures[indx];
299
300     /* calculate time delta between request and reply */
301     t=pinfo->abs_ts;
302     nstime_delta(&delta, &t, req_time);
303
304     time_stat_update(&rp->stats, &delta, pinfo);
305 }
306
307 /*
308  * Editor modelines
309  *
310  * Local Variables:
311  * c-basic-offset: 4
312  * tab-width: 8
313  * indent-tabs-mode: nil
314  * End:
315  *
316  * ex: set shiftwidth=4 tabstop=8 expandtab:
317  * :indentSize=4:tabSize=8:noTabs=true:
318  */