3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
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.
19 #include <epan/packet.h>
20 #include <epan/expert.h>
22 /* Forward declaration we need below */
23 void proto_register_brp(void);
24 void proto_reg_handoff_brp(void);
26 #define PROTO_TAG_BRP "BRP"
28 /* Wireshark ID of the BRP protocol */
31 static dissector_handle_t brp_handle
;
33 static const value_string brp_packettype_names
[] = {
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" },
53 static const value_string brp_stat_vals
[] = {
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)." },
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()
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
;
92 static int hf_brp_life
;
93 static int hf_brp_flid
;
94 static int hf_brp_rmttl
;
95 static int hf_brp_fltype
;
97 /* These are the ids of the subtrees that we may be creating */
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
;
113 static expert_field ei_brp_type_unknown
;
116 dissect_brp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
119 proto_item
*brp_item
= NULL
;
120 proto_tree
*brp_tree
= NULL
;
123 uint8_t packet_type
= tvb_get_uint8(tvb
, 0);
125 /* If there is a "tree" requested, we handle that request. */
127 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 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Message Type - %s",
131 val_to_str(packet_type
, brp_packettype_names
, "Unknown (0x%02x)"));
133 /* This call adds our tree to the main dissection tree. */
135 if (tree
) { /* we are being asked for details */
137 /* Here we add our tree/subtree so we can have a collapsible branch. */
138 brp_item
= proto_tree_add_item( tree
, proto_brp
, tvb
, 0, -1, ENC_NA
);
139 brp_tree
= proto_item_add_subtree( brp_item
, ett_brp
);
141 /* We use tvb_get_uint8 to get our type value out. */
142 type
= tvb_get_uint8(tvb
, offset
);
145 brp_item
= proto_tree_add_item( brp_tree
, hf_brp_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
148 /* Now let's break down each packet and display it in the collapsible branch */
151 case 1: /* Setup Request */
152 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
154 proto_tree_add_item( brp_tree
, hf_brp_ver
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
158 case 2: /* Setup Response */
159 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
161 proto_tree_add_item( brp_tree
, hf_brp_stat
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
165 case 3: /* Teardown Request */
166 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
170 case 4: /* Teardown Response */
171 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
175 case 5: /* Heartbeat Request */
176 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
180 case 6: /* Heartbeat Response */
181 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
185 case 7: /* Uni Flow Create Request */
186 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
188 proto_tree_add_item( brp_tree
, hf_brp_srcip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
190 proto_tree_add_item( brp_tree
, hf_brp_dstip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
192 proto_tree_add_item( brp_tree
, hf_brp_dstuport
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
194 proto_tree_add_item( brp_tree
, hf_brp_mbz
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
196 proto_tree_add_item( brp_tree
, hf_brp_bw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
198 proto_tree_add_item( brp_tree
, hf_brp_life
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
202 case 8: /* Flow Create Response */
203 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
205 proto_tree_add_item( brp_tree
, hf_brp_stat
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
207 proto_tree_add_item( brp_tree
, hf_brp_flid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
211 case 9: /* Flow Delete Request */
212 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
214 proto_tree_add_item( brp_tree
, hf_brp_flid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
218 case 10: /* Flow Delete Response */
219 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
221 proto_tree_add_item( brp_tree
, hf_brp_stat
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
225 case 11: /* Flow Get Request */
226 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
228 proto_tree_add_item( brp_tree
, hf_brp_flid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
232 case 12: /* Flow Get Response */
233 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
235 proto_tree_add_item( brp_tree
, hf_brp_stat
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
237 proto_tree_add_item( brp_tree
, hf_brp_rmttl
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
239 proto_tree_add_item( brp_tree
, hf_brp_srcip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
241 proto_tree_add_item( brp_tree
, hf_brp_dstip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
243 proto_tree_add_item( brp_tree
, hf_brp_dstuport
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
245 proto_tree_add_item( brp_tree
, hf_brp_mbz
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
247 proto_tree_add_item( brp_tree
, hf_brp_fltype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
249 proto_tree_add_item( brp_tree
, hf_brp_bw
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
251 proto_tree_add_item( brp_tree
, hf_brp_life
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
253 proto_tree_add_item( brp_tree
, hf_brp_flid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
257 case 13: /* Flow Get Next Request */
258 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
260 proto_tree_add_item( brp_tree
, hf_brp_flid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
264 case 14: /* Flow Get Next Response */
265 proto_tree_add_item( brp_tree
, hf_brp_trans
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
267 proto_tree_add_item( brp_tree
, hf_brp_stat
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
269 proto_tree_add_item( brp_tree
, hf_brp_rmttl
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
271 proto_tree_add_item( brp_tree
, hf_brp_srcip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
273 proto_tree_add_item( brp_tree
, hf_brp_dstip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
275 proto_tree_add_item( brp_tree
, hf_brp_dstuport
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
277 proto_tree_add_item( brp_tree
, hf_brp_mbz
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
279 proto_tree_add_item( brp_tree
, hf_brp_fltype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
281 proto_tree_add_item( brp_tree
, hf_brp_bw
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
283 proto_tree_add_item( brp_tree
, hf_brp_life
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
285 proto_tree_add_item( brp_tree
, hf_brp_flid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
289 case 15: /* Flow Abort */
290 proto_tree_add_item( brp_tree
, hf_brp_mbz
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
292 proto_tree_add_item( brp_tree
, hf_brp_flid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
298 expert_add_info(pinfo
, brp_item
, &ei_brp_type_unknown
);
306 /*--- proto_register_brp ----------------------------------------------*/
307 void proto_register_brp (void)
309 expert_module_t
* expert_brp
;
311 /* A data field is something you can search/filter on.
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}}.
317 static hf_register_info hf
[] = {
319 { "Type", "brp.type", FT_UINT8
, BASE_DEC
, VALS(brp_packettype_names
), 0x0,
322 { "Transaction ID", "brp.trans", FT_UINT24
, BASE_DEC
, NULL
, 0x0,
325 { "Version", "brp.ver", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
328 { "Status", "brp.stat", FT_UINT32
, BASE_DEC
, VALS(brp_stat_vals
), 0x0,
331 { "Source IP Address", "brp.srcip", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
334 { "Destination IP Address", "brp.dstip", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
337 { "Destination UDP Port", "brp.dstuport", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
340 { "MBZ", "brp.mbz", FT_UINT24
, BASE_DEC
, NULL
, 0x0,
343 { "Bandwidth - Kbytes/sec", "brp.bw", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
346 { "Lifetime", "brp.life", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
349 { "Flow Identifier", "brp.flid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
352 { "Flow Type", "brp.fltype", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
355 { "Remaining TTL", "brp.rmttl", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
358 static int *ett
[] = {
376 static ei_register_info ei
[] = {
377 { &ei_brp_type_unknown
, { "brp.type.unknown", PI_UNDECODED
, PI_WARN
, "Unknown packet type", EXPFILL
}},
380 proto_brp
= proto_register_protocol ("BRP Protocol", "BRP", "brp");
381 proto_register_field_array (proto_brp
, hf
, array_length (hf
));
382 proto_register_subtree_array (ett
, array_length (ett
));
383 expert_brp
= expert_register_protocol(proto_brp
);
384 expert_register_field_array(expert_brp
, ei
, array_length(ei
));
386 brp_handle
= register_dissector("brp", dissect_brp
, proto_brp
);
389 /*--- proto_reg_handoff_brp -------------------------------------------*/
390 void proto_reg_handoff_brp(void)
392 dissector_add_for_decode_as_with_preference("udp.port", brp_handle
);
396 * Editor modelines - https://www.wireshark.org/tools/modelines.html
401 * indent-tabs-mode: nil
404 * vi: set shiftwidth=4 tabstop=8 expandtab:
405 * :indentSize=4:tabSize=8:noTabs=true: