Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-lbttcp.c
Line
Count
Source
1
/* packet-lbttcp.c
2
 * Routines for LBM TCP 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
15
#include <epan/packet.h>
16
#include <epan/prefs.h>
17
#include <epan/uat.h>
18
#include <epan/to_str.h>
19
#include "packet-tcp.h"
20
#include "packet-lbm.h"
21
#include "packet-lbttcp.h"
22
23
void proto_register_lbttcp(void);
24
void proto_reg_handoff_lbttcp(void);
25
26
/* Protocol handle */
27
static int proto_lbttcp;
28
29
/* Dissector handle */
30
static dissector_handle_t lbttcp_dissector_handle;
31
32
/*----------------------------------------------------------------------------*/
33
/* LBT-TCP protocol management.                                               */
34
/*----------------------------------------------------------------------------*/
35
36
typedef struct
37
{
38
    wmem_tree_t * frame_tree;
39
    wmem_tree_t * session_tree;
40
} lbttcp_transport_conv_data_t;
41
42
static const address lbttcp_null_address = ADDRESS_INIT_NONE;
43
44
lbttcp_transport_t * lbttcp_transport_find(const address * source_address, uint16_t source_port, uint32_t session_id, uint32_t frame)
45
28
{
46
28
    lbttcp_transport_t * entry = NULL;
47
28
    conversation_t * conv = NULL;
48
28
    lbttcp_transport_conv_data_t * conv_data = NULL;
49
50
28
    conv = find_conversation(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0);
51
28
    if (conv != NULL)
52
0
    {
53
0
        conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp);
54
0
        if (conv_data != NULL)
55
0
        {
56
0
            entry = (lbttcp_transport_t *) wmem_tree_lookup32(conv_data->session_tree, session_id);
57
0
        }
58
0
    }
59
28
    return (entry);
60
28
}
61
62
static lbttcp_transport_t * lbttcp_transport_create(const address * source_address, uint16_t source_port, uint32_t session_id)
63
0
{
64
0
    lbttcp_transport_t * transport = NULL;
65
66
0
    transport = wmem_new(wmem_file_scope(), lbttcp_transport_t);
67
0
    copy_address_wmem(wmem_file_scope(), &(transport->source_address), source_address);
68
0
    transport->source_port = source_port;
69
0
    transport->session_id = session_id;
70
0
    transport->channel = lbm_channel_assign(LBM_CHANNEL_TRANSPORT_LBTTCP);
71
0
    transport->next_client_id = 1;
72
0
    transport->client_list = wmem_list_new(wmem_file_scope());
73
0
    return (transport);
74
0
}
75
76
lbttcp_transport_t * lbttcp_transport_add(const address * source_address, uint16_t source_port, uint32_t session_id, uint32_t frame)
77
0
{
78
0
    lbttcp_transport_t * entry = NULL;
79
0
    conversation_t * conv = NULL;
80
0
    lbttcp_transport_conv_data_t * conv_data = NULL;
81
82
0
    conv = find_conversation(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0);
83
0
    if (conv == NULL)
84
0
    {
85
0
        conv = conversation_new(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0);
86
0
    }
87
0
    conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp);
88
0
    if (conv_data == NULL)
89
0
    {
90
0
        conv_data = wmem_new(wmem_file_scope(), lbttcp_transport_conv_data_t);
91
0
        conv_data->frame_tree = wmem_tree_new(wmem_file_scope());
92
0
        conv_data->session_tree = wmem_tree_new(wmem_file_scope());
93
0
        conversation_add_proto_data(conv, proto_lbttcp, (void *) conv_data);
94
0
    }
95
0
    entry = (lbttcp_transport_t *) wmem_tree_lookup32(conv_data->session_tree, session_id);
96
0
    if (entry != NULL)
97
0
    {
98
0
        return (entry);
99
0
    }
100
0
    entry = lbttcp_transport_create(source_address, source_port, session_id);
101
0
    wmem_tree_insert32(conv_data->session_tree, session_id, (void *) entry);
102
0
    wmem_tree_insert32(conv_data->frame_tree, frame, (void *) entry);
103
0
    return (entry);
104
0
}
105
106
static lbttcp_client_transport_t * lbttcp_client_transport_find(lbttcp_transport_t * transport, const address * receiver_address, uint16_t receiver_port, uint32_t frame)
107
0
{
108
0
    lbttcp_client_transport_t * entry = NULL;
109
0
    conversation_t * client_conv = NULL;
110
111
0
    if (transport == NULL)
112
0
    {
113
0
        return (NULL);
114
0
    }
115
0
    client_conv = find_conversation(frame, &(transport->source_address), receiver_address, CONVERSATION_TCP, transport->source_port, receiver_port, 0);
116
0
    if (client_conv != NULL)
117
0
    {
118
0
        wmem_tree_t * session_tree = NULL;
119
120
0
        session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbttcp);
121
0
        if (session_tree != NULL)
122
0
        {
123
0
            entry = (lbttcp_client_transport_t *) wmem_tree_lookup32(session_tree, transport->session_id);
124
0
        }
125
0
    }
