summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-brp.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-brp.c')
-rw-r--r--epan/dissectors/packet-brp.c406
1 files changed, 406 insertions, 0 deletions
diff --git a/epan/dissectors/packet-brp.c b/epan/dissectors/packet-brp.c
new file mode 100644
index 00000000..56f85d95
--- /dev/null
+++ b/epan/dissectors/packet-brp.c
@@ -0,0 +1,406 @@
+/* packet-brp.c
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * This is a dissector for the BRP (Bandwidth Reservation Protocol). This protocol
+ * is used by various telecommunications vendors to establish VoD (Video
+ * On-Demand) sessions between a STB (Set Top Box) at the customer's home and the
+ * VoD server at the video head-end.
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+
+/* Forward declaration we need below */
+void proto_register_brp(void);
+void proto_reg_handoff_brp(void);
+
+#define PROTO_TAG_BRP "BRP"
+
+/* Wireshark ID of the BRP protocol */
+static int proto_brp = -1;
+
+static dissector_handle_t brp_handle;
+
+static const value_string brp_packettype_names[] = {
+ { 0, "BRP" },
+ { 1, "Setup Request - BRC -> BRS" },
+ { 2, "Setup Response - BRS -> BRC" },
+ { 3, "Teardown Request - BRC -> BRS" },
+ { 4, "Teardown Response - BRS -> BRC" },
+ { 5, "Heartbeat Request - BRS -> BRC" },
+ { 6, "Heartbeat Response - BRC -> BRS" },
+ { 7, "Unidirectional Flow Create Request - BRC -> BRS" },
+ { 8, "Flow Create Response - BRS -> BRC" },
+ { 9, "Flow Delete Request BRC -> BRS" },
+ { 10, "Flow Delete Response - BRS -> BRC" },
+ { 11, "Flow Get Request - BRC -> BRS" },
+ { 12, "Flow Get Response - BRS -> BRC" },
+ { 13, "Flow Get Next Request - BRC -> BRS" },
+ { 14, "Flow Get Next Response - BRS -> BRC" },
+ { 15, "Flow Abort - BRS -> BRC" },
+ { 0, NULL }
+};
+
+static const value_string brp_stat_vals[] = {
+ { 0, "OK" },
+ { 1, "Comm Error - Network connectivity has been lost (Client Message)." },
+ { 2, "No Bandwidth - There is insufficient bandwidth available in the network to honor the request (Server Message)." },
+ { 3, "Insufficient Resource - Either there is insufficient memory or resource available to transmit the request or,"
+ " insufficient resources existed at the server to complete the request. Note that insufficient bandwidth in the"
+ " network is handled by the previous status value. This is the catchall for all other resource deficiencies"
+ " (Client/Server Message)." },
+ { 4, "No Such - The requested flow does not exist (Server Message)." },
+ { 5, "No Session - There is no active session. The server may return this in the event that the client and server"
+ " are out of sync. In that eventuality, the client must reestablish its session and recreate any flows that"
+ " it believes have been lost (Server Message)." },
+ { 6, "Invalid Argument - One of the input arguments to the call was not valid (Client/Server Message)." },
+ { 7, "Unreachable - The specified BRS is not reachable (Client Message)." },
+ { 8, "Internal Error - An internal fault has occurred. This is generally indicative of a fatal condition within"
+ " the client system (Server Message)." },
+ { 9, "Already Exists - The flow or session that the client requested already exists (Server Message)." },
+ { 10, "Flow Removed - The flow was removed or lost due to issues internal to the network (Server Message)." },
+ { 11, "Invalid Sender - Received packet was from an unknown sender (Server Message)." },
+ { 12, "Invalid Message - Input message is not defined or malformed (Client/Server Message)." },
+ { 13, "Unsupported Version - The requested version (in a setup) is not supported (Server Message)." },
+ { 14, "Pending - The requested operation is proceeding and a status will be returned with the final result"
+ " shortly (Server Message)." },
+ { 0, NULL }
+};
+
+/* The following hf_* variables are used to hold the Wireshark IDs of
+* our data fields; they are filled out when we call
+* proto_register_field_array() in proto_register_brp()
+*/
+static gint hf_brp_type = -1;
+static gint hf_brp_trans = -1;
+static gint hf_brp_ver = -1;
+static gint hf_brp_stat = -1;
+static gint hf_brp_srcip = -1;
+static gint hf_brp_dstip = -1;
+static gint hf_brp_dstuport = -1;
+static gint hf_brp_mbz = -1;
+static gint hf_brp_bw = -1;
+static gint hf_brp_life = -1;
+static gint hf_brp_flid = -1;
+static gint hf_brp_rmttl = -1;
+static gint hf_brp_fltype = -1;
+
+/* These are the ids of the subtrees that we may be creating */
+static gint ett_brp = -1;
+static gint ett_brp_type = -1;
+static gint ett_brp_trans = -1;
+static gint ett_brp_ver = -1;
+static gint ett_brp_stat = -1;
+static gint ett_brp_srcip = -1;
+static gint ett_brp_dstip = -1;
+static gint ett_brp_dstuport = -1;
+static gint ett_brp_mbz = -1;
+static gint ett_brp_bw = -1;
+static gint ett_brp_life = -1;
+static gint ett_brp_flid = -1;
+static gint ett_brp_rmttl = -1;
+static gint ett_brp_fltype = -1;
+
+static expert_field ei_brp_type_unknown = EI_INIT;
+
+static int
+dissect_brp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+
+ proto_item *brp_item = NULL;
+ proto_tree *brp_tree = NULL;
+ gint offset = 0;
+ guint8 type = 0;
+ guint8 packet_type = tvb_get_guint8(tvb, 0);
+
+ /* If there is a "tree" requested, we handle that request. */
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_BRP);
+ /* We add some snazzy bizness to the info field to quickly ascertain
+ what type of message was sent to/from the BRS/BRC. */
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Message Type - %s",
+ val_to_str(packet_type, brp_packettype_names, "Unknown (0x%02x)"));
+
+ /* This call adds our tree to the main dissection tree. */
+
+ if (tree) { /* we are being asked for details */
+
+ /* Here we add our tree/subtree so we can have a collapsible branch. */
+ brp_item = proto_tree_add_item( tree, proto_brp, tvb, 0, -1, ENC_NA );
+ brp_tree = proto_item_add_subtree( brp_item, ett_brp);
+
+ /* We use tvb_get_guint8 to get our type value out. */
+ type = tvb_get_guint8(tvb, offset);
+ offset += 0;
+
+ brp_item = proto_tree_add_item( brp_tree, hf_brp_type, tvb, offset, 1, ENC_BIG_ENDIAN );
+ offset += 1;
+
+ /* Now let's break down each packet and display it in the collapsible branch */
+ switch(type)
+ {
+ case 1: /* Setup Request */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_ver, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 2: /* Setup Response */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 3: /* Teardown Request */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ break;
+
+ case 4: /* Teardown Response */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ break;
+
+ case 5: /* Heartbeat Request */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ break;
+
+ case 6: /* Heartbeat Response */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ break;
+
+ case 7: /* Uni Flow Create Request */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
+ offset +=2;
+ proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
+ offset +=2;
+ proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 8: /* Flow Create Response */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 9: /* Flow Delete Request */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 10: /* Flow Delete Response */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 11: /* Flow Get Request */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 12: /* Flow Get Response */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_rmttl, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
+ offset +=2;
+ proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
+ offset +=2;
+ proto_tree_add_item( brp_tree, hf_brp_fltype, tvb, offset, 1, ENC_BIG_ENDIAN );
+ offset +=1;
+ proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset +=3;
+ proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 13: /* Flow Get Next Request */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 14: /* Flow Get Next Response */
+ proto_tree_add_item( brp_tree, hf_brp_trans, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset += 3;
+ proto_tree_add_item( brp_tree, hf_brp_stat, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_rmttl, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_srcip, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_dstip, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_dstuport, tvb, offset, 2, ENC_BIG_ENDIAN );
+ offset +=2;
+ proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 2, ENC_BIG_ENDIAN );
+ offset +=2;
+ proto_tree_add_item( brp_tree, hf_brp_fltype, tvb, offset, 1, ENC_BIG_ENDIAN );
+ offset +=1;
+ proto_tree_add_item( brp_tree, hf_brp_bw, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset +=3;
+ proto_tree_add_item( brp_tree, hf_brp_life, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ case 15: /* Flow Abort */
+ proto_tree_add_item( brp_tree, hf_brp_mbz, tvb, offset, 3, ENC_BIG_ENDIAN );
+ offset +=3;
+ proto_tree_add_item( brp_tree, hf_brp_flid, tvb, offset, 4, ENC_BIG_ENDIAN );
+ offset +=4;
+ break;
+
+ default:
+ /* Invalid type */
+ expert_add_info(pinfo, brp_item, &ei_brp_type_unknown);
+ break;
+ }
+
+ }
+return offset;
+}
+
+/*--- proto_register_brp ----------------------------------------------*/
+void proto_register_brp (void)
+{
+ expert_module_t* expert_brp;
+
+ /* A data field is something you can search/filter on.
+ *
+ * We create a structure to register our fields. It consists of an
+ * array of hf_register_info structures, each of which are of the format
+ * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
+ */
+ static hf_register_info hf[] = {
+ { &hf_brp_type,
+ { "Type", "brp.type", FT_UINT8, BASE_DEC, VALS(brp_packettype_names), 0x0,
+ NULL, HFILL }},
+ { &hf_brp_trans,
+ { "Transaction ID", "brp.trans", FT_UINT24, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_ver,
+ { "Version", "brp.ver", FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_stat,
+ { "Status", "brp.stat", FT_UINT32, BASE_DEC, VALS(brp_stat_vals), 0x0,
+ NULL, HFILL }},
+ { &hf_brp_srcip,
+ { "Source IP Address", "brp.srcip", FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_dstip,
+ { "Destination IP Address", "brp.dstip", FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_dstuport,
+ { "Destination UDP Port", "brp.dstuport", FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_mbz,
+ { "MBZ", "brp.mbz", FT_UINT24, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_bw,
+ { "Bandwidth - Kbytes/sec", "brp.bw", FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_life,
+ { "Lifetime", "brp.life", FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_flid,
+ { "Flow Identifier", "brp.flid", FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_fltype,
+ { "Flow Type", "brp.fltype", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_brp_rmttl,
+ { "Remaining TTL", "brp.rmttl", FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ };
+ static gint *ett[] = {
+ &ett_brp,
+ &ett_brp_type,
+ &ett_brp_trans,
+ &ett_brp_ver,
+ &ett_brp_stat,
+ &ett_brp_srcip,
+ &ett_brp_dstip,
+ &ett_brp_dstuport,
+ &ett_brp_mbz,
+ &ett_brp_bw,
+ &ett_brp_life,
+ &ett_brp_flid,
+ &ett_brp_fltype,
+ &ett_brp_rmttl
+
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_brp_type_unknown, { "brp.type.unknown", PI_UNDECODED, PI_WARN, "Unknown packet type", EXPFILL }},
+ };
+
+ proto_brp = proto_register_protocol ("BRP Protocol", "BRP", "brp");
+ proto_register_field_array (proto_brp, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ expert_brp = expert_register_protocol(proto_brp);
+ expert_register_field_array(expert_brp, ei, array_length(ei));
+
+ brp_handle = register_dissector("brp", dissect_brp, proto_brp);
+}
+
+/*--- proto_reg_handoff_brp -------------------------------------------*/
+void proto_reg_handoff_brp(void)
+{
+ dissector_add_for_decode_as_with_preference("udp.port", brp_handle);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */