Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-lbtru.c
Line
Count
Source
1
/* packet-lbtru.c
2
 * Routines for LBT-RU 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/prefs.h>
16
#include <epan/expert.h>
17
#include <epan/uat.h>
18
#include <epan/conversation.h>
19
#include <epan/to_str.h>
20
#include <epan/tap.h>
21
#include "packet-lbm.h"
22
#include "packet-lbtru.h"
23
24
void proto_register_lbtru(void);
25
void proto_reg_handoff_lbtru(void);
26
27
/* Protocol handle */
28
static int proto_lbtru;
29
30
/* Dissector handle */
31
static dissector_handle_t lbtru_dissector_handle;
32
33
/* Tap handle */
34
static int lbtru_tap_handle = -1;
35
36
/*----------------------------------------------------------------------------*/
37
/* LBT-RU transport management.                                               */
38
/*----------------------------------------------------------------------------*/
39
40
static const address lbtru_null_address = ADDRESS_INIT_NONE;
41
42
static lbtru_transport_t * lbtru_transport_find(const address * source_address, uint16_t source_port, uint32_t session_id, uint32_t frame)
43
0
{
44
0
    lbtru_transport_t * entry = NULL;
45
0
    wmem_tree_t * session_tree = NULL;
46
0
    conversation_t * conv = NULL;
47
48
0
    conv = find_conversation(frame, source_address, &lbtru_null_address, CONVERSATION_UDP, source_port, 0, 0);
49
0
    if (conv != NULL)
50
0
    {
51
0
        if (frame != 0)
52
0
        {
53
0
            if (conv->setup_frame == 0)
54
0
            {
55
0
                conv->setup_frame = frame;
56
0
            }
57
0
            if (frame > conv->last_frame)
58
0
            {
59
0
                conv->last_frame = frame;
60
0
            }
61
0
        }
62
0
        session_tree = (wmem_tree_t *) conversation_get_proto_data(conv, proto_lbtru);
63
0
        if (session_tree != NULL)
64
0
        {
65
0
            entry = (lbtru_transport_t *) wmem_tree_lookup32(session_tree, session_id);
66
0
        }
67
0
    }
68
0
    return (entry);
69
0
}
70
71
lbtru_transport_t * lbtru_transport_add(const address * source_address, uint16_t source_port, uint32_t session_id, uint32_t frame)
72
0
{
73
0
    lbtru_transport_t * entry = NULL;
74
0
    wmem_tree_t * session_tree = NULL;
75
0
    conversation_t * conv = NULL;
76
77
0
    conv = find_conversation(frame, source_address, &lbtru_null_address, CONVERSATION_UDP, source_port, 0, 0);
78
0
    if (conv == NULL)
79
0
    {
80
0
        conv = conversation_new(frame, source_address, &lbtru_null_address, CONVERSATION_UDP, source_port, 0, 0);
81
0
    }
82
0
    if (frame != 0)
83
0
    {
84
0
        if (conv->setup_frame == 0)
85
0
        {
86
0
            conv->setup_frame = frame;
87
0
        }
88
0
        if (frame > conv->last_frame)
89
0
        {
90
0
            conv->last_frame = frame;
91
0
        }
92
0
    }
93
0
    session_tree = (wmem_tree_t *) conversation_get_proto_data(conv, proto_lbtru);
94
0
    if (session_tree == NULL)
95
0
    {
96
0
        session_tree = wmem_tree_new(wmem_file_scope());
97
0
        conversation_add_proto_data(conv, proto_lbtru, (void *)session_tree);
98
0
    }
99
0
    entry = (lbtru_transport_t *) wmem_tree_lookup32(session_tree, session_id);
100
0
    if (entry != NULL)
101
0
    {
102
0
        return (entry);
103
0
    }
104
0
    entry = wmem_new(wmem_file_scope(), lbtru_transport_t);
105
0
    copy_address_wmem(wmem_file_scope(), &(entry->source_address), source_address);
106
0
    entry->source_port = source_port;
107
0
    entry->session_id = session_id;
108
0
    entry->channel = lbm_channel_assign(LBM_CHANNEL_TRANSPORT_LBTRU);
109
0
    entry->next_client_id = 1;
110
0
    entry->client_list = wmem_list_new(wmem_file_scope());
111
0
    wmem_tree_insert32(session_tree, session_id, (void *) entry);
112
0
    return (entry);
113
0
}
114
115
static lbtru_client_transport_t * lbtru_client_transport_find(lbtru_transport_t * transport, const address * receiver_address, uint16_t receiver_port, uint32_t frame)
116
0
{
117
0
    lbtru_client_transport_t * entry = NULL;
118
0
    conversation_t * client_conv = NULL;
119
120
0
    if (transport == NULL)
121
0
    {
122
0
        return (NULL);
123
0
    }
124
0
    client_conv = find_conversation(frame, &(transport->source_address), receiver_address, CONVERSATION_UDP, transport->source_port, receiver_port, 0);
125
0
    if (client_conv != NULL)
126
0
    {
127
0
        wmem_tree_t * session_tree = NULL;
128
129
0
        session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbtru);
130
0
        if (session_tree != NULL)
131
0
        {
132
0
            entry = (lbtru_client_transport_t *) wmem_tree_lookup32(session_tree, transport->session_id);
133
0
        }
134
0
    }
135
0
    return (entry);
136
0
}
137
138
static lbtru_client_transport_t * lbtru_client_transport_add(lbtru_transport_t * transport, const address * receiver_address, uint16_t receiver_port, uint32_t frame)
139
0
{
140
0
    lbtru_client_transport_t * entry = NULL;
141
0
    conversation_t * client_conv = NULL;
142
0
    wmem_tree_t * session_tree = NULL;
143
144
0
    if (transport == NULL)
145
0
    {
146
0
        return (NULL);
147
0
    }
148
0
    entry = lbtru_client_transport_find(transport, receiver_address, receiver_port, frame);
149
0
    if (entry != NULL)
150
0
    {
151
0
        return (entry);
152
0
    }
153
0
    entry = wmem_new0(wmem_file_scope(), lbtru_client_transport_t);
154
0
    copy_address_wmem(wmem_file_scope(), &(entry->receiver_address), receiver_address);
155
0
    entry->receiver_port = receiver_port;
156
0
    entry->transport = transport;
157
0
    entry->id = transport->next_client_id++;
158
0
    entry->frame = wmem_tree_new(wmem_file_scope());
159
0
    entry->last_frame = NULL;
160
0
    entry->last_data_frame = NULL;
161
0
    entry->last_sm_frame = NULL;
162
0
    entry->last_nak_frame = NULL;
163
0
    entry->last_ncf_frame = NULL;
164
0
    entry->last_ack_frame = NULL;
165
0
    entry->last_creq_frame = NULL;
166
0
    entry->last_rst_frame = NULL;
167
0
    entry->data_sqn = wmem_tree_new(wmem_file_scope());
168
0
    entry->sm_sqn = wmem_tree_new(wmem_file_scope());
169
0
    entry->data_high_sqn = 0;
170
0
    entry->sm_high_sqn = 0;
171
172
    /* See if a conversation for this address/port pair exists. */
173
0
    client_conv = find_conversation(frame, &(transport->source_address), receiver_address, CONVERSATION_UDP, transport->source_port, receiver_port, 0);
174
0
    if (client_conv == NULL)
175
0
    {
176
0
        client_conv = conversation_new(frame, &(transport->source_address), receiver_address, CONVERSATION_UDP, transport->source_port, receiver_port, 0);
177
0
        session_tree = wmem_tree_new(wmem_file_scope());
178
0
        conversation_add_proto_data(client_conv, proto_lbtru, (void *) session_tree);
179
0
    }
180
0
    else
181
0
    {
182
0
        session_tree = (wmem_tree_t *) conversation_get_proto_data(client_conv, proto_lbtru);
183
0
        if (session_tree == NULL)
184
0
        {
185
0
            session_tree = wmem_tree_new(wmem_file_scope());
186
0
            conversation_add_proto_data(client_conv, proto_lbtru, (void *) session_tree);
187
0
        }
188
0
    }
189
0
    wmem_tree_insert32(session_tree, transport->session_id, (void *) entry);
190
191
    /* Add this client to the transport. */
192
0
    wmem_list_append(transport->client_list, (void *) entry);
193
0
    return (entry);
194
0
}
195
196
static lbm_transport_sqn_t * lbtru_client_transport_sqn_find(lbtru_client_transport_t * client, uint8_t type, uint32_t sqn)
197
0
{
198
0
    lbm_transport_sqn_t * sqn_entry = NULL;
199
200
0
    switch (type)
201
0
    {
202
0
        case LBTRU_PACKET_TYPE_DATA:
203
0
            sqn_entry = (lbm_transport_sqn_t *) wmem_tree_lookup32(client->data_sqn, sqn);
204
0
            break;
205
0
        case LBTRU_PACKET_TYPE_SM:
206
0
            sqn_entry = (lbm_transport_sqn_t *) wmem_tree_lookup32(client->sm_sqn, sqn);
207
0
            break;
208
0
        case LBTRU_PACKET_TYPE_NAK:
209
0
        case LBTRU_PACKET_TYPE_NCF:
210
0
        case LBTRU_PACKET_TYPE_ACK:
211
0
        case LBTRU_PACKET_TYPE_CREQ:
212
0
        case LBTRU_PACKET_TYPE_RST:
213
0
        default:
214
0
            sqn_entry = NULL;
215
0
            break;
216
0
    }
217
0
    return (sqn_entry);
218
0
}
219
220
static lbm_transport_sqn_t * lbtru_client_transport_sqn_add(lbtru_client_transport_t * client, lbm_transport_frame_t * frame)
221
0
{
222
0
    wmem_tree_t * sqn_list = NULL;
223
0
    lbm_transport_sqn_t * sqn_entry = NULL;
224
225
0
    switch (frame->type)
226
0
    {
227
0
        case LBTRU_PACKET_TYPE_DATA:
228
0
            sqn_list = client->data_sqn;
229
0
            break;
230
0
        case LBTRU_PACKET_TYPE_SM:
231
0
            sqn_list = client->sm_sqn;
232
0
            break;
233
0
        case LBTRU_PACKET_TYPE_NAK:
234
0
        case LBTRU_PACKET_TYPE_NCF:
235
0
        case LBTRU_PACKET_TYPE_ACK:
236
0
        case LBTRU_PACKET_TYPE_CREQ:
237
0
        case LBTRU_PACKET_TYPE_RST:
238
0
        default:
239
0
            return (NULL);
240
0
    }
241
242
    /* Add the sqn. */
243
0
    sqn_entry = lbm_transport_sqn_add(sqn_list, frame);
244
0
    return (sqn_entry);
245
0
}
246
247
static lbm_transport_frame_t * lbtru_client_transport_frame_find(lbtru_client_transport_t * client, uint32_t frame)
248
0
{
249
0
    return ((lbm_transport_frame_t *) wmem_tree_lookup32(client->frame, frame));
250
0
}
251
252
static lbm_transport_frame_t * lbtru_client_transport_frame_add(lbtru_client_transport_t * client, uint8_t type, uint32_t frame, uint32_t sqn, bool retransmission)
253
0
{
254
0
    lbm_transport_sqn_t * dup_sqn_entry = NULL;
255
0
    lbm_transport_frame_t * frame_entry = NULL;
256
257
    /* Locate the frame. */
258
0
    frame_entry = lbtru_client_transport_frame_find(client, frame);
259
0
    if (frame_entry != NULL)
260
0
    {
261
0
        return (frame_entry);
262
0
    }
263
0
    frame_entry = lbm_transport_frame_add(client->frame, type, frame, sqn, retransmission);
264
0
    if (client->last_frame != NULL)
265
0
    {
266
0
        frame_entry->previous_frame = client->last_frame->frame;
267
0
        client->last_frame->next_frame = frame;
268
0
    }
269
0
    client->last_frame = frame_entry;
270
0
    switch (type)
271
0
    {
272
0
        case LBTRU_PACKET_TYPE_DATA:
273
0
            if (client->last_data_frame != NULL)
274
0
            {
275
0
                frame_entry->previous_type_frame = client->last_data_frame->frame;
276
0
                client->last_data_frame->next_type_frame = frame;
277
                /* Ideally, this frame's sqn is 1 more than the highest data sqn seen */
278
0
                if (frame_entry->sqn <= client->data_high_sqn)
279
0
                {
280
0
                    dup_sqn_entry = lbtru_client_transport_sqn_find(client, type, frame_entry->sqn);
281
0
                    if (!frame_entry->retransmission)
282
0
                    {
283
                        /* Out of order */
284
0
                        if (dup_sqn_entry != NULL)
285
0
                        {
286
0
                            frame_entry->duplicate = true;
287
0
                        }
288
0
                        if (frame_entry->sqn != client->data_high_sqn)
289
0
                        {
290
0
                            frame_entry->ooo_gap = client->data_high_sqn - frame_entry->sqn;
291
0
                        }
292
0
                    }
293
0
                }
294
0
                else
295
0
                {
296
0
                    if (!frame_entry->retransmission)
297
0
                    {
298
0
                        if (frame_entry->sqn != (client->data_high_sqn + 1))
299
0
                        {
300
                            /* Gap */
301
0
                            frame_entry->sqn_gap = frame_entry->sqn - (client->last_data_frame->sqn + 1);
302
0
                        }
303
0
                    }
304
0
                }
305
0
            }
306
0
            if ((frame_entry->sqn > client->data_high_sqn) && !frame_entry->retransmission)
307
0
            {
308
0
                client->data_high_sqn = frame_entry->sqn;
309
0
            }
310
0
            client->last_data_frame = frame_entry;
311
0
            break;
312
0
        case LBTRU_PACKET_TYPE_SM:
313
0
            if (client->last_sm_frame != NULL)
314
0
            {
315
0
                frame_entry->previous_type_frame = client->last_sm_frame->frame;
316
0
                client->last_sm_frame->next_type_frame = frame;
317
                /* Ideally, this frame's sqn is 1 more than the highest SM sqn seen */
318
0
                if (frame_entry->sqn <= client->sm_high_sqn)
319
0
                {
320
                    /* Out of order */
321
0
                    dup_sqn_entry = lbtru_client_transport_sqn_find(client, type, frame_entry->sqn);
322
0
                    if (dup_sqn_entry != NULL)
323
0
                    {
324
0
                        frame_entry->duplicate = true;
325
0
                    }
326
0
                    if (frame_entry->sqn != client->sm_high_sqn)
327
0
                    {
328
0
                        frame_entry->ooo_gap = client->sm_high_sqn - frame_entry->sqn;
329
0
                    }
330
0
                }
331
0
                else
332
0
                {
333
0
                    if (frame_entry->sqn != (client->sm_high_sqn + 1))
334
0
                    {
335
                        /* Gap */
336
0
                        frame_entry->sqn_gap = frame_entry->sqn - (client->sm_high_sqn + 1);
337
0
                    }
338
0
                }
339
0
            }
340
0
            if (frame_entry->sqn > client->sm_high_sqn)
341
0
            {
342
0
                client->sm_high_sqn = frame_entry->sqn;
343
0
            }
344
0
            client->last_sm_frame = frame_entry;
345
0
            break;
346
0
        case LBTRU_PACKET_TYPE_NAK:
347
0
            if (client->last_nak_frame != NULL)
348
0
            {
349
0
                frame_entry->previous_type_frame = client->last_nak_frame->frame;
350
0
                client->last_nak_frame->next_type_frame = frame;
351
0
            }
352
0
            client->last_nak_frame = frame_entry;
353
0
            break;
354
0
        case LBTRU_PACKET_TYPE_NCF:
355
0
            if (client->last_ncf_frame != NULL)
356
0
            {
357
0
                frame_entry->previous_type_frame = client->last_ncf_frame->frame;
358
0
                client->last_ncf_frame->next_type_frame = frame;
359
0
            }
360
0
            client->last_ncf_frame = frame_entry;
361
0
            break;
362
0
        case LBTRU_PACKET_TYPE_ACK:
363
0
            if (client->last_ack_frame != NULL)
364
0
            {
365
0
                frame_entry->previous_type_frame = client->last_ack_frame->frame;
366
0
                client->last_ack_frame->next_type_frame = frame;
367
0
            }
368
0
            client->last_ack_frame = frame_entry;
369
0
            break;
370
0
        case LBTRU_PACKET_TYPE_CREQ:
371
0
            if (client->last_creq_frame != NULL)
372
0
            {
373
0
                frame_entry->previous_type_frame = client->last_creq_frame->frame;
374
0
                client->last_creq_frame->next_type_frame = frame;
375
0
            }
376
0
            client->last_creq_frame = frame_entry;
377
0
            break;
378
0
        case LBTRU_PACKET_TYPE_RST:
379
0
            if (client->last_rst_frame != NULL)
380
0
            {
381
0
                frame_entry->previous_type_frame = client->last_rst_frame->frame;
382
0
                client->last_rst_frame->next_type_frame = frame;
383
0
            }
384
0
            client->last_rst_frame = frame_entry;
385
0
            break;
386
0
    }
387
388
    /* Add the sqn. */
389
0
    (void)lbtru_client_transport_sqn_add(client, frame_entry);
390
0
    return (frame_entry);
391
0
}
392
393
static char * lbtru_transport_source_string_format(wmem_allocator_t *scope, const address * source_address, uint16_t source_port, uint32_t session_id)
394
0
{
395
0
    char * bufptr = NULL;
396
397
0
    if (session_id == 0)
398
0
    {
399
0
        bufptr = wmem_strdup_printf(scope, "LBT-RU:%s:%" PRIu16, address_to_str(scope, source_address), source_port);
400
0
    }
401
0
    else
402
0
    {
403
0
        bufptr = wmem_strdup_printf(scope, "LBT-RU:%s:%" PRIu16 ":%08x", address_to_str(scope, source_address), source_port, session_id);
404
0
    }
405
0
    return (bufptr);
406
0
}
407
408
char * lbtru_transport_source_string(const address * source_address, uint16_t source_port, uint32_t session_id)
409
0
{
410
    /* Returns a file-scoped string. */
411
0
    return lbtru_transport_source_string_format(wmem_file_scope(), source_address, source_port, session_id);
412
0
}
413
414
static char * lbtru_transport_source_string_transport(wmem_allocator_t *scope, lbtru_transport_t * transport)
415
0
{
416
0
    return lbtru_transport_source_string_format(scope, &(transport->source_address), transport->source_port, transport->session_id);
417
0
}
418
419
/*----------------------------------------------------------------------------*/
420
/* Packet layouts.                                                            */
421
/*----------------------------------------------------------------------------*/
422
423
/* LBT-RU main header */
424
typedef struct
425
{
426
    lbm_uint8_t ver_type;
427
    lbm_uint8_t next_hdr;
428
    lbm_uint16_t flags_or_res;
429
} lbtru_hdr_t;
430
0
#define O_LBTRU_HDR_T_VER_TYPE OFFSETOF(lbtru_hdr_t, ver_type)
431
0
#define L_LBTRU_HDR_T_VER_TYPE SIZEOF(lbtru_hdr_t, ver_type)
432
0
#define O_LBTRU_HDR_T_NEXT_HDR OFFSETOF(lbtru_hdr_t, next_hdr)
433
0
#define L_LBTRU_HDR_T_NEXT_HDR SIZEOF(lbtru_hdr_t, next_hdr)
434
0
#define O_LBTRU_HDR_T_FLAGS_OR_RES OFFSETOF(lbtru_hdr_t, flags_or_res)
435
30
#define L_LBTRU_HDR_T_FLAGS_OR_RES SIZEOF(lbtru_hdr_t, flags_or_res)
436
0
#define L_LBTRU_HDR_T (int) sizeof(lbtru_hdr_t)
437
438
#define LBTRU_VERSION 0x00
439
0
#define LBTRU_HDR_VER(x) (x >> 4)
440
0
#define LBTRU_HDR_TYPE(x) (x & 0x0F)
441
15
#define LBTRU_HDR_VER_VER_MASK 0xF0
442
15
#define LBTRU_HDR_VER_TYPE_MASK 0x0F
443
444
15
#define LBTRU_RETRANSMISSION_FLAG 0x4000
445
446
/* LBT-RU data header */
447
typedef struct
448
{
449
    lbm_uint32_t sqn;
450
    lbm_uint32_t trail_sqn;
451
} lbtru_data_hdr_t;
452
0
#define O_LBTRU_DATA_HDR_T_SQN OFFSETOF(lbtru_data_hdr_t, sqn)
453
0
#define L_LBTRU_DATA_HDR_T_SQN SIZEOF(lbtru_data_hdr_t, sqn)
454
0
#define O_LBTRU_DATA_HDR_T_TRAIL_SQN OFFSETOF(lbtru_data_hdr_t, trail_sqn)
455
0
#define L_LBTRU_DATA_HDR_T_TRAIL_SQN SIZEOF(lbtru_data_hdr_t, trail_sqn)
456
0
#define L_LBTRU_DATA_HDR_T (int) (sizeof(lbtru_data_hdr_t))
457
458
/* LBT-RU Session Message header */
459
typedef struct
460
{
461
    lbm_uint32_t sm_sqn;
462
    lbm_uint32_t lead_sqn;
463
    lbm_uint32_t trail_sqn;
464
} lbtru_sm_hdr_t;
465
0
#define O_LBTRU_SM_HDR_T_SM_SQN OFFSETOF(lbtru_sm_hdr_t, sm_sqn)
466
0
#define L_LBTRU_SM_HDR_T_SM_SQN SIZEOF(lbtru_sm_hdr_t, sm_sqn)
467
0
#define O_LBTRU_SM_HDR_T_LEAD_SQN OFFSETOF(lbtru_sm_hdr_t, lead_sqn)
468
0
#define L_LBTRU_SM_HDR_T_LEAD_SQN SIZEOF(lbtru_sm_hdr_t, lead_sqn)
469
0
#define O_LBTRU_SM_HDR_T_TRAIL_SQN OFFSETOF(lbtru_sm_hdr_t, trail_sqn)
470
0
#define L_LBTRU_SM_HDR_T_TRAIL_SQN SIZEOF(lbtru_sm_hdr_t, trail_sqn)
471
0
#define L_LBTRU_SM_HDR_T (int) (sizeof(lbtru_sm_hdr_t))
472
473
15
#define LBTRU_SM_SYN_FLAG 0x8000
474
475
/* LBT-RU NAK header */
476
typedef struct
477
{
478
    lbm_uint16_t num_naks;
479
    lbm_uint16_t format;
480
} lbtru_nak_hdr_t;
481
0
#define O_LBTRU_NAK_HDR_T_NUM_NAKS OFFSETOF(lbtru_nak_hdr_t, num_naks)
482
0
#define L_LBTRU_NAK_HDR_T_NUM_NAKS SIZEOF(lbtru_nak_hdr_t, num_naks)
483
0
#define O_LBTRU_NAK_HDR_T_FORMAT OFFSETOF(lbtru_nak_hdr_t, format)
484
0
#define L_LBTRU_NAK_HDR_T_FORMAT SIZEOF(lbtru_nak_hdr_t, format)
485
0
#define L_LBTRU_NAK_HDR_T (int) (sizeof(lbtru_nak_hdr_t))
486
487
#define LBTRU_NAK_SELECTIVE_FORMAT 0x0
488
15
#define LBTRU_NAK_HDR_FORMAT_MASK 0x000F
489
#define LBTRU_NAK_HDR_FORMAT(x) (x & 0xF)
490
491
/* LBT-RU NAK Confirmation header */
492
typedef struct
493
{
494
    lbm_uint32_t trail_sqn;
495
    lbm_uint16_t num_ncfs;
496
    lbm_uint8_t reserved;
497
    lbm_uint8_t reason_format;
498
} lbtru_ncf_hdr_t;
499
0
#define O_LBTRU_NCF_HDR_T_TRAIL_SQN OFFSETOF(lbtru_ncf_hdr_t, trail_sqn)
500
0
#define L_LBTRU_NCF_HDR_T_TRAIL_SQN SIZEOF(lbtru_ncf_hdr_t, trail_sqn)
501
0
#define O_LBTRU_NCF_HDR_T_NUM_NCFS OFFSETOF(lbtru_ncf_hdr_t, num_ncfs)
502
0
#define L_LBTRU_NCF_HDR_T_NUM_NCFS SIZEOF(lbtru_ncf_hdr_t, num_ncfs)
503
0
#define O_LBTRU_NCF_HDR_T_RESERVED OFFSETOF(lbtru_ncf_hdr_t, reserved)
504
0
#define L_LBTRU_NCF_HDR_T_RESERVED SIZEOF(lbtru_ncf_hdr_t, reserved)
505
0
#define O_LBTRU_NCF_HDR_T_REASON_FORMAT OFFSETOF(lbtru_ncf_hdr_t, reason_format)
506
0
#define L_LBTRU_NCF_HDR_T_REASON_FORMAT SIZEOF(lbtru_ncf_hdr_t, reason_format)
507
0
#define L_LBTRU_NCF_HDR_T (int) (sizeof(lbtru_ncf_hdr_t))
508
509
#define LBTRU_NCF_SELECTIVE_FORMAT 0x0
510
0
#define LBTRU_NCF_HDR_REASON(x) ((x & 0xF0) >> 4)
511
#define LBTRU_NCF_HDR_FORMAT(x) (x & 0xF)
512
15
#define LBTRU_NCF_HDR_REASON_MASK 0xF0
513
15
#define LBTRU_NCF_HDR_FORMAT_MASK 0x0F
514
515
/* LBT-RU ACK header */
516
typedef struct
517
{
518
    lbm_uint32_t ack_sqn;
519
} lbtru_ack_hdr_t;
520
0
#define O_LBTRU_ACK_HDR_T_ACK_SQN OFFSETOF(lbtru_ack_hdr_t, ack_sqn)
521
0
#define L_LBTRU_ACK_HDR_T_ACK_SQN SIZEOF(lbtru_ack_hdr_t, ack_sqn)
522
0
#define L_LBTRU_ACK_HDR_T (int) (sizeof(lbtru_ack_hdr_t))
523
524
/* LBT-RU basic option header */
525
typedef struct
526
{
527
    lbm_uint8_t next_hdr;
528
    lbm_uint8_t hdr_len;
529
    lbm_uint16_t res;
530
} lbtru_basic_opt_t;
531
0
#define O_LBTRU_BASIC_OPT_T_NEXT_HDR OFFSETOF(lbtru_basic_opt_t, next_hdr)
532
0
#define L_LBTRU_BASIC_OPT_T_NEXT_HDR SIZEOF(lbtru_basic_opt_t, next_hdr)
533
0
#define O_LBTRU_BASIC_OPT_T_HDR_LEN OFFSETOF(lbtru_basic_opt_t, hdr_len)
534
0
#define L_LBTRU_BASIC_OPT_T_HDR_LEN SIZEOF(lbtru_basic_opt_t, hdr_len)
535
0
#define O_LBTRU_BASIC_OPT_T_RES OFFSETOF(lbtru_basic_opt_t, res)
536
30
#define L_LBTRU_BASIC_OPT_T_RES SIZEOF(lbtru_basic_opt_t, res)
537
0
#define L_LBTRU_BASIC_OPT_T (int) (sizeof(lbtru_basic_opt_t))
538
539
/* LBT-RU Session ID option header */
540
typedef struct
541
{
542
    lbm_uint32_t session_id;
543
} lbtru_sid_opt_t;
544
0
#define O_LBTRU_SID_OPT_T_SESSION_ID OFFSETOF(lbtru_sid_opt_t, session_id)
545
0
#define L_LBTRU_SID_OPT_T_SESSION_ID SIZEOF(lbtru_sid_opt_t, session_id)
546
0
#define L_LBTRU_SID_OPT_T (int) (sizeof(lbtru_sid_opt_t))
547
548
/* LBT-RU Client ID option header */
549
typedef struct
550
{
551
    lbm_uint32_t client_sid;
552
} lbtru_cid_opt_t;
553
0
#define O_LBTRU_CID_OPT_T_CLIENT_SID OFFSETOF(lbtru_cid_opt_t, client_sid)
554
0
#define L_LBTRU_CID_OPT_T_CLIENT_SID SIZEOF(lbtru_cid_opt_t, client_sid)
555
0
#define L_LBTRU_CID_OPT_T (int) (sizeof(lbtru_cid_opt_t))
556
557
30
#define LBTRU_OPT_IGNORE 0x8000
558
559
0
#define LBTRU_NHDR_DATA 0x00
560
0
#define LBTRU_NHDR_SID 0x01
561
0
#define LBTRU_NHDR_CID 0x02
562
563
/*----------------------------------------------------------------------------*/
564
/* Value translation tables.                                                  */
565
/*----------------------------------------------------------------------------*/
566
567
static const value_string lbtru_packet_type[] =
568
{
569
    { LBTRU_PACKET_TYPE_DATA, "DATA" },
570
    { LBTRU_PACKET_TYPE_SM, "SM" },
571
    { LBTRU_PACKET_TYPE_NAK, "NAK" },
572
    { LBTRU_PACKET_TYPE_NCF, "NCF" },
573
    { LBTRU_PACKET_TYPE_ACK, "ACK" },
574
    { LBTRU_PACKET_TYPE_CREQ, "CREQ" },
575
    { LBTRU_PACKET_TYPE_RST, "RST" },
576
    { 0x0, NULL }
577
};
578
579
static const value_string lbtru_nak_format[] =
580
{
581
    { LBTRU_NAK_SELECTIVE_FORMAT, "Selective" },
582
    { 0x0, NULL }
583
};
584
585
static const value_string lbtru_ncf_format[] =
586
{
587
    { LBTRU_NCF_SELECTIVE_FORMAT, "Selective" },
588
    { 0x0, NULL }
589
};
590
591
static const value_string lbtru_ncf_reason[] =
592
{
593
    { LBTRU_NCF_REASON_NO_RETRY, "Do not retry" },
594
    { LBTRU_NCF_REASON_IGNORED, "NAK Ignored" },
595
    { LBTRU_NCF_REASON_RX_DELAY, "Retransmit Delay" },
596
    { LBTRU_NCF_REASON_SHED, "NAK Shed" },
597
    { 0x0, NULL }
598
};
599
600
static const value_string lbtru_creq_request[] =
601
{
602
    { LBTRU_CREQ_REQUEST_SYN, "SYN" },
603
    { 0x0, NULL }
604
};
605
606
static const value_string lbtru_rst_reason[] =
607
{
608
    { LBTRU_RST_REASON_DEFAULT, "Default" },
609
    { 0x0, NULL }
610
};
611
612
static const value_string lbtru_next_header[] =
613
{
614
    { LBTRU_NHDR_DATA, "DATA" },
615
    { LBTRU_NHDR_SID, "SID" },
616
    { LBTRU_NHDR_CID, "CID" },
617
    { 0x0, NULL }
618
};
619
620
/*----------------------------------------------------------------------------*/
621
/* Preferences.                                                               */
622
/*----------------------------------------------------------------------------*/
623
624
/* Preferences default values. */
625
#define LBTRU_DEFAULT_SOURCE_PORT_LOW    14380
626
#define LBTRU_DEFAULT_SOURCE_PORT_HIGH   14389
627
#define LBTRU_DEFAULT_RECEIVER_PORT_LOW  14360
628
#define LBTRU_DEFAULT_RECEIVER_PORT_HIGH 14379
629
630
/* Global preferences variables (altered by the preferences dialog). */
631
static uint32_t global_lbtru_source_port_low = LBTRU_DEFAULT_SOURCE_PORT_LOW;
632
static uint32_t global_lbtru_source_port_high = LBTRU_DEFAULT_SOURCE_PORT_HIGH;
633
static uint32_t global_lbtru_receiver_port_low = LBTRU_DEFAULT_RECEIVER_PORT_LOW;
634
static uint32_t global_lbtru_receiver_port_high = LBTRU_DEFAULT_RECEIVER_PORT_HIGH;
635
static bool global_lbtru_expert_separate_naks;
636
static bool global_lbtru_expert_separate_ncfs;
637
static bool global_lbtru_use_tag;
638
static bool global_lbtru_sequence_analysis;
639
640
/* Local preferences variables (used by the dissector). */
641
static uint32_t lbtru_source_port_low = LBTRU_DEFAULT_SOURCE_PORT_LOW;
642
static uint32_t lbtru_source_port_high = LBTRU_DEFAULT_SOURCE_PORT_HIGH;
643
static uint32_t lbtru_receiver_port_low = LBTRU_DEFAULT_RECEIVER_PORT_LOW;
644
static uint32_t lbtru_receiver_port_high = LBTRU_DEFAULT_RECEIVER_PORT_HIGH;
645
static bool lbtru_expert_separate_naks;
646
static bool lbtru_expert_separate_ncfs;
647
static bool lbtru_use_tag;
648
static bool lbtru_sequence_analysis;
649
650
/*----------------------------------------------------------------------------*/
651
/* Tag management.                                                            */
652
/*----------------------------------------------------------------------------*/
653
typedef struct
654
{
655
    char * name;
656
    uint32_t source_port_low;
657
    uint32_t source_port_high;
658
    uint32_t receiver_port_low;
659
    uint32_t receiver_port_high;
660
} lbtru_tag_entry_t;
661
662
static lbtru_tag_entry_t * lbtru_tag_entry;
663
static unsigned lbtru_tag_count;
664
665
0
UAT_CSTRING_CB_DEF(lbtru_tag, name, lbtru_tag_entry_t)
666
0
UAT_DEC_CB_DEF(lbtru_tag, source_port_low, lbtru_tag_entry_t)
Unexecuted instantiation: packet-lbtru.c:lbtru_tag_source_port_low_set_cb
Unexecuted instantiation: packet-lbtru.c:lbtru_tag_source_port_low_tostr_cb
667
0
UAT_DEC_CB_DEF(lbtru_tag, source_port_high, lbtru_tag_entry_t)
Unexecuted instantiation: packet-lbtru.c:lbtru_tag_source_port_high_set_cb
Unexecuted instantiation: packet-lbtru.c:lbtru_tag_source_port_high_tostr_cb
668
0
UAT_DEC_CB_DEF(lbtru_tag, receiver_port_low, lbtru_tag_entry_t)
Unexecuted instantiation: packet-lbtru.c:lbtru_tag_receiver_port_low_set_cb
Unexecuted instantiation: packet-lbtru.c:lbtru_tag_receiver_port_low_tostr_cb
669
0
UAT_DEC_CB_DEF(lbtru_tag, receiver_port_high, lbtru_tag_entry_t)
Unexecuted instantiation: packet-lbtru.c:lbtru_tag_receiver_port_high_set_cb
Unexecuted instantiation: packet-lbtru.c:lbtru_tag_receiver_port_high_tostr_cb
670
static uat_field_t lbtru_tag_array[] =
671
{
672
    UAT_FLD_CSTRING(lbtru_tag, name, "Tag name", "Tag name"),
673
    UAT_FLD_DEC(lbtru_tag, source_port_low, "Source port low", "Source port low"),
674
    UAT_FLD_DEC(lbtru_tag, source_port_high, "Source port high", "Source port high"),
675
    UAT_FLD_DEC(lbtru_tag, receiver_port_low, "Receiver port low", "Receiver port low"),
676
    UAT_FLD_DEC(lbtru_tag, receiver_port_high, "Receiver port high", "Receiver port high"),
677
    UAT_END_FIELDS
678
};
679
680
/*----------------------------------------------------------------------------*/
681
/* UAT callback functions.                                                    */
682
/*----------------------------------------------------------------------------*/
683
static bool lbtru_tag_update_cb(void * record, char * * error_string)
684
0
{
685
0
    lbtru_tag_entry_t * tag = (lbtru_tag_entry_t *)record;
686
687
0
    if (tag->name == NULL)
688
0
    {
689
0
        *error_string = g_strdup("Tag name can't be empty");
690
0
        return false;
691
0
    }
692
0
    else
693
0
    {
694
0
        g_strstrip(tag->name);
695
0
        if (tag->name[0] == 0)
696
0
        {
697
0
            *error_string = g_strdup("Tag name can't be empty");
698
0
            return false;
699
0
        }
700
0
    }
701
0
    return true;
702
0
}
703
704
static void * lbtru_tag_copy_cb(void * destination, const void * source, size_t length _U_)
705
0
{
706
0
    const lbtru_tag_entry_t * src = (const lbtru_tag_entry_t *)source;
707
0
    lbtru_tag_entry_t * dest = (lbtru_tag_entry_t *)destination;
708
709
0
    dest->name = g_strdup(src->name);
710
0
    dest->source_port_low = src->source_port_low;
711
0
    dest->source_port_high = src->source_port_high;
712
0
    dest->receiver_port_low = src->receiver_port_low;
713
0
    dest->receiver_port_high = src->receiver_port_high;
714
0
    return (dest);
715
0
}
716
717
static void lbtru_tag_free_cb(void * record)
718
0
{
719
0
    lbtru_tag_entry_t * tag = (lbtru_tag_entry_t *)record;
720
721
0
    if (tag->name != NULL)
722
0
    {
723
0
        g_free(tag->name);
724
0
        tag->name = NULL;
725
0
    }
726
0
}
727
728
static char * lbtru_tag_find(packet_info * pinfo)
729
0
{
730
0
    unsigned idx;
731
0
    lbtru_tag_entry_t * tag = NULL;
732
733
0
    if (!lbtru_use_tag)
734
0
    {
735
0
        return (NULL);
736
0
    }
737
738
0
    for (idx = 0; idx < lbtru_tag_count; ++idx)
739
0
    {
740
0
        tag = &(lbtru_tag_entry[idx]);
741
0
        if (((pinfo->destport >= tag->source_port_low)
742
0
             && (pinfo->destport <= tag->source_port_high)
743
0
             && (pinfo->srcport >= tag->receiver_port_low)
744
0
             && (pinfo->srcport <= tag->receiver_port_high))
745
0
            || ((pinfo->destport >= tag->receiver_port_low)
746
0
                && (pinfo->destport <= tag->receiver_port_high)
747
0
                && (pinfo->srcport >= tag->source_port_low)
748
0
                && (pinfo->srcport <= tag->source_port_high)))
749
0
        {
750
            /* One of ours. */
751
0
            return tag->name;
752
0
        }
753
0
    }
754
0
    return (NULL);
755
0
}
756
757
/*----------------------------------------------------------------------------*/
758
/* Handles of all types.                                                      */
759
/*----------------------------------------------------------------------------*/
760
761
/* Dissector tree handles */
762
static int ett_lbtru;
763
static int ett_lbtru_channel;
764
static int ett_lbtru_hdr;
765
static int ett_lbtru_hdr_flags;
766
static int ett_lbtru_data;
767
static int ett_lbtru_sm;
768
static int ett_lbtru_nak;
769
static int ett_lbtru_nak_list;
770
static int ett_lbtru_ncf;
771
static int ett_lbtru_ncf_list;
772
static int ett_lbtru_ack;
773
static int ett_lbtru_opt;
774
static int ett_lbtru_opt_sid_flags;
775
static int ett_lbtru_opt_cid_flags;
776
static int ett_lbtru_transport;
777
static int ett_lbtru_transport_sqn;
778
779
/* Dissector field handles */
780
static int hf_lbtru_channel;
781
static int hf_lbtru_channel_id;
782
static int hf_lbtru_channel_client;
783
static int hf_lbtru_tag;
784
static int hf_lbtru_hdr;
785
static int hf_lbtru_hdr_ver;
786
static int hf_lbtru_hdr_type;
787
static int hf_lbtru_hdr_next_hdr;
788
static int hf_lbtru_hdr_res;
789
static int hf_lbtru_hdr_flags;
790
static int hf_lbtru_hdr_flags_syn;
791
static int hf_lbtru_hdr_flags_rx;
792
static int hf_lbtru_hdr_request;
793
static int hf_lbtru_hdr_reason;
794
static int hf_lbtru_data;
795
static int hf_lbtru_data_sqn;
796
static int hf_lbtru_data_trail_sqn;
797
static int hf_lbtru_sm;
798
static int hf_lbtru_sm_sqn;
799
static int hf_lbtru_sm_lead_sqn;
800
static int hf_lbtru_sm_trail_sqn;
801
static int hf_lbtru_nak;
802
static int hf_lbtru_nak_num;
803
static int hf_lbtru_nak_format;
804
static int hf_lbtru_nak_list;
805
static int hf_lbtru_nak_list_nak;
806
static int hf_lbtru_ncf;
807
static int hf_lbtru_ncf_trail_sqn;
808
static int hf_lbtru_ncf_num;
809
static int hf_lbtru_ncf_reserved;
810
static int hf_lbtru_ncf_reason;
811
static int hf_lbtru_ncf_format;
812
static int hf_lbtru_ncf_list;
813
static int hf_lbtru_ncf_list_ncf;
814
static int hf_lbtru_ack;
815
static int hf_lbtru_ack_sqn;
816
static int hf_lbtru_opt_sid;
817
static int hf_lbtru_opt_sid_next_hdr;
818
static int hf_lbtru_opt_sid_hdr_len;
819
static int hf_lbtru_opt_sid_flags;
820
static int hf_lbtru_opt_sid_flags_ignore;
821
static int hf_lbtru_opt_sid_session_id;
822
static int hf_lbtru_opt_cid;
823
static int hf_lbtru_opt_cid_next_hdr;
824
static int hf_lbtru_opt_cid_hdr_len;
825
static int hf_lbtru_opt_cid_flags;
826
static int hf_lbtru_opt_cid_flags_ignore;
827
static int hf_lbtru_opt_cid_client_id;
828
static int hf_lbtru_opt_unknown;
829
static int hf_lbtru_opt_unknown_next_hdr;
830
static int hf_lbtru_opt_unknown_hdr_len;
831
static int hf_lbtru_analysis;
832
static int hf_lbtru_analysis_prev_frame;
833
static int hf_lbtru_analysis_prev_data_frame;
834
static int hf_lbtru_analysis_prev_sm_frame;
835
static int hf_lbtru_analysis_prev_nak_frame;
836
static int hf_lbtru_analysis_prev_ncf_frame;
837
static int hf_lbtru_analysis_prev_ack_frame;
838
static int hf_lbtru_analysis_prev_creq_frame;
839
static int hf_lbtru_analysis_prev_rst_frame;
840
static int hf_lbtru_analysis_next_frame;
841
static int hf_lbtru_analysis_next_data_frame;
842
static int hf_lbtru_analysis_next_sm_frame;
843
static int hf_lbtru_analysis_next_nak_frame;
844
static int hf_lbtru_analysis_next_ncf_frame;
845
static int hf_lbtru_analysis_next_ack_frame;
846
static int hf_lbtru_analysis_next_creq_frame;
847
static int hf_lbtru_analysis_next_rst_frame;
848
static int hf_lbtru_analysis_sqn;
849
static int hf_lbtru_analysis_sqn_frame;
850
static int hf_lbtru_analysis_data_retransmission;
851
static int hf_lbtru_analysis_data_sqn_gap;
852
static int hf_lbtru_analysis_data_ooo_gap;
853
static int hf_lbtru_analysis_data_duplicate;
854
static int hf_lbtru_analysis_sm_sqn_gap;
855
static int hf_lbtru_analysis_sm_ooo_gap;
856
static int hf_lbtru_analysis_sm_duplicate;
857
858
/* Expert info handles */
859
static expert_field ei_lbtru_analysis_unknown_type;
860
static expert_field ei_lbtru_analysis_unknown_header;
861
static expert_field ei_lbtru_analysis_zero_length_header;
862
static expert_field ei_lbtru_analysis_ack;
863
static expert_field ei_lbtru_analysis_ncf;
864
static expert_field ei_lbtru_analysis_ncf_ncf;
865
static expert_field ei_lbtru_analysis_nak;
866
static expert_field ei_lbtru_analysis_nak_nak;
867
static expert_field ei_lbtru_analysis_sm;
868
static expert_field ei_lbtru_analysis_sm_syn;
869
static expert_field ei_lbtru_analysis_creq;
870
static expert_field ei_lbtru_analysis_rst;
871
static expert_field ei_lbtru_analysis_data_rx;
872
static expert_field ei_lbtru_analysis_data_gap;
873
static expert_field ei_lbtru_analysis_data_ooo;
874
static expert_field ei_lbtru_analysis_data_dup;
875
static expert_field ei_lbtru_analysis_sm_gap;
876
static expert_field ei_lbtru_analysis_sm_ooo;
877
static expert_field ei_lbtru_analysis_sm_dup;
878
879
/*----------------------------------------------------------------------------*/
880
/* LBT-RU data payload dissection functions.                                  */
881
/*----------------------------------------------------------------------------*/
882
static int dissect_lbtru_data_contents(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, const char * tag_name, uint64_t channel)
883
0
{
884
0
    tvbuff_t * next_tvb;
885
886
0
    next_tvb = tvb_new_subset_remaining(tvb, offset);
887
0
    return (lbmc_dissect_lbmc_packet(next_tvb, 0, pinfo, tree, tag_name, channel));
888
0
}
889
890
/*----------------------------------------------------------------------------*/
891
/* LBT-RU ACK packet dissection functions.                                    */
892
/*----------------------------------------------------------------------------*/
893
static int dissect_lbtru_ack(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, lbm_lbtru_tap_info_t * tap_info)
894
0
{
895
0
    proto_tree * ack_tree = NULL;
896
0
    proto_item * ack_item = NULL;
897
0
    proto_item * ack = NULL;
898
899
0
    ack_item = proto_tree_add_item(tree, hf_lbtru_ack, tvb, offset, L_LBTRU_ACK_HDR_T, ENC_NA);
900
0
    ack_tree = proto_item_add_subtree(ack_item, ett_lbtru_ack);
901
0
    ack = proto_tree_add_item(ack_tree, hf_lbtru_ack_sqn, tvb, offset + O_LBTRU_ACK_HDR_T_ACK_SQN, L_LBTRU_ACK_HDR_T_ACK_SQN, ENC_BIG_ENDIAN);
902
0
    expert_add_info(pinfo, ack, &ei_lbtru_analysis_ack);
903
0
    tap_info->sqn = tvb_get_ntohl(tvb, offset + O_LBTRU_ACK_HDR_T_ACK_SQN);
904
0
    return (L_LBTRU_ACK_HDR_T);
905
0
}
906
907
/*----------------------------------------------------------------------------*/
908
/* LBT-RU NAK confirmation packet dissection functions.                       */
909
/*----------------------------------------------------------------------------*/
910
static int dissect_lbtru_ncf_list(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, int ncf_count, int reason, lbm_lbtru_tap_info_t * tap_info)
911
0
{
912
0
    proto_tree * ncf_tree = NULL;
913
0
    proto_item * ncf_item = NULL;
914
0
    lbm_uint32_t ncf;
915
0
    int idx = 0;
916
0
    int len = 0;
917
918
0
    ncf_item = proto_tree_add_item(tree, hf_lbtru_ncf_list, tvb, offset, -1, ENC_NA);
919
0
    ncf_tree = proto_item_add_subtree(ncf_item, ett_lbtru_ncf_list);
920
921
0
    for (idx = 0; idx < ncf_count; idx++)
922
0
    {
923
0
        proto_item * sep_ncf_item = NULL;
924
925
0
        sep_ncf_item = proto_tree_add_item_ret_uint(ncf_tree, hf_lbtru_ncf_list_ncf, tvb, offset + len, sizeof(lbm_uint32_t), ENC_BIG_ENDIAN, &ncf);
926
0
        if (lbtru_expert_separate_ncfs)
927
0
        {
928
0
            expert_add_info_format(pinfo, sep_ncf_item, &ei_lbtru_analysis_ncf_ncf, "NCF 0x%08x %s", ncf, val_to_str(pinfo->pool, reason, lbtru_ncf_reason, "Unknown (0x%02x)"));
929
0
        }
930
0
        tap_info->sqns[idx] = ncf;
931
0
        len += (int)sizeof(lbm_uint32_t);
932
0
    }
933
0
    proto_item_set_len(ncf_item, len);
934
0
    return (len);
935
0
}
936
937
static int dissect_lbtru_ncf(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, lbm_lbtru_tap_info_t * tap_info)
938
0
{
939
0
    int len_dissected;
940
0
    uint8_t reason_format;
941
0
    proto_tree * ncf_tree = NULL;
942
0
    proto_item * ncf_item = NULL;
943
0
    uint16_t num_ncfs = 0;
944
945
0
    ncf_item = proto_tree_add_item(tree, hf_lbtru_ncf, tvb, offset, -1, ENC_NA);
946
0
    ncf_tree = proto_item_add_subtree(ncf_item, ett_lbtru_ncf);
947
0
    reason_format = tvb_get_uint8(tvb, offset + O_LBTRU_NCF_HDR_T_REASON_FORMAT);
948
0
    num_ncfs = tvb_get_ntohs(tvb, offset + O_LBTRU_NCF_HDR_T_NUM_NCFS);
949
0
    proto_tree_add_item(ncf_tree, hf_lbtru_ncf_trail_sqn, tvb, offset + O_LBTRU_NCF_HDR_T_TRAIL_SQN, L_LBTRU_NCF_HDR_T_TRAIL_SQN, ENC_BIG_ENDIAN);
950
0
    proto_tree_add_item(ncf_tree, hf_lbtru_ncf_num, tvb, offset + O_LBTRU_NCF_HDR_T_NUM_NCFS, L_LBTRU_NCF_HDR_T_NUM_NCFS, ENC_BIG_ENDIAN);
951
0
    proto_tree_add_item(ncf_tree, hf_lbtru_ncf_reserved, tvb, offset + O_LBTRU_NCF_HDR_T_RESERVED, L_LBTRU_NCF_HDR_T_RESERVED, ENC_BIG_ENDIAN);
952
0
    proto_tree_add_item(ncf_tree, hf_lbtru_ncf_reason, tvb, offset + O_LBTRU_NCF_HDR_T_REASON_FORMAT, L_LBTRU_NCF_HDR_T_REASON_FORMAT, ENC_BIG_ENDIAN);
953
0
    proto_tree_add_item(ncf_tree, hf_lbtru_ncf_format, tvb, offset + O_LBTRU_NCF_HDR_T_REASON_FORMAT, L_LBTRU_NCF_HDR_T_REASON_FORMAT, ENC_BIG_ENDIAN);
954
0
    len_dissected = L_LBTRU_NCF_HDR_T;
955
0
    if (!lbtru_expert_separate_ncfs)
956
0
    {
957
0
        expert_add_info_format(pinfo, ncf_item, &ei_lbtru_analysis_ncf, "NCF %s", val_to_str(pinfo->pool, LBTRU_NCF_HDR_REASON(reason_format), lbtru_ncf_reason, "Unknown (0x%02x)"));
958
0
    }
959
0
    tap_info->ncf_reason = LBTRU_NCF_HDR_REASON(reason_format);
960
0
    tap_info->num_sqns = num_ncfs;
961
0
    tap_info->sqns = wmem_alloc_array(pinfo->pool, uint32_t, num_ncfs);
962
0
    len_dissected += dissect_lbtru_ncf_list(tvb, offset + L_LBTRU_NCF_HDR_T, pinfo, ncf_tree, num_ncfs, LBTRU_NCF_HDR_REASON(reason_format), tap_info);
963
0
    proto_item_set_len(ncf_item, len_dissected);
964
0
    return (len_dissected);
965
0
}
966
967
/*----------------------------------------------------------------------------*/
968
/* LBT-RU NAK packet dissection functions.                                    */
969
/*----------------------------------------------------------------------------*/
970
static int dissect_lbtru_nak_list(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, int nak_count, lbm_lbtru_tap_info_t * tap_info)
971
0
{
972
0
    proto_tree * nak_tree = NULL;
973
0
    proto_item * nak_item = NULL;
974
0
    int idx = 0;
975
0
    int len = 0;
976
977
0
    nak_item = proto_tree_add_item(tree, hf_lbtru_nak_list, tvb, offset, -1, ENC_NA);
978
0
    nak_tree = proto_item_add_subtree(nak_item, ett_lbtru_nak_list);
979
980
0
    for (idx = 0; idx < nak_count; idx++)
981
0
    {
982
0
        proto_item * sep_nak_item = NULL;
983
0
        lbm_uint32_t nak;
984
985
0
        sep_nak_item = proto_tree_add_item_ret_uint(nak_tree, hf_lbtru_nak_list_nak, tvb, offset + len, sizeof(lbm_uint32_t), ENC_BIG_ENDIAN, &nak);
986
0
        if (lbtru_expert_separate_naks)
987
0
        {
988
0
            expert_add_info_format(pinfo, sep_nak_item, &ei_lbtru_analysis_nak_nak, "NAK 0x%08x", nak);
989
0
        }
990
0
        tap_info->sqns[idx] = nak;
991
0
        len += (int)sizeof(lbm_uint32_t);
992
0
    }
993
0
    proto_item_set_len(nak_item, len);
994
0
    return (len);
995
0
}
996
997
static int dissect_lbtru_nak(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, lbm_lbtru_tap_info_t * tap_info)
998
0
{
999
0
    int len_dissected;
1000
0
    proto_tree * nak_tree = NULL;
1001
0
    proto_item * nak_item = NULL;
1002
0
    uint16_t num_naks = 0;
1003
1004
0
    nak_item = proto_tree_add_item(tree, hf_lbtru_nak, tvb, offset, -1, ENC_NA);
1005
0
    nak_tree = proto_item_add_subtree(nak_item, ett_lbtru_nak);
1006
0
    num_naks = tvb_get_ntohs(tvb, offset + O_LBTRU_NAK_HDR_T_NUM_NAKS);
1007
0
    proto_tree_add_item(nak_tree, hf_lbtru_nak_num, tvb, offset + O_LBTRU_NAK_HDR_T_NUM_NAKS, L_LBTRU_NAK_HDR_T_NUM_NAKS, ENC_BIG_ENDIAN);
1008
0
    proto_tree_add_item(nak_tree, hf_lbtru_nak_format, tvb, offset + O_LBTRU_NAK_HDR_T_FORMAT, L_LBTRU_NAK_HDR_T_FORMAT, ENC_BIG_ENDIAN);
1009
0
    len_dissected = L_LBTRU_NAK_HDR_T;
1010
0
    if (!lbtru_expert_separate_naks)
1011
0
    {
1012
0
        expert_add_info(pinfo, nak_item, &ei_lbtru_analysis_nak);
1013
0
    }
1014
0
    tap_info->num_sqns = num_naks;
1015
0
    tap_info->sqns = wmem_alloc_array(pinfo->pool, uint32_t, num_naks);
1016
0
    len_dissected += dissect_lbtru_nak_list(tvb, offset + L_LBTRU_NAK_HDR_T, pinfo, nak_tree, num_naks, tap_info);
1017
0
    proto_item_set_len(nak_item, len_dissected);
1018
0
    return (len_dissected);
1019
0
}
1020
1021
/*----------------------------------------------------------------------------*/
1022
/* LBT-RU session message packet dissection function.                         */
1023
/*----------------------------------------------------------------------------*/
1024
static int dissect_lbtru_sm(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, int syn, lbm_lbtru_tap_info_t * tap_info)
1025
0
{
1026
0
    proto_tree * sm_tree = NULL;
1027
0
    proto_item * sm_item = NULL;
1028
0
    proto_item * sm_sqn = NULL;
1029
1030
0
    sm_item = proto_tree_add_item(tree, hf_lbtru_sm, tvb, offset, L_LBTRU_SM_HDR_T, ENC_NA);
1031
0
    sm_tree = proto_item_add_subtree(sm_item, ett_lbtru_sm);
1032
0
    sm_sqn = proto_tree_add_item(sm_tree, hf_lbtru_sm_sqn, tvb, offset + O_LBTRU_SM_HDR_T_SM_SQN, L_LBTRU_SM_HDR_T_SM_SQN, ENC_BIG_ENDIAN);
1033
0
    proto_tree_add_item(sm_tree, hf_lbtru_sm_lead_sqn, tvb, offset + O_LBTRU_SM_HDR_T_LEAD_SQN, L_LBTRU_SM_HDR_T_LEAD_SQN, ENC_BIG_ENDIAN);
1034
0
    proto_tree_add_item(sm_tree, hf_lbtru_sm_trail_sqn, tvb, offset + O_LBTRU_SM_HDR_T_TRAIL_SQN, L_LBTRU_SM_HDR_T_TRAIL_SQN, ENC_BIG_ENDIAN);
1035
0
    if (syn)
1036
0
    {
1037
0
        expert_add_info(pinfo, sm_sqn, &ei_lbtru_analysis_sm_syn);
1038
0
    }
1039
0
    else
1040
0
    {
1041
0
        expert_add_info(pinfo, sm_sqn, &ei_lbtru_analysis_sm);
1042
0
    }
1043
0
    tap_info->sqn = tvb_get_ntohl(tvb, offset + O_LBTRU_SM_HDR_T_SM_SQN);
1044
0
    return (L_LBTRU_SM_HDR_T);
1045
0
}
1046
1047
/*----------------------------------------------------------------------------*/
1048
/* LBT-RU data packet dissection functions.                                   */
1049
/*----------------------------------------------------------------------------*/
1050
static int dissect_lbtru_data(tvbuff_t * tvb, int offset, packet_info * pinfo _U_, proto_tree * tree, lbm_lbtru_tap_info_t * tap_info)
1051
0
{
1052
0
    proto_tree * data_tree = NULL;
1053
0
    proto_item * data_item = NULL;
1054
1055
0
    data_item = proto_tree_add_item(tree, hf_lbtru_data, tvb, offset, L_LBTRU_DATA_HDR_T, ENC_NA);
1056
0
    data_tree = proto_item_add_subtree(data_item, ett_lbtru_data);
1057
0
    proto_tree_add_item(data_tree, hf_lbtru_data_sqn, tvb, offset + O_LBTRU_DATA_HDR_T_SQN, L_LBTRU_DATA_HDR_T_SQN, ENC_BIG_ENDIAN);
1058
0
    proto_tree_add_item(data_tree, hf_lbtru_data_trail_sqn, tvb, offset + O_LBTRU_DATA_HDR_T_TRAIL_SQN, L_LBTRU_DATA_HDR_T_TRAIL_SQN, ENC_BIG_ENDIAN);
1059
0
    tap_info->sqn = tvb_get_ntohl(tvb, offset + O_LBTRU_DATA_HDR_T_SQN);
1060
0
    return (L_LBTRU_DATA_HDR_T);
1061
0
}
1062
1063
/*----------------------------------------------------------------------------*/
1064
/* LBT-RU packet dissector.                                                   */
1065
/*----------------------------------------------------------------------------*/
1066
typedef struct
1067
{
1068
    proto_tree * tree;
1069
    tvbuff_t * tvb;
1070
    uint32_t current_frame;
1071
} lbtru_sqn_frame_list_callback_data_t;
1072
1073
static bool dissect_lbtru_sqn_frame_list_callback(const void *key _U_, void * frame, void * user_data)
1074
0
{
1075
0
    lbtru_sqn_frame_list_callback_data_t * cb_data = (lbtru_sqn_frame_list_callback_data_t *) user_data;
1076
0
    proto_item * transport_item = NULL;
1077
0
    lbm_transport_sqn_frame_t * sqn_frame = (lbm_transport_sqn_frame_t *) frame;
1078
1079
0
    if (sqn_frame->frame != cb_data->current_frame)
1080
0
    {
1081
0
        if (sqn_frame->retransmission)
1082
0
        {
1083
0
            transport_item = proto_tree_add_uint_format_value(cb_data->tree, hf_lbtru_analysis_sqn_frame, cb_data->tvb, 0, 0, sqn_frame->frame, "%" PRIu32 " (RX)", sqn_frame->frame);
1084
0
        }
1085
0
        else
1086
0
        {
1087
0
            transport_item = proto_tree_add_uint(cb_data->tree, hf_lbtru_analysis_sqn_frame, cb_data->tvb, 0, 0, sqn_frame->frame);
1088
0
        }
1089
0
        proto_item_set_generated(transport_item);
1090
0
    }
1091
0
    return false;
1092
0
}
1093
1094
static int dissect_lbtru(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * user_data _U_)
1095
0
{
1096
0
    proto_tree * lbtru_tree = NULL;
1097
0
    proto_item * lbtru_item = NULL;
1098
0
    static int * const flags_data[] =
1099
0
    {
1100
0
        &hf_lbtru_hdr_flags_rx,
1101
0
        NULL
1102
0
    };
1103
0
    static int * const flags_sm[] =
1104
0
    {
1105
0
        &hf_lbtru_hdr_flags_syn,
1106
0
        NULL
1107
0
    };
1108
0
    int ofs = 0;
1109
0
    uint32_t session_id = 0;
1110
0
    char * tag_name = NULL;
1111
0
    int dissected_len;
1112
0
    int total_dissected_len = 0;
1113
0
    proto_tree * header_tree = NULL;
1114
0
    proto_item * header_item = NULL;
1115
0
    proto_tree * transport_tree = NULL;
1116
0
    proto_item * transport_item = NULL;
1117
0
    bool from_source = true;
1118
0
    uint8_t packet_type = 0;
1119
0
    address source_address;
1120
0
    address receiver_address;
1121
0
    uint16_t source_port = 0;
1122
0
    uint16_t receiver_port = 0;
1123
0
    lbtru_transport_t * transport = NULL;
1124
0
    lbtru_client_transport_t * client = NULL;
1125
0
    uint64_t channel = LBM_CHANNEL_NO_CHANNEL;
1126
0
    proto_tree * channel_tree = NULL;
1127
0
    proto_item * channel_item = NULL;
1128
0
    uint8_t ver_type = 0;
1129
0
    uint8_t next_hdr = 0;
1130
0
    uint32_t packet_sqn = 0;
1131
0
    uint16_t flags_or_res = 0;
1132
0
    uint16_t num_naks = 0;
1133
0
    uint16_t num_ncfs = 0;
1134
0
    bool retransmission = false;
1135
0
    proto_item * fld_item = NULL;
1136
0
    proto_item * ei_item = NULL;
1137
0
    proto_item * type_item = NULL;
1138
0
    proto_item * next_hdr_item = NULL;
1139
0
    lbm_lbtru_tap_info_t * tapinfo = NULL;
1140
1141
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "LBT-RU");
1142
0
    if (lbtru_use_tag)