126
0
    return (entry);
127
0
}
128
129
static lbttcp_client_transport_t * lbttcp_client_transport_add(lbttcp_transport_t * transport, const address * receiver_address, uint16_t receiver_port, uint32_t frame)
130
0
{
131
0
    lbttcp_client_transport_t * entry;
132
0
    conversation_t * client_conv = NULL;
133
0
    wmem_tree_t * session_tree = NULL;
134
135
0
    if (transport == NULL)
136
0
    {
137
0
        return (NULL);
138
0
    }
139
0
    entry = lbttcp_client_transport_find(transport, receiver_address, receiver_port, frame);
140
0
    if (entry != NULL)
141
0
    {
142
0
        return (entry);
143
0
    }
144
0
    entry = wmem_new(wmem_file_scope(), lbttcp_client_transport_t);
145
0
    copy_address_wmem(wmem_file_scope(), &(entry->receiver_address), receiver_address);
146
0
    entry->receiver_port = receiver_port;
147
0
    entry->id = transport->next_client_id++;
148
149
    /* See if a conversation for this address/port pair exists. */
150
0
    client_conv = find_conversation(frame, &(transport->source_address), receiver_address, CONVERSATION_TCP, transport->source_port, receiver_port, 0);
151
0
    if (client_conv == NULL)
152
0
    {
153
0
        client_conv = conversation_new(frame, &(transport->source_address), receiver_address, CONVERSATION_TCP, transport->source_port, receiver_port, 0);
154
0
        session_tree = wmem_tree_new(wmem_file_scope());
155
0
        conversation_add_proto_data(client_conv, proto_lbttcp, (void *) session_tree);
156
0
    }
157
0
    session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbttcp);
158
0
    if (session_tree == NULL)
159
0
    {
160
0
        session_tree = wmem_tree_new(wmem_file_scope());
161
0
        conversation_add_proto_data(client_conv, proto_lbttcp, (void *) session_tree);
162
0
    }
163
0
    wmem_tree_insert32(session_tree, transport->session_id, (void *) entry);
164
165
    /* Add this client to the transport. */
166
0
    wmem_list_append(transport->client_list, (void *) entry);
167
0
    return (entry);
168
0
}
169
170
char * lbttcp_transport_source_string(wmem_allocator_t* allocator, const address * source_address, uint16_t source_port, uint32_t session_id)
171
0
{
172
0
    char * bufptr = NULL;
173
174
0
    if (session_id == 0)
175
0
    {
176
0
        bufptr = wmem_strdup_printf(allocator, "TCP:%s:%" PRIu16, address_to_str(allocator, source_address), source_port);
177
0
    }
178
0
    else
179
0
    {
180
0
        bufptr = wmem_strdup_printf(allocator, "TCP:%s:%" PRIu16 ":%08x", address_to_str(allocator, source_address), source_port, session_id);
181
0
    }
182
0
    return (bufptr);
183
0
}
184
185
bool lbttcp_transport_sid_find(const address * source_address, uint16_t source_port, uint32_t frame, uint32_t * session_id)
186
49
{
187
49
    conversation_t * conv = NULL;
188
49
    lbttcp_transport_conv_data_t * conv_data = NULL;
189
49
    lbttcp_transport_t * transport = NULL;
190
191
49
    conv = find_conversation(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0);
192
49
    if (conv == NULL)
193
49
    {
194
49
        return false;
195
49
    }
196
0
    conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp);
197
0
    if (conv_data == NULL)
198
0
    {
199
0
        return false;
200
0
    }
201
0
    if (conv_data->frame_tree == NULL)
202
0
    {
203
0
        return false;
204
0
    }
205
0
    transport = (lbttcp_transport_t *)wmem_tree_lookup32_le(conv_data->frame_tree, frame);
206
0
    if (transport == NULL)
207
0
    {
208
0
        return false;
209
0
    }
210
0
    *session_id = transport->session_id;
211
0
    return true;
