Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/dissectors/packet-brp.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-brp.c
2
 *
3
 * Wireshark - Network traffic analyzer
4
 * By Gerald Combs <gerald@wireshark.org>
5
 * Copyright 1998 Gerald Combs
6
 *
7
 * SPDX-License-Identifier: GPL-2.0-or-later
8
 */
9
10
/*
11
 * This is a dissector for the BRP (Bandwidth Reservation Protocol). This protocol
12
 * is used by various telecommunications vendors to establish VoD (Video
13
 * On-Demand) sessions between a STB (Set Top Box) at the customer's home and the
14
 * VoD server at the video head-end.
15
 */
16
17
#include "config.h"
18
19
#include <epan/packet.h>
20
#include <epan/expert.h>
21
22
/* Forward declaration we need below */
23
void proto_register_brp(void);
24
void proto_reg_handoff_brp(void);
25
26
0
#define PROTO_TAG_BRP   "BRP"
27
28
/* Wireshark ID of the BRP protocol */
29
static int proto_brp;
30
31
static dissector_handle_t brp_handle;
32
33
static const value_string brp_packettype_names[] = {
34
    {  0, "BRP" },
35
    {  1, "Setup Request - BRC -> BRS" },
36
    {  2, "Setup Response - BRS -> BRC" },
37
    {  3, "Teardown Request - BRC -> BRS" },
38
    {  4, "Teardown Response - BRS -> BRC" },
39
    {  5, "Heartbeat Request - BRS -> BRC" },
40
    {  6, "Heartbeat Response - BRC -> BRS" },
41
    {  7, "Unidirectional Flow Create Request - BRC -> BRS" },
42
    {  8, "Flow Create Response - BRS -> BRC" },
43
    {  9, "Flow Delete Request BRC -> BRS" },
44
    { 10, "Flow Delete Response - BRS -> BRC" },
45
    { 11, "Flow Get Request - BRC -> BRS" },
46
    { 12, "Flow Get Response - BRS -> BRC" },
47
    { 13, "Flow Get Next Request - BRC -> BRS" },
48
    { 14, "Flow Get Next Response - BRS -> BRC" },
49
    { 15, "Flow Abort - BRS -> BRC" },
50
    { 0, NULL }
51
};
52
53
static const value_string brp_stat_vals[] = {
54
    {  0, "OK" },
55
    {  1, "Comm Error - Network connectivity has been lost (Client Message)." },
56
    {  2, "No Bandwidth - There is insufficient bandwidth available in the network to honor the request (Server Message)." },
57
    {  3, "Insufficient Resource - Either there is insufficient memory or resource available to transmit the request or,"
58
           " insufficient resources existed at the server to complete the request. Note that insufficient bandwidth in the"
59
           " network is handled by the previous status value. This is the catchall for all other resource deficiencies"
60
           " (Client/Server Message)." },
61
    {  4, "No Such - The requested flow does not exist (Server Message)." },
62
    {  5, "No Session - There is no active session. The server may return this in the event that the client and server"
63
           " are out of sync. In that eventuality, the client must reestablish its session and recreate any flows that"
64
           " it believes have been lost (Server Message)." },
65
    {  6, "Invalid Argument - One of the input arguments to the call was not valid (Client/Server Message)." },
66
    {  7, "Unreachable - The specified BRS is not reachable (Client Message)." },
67
    {  8, "Internal Error - An internal fault has occurred. This is generally indicative of a fatal condition within"
68
           " the client system (Server Message)." },
69
    {  9, "Already Exists - The flow or session that the client requested already exists (Server Message)." },
70
    { 10, "Flow Removed - The flow was removed or lost due to issues internal to the network (Server Message)." },
71
    { 11, "Invalid Sender - Received packet was from an unknown sender (Server Message)." },
72
    { 12, "Invalid Message - Input message is not defined or malformed (Client/Server Message)." },
73
    { 13, "Unsupported Version - The requested version (in a setup) is not supported (Server Message)." },
74
    { 14, "Pending - The requested operation is proceeding and a status will be returned with the final result"
75
           " shortly (Server Message)." },
76
    { 0, NULL }
77
};
78
79
/* The following hf_* variables are used to hold the Wireshark IDs of
80
* our data fields; they are filled out when we call
81
* proto_register_field_array() in proto_register_brp()
82
*/
83
static int hf_brp_type;
84
static int hf_brp_trans;
85
static int hf_brp_ver;
86
static int hf_brp_stat;
87
static int hf_brp_srcip;
88
static int hf_brp_dstip;
89
static int hf_brp_dstuport;
90
static int hf_brp_mbz;
91
static int hf_brp_bw;
92
static int hf_brp_life;
93
static int hf_brp_flid;
94
static int hf_brp_rmttl;
95
static int hf_brp_fltype;
96
97
/* These are the ids of the subtrees that we may be creating */
98
static int ett_brp;
99
static int ett_brp_type;
100
static int ett_brp_trans;
101
static int ett_brp_ver;
102
static int ett_brp_stat;
103
static int ett_brp_srcip;
104
static int ett_brp_dstip;
105
static int ett_brp_dstuport;
106
static int ett_brp_mbz;
107
static int ett_brp_bw;
108
static int ett_brp_life;
109
static int ett_brp_flid;
110
static int ett_brp_rmttl;
111
static int ett_brp_fltype;
112
113
static expert_field ei_brp_type_unknown;
114
115
static int
116
dissect_brp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
117
0
{
118
119
0
    proto_item *brp_item    = NULL;
120
0
    proto_tree *brp_tree    = NULL;
121
0
    int         offset      = 0;
122
0
    uint8_t     type        = 0;
123
0
    uint8_t     packet_type = tvb_get_uint8(tvb, 0);
124
125
    /* If there is a "tree" requested, we handle that request. */
126
127
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_BRP);
128
    /* We add some snazzy bizness to the info field to quickly ascertain
129
        what type of message was sent to/from the BRS/BRC. */
130
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Message Type - %s",
131
0
            val_to_str(packet_type, brp_packettype_names, "Unknown (0x%02x)"));
132
133
    /* This call adds our tree to the main dissection tree. */
134
135
0
    if (tree) { /* we are being asked for details */
136
137
        /* Here we add our tree/subtree so we can have a collapsible branch. */
138
0
        brp_item = proto_tree_add_item( tree, proto_brp, tvb, 0, -1, ENC_NA );
139
0
        brp_tree = proto_item_add_subtree( brp_item, ett_brp);
140
141
        /* We use tvb_get_uint8 to get our type value out. */
142
0
        type = tvb_get_uint8(tvb, offset);
143
0
        offset += 0;
144
145
0
        brp_item = proto_tree_add_item( brp_tree, hf_brp_type, tvb, offset, 1, ENC_BIG_ENDIAN );
146
0
        offset += 1;
147
148
        /* Now let's break down each packet and display it in the collapsible branch */
149
0
        switch(type)
150
0
        {
151
0
        case 1: /* Setup Request */
152
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
153
0
            offset += 3;
154
0
            proto_tree_add_item( brp_tree, hf_brp_ver, tvb, offset, 4, ENC_BIG_ENDIAN );
155
0
            offset +=4;
156
0
            break;
157
158
0
        case 2: /* Setup Response */
159
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
160
0
            offset += 3;
161
0
            proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
162
0
            offset +=4;
163
0
            break;
164
165
0
        case 3: /* Teardown Request */
166
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
167
0
            offset += 3;
168
0
            break;
169
170
0
        case 4: /* Teardown Response */
171
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
172
0
            offset += 3;
173
0
            break;
174
175
0
        case 5: /* Heartbeat Request */
176
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
177
0
            offset += 3;
178
0
            break;
179
180
0
        case 6: /* Heartbeat Response */
181
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
182
0
            offset += 3;
183
0
            break;
184
185
0
        case 7: /* Uni Flow Create Request */
186
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
187
0
            offset += 3;
188
0
            proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
189
0
            offset +=4;
190
0
            proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
191
0
            offset +=4;
192
0
            proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
193
0
            offset +=2;
194
0
            proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
195
0
            offset +=2;
196
0
            proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 4, ENC_BIG_ENDIAN );
197
0
            offset +=4;
198
0
            proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
199
0
            offset +=4;
200
0
            break;
201
202
0
        case 8: /* Flow Create Response */
203
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
204
0
            offset += 3;
205
0
            proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
206
0
            offset +=4;
207
0
            proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
208
0
            offset +=4;
209
0
            break;
210
211
0
        case 9: /* Flow Delete Request */
212
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
213
0
            offset += 3;
214
0
            proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
215
0
            offset +=4;
216
0
            break;
217
218
0
        case 10: /* Flow Delete Response */
219
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
220
0
            offset += 3;
221
0
            proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
222
0
            offset +=4;
223
0
            break;
224
225
0
        case 11: /* Flow Get Request */
226
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
227
0
            offset += 3;
228
0
            proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
229
0
            offset +=4;
230
0
            break;
231
232
0
        case 12: /* Flow Get Response */
233
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
234
0
            offset += 3;
235
0
            proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
236
0
            offset +=4;
237
0
            proto_tree_add_item( brp_tree, hf_brp_rmttl, tvb, offset, 4, ENC_BIG_ENDIAN );
238
0
            offset +=4;
239
0
            proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
240
0
            offset +=4;
241
0
            proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
242
0
            offset +=4;
243
0
            proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
244
0
            offset +=2;
245
0
            proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
246
0
            offset +=2;
247
0
            proto_tree_add_item( brp_tree, hf_brp_fltype, tvb, offset, 1, ENC_BIG_ENDIAN );
248
0
            offset +=1;
249
0
            proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 3, ENC_BIG_ENDIAN );