1143
0
    {
1144
0
        tag_name = lbtru_tag_find(pinfo);
1145
0
    }
1146
0
    col_clear(pinfo->cinfo, COL_INFO);
1147
0
    if (tag_name != NULL)
1148
0
    {
1149
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "[Tag: %s]", tag_name);
1150
0
    }
1151
0
    col_set_fence(pinfo->cinfo, COL_INFO);
1152
1153
0
    ver_type = tvb_get_uint8(tvb, O_LBTRU_HDR_T_VER_TYPE);
1154
0
    next_hdr = tvb_get_uint8(tvb, O_LBTRU_HDR_T_NEXT_HDR);
1155
0
    flags_or_res = tvb_get_ntohs(tvb, O_LBTRU_HDR_T_FLAGS_OR_RES);
1156
0
    packet_type = LBTRU_HDR_TYPE(ver_type);
1157
0
    if (tag_name != NULL)
1158
0
    {
1159
0
        lbtru_item = proto_tree_add_protocol_format(tree, proto_lbtru, tvb, ofs, -1, "LBT-RU Protocol (Tag: %s): Version %u, Type %s", tag_name,
1160
0
            LBTRU_HDR_VER(ver_type), val_to_str(pinfo->pool, LBTRU_HDR_TYPE(ver_type), lbtru_packet_type, "Unknown (0x%02x)"));
1161
0
    }