212
0
}
213
214
void lbttcp_transport_sid_add(const address * source_address, uint16_t source_port, uint32_t frame, uint32_t session_id)
215
0
{
216
0
    conversation_t * conv = NULL;
217
0
    lbttcp_transport_conv_data_t * conv_data = NULL;
218
0
    lbttcp_transport_t * transport = NULL;
219
220
0
    conv = find_conversation(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0);
221
0
    if (conv == NULL)
222
0
    {
223
0
        conv = conversation_new(frame, source_address, &lbttcp_null_address, CONVERSATION_TCP, source_port, 0, 0);
224
0
    }
225
0
    conv_data = (lbttcp_transport_conv_data_t *) conversation_get_proto_data(conv, proto_lbttcp);
226
0
    if (conv_data == NULL)
227
0
    {
228
0
        conv_data = wmem_new(wmem_file_scope(), lbttcp_transport_conv_data_t);
229
0
        conv_data->frame_tree = wmem_tree_new(wmem_file_scope());
230
0
        conv_data->session_tree = wmem_tree_new(wmem_file_scope());
231
0
        conversation_add_proto_data(conv, proto_lbttcp, (void *) conv_data);
232
0
    }
233
    /* Lookup by frame */
234
0
    transport = (lbttcp_transport_t *) wmem_tree_lookup32_le(conv_data->frame_tree, frame);
235
0
    if (transport != NULL)
236
0
    {
237
0
        if (transport->session_id != session_id)
238
0
        {
239
0
            transport = NULL;
240
0
        }
241
0
    }
242
0
    if (transport == NULL)
243
0
    {
244
0
        transport = lbttcp_transport_create(source_address, source_port, session_id);
245
0
        wmem_tree_insert32(conv_data->session_tree, session_id, (void *) transport);
246
0
        wmem_tree_insert32(conv_data->frame_tree, frame, (void *) transport);
247
0
    }
248
0
}
249
250
/*----------------------------------------------------------------------------*/
251
/* Preferences.                                                               */
252
/*----------------------------------------------------------------------------*/
253
254
/* Preferences default values. */
255
#define LBTTCP_DEFAULT_SOURCE_PORT_LOW 14371
256
#define LBTTCP_DEFAULT_SOURCE_PORT_HIGH 14390
257
#define LBTTCP_DEFAULT_REQUEST_PORT_LOW 14391
258
#define LBTTCP_DEFAULT_REQUEST_PORT_HIGH 14395
259
#define LBTTCP_DEFAULT_STORE_PORT_LOW 0
260
#define LBTTCP_DEFAULT_STORE_PORT_HIGH 0
261
262
/* Global preferences variables (altered by the preferences dialog). */
263
static uint32_t global_lbttcp_source_port_low = LBTTCP_DEFAULT_SOURCE_PORT_LOW;
264
static uint32_t global_lbttcp_source_port_high  = LBTTCP_DEFAULT_SOURCE_PORT_HIGH;
265
static uint32_t global_lbttcp_request_port_low = LBTTCP_DEFAULT_REQUEST_PORT_LOW;
266
static uint32_t global_lbttcp_request_port_high = LBTTCP_DEFAULT_REQUEST_PORT_HIGH;
267
static uint32_t global_lbttcp_store_port_low = LBTTCP_DEFAULT_STORE_PORT_LOW;
268
static uint32_t global_lbttcp_store_port_high = LBTTCP_DEFAULT_STORE_PORT_HIGH;
269
static bool global_lbttcp_use_tag;
270
271
/* Local preferences variables (used by the dissector). */
272
static uint32_t lbttcp_source_port_low = LBTTCP_DEFAULT_SOURCE_PORT_LOW;
273
static uint32_t lbttcp_source_port_high = LBTTCP_DEFAULT_SOURCE_PORT_HIGH;
274
static uint32_t lbttcp_request_port_low = LBTTCP_DEFAULT_REQUEST_PORT_LOW;
275
static uint32_t lbttcp_request_port_high = LBTTCP_DEFAULT_REQUEST_PORT_HIGH;
276
static uint32_t lbttcp_store_port_low = LBTTCP_DEFAULT_STORE_PORT_LOW;
277
static uint32_t lbttcp_store_port_high = LBTTCP_DEFAULT_STORE_PORT_HIGH;
278
static bool lbttcp_use_tag;
279
280
/* Tag definitions. */
281
typedef struct
282
{
283
    char * name;
284
    uint32_t source_port_low;
285
    uint32_t source_port_high;
286
    uint32_t request_port_low;
287
    uint32_t request_port_high;
288
    uint32_t store_port_low;
289
    uint32_t store_port_high;
290
} lbttcp_tag_entry_t;
291
292
static lbttcp_tag_entry_t * lbttcp_tag_entry;
293
static unsigned lbttcp_tag_count;
294
295
0
UAT_CSTRING_CB_DEF(lbttcp_tag, name, lbttcp_tag_entry_t)
296
0
UAT_DEC_CB_DEF(lbttcp_tag, source_port_low, lbttcp_tag_entry_t)
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_source_port_low_set_cb
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_source_port_low_tostr_cb
297
0
UAT_DEC_CB_DEF(lbttcp_tag, source_port_high, lbttcp_tag_entry_t)
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_source_port_high_set_cb
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_source_port_high_tostr_cb
298
0
UAT_DEC_CB_DEF(lbttcp_tag, request_port_low, lbttcp_tag_entry_t)
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_request_port_low_set_cb
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_request_port_low_tostr_cb
299
0
UAT_DEC_CB_DEF(lbttcp_tag, request_port_high, lbttcp_tag_entry_t)
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_request_port_high_set_cb
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_request_port_high_tostr_cb
300
0
UAT_DEC_CB_DEF(lbttcp_tag, store_port_low, lbttcp_tag_entry_t)
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_store_port_low_set_cb
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_store_port_low_tostr_cb
301
0
UAT_DEC_CB_DEF(lbttcp_tag, store_port_high, lbttcp_tag_entry_t)
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_store_port_high_set_cb
Unexecuted instantiation: packet-lbttcp.c:lbttcp_tag_store_port_high_tostr_cb
302
static uat_field_t lbttcp_tag_array[] =
303
{
304
    UAT_FLD_CSTRING(lbttcp_tag, name, "Tag name", "Tag name"),
305
    UAT_FLD_DEC(lbttcp_tag, source_port_low, "Source port low", "Source port low"),
306
    UAT_FLD_DEC(lbttcp_tag, source_port_high, "Source port high", "Source port high"),
307
    UAT_FLD_DEC(lbttcp_tag, request_port_low, "Request port low", "Request port low"),
308
    UAT_FLD_DEC(lbttcp_tag, request_port_high, "Request port high", "Request port high"),
309
    UAT_FLD_DEC(lbttcp_tag, store_port_low, "Store port low", "Store port low"),
310
    UAT_FLD_DEC(lbttcp_tag, store_port_high, "Store port high", "Store port high"),
311
    UAT_END_FIELDS
312
};
313
314
/*----------------------------------------------------------------------------*/
315
/* UAT callback functions.                                                    */
316
/*----------------------------------------------------------------------------*/
317
static bool lbttcp_tag_update_cb(void * record, char * * error_string)
318
0
{
319
0
    lbttcp_tag_entry_t * tag = (lbttcp_tag_entry_t *)record;
320
321
0
    if (tag->name == NULL)
322
0
    {
323
0
        *error_string = g_strdup("Tag name can't be empty");
324
0
        return false;
325
0
    }
326
0
    else
327
0
    {
328
0
        g_strstrip(tag->name);
329
0
        if (tag->name[0] == 0)
330
0
        {
331
0
            *error_string = g_strdup("Tag name can't be empty");
332
0
            return false;
333
0
        }
334
0
    }
335
0
    return true;
336
0
}
337
338
static void * lbttcp_tag_copy_cb(void * destination, const void * source, size_t length _U_)
339
0
{
340
0
    const lbttcp_tag_entry_t * src = (const lbttcp_tag_entry_t *)source;
341
0
    lbttcp_tag_entry_t * dest = (lbttcp_tag_entry_t *)destination;
342
343
0
    dest->name = g_strdup(src->name);
344
0
    dest->source_port_low = src->source_port_low;
345
0
    dest->source_port_high = src->source_port_high;
346
0
    dest->request_port_low = src->request_port_low;
347
0
    dest->request_port_high = src->request_port_high;
348
0
    dest->store_port_low = src->store_port_low;
349
0
    dest->store_port_high = src->store_port_high;
350
0
    return (dest);
351
0
}
352
353
static void lbttcp_tag_free_cb(void * record)
354
0
{
355
0
    lbttcp_tag_entry_t * tag = (lbttcp_tag_entry_t *)record;
356
357
0
    if (tag->name != NULL)
358
0
    {
359
0
        g_free(tag->name);
360
0
        tag->name = NULL;
361
0
    }
362
0
}
363
364
static const lbttcp_tag_entry_t * lbttcp_tag_locate(packet_info * pinfo)
365
0
{
366
0
    unsigned idx;
367
0
    const lbttcp_tag_entry_t * tag = NULL;
368
369
0
    if (!lbttcp_use_tag)
370
0
    {
371
0
        return (NULL);
372
0
    }
373
374
0
    for (idx = 0; idx < lbttcp_tag_count; ++idx)
375
0
    {
376
0
        tag = &(lbttcp_tag_entry[idx]);
377
0
        if (((pinfo->srcport >= tag->source_port_low) && (pinfo->srcport <= tag->source_port_high))
378
0
            || ((pinfo->destport >= tag->source_port_low) && (pinfo->destport <= tag->source_port_high))
379
0
            || ((pinfo->srcport >= tag->request_port_low) && (pinfo->srcport <= tag->request_port_high))
380
0
            || ((pinfo->destport >= tag->request_port_low) && (pinfo->destport <= tag->request_port_high))
381
0
            || ((pinfo->srcport >= tag->store_port_low) && (pinfo->srcport <= tag->store_port_high))
382
0
            || ((pinfo->destport >= tag->store_port_low) && (pinfo->destport <= tag->store_port_high)))
383
0
        {
384
0
            return (tag);
385
0
        }
386
0
    }
387
0
    return (NULL);
388
0
}
389
390
static char * lbttcp_tag_find(packet_info * pinfo)
391
0
{
392
0
    const lbttcp_tag_entry_t * tag = NULL;
393
394
0
    if (!lbttcp_use_tag)
395
0
    {
396
0
        return (NULL);
397
0
    }
398
399
0
    tag = lbttcp_tag_locate(pinfo);
400
0
    if (tag != NULL)
401
0
    {
402
0
        return tag->name;
403
0
    }
404
0
    return (NULL);
405
0
}
406
407
/*----------------------------------------------------------------------------*/
408
/* Handles of all types.                                                      */
409
/*----------------------------------------------------------------------------*/
410
411
/* Dissector tree handles */
412
static int ett_lbttcp;
413
static int ett_lbttcp_channel;
414
415
/* Dissector field handles */
416
static int hf_lbttcp_tag;
417
static int hf_lbttcp_channel;
418
static int hf_lbttcp_channel_id;
419
static int hf_lbttcp_channel_client;
420
421
static bool lbttcp_packet_is_transport_source(packet_info * pinfo, const lbttcp_tag_entry_t * tag)
422
798
{
423
798
    bool is_transport_source_packet = false;
424
425
798
    if (tag == NULL)
426
798
    {
427
798
        if ((pinfo->srcport >= lbttcp_source_port_low) && (pinfo->srcport <= lbttcp_source_port_high))
428
14
        {
429
14
            is_transport_source_packet = true;
430
14
        }
431
798
    }
432
0
    else
433
0
    {
434
0
        if ((pinfo->srcport >= tag->source_port_low) && (pinfo->srcport <= tag->source_port_high))
435
0
        {
436
0
            is_transport_source_packet = true;
437
0
        }
438
0
    }
439
798
    return (is_transport_source_packet);
440
798
}
441
442
static bool lbttcp_packet_is_transport_client(packet_info * pinfo, const lbttcp_tag_entry_t * tag)
443
784
{
444
784
    bool is_transport_client_packet = false;
445
446
784
    if (tag == NULL)
447
784
    {
448
784
        if ((pinfo->destport >= lbttcp_source_port_low) && (pinfo->destport <= lbttcp_source_port_high))
449
14
        {
450
14
            is_transport_client_packet = true;
451
14
        }
452
784
    }
453
0
    else
454
0
    {
455
0
        if ((pinfo->destport >= tag->source_port_low) && (pinfo->destport <= tag->source_port_high))
456
0
        {
457
0
            is_transport_client_packet = true;
458
0
        }
459
0
    }
460
784
    return (is_transport_client_packet);
461
784
}
462
463
static unsigned get_lbttcp_pdu_length(packet_info * pinfo _U_, tvbuff_t * tvb,
464
                                   int offset, void *data _U_)