250
0
            offset +=3;
251
0
            proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
252
0
            offset +=4;
253
0
            proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
254
0
            offset +=4;
255
0
            break;
256
257
0
        case 13: /* Flow Get Next Request */
258
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
259
0
            offset += 3;
260
0
            proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
261
0
            offset +=4;
262
0
            break;
263
264
0
        case 14: /* Flow Get Next Response */
265
0
            proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
266
0
            offset += 3;
267
0
            proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
268
0
            offset +=4;
269
0
            proto_tree_add_item( brp_tree, hf_brp_rmttl, tvb, offset, 4, ENC_BIG_ENDIAN );
270
0
            offset +=4;
271
0
            proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
272
0
            offset +=4;
273
0
            proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
274
0
            offset +=4;
275
0
            proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
276
0
            offset +=2;
277
0
            proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
278
0
            offset +=2;
279
0
            proto_tree_add_item( brp_tree, hf_brp_fltype, tvb, offset, 1, ENC_BIG_ENDIAN );
280
0
            offset +=1;
281
0
            proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 3, ENC_BIG_ENDIAN );
282
0
            offset +=3;
283
0
            proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
284
0
            offset +=4;
285
0
            proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
286
0
            offset +=4;
287
0
            break;
288
289
0
        case 15: /* Flow Abort */
290
0
            proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 3, ENC_BIG_ENDIAN );
291
0
            offset +=3;
292
0
            proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
293
0
            offset +=4;
294
0
            break;
295
296
0
        default:
297
            /* Invalid type */
298
0
            expert_add_info(pinfo, brp_item, &ei_brp_type_unknown);
299
0
            break;
300
0
        }
301
302
0
    }
303
0
return offset;
304
0
}
305
306
/*--- proto_register_brp ----------------------------------------------*/
307
void proto_register_brp (void)
308
14
{
309
14
    expert_module_t* expert_brp;
310
311
    /* A data field is something you can search/filter on.
312
    *
313
    * We create a structure to register our fields. It consists of an
314
    * array of hf_register_info structures, each of which are of the format
315
    * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
316
    */
317
14
    static hf_register_info hf[] = {
318
14
        { &hf_brp_type,
319
14
          { "Type", "brp.type", FT_UINT8, BASE_DEC, VALS(brp_packettype_names), 0x0,
320
14
            NULL, HFILL }},
321
14
        { &hf_brp_trans,
322
14
          { "Transaction ID", "brp.trans", FT_UINT24, BASE_DEC, NULL, 0x0,
323
14
            NULL, HFILL }},
324
14
        { &hf_brp_ver,
325
14
          { "Version", "brp.ver", FT_UINT32, BASE_DEC, NULL, 0x0,
326
14
            NULL, HFILL }},
327
14
        { &hf_brp_stat,
328
14
          { "Status", "brp.stat", FT_UINT32, BASE_DEC, VALS(brp_stat_vals), 0x0,
329
14
            NULL, HFILL }},
330
14
        { &hf_brp_srcip,
331
14
          { "Source IP Address", "brp.srcip", FT_IPv4, BASE_NONE, NULL, 0x0,
332
14
            NULL, HFILL }},
333
14
        { &hf_brp_dstip,
334
14
          { "Destination IP Address", "brp.dstip", FT_IPv4, BASE_NONE, NULL, 0x0,
335
14
            NULL, HFILL }},
336
14
        { &hf_brp_dstuport,
337
14
          { "Destination UDP Port", "brp.dstuport", FT_UINT16, BASE_PT_UDP, NULL, 0x0,
338
14
            NULL, HFILL }},
339
14
        { &hf_brp_mbz,
340
14
          { "MBZ", "brp.mbz", FT_UINT24, BASE_DEC, NULL, 0x0,
341
14
            NULL, HFILL }},
342
14
        { &hf_brp_bw,
343
14
          { "Bandwidth - Kbytes/sec", "brp.bw", FT_UINT32, BASE_DEC, NULL, 0x0,
344
14
            NULL, HFILL }},
345
14
        { &hf_brp_life,
346
14
          { "Lifetime", "brp.life", FT_UINT32, BASE_DEC, NULL, 0x0,
347
14
            NULL, HFILL }},
348
14
        { &hf_brp_flid,
349
14
          { "Flow Identifier", "brp.flid", FT_UINT32, BASE_DEC, NULL, 0x0,
350
14
            NULL, HFILL }},
351
14
        { &hf_brp_fltype,
352
14
          { "Flow Type", "brp.fltype", FT_UINT8, BASE_DEC, NULL, 0x0,
353
14
            NULL, HFILL }},
354
14
        { &hf_brp_rmttl,
355
14
          { "Remaining TTL", "brp.rmttl", FT_UINT32, BASE_DEC, NULL, 0x0,
356
14
            NULL, HFILL }},
357
14
    };
358
14
    static int *ett[] = {
359
14
        &ett_brp,
360
14
        &ett_brp_type,
361
14
        &ett_brp_trans,
362
14
        &ett_brp_ver,
363
14
        &ett_brp_stat,
364
14
        &ett_brp_srcip,
365
14
        &ett_brp_dstip,
366
14
        &ett_brp_dstuport,
367
14
        &ett_brp_mbz,
368
14
        &ett_brp_bw,
369
14
        &ett_brp_life,
370
14
        &ett_brp_flid,
371
14
        &ett_brp_fltype,
372
14
        &ett_brp_rmttl
373
374
14
    };
375
376
14
    static ei_register_info ei[] = {
377
14
        { &ei_brp_type_unknown, { "brp.type.unknown", PI_UNDECODED, PI_WARN, "Unknown packet type", EXPFILL }},
378
14
    };
379
380
14
    proto_brp = proto_register_protocol ("BRP Protocol", "BRP", "brp");
381
14
    proto_register_field_array (proto_brp, hf, array_length (hf));
382
14
    proto_register_subtree_array (ett, array_length (ett));
383
14
    expert_brp = expert_register_protocol(proto_brp);
384
14
    expert_register_field_array(expert_brp, ei, array_length(ei));
385
386
14
    brp_handle = register_dissector("brp", dissect_brp, proto_brp);
387
14
}
388
389
/*--- proto_reg_handoff_brp -------------------------------------------*/
390
void proto_reg_handoff_brp(void)
391
14
{
392
14
    dissector_add_for_decode_as_with_preference("udp.port", brp_handle);
393
14
}
394
395
/*
396
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
397
 *
398
 * Local variables:
399
 * c-basic-offset: 4
400
 * tab-width: 8
401
 * indent-tabs-mode: nil
402
 * End:
403
 *
404
 * vi: set shiftwidth=4 tabstop=8 expandtab:
405
 * :indentSize=4:tabSize=8:noTabs=true:
406
 */