1162
0
    else
1163
0
    {
1164
0
        lbtru_item = proto_tree_add_protocol_format(tree, proto_lbtru, tvb, ofs, -1, "LBT-RU Protocol: Version %u, Type %s", LBTRU_HDR_VER(ver_type),
1165
0
            val_to_str(pinfo->pool, LBTRU_HDR_TYPE(ver_type), lbtru_packet_type, "Unknown (0x%02x)"));
1166
0
    }
1167
0
    lbtru_tree = proto_item_add_subtree(lbtru_item, ett_lbtru);
1168
0
    if (tag_name != NULL)
1169
0
    {
1170
0
        proto_item * item = NULL;
1171
0
        item = proto_tree_add_string(lbtru_tree, hf_lbtru_tag, tvb, 0, 0, tag_name);
1172
0
        proto_item_set_generated(item);
1173
0
    }
1174
0
    channel_item = proto_tree_add_item(lbtru_tree, hf_lbtru_channel, tvb, 0, 0, ENC_NA);
1175
0
    proto_item_set_generated(channel_item);
1176
0
    channel_tree = proto_item_add_subtree(channel_item, ett_lbtru_channel);
1177
1178
0
    tapinfo = wmem_new0(pinfo->pool, lbm_lbtru_tap_info_t);
1179
0
    tapinfo->type = packet_type;
