Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/srt_table.c
Line
Count
Source
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
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 */
10
11
#include "config.h"
12
13
#include <string.h>
14
15
#include "proto.h"
16
#include "packet_info.h"
17
#include "srt_table.h"
18
#include <wsutil/ws_assert.h>
19
20
struct register_srt {
21
    int proto_id;              /* protocol id (0-indexed) */
22
    const char* tap_listen_str;      /* string used in register_tap_listener (NULL to use protocol name) */
23
    int max_tables;            /* Maximum number of tables expected (used by GUI to determine how to display tables) */
24
    tap_packet_cb srt_func;    /* function to be called for new incoming packets for SRT */
25
    srt_init_cb srt_init;      /* function to create dissector SRT tables */
26
    srt_param_handler_cb param_cb; /* function to parse parameters of optional arguments of tap string */
27
    void* param_data;          /* Storage for tap parameter data */
28
};
29
30
int get_srt_proto_id(register_srt_t* srt)
31
0
{
32
0
    if (!srt) {
33
0
        return -1;
34
0
    }
35
0
    return srt->proto_id;
36
0
}
37
38
const char* get_srt_tap_listener_name(register_srt_t* srt)
39
0
{
40
0
    return srt->tap_listen_str;
41
0
}
42
43
int get_srt_max_tables(register_srt_t* srt)
44
0
{
45
0
    return srt->max_tables;
46
0
}
47
48
tap_packet_cb get_srt_packet_func(register_srt_t* srt)
49
0
{
50
0
    return srt->srt_func;
51
0
}
52
53
void set_srt_table_param_data(register_srt_t* srt, void* data)
54
0
{
55
0
    srt->param_data = data;
56
0
}
57
58
void* get_srt_table_param_data(register_srt_t* srt)
59
0
{
60
0
    return srt->param_data;
61
0
}
62
63
void
64
free_srt_table_data(srt_stat_table *rst)
65
0
{
66
0
    int i;
67
68
0
    for(i=0;i<rst->num_procs;i++){
69
0
        g_free(rst->procedures[i].procedure);
70
0
        rst->procedures[i].procedure=NULL;
71
0
    }
72
0
    g_free(rst->filter_string);
73
0
    rst->filter_string=NULL;
74
0
    g_free(rst->procedures);
75
0
    rst->procedures=NULL;
76
0
    rst->num_procs=0;
77
0
}
78
79
void free_srt_table(register_srt_t *srt, GArray* srt_array)
80
0
{
81
0
    unsigned i = 0;
82
0
    srt_stat_table *srt_table;
83
84
0
    for (i = 0; i < srt_array->len; i++)
85
0
    {
86
0
        srt_table = g_array_index(srt_array, srt_stat_table*, i);
87
88
0
        free_srt_table_data(srt_table);
89
0
        g_free(srt_table);
90
0
    }
91
92
    /* Clear the tables */
93
0
    g_array_set_size(srt_array, 0);
94
95
    /* Clear out any possible parameter data */
96
0
    g_free(srt->param_data);
97
0
    srt->param_data = NULL;
98
0
}
99
100
static void reset_srt_table_data(srt_stat_table *rst)
101
0
{
102
0
    int i;
103
104
0
    for(i=0;i<rst->num_procs;i++){
105
0
        time_stat_init(&rst->procedures[i].stats);
106
0
    }
107
0
}
108
109
void reset_srt_table(GArray* srt_array)
110
0
{
111
0
    unsigned i = 0;
112
0
    srt_stat_table *srt_table;
113
114
0
    for (i = 0; i < srt_array->len; i++)
115
0
    {
116
0
        srt_table = g_array_index(srt_array, srt_stat_table*, i);
117
118
0
        reset_srt_table_data(srt_table);
119
0
    }
120
0
}
121
122
static wmem_tree_t *registered_srt_tables;
123
124
register_srt_t* get_srt_table_by_name(const char* name)
125
0
{
126
0
    return (register_srt_t*)wmem_tree_lookup_string(registered_srt_tables, name, 0);
127
0
}
128
129
char* srt_table_get_tap_string(register_srt_t* srt)
130
0
{
131
0
    GString *cmd_str = g_string_new(proto_get_protocol_filter_name(srt->proto_id));
132
0
    g_string_append(cmd_str, ",srt");
133
0
    return g_string_free(cmd_str, FALSE);
134
0
}
135
136
srt_param_handler_cb srt_table_get_param_handler_cb(register_srt_t* srt)
137
0
{
138
0
    return srt->param_cb;
139
0
}
140
141
void srt_table_get_filter(register_srt_t* srt, const char *opt_arg, const char **filter, char** err)
142
0
{
143
0
    char* cmd_str = srt_table_get_tap_string(srt);
144
0
    unsigned len = (uint32_t)strlen(cmd_str);
145
0
    unsigned pos = len;
146
0
    *filter=NULL;
147
0
    *err = NULL;
148
149
0
    if(!strncmp(opt_arg, cmd_str, len))
150
0
    {
151
0
        if (srt->param_cb != NULL)
152
0
        {
153
0
            pos = srt->param_cb(srt, opt_arg + len, err);
154
0
            if (*err != NULL)
155
0
                return;
156
157
0
            if (pos > 0)
158
0
                pos += len;
159
0
        }
160
161
0
        if (opt_arg[pos] == ',')
162
0
        {
163
0
           *filter = opt_arg + pos+1;
164
0
        }
165
0
    }
166
167
0
    g_free(cmd_str);
168
0
}
169
170
void srt_table_dissector_init(register_srt_t* srt, GArray* srt_array)
171
0
{
172
0
    srt->srt_init(srt, srt_array);
173
0
}
174
175
void srt_table_init(void)
176
14
{
177
14
    registered_srt_tables = wmem_tree_new(wmem_epan_scope());
178
14
}
179
180
void
181
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)
182
238
{
183
238
    register_srt_t *table;
184
238
    DISSECTOR_ASSERT(init_cb);
185
238
    DISSECTOR_ASSERT(srt_packet_func);
186
187
238
    table = wmem_new(wmem_epan_scope(), register_srt_t);
188
189
238
    table->proto_id      = proto_id;
190
238
    if (tap_listener != NULL)
191
42
        table->tap_listen_str = tap_listener;
192
196
    else
193
196
        table->tap_listen_str = proto_get_protocol_filter_name(proto_id);
194
238
    table->max_tables    = max_tables;
195
238
    table->srt_func      = srt_packet_func;
196
238
    table->srt_init      = init_cb;
197
238
    table->param_cb      = param_cb;
198
238
    table->param_data    = NULL;
199
200
238
    wmem_tree_insert_string(registered_srt_tables, proto_get_protocol_filter_name(proto_id), table, 0);
201
238
}
202
203
void srt_table_iterate_tables(wmem_foreach_func func, void *user_data)
204
0
{
205
0
    wmem_tree_foreach(registered_srt_tables, func, user_data);
206
0
}
207
208
srt_stat_table*
209
init_srt_table(const char *name, const char *short_name, GArray *srt_array, int num_procs, const char* proc_column_name,
210
                const char *filter_string, void* table_specific_data)
