aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-rlm.c
diff options
context:
space:
mode:
authorjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>2009-02-22 09:24:27 +0000
committerjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>2009-02-22 09:24:27 +0000
commitd1c04a6cad391379b02a188291e56cc55588fbd1 (patch)
tree0ea7e2d755167837b4cdecb23979a3dce6e1c6d8 /epan/dissectors/packet-rlm.c
parent416d4257f7901849a05a7efc34530d96512f5807 (diff)
Incorporate plugin dissector into build in collection.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@27498 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-rlm.c')
-rw-r--r--epan/dissectors/packet-rlm.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/epan/dissectors/packet-rlm.c b/epan/dissectors/packet-rlm.c
new file mode 100644
index 0000000000..db05bab821
--- /dev/null
+++ b/epan/dissectors/packet-rlm.c
@@ -0,0 +1,247 @@
+/* packet-rlm.c
+ * Routines for RLM dissection
+ * Copyright 2004, Duncan Sargeant <dunc-ethereal@rcpt.to>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * RLM is a proprietary Cisco protocol used for centralling managing
+ * many redundant NASes. I don't know much about the format, but you
+ * can read about the feature here:
+ *
+ * http://www.cisco.com/en/US/docs/ios/12_0t/12_0t3/feature/guide/rlm_123.html
+ *
+ * RLM runs on a UDP port (default 3000) between the MGC and the NAS.
+ * On port N+1 (default 3001), a Q.931/LAPD/UDP connection is maintained.
+ * Both sides use the same local port number for the connection, so source
+ * and dest port are always the same.
+ *
+ * In large networks, the links are typically split onto higher ports,
+ * so anything up to 3015 (or higher) could either be RLM or Q.931 traffic,
+ * although always the RLM has the one lower port number for that RLM group.
+ *
+ * Multiple RLM groups are possible on a single NAS.
+ *
+ * I haven't been able to find the protocol documented, so I've
+ * guessed some of the fields based on the output of debug commands on
+ * cisco NASes.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/xdlc.h>
+
+/* Initialize the protocol and registered fields */
+static int proto_rlm = -1;
+
+static int hf_rlm_version = -1;
+static int hf_rlm_type = -1;
+static int hf_rlm_unknown = -1;
+static int hf_rlm_tid = -1;
+static int hf_rlm_unknown2 = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_rlm = -1;
+
+
+/* RLM definitions - missing some! */
+
+#define RLM_START_REQUEST 1
+#define RLM_START_ACK 2
+/* #define ??? 3 */
+/* #define ??? 4 */
+#define RLM_ECHO_REQUEST 5
+#define RLM_ECHO_REPLY 6
+/* #define ??? ?? */
+
+
+/*
+ Maybe this isn't the best place for it, but RLM goes hand in hand
+ with Q.931 traffic on a higher port.
+*/
+static dissector_handle_t lapd_handle;
+
+static gboolean
+dissect_udp_lapd(tvbuff_t *tvb, packet_info *pinfo _U_ , proto_tree *tree) {
+
+ if (pinfo->srcport < 3001 || pinfo->srcport > 3015
+ || pinfo->destport < 3001 || pinfo->destport > 3015
+ || pinfo->destport != pinfo->srcport)
+ return FALSE;
+
+ /*
+ * XXX - check for a valid LAPD address field.
+ */
+
+ /*
+ * OK, check whether the control field looks valid.
+ */
+ if (!check_xdlc_control(tvb, 2, NULL, NULL, FALSE, FALSE))
+ return FALSE;
+
+ /*
+ * Loooks OK - call the LAPD dissector.
+ */
+ call_dissector(lapd_handle, tvb, pinfo, tree);
+ return TRUE;
+}
+
+
+/* Code to actually dissect the packets */
+static gboolean
+dissect_rlm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti;
+ proto_tree *rlm_tree;
+ guint8 rlm_type, version;
+ const char *type_str = NULL;
+
+ if (pinfo->srcport < 3000 || pinfo->srcport > 3015
+ || pinfo->destport < 3000 || pinfo->destport > 3015
+ || pinfo->destport != pinfo->srcport)
+ return FALSE;
+
+ version = tvb_get_guint8(tvb, 0);
+ rlm_type = tvb_get_guint8(tvb, 1);
+
+ /* we only know about version 2, and I've only seen 8 byte packets */
+ if (tvb_length(tvb) != 8 || version != 2) {
+ return FALSE;
+ }
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLM");
+
+ switch (rlm_type) {
+ case RLM_START_REQUEST:
+ type_str = "Start request";
+ break;;
+
+ case RLM_START_ACK:
+ type_str = "Start acknowledgement";
+ break;;
+
+ case RLM_ECHO_REQUEST:
+ type_str = "Echo request";
+ break;;
+
+ case RLM_ECHO_REPLY:
+ type_str = "Echo reply";
+ break;;
+
+ default:
+ type_str = "Unknown type";
+ break;;
+ }
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, type_str);
+
+ if (tree) {
+ /* proto_tree_add_protocol_format(tree, proto_rlm, tvb, 0,
+ 16, "Cisco Session Management"); */
+ ti = proto_tree_add_item(tree, proto_rlm, tvb, 0, 8, FALSE);
+ rlm_tree = proto_item_add_subtree(ti, ett_rlm);
+ ti = proto_tree_add_item(rlm_tree, hf_rlm_version, tvb, 0, 1, FALSE);
+ proto_tree_add_uint_format(rlm_tree, hf_rlm_type, tvb, 1, 1, rlm_type, "Type: %u (%s)", rlm_type, type_str);
+ ti = proto_tree_add_item(rlm_tree, hf_rlm_unknown, tvb, 2, 2, FALSE);
+ ti = proto_tree_add_item(rlm_tree, hf_rlm_tid, tvb, 4, 2, FALSE);
+ ti = proto_tree_add_item(rlm_tree, hf_rlm_unknown2, tvb, 6, 2, FALSE);
+ }
+
+ return TRUE;
+}
+
+
+/* Register the protocol with Wireshark */
+
+/* this format is require because a script is used to build the C function
+ that calls all the protocol registration.
+*/
+
+void
+proto_reg_handoff_rlm(void)
+{
+ /*
+ * Find a handle for the LAPD dissector.
+ */
+ lapd_handle = find_dissector("lapd");
+
+ heur_dissector_add("udp", dissect_rlm, proto_rlm);
+ heur_dissector_add("udp", dissect_udp_lapd, proto_get_id_by_filter_name("lapd"));
+}
+
+void
+proto_register_rlm(void)
+{
+
+/* Setup list of header fields See Section 1.6.1 for details*/
+ static hf_register_info hf[] = {
+ { &hf_rlm_version,
+ { "Version", "rlm.version",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_rlm_type,
+ { "Type", "rlm.type",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_rlm_unknown,
+ { "Unknown", "rlm.unknown",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_rlm_tid,
+ { "Transaction ID", "rlm.tid",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_rlm_unknown2,
+ { "Unknown", "rlm.unknown2",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "", HFILL }
+ },
+ };
+
+/* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_rlm,
+ };
+
+/* Register the protocol name and description */
+ proto_rlm = proto_register_protocol("Redundant Link Management Protocol",
+ "RLM", "rlm");
+
+/* Required function calls to register the header fields and subtrees used */
+ proto_register_field_array(proto_rlm, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+}