1180
1181
0
    header_item = proto_tree_add_item(lbtru_tree, hf_lbtru_hdr, tvb, 0, -1, ENC_NA);
1182
0
    header_tree = proto_item_add_subtree(header_item, ett_lbtru_hdr);
1183
0
    proto_tree_add_item(header_tree, hf_lbtru_hdr_ver, tvb, O_LBTRU_HDR_T_VER_TYPE, L_LBTRU_HDR_T_VER_TYPE, ENC_BIG_ENDIAN);
1184
0
    type_item = proto_tree_add_item(header_tree, hf_lbtru_hdr_type, tvb, O_LBTRU_HDR_T_VER_TYPE, L_LBTRU_HDR_T_VER_TYPE, ENC_BIG_ENDIAN);
1185
0
    next_hdr_item = proto_tree_add_item(header_tree, hf_lbtru_hdr_next_hdr, tvb, O_LBTRU_HDR_T_NEXT_HDR, L_LBTRU_HDR_T_NEXT_HDR, ENC_BIG_ENDIAN);
1186
0
    total_dissected_len = L_LBTRU_HDR_T_VER_TYPE + L_LBTRU_HDR_T_NEXT_HDR;
1187
0
    ofs = L_LBTRU_HDR_T_VER_TYPE + L_LBTRU_HDR_T_NEXT_HDR;
1188
1189
0
    switch (packet_type)
1190
0
    {
1191
0
        case LBTRU_PACKET_TYPE_DATA:
1192
0
            packet_sqn = tvb_get_ntohl(tvb, L_LBTRU_HDR_T + O_LBTRU_DATA_HDR_T_SQN);
1193
0
            if ((flags_or_res & LBTRU_RETRANSMISSION_FLAG) != 0)
1194
0
            {
1195
0
                retransmission = true;
1196
0
                tapinfo->retransmission = true;
1197
0
            }
1198
0
            if (retransmission)
1199
0
            {
1200
0
                col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "DATA(RX) sqn 0x%x", packet_sqn);
1201
0
            }
1202
0
            else
1203
0
            {
1204
0
                col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "DATA sqn 0x%x", packet_sqn);
1205
0
            }
1206
0
            from_source = true;
1207
0
            break;
1208
0
        case LBTRU_PACKET_TYPE_SM:
1209
0
            packet_sqn = tvb_get_ntohl(tvb, L_LBTRU_HDR_T + O_LBTRU_SM_HDR_T_SM_SQN);
1210
0
            if ((flags_or_res & LBTRU_SM_SYN_FLAG) != 0)
1211
0
            {
1212
0
                col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SM sqn 0x%x SYN", packet_sqn);
1213
0
            }
1214
0
            else
1215
0
            {
1216
0
                col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SM sqn 0x%x", packet_sqn);
1217
0
            }
1218
0
            from_source = true;
1219
0
            break;
1220
0
        case LBTRU_PACKET_TYPE_NAK:
1221
0
            num_naks = tvb_get_ntohs(tvb, L_LBTRU_HDR_T + O_LBTRU_NAK_HDR_T_NUM_NAKS);
1222
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "NAK %" PRIu16 " naks", num_naks);
1223
0
            from_source = false;
1224
0
            break;
1225
0
        case LBTRU_PACKET_TYPE_NCF:
1226
0
            num_ncfs = tvb_get_ntohs(tvb, L_LBTRU_HDR_T + O_LBTRU_NCF_HDR_T_NUM_NCFS);
1227
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "NCF %" PRIu16 " ncfs", num_ncfs);
1228
0
            from_source = true;
1229
0
            break;
1230
0
        case LBTRU_PACKET_TYPE_ACK:
1231
0
            packet_sqn = tvb_get_ntohl(tvb, L_LBTRU_HDR_T + O_LBTRU_ACK_HDR_T_ACK_SQN);
1232
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ACK sqn 0x%x", packet_sqn);
1233
0
            from_source = false;
1234
0
            break;
1235
0
        case LBTRU_PACKET_TYPE_CREQ:
1236
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "CREQ %s", val_to_str(pinfo->pool, flags_or_res, lbtru_creq_request, "Unknown (0x%02x)"));
1237
0
            from_source = false;
1238
0
            break;
1239
0
        case LBTRU_PACKET_TYPE_RST:
1240
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "RST %s", val_to_str(pinfo->pool, flags_or_res, lbtru_rst_reason, "Unknown (0x%02x)"));
1241
0
            from_source = true;
1242
0
            break;
1243
0
        default:
1244
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",  "Unknown (0x%02x)", LBTRU_HDR_TYPE(ver_type));
1245
0
            expert_add_info_format(pinfo, type_item, &ei_lbtru_analysis_unknown_type, "Unrecognized type 0x%02x", LBTRU_HDR_TYPE(ver_type));
1246
0
            return (total_dissected_len);
1247
0
    }
1248
1249
    /* Handle the flags_or_res field. */
1250
0
    switch (packet_type)
1251
0
    {
1252
0
        case LBTRU_PACKET_TYPE_DATA:
1253
0
            proto_tree_add_bitmask(header_tree, tvb, O_LBTRU_HDR_T_FLAGS_OR_RES, hf_lbtru_hdr_flags, ett_lbtru_hdr_flags, flags_data, ENC_BIG_ENDIAN);
1254
0
            total_dissected_len += L_LBTRU_HDR_T_FLAGS_OR_RES;
1255
0
            ofs += L_LBTRU_HDR_T_FLAGS_OR_RES;
1256
0
            break;
1257
0
        case LBTRU_PACKET_TYPE_NAK:
1258
0
        case LBTRU_PACKET_TYPE_NCF:
1259
0
        case LBTRU_PACKET_TYPE_ACK:
1260
0
            proto_tree_add_item(header_tree, hf_lbtru_hdr_res, tvb, O_LBTRU_HDR_T_FLAGS_OR_RES, L_LBTRU_HDR_T_FLAGS_OR_RES, ENC_BIG_ENDIAN);
1261
0
            total_dissected_len += L_LBTRU_HDR_T_FLAGS_OR_RES;
1262
0
            ofs += L_LBTRU_HDR_T_FLAGS_OR_RES;
1263
0
            break;
1264
0
        case LBTRU_PACKET_TYPE_SM:
1265
0
            proto_tree_add_bitmask(header_tree, tvb, O_LBTRU_HDR_T_FLAGS_OR_RES, hf_lbtru_hdr_flags, ett_lbtru_hdr_flags, flags_sm, ENC_BIG_ENDIAN);
1266
0
            total_dissected_len += L_LBTRU_HDR_T_FLAGS_OR_RES;
1267
0
            ofs += L_LBTRU_HDR_T_FLAGS_OR_RES;
1268
0
            break;
1269
0
        case LBTRU_PACKET_TYPE_CREQ:
1270
0
            ei_item = proto_tree_add_item(header_tree, hf_lbtru_hdr_request, tvb, O_LBTRU_HDR_T_FLAGS_OR_RES, L_LBTRU_HDR_T_FLAGS_OR_RES, ENC_BIG_ENDIAN);
1271
0
            expert_add_info_format(pinfo, ei_item, &ei_lbtru_analysis_creq, "CREQ %s", val_to_str(pinfo->pool, flags_or_res, lbtru_creq_request, "Unknown (0x%04x)"));
1272
0
            total_dissected_len += L_LBTRU_HDR_T_FLAGS_OR_RES;
1273
0
            ofs += L_LBTRU_HDR_T_FLAGS_OR_RES;
1274
0
            break;
1275
0
        case LBTRU_PACKET_TYPE_RST:
1276
0
            ei_item = proto_tree_add_item(header_tree, hf_lbtru_hdr_reason, tvb, O_LBTRU_HDR_T_FLAGS_OR_RES, L_LBTRU_HDR_T_FLAGS_OR_RES, ENC_BIG_ENDIAN);
1277
0
            expert_add_info_format(pinfo, ei_item, &ei_lbtru_analysis_rst, "RST %s", val_to_str(pinfo->pool, flags_or_res, lbtru_rst_reason, "Unknown (0x%04x)"));
1278
0
            break;
1279
0
        default:
1280
0
            break;
1281
0
    }
1282
1283
    /* Handle the packet-specific data */
1284
0
    switch (packet_type)
1285
0
    {
1286
0
        case LBTRU_PACKET_TYPE_DATA:
1287
0
            dissected_len = dissect_lbtru_data(tvb, L_LBTRU_HDR_T, pinfo, lbtru_tree, tapinfo);
1288
0
            break;
1289
0
        case LBTRU_PACKET_TYPE_SM:
1290
0
            dissected_len = dissect_lbtru_sm(tvb, L_LBTRU_HDR_T, pinfo, lbtru_tree, (flags_or_res & LBTRU_SM_SYN_FLAG), tapinfo);
1291
0
            break;
1292
0
        case LBTRU_PACKET_TYPE_NAK:
1293
0
            dissected_len = dissect_lbtru_nak(tvb, ofs, pinfo, lbtru_tree, tapinfo);
1294
0
            break;
1295
0
        case LBTRU_PACKET_TYPE_NCF:
1296
0
            dissected_len = dissect_lbtru_ncf(tvb, ofs, pinfo, lbtru_tree, tapinfo);
1297
0
            break;
1298
0
        case LBTRU_PACKET_TYPE_ACK:
1299
0
            dissected_len = dissect_lbtru_ack(tvb, ofs, pinfo, lbtru_tree, tapinfo);
1300
0
            break;
1301
0
        case LBTRU_PACKET_TYPE_CREQ:
1302
0
            dissected_len = 0;
1303
0
            tapinfo->creq_type = flags_or_res;
1304
0
            break;
1305
0
        case LBTRU_PACKET_TYPE_RST:
1306
0
            dissected_len = 0;
1307
0
            tapinfo->rst_type = flags_or_res;
1308
0
            break;
1309
0
        default:
1310
0
            dissected_len = 0;
1311
0
            break;
1312
0
    }
1313
0
    total_dissected_len += dissected_len;
1314
0
    ofs += dissected_len;
1315
    /* If we're doing sequence analysis, the tree goes here. */
1316
0
    if (lbtru_sequence_analysis)
1317
0
    {
1318
0
        transport_item = proto_tree_add_item(lbtru_tree, hf_lbtru_analysis, tvb, 0, 0, ENC_NA);
1319
0
        proto_item_set_generated(transport_item);
1320
0
        transport_tree = proto_item_add_subtree(transport_item, ett_lbtru_transport);
1321
0
    }
1322
0
    while (next_hdr != LBTRU_NHDR_DATA)