465
808
{
466
808
    return lbmc_get_message_length(tvb, offset);
467
808
}
468
469
static int dissect_lbttcp_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * dissector_data _U_)
470
798
{
471
798
    proto_tree * lbttcp_tree = NULL;
472
798
    proto_item * ti = NULL;
473
798
    char * tag_name = NULL;
474
798
    int len_dissected;
475
798
    const lbttcp_tag_entry_t * tag = NULL;
476
798
    uint64_t channel = LBM_CHANNEL_NO_CHANNEL;
477
798
    uint32_t client_id = 0;
478
798
    bool from_source = false;
479
798
    bool transport_packet = false;
480
481
798
    if (lbttcp_use_tag)
482
0
    {
483
0
        tag = lbttcp_tag_locate(pinfo);
484
0
        tag_name = lbttcp_tag_find(pinfo);
485
0
    }
486
798
    if (tag_name != NULL)
487
0
    {
488
0
        ti = proto_tree_add_protocol_format(tree, proto_lbttcp, tvb, 0, -1, "LBT-TCP Protocol (Tag: %s)", tag_name);
489
0
    }
490
798
    else
491
798
    {
492
798
        ti = proto_tree_add_protocol_format(tree, proto_lbttcp, tvb, 0, -1, "LBT-TCP Protocol");
493
798
    }
494
798
    lbttcp_tree = proto_item_add_subtree(ti, ett_lbttcp);
495
798
    if (tag_name != NULL)
496
0
    {
497
0
        proto_item * item = NULL;
498
499
0
        item = proto_tree_add_string(lbttcp_tree, hf_lbttcp_tag, tvb, 0, 0, tag_name);
500
0
        proto_item_set_generated(item);
501
0
    }
502
798
    if (lbttcp_packet_is_transport_source(pinfo, tag))
503
14
    {
504
14
        from_source = true;
505
14
        transport_packet = true;
506
14
    }
507
784
    else if (lbttcp_packet_is_transport_client(pinfo, tag))
508
14
    {
509
14
        from_source = false;
510
14
        transport_packet = true;
511
14
    }
512
798
    if (transport_packet)
513
28
    {
514
28
        address source_address;
515
28
        address client_address;
516
28
        uint16_t srcport;
517
28
        uint16_t clntport;
518
28
        uint32_t sid = 0;
519
28
        lbttcp_transport_t * transport = NULL;
520
28
        lbttcp_client_transport_t * client = NULL;
521
522
28
        if (from_source)
523
14
        {
524
14
            copy_address_shallow(&source_address, &(pinfo->src));
525
14
            srcport = pinfo->srcport;
526
14
            copy_address_shallow(&client_address, &(pinfo->dst));
527
14
            clntport = pinfo->destport;
528
14
        }
529
14
        else
530
14
        {
531
14
            copy_address_shallow(&source_address, &(pinfo->dst));
532
14
            srcport = pinfo->destport;
533
14
            copy_address_shallow(&client_address, &(pinfo->src));
534
14
            clntport = pinfo->srcport;
535
14
        }
536
        /* See if we have a matching transport with no session ID. */
537
28
        transport = lbttcp_transport_find(&source_address, srcport, sid, pinfo->num);
538
28
        if (transport == NULL)
539
28
        {
540
            /* See if we know about a SID */
541
28
            if (lbttcp_transport_sid_find(&source_address, srcport, pinfo->num, &sid))
542
0
            {
543
0
                transport = lbttcp_transport_find(&source_address, srcport, sid, pinfo->num);
544
0
            }
545
28
        }
546
28
        if (transport != NULL)
547
0
        {
548
0
            channel = transport->channel;
549
            /* See if we already know about this client */
550
0
            client = lbttcp_client_transport_find(transport, &client_address, clntport, pinfo->num);
551
0
            if (client == NULL)
552
0
            {
553
                /* No - add it. */
554
0
                client = lbttcp_client_transport_add(transport, &client_address, clntport, pinfo->num);
555
0
            }
556
0
            if (client != NULL)
557
0
            {
558
0
                client_id = client->id;
559
0
            }
560
0
        }
561
28
        else
562
28
        {
563
28
            if (PINFO_FD_VISITED(pinfo))
564
0
            {
565
                /* No TIR and no session ID seen, so create the transport */
566
0
                transport = lbttcp_transport_add(&source_address, srcport, 0, pinfo->num);
567
0
                if (transport != NULL)
568
0
                {
569
0
                    channel = transport->channel;
570
0
                    client = lbttcp_client_transport_add(transport, &client_address, clntport, pinfo->num);
571
0
                    if (client != NULL)
572
0
                    {
573
0
                        client_id = client->id;
574
0
                    }
575
0
                }
576
0
            }
577
28
            else
578
28
            {
579
                /* Defer determining the channel. */
580
28
                if (from_source)
581
14
                {
582
14
                    channel = lbm_channel_assign_unknown_transport_source_lbttcp();
583
14
                }
584
14
                else
585
14
                {
586
14
                    channel = lbm_channel_assign_unknown_transport_client_lbttcp();
587
14
                }
588
28
            }
589
28
        }
590
28
    }
591
770
    else
592
770
    {
593
770
        channel = lbm_channel_assign_unknown_stream_tcp();
594
770
    }
595
798
    if (lbm_channel_is_known(channel))
596
0
    {
597
0
        proto_item * channel_item = NULL;
598
0
        proto_tree * channel_tree = NULL;
599
600
0
        channel_item = proto_tree_add_item(lbttcp_tree, hf_lbttcp_channel, tvb, 0, 0, ENC_NA);
601
0
        proto_item_set_generated(channel_item);
602
0
        channel_tree = proto_item_add_subtree(channel_item, ett_lbttcp_channel);
603
0
        channel_item = proto_tree_add_uint64(channel_tree, hf_lbttcp_channel_id, tvb, 0, 0, channel);
604
0
        proto_item_set_generated(channel_item);
605
0
        channel_item = proto_tree_add_uint(channel_tree, hf_lbttcp_channel_client, tvb, 0, 0, client_id);
606
0
        proto_item_set_generated(channel_item);
607
0
    }
608
798
    len_dissected = lbmc_dissect_lbmc_packet(tvb, 0, pinfo, tree, tag_name, channel);
609
798
    return (len_dissected);
610
798
}
611
612
/*
613
 * dissect_lbttcp_real - The "common" dissection for LBT-TCP
614
 */