211
0
{
212
0
    int i;
213
0
    srt_stat_table *table = g_new(srt_stat_table, 1);
214
215
0
    table->filter_string = g_strdup(filter_string);
216
217
0
    table->name = name;
218
0
    table->short_name = short_name;
219
0
    table->proc_column_name = proc_column_name;
220
0
    table->num_procs=num_procs;
221
0
    table->procedures=g_new(srt_procedure_t, num_procs);
222
0
    for(i=0;i<num_procs;i++){
223
0
        time_stat_init(&table->procedures[i].stats);
224
0
        table->procedures[i].proc_index = 0;
225
0
        table->procedures[i].procedure = NULL;
226
0
    }
227
228
0
    g_array_insert_val(srt_array, srt_array->len, table);
229
230
0
    table->table_specific_data = table_specific_data;
231
232
0
    return table;
233
0
}
234
235
void
236
init_srt_table_row(srt_stat_table *rst, int indx, const char *procedure)
237
0
{
238
    /* we have discovered a new procedure. Extend the table accordingly */
239
0
    if(indx>=rst->num_procs){
240
0
        int old_num_procs=rst->num_procs;
241
0
        int i;
242
243
0
        rst->num_procs=indx+1;
244
0
        rst->procedures=(srt_procedure_t *)g_realloc(rst->procedures, sizeof(srt_procedure_t)*(rst->num_procs));
245
0
        for(i=old_num_procs;i<rst->num_procs;i++){
246
0
            time_stat_init(&rst->procedures[i].stats);
247
0
            rst->procedures[i].proc_index = i;
248
0
            rst->procedures[i].procedure=NULL;
249
0
        }
250
0
    }
251
0
    rst->procedures[indx].proc_index = indx;
252
0
    rst->procedures[indx].procedure=g_strdup(procedure);
253
0
}
254
255
void
256
add_srt_table_data(srt_stat_table *rst, int indx, const nstime_t *req_time, packet_info *pinfo)
257
0
{
258
0
    srt_procedure_t *rp;
259
0
    nstime_t t, delta;
260
261
0
    ws_assert(indx >= 0 && indx < rst->num_procs);
262
0
    rp=&rst->procedures[indx];
263
264
    /* calculate time delta between request and reply */
265
0
    t=pinfo->abs_ts;
266
0
    nstime_delta(&delta, &t, req_time);
267
268
0
    time_stat_update(&rp->stats, &delta, pinfo);
269
0
}
270
271
/*
272
 * Editor modelines
273
 *
274
 * Local Variables:
275
 * c-basic-offset: 4
276
 * tab-width: 8
277
 * indent-tabs-mode: nil
278
 * End:
279
 *
280
 * ex: set shiftwidth=4 tabstop=8 expandtab:
281
 * :indentSize=4:tabSize=8:noTabs=true:
282
 */