5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 * This is a dissector for the BRP (Bandwidth Reservation Protocol). This protocol
26 * is used by various telecommunications vendors to establish VoD (Video
27 * On-Demand) sessions between a STB (Set Top Box) at the customer's home and the
28 * VoD server at the video head-end.
34 #include <epan/packet.h>
35 #include <epan/expert.h>
36 #include <epan/prefs.h>
38 /* Forward declaration we need below */
39 void proto_reg_handoff_brp(void);
41 #define PROTO_TAG_BRP "BRP"
43 /* Wireshark ID of the BRP protocol */
44 static int proto_brp = -1;
46 /*static int global_brp_port = 1958; *//* The port is registered for another protocol */
48 static const value_string brp_packettype_names[] = {
50 { 1, "Setup Request - BRC -> BRS" },
51 { 2, "Setup Response - BRS -> BRC" },
52 { 3, "Teardown Request - BRC -> BRS" },
53 { 4, "Teardown Response - BRS -> BRC" },
54 { 5, "Heartbeat Request - BRS -> BRC" },
55 { 6, "Heartbeat Response - BRC -> BRS" },
56 { 7, "Unidirectional Flow Create Request - BRC -> BRS" },
57 { 8, "Flow Create Response - BRS -> BRC" },
58 { 9, "Flow Delete Request BRC -> BRS" },
59 { 10, "Flow Delete Response - BRS -> BRC" },
60 { 11, "Flow Get Request - BRC -> BRS" },
61 { 12, "Flow Get Response - BRS -> BRC" },
62 { 13, "Flow Get Next Request - BRC -> BRS" },
63 { 14, "Flow Get Next Response - BRS -> BRC" },
64 { 15, "Flow Abort - BRS -> BRC" },
68 static const value_string brp_stat_vals[] = {
70 { 1, "Comm Error - Network connectivity has been lost (Client Message)." },
71 { 2, "No Bandwidth - There is insufficient bandwidth available in the network to honor the request (Server Message)." },
72 { 3, "Insufficient Resource - Either there is insufficient memory or resource available to transmit the request or,"
73 " insufficient resources existed at the server to complete the request. Note that insufficient bandwidth in the"
74 " network is handled by the previous status value. This is the catchall for all other resource deficiencies"
75 " (Client/Server Message)." },
76 { 4, "No Such - The requested flow does not exist (Server Message)." },
77 { 5, "No Session - There is no active session. The server may return this in the event that the client and server"
78 " are out of sync. In that eventuality, the client must reestablish its session and recreate any flows that"
79 " it believes have been lost (Server Message)." },
80 { 6, "Invalid Argument - One of the input arguments to the call was not valid (Client/Server Message)." },
81 { 7, "Unreachable - The specified BRS is not reachable (Client Message)." },
82 { 8, "Internal Error - An internal fault has occurred. This is generally indicative of a fatal condition within"
83 " the client system (Server Message)." },
84 { 9, "Already Exists - The flow or session that the client requested already exists (Server Message)." },
85 { 10, "Flow Removed - The flow was removed or lost due to issues internal to the network (Server Message)." },
86 { 11, "Invalid Sender - Received packet was from an unknown sender (Server Message)." },
87 { 12, "Invalid Message - Input message is not defined or malformed (Client/Server Message)." },
88 { 13, "Unsupported Version - The requested version (in a setup) is not supported (Server Message)." },
89 { 14, "Pending - The requested operation is proceeding and a status will be returned with the final result"
90 " shortly (Server Message)." },
94 /* The following hf_* variables are used to hold the Wireshark IDs of
95 * our data fields; they are filled out when we call
96 * proto_register_field_array() in proto_register_brp()
98 static gint hf_brp_type = -1;
99 static gint hf_brp_trans = -1;
100 static gint hf_brp_ver = -1;
101 static gint hf_brp_stat = -1;
102 static gint hf_brp_srcip = -1;
103 static gint hf_brp_dstip = -1;
104 static gint hf_brp_dstuport = -1;
105 static gint hf_brp_mbz = -1;
106 static gint hf_brp_bw = -1;
107 static gint hf_brp_life = -1;
108 static gint hf_brp_flid = -1;
109 static gint hf_brp_rmttl = -1;
110 static gint hf_brp_fltype = -1;
112 /* These are the ids of the subtrees that we may be creating */
113 static gint ett_brp = -1;
114 static gint ett_brp_type = -1;
115 static gint ett_brp_trans = -1;
116 static gint ett_brp_ver = -1;
117 static gint ett_brp_stat = -1;
118 static gint ett_brp_srcip = -1;
119 static gint ett_brp_dstip = -1;
120 static gint ett_brp_dstuport = -1;
121 static gint ett_brp_mbz = -1;
122 static gint ett_brp_bw = -1;
123 static gint ett_brp_life = -1;
124 static gint ett_brp_flid = -1;
125 static gint ett_brp_rmttl = -1;
126 static gint ett_brp_fltype = -1;
129 static guint global_brp_port = 0;
132 dissect_brp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
135 proto_item *brp_item = NULL;
136 proto_tree *brp_tree = NULL;
139 guint8 packet_type = tvb_get_guint8(tvb, 0);
141 /* If there is a "tree" requested, we handle that request. */
143 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_BRP);
144 if(check_col(pinfo->cinfo,COL_INFO)){
145 /* We add some snazzy bizness to the info field to quickly ascertain
146 what type of message was sent to/from the BRS/BRC. */
147 col_add_fstr(pinfo->cinfo, COL_INFO, "Message Type - %s",
148 val_to_str(packet_type, brp_packettype_names, "Unknown (0x%02x)"));
151 /* This call adds our tree to the main dissection tree. */
153 if (tree) { /* we are being asked for details */
155 /* Here we add our tree/subtree so we can have a collapsible branch. */
156 brp_item = proto_tree_add_item( tree, proto_brp, tvb, 0, -1, ENC_NA );
157 brp_tree = proto_item_add_subtree( brp_item, ett_brp);
159 /* We use tvb_get_guint8 to get our type value out. */
160 type = tvb_get_guint8(tvb, offset);
163 brp_item = proto_tree_add_item( brp_tree, hf_brp_type, tvb, offset, 1, ENC_BIG_ENDIAN );
166 /* Now let's break down each packet and display it in the collapsible branch */
169 case 1: /* Setup Request */
170 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
172 proto_tree_add_item( brp_tree, hf_brp_ver, tvb, offset, 4, ENC_BIG_ENDIAN );
176 case 2: /* Setup Response */
177 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
179 proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
183 case 3: /* Teardown Request */
184 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
188 case 4: /* Teardown Response */
189 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
193 case 5: /* Heartbeat Request */
194 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
198 case 6: /* Heartbeat Response */
199 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
203 case 7: /* Uni Flow Create Request */
204 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
206 proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
208 proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
210 proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
212 proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
214 proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 4, ENC_BIG_ENDIAN );
216 proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
220 case 8: /* Flow Create Response */
221 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
223 proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
225 proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
229 case 9: /* Flow Delete Request */
230 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
232 proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
236 case 10: /* Flow Delete Response */
237 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
239 proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
243 case 11: /* Flow Get Request */
244 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
246 proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
250 case 12: /* Flow Get Response */
251 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
253 proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
255 proto_tree_add_item( brp_tree, hf_brp_rmttl, tvb, offset, 4, ENC_BIG_ENDIAN );
257 proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
259 proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
261 proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
263 proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
265 proto_tree_add_item( brp_tree, hf_brp_fltype, tvb, offset, 1, ENC_BIG_ENDIAN );
267 proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 3, ENC_BIG_ENDIAN );
269 proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
271 proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
275 case 13: /* Flow Get Next Request */
276 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
278 proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
282 case 14: /* Flow Get Next Response */
283 proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
285 proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
287 proto_tree_add_item( brp_tree, hf_brp_rmttl, tvb, offset, 4, ENC_BIG_ENDIAN );
289 proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
291 proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
293 proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
295 proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
297 proto_tree_add_item( brp_tree, hf_brp_fltype, tvb, offset, 1, ENC_BIG_ENDIAN );
299 proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 3, ENC_BIG_ENDIAN );
301 proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
303 proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
307 case 15: /* Flow Abort */
308 proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 3, ENC_BIG_ENDIAN );
310 proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
316 expert_add_info_format(pinfo, brp_item, PI_UNDECODED, PI_WARN, "Unknown packet type");
324 /*--- proto_register_brp ----------------------------------------------*/
325 void proto_register_brp (void)
327 module_t *brp_module;
329 /* A data field is something you can search/filter on.
331 * We create a structure to register our fields. It consists of an
332 * array of hf_register_info structures, each of which are of the format
333 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
335 static hf_register_info hf[] = {
337 { "Type", "brp.type", FT_UINT8, BASE_DEC, VALS(brp_packettype_names), 0x0,
340 { "Transaction ID", "brp.trans", FT_UINT8, BASE_DEC, NULL, 0x0,
343 { "Version", "brp.ver", FT_UINT8, BASE_DEC, NULL, 0x0,
346 { "Status", "brp.stat", FT_UINT8, BASE_DEC, VALS(brp_stat_vals), 0x0,
349 { "Source IP Address", "brp.srcip", FT_IPv4, BASE_NONE, NULL, 0x0,
352 { "Destination IP Address", "brp.dstip", FT_IPv4, BASE_NONE, NULL, 0x0,
355 { "Destination UDP Port", "brp.dstuport", FT_UINT16, BASE_DEC, NULL, 0x0,
358 { "MBZ", "brp.mbz", FT_UINT8, BASE_DEC, NULL, 0x0,
361 { "Bandwidth - Kbytes/sec", "brp.bw", FT_UINT32, BASE_DEC, NULL, 0x0,
364 { "Lifetime", "brp.life", FT_UINT32, BASE_DEC, NULL, 0x0,
367 { "Flow Identifier", "brp.flid", FT_UINT16, BASE_DEC, NULL, 0x0,
370 { "Flow Type", "brp.fltype", FT_UINT8, BASE_DEC, NULL, 0x0,
373 { "Remaining TTL", "brp.rmttl", FT_UINT32, BASE_DEC, NULL, 0x0,
376 static gint *ett[] = {
393 proto_brp = proto_register_protocol ("BRP Protocol", "BRP", "brp");
394 proto_register_field_array (proto_brp, hf, array_length (hf));
395 proto_register_subtree_array (ett, array_length (ett));
397 /* Register preferences module */
398 brp_module = prefs_register_protocol(proto_brp, proto_reg_handoff_brp);
400 /* Register preferences */
401 prefs_register_uint_preference(brp_module, "port",
403 "Set the UDP port for BRP messages",
404 10, &global_brp_port);
406 new_register_dissector("brp", dissect_brp, proto_brp);
409 /*--- proto_reg_handoff_brp -------------------------------------------*/
410 void proto_reg_handoff_brp(void)
412 static gboolean initialized = FALSE;
413 static dissector_handle_t brp_handle;
414 static guint saved_brp_port;
417 brp_handle = new_create_dissector_handle(dissect_brp, proto_brp);
418 dissector_add_handle("udp.port", brp_handle);
421 if (saved_brp_port != 0) {
422 dissector_delete_uint("udp.port", saved_brp_port, brp_handle);
426 /* Set the port number */
427 if (global_brp_port != 0) {
428 dissector_add_uint("udp.port", global_brp_port, brp_handle);
430 saved_brp_port = global_brp_port;