1323
0
    {
1324
0
        proto_item * hdr_length_item;
1325
0
        proto_tree * opt_tree = NULL;
1326
0
        static int * const sid_flags[] =
1327
0
        {
1328
0
            &hf_lbtru_opt_sid_flags_ignore,
1329
0
            NULL
1330
0
        };
1331
0
        static int * const cid_flags[] =
1332
0
        {
1333
0
            &hf_lbtru_opt_cid_flags_ignore,
1334
0
            NULL
1335
0
        };
1336
0
        int hdrlen;
1337
0
        uint8_t cur_next_hdr;
1338
1339
0
        cur_next_hdr = tvb_get_uint8(tvb, ofs + O_LBTRU_BASIC_OPT_T_NEXT_HDR);
1340
0
        hdrlen = (int)tvb_get_uint8(tvb, ofs + O_LBTRU_BASIC_OPT_T_HDR_LEN);
1341
0
        switch (next_hdr)
1342
0
        {
1343
0
            case LBTRU_NHDR_SID:
1344
0
                fld_item = proto_tree_add_item(lbtru_tree, hf_lbtru_opt_sid, tvb, ofs, L_LBTRU_BASIC_OPT_T + L_LBTRU_SID_OPT_T, ENC_NA);
1345
0
                opt_tree = proto_item_add_subtree(fld_item, ett_lbtru_opt);
1346
0
                next_hdr_item = proto_tree_add_item(opt_tree, hf_lbtru_opt_sid_next_hdr, tvb, ofs + O_LBTRU_BASIC_OPT_T_NEXT_HDR, L_LBTRU_BASIC_OPT_T_NEXT_HDR, ENC_BIG_ENDIAN);
1347
0
                hdr_length_item = proto_tree_add_item(opt_tree, hf_lbtru_opt_sid_hdr_len, tvb, ofs + O_LBTRU_BASIC_OPT_T_HDR_LEN, L_LBTRU_BASIC_OPT_T_HDR_LEN, ENC_BIG_ENDIAN);
1348
0
                if (hdrlen == 0)
1349
0
                {
1350
0
                    expert_add_info(pinfo, hdr_length_item, &ei_lbtru_analysis_zero_length_header);
1351
0
                    return (total_dissected_len);
1352
0
                }
1353
0
                proto_tree_add_bitmask(opt_tree, tvb, ofs + O_LBTRU_BASIC_OPT_T_RES, hf_lbtru_opt_sid_flags, ett_lbtru_opt_sid_flags, sid_flags, ENC_BIG_ENDIAN);
1354
0
                proto_tree_add_item(opt_tree, hf_lbtru_opt_sid_session_id, tvb, ofs + L_LBTRU_BASIC_OPT_T + O_LBTRU_SID_OPT_T_SESSION_ID, L_LBTRU_SID_OPT_T_SESSION_ID, ENC_BIG_ENDIAN);
1355
0
                session_id = tvb_get_ntohl(tvb, ofs + L_LBTRU_BASIC_OPT_T + O_LBTRU_SID_OPT_T_SESSION_ID);
1356
0
                break;
1357
0
            case LBTRU_NHDR_CID:
1358
0
                fld_item = proto_tree_add_item(lbtru_tree, hf_lbtru_opt_cid, tvb, ofs, L_LBTRU_BASIC_OPT_T + L_LBTRU_CID_OPT_T, ENC_NA);
1359
0
                opt_tree = proto_item_add_subtree(fld_item, ett_lbtru_opt);
1360
0
                next_hdr_item = proto_tree_add_item(opt_tree, hf_lbtru_opt_cid_next_hdr, tvb, ofs + O_LBTRU_BASIC_OPT_T_NEXT_HDR, L_LBTRU_BASIC_OPT_T_NEXT_HDR, ENC_BIG_ENDIAN);
1361
0
                hdr_length_item = proto_tree_add_item(opt_tree, hf_lbtru_opt_cid_hdr_len, tvb, ofs + O_LBTRU_BASIC_OPT_T_HDR_LEN, L_LBTRU_BASIC_OPT_T_HDR_LEN, ENC_BIG_ENDIAN);
1362
0
                if (hdrlen == 0)
1363
0
                {
1364
0
                    expert_add_info(pinfo, hdr_length_item, &ei_lbtru_analysis_zero_length_header);
1365
0
                    return (total_dissected_len);
1366
0
                }
1367
0
                proto_tree_add_bitmask(opt_tree, tvb, ofs + O_LBTRU_BASIC_OPT_T_RES, hf_lbtru_opt_cid_flags, ett_lbtru_opt_cid_flags, cid_flags, ENC_BIG_ENDIAN);
1368
0
                proto_tree_add_item(opt_tree, hf_lbtru_opt_cid_client_id, tvb, ofs + L_LBTRU_BASIC_OPT_T + O_LBTRU_CID_OPT_T_CLIENT_SID, L_LBTRU_CID_OPT_T_CLIENT_SID, ENC_BIG_ENDIAN);
1369
0
                break;
1370
0
            default:
1371
0
                expert_add_info_format(pinfo, next_hdr_item, &ei_lbtru_analysis_unknown_header, "Unrecognized header 0x%02x", next_hdr);
1372
0
                fld_item = proto_tree_add_item(lbtru_tree, hf_lbtru_opt_unknown, tvb, ofs, L_LBTRU_BASIC_OPT_T + L_LBTRU_CID_OPT_T, ENC_NA);
1373
0
                opt_tree = proto_item_add_subtree(fld_item, ett_lbtru_opt);
1374
0
                next_hdr_item = proto_tree_add_item(opt_tree, hf_lbtru_opt_unknown_next_hdr, tvb, ofs + O_LBTRU_BASIC_OPT_T_NEXT_HDR, L_LBTRU_BASIC_OPT_T_NEXT_HDR, ENC_BIG_ENDIAN);
1375
0
                hdr_length_item = proto_tree_add_item(opt_tree, hf_lbtru_opt_unknown_hdr_len, tvb, ofs + O_LBTRU_BASIC_OPT_T_HDR_LEN, L_LBTRU_BASIC_OPT_T_HDR_LEN, ENC_BIG_ENDIAN);
1376
0
                if (hdrlen == 0)
1377
0
                {
1378
0
                    expert_add_info(pinfo, hdr_length_item, &ei_lbtru_analysis_zero_length_header);
1379
0
                    return (total_dissected_len);
1380
0
                }
1381
0
                break;
1382
0
        }
1383
0
        next_hdr = cur_next_hdr;
1384
0
        ofs += hdrlen;
1385
0
        total_dissected_len += hdrlen;
1386
0
    }
1387
1388
    /* Find (or create) the transport and client entries */
1389
0
    if (from_source)
1390
0
    {
1391
0
        copy_address_shallow(&source_address, &(pinfo->src));
1392
0
        source_port = pinfo->srcport;
1393
0
        copy_address_shallow(&receiver_address, &(pinfo->dst));
1394
0
        receiver_port = pinfo->destport;
1395
0
    }
1396
0
    else
1397
0
    {
1398
0
        copy_address_shallow(&source_address, &(pinfo->dst));
1399
0
        source_port = pinfo->destport;
1400
0
        copy_address_shallow(&receiver_address, &(pinfo->src));
1401
0
        receiver_port = pinfo->srcport;
1402
0
    }
1403
0
    if (pinfo->fd->visited == 0)
1404
0
    {
1405
0
        transport = lbtru_transport_add(&source_address, source_port, session_id, pinfo->num);
1406
0
    }
1407
0
    else
1408
0
    {
1409
0
        transport = lbtru_transport_find(&source_address, source_port, session_id, pinfo->num);
1410
0
    }
1411
0
    if (transport != NULL)
1412
0
    {
1413
0
        if (pinfo->fd->visited == 0)
1414
0
        {
1415
0
            client = lbtru_client_transport_add(transport, &receiver_address, receiver_port, pinfo->num);
1416
0
            if (client != NULL)
1417
0
            {
1418
0
                if (lbtru_sequence_analysis)
1419
0
                {
1420
0
                    lbtru_client_transport_frame_add(client, packet_type, pinfo->num, packet_sqn, retransmission);
1421
0
                }
1422
0
            }
1423
0
        }
1424
0
        else
1425
0
        {
1426
0
            client = lbtru_client_transport_find(transport, &receiver_address, receiver_port, pinfo->num);
1427
0
        }
1428
0
        tapinfo->transport = lbtru_transport_source_string_transport(pinfo->pool, transport);
1429
0
        channel = transport->channel;
1430
0
        fld_item = proto_tree_add_uint64(channel_tree, hf_lbtru_channel_id, tvb, 0, 0, channel);
1431
0
        proto_item_set_generated(fld_item);
1432
0
        if (client != NULL)
1433
0
        {
1434
0
            fld_item = proto_tree_add_uint(channel_tree, hf_lbtru_channel_client, tvb, 0, 0, client->id);
1435
0
            proto_item_set_generated(fld_item);
1436
0
        }
1437
0
    }
1438
0
    proto_item_set_len(lbtru_item, total_dissected_len);
1439
0
    if ((packet_type == LBTRU_PACKET_TYPE_DATA) && (next_hdr == LBTRU_NHDR_DATA))
1440
0
    {
1441
0
        total_dissected_len += dissect_lbtru_data_contents(tvb, ofs, pinfo, tree, tag_name, channel);
1442
0
    }
1443
0
    if (lbtru_sequence_analysis)
1444
0
    {
1445
0
        if ((transport != NULL) && (client != NULL))
1446
0
        {
1447
0
            lbm_transport_frame_t * frame = NULL;
1448
1449
            /* Fill in the tree */
1450
0
            frame = lbtru_client_transport_frame_find(client, pinfo->num);
1451
0
            if (frame != NULL)
1452
0
            {
1453
0
                lbm_transport_sqn_t * sqn = NULL;
1454
1455
0
                if (frame->previous_frame != 0)
1456
0
                {
1457
0
                    transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_prev_frame, tvb, 0, 0, frame->previous_frame);
1458
0
                    proto_item_set_generated(transport_item);
1459
0
                }
1460
0
                if (frame->next_frame != 0)
1461
0
                {
1462
0
                    transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_next_frame, tvb, 0, 0, frame->next_frame);
1463
0
                    proto_item_set_generated(transport_item);
1464
0
                }
1465
0
                switch (packet_type)
1466
0
                {
1467
0
                    case LBTRU_PACKET_TYPE_DATA:
1468
0
                        if (frame->previous_type_frame != 0)
1469
0
                        {
1470
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_prev_data_frame, tvb, 0, 0, frame->previous_type_frame);
1471
0
                            proto_item_set_generated(transport_item);
1472
0
                        }
1473
0
                        if (frame->next_type_frame != 0)
1474
0
                        {
1475
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_next_data_frame, tvb, 0, 0, frame->next_type_frame);
1476
0
                            proto_item_set_generated(transport_item);
1477
0
                        }
1478
0
                        sqn = lbtru_client_transport_sqn_find(client, packet_type, packet_sqn);
1479
0
                        if (sqn != NULL)
1480
0
                        {
1481
0
                            if (sqn->frame_count > 1)
1482
0
                            {
1483
0
                                proto_tree * frame_tree = NULL;
1484
0
                                proto_item * frame_tree_item = NULL;
1485
0
                                lbtru_sqn_frame_list_callback_data_t cb_data;
1486
1487
0
                                frame_tree_item = proto_tree_add_item(transport_tree, hf_lbtru_analysis_sqn, tvb, 0, 0, ENC_NA);
1488
0
                                proto_item_set_generated(frame_tree_item);
1489
0
                                frame_tree = proto_item_add_subtree(frame_tree_item, ett_lbtru_transport_sqn);
1490
0
                                cb_data.tree = frame_tree;
1491
0
                                cb_data.tvb = tvb;
1492
0
                                cb_data.current_frame = pinfo->num;
1493
0
                                wmem_tree_foreach(sqn->frame, dissect_lbtru_sqn_frame_list_callback, (void *) &cb_data);
1494
0
                            }
1495
0
                        }
1496
0
                        if (frame->retransmission)
1497
0
                        {
1498
0
                            transport_item = proto_tree_add_boolean(transport_tree, hf_lbtru_analysis_data_retransmission, tvb, 0, 0, true);
1499
0
                            proto_item_set_generated(transport_item);
1500
0
                            expert_add_info(pinfo, transport_item, &ei_lbtru_analysis_data_rx);
1501
0
                        }
1502
0
                        if (frame->sqn_gap != 0)
1503
0
                        {
1504
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_data_sqn_gap, tvb, 0, 0, frame->sqn_gap);
1505
0
                            proto_item_set_generated(transport_item);
1506
0
                            expert_add_info_format(pinfo, transport_item, &ei_lbtru_analysis_data_gap, "Data sequence gap (%" PRIu32 ")", frame->sqn_gap);
1507
1508
0
                        }
1509
0
                        if (frame->ooo_gap != 0)
1510
0
                        {
1511
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_data_ooo_gap, tvb, 0, 0, frame->ooo_gap);
1512
0
                            proto_item_set_generated(transport_item);
1513
0
                            expert_add_info_format(pinfo, transport_item, &ei_lbtru_analysis_data_ooo, "Data sequence out of order gap (%" PRIu32 ")", frame->ooo_gap);
1514
0
                        }
1515
0
                        if (frame->duplicate)
1516
0
                        {
1517
0
                            transport_item = proto_tree_add_boolean(transport_tree, hf_lbtru_analysis_data_duplicate, tvb, 0, 0, true);
1518
0
                            proto_item_set_generated(transport_item);
1519
0
                            expert_add_info(pinfo, transport_item, &ei_lbtru_analysis_data_dup);
1520
0
                        }
1521
0
                        break;
1522
0
                    case LBTRU_PACKET_TYPE_SM:
1523
0
                        if (frame->previous_type_frame != 0)
1524
0
                        {
1525
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_prev_sm_frame, tvb, 0, 0, frame->previous_type_frame);
1526
0
                            proto_item_set_generated(transport_item);
1527
0
                        }
1528
0
                        if (frame->next_type_frame != 0)
1529
0
                        {
1530
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_next_sm_frame, tvb, 0, 0, frame->next_type_frame);
1531
0
                            proto_item_set_generated(transport_item);
1532
0
                        }
1533
0
                        sqn = lbtru_client_transport_sqn_find(client, packet_type, packet_sqn);
1534
0
                        if (sqn != NULL)
1535
0
                        {
1536
0
                            if (sqn->frame_count > 1)
1537
0
                            {
1538
0
                                proto_tree * frame_tree = NULL;
1539
0
                                proto_item * frame_tree_item = NULL;
1540
0
                                lbtru_sqn_frame_list_callback_data_t cb_data;
1541
1542
0
                                frame_tree_item = proto_tree_add_item(transport_tree, hf_lbtru_analysis_sqn, tvb, 0, 0, ENC_NA);
1543
0
                                proto_item_set_generated(frame_tree_item);
1544
0
                                frame_tree = proto_item_add_subtree(frame_tree_item, ett_lbtru_transport_sqn);
1545
0
                                cb_data.tree = frame_tree;
1546
0
                                cb_data.tvb = tvb;
1547
0
                                cb_data.current_frame = pinfo->num;
1548
0
                                wmem_tree_foreach(sqn->frame, dissect_lbtru_sqn_frame_list_callback, (void *) &cb_data);
1549
0
                            }
1550
0
                        }
1551
0
                        if (frame->sqn_gap != 0)
1552
0
                        {
1553
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_sm_sqn_gap, tvb, 0, 0, frame->sqn_gap);
1554
0
                            proto_item_set_generated(transport_item);
1555
0
                            expert_add_info_format(pinfo, transport_item, &ei_lbtru_analysis_sm_gap, "SM sequence gap (%" PRIu32 ")", frame->sqn_gap);
1556
1557
0
                        }
1558
0
                        if (frame->ooo_gap != 0)
1559
0
                        {
1560
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_sm_ooo_gap, tvb, 0, 0, frame->ooo_gap);
1561
0
                            proto_item_set_generated(transport_item);
1562
0
                            expert_add_info_format(pinfo, transport_item, &ei_lbtru_analysis_sm_ooo, "SM sequence out of order gap (%" PRIu32 ")", frame->ooo_gap);
1563
0
                        }
1564
0
                        if (frame->duplicate)
1565
0
                        {
1566
0
                            transport_item = proto_tree_add_boolean(transport_tree, hf_lbtru_analysis_sm_duplicate, tvb, 0, 0, true);
1567
0
                            proto_item_set_generated(transport_item);
1568
0
                            expert_add_info(pinfo, transport_item, &ei_lbtru_analysis_sm_dup);
1569
0
                        }
1570
0
                        break;
1571
0
                    case LBTRU_PACKET_TYPE_NAK:
1572
0
                        if (frame->previous_type_frame != 0)
1573
0
                        {
1574
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_prev_nak_frame, tvb, 0, 0, frame->previous_type_frame);
1575
0
                            proto_item_set_generated(transport_item);
1576
0
                        }
1577
0
                        if (frame->next_type_frame != 0)
1578
0
                        {
1579
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_next_nak_frame, tvb, 0, 0, frame->next_type_frame);
1580
0
                            proto_item_set_generated(transport_item);
1581
0
                        }
1582
0
                        break;
1583
0
                    case LBTRU_PACKET_TYPE_NCF:
1584
0
                        if (frame->previous_type_frame != 0)
1585
0
                        {
1586
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_prev_ncf_frame, tvb, 0, 0, frame->previous_type_frame);
1587
0
                            proto_item_set_generated(transport_item);
1588
0
                        }
1589
0
                        if (frame->next_type_frame != 0)
1590
0
                        {
1591
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_next_ncf_frame, tvb, 0, 0, frame->next_type_frame);
1592
0
                            proto_item_set_generated(transport_item);
1593
0
                        }
1594
0
                        break;
1595
0
                    case LBTRU_PACKET_TYPE_ACK:
1596
0
                        if (frame->previous_type_frame != 0)
1597
0
                        {
1598
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_prev_ack_frame, tvb, 0, 0, frame->previous_type_frame);
1599
0
                            proto_item_set_generated(transport_item);
1600
0
                        }
1601
0
                        if (frame->next_type_frame != 0)
1602
0
                        {
1603
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_next_ack_frame, tvb, 0, 0, frame->next_type_frame);
1604
0
                            proto_item_set_generated(transport_item);
1605
0
                        }
1606
0
                        break;
1607
0
                    case LBTRU_PACKET_TYPE_CREQ:
1608
0
                        if (frame->previous_type_frame != 0)
1609
0
                        {
1610
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_prev_creq_frame, tvb, 0, 0, frame->previous_type_frame);
1611
0
                            proto_item_set_generated(transport_item);
1612
0
                        }
1613
0
                        if (frame->next_type_frame != 0)
1614
0
                        {
1615
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_next_creq_frame, tvb, 0, 0, frame->next_type_frame);
1616
0
                            proto_item_set_generated(transport_item);
1617
0
                        }
1618
0
                        break;
1619
0
                    case LBTRU_PACKET_TYPE_RST:
1620
0
                        if (frame->previous_type_frame != 0)
1621
0
                        {
1622
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_prev_rst_frame, tvb, 0, 0, frame->previous_type_frame);
1623
0
                            proto_item_set_generated(transport_item);
1624
0
                        }
1625
0
                        if (frame->next_type_frame != 0)
1626
0
                        {
1627
0
                            transport_item = proto_tree_add_uint(transport_tree, hf_lbtru_analysis_next_rst_frame, tvb, 0, 0, frame->next_type_frame);
1628
0
                            proto_item_set_generated(transport_item);
1629
0
                        }
1630
0
                        break;
1631
0
                    default:
1632
0
                        break;
1633
0
                }
1634
0
            }
1635
0
        }
1636
0
    }
1637
0
    if (tapinfo->transport != NULL)
1638
0
    {
1639
0
        tap_queue_packet(lbtru_tap_handle, pinfo, (void *) tapinfo);
1640
0
    }
1641
0
    return (total_dissected_len);
