aboutsummaryrefslogtreecommitdiffstats
path: root/packet-lmp.c
diff options
context:
space:
mode:
authorAshok Narayanan <ashokn@cisco.com>2002-04-10 22:00:49 +0000
committerAshok Narayanan <ashokn@cisco.com>2002-04-10 22:00:49 +0000
commit60fae996409536268a771061af796dec1d7751cd (patch)
treecefe913fa19b6b96a26a5efd0b3d89fcb0e3844b /packet-lmp.c
parent86a0e134e039b88bd8d69d88c3acfb4ff8bf02ed (diff)
downloadwireshark-60fae996409536268a771061af796dec1d7751cd.tar.gz
wireshark-60fae996409536268a771061af796dec1d7751cd.tar.bz2
wireshark-60fae996409536268a771061af796dec1d7751cd.zip
Added support for the Link Management Protocol (LMP), used for optical
signalling and Generalized MPLS. This commit contains code for the protocol version described in draft-ietf-ccamp-lmp-03.txt. svn path=/trunk/; revision=5138
Diffstat (limited to 'packet-lmp.c')
-rw-r--r--packet-lmp.c1458
1 files changed, 1458 insertions, 0 deletions
diff --git a/packet-lmp.c b/packet-lmp.c
new file mode 100644
index 0000000000..d8509bf373
--- /dev/null
+++ b/packet-lmp.c
@@ -0,0 +1,1458 @@
+/* packet-lmp.c
+ * Routines for LMP packet disassembly
+ *
+ * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
+ *
+ * $Id: packet-lmp.c,v 1.1 2002/04/10 22:00:49 ashokn Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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.
+ */
+
+/*
+ * LMP as a standard has shown a remarkable ability to get completely rewritten
+ * across minor versions of the draft. This file currently implements
+ * the version described in draft-ietf-ccamp-lmp-03.txt
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#include <glib.h>
+
+#ifdef NEED_SNPRINTF_H
+# include "snprintf.h"
+#endif
+
+#include <epan/tvbuff.h>
+#include <epan/packet.h>
+#include "in_cksum.h"
+#include "ieee-float.h"
+#include "etypes.h"
+#include "ipproto.h"
+
+#include "packet-ip.h"
+
+static int proto_lmp = -1;
+
+/* #define IP_PROTO_LMP 0x6e */
+#define IP_PROTO_LMP 140
+
+/*----------------------------------------------------------------------
+ * LMP message types
+ */
+typedef enum {
+ LMP_MSG_CONFIG=1,
+ LMP_MSG_CONFIG_ACK,
+ LMP_MSG_CONFIG_NACK,
+ LMP_MSG_HELLO,
+ LMP_MSG_BEGIN_VERIFY,
+ LMP_MSG_BEGIN_VERIFY_ACK,
+ LMP_MSG_BEGIN_VERIFY_NACK,
+ LMP_MSG_END_VERIFY,
+ LMP_MSG_END_VERIFY_ACK,
+ LMP_MSG_TEST,
+ LMP_MSG_TEST_STATUS_SUCCESS,
+ LMP_MSG_TEST_STATUS_FAILURE,
+ LMP_MSG_TEST_STATUS_ACK,
+ LMP_MSG_LINK_SUMMARY,
+ LMP_MSG_LINK_SUMMARY_ACK,
+ LMP_MSG_LINK_SUMMARY_NACK,
+ LMP_MSG_CHANNEL_FAIL,
+ LMP_MSG_CHANNEL_FAIL_ACK,
+ LMP_MSG_CHANNEL_FAIL_NACK,
+ LMP_MSG_CHANNEL_STATUS,
+ LMP_MSG_CHANNEL_STATUS_ACK,
+ LMP_MSG_CHANNEL_STATUS_REQ,
+ LMP_MSG_CHANNEL_STATUS_RESP,
+} lmp_message_types;
+
+static value_string message_type_vals[] = {
+ {LMP_MSG_CONFIG, "Config Message. "},
+ {LMP_MSG_CONFIG_ACK, "ConfigAck Message. "},
+ {LMP_MSG_CONFIG_NACK, "ConfigNack Message. "},
+ {LMP_MSG_HELLO, "Hello Message. "},
+ {LMP_MSG_BEGIN_VERIFY, "BeginVerify Message. "},
+ {LMP_MSG_BEGIN_VERIFY_ACK, "BeginVerifyAck Message. "},
+ {LMP_MSG_BEGIN_VERIFY_NACK, "BeginVerifyNack Message. "},
+ {LMP_MSG_END_VERIFY, "EndVerifyNack Message. "},
+ {LMP_MSG_TEST, "Test Message. "},
+ {LMP_MSG_TEST_STATUS_SUCCESS, "TestStatusSuccess Message. "},
+ {LMP_MSG_TEST_STATUS_FAILURE, "TestStatusFailure Message. "},
+ {LMP_MSG_TEST_STATUS_ACK, "TestStatusAck Message. "},
+ {LMP_MSG_LINK_SUMMARY, "LinkSummary Message. "},
+ {LMP_MSG_LINK_SUMMARY_ACK, "LinkSummaryAck Message. "},
+ {LMP_MSG_LINK_SUMMARY_NACK, "LinkSummaryNack Message. "},
+ {LMP_MSG_CHANNEL_FAIL, "ChannelFail Message. "},
+ {LMP_MSG_CHANNEL_FAIL_ACK, "ChannelFailAck Message. "},
+ {LMP_MSG_CHANNEL_FAIL_NACK, "ChannelFailNack Message. "},
+ {LMP_MSG_CHANNEL_STATUS, "ChannelStatus Message. "},
+ {LMP_MSG_CHANNEL_STATUS_ACK, "ChannelStatusAck Message. "},
+ {LMP_MSG_CHANNEL_STATUS_REQ, "ChannelStatusRequest Message. "},
+ {LMP_MSG_CHANNEL_STATUS_RESP, "ChannelStatusResponse Message. "},
+ {0, NULL}
+};
+
+/*------------------------------------------------------------------------------
+ * LMP object classes
+ */
+typedef enum {
+ LMP_CLASS_NULL = 0,
+
+ LMP_CLASS_LOCAL_CCID,
+ LMP_CLASS_REMOTE_CCID,
+ LMP_CLASS_LOCAL_NODE_ID,
+ LMP_CLASS_REMOTE_NODE_ID,
+ LMP_CLASS_LOCAL_LINK_ID,
+ LMP_CLASS_REMOTE_LINK_ID,
+ LMP_CLASS_LOCAL_INTERFACE_ID,
+ LMP_CLASS_REMOTE_INTERFACE_ID,
+ LMP_CLASS_MESSAGE_ID,
+ LMP_CLASS_MESSAGE_ID_ACK,
+ LMP_CLASS_CONFIG,
+ LMP_CLASS_HELLO,
+ LMP_CLASS_BEGIN_VERIFY,
+ LMP_CLASS_BEGIN_VERIFY_ACK,
+ LMP_CLASS_VERIFY_ID,
+ LMP_CLASS_TE_LINK,
+ LMP_CLASS_DATA_LINK,
+ LMP_CLASS_CHANNEL_STATUS,
+ LMP_CLASS_CHANNEL_STATUS_REQUEST,
+ LMP_CLASS_ERROR,
+
+ LMP_CLASS_MAX
+} lmp_classes;
+
+static value_string lmp_class_vals[] = {
+
+ {LMP_CLASS_LOCAL_CCID, "LOCAL_CCID"},
+ {LMP_CLASS_REMOTE_CCID, "REMOTE_CCID"},
+ {LMP_CLASS_LOCAL_NODE_ID, "LOCAL_NODE_ID"},
+ {LMP_CLASS_REMOTE_NODE_ID, "REMOTE_NODE_ID"},
+ {LMP_CLASS_LOCAL_LINK_ID, "LOCAL_LINK_ID"},
+ {LMP_CLASS_REMOTE_LINK_ID, "REMOTE_LINK_ID"},
+ {LMP_CLASS_LOCAL_INTERFACE_ID, "LOCAL_INTERFACE_ID"},
+ {LMP_CLASS_REMOTE_INTERFACE_ID, "REMOTE_INTERFACE_ID"},
+ {LMP_CLASS_MESSAGE_ID, "MESSAGE_ID"},
+ {LMP_CLASS_MESSAGE_ID_ACK, "MESSAGE_ID_ACK"},
+ {LMP_CLASS_CONFIG, "CONFIG"},
+ {LMP_CLASS_HELLO, "HELLO"},
+ {LMP_CLASS_BEGIN_VERIFY, "BEGIN_VERIFY"},
+ {LMP_CLASS_BEGIN_VERIFY_ACK, "BEGIN_VERIFY_ACK"},
+ {LMP_CLASS_VERIFY_ID, "VERIFY_ID"},
+ {LMP_CLASS_TE_LINK, "TE_LINK"},
+ {LMP_CLASS_DATA_LINK, "DATA_LINK"},
+ {LMP_CLASS_CHANNEL_STATUS, "CHANNEL_STATUS"},
+ {LMP_CLASS_CHANNEL_STATUS_REQUEST, "CHANNEL_STATUS_REQUEST"},
+ {LMP_CLASS_ERROR, "ERROR"},
+};
+
+#define VALID_CLASS(class) ((class) > LMP_CLASS_NULL && (class) < LMP_CLASS_MAX)
+
+/*------------------------------------------------------------------------------
+ * Other constants & stuff
+ */
+
+/*
+ * From packet-rsvp.c
+ */
+extern const value_string gmpls_lsp_enc_str[];
+extern const value_string gmpls_switching_type_str[];
+
+/* Channel Status */
+static const value_string channel_status_str[] = {
+ {1, "Signal Okay (OK)"},
+ {2, "Signal Degraded (SD)"},
+ {3, "Signal Failed (SF)"},
+};
+static const value_string channel_status_short_str[] = {
+ {1, "OK"},
+ {2, "SD"},
+ {3, "SF"},
+};
+
+/*------------------------------------------------------------------------------
+ * LMP Filter values
+ */
+
+enum lmp_filter_keys {
+
+ /* Message types ---------------- */
+ LMPF_MSG,
+
+ LMPF_MSG_CONFIG,
+ LMPF_MSG_CONFIG_ACK,
+ LMPF_MSG_CONFIG_NACK,
+ LMPF_MSG_HELLO,
+ LMPF_MSG_BEGIN_VERIFY,
+ LMPF_MSG_BEGIN_VERIFY_ACK,
+ LMPF_MSG_BEGIN_VERIFY_NACK,
+ LMPF_MSG_END_VERIFY,
+ LMPF_MSG_END_VERIFY_ACK,
+ LMPF_MSG_TEST,
+ LMPF_MSG_TEST_STATUS_SUCCESS,
+ LMPF_MSG_TEST_STATUS_FAILURE,
+ LMPF_MSG_TEST_STATUS_ACK,
+ LMPF_MSG_LINK_SUMMARY,
+ LMPF_MSG_LINK_SUMMARY_ACK,
+ LMPF_MSG_LINK_SUMMARY_NACK,
+ LMPF_MSG_CHANNEL_FAIL,
+ LMPF_MSG_CHANNEL_FAIL_ACK,
+ LMPF_MSG_CHANNEL_FAIL_NACK,
+ LMPF_MSG_CHANNEL_STATUS,
+ LMPF_MSG_CHANNEL_STATUS_ACK,
+ LMPF_MSG_CHANNEL_STATUS_REQ,
+ LMPF_MSG_CHANNEL_STATUS_RESP,
+
+ /* LMP Message Header Fields ------------------ */
+ LMPF_HDR_FLAGS,
+ LMPF_HDR_FLAGS_CC_DOWN,
+ LMPF_HDR_FLAGS_REBOOT,
+ LMPF_HDR_FLAGS_DWDM,
+ LMPF_HDR_FLAGS_AUTHENTICATION,
+
+ /* LMP Object Class Filters -------------------- */
+ LMPF_OBJECT,
+
+ LMPF_CLASS_LOCAL_CCID,
+ LMPF_CLASS_REMOTE_CCID,
+ LMPF_CLASS_LOCAL_NODE_ID,
+ LMPF_CLASS_REMOTE_NODE_ID,
+ LMPF_CLASS_LOCAL_LINK_ID,
+ LMPF_CLASS_REMOTE_LINK_ID,
+ LMPF_CLASS_LOCAL_INTERFACE_ID,
+ LMPF_CLASS_REMOTE_INTERFACE_ID,
+ LMPF_CLASS_MESSAGE_ID,
+ LMPF_CLASS_MESSAGE_ID_ACK,
+ LMPF_CLASS_CONFIG,
+ LMPF_CLASS_HELLO,
+ LMPF_CLASS_BEGIN_VERIFY,
+ LMPF_CLASS_BEGIN_VERIFY_ACK,
+ LMPF_CLASS_VERIFY_ID,
+ LMPF_CLASS_TE_LINK,
+ LMPF_CLASS_DATA_LINK,
+ LMPF_CLASS_CHANNEL_STATUS,
+ LMPF_CLASS_CHANNEL_STATUS_REQUEST,
+ LMPF_CLASS_ERROR,
+
+ LMPF_VAL_CTYPE,
+ LMPF_VAL_LOCAL_CCID,
+ LMPF_VAL_REMOTE_CCID,
+ LMPF_VAL_LOCAL_NODE_ID,
+ LMPF_VAL_REMOTE_NODE_ID,
+ LMPF_VAL_LOCAL_LINK_ID_IPV4,
+ LMPF_VAL_LOCAL_LINK_ID_UNNUM,
+ LMPF_VAL_REMOTE_LINK_ID_IPV4,
+ LMPF_VAL_REMOTE_LINK_ID_UNNUM,
+ LMPF_VAL_LOCAL_INTERFACE_ID_IPV4,
+ LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM,
+ LMPF_VAL_REMOTE_INTERFACE_ID_IPV4,
+ LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM,
+ LMPF_VAL_MESSAGE_ID,
+ LMPF_VAL_MESSAGE_ID_ACK,
+ LMPF_VAL_CONFIG_HELLO,
+ LMPF_VAL_CONFIG_HELLO_DEAD,
+ LMPF_VAL_HELLO_TXSEQ,
+ LMPF_VAL_HELLO_RXSEQ,
+
+ LMPF_VAL_BEGIN_VERIFY_FLAGS,
+ LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS,
+ LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE,
+ LMPF_VAL_BEGIN_VERIFY_INTERVAL,
+ LMPF_VAL_BEGIN_VERIFY_ENCTYPE,
+ LMPF_VAL_BEGIN_VERIFY_TRANSPORT,
+ LMPF_VAL_BEGIN_VERIFY_TRANSMISSION_RATE,
+ LMPF_VAL_BEGIN_VERIFY_WAVELENGTH,
+ LMPF_VAL_VERIFY_ID,
+
+ LMPF_VAL_TE_LINK_FLAGS,
+ LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT,
+ LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY,
+ LMPF_VAL_TE_LINK_LOCAL_IPV4,
+ LMPF_VAL_TE_LINK_LOCAL_UNNUM,
+ LMPF_VAL_TE_LINK_REMOTE_IPV4,
+ LMPF_VAL_TE_LINK_REMOTE_UNNUM,
+
+ LMPF_VAL_DATA_LINK_FLAGS,
+ LMPF_VAL_DATA_LINK_FLAGS_PORT,
+ LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED,
+ LMPF_VAL_DATA_LINK_LOCAL_IPV4,
+ LMPF_VAL_DATA_LINK_LOCAL_UNNUM,
+ LMPF_VAL_DATA_LINK_REMOTE_IPV4,
+ LMPF_VAL_DATA_LINK_REMOTE_UNNUM,
+ LMPF_VAL_DATA_LINK_SUBOBJ,
+ LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE,
+ LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING,
+
+ LMPF_VAL_ERROR,
+ LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK,
+ LMPF_VAL_ERROR_VERIFY_UNWILLING,
+ LMPF_VAL_ERROR_VERIFY_TRANSPORT,
+ LMPF_VAL_ERROR_VERIFY_TE_LINK_ID,
+ LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS,
+ LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE,
+ LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID,
+ LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK,
+ LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK,
+
+ LMPF_MAX,
+};
+
+static int lmp_filter[LMPF_MAX];
+
+static hf_register_info lmpf_info[] = {
+
+ /* Message type number */
+ {&lmp_filter[LMPF_MSG],
+ { "Message Type", "lmp.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0,
+ "", HFILL }},
+
+ /* Message type shorthands */
+ {&lmp_filter[LMPF_MSG_CONFIG],
+ { "Config Message", "lmp.msg.config", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CONFIG_ACK],
+ { "ConfigAck Message", "lmp.msg.configack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CONFIG_NACK],
+ { "ConfigNack Message", "lmp.msg.confignack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_HELLO],
+ { "HELLO Message", "lmp.msg.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_BEGIN_VERIFY],
+ { "BeginVerify Message", "lmp.msg.beginverify", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_BEGIN_VERIFY_ACK],
+ { "BeginVerifyAck Message", "lmp.msg.beginverifyack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_BEGIN_VERIFY_NACK],
+ { "BeginVerifyNack Message", "lmp.msg.beginverifynack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_END_VERIFY],
+ { "EndVerify Message", "lmp.msg.endverify", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_TEST],
+ { "Test Message", "lmp.msg.test", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_TEST_STATUS_SUCCESS],
+ { "TestStatusSuccess Message", "lmp.msg.teststatussuccess", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_TEST_STATUS_FAILURE],
+ { "TestStatusFailure Message", "lmp.msg.teststatusfailure", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_TEST_STATUS_ACK],
+ { "TestStatusAck Message", "lmp.msg.teststatusack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_LINK_SUMMARY],
+ { "LinkSummary Message", "lmp.msg.linksummary", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_LINK_SUMMARY_ACK],
+ { "LinkSummaryAck Message", "lmp.msg.linksummaryack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_LINK_SUMMARY_NACK],
+ { "LinkSummaryNack Message", "lmp.msg.linksummarynack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CHANNEL_FAIL],
+ { "ChannelFail Message", "lmp.msg.channelfail", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CHANNEL_FAIL_ACK],
+ { "ChannelFailAck Message", "lmp.msg.channelfailack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CHANNEL_FAIL_NACK],
+ { "ChannelFailNack Message", "lmp.msg.channelfailnack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CHANNEL_STATUS],
+ { "ChannelStatus Message", "lmp.msg.channelstatus", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_ACK],
+ { "ChannelStatusAck Message", "lmp.msg.channelstatusack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_REQ],
+ { "ChannelStatusRequest Message", "lmp.msg.channelstatusrequest", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_MSG_CHANNEL_STATUS_RESP],
+ { "ChannelStatusResponse Message", "lmp.msg.channelstatusresponse", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+
+ /* LMP Message Header Fields ------------------- */
+
+ {&lmp_filter[LMPF_HDR_FLAGS],
+ { "LMP Header - Flags", "lmp.hdr.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_HDR_FLAGS_CC_DOWN],
+ { "ControlChannelDown", "lmp.hdr.ccdown", FT_BOOLEAN, 8, NULL, 0x01,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_HDR_FLAGS_REBOOT],
+ { "Reboot", "lmp.hdr.reboot", FT_BOOLEAN, 8, NULL, 0x02,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_HDR_FLAGS_DWDM],
+ { "DWDM Node", "lmp.hdr.dwdm", FT_BOOLEAN, 8, NULL, 0x04,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_HDR_FLAGS_AUTHENTICATION],
+ { "Authentication", "lmp.hdr.auth", FT_BOOLEAN, 8, NULL, 0x08,
+ "", HFILL }},
+
+ /* LMP object class filters ------------------------------- */
+
+ {&lmp_filter[LMPF_OBJECT],
+ { "LOCAL_CCID", "lmp.object", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_LOCAL_CCID],
+ { "LOCAL_CCID", "lmp.obj.local_ccid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_REMOTE_CCID],
+ { "REMOTE_CCID", "lmp.obj.remote_ccid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_LOCAL_NODE_ID],
+ { "LOCAL_NODE_ID", "lmp.obj.local_nodeid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_REMOTE_NODE_ID],
+ { "REMOTE_NODE_ID", "lmp.obj.remote_nodeid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_LOCAL_NODE_ID],
+ { "LOCAL_NODE_ID", "lmp.obj.local_nodeid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_REMOTE_NODE_ID],
+ { "REMOTE_NODE_ID", "lmp.obj.remote_nodeid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_LOCAL_LINK_ID],
+ { "LOCAL_LINK_ID", "lmp.obj.local_linkid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_REMOTE_LINK_ID],
+ { "REMOTE_LINK_ID", "lmp.obj.remote_linkid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_LOCAL_INTERFACE_ID],
+ { "LOCAL_INTERFACE_ID", "lmp.obj.local_interfaceid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_REMOTE_INTERFACE_ID],
+ { "REMOTE_INTERFACE_ID", "lmp.obj.remote_interfaceid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_MESSAGE_ID],
+ { "MESSAGE_ID", "lmp.obj.messageid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_MESSAGE_ID_ACK],
+ { "MESSAGE_ID_ACK", "lmp.obj.messageid_ack", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_CONFIG],
+ { "CONFIG", "lmp.obj.config", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_HELLO],
+ { "HELLO", "lmp.obj.hello", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_BEGIN_VERIFY],
+ { "BEGIN_VERIFY", "lmp.obj.begin_verify", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_BEGIN_VERIFY_ACK],
+ { "BEGIN_VERIFY_ACK", "lmp.obj.begin_verify_ack", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_VERIFY_ID],
+ { "VERIFY_ID", "lmp.obj.verifyid", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_TE_LINK],
+ { "TE_LINK", "lmp.obj.te_link", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_DATA_LINK],
+ { "DATA_LINK", "lmp.obj.data_link", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_CHANNEL_STATUS],
+ { "CHANNEL_STATUS", "lmp.obj.channel_status", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_CLASS_CHANNEL_STATUS_REQUEST],
+ { "CHANNEL_STATUS_REQUEST", "lmp.obj.channel_status_request", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_CLASS_ERROR],
+ { "ERROR", "lmp.obj.error", FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ /* Other LMP Value Filters ------------------------------ */
+
+ {&lmp_filter[LMPF_VAL_CTYPE],
+ { "Object C-Type", "lmp.obj.ctype", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_LOCAL_CCID],
+ { "Local CCID Value", "lmp.local_ccid", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_REMOTE_CCID],
+ { "Remote CCID Value", "lmp.remote_ccid", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_LOCAL_NODE_ID],
+ { "Local Node ID Value", "lmp.local_nodeid", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_REMOTE_NODE_ID],
+ { "Remote Node ID Value", "lmp.remote_nodeid", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_LOCAL_LINK_ID_IPV4],
+ { "Local Link ID - IPv4", "lmp.local_linkid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_LOCAL_LINK_ID_UNNUM],
+ { "Local Link ID - Unnumbered", "lmp.local_linkid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_REMOTE_LINK_ID_IPV4],
+ { "Remote Link ID - IPv4", "lmp.remote_linkid_ipv4", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_REMOTE_LINK_ID_UNNUM],
+ { "Remote Link ID - Unnumbered", "lmp.remote_linkid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_LOCAL_INTERFACE_ID_IPV4],
+ { "Local Interface ID - IPv4", "lmp.local_interfaceid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM],
+ { "Local Interface ID - Unnumbered", "lmp.local_interfaceid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_REMOTE_INTERFACE_ID_IPV4],
+ { "Remote Interface ID - IPv4", "lmp.remote_interfaceid_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM],
+ { "Remote Interface ID - Unnumbered", "lmp.remote_interfaceid_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_MESSAGE_ID],
+ { "Message-ID Value", "lmp.messageid", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_MESSAGE_ID_ACK],
+ { "Message-ID Ack Value", "lmp.messageid_ack", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_CONFIG_HELLO],
+ { "HelloInterval", "lmp.hellointerval", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_CONFIG_HELLO_DEAD],
+ { "HelloDeadInterval", "lmp.hellodeadinterval", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_HELLO_TXSEQ],
+ { "TxSeqNum", "lmp.txseqnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_HELLO_RXSEQ],
+ { "RxSeqNum", "lmp.rxseqnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS],
+ { "Flags", "lmp.begin_verify.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS],
+ { "Verify All Links", "lmp.begin_verify.all_links",
+ FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE],
+ { "Data Link Type", "lmp.begin_verify.link_type",
+ FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_BEGIN_VERIFY_ENCTYPE],
+ { "Encoding Type", "lmp.begin_verify.enctype", FT_UINT8, BASE_DEC, VALS(gmpls_lsp_enc_str), 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_VERIFY_ID],
+ { "Verify-ID", "lmp.verifyid", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_TE_LINK_FLAGS],
+ { "TE-Link Flags", "lmp.te_link_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT],
+ { "Fault Management Supported", "lmp.te_link.fault_mgmt",
+ FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY],
+ { "Link Verification Supported", "lmp.te_link.link_verify",
+ FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_TE_LINK_LOCAL_IPV4],
+ { "TE-Link Local ID - IPv4", "lmp.te_link.local_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_TE_LINK_LOCAL_UNNUM],
+ { "TE-Link Local ID - Unnumbered", "lmp.te_link.local_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_TE_LINK_REMOTE_IPV4],
+ { "TE-Link Remote ID - IPv4", "lmp.te_link.remote_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_TE_LINK_REMOTE_UNNUM],
+ { "TE-Link Remote ID - Unnumbered", "lmp.te_link.remote_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_DATA_LINK_FLAGS],
+ { "Data-Link Flags", "lmp.data_link_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_PORT],
+ { "Data-Link is Individual Port", "lmp.data_link.port",
+ FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED],
+ { "Data-Link is Allocated", "lmp.data_link.link_verify",
+ FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_IPV4],
+ { "Data-Link Local ID - IPv4", "lmp.data_link.local_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_UNNUM],
+ { "Data-Link Local ID - Unnumbered", "lmp.data_link.local_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_IPV4],
+ { "Data-Link Remote ID - IPv4", "lmp.data_link.remote_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_UNNUM],
+ { "Data-Link Remote ID - Unnumbered", "lmp.data_link.remote_unnum", FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ],
+ { "Subobject", "lmp.data_link_subobj", FT_NONE, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE],
+ { "Interface Switching Capability", "lmp.data_link_switching", FT_UINT8, BASE_DEC,
+ VALS(gmpls_switching_type_str), 0x0, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING],
+ { "LSP Encoding Type", "lmp.data_link_encoding", FT_UINT8, BASE_DEC,
+ VALS(gmpls_lsp_enc_str), 0x0, "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_ERROR],
+ { "Error Code", "lmp.error", FT_UINT32, BASE_HEX, NULL, 0x0,
+ "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
+ { "Verification - Unsupported for this TE-Link", "lmp.error.verify_unsupported_link",
+ FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
+ { "Verification - Unwilling to Verify at this time", "lmp.error.verify_unwilling",
+ FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
+ { "Verification - Transport Unsupported", "lmp.error.verify_unsupported_transport",
+ FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
+ { "Verification - TE Link ID Configuration Error", "lmp.error.verify_te_link_id",
+ FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }},
+
+ {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
+ { "Summary - Unacceptable non-negotiable parameters", "lmp.error.summary_bad_params",
+ FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
+ { "Summary - Renegotiate Parametere", "lmp.error.summary_renegotiate",
+ FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID],
+ { "Summary - Bad Remote Link ID", "lmp.error.summary_bad_remote_linkid",
+ FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK],
+ { "Summary - Bad TE Link Object", "lmp.error.summary_bad_te_link",
+ FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }},
+ {&lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK],
+ { "Summary - Bad Data Link Object", "lmp.error.summary_bad_data_link",
+ FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }},
+};
+
+static int
+lmp_class_to_filter_num(int class)
+{
+ if (VALID_CLASS(class))
+ return class + LMPF_OBJECT;
+ return -1;
+}
+
+/*------------------------------------------------------------------------------
+ * LMP Subtrees
+ *
+ * We have two types of subtrees - a statically defined, constant set and
+ * a class set - one for each class. The static ones are before all the class ones
+ */
+enum {
+ LMP_TREE_MAIN,
+ LMP_TREE_HEADER,
+ LMP_TREE_HEADER_FLAGS,
+ LMP_TREE_OBJECT_HEADER,
+ LMP_TREE_ERROR_FLAGS,
+ LMP_TREE_BEGIN_VERIFY_FLAGS,
+ LMP_TREE_BEGIN_VERIFY_TRANSPORT_FLAGS,
+ LMP_TREE_TE_LINK_FLAGS,
+ LMP_TREE_DATA_LINK_FLAGS,
+ LMP_TREE_DATA_LINK_SUBOBJ,
+ LMP_TREE_CHANNEL_STATUS_ID,
+
+ LMP_TREE_CLASS_START
+};
+#define NUM_LMP_SUBTREES (LMP_TREE_CLASS_START + LMP_CLASS_MAX)
+
+static gint lmp_subtree[NUM_LMP_SUBTREES];
+
+static int lmp_class_to_subtree(int class)
+{
+ if (VALID_CLASS(class))
+ return lmp_subtree[LMP_TREE_CLASS_START + class];
+
+ return -1;
+}
+
+/*------------------------------------------------------------------------------
+ * Da code
+ */
+
+static void
+dissect_lmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ int offset = 0;
+ proto_tree *lmp_tree = NULL, *ti, *ti2;
+ proto_tree *lmp_header_tree;
+ proto_tree *lmp_header_flags_tree;
+ proto_tree *lmp_object_tree;
+ proto_tree *lmp_object_header_tree;
+ proto_tree *lmp_flags_tree;
+ proto_tree *lmp_subobj_tree;
+
+ guint8 version;
+ guint8 flags;
+ guint8 message_type;
+ guint16 cksum, computed_cksum;
+ vec_t cksum_vec[1];
+ int i, j, k, l, len;
+ int msg_length;
+ int obj_length;
+ int mylen;
+ int offset2;
+ char *objtype;
+ int session_off, tempfilt_off;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LMP");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ version = (tvb_get_guint8(tvb, offset+0)) >> 4;
+ flags = tvb_get_guint8(tvb, offset+2);
+ message_type = tvb_get_guint8(tvb, offset+3);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_str(pinfo->cinfo, COL_INFO,
+ val_to_str(message_type, message_type_vals, "Unknown (%u). "));
+ }
+
+ if (tree) {
+ msg_length = tvb_get_ntohs(tvb, offset+4);
+ ti = proto_tree_add_item(tree, proto_lmp, tvb, offset, msg_length,
+ FALSE);
+ lmp_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_MAIN]);
+
+ ti = proto_tree_add_text(lmp_tree, tvb, offset, 12, "LMP Header. %s",
+ val_to_str(message_type, message_type_vals,
+ "Unknown Message (%u). "));
+ lmp_header_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_HEADER]);
+
+ proto_tree_add_text(lmp_header_tree, tvb, offset, 1, "LMP Version: %u",
+ version);
+ ti = proto_tree_add_text(lmp_header_tree, tvb, offset+2, 1, "Flags: %02x",
+ flags);
+ lmp_header_flags_tree = proto_item_add_subtree(ti, lmp_subtree[LMP_TREE_HEADER_FLAGS]);
+ proto_tree_add_boolean(lmp_header_flags_tree, lmp_filter[LMPF_HDR_FLAGS_CC_DOWN],
+ tvb, offset+2, 1, flags);
+ proto_tree_add_boolean(lmp_header_flags_tree, lmp_filter[LMPF_HDR_FLAGS_REBOOT],
+ tvb, offset+2, 1, flags);
+ proto_tree_add_boolean(lmp_header_flags_tree, lmp_filter[LMPF_HDR_FLAGS_DWDM],
+ tvb, offset+2, 1, flags);
+ proto_tree_add_boolean(lmp_header_flags_tree, lmp_filter[LMPF_HDR_FLAGS_AUTHENTICATION],
+ tvb, offset+2, 1, flags);
+ proto_tree_add_uint(lmp_header_tree, lmp_filter[LMPF_MSG], tvb,
+ offset+3, 1, message_type);
+ proto_tree_add_text(lmp_header_tree, tvb, offset+4, 2, "Length: %d bytes",
+ msg_length);
+ proto_tree_add_boolean_hidden(lmp_header_tree, lmp_filter[LMPF_MSG + message_type], tvb,
+ offset+3, 1, 1);
+
+ cksum = tvb_get_ntohs(tvb, offset+6);
+ if (!pinfo->fragmented && (int) tvb_length(tvb) >= msg_length) {
+ /* The packet isn't part of a fragmented datagram and isn't
+ truncated, so we can checksum it. */
+ cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, msg_length);
+ cksum_vec[0].len = msg_length;
+ computed_cksum = in_cksum(&cksum_vec[0], 1);
+ if (computed_cksum == 0) {
+ proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
+ "Message Checksum: 0x%04x (correct)",
+ cksum);
+ } else {
+ proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
+ "Message Checksum: 0x%04x (incorrect, should be 0x%04x)",
+ cksum,
+ in_cksum_shouldbe(cksum, computed_cksum));
+ }
+ } else {
+ proto_tree_add_text(lmp_header_tree, tvb, offset+6, 2,
+ "Message Checksum: 0x%04x",
+ cksum);
+ }
+ proto_tree_add_text(lmp_header_tree, tvb, offset+8, 4,
+ "Local Control Channel ID: %d (%s)",
+ tvb_get_ntohl(tvb, offset+8),
+ ip_to_str(tvb_get_ptr(tvb, offset+8, 4)));
+
+ offset += 8;
+ len = 8;
+ while (len < msg_length) {
+ guint8 class;
+ guint8 type;
+ guint8 negotiable;
+ char *object_type;
+
+ obj_length = tvb_get_ntohs(tvb, offset+2);
+ class = tvb_get_guint8(tvb, offset+1);
+ type = tvb_get_guint8(tvb, offset);
+ negotiable = (type >> 7); type &= 0x7f;
+ object_type = val_to_str(class, lmp_class_vals, "Unknown");
+ proto_tree_add_uint_hidden(lmp_tree, lmp_filter[LMPF_OBJECT], tvb,
+ offset, 1, class);
+ ti = proto_tree_add_item(lmp_tree, lmp_filter[lmp_class_to_filter_num(class)],
+ tvb, offset, obj_length, FALSE);
+
+ lmp_object_tree = proto_item_add_subtree(ti, lmp_class_to_subtree(class));
+
+ ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset, 4,
+ "Header. Class %d, C-Type %d, Length %d, %s",
+ class, type, obj_length,
+ negotiable ? "Negotiable" : "Not Negotiable");
+ lmp_object_header_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_OBJECT_HEADER]);
+ proto_tree_add_text(lmp_object_header_tree, tvb, offset, 1,
+ negotiable ? "Negotiable" : "Not Negotiable");
+ proto_tree_add_text(lmp_object_header_tree, tvb, offset+2, 2,
+ "Length: %u", obj_length);
+ proto_tree_add_text(lmp_object_header_tree, tvb, offset+1, 1,
+ "Object Class: %u - %s",
+ class, object_type);
+ proto_tree_add_item(lmp_object_header_tree, lmp_filter[LMPF_VAL_CTYPE],
+ tvb, offset, 1, type);
+ offset2 = offset+4;
+ mylen = obj_length - 4;
+
+ switch(class) {
+
+ case LMP_CLASS_NULL:
+ break;
+
+ case LMP_CLASS_LOCAL_CCID:
+ case LMP_CLASS_REMOTE_CCID:
+ switch(type) {
+ case 1:
+ l = (class == LMP_CLASS_LOCAL_CCID) ?
+ LMPF_VAL_LOCAL_CCID : LMPF_VAL_REMOTE_CCID;
+ proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
+ proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
+ tvb_get_ntohl(tvb, offset2));
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_LOCAL_NODE_ID:
+ case LMP_CLASS_REMOTE_NODE_ID:
+ switch(type) {
+ case 1:
+ l = (class == LMP_CLASS_LOCAL_NODE_ID) ?
+ LMPF_VAL_LOCAL_NODE_ID : LMPF_VAL_REMOTE_NODE_ID;
+ proto_item_append_text(ti, ": %s",
+ ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
+ FALSE);
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_LOCAL_LINK_ID:
+ case LMP_CLASS_REMOTE_LINK_ID:
+ switch(type) {
+ case 1:
+ l = (class == LMP_CLASS_LOCAL_LINK_ID) ?
+ LMPF_VAL_LOCAL_LINK_ID_IPV4 : LMPF_VAL_REMOTE_LINK_ID_IPV4;
+ proto_item_append_text(ti, ": IPv4 %s",
+ ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
+ FALSE);
+ break;
+ case 2:
+ proto_item_append_text(ti, ": IPv6 %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
+ break;
+ case 3:
+ l = (class == LMP_CLASS_LOCAL_LINK_ID) ?
+ LMPF_VAL_LOCAL_LINK_ID_UNNUM : LMPF_VAL_REMOTE_LINK_ID_UNNUM;
+ proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
+ FALSE);
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_LOCAL_INTERFACE_ID:
+ case LMP_CLASS_REMOTE_INTERFACE_ID:
+ switch(type) {
+ case 1:
+ l = (class == LMP_CLASS_LOCAL_INTERFACE_ID) ?
+ LMPF_VAL_LOCAL_INTERFACE_ID_IPV4 : LMPF_VAL_REMOTE_INTERFACE_ID_IPV4;
+ proto_item_append_text(ti, ": IPv4 %s",
+ ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
+ FALSE);
+ break;
+ case 2:
+ proto_item_append_text(ti, ": IPv6 %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, 16, "IPv6: %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
+ break;
+ case 3:
+ l = (class == LMP_CLASS_LOCAL_INTERFACE_ID) ?
+ LMPF_VAL_LOCAL_INTERFACE_ID_UNNUM : LMPF_VAL_REMOTE_INTERFACE_ID_UNNUM;
+ proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
+ FALSE);
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_MESSAGE_ID:
+ case LMP_CLASS_MESSAGE_ID_ACK:
+ switch(type) {
+ case 1:
+ l = (class == LMP_CLASS_MESSAGE_ID) ?
+ LMPF_VAL_MESSAGE_ID : LMPF_VAL_MESSAGE_ID_ACK;
+ proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
+ proto_tree_add_uint(lmp_object_tree, lmp_filter[l], tvb, offset2, 4,
+ tvb_get_ntohl(tvb, offset2));
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_CONFIG:
+ switch(type) {
+ case 1:
+ proto_item_append_text(ti, ": HelloInterval: %d, HelloDeadInterval: %d",
+ tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
+ proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO],
+ tvb, offset2, 2, tvb_get_ntohs(tvb, offset2));
+ proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_CONFIG_HELLO_DEAD],
+ tvb, offset2+2, 2, tvb_get_ntohs(tvb, offset2+2));
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_HELLO:
+ switch(type) {
+ case 1:
+ proto_item_append_text(ti, ": TxSeq %d, RxSeq: %d",
+ tvb_get_ntohl(tvb, offset2),
+ tvb_get_ntohl(tvb, offset2+4));
+ proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_TXSEQ],
+ tvb, offset2, 4, tvb_get_ntohl(tvb, offset2));
+ proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_HELLO_RXSEQ],
+ tvb, offset2+4, 4, tvb_get_ntohl(tvb, offset2+4));
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_BEGIN_VERIFY:
+ switch(type) {
+ case 1:
+ l = tvb_get_ntohs(tvb, offset2);
+ ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS],
+ tvb, offset2, 2, FALSE);
+
+ lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_BEGIN_VERIFY_FLAGS]);
+ proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_ALL_LINKS],
+ tvb, offset2, 2, l);
+ proto_tree_add_boolean(lmp_flags_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_FLAGS_LINK_TYPE],
+ tvb, offset2, 2, l);
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
+ "Verify Interval: %d ms", tvb_get_ntohs(tvb, offset2+2));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 4,
+ "Number of Data Links: %d", tvb_get_ntohl(tvb, offset2+4));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_BEGIN_VERIFY_ENCTYPE],
+ tvb, offset2+8, 1, FALSE);
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+10, 2,
+ "Verify Transport Mechanism: 0x%0x", tvb_get_ntohs(tvb, offset2+10));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+12, 4,
+ "Transmission Rate: %ld", tvb_ieee_to_long(tvb, offset2+12));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+16, 4,
+ "Wavelength: %d", tvb_get_ntohl(tvb, offset2+4));
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_BEGIN_VERIFY_ACK:
+ switch(type) {
+ case 1:
+ proto_item_append_text(ti, ": VerifyDeadInterval: %d, TransportResponse: 0x%0x",
+ tvb_get_ntohs(tvb, offset2), tvb_get_ntohs(tvb, offset2+2));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, 2,
+ "VerifyDeadInterval: %d ms", tvb_get_ntohs(tvb, offset2));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+2, 2,
+ "Verify Transport Response: 0x%0x", tvb_get_ntohs(tvb, offset2+2));
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_VERIFY_ID:
+ switch(type) {
+ case 1:
+ proto_item_append_text(ti, ": %d", tvb_get_ntohl(tvb, offset2));
+ proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_VERIFY_ID], tvb, offset2, 4,
+ tvb_get_ntohl(tvb, offset2));
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_TE_LINK:
+ l = tvb_get_guint8(tvb, offset2);
+ ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_FLAGS],
+ tvb, offset2, 1, l);
+ proto_item_append_text(ti2, ": %s%s",
+ (l&0x01) ? "Fault-Mgmt-Supported " : "",
+ (l&0x02) ? "Link-Verification-Supported " : "");
+ lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_TE_LINK_FLAGS]);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_TE_LINK_FLAGS_FAULT_MGMT],
+ tvb, offset2, 1, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_TE_LINK_FLAGS_LINK_VERIFY],
+ tvb, offset2, 1, l);
+ switch(type) {
+ case 1:
+ proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
+ ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
+ ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_IPV4],
+ tvb, offset2+4, 4, FALSE);
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_IPV4],
+ tvb, offset2+8, 4, FALSE);
+ break;
+ case 2:
+ proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16, "TE-Link Local ID - IPv6: %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16, "TE-Link Remote ID - IPv6: %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
+ break;
+ case 3:
+ proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
+ tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_LOCAL_UNNUM],
+ tvb, offset2+4, 4, FALSE);
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_TE_LINK_REMOTE_UNNUM],
+ tvb, offset2+8, 4, FALSE);
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ case LMP_CLASS_DATA_LINK:
+ l = tvb_get_guint8(tvb, offset2);
+ ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_FLAGS],
+ tvb, offset2, 1, l);
+ proto_item_append_text(ti2, ": %s%s",
+ (l&0x01) ? "Interface-Type-Port " : "Interface-Type-Component-Link ",
+ (l&0x02) ? "Allocated " : "Unallocated ");
+ lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_DATA_LINK_FLAGS]);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_PORT],
+ tvb, offset2, 1, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_DATA_LINK_FLAGS_ALLOCATED],
+ tvb, offset2, 1, l);
+ switch(type) {
+ case 1:
+ proto_item_append_text(ti, ": IPv4: Local %s, Remote %s",
+ ip_to_str(tvb_get_ptr(tvb, offset2+4, 4)),
+ ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_IPV4],
+ tvb, offset2+4, 4, FALSE);
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_IPV4],
+ tvb, offset2+8, 4, FALSE);
+ l = 12;
+ break;
+ case 2:
+ proto_item_append_text(ti, ": IPv6: Local %s, Remote %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)),
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+8, 16)));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+4, 16,
+ "Data-Link Local ID - IPv6: %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+20,16,
+ "Data-Link Remote ID - IPv6: %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+4, 16)));
+ l = 36;
+ break;
+ case 3:
+ proto_item_append_text(ti, ": Unnumbered: Local %d, Remote %d",
+ tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8));
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_LOCAL_UNNUM],
+ tvb, offset2+4, 4, FALSE);
+ proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_REMOTE_UNNUM],
+ tvb, offset2+8, 4, FALSE);
+ l = 12;
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+
+ while (l < obj_length - 4) {
+ mylen = tvb_get_guint8(tvb, offset2+l+1);
+ ti2 = proto_tree_add_item(lmp_object_tree, lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ],
+ tvb, offset2+l, mylen, FALSE);
+ lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_DATA_LINK_SUBOBJ]);
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
+ "Subobject Type: %d", tvb_get_guint8(tvb, offset2+l));
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+1, 1,
+ "Subobject Length: %d", mylen);
+ switch(tvb_get_guint8(tvb, offset2+l)) {
+ case 1:
+ proto_item_set_text(ti2, "Interface Switching Capability: "
+ "Switching Cap: %s, Encoding Type: %s, Min BW: %ld, Max BW: %ld",
+ val_to_str(tvb_get_guint8(tvb, offset2+l+2),
+ gmpls_switching_type_str, "Unknown (%d)"),
+ val_to_str(tvb_get_guint8(tvb, offset2+l+3),
+ gmpls_lsp_enc_str, "Unknown (%d)"),
+ tvb_ieee_to_long(tvb, offset2+l+4),
+ tvb_ieee_to_long(tvb, offset2+l+8));
+ proto_tree_add_item(lmp_subobj_tree,
+ lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_SWITCHING_TYPE],
+ tvb, offset2+l+2, 1, FALSE);
+ proto_tree_add_item(lmp_subobj_tree,
+ lmp_filter[LMPF_VAL_DATA_LINK_SUBOBJ_LSP_ENCODING],
+ tvb, offset2+l+3, 1, FALSE);
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
+ "Minimum Reservable Bandwidth: %ld bytes/s",
+ tvb_ieee_to_long(tvb, offset2+l+4));
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+8, 4,
+ "Maximum Reservable Bandwidth: %ld bytes/s",
+ tvb_ieee_to_long(tvb, offset2+l+8));
+ break;
+
+ case 2:
+ proto_item_set_text(ti2, "Wavelength: %d",
+ tvb_get_ntohl(tvb, offset2+l+2));
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l+4, 4,
+ "Wavelength: %d",
+ tvb_get_ntohl(tvb, offset2+l+2));
+ break;
+
+ default:
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l,
+ tvb_get_guint8(tvb, offset2+l+1),
+ "Data (%d bytes)", tvb_get_guint8(tvb, offset2+l+1));
+ break;
+ }
+ l += tvb_get_guint8(tvb, offset2+l+1);
+ }
+
+ break;
+
+ case LMP_CLASS_CHANNEL_STATUS:
+ k = 0; j = 0;
+ switch(type) {
+ case 1:
+ case 3:
+ k = 8; break;
+ case 2:
+ k = 20; break;
+ }
+ if (!k)
+ break;
+ for (l=0; l<obj_length - 4; ) {
+ ti2 = proto_tree_add_text(lmp_object_tree, tvb, offset2+l, k,
+ "Interface-Id");
+ lmp_subobj_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_CHANNEL_STATUS_ID]);
+ switch(type) {
+ case 1:
+ if (j < 4)
+ proto_item_append_text(ti, ": [IPv4-%s",
+ ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
+ proto_item_append_text(ti2, ": IPv4 %s",
+ ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
+ "Interface ID: IPv4: %s",
+ ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
+ l += 4;
+ break;
+ case 2:
+ if (j < 4)
+ proto_item_append_text(ti, ": [IPv6-%s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
+ proto_item_append_text(ti2, ": IPv6 %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2, 16, "Interface ID: IPv6: %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l, 16)));
+ l += 16;
+ break;
+ case 3:
+ if (j < 4)
+ proto_item_append_text(ti, ": [Unnum-%d", tvb_get_ntohl(tvb, offset2+l));
+ proto_item_append_text(ti, ": Unnumbered %d", tvb_get_ntohl(tvb, offset2+l));
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
+ "Interface ID: Unnumbered: %d",
+ tvb_get_ntohl(tvb, offset2+l));
+ l += 4;
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
+ "Data (%d bytes)", obj_length-4-l);
+ l = obj_length - 4;
+ break;
+ }
+ if (l == obj_length - 4) break;
+
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 1,
+ tvb_get_guint8(tvb, offset2+l) & 0x80 ?
+ "Link Allocated - Active Monitoring" :
+ "Link Not Allocated");
+ if (j < 4)
+ proto_item_append_text(ti, "-%s,%s], ",
+ tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Act" : "NA",
+ val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
+ channel_status_short_str, "UNK (%u)."));
+ proto_item_append_text(ti2, ": %s, ",
+ tvb_get_guint8(tvb, offset2+l) & 0x80 ? "Active" : "Not Active");
+ proto_tree_add_text(lmp_subobj_tree, tvb, offset2+l, 4,
+ "Channel Status: %s",
+ val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
+ channel_status_str, "Unknown (%u). "));
+ proto_item_append_text(ti2, val_to_str(tvb_get_ntohl(tvb, offset2+l) & 0x7fffffff,
+ channel_status_str, "Unknown (%u). "));
+ j++;
+ l += 4;
+ if (j==4 && l < obj_length - 4)
+ proto_item_append_text(ti, " ...");
+ }
+ break;
+
+ case LMP_CLASS_CHANNEL_STATUS_REQUEST:
+ for (l=0; l<obj_length - 4; ) {
+ switch(type) {
+ case 1:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
+ "Interface ID: IPv4: %s",
+ ip_to_str(tvb_get_ptr(tvb, offset2+l, 4)));
+ l += 4;
+ break;
+ case 2:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 16, "Interface ID: IPv6: %s",
+ ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l,16)));
+ l += 16;
+ break;
+ case 3:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+l, 4,
+ "Interface ID: Unnumbered: %d",
+ tvb_get_ntohl(tvb, offset2+l));
+ l += 4;
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2+l, obj_length-4-l,
+ "Data (%d bytes)", obj_length-4-l);
+ l = obj_length - 4;
+ break;
+ }
+ }
+ break;
+
+ case LMP_CLASS_ERROR:
+ l = tvb_get_ntohl(tvb, offset2);
+ ti2 = proto_tree_add_uint(lmp_object_tree, lmp_filter[LMPF_VAL_ERROR],
+ tvb, offset2, 4, l);
+
+ switch(type) {
+ case 1:
+ proto_item_append_text(ti, ": BEGIN_VERIFY_ERROR: %s%s%s%s",
+ (l&0x01) ? "Unsupported-Link " : "",
+ (l&0x02) ? "Unwilling" : "",
+ (l&0x04) ? "Unsupported-Transport" : "",
+ (l&0x08) ? "TE-Link-ID" : "");
+ lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_VERIFY_UNSUPPORTED_LINK],
+ tvb, offset, 4, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_VERIFY_UNWILLING],
+ tvb, offset, 4, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_VERIFY_TRANSPORT],
+ tvb, offset, 4, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_VERIFY_TE_LINK_ID],
+ tvb, offset, 4, l);
+ break;
+ case 2:
+ proto_item_append_text(ti, ": LINK_SUMMARY_ERROR: %s%s%s%s%s",
+ (l&0x01) ? "Unacceptable-Params " : "",
+ (l&0x02) ? "Renegotiate" : "",
+ (l&0x04) ? "Remote-Link-ID" : "",
+ (l&0x08) ? "TE-Link" : "",
+ (l&0x10) ? "Data-Link" : "");
+ lmp_flags_tree = proto_item_add_subtree(ti2, lmp_subtree[LMP_TREE_ERROR_FLAGS]);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_PARAMETERS],
+ tvb, offset, 4, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_SUMMARY_RENEGOTIATE],
+ tvb, offset, 4, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_REMOTE_LINK_ID],
+ tvb, offset, 4, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_TE_LINK],
+ tvb, offset, 4, l);
+ proto_tree_add_boolean(lmp_flags_tree,
+ lmp_filter[LMPF_VAL_ERROR_SUMMARY_BAD_DATA_LINK],
+ tvb, offset, 4, l);
+ break;
+ default:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+ }
+ break;
+
+ default :
+ default_class:
+ proto_tree_add_text(lmp_object_tree, tvb, offset2, mylen,
+ "Data (%d bytes)", mylen);
+ break;
+
+ }
+
+ offset += obj_length;
+ len += obj_length;
+ }
+ }
+}
+
+void
+proto_register_lmp(void)
+{
+ static gint *ett[NUM_LMP_SUBTREES];
+ int i;
+
+ for (i=0; i<NUM_LMP_SUBTREES; i++) {
+ lmp_subtree[i] = -1;
+ ett[i] = &lmp_subtree[i];
+ }
+
+ proto_lmp = proto_register_protocol("Link Management Protocol (LMP)",
+ "LMP", "lmp");
+ proto_register_field_array(proto_lmp, lmpf_info, array_length(lmpf_info));
+ proto_register_subtree_array(ett, array_length(ett));
+}
+
+void
+proto_reg_handoff_lmp(void)
+{
+ dissector_handle_t lmp_handle;
+
+ lmp_handle = create_dissector_handle(dissect_lmp, proto_lmp);
+ dissector_add("ip.proto", IP_PROTO_LMP, lmp_handle);
+}