Coverage Report

Created: 2026-01-02 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-lbm.c
Line
Count
Source
1
/* packet-lbm.c
2
 * Routines for LBM Packet dissection
3
 *
4
 * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
#include <epan/packet.h>
15
#include <epan/tfs.h>
16
#include "packet-lbm.h"
17
18
void proto_register_lbm(void);
19
20
/*----------------------------------------------------------------------------*/
21
/* Value translation tables.                                                  */
22
/*----------------------------------------------------------------------------*/
23
24
const true_false_string lbm_ignore_flag =
25
{
26
    "May be ignored",
27
    "Must be processed"
28
};
29
30
#define LBM_WILDCARD_PATTERN_TYPE_PCRE 1
31
#define LBM_WILDCARD_PATTERN_TYPE_REGEX 2
32
33
const value_string lbm_wildcard_pattern_type[] =
34
{
35
    { LBM_WILDCARD_PATTERN_TYPE_PCRE, "Perl Compatible Regular Expression (PCRE)" },
36
    { LBM_WILDCARD_PATTERN_TYPE_REGEX, "POSIX Extended Regular Expression (REGEX)" },
37
    { 0x0, NULL }
38
};
39
40
const value_string lbm_wildcard_pattern_type_short[] =
41
{
42
    { LBM_WILDCARD_PATTERN_TYPE_PCRE, "PCRE" },
43
    { LBM_WILDCARD_PATTERN_TYPE_REGEX, "REGEX" },
44
    { 0x0, NULL }
45
};
46
47
/* Initialization function, called whenever Wireshark loads a new capture, etc. */
48
static void lbm_init(void)
49
14
{
50
14
    lbm_channel_reset();
51
14
}
52
53
/* Register all the bits needed with the filtering engine */
54
void proto_register_lbm(void)
55
14
{
56
14
    register_init_routine(lbm_init);
57
14
}
58
59
/*----------------------------------------------------------------------------*/
60
/* Channel interface.                                                         */
61
/*----------------------------------------------------------------------------*/
62
/*
63
  lbm_next_channel_value is a counter (akin to tcp_stream_count in packet-tcp.c) used to assign a unique index to an LBM communication
64
  stream or transport session. The actual channel value consists of:
65
  - The lower 52 bits of the counter, shifted left 12 bits
66
  - A 4-bit source/client classification (for unicast channels), shifted left 8 bits
67
  - An 8-bit channel type
68
69
   6                                                                                                     1 1     0 0             0
70
   3                                                                                                     2 1     8 7             0
71
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72
  |                                    Counter                                                            |  S/C  |     Type      |
73
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74
75
  The counter wraps at 0x000ffffffffffffe, and is reset to 1 whenever Wireshark invokes any init routines registered via
76
  register_init_routine() (the call to lbm_channel_reset() is in packet-lbm.c).
77
78
  Special values are used as placeholders to indicate an as-yet-unknown transport or stream TCP channel.
79
*/
80
81
static uint64_t lbm_next_channel_value = 1;
82
83
1.16k
#define LBM_CHANNEL_TYPE_MASK UINT64_C(0x00000000000000ff)
84
7
#define LBM_CHANNEL_VALUE_LIMIT_MASK UINT64_C(0x000ffffffffffffff)
85
7
#define LBM_CHANNEL_MAX_VALUE UINT64_C(0x000ffffffffffffe)
86
87
1.62k
#define LBM_CHANNEL_VALUE_UNKNOWN UINT64_C(0xfffffffffffff000)
88
1.35k
#define LBM_CHANNEL_VALUE_UNKNOWN_SOURCE UINT64_C(0xfffffffffffff100)
89
1.31k
#define LBM_CHANNEL_VALUE_UNKNOWN_CLIENT UINT64_C(0xfffffffffffff200)
90
1.35k
#define LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP (LBM_CHANNEL_VALUE_UNKNOWN_SOURCE | LBM_CHANNEL_TRANSPORT_LBTTCP)
91
1.31k
#define LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP (LBM_CHANNEL_VALUE_UNKNOWN_CLIENT | LBM_CHANNEL_TRANSPORT_LBTTCP)
92
1.62k
#define LBM_CHANNEL_UNKNOWN_STREAM_TCP (LBM_CHANNEL_VALUE_UNKNOWN | LBM_CHANNEL_STREAM_TCP)
93
94
1.16k
#define LBM_CHANNEL_TYPE(ch) ((uint8_t)(ch & LBM_CHANNEL_TYPE_MASK))
95
96
void lbm_channel_reset(void)
97
14
{
98
14
    lbm_next_channel_value = 1;
99
14
}
100
101
uint64_t lbm_channel_assign(uint8_t channel_type)
102
7
{
103
7
    uint64_t ch;
104
7
    uint64_t ch_counter = lbm_next_channel_value++;
105
106
7
    if (lbm_next_channel_value == LBM_CHANNEL_MAX_VALUE)
107
0
    {
108
0
        lbm_next_channel_value = 1;
109
0
    }
110
7
    ch = ((uint64_t)((ch_counter & LBM_CHANNEL_VALUE_LIMIT_MASK) << LBM_CHANNEL_VALUE_SHIFT_COUNT)) | channel_type;
111
7
    return (ch);
112
7
}
113
114
bool lbm_channel_is_transport(uint64_t channel)
115
732
{
116
732
    uint8_t ch_type;
117
118
732
    ch_type = LBM_CHANNEL_TYPE(channel);
119
732
    switch (ch_type)
120
732
    {
121
43
        case LBM_CHANNEL_TRANSPORT_LBTTCP:
122
43
        case LBM_CHANNEL_TRANSPORT_LBTRU:
123
43
        case LBM_CHANNEL_TRANSPORT_LBTRM:
124
43
        case LBM_CHANNEL_TRANSPORT_LBTIPC:
125
43
        case LBM_CHANNEL_TRANSPORT_LBTRDMA:
126
43
        case LBM_CHANNEL_TRANSPORT_LBTSMX:
127
43
            return true;
128
689
        default:
129
689
            break;
130
732
    }
131
689
    return false;
132
732
}
133
134
uint8_t lbm_channel_type(uint64_t channel)
135
437
{
136
437
    uint8_t ch_type;
137
138
437
    ch_type = LBM_CHANNEL_TYPE(channel);
139
437
    return (ch_type);
140
437
}
141
142
uint64_t lbm_channel_assign_unknown_transport_source_lbttcp(void)
143
14
{
144
14
    return (LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP);
145
14
}
146
147
uint64_t lbm_channel_assign_unknown_transport_client_lbttcp(void)
148
20
{
149
20
    return (LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP);
150
20
}
151
152
uint64_t lbm_channel_assign_unknown_stream_tcp(void)
153
810
{
154
810
    return (LBM_CHANNEL_UNKNOWN_STREAM_TCP);
155
810
}
156
157
bool lbm_channel_is_unknown_transport_lbttcp(uint64_t channel)
158
899
{
159
899
    return (lbm_channel_is_unknown_transport_source_lbttcp(channel) || lbm_channel_is_unknown_transport_client_lbttcp(channel));
160
899
}
161
162
bool lbm_channel_is_unknown_transport_source_lbttcp(uint64_t channel)
163
1.33k
{
164
1.33k
    if (channel == LBM_CHANNEL_UNKNOWN_TRANSPORT_SOURCE_LBTTCP)
165
44
    {
166
44
        return true;
167
44
    }
168
1.29k
    return false;
169
1.33k
}
170
171
bool lbm_channel_is_unknown_transport_client_lbttcp(uint64_t channel)
172
1.29k
{
173
1.29k
    if (channel == LBM_CHANNEL_UNKNOWN_TRANSPORT_CLIENT_LBTTCP)
174
65
    {
175
65
        return true;
176
65
    }
177
1.22k
    return false;
178
1.29k
}
179
180
bool lbm_channel_is_unknown_stream_tcp(uint64_t channel)
181
810
{
182
810
    if (channel == LBM_CHANNEL_UNKNOWN_STREAM_TCP)
183
810
    {
184
810
        return true;
185
810
    }
186
0
    return false;
187
810
}
188
189
bool lbm_channel_is_known(uint64_t channel)
190
895
{
191
895
    return (!lbm_channel_is_unknown_transport_lbttcp(channel) && !lbm_channel_is_unknown_stream_tcp(channel));
192
895
}
193
194
/*----------------------------------------------------------------------------*/
195
/* Frame/SQN interface.                                                       */
196
/*----------------------------------------------------------------------------*/
197
lbm_transport_frame_t * lbm_transport_frame_add(wmem_tree_t * list, uint8_t type, uint32_t frame, uint32_t sqn, bool retransmission)
198
0
{
199
0
    lbm_transport_frame_t * frame_entry = NULL;
200
201
    /* Locate the frame. */
202
0
    frame_entry = (lbm_transport_frame_t *) wmem_tree_lookup32(list, frame);
203
0
    if (frame_entry != NULL)
204
0
    {
205
0
        return (frame_entry);
206
0
    }
207
0
    frame_entry = wmem_new(wmem_file_scope(), lbm_transport_frame_t);
208
0
    frame_entry->frame = frame;
209
0
    frame_entry->type = type;
210
0
    frame_entry->sqn = sqn;
211
0
    frame_entry->previous_frame = 0;
212
0
    frame_entry->previous_type_frame = 0;
213
0
    frame_entry->next_frame = 0;
214
0
    frame_entry->next_type_frame = 0;
215
0
    frame_entry->retransmission = retransmission;
216
0
    frame_entry->sqn_gap = 0;
217
0
    frame_entry->ooo_gap = 0;
218
0
    frame_entry->duplicate = false;
219
0
    wmem_tree_insert32(list, frame, (void *) frame_entry);
220
0
    return (frame_entry);
221
0
}
222
223
lbm_transport_sqn_t * lbm_transport_sqn_add(wmem_tree_t * list, lbm_transport_frame_t * frame)
224
0
{
225
0
    lbm_transport_sqn_t * sqn_entry = NULL;
226
0
    lbm_transport_sqn_frame_t * frame_entry = NULL;
227
228
    /* Locate the SQN. */
229
0
    sqn_entry = (lbm_transport_sqn_t *) wmem_tree_lookup32(list, frame->sqn);
230
0
    if (sqn_entry == NULL)
231
0
    {
232
0
        sqn_entry = wmem_new(wmem_file_scope(), lbm_transport_sqn_t);
233
0
        sqn_entry->sqn = frame->sqn;
234
0
        sqn_entry->frame_count = 0;
235
0
        sqn_entry->frame = wmem_tree_new(wmem_file_scope());
236
0
        wmem_tree_insert32(list, frame->sqn, (void *) sqn_entry);
237
0
    }
238
    /* Add this frame to the list of frames this SQN appears in. */
239
0
    frame_entry = wmem_new(wmem_file_scope(), lbm_transport_sqn_frame_t);
240
0
    frame_entry->frame = frame->frame;
241
0
    frame_entry->retransmission = frame->retransmission;
242
0
    wmem_tree_insert32(sqn_entry->frame, frame->frame, (void *) frame_entry);
243
0
    sqn_entry->frame_count++;
244
0
    return (sqn_entry);
245
0
}
246
247
/*----------------------------------------------------------------------------*/
248
/* Topic interface.                                                           */
249
/*----------------------------------------------------------------------------*/
250
static wmem_tree_t * lbm_topic_table;
251
252
0
#define LBM_TOPIC_KEY_ELEMENT_COUNT 3
253
0
#define LBM_TOPIC_KEY_ELEMENT_CHANNEL_HIGH 0
254
0
#define LBM_TOPIC_KEY_ELEMENT_CHANNEL_LOW 1
255
0
#define LBM_TOPIC_KEY_ELEMENT_TOPIC_INDEX 2
256
257
struct lbm_topic_t_stct;
258
typedef struct lbm_topic_t_stct lbm_topic_t;
259
260
typedef struct
261
{
262
    uint64_t channel;
263
    uint32_t topic_idx;
264
    lbm_topic_t * topic;
265
} lbm_topic_key_t;
266
267
struct lbm_topic_t_stct
268
{
269
    lbm_topic_key_t key;
270
    char * topic;
271
};
272
273
void lbm_topic_init(void)
274
14
{
275
14
    lbm_topic_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
276
14
}
277
278
static void lbm_topic_build_key(uint32_t * key_value, wmem_tree_key_t * key, uint64_t channel, uint32_t topic_index)
279
0
{
280
0
    key_value[LBM_TOPIC_KEY_ELEMENT_CHANNEL_HIGH] = (uint32_t) ((channel >> 32) & 0xffffffff);
281
0
    key_value[LBM_TOPIC_KEY_ELEMENT_CHANNEL_LOW] = (uint32_t) (channel & 0xffffffff);
282
0
    key_value[LBM_TOPIC_KEY_ELEMENT_TOPIC_INDEX] = topic_index;
283
0
    key[0].length = LBM_TOPIC_KEY_ELEMENT_COUNT;
284
0
    key[0].key = key_value;
285
0
    key[1].length = 0;
286
0
    key[1].key = NULL;
287
0
}
288
289
static lbm_topic_t * lbm_topic_locate(uint64_t channel, uint32_t topic_index)
290
0
{
291
0
    lbm_topic_t * entry = NULL;
292
0
    uint32_t keyval[LBM_TOPIC_KEY_ELEMENT_COUNT];
293
0
    wmem_tree_key_t tkey[2];
294
295
0
    lbm_topic_build_key(keyval, tkey, channel, topic_index);
296
0
    entry = (lbm_topic_t *) wmem_tree_lookup32_array(lbm_topic_table, tkey);
297
0
    return (entry);
298
0
}
299
300
const char * lbm_topic_find(uint64_t channel, uint32_t topic_index)
301
0
{
302
0
    lbm_topic_t * entry = NULL;
303
0
    const char * topic = NULL;
304
305
0
    entry = lbm_topic_locate(channel, topic_index);
306
0
    if (entry != NULL)
307
0
    {
308
0
        topic = entry->topic;
309
0
    }
310
0
    return (topic);
311
0
}
312
313
void lbm_topic_add(uint64_t channel, uint32_t topic_index, const char * name)
314
0
{
315
0
    lbm_topic_t * entry;
316
0
    uint32_t keyval[LBM_TOPIC_KEY_ELEMENT_COUNT];
317
0
    wmem_tree_key_t tkey[2];
318
319
0
    entry = lbm_topic_locate(channel, topic_index);
320
0
    if (entry != NULL)
321
0
    {
322
0
        return;
323
0
    }
324
0
    entry = wmem_new(wmem_file_scope(), lbm_topic_t);
325
0
    entry->key.channel = channel;
326
0
    entry->key.topic_idx = topic_index;
327
0
    entry->key.topic = entry;
328
0
    entry->topic = wmem_strdup(wmem_file_scope(), name);
329
0
    lbm_topic_build_key(keyval, tkey, channel, topic_index);
330
0
    wmem_tree_insert32_array(lbm_topic_table, tkey, (void *) entry);
331
0
}
332
333
/*
334
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
335
 *
336
 * Local variables:
337
 * c-basic-offset: 4
338
 * tab-width: 8
339
 * indent-tabs-mode: nil
340
 * End:
341
 *
342
 * vi: set shiftwidth=4 tabstop=8 expandtab:
343
 * :indentSize=4:tabSize=8:noTabs=true:
344
 */