615
static int dissect_lbttcp_real(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
616
622
{
617
622
    char * tag_name = NULL;
618
619
622
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "LBT-TCP");
620
622
    col_clear(pinfo->cinfo, COL_INFO);
621
622
    if (lbttcp_use_tag)
622
0
    {
623
0
        tag_name = lbttcp_tag_find(pinfo);
624
0
    }
625
622
    if (tag_name != NULL)
626
0
    {
627
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "[Tag: %s]", tag_name);
628
0
    }
629
622
    col_set_fence(pinfo->cinfo, COL_INFO);
630
622
    tcp_dissect_pdus(tvb, pinfo, tree, true, lbmc_get_minimum_length(), /* Need at least the msglen */
631
622
        get_lbttcp_pdu_length, dissect_lbttcp_pdu, NULL);
632
633
622
    return tvb_captured_length(tvb);
634
622
}
635
636
/*
637
 * dissect_lbttcp - The dissector for LBT-TCP
638
 */
639
static int dissect_lbttcp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data)
640
0
{
641
0
    if (!lbmc_test_lbmc_header(tvb, 0))
642
0
        return 0;
643
644
0
    return dissect_lbttcp_real(tvb, pinfo, tree, data);
645
0
}
646
647
static bool test_lbttcp_packet(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data)
648
5.99k
{
649
    /* Destination address must be IPV4 and 4 bytes in length. */
650
5.99k
    if ((pinfo->dst.type != AT_IPv4) || (pinfo->dst.len != 4))
651
1.10k
    {
652
1.10k
        return false;
653
1.10k
    }
654
655
4.88k
    if (lbttcp_use_tag)
656
0
    {
657
0
        if (lbttcp_tag_find(pinfo) != NULL)
658
0
        {
659
0
            dissect_lbttcp_real(tvb, pinfo, tree, data);
660
0
            return true;
661
0
        }
662
0
        else
663
0
        {
664
0
            return false;
665
0
        }
666
0
    }
667
668
    /*
669
        Source port or destination port must be in the source port range, or destination port must be in
670
        the request port range, or either port in the UME store port range.
671
    */
672
4.88k
    if (!(((pinfo->srcport >= lbttcp_source_port_low) && (pinfo->srcport <= lbttcp_source_port_high))
673
4.87k
          || ((pinfo->destport >= lbttcp_source_port_low) && (pinfo->destport <= lbttcp_source_port_high))
674
4.85k
          || ((pinfo->srcport >= lbttcp_request_port_low) && (pinfo->srcport <= lbttcp_request_port_high))
675
4.85k
          || ((pinfo->destport >= lbttcp_request_port_low) && (pinfo->destport <= lbttcp_request_port_high))
676
4.85k
          || ((pinfo->srcport >= lbttcp_store_port_low) && (pinfo->srcport <= lbttcp_store_port_high))
677
3.91k
          || ((pinfo->destport >= lbttcp_store_port_low) && (pinfo->destport <= lbttcp_store_port_high))))
678
3.35k
    {
679
3.35k
        return false;
680
3.35k
    }
681
682
1.53k
    if (!lbmc_test_lbmc_header(tvb, 0))
683
911
        return false;
684
685
    /* One of ours. Probably. */
686
622
    dissect_lbttcp_real(tvb, pinfo, tree, data);
687
622
    return true;
688
1.53k
}
689
690
/* Register all the bits needed with the filtering engine */
691
void proto_register_lbttcp(void)
692
16
{
693
16
    static hf_register_info hf[] =
694
16
    {
695
16
        { &hf_lbttcp_tag,
696
16
            { "Tag", "lbttcp.tag", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
697
16
        { &hf_lbttcp_channel,
698
16
            { "Channel", "lbttcp.channel", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
699
16
        { &hf_lbttcp_channel_id,
700
16
            { "Channel ID", "lbttcp.channel.channel", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
701
16
        { &hf_lbttcp_channel_client,
702
16
            { "Channel Client", "lbttcp.channel.client", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
703
16
    };
704
16
    static int * ett[] =
705
16
    {
706
16
        &ett_lbttcp,
707
16
        &ett_lbttcp_channel
708
16
    };
709
16
    module_t * lbttcp_module;
710
16
    uat_t * tag_uat;
711
712
16
    proto_lbttcp = proto_register_protocol("LBT TCP Protocol", "LBT-TCP", "lbttcp");
713
714
16
    proto_register_field_array(proto_lbttcp, hf, array_length(hf));
715
16
    proto_register_subtree_array(ett, array_length(ett));
716
717
16
    lbttcp_dissector_handle = register_dissector("lbttcp", dissect_lbttcp, proto_lbttcp);
718
719
16
    lbttcp_module = prefs_register_protocol_subtree("29West", proto_lbttcp, proto_reg_handoff_lbttcp);
720
16
    prefs_register_uint_preference(lbttcp_module,
721
16
        "source_port_low",
722
16
        "Source port range low (default " MAKESTRING(LBTTCP_DEFAULT_SOURCE_PORT_LOW)")",
723
16
        "Set the low end of the LBT-TCP source TCP port range (context transport_tcp_port_low)",
724
16
        10,
725
16
        &global_lbttcp_source_port_low);
726
727
16
    prefs_register_uint_preference(lbttcp_module,
728
16
        "source_port_high",
729
16
        "Source port range high (default " MAKESTRING(LBTTCP_DEFAULT_SOURCE_PORT_HIGH)")",
730
16
        "Set the high end of the LBT-TCP source TCP port range (context transport_tcp_port_high)",
731
16
        10,
732
16
        &global_lbttcp_source_port_high);
733
734
16
    prefs_register_uint_preference(lbttcp_module,
735
16
        "request_port_low",
736
16
        "Request port range low (default " MAKESTRING(LBTTCP_DEFAULT_REQUEST_PORT_LOW)")",
737
16
        "Set the low end of the LBT-TCP request TCP port range (context request_tcp_port_low)",
738
16
        10,
739
16
        &global_lbttcp_request_port_low);
740
741
16
    prefs_register_uint_preference(lbttcp_module,
742
16
        "request_port_high",
743
16
        "Request port range high (default " MAKESTRING(LBTTCP_DEFAULT_REQUEST_PORT_HIGH)")",
744
16
        "Set the high end of the LBT-TCP request TCP port range (context request_tcp_port_high)",
745
16
        10,
746
16
        &global_lbttcp_request_port_high);
747
748
16
    prefs_register_uint_preference(lbttcp_module,
749
16
        "store_port_low",
750
16
        "UME Store port range low (default " MAKESTRING(LBTTCP_DEFAULT_STORE_PORT_LOW)")",
751
16
        "Set the low end of the LBT-TCP UME Store TCP port range",
752
16
        10,
753
16
        &global_lbttcp_store_port_low);
754
755
16
    prefs_register_uint_preference(lbttcp_module,
756
16
        "store_port_high",
757
16
        "UME Store port range high (default " MAKESTRING(LBTTCP_DEFAULT_STORE_PORT_HIGH)")",
758
16
        "Set the high end of the LBT-TCP UME Store TCP port range",
759
16
        10,
760
16
        &global_lbttcp_store_port_high);
761
762
16
    prefs_register_bool_preference(lbttcp_module,
763
16
        "use_lbttcp_domain",
764
16
        "Use LBT-TCP tag table",
765
16
        "Use table of LBT-TCP tags to decode the packet instead of above values",
766
16
        &global_lbttcp_use_tag);
767
16
    tag_uat = uat_new("LBT-TCP tag definitions",
768
16
        sizeof(lbttcp_tag_entry_t),
769
16
        "lbttcp_domains",
770
16
        true,
771
16
        (void * *)&lbttcp_tag_entry,
772
16
        &lbttcp_tag_count,
773
16
        UAT_AFFECTS_DISSECTION,
774
16
        NULL,
775
16
        lbttcp_tag_copy_cb,
776
16
        lbttcp_tag_update_cb,
777
16
        lbttcp_tag_free_cb,
778
16
        NULL,
779
16
        NULL,
780
16
        lbttcp_tag_array);
781
16
    prefs_register_uat_preference(lbttcp_module,
782
16
        "tnw_lbttcp_tags",
783
16
        "LBT-TCP Tags",
784
16
        "A table to define LBT-TCP tags",
785
16
        tag_uat);
786
16
}
787
788
/* The registration hand-off routine */
789
void proto_reg_handoff_lbttcp(void)
790
16
{
791
16
    static bool already_registered = false;
792
793
16
    if (!already_registered)
794
16
    {
795
16
        dissector_add_for_decode_as_with_preference("tcp.port", lbttcp_dissector_handle);
796
16
        heur_dissector_add("tcp", test_lbttcp_packet, "LBT over TCP", "lbttcp_tcp", proto_lbttcp, HEURISTIC_ENABLE);
797
16
    }
798
799
    /* Make sure the source port low is <= the source port high. If not, don't change them. */
800
16
    if (global_lbttcp_source_port_low <= global_lbttcp_source_port_high)
801
16
    {
802
16
        lbttcp_source_port_low = global_lbttcp_source_port_low;
803
16
        lbttcp_source_port_high = global_lbttcp_source_port_high;
804
16
    }
805
806
    /* Make sure the request port low is <= the request port high. If not, don't change them. */
807
16
    if (global_lbttcp_request_port_low <= global_lbttcp_request_port_high)
808
16
    {
809
16
        lbttcp_request_port_low = global_lbttcp_request_port_low;
810
16
        lbttcp_request_port_high = global_lbttcp_request_port_high;
811
16
    }
812
813
    /* Make sure the store port low is <= the store port high. If not, don't change them. */
814
16
    if (global_lbttcp_store_port_low <= global_lbttcp_store_port_high)
815
16
    {
816
16
        lbttcp_store_port_low = global_lbttcp_store_port_low;
817
16
        lbttcp_store_port_high = global_lbttcp_store_port_high;
818
16
    }
819
820
16
    lbttcp_use_tag = global_lbttcp_use_tag;
821
822
    already_registered = true;
823
16
}
824
825
/*
826
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
827
 *
828
 * Local variables:
829
 * c-basic-offset: 4
830
 * tab-width: 8
831
 * indent-tabs-mode: nil
832
 * End:
833
 *
834
 * vi: set shiftwidth=4 tabstop=8 expandtab:
835
 * :indentSize=4:tabSize=8:noTabs=true:
836
 */