1642
0
}
1643
1644
static bool test_lbtru_packet(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * user_data)
1645
881
{
1646
881
    bool valid_packet = false;
1647
1648
    /* Must be a UDP packet. */
1649
881
    if (pinfo->ptype != PT_UDP)
1650
1
    {
1651
1
        return false;
1652
1
    }
1653
    /* Destination address must be IPV4 and 4 bytes in length. */
1654
880
    if ((pinfo->dst.type != AT_IPv4) || (pinfo->dst.len != 4))
1655
880
    {
1656
880
        return false;
1657
880
    }
1658
1659
0
    if (lbtru_use_tag)
1660
0
    {
1661
0
        if (lbtru_tag_find(pinfo) != NULL)
1662
0
        {
1663
0
            valid_packet = true;
1664
0
        }
1665
0
    }
1666
0
    else
1667
0
    {
1668
        /*
1669
            Source port must be in the source port range and destination port must be in the receiver port range,
1670
            or vice-versa.
1671
        */
1672
0
        if (((pinfo->destport >= lbtru_source_port_low)
1673
0
             && (pinfo->destport <= lbtru_source_port_high)
1674
0
             && (pinfo->srcport >= lbtru_receiver_port_low)
1675
0
             && (pinfo->srcport <= lbtru_receiver_port_high))
1676
0
            || ((pinfo->destport >= lbtru_receiver_port_low)
1677
0
                && (pinfo->destport <= lbtru_receiver_port_high)
1678
0
                && (pinfo->srcport >= lbtru_source_port_low)
1679
0
                && (pinfo->srcport <= lbtru_source_port_high)))
1680
0
        {
1681
            /* One of ours. */
1682
0
            valid_packet = true;
1683
0
        }
1684
0
    }
1685
0
    if (valid_packet)
1686
0
    {
1687
0
        dissect_lbtru(tvb, pinfo, tree, user_data);
1688
0
        return true;
1689
0
    }
1690
    /* Not one of ours. */
1691
0
    return false;
1692
0
}
1693
1694
/* Register all the bits needed with the filtering engine */
1695
void proto_register_lbtru(void)
1696
15
{
1697
15
    static hf_register_info hf[] =
1698
15
    {
1699
15
        { &hf_lbtru_channel,
1700
15
            { "Channel", "lbtru.channel", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1701
15
        { &hf_lbtru_channel_id,
1702
15
            { "Channel ID", "lbtru.channel.channel", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1703
15
        { &hf_lbtru_channel_client,
1704
15
            { "Channel Client", "lbtru.channel.client", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1705
15
        { &hf_lbtru_tag,
1706
15
            { "Tag", "lbtru.tag", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1707
15
        { &hf_lbtru_hdr,
1708
15
            { "Header", "lbtru.hdr", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1709
15
        { &hf_lbtru_hdr_ver,
1710
15
            { "Version", "lbtru.hdr.ver", FT_UINT8, BASE_DEC, NULL, LBTRU_HDR_VER_VER_MASK, NULL, HFILL } },
1711
15
        { &hf_lbtru_hdr_type,
1712
15
            { "Type", "lbtru.hdr.type", FT_UINT8, BASE_HEX, VALS(lbtru_packet_type), LBTRU_HDR_VER_TYPE_MASK, NULL, HFILL } },
1713
15
        { &hf_lbtru_hdr_next_hdr,
1714
15
            { "Next Header", "lbtru.hdr.next_hdr", FT_UINT8, BASE_HEX, VALS(lbtru_next_header), 0x0, NULL, HFILL } },
1715
15
        { &hf_lbtru_hdr_res,
1716
15
            { "Reserved", "lbtru.hdr.res", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1717
15
        { &hf_lbtru_hdr_flags,
1718
15
            { "Flags", "lbtru.hdr.flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1719
15
        { &hf_lbtru_hdr_flags_rx,
1720
15
            { "Retransmission", "lbtru.hdr.flags.rx", FT_BOOLEAN, L_LBTRU_HDR_T_FLAGS_OR_RES * 8, TFS(&tfs_set_notset), LBTRU_RETRANSMISSION_FLAG, NULL, HFILL } },
1721
15
        { &hf_lbtru_hdr_flags_syn,
1722
15
            { "SYN", "lbtru.hdr.flags.syn", FT_BOOLEAN, L_LBTRU_HDR_T_FLAGS_OR_RES * 8, TFS(&tfs_set_notset), LBTRU_SM_SYN_FLAG, NULL, HFILL } },
1723
15
        { &hf_lbtru_hdr_request,
1724
15
            { "Request", "lbtru.hdr.request", FT_UINT16, BASE_HEX, VALS(lbtru_creq_request), 0x0, NULL, HFILL } },
1725
15
        { &hf_lbtru_hdr_reason,
1726
15
            { "Reason", "lbtru.hdr.reason", FT_UINT16, BASE_HEX, VALS(lbtru_rst_reason), 0x0, NULL, HFILL } },
1727
15
        { &hf_lbtru_data,
1728
15
            { "Data Header", "lbtru.data", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1729
15
        { &hf_lbtru_data_sqn,
1730
15
            { "Sequence Number", "lbtru.data.sqn", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1731
15
        { &hf_lbtru_data_trail_sqn,
1732
15
            { "Trailing Edge Sequence Number", "lbtru.data.trail", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1733
15
        { &hf_lbtru_sm,
1734
15
            { "Session Message Header", "lbtru.sm", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1735
15
        { &hf_lbtru_sm_sqn,
1736
15
            { "Sequence Number", "lbtru.sm.sqn", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1737
15
        { &hf_lbtru_sm_lead_sqn,
1738
15
            { "Leading Edge Sequence Number", "lbtru.sm.lead", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1739
15
        { &hf_lbtru_sm_trail_sqn,
1740
15
            { "Trailing Edge Sequence Number", "lbtru.sm.trail", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1741
15
        { &hf_lbtru_nak,
1742
15
            { "NAK Header", "lbtru.nak", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1743
15
        { &hf_lbtru_nak_num,
1744
15
            { "Number of NAKs", "lbtru.nak.num", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1745
15
        { &hf_lbtru_nak_format,
1746
15
            { "Format", "lbtru.nak.format", FT_UINT16, BASE_DEC, VALS(lbtru_nak_format), LBTRU_NAK_HDR_FORMAT_MASK, NULL, HFILL } },
1747
15
        { &hf_lbtru_nak_list,
1748
15
            { "NAK List", "lbtru.nak.list", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1749
15
        { &hf_lbtru_nak_list_nak,
1750
15
            { "NAK", "lbtru.nak.list.nak", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } },
1751
15
        { &hf_lbtru_ncf,
1752
15
            { "NAK Confirmation Header", "lbtru.ncf", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1753
15
        { &hf_lbtru_ncf_trail_sqn,
1754
15
            { "Trailing Edge Sequence Number", "lbtru.ncf.trail", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1755
15
        { &hf_lbtru_ncf_num,
1756
15
            { "Number of Individual NCFs", "lbtru.ncf.num", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1757
15
        { &hf_lbtru_ncf_reserved,
1758
15
            { "Reserved", "lbtru.ncf.reserved", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1759
15
        { &hf_lbtru_ncf_reason,
1760
15
            { "Reason", "lbtru.ncf.reason", FT_UINT8, BASE_HEX, VALS(lbtru_ncf_reason), LBTRU_NCF_HDR_REASON_MASK, NULL, HFILL } },
1761
15
        { &hf_lbtru_ncf_format,
1762
15
            { "Format", "lbtru.ncf.format", FT_UINT8, BASE_HEX, VALS(lbtru_ncf_format), LBTRU_NCF_HDR_FORMAT_MASK, NULL, HFILL } },
1763
15
        { &hf_lbtru_ncf_list,
1764
15
            { "NCF List", "lbtru.ncf.list", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1765
15
        { &hf_lbtru_ncf_list_ncf,
1766
15
            { "NCF", "lbtru.ncf.list.ncf", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } },
1767
15
        { &hf_lbtru_ack,
1768
15
            { "ACK Header", "lbtru.ack", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1769
15
        { &hf_lbtru_ack_sqn,
1770
15
            { "ACK Sequence Number", "lbtru.ack.sqn", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
1771
15
        { &hf_lbtru_opt_sid,
1772
15
            { "SID Option", "lbtru.opt_sid", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1773
15
        { &hf_lbtru_opt_sid_next_hdr,
1774
15
            { "Next Header", "lbtru.opt_sid.next_hdr", FT_UINT8, BASE_DEC_HEX, VALS(lbtru_next_header), 0x0, NULL, HFILL } },
1775
15
        { &hf_lbtru_opt_sid_hdr_len,
1776
15
            { "Header Length", "lbtru.opt_sid.hdr_len", FT_UINT8, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } },
1777
15
        { &hf_lbtru_opt_sid_flags,
1778
15
            { "Flags", "lbtru.opt_sid.flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1779
15
        { &hf_lbtru_opt_sid_flags_ignore,
1780
15
            { "Ignore", "lbtru.opt_sid.flags.ignore", FT_BOOLEAN, L_LBTRU_BASIC_OPT_T_RES * 8, &(tfs_set_notset), LBTRU_OPT_IGNORE, NULL, HFILL } },
1781
15
        { &hf_lbtru_opt_sid_session_id,
1782
15
            { "Session ID", "lbtru.opt_sid.session_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1783
15
        { &hf_lbtru_opt_cid,
1784
15
            { "CID Option", "lbtru.opt_cid", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1785
15
        { &hf_lbtru_opt_cid_next_hdr,
1786
15
            { "Next Header", "lbtru.opt_cid.next_hdr", FT_UINT8, BASE_DEC_HEX, VALS(lbtru_next_header), 0x0, NULL, HFILL } },
1787
15
        { &hf_lbtru_opt_cid_hdr_len,
1788
15
            { "Header Length", "lbtru.opt_cid.hdr_len", FT_UINT8, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } },
1789
15
        { &hf_lbtru_opt_cid_flags,
1790
15
            { "Flags", "lbtru.opt_cid.flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1791
15
        { &hf_lbtru_opt_cid_flags_ignore,
1792
15
            { "Ignore", "lbtru.opt_cid.flags.ignore", FT_BOOLEAN, L_LBTRU_BASIC_OPT_T_RES * 8, &(tfs_set_notset), LBTRU_OPT_IGNORE, NULL, HFILL } },
1793
15
        { &hf_lbtru_opt_cid_client_id,
1794
15
            { "Client ID", "lbtru.opt_cid.client_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1795
15
        { &hf_lbtru_opt_unknown,
1796
15
            { "Unknown Option", "lbtru.opt_unknown", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1797
15
        { &hf_lbtru_opt_unknown_next_hdr,
1798
15
            { "Next Header", "lbtru.opt_unknown.next_hdr", FT_UINT8, BASE_DEC_HEX, VALS(lbtru_next_header), 0x0, NULL, HFILL } },
1799
15
        { &hf_lbtru_opt_unknown_hdr_len,
1800
15
            { "Header Length", "lbtru.opt_unknown.hdr_len", FT_UINT8, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } },
1801
15
        { &hf_lbtru_analysis,
1802
15
            { "Transport Analysis", "lbtru.analysis", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1803
15
        { &hf_lbtru_analysis_prev_frame,
1804
15
            { "Previous Transport Frame", "lbtru.analysis.prev_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1805
15
        { &hf_lbtru_analysis_prev_data_frame,
1806
15
            { "Previous Transport DATA Frame", "lbtru.analysis.prev_data_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1807
15
        { &hf_lbtru_analysis_prev_sm_frame,
1808
15
            { "Previous Transport SM Frame", "lbtru.analysis.prev_sm_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1809
15
        { &hf_lbtru_analysis_prev_nak_frame,
1810
15
            { "Previous Transport NAK Frame", "lbtru.analysis.prev_nak_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1811
15
        { &hf_lbtru_analysis_prev_ncf_frame,
1812
15
            { "Previous Transport NCF Frame", "lbtru.analysis.prev_ncf_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1813
15
        { &hf_lbtru_analysis_prev_ack_frame,
1814
15
            { "Previous Transport ACK Frame", "lbtru.analysis.prev_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1815
15
        { &hf_lbtru_analysis_prev_creq_frame,
1816
15
            { "Previous Transport CREQ Frame", "lbtru.analysis.prev_creq_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1817
15
        { &hf_lbtru_analysis_prev_rst_frame,
1818
15
            { "Previous Transport RST Frame", "lbtru.analysis.prev_rst_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1819
15
        { &hf_lbtru_analysis_next_frame,
1820
15
            { "Next Transport Frame", "lbtru.analysis.next_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1821
15
        { &hf_lbtru_analysis_next_data_frame,
1822
15
            { "Next Transport DATA Frame", "lbtru.analysis.next_data_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1823
15
        { &hf_lbtru_analysis_next_sm_frame,
1824
15
            { "Next Transport SM Frame", "lbtru.analysis.next_sm_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1825
15
        { &hf_lbtru_analysis_next_nak_frame,
1826
15
            { "Next Transport NAK Frame", "lbtru.analysis.next_nak_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1827
15
        { &hf_lbtru_analysis_next_ncf_frame,
1828
15
            { "Next Transport NCF Frame", "lbtru.analysis.next_ncf_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1829
15
        { &hf_lbtru_analysis_next_ack_frame,
1830
15
            { "Next Transport ACK Frame", "lbtru.analysis.next_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1831
15
        { &hf_lbtru_analysis_next_creq_frame,
1832
15
            { "Next Transport CREQ Frame", "lbtru.analysis.next_creq_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1833
15
        { &hf_lbtru_analysis_next_rst_frame,
1834
15
            { "Next Transport RST Frame", "lbtru.analysis.next_rst_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1835
15
        { &hf_lbtru_analysis_sqn,
1836
15
            { "SQN Also in", "lbtru.analysis.sqn", FT_NONE, BASE_NONE, NULL, 0x0, "Sequence number also appears in these frames", HFILL } },
1837
15
        { &hf_lbtru_analysis_sqn_frame,
1838
15
            { "Frame", "lbtru.analysis.sqn.frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1839
15
        { &hf_lbtru_analysis_data_retransmission,
1840
15
            { "Frame is a Data Retransmission", "lbtru.analysis.data_retransmission", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1841
15
        { &hf_lbtru_analysis_data_sqn_gap,
1842
15
            { "Gap in Data Sequence", "lbtru.analysis.data_sqn_gap", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1843
15
        { &hf_lbtru_analysis_data_ooo_gap,
1844
15
            { "Data Sequence Out of Order Gap", "lbtru.analysis.data_ooo_gap", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1845
15
        { &hf_lbtru_analysis_data_duplicate,
1846
15
            { "Duplicate Data Frame", "lbtru.analysis.data_duplicate", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1847
15
        { &hf_lbtru_analysis_sm_sqn_gap,
1848
15
            { "Gap in SM Sequence", "lbtru.analysis.sm_sqn_gap", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1849
15
        { &hf_lbtru_analysis_sm_ooo_gap,
1850
15
            { "SM Sequence Out of Order Gap", "lbtru.analysis.sm_ooo_gap", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1851
15
        { &hf_lbtru_analysis_sm_duplicate,
1852
15
            { "Duplicate SM Frame", "lbtru.analysis.sm_duplicate", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1853
15
    };
1854
15
    static int * ett[] =
1855
15
    {
1856
15
        &ett_lbtru,
1857
15
        &ett_lbtru_channel,
1858
15
        &ett_lbtru_hdr,
1859
15
        &ett_lbtru_hdr_flags,
1860
15
        &ett_lbtru_data,
1861
15
        &ett_lbtru_sm,
1862
15
        &ett_lbtru_nak,
1863
15
        &ett_lbtru_nak_list,
1864
15
        &ett_lbtru_ncf,
1865
15
        &ett_lbtru_ncf_list,
1866
15
        &ett_lbtru_ack,
1867
15
        &ett_lbtru_opt,
1868
15
        &ett_lbtru_opt_sid_flags,
1869
15
        &ett_lbtru_opt_cid_flags,
1870
15
        &ett_lbtru_transport,
1871
15
        &ett_lbtru_transport_sqn,
1872
15
    };
1873
15
    static ei_register_info ei[] =
1874
15
    {
1875
15
        { &ei_lbtru_analysis_unknown_type, { "lbtru.analysis.unknown_type", PI_MALFORMED, PI_ERROR, "Unrecognized type", EXPFILL } },
1876
15
        { &ei_lbtru_analysis_unknown_header, { "lbtru.analysis.unknown_header", PI_MALFORMED, PI_ERROR, "Unrecognized header", EXPFILL } },
1877
15
        { &ei_lbtru_analysis_zero_length_header, { "lbtru.analysis.zero_length_header", PI_MALFORMED, PI_ERROR, "Zero-length header", EXPFILL } },
1878
15
        { &ei_lbtru_analysis_ack, { "lbtru.analysis.ack", PI_SEQUENCE, PI_CHAT, "ACK", EXPFILL } },
1879
15
        { &ei_lbtru_analysis_ncf, { "lbtru.analysis.ncf", PI_SEQUENCE, PI_NOTE, "NCF", EXPFILL } },
1880
15
        { &ei_lbtru_analysis_ncf_ncf, { "lbtru.analysis.ncf.ncf", PI_SEQUENCE, PI_NOTE, "NCF", EXPFILL } },
1881
15
        { &ei_lbtru_analysis_nak, { "lbtru.analysis.nak", PI_SEQUENCE, PI_WARN, "NAK", EXPFILL } },
1882
15
        { &ei_lbtru_analysis_nak_nak, { "lbtru.analysis.nak.nak", PI_SEQUENCE, PI_WARN, "NAK", EXPFILL } },
1883
15
        { &ei_lbtru_analysis_sm, { "lbtru.analysis.sm", PI_SEQUENCE, PI_CHAT, "SM", EXPFILL } },
1884
15
        { &ei_lbtru_analysis_sm_syn, { "lbtru.analysis.sm.syn", PI_SEQUENCE, PI_CHAT, "SM SYN", EXPFILL } },
1885
15
        { &ei_lbtru_analysis_creq, { "lbtru.analysis.creq", PI_SEQUENCE, PI_CHAT, "Connection REQuest", EXPFILL } },
1886
15
        { &ei_lbtru_analysis_rst, { "lbtru.analysis.rst", PI_SEQUENCE, PI_CHAT, "ReSeT", EXPFILL } },
1887
15
        { &ei_lbtru_analysis_data_rx, { "lbtru.analysis.data.rx", PI_SEQUENCE, PI_NOTE, "Data retransmission", EXPFILL } },
1888
15
        { &ei_lbtru_analysis_data_gap, { "lbtru.analysis.data.gap", PI_SEQUENCE, PI_NOTE, "Data sequence gap", EXPFILL } },
1889
15
        { &ei_lbtru_analysis_data_ooo, { "lbtru.analysis.data.ooo", PI_SEQUENCE, PI_NOTE, "Data sequence out of order", EXPFILL } },
1890
15
        { &ei_lbtru_analysis_data_dup, { "lbtru.analysis.data.dup", PI_SEQUENCE, PI_NOTE, "Duplicate data", EXPFILL } },
1891
15
        { &ei_lbtru_analysis_sm_gap, { "lbtru.analysis.sm.gap", PI_SEQUENCE, PI_NOTE, "SM sequence gap", EXPFILL } },
1892
15
        { &ei_lbtru_analysis_sm_ooo, { "lbtru.analysis.sm.ooo", PI_SEQUENCE, PI_NOTE, "SM sequence out of order", EXPFILL } },
1893
15
        { &ei_lbtru_analysis_sm_dup, { "lbtru.analysis.sm.dup", PI_SEQUENCE, PI_NOTE, "Duplicate SM", EXPFILL } },
1894
15
    };
1895
15
    module_t * lbtru_module;
1896
15
    uat_t * tag_uat;
1897
15
    expert_module_t * expert_lbtru;
1898
1899
15
    proto_lbtru = proto_register_protocol("LBT Reliable Unicast Protocol",
1900
15
        "LBT-RU", "lbtru");
1901
1902
15
    proto_register_field_array(proto_lbtru, hf, array_length(hf));
1903
15
    proto_register_subtree_array(ett, array_length(ett));
1904
15
    expert_lbtru = expert_register_protocol(proto_lbtru);
1905
15
    expert_register_field_array(expert_lbtru, ei, array_length(ei));
1906
1907
15
    lbtru_dissector_handle = register_dissector("lbtru", dissect_lbtru, proto_lbtru);
1908
1909
15
    lbtru_tap_handle = register_tap("lbm_lbtru");
1910
1911
15
    lbtru_module = prefs_register_protocol_subtree("29West", proto_lbtru, proto_reg_handoff_lbtru);
1912
15
    prefs_register_uint_preference(lbtru_module,
1913
15
        "source_port_low",
1914
15
        "Source port range low (default " MAKESTRING(LBTRU_DEFAULT_SOURCE_PORT_LOW)")",
1915
15
        "Set the low end of the LBT-RU source UDP port range (context transport_lbtru_port_low)",
1916
15
        10,
1917
15
        &global_lbtru_source_port_low);
1918
1919
15
    prefs_register_uint_preference(lbtru_module,
1920
15
        "source_port_high",
1921
15
        "Source port range high (default " MAKESTRING(LBTRU_DEFAULT_SOURCE_PORT_HIGH)")",
1922
15
        "Set the high end of the LBT-RU source UDP port range (context transport_lbtru_port_high)",
1923
15
        10,
1924
15
        &global_lbtru_source_port_high);
1925
1926
15
    prefs_register_uint_preference(lbtru_module,
1927
15
        "receiver_port_low",
1928
15
        "Receiver port range low (default " MAKESTRING(LBTRU_DEFAULT_RECEIVER_PORT_LOW)")",
1929
15
        "Set the low end of the LBT-RU receiver UDP port range (receiver transport_lbtru_port_low)",
1930
15
        10,
1931
15
        &global_lbtru_receiver_port_low);
1932
1933
15
    prefs_register_uint_preference(lbtru_module,
1934
15
        "receiver_port_high",
1935
15
        "Receiver port range high (default " MAKESTRING(LBTRU_DEFAULT_RECEIVER_PORT_HIGH)")",
1936
15
        "Set the high end of the LBT-RU receiver UDP port range (receiver transport_lbtru_port_high)",
1937
15
        10,
1938
15
        &global_lbtru_receiver_port_high);
1939
1940
15
    lbtru_expert_separate_naks = global_lbtru_expert_separate_naks;
1941
15
    prefs_register_bool_preference(lbtru_module,
1942
15
        "expert_separate_naks",
1943
15
        "Separate NAKs in Expert Info",
1944
15
        "Separate multiple NAKs from a single packet into distinct Expert Info entries",
1945
15
        &global_lbtru_expert_separate_naks);
1946
15
    lbtru_expert_separate_ncfs = global_lbtru_expert_separate_ncfs;
1947
15
    prefs_register_bool_preference(lbtru_module,
1948
15
        "expert_separate_ncfs",
1949
15
        "Separate NCFs in Expert Info",
1950
15
        "Separate multiple NCFs from a single packet into distinct Expert Info entries",
1951
15
        &global_lbtru_expert_separate_ncfs);
1952
1953
15
    lbtru_sequence_analysis = global_lbtru_sequence_analysis;
1954
15
    prefs_register_bool_preference(lbtru_module,
1955
15
        "sequence_analysis",
1956
15
        "Perform Sequence Number Analysis",
1957
15
        "Perform analysis on LBT-RU sequence numbers to determine out-of-order, gaps, loss, etc",
1958
15
        &global_lbtru_sequence_analysis);
1959
1960
15
    prefs_register_bool_preference(lbtru_module,
1961
15
        "use_lbtru_domain",
1962
15
        "Use LBT-RU tag table",
1963
15
        "Use table of LBT-RU tags to decode the packet instead of above values",
1964
15
        &global_lbtru_use_tag);
1965
15
    tag_uat = uat_new("LBT-RU tag definitions",
1966
15
        sizeof(lbtru_tag_entry_t),
1967
15
        "lbtru_domains",
1968
15
        true,
1969
15
        (void * *)&lbtru_tag_entry,
1970
15
        &lbtru_tag_count,
1971
15
        UAT_AFFECTS_DISSECTION,
1972
15
        NULL,
1973
15
        lbtru_tag_copy_cb,
1974
15
        lbtru_tag_update_cb,
1975
15
        lbtru_tag_free_cb,
1976
15
        NULL,
1977
15
        NULL,
1978
15
        lbtru_tag_array);
1979
15
    prefs_register_uat_preference(lbtru_module,
1980
15
        "tnw_lbtru_tags",
1981
15
        "LBT-RU Tags",
1982
15
        "A table to define LBT-RU tags",
1983
15
        tag_uat);
1984
15
}
1985
1986
/* The registration hand-off routine */
1987
void proto_reg_handoff_lbtru(void)
1988
15
{
1989
15
    static bool already_registered = false;
1990
1991
15
    if (!already_registered)
1992
15
    {
1993
15
        dissector_add_for_decode_as_with_preference("udp.port", lbtru_dissector_handle);
1994
15
        heur_dissector_add("udp", test_lbtru_packet, "LBT Reliable Unicast over UDP", "lbtru_udp", proto_lbtru, HEURISTIC_ENABLE);
1995
15
    }
1996
1997
    /* Make sure the low source port is <= the high source port. If not, don't change them. */
1998
15
    if (global_lbtru_source_port_low <= global_lbtru_source_port_high)
1999
15
    {
2000
15
        lbtru_source_port_low = global_lbtru_source_port_low;
2001
15
        lbtru_source_port_high = global_lbtru_source_port_high;
2002
15
    }
2003
2004
    /* Make sure the low receiver port is <= the high receiver port. If not, don't change them. */
2005
15
    if (global_lbtru_receiver_port_low <= global_lbtru_receiver_port_high)
2006
15
    {
2007
15
        lbtru_receiver_port_low = global_lbtru_receiver_port_low;
2008
15
        lbtru_receiver_port_high = global_lbtru_receiver_port_high;
2009
15
    }
2010
2011
15
    lbtru_expert_separate_naks = global_lbtru_expert_separate_naks;
2012
15
    lbtru_expert_separate_ncfs = global_lbtru_expert_separate_ncfs;
2013
2014
15
    lbtru_sequence_analysis = global_lbtru_sequence_analysis;
2015
2016
15
    lbtru_use_tag = global_lbtru_use_tag;
2017
2018
    already_registered = true;
2019
15
}
2020
2021
/*
2022
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2023
 *
2024
 * Local variables:
2025
 * c-basic-offset: 4
2026
 * tab-width: 8
2027
 * indent-tabs-mode: nil
2028
 * End:
2029
 *
2030
 * vi: set shiftwidth=4 tabstop=8 expandtab:
2031
 * :indentSize=4:tabSize=8:noTabs=true:
2032
 */