Coverage Report

Created: 2026-06-30 07:22

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