Wireshark-dev: Re: [Wireshark-dev] Adding CFM plugin and requesting review.
From: keith mercer <maulkin@xxxxxxxx>
Date: Fri, 21 Dec 2007 21:13:27 -0800 (PST)
Hey Alex,
I have already coded up the CFM protocol in the recently release version of Wireshark v0.99.7. The source code is under the packet-cfm.c file in the /epan/dissectors directory. It includes both the IEEE and the ITU current recommendations of the specification.
Cheers,
--Keith
----- Original Message ----
From: alex rozin <arozin@xxxxxxx>
To: maulkin@xxxxxxxx
Sent: Wednesday, December 19, 2007 2:21:29 AM
Subject: [Wireshark-dev] Adding CFM plugin and requesting review.
Hi,
I am a newby in wireshark (while in ethereal I participated in MSTP
dissector).
I looked for an option to debug my 802.1ag implementation and found some
code in
http://www.mail-archive.com/wireshark-dev@xxxxxxxxxxxxx/msg07229/packet-ieee8021ag.c
Good work!
I fixed a few of little bugs in this code and supplemented it with TLV
parsing, LBM/LBR, DMM/DMR and LTM/LTR. I also did operation code
oriented parsing of the field FLAGS.
The patch I attached to this message.
Let me know if you want to have the complete file instead of a patch.
Sure you free to use it at your discretion. I'd be glad to have it in a
next version of wireshark.
Thanks & regards,
Alex
-----Inline Attachment Follows-----
diff -rBbNu wireshark-0.99.6/epan/dissectors/Makefile.common wireshark-0.99.6.new/epan/dissectors/Makefile.common
--- wireshark-0.99.6/epan/dissectors/Makefile.common 2007-07-05 22:24:58.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/Makefile.common 2007-12-13 11:13:40.000000000 +0200
@@ -228,6 +228,7 @@
packet-catapult-dct2000.c \
packet-ccsds.c \
packet-cdp.c \
+ packet-ieee8021ag.c \
packet-cgmp.c \
packet-chdlc.c \
packet-cigi.c \
@@ -753,6 +754,7 @@
packet-scsi-osd.c \
packet-sctp.c \
packet-ssl-utils.c \
+ packet-ieee8021ag.c \
packet-user_encap.c
# corresponding headers
diff -rBbNu wireshark-0.99.6/epan/dissectors/Makefile.in wireshark-0.99.6.new/epan/dissectors/Makefile.in
--- wireshark-0.99.6/epan/dissectors/Makefile.in 2007-07-05 22:26:07.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/Makefile.in 2007-12-13 11:15:51.000000000 +0200
@@ -211,6 +211,7 @@
libcleandissectors_la-packet-catapult-dct2000.lo \
libcleandissectors_la-packet-ccsds.lo \
libcleandissectors_la-packet-cdp.lo \
+ libcleandissectors_la-packet-ieee8021ag.lo \
libcleandissectors_la-packet-cgmp.lo \
libcleandissectors_la-packet-chdlc.lo \
libcleandissectors_la-packet-cigi.lo \
@@ -1218,6 +1219,7 @@
packet-catapult-dct2000.c \
packet-ccsds.c \
packet-cdp.c \
+ packet-ieee8021ag.c \
packet-cgmp.c \
packet-chdlc.c \
packet-cigi.c \
@@ -2258,6 +2260,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-catapult-dct2000.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-ccsds.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-cdp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-cgmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-chdlc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-cigi.Plo@am__quote@
@@ -3471,6 +3474,13 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -c -o libcleandissectors_la-packet-cdp.lo `test -f 'packet-cdp.c' || echo '$(srcdir)/'`packet-cdp.c
+libcleandissectors_la-packet-ieee8021ag.lo: packet-ieee8021ag.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -MT libcleandissectors_la-packet-ieee8021ag.lo -MD -MP -MF "$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Tpo" -c -o libcleandissectors_la-packet-ieee8021ag.lo `test -f 'packet-ieee8021ag.c' || echo '$(srcdir)/'`packet-ieee8021ag.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Tpo" "$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Plo"; else rm -f "$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet-ieee8021ag.c' object='libcleandissectors_la-packet-ieee8021ag.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -c -o libcleandissectors_la-packet-ieee8021ag.lo `test -f 'packet-ieee8021ag.c' || echo '$(srcdir)/'`packet-ieee8021ag.c
+
libcleandissectors_la-packet-cgmp.lo: packet-cgmp.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -MT libcleandissectors_la-packet-cgmp.lo -MD -MP -MF "$(DEPDIR)/libcleandissectors_la-packet-cgmp.Tpo" -c -o libcleandissectors_la-packet-cgmp.lo `test -f 'packet-cgmp.c' || echo '$(srcdir)/'`packet-cgmp.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libcleandissectors_la-packet-cgmp.Tpo" "$(DEPDIR)/libcleandissectors_la-packet-cgmp.Plo"; else rm -f "$(DEPDIR)/libcleandissectors_la-packet-cgmp.Tpo"; exit 1; fi
diff -rBbNu wireshark-0.99.6/epan/dissectors/packet-chdlc.c wireshark-0.99.6.new/epan/dissectors/packet-chdlc.c
--- wireshark-0.99.6/epan/dissectors/packet-chdlc.c 2007-07-05 22:25:03.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/packet-chdlc.c 2007-12-13 13:50:19.000000000 +0200
@@ -103,6 +103,7 @@
{CHDLCTYPE_OSI, "OSI" },
{ETHERTYPE_MPLS, "MPLS unicast"},
{ETHERTYPE_MPLS_MULTI, "MPLS multicast"},
+ {ETHERTYPE_IEEE_802_1AG, "802.1ag CFM"},
{0, NULL}
};
diff -rBbNu wireshark-0.99.6/epan/dissectors/packet-ethertype.c wireshark-0.99.6.new/epan/dissectors/packet-ethertype.c
--- wireshark-0.99.6/epan/dissectors/packet-ethertype.c 2007-07-05 22:24:56.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/packet-ethertype.c 2007-12-13 13:53:14.000000000 +0200
@@ -131,6 +131,7 @@
{PPP_PAP, "PPP Password Authentication Protocol" },
{PPP_CCP, "PPP Compression Control Protocol" },
{ETHERTYPE_LLT, "Veritas Low Latency Transport (not officially registered)"},
+ {ETHERTYPE_IEEE_802_1AG, "802.1ag CFM"},
{ETHERTYPE_FCOE, "Fibre Channel over Ethernet" },
{0, NULL } };
diff -rBbNu wireshark-0.99.6/epan/dissectors/packet-ieee8021ag.c wireshark-0.99.6.new/epan/dissectors/packet-ieee8021ag.c
--- wireshark-0.99.6/epan/dissectors/packet-ieee8021ag.c 2007-12-18 11:43:43.000000000 +0200
+++ wireshark-0.99.6.new/epan/dissectors/packet-ieee8021ag.c 2007-12-18 11:40:10.000000000 +0200
@@ -1,5 +1,8 @@
/* packet-ieee8021ag.h
* Routines for IEEE 802.1ag dissection
+ *
+ * Copyright (C) 2007 Alex Rizin, MRV, <arozin dot mrv com>
+ *
* Copyright 2007 _FF_
* Francesco Fondelli <francesco dot fondelli, gmail dot com>
*
@@ -57,7 +60,15 @@
#define IEEE8021AG_MAID_LEN 48
-static const guint32 flags_offset = 2;
+#define CFM_CCM_FLAGS_RDI_MASK 0x80
+#define CFM_CCM_FLAGS_RES_MASK 0x78
+#define CFM_CCM_FLAGS_INTERVAL_MASK 0x07
+
+#define CFM_LTM_USE_FDB_ONLY_MASK 0x80
+#define CFM_LTM_RES_MASK 0x7f
+#define CFM_LTR_FWD_YES_MASK 0x40
+#define CFM_LTR_TERM_MEP_MASK 0x20
+#define CFM_LTR_RES_MASK 0x1f
static const guint32 flags_size = 1;
static const guint32 ftlvo_offset = 3;
static const guint32 ftlvo_size = 1;
@@ -83,6 +94,19 @@
static int hf_ieee8021ag_ccm_txfcf = -1;
static int hf_ieee8021ag_ccm_rxfcb = -1;
static int hf_ieee8021ag_ccm_txfcb = -1;
+static int hf_ieee8021ag_ltm_trn_num = -1;
+static int hf_ieee8021ag_ltm_ttl = -1;
+static int hf_ieee8021ag_ltm_use_fdb_only = -1;
+static int hf_ieee8021ag_fwd_yes = -1;
+static int hf_ieee8021ag_term = -1;
+static int hf_ieee8021ag_ltr_res = -1;
+static int hf_ieee8021ag_ltr_relay = -1;
+static int hf_ieee8021ag_ltm_res = -1;
+static int hf_ieee8021ag_tlv_type = -1;
+static int hf_ieee8021ag_tlv_len = -1;
+static int hf_ieee8021ag_tlv_value = -1;
+static int hf_ieee8021ag_tlv_port_status = -1;
+static int hf_ieee8021ag_tlv_if_status = -1;
static int hf_ieee8021ag_ccm_endtlv = -1;
/* maid fields */
@@ -99,7 +123,16 @@
/* subtree pointers */
static gint ett_ieee8021ag = -1;
static gint ett_ieee8021ag_ccm = -1;
+static gint ett_ieee8021ag_ltm = -1;
+static gint ett_ieee8021ag_ltr = -1;
+static gint ett_ieee8021ag_lbm = -1;
+static gint ett_ieee8021ag_lbr = -1;
+static gint ett_ieee8021ag_dmr = -1;
+static gint ett_ieee8021ag_dmm = -1;
static gint ett_ieee8021ag_maid = -1;
+static gint ett_ieee8021ag_tlv = -1;
+static gint ett_ieee8021ag_time = -1;
+static gint ett_ieee8021ag_flag = -1;
/* IEEE802.1ag/Y.1731, OpCode values */
static const range_string op_code_long_rvals[] = {
@@ -205,6 +238,42 @@
{ 0, 0, NULL }
};
+static const value_string ieee8021ag_ltr_relay_names[] = {
+ { 1, "RlyHit" },
+ { 2, "RlyFDB" },
+ { 3, "RlyMPDP"},
+};
+
+// find tlv_type
+//
+typedef enum {
+ eee8021ag_end_tlv = 0,
+ eee8021ag_sender_id_tlv,
+ eee8021ag_port_status_tlv,
+ eee8021ag_data_tlv,
+ eee8021ag_interface_status_tlv,
+ eee8021ag_reply_ingress_id_tlv,
+ eee8021ag_reply_egress_id_tlv,
+ eee8021ag_ltm_egress_id_tlv,
+ eee8021ag_ltr_egress_id_tlv,
+ eee8021ag_organization_specific_tlv = 31,
+ eee8021ag_test_tlv = 32,
+} ieee8021ag_tlv_t;
+
+static const value_string ieee8021ag_tlv_type_names[] = {
+ { eee8021ag_end_tlv, "End TLV" },
+ { eee8021ag_sender_id_tlv, "SenderId TLV" },
+ { eee8021ag_port_status_tlv, "PortStatus TLV" },
+ { eee8021ag_data_tlv, "Data TLV" },
+ { eee8021ag_interface_status_tlv, "InterfaceStatus TLV" },
+ { eee8021ag_reply_ingress_id_tlv, "ReplyIngress TLV" },
+ { eee8021ag_reply_egress_id_tlv, "Reply Egress TLV" },
+ { eee8021ag_ltm_egress_id_tlv, "LTM Egress TLV" },
+ { eee8021ag_ltr_egress_id_tlv, "LTR Egress TLV" },
+ { eee8021ag_organization_specific_tlv, "Organization Specific TLV" },
+ { eee8021ag_test_tlv, "Test TLV" },
+};
+
/* IEEE802.1ag/Y.1731, Association Name format type */
static const range_string maid_sformat_type_rvals[] = {
@@ -222,6 +291,27 @@
{ 0, 0, NULL }
};
+static const true_false_string yesno = {
+ "Yes",
+ "No"
+};
+
+static const value_string port_status_vals[] = {
+ { 0, "Invalid" },
+ { 1, "psBlocked" },
+ { 2, "psUp" },
+};
+
+static const value_string if_status_vals[] = {
+ { 0, "Invalid" },
+ { 1, "isUp" },
+ { 2, "isDown" },
+ { 3, "isTesting" },
+ { 4, "isUnknown" },
+ { 5, "isDormant" },
+ { 6, "isNotPresent" },
+ { 7, "isLowerLayerDown" },
+};
static void
dissect_maid(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
@@ -350,64 +440,110 @@
offset += pad_size;
}
-static void
-dissect_ccm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
+static void dissect_tlv (proto_tree *tree, tvbuff_t *tvb, guint32 *offset)
{
- guint8 rdi = 0;
- guint8 res1 = 0;
- guint32 res2 = 0;
- guint8 interval = 0;
- guint8 ftlvo = 0;
- guint32 seq_num = 0;
- guint16 mepid = 0;
- guint8 endtlv = 0;
+ guint8 tlv_type = 0;
+ guint16 tlv_length = 0;
+ guint8 t8 = 0;
proto_item *ti = NULL;
- proto_tree *ccm_tree = NULL;
+ proto_tree *subtree = NULL;
- /* create ccm subtree */
- ti = proto_tree_add_text(tree, tvb, offset, -1, "CCM");
- ccm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_ccm);
+ for (;;) {
+ if (! tvb_bytes_exist(tvb, *offset, 1)) {
+ proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed, tvb, *offset, 0, TRUE);
+ proto_tree_add_text(tree, tvb, *offset, -1, "Error: Packet does not have End TLV");
+ return;
+ }
+ tlv_type = tvb_get_guint8(tvb, *offset);
+ if (! tlv_type) {
+ proto_tree_add_uint(tree, hf_ieee8021ag_tlv_type, tvb, *offset, 1, tlv_type);
+ *offset += 1;
+ return; /* End TLV */
+ }
+ *offset += 1;
+ tlv_length = tvb_get_ntohs(tvb, *offset);
+ ti = proto_tree_add_text(tree, tvb, *offset, tlv_length, match_strval(tlv_type, ieee8021ag_tlv_type_names));
+ subtree = proto_item_add_subtree(ti, ett_ieee8021ag_tlv);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_tlv_type, tvb, *offset - 1, 1, tlv_type);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_tlv_len, tvb, *offset, 2, tlv_length);
+ *offset += 2;
+ switch (tlv_type) {
+ case eee8021ag_sender_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_port_status_tlv:
+ t8 = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_tlv_port_status, tvb, *offset, 1, t8);
+ break;
+ case eee8021ag_data_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_interface_status_tlv:
+ t8 = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_tlv_if_status, tvb, *offset, 1, t8);
+ break;
+ case eee8021ag_reply_ingress_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_reply_egress_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_ltm_egress_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_ltr_egress_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_organization_specific_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_test_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ default:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
- /* reinterpret flags field in ccm case */
- rdi = tvb_get_guint8(tvb, flags_offset) & 0x80;
- proto_tree_add_boolean(ccm_tree, hf_ieee8021ag_ccm_rdi,
- tvb, flags_offset, flags_size, rdi);
-
- res1 = tvb_get_guint8(tvb, flags_offset) & 0x78;
- proto_tree_add_uint_hidden(ccm_tree, hf_ieee8021ag_ccm_res1,
- tvb, flags_offset, flags_size, res1);
- if (res1 != 0) {
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, flags_offset, flags_size, TRUE);
- proto_tree_add_text(ccm_tree, tvb, flags_offset, flags_size,
- "Error: bit 7, 6, 5 and 4 of "
- "Flags field should be zero");
}
+ *offset += tlv_length;
+ }
+}
- interval = tvb_get_guint8(tvb, flags_offset) & 0x07;
- proto_tree_add_item(ccm_tree, hf_ieee8021ag_ccm_interval,
- tvb, flags_offset, flags_size, interval);
+static void check_specific_ftlvo (tvbuff_t *tvb, guint32 offset, proto_tree *tree, guint8 must_by_ftlvo)
+{
+ guint8 ftlvo;
/* check first tlv offset field */
ftlvo = tvb_get_guint8(tvb, ftlvo_offset);
- if (ftlvo < 70) {
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, ftlvo_offset, ftlvo_size, TRUE);
- proto_tree_add_text(ccm_tree, tvb, ftlvo_offset, ftlvo_size,
- "Error: First TLV Offset field "
- "should be >= 70");
- }
/* check advertised size agaist real pkt size */
if (!tvb_bytes_exist(tvb, offset, ftlvo + 1)) {
-
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, offset, 0, TRUE);
- proto_tree_add_text(ccm_tree, tvb, offset, -1,
- "Error: Packet too short");
+ proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed, tvb, offset, 0, TRUE);
+ proto_tree_add_text(tree, tvb, offset, -1, "Error: Packet too short");
THROW(ReportedBoundsError);
}
+ if (ftlvo < must_by_ftlvo) {
+ proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed, tvb, ftlvo_offset, ftlvo_size, TRUE);
+ proto_tree_add_text(tree, tvb, ftlvo_offset, ftlvo_size, "Error: First TLV Offset field should be >= %d", (int) must_by_ftlvo);
+ }
+}
+
+static void
+dissect_ccm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint32 res2 = 0;
+ guint32 seq_num = 0;
+ guint16 mepid = 0;
+ proto_item *ti = NULL;
+ proto_tree *ccm_tree = NULL;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "CCM");
+ ccm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_ccm);
+
+ check_specific_ftlvo (tvb, offset, ccm_tree, 70);
+
/* and finally others ccm fields */
seq_num = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(ccm_tree, hf_ieee8021ag_ccm_seq_num,
@@ -463,26 +599,74 @@
* d) Organization-Specific TLV (21.5.2).
*/
- /* there must be only one more byte: the stop byte (End TLV) */
- endtlv = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(ccm_tree, hf_ieee8021ag_ccm_endtlv,
- tvb, offset, 1, FALSE);
- if (endtlv != 0) {
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, offset, 1, TRUE);
- proto_tree_add_text(ccm_tree, tvb, offset, 1,
- "Error: End TLV octect "
- "should be set to zero");
+ dissect_tlv (ccm_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
}
- offset += 1;
+}
+
+static void dissect_timestamp (tvbuff_t *tvb, guint32 *offset, proto_tree *tree, const char * stamp_name)
+{
+ proto_item *ti = NULL;
+ proto_tree *subtree = NULL;
+
+ ti = proto_tree_add_text(tree, tvb, *offset, 8, stamp_name);
+ subtree = proto_item_add_subtree(ti, ett_ieee8021ag_time);
+ proto_tree_add_text(subtree, tvb, *offset, 4, "tv_sec: %lu sec.", (unsigned long) tvb_get_letohl(tvb, *offset));
+ *offset += 4;
+ proto_tree_add_text(subtree, tvb, *offset, 4, "tv_usec: %lu nanosec.", (unsigned long) tvb_get_letohl(tvb, *offset));
+ *offset += 4;
+}
+
+static void
+dissect_dmr(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *ti = NULL;
+ proto_tree *dmr_tree = NULL;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "DMR");
+ dmr_tree = proto_item_add_subtree(ti, ett_ieee8021ag_dmr);
+
+ check_specific_ftlvo (tvb, offset, dmr_tree, 32);
+
+ dissect_timestamp (tvb, &offset, dmr_tree, "T1");
+ dissect_timestamp (tvb, &offset, dmr_tree, "T2");
+ dissect_timestamp (tvb, &offset, dmr_tree, "T3");
+ dissect_timestamp (tvb, &offset, dmr_tree, "T4");
+
+ dissect_tlv (dmr_tree, tvb, &offset);
/* extra check: no more data should be present */
if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
+}
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, offset, 0, TRUE);
- proto_tree_add_text(ccm_tree, tvb, offset, -1,
- "Error: Packet too long");
+static void
+dissect_dmm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *ti = NULL;
+ proto_tree *dmm_tree = NULL;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "DMM");
+ dmm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_dmm);
+
+ check_specific_ftlvo (tvb, offset, dmm_tree, 32);
+
+ dissect_timestamp (tvb, &offset, dmm_tree, "T1");
+ dissect_timestamp (tvb, &offset, dmm_tree, "T2");
+ dissect_timestamp (tvb, &offset, dmm_tree, "T3");
+ dissect_timestamp (tvb, &offset, dmm_tree, "T4");
+
+ dissect_tlv (dmm_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
}
}
@@ -489,28 +674,164 @@
static void
dissect_lbr(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
{
- assert(tvb); assert(offset); assert(pinfo); assert(tree); //temp
+ proto_item *ti = NULL;
+ proto_tree *lbr_tree = NULL;
+ guint32 seq_num = 0;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "LBR");
+ lbr_tree = proto_item_add_subtree(ti, ett_ieee8021ag_lbr);
+
+ check_specific_ftlvo (tvb, offset, lbr_tree, 4);
+
+ seq_num = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(lbr_tree, hf_ieee8021ag_ccm_seq_num, tvb, offset, 4, seq_num);
+ offset += 4;
+
+ dissect_tlv (lbr_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
}
static void
dissect_lbm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
{
- assert(tvb); assert(offset); assert(pinfo); assert(tree); //temp
+ proto_item *ti = NULL;
+ proto_tree *lbm_tree = NULL;
+ guint32 seq_num = 0;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "LBM");
+ lbm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_lbm);
+
+ check_specific_ftlvo (tvb, offset, lbm_tree, 4);
+
+ seq_num = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(lbm_tree, hf_ieee8021ag_ccm_seq_num, tvb, offset, 4, seq_num);
+ offset += 4;
+
+ dissect_tlv (lbm_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
}
static void
dissect_ltr(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
{
- assert(tvb); assert(offset); assert(pinfo); assert(tree); //temp
-}
+ guint8 t8 = 0;
+ guint32 seq_num = 0;
+ proto_item *ti = NULL;
+ proto_tree *ltr_tree = NULL;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "LTR");
+ ltr_tree = proto_item_add_subtree(ti, ett_ieee8021ag_ltr);
+
+ check_specific_ftlvo (tvb, offset, ltr_tree, 6);
+
+ seq_num = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(ltr_tree, hf_ieee8021ag_ltm_trn_num, tvb, offset, 4, seq_num);
+ offset += 4;
+
+ t8 = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(ltr_tree, hf_ieee8021ag_ltm_ttl, tvb, offset, 1, t8);
+ offset += 1;
+
+ t8 = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(ltr_tree, hf_ieee8021ag_ltr_relay, tvb, offset, 1, t8);
+ offset += 1;
+
+ dissect_tlv (ltr_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
+} /* ltr end */
static void
dissect_ltm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
{
- assert(tvb); assert(offset); assert(pinfo); assert(tree); //temp
+ guint8 ttl = 0;
+ guint32 seq_num = 0;
+ proto_item *ti = NULL;
+ proto_tree *ltm_tree = NULL;
+ const guint8 *mac_addr;
+ gchar *mac_addr_str;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "LTM");
+ ltm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_ltm);
+
+ check_specific_ftlvo (tvb, offset, ltm_tree, 17);
+
+ seq_num = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(ltm_tree, hf_ieee8021ag_ltm_trn_num, tvb, offset, 4, seq_num);
+ offset += 4;
+
+ ttl = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(ltm_tree, hf_ieee8021ag_ltm_ttl, tvb, offset, 1, ttl);
+ offset += 1;
+
+ mac_addr = tvb_get_ptr(tvb, offset, 6);
+ mac_addr_str = ether_to_str(mac_addr);
+ proto_tree_add_text(ltm_tree, tvb, offset, 6, "Original MAC Address %s", mac_addr_str);
+ offset += 6;
+
+ mac_addr = tvb_get_ptr(tvb, offset, 6);
+ mac_addr_str = ether_to_str(mac_addr);
+ proto_tree_add_text(ltm_tree, tvb, offset, 6, "Target MAC Address %s", mac_addr_str);
+ offset += 6;
+
+ dissect_tlv (ltm_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
}
+static void dissect_flags (tvbuff_t *tvb, proto_tree *ieee8021ag_tree, guint8 opcode, guint32 offset)
+{
+ proto_item *ti = NULL;
+ proto_tree *subtree = NULL;
+ guint8 flags = 0;
+
+ flags = tvb_get_guint8(tvb, offset);
+ ti = proto_tree_add_item(ieee8021ag_tree, hf_ieee8021ag_flags, tvb, offset, 1, FALSE);
+ subtree = proto_item_add_subtree(ti, ett_ieee8021ag_flag);
+ switch (opcode) {
+ case 1:
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_ccm_rdi, tvb, offset, 1, flags);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_ccm_res1, tvb, offset, 1, flags);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_ccm_interval, tvb, offset, 1, flags);
+ break;
+ case 2: /* lbr */
+ break;
+ case 3: /* lbr */
+ break;
+ case 4: /* ltr */
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_ltm_use_fdb_only, tvb, offset, 1, flags);
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_fwd_yes, tvb, offset, 1, flags);
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_term, tvb, offset, 1, flags);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_ltr_res, tvb, offset, 1, flags);
+ break;
+ case 5: /* ltm */
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_ltm_use_fdb_only, tvb, offset, 1, flags);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_ltm_res, tvb, offset, 1, flags);
+ break;
+ default:
+ break;
+ }
+}
+
static void
dissect_ieee8021ag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
@@ -522,6 +843,7 @@
/* get at least a full message header */
if (!tvb_bytes_exist(tvb, 0, IEEE8021AG_HDR_LEN_MIN)) {
+ printf ("%s(%d) - %s\n", __FILE__, __LINE__, __FUNCTION__);
if (tree) {
proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
tvb, offset, 0, TRUE);
@@ -550,6 +872,7 @@
if (!tree) {
/* nothing to do, col info and proto info already done */
+ printf ("%s(%d) - %s\n", __FILE__, __LINE__, __FUNCTION__);
return;
}
@@ -571,8 +894,11 @@
opcode = tvb_get_guint8(tvb, offset);
proto_tree_add_item(ieee8021ag_tree, hf_ieee8021ag_op_code,
tvb, offset, 1, FALSE);
- offset += 1;
+ offset += 1;
+#if 1
+ dissect_flags (tvb, ieee8021ag_tree, opcode, offset);
+#else
/*
* FF: The rest is opCode specific. Please note that "Flags" field is
* hemmm "a placeholder where you can put whatever you want with
@@ -583,6 +909,7 @@
*/
proto_tree_add_item(ieee8021ag_tree, hf_ieee8021ag_flags,
tvb, offset, 1, FALSE);
+#endif
offset += 1;
proto_tree_add_item(ieee8021ag_tree, hf_ieee8021ag_ftlv_offset,
@@ -605,6 +933,12 @@
case 5:
return dissect_ltm(tvb, offset, pinfo, ieee8021ag_tree);
break;
+ case 46:
+ return dissect_dmr(tvb, offset, pinfo, ieee8021ag_tree);
+ break;
+ case 47:
+ return dissect_dmm(tvb, offset, pinfo, ieee8021ag_tree);
+ break;
default:
/* reserved pdu type, I can't do much */
if (tvb_bytes_exist(tvb, offset, 1)) {
@@ -680,7 +1014,7 @@
{
"Interval",
"ieee8021ag.ccm.interval",
- FT_UINT8, BASE_DEC, VALS(&ccm_interval_vals), 0x0,
+ FT_UINT8, BASE_DEC, VALS(&ccm_interval_vals), CFM_CCM_FLAGS_INTERVAL_MASK,
"The CCM transmission interval",
HFILL
}
@@ -709,7 +1043,8 @@
{
"RDI",
"ieee8021ag.ccm.rdi",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, 8, TFS(&yesno),
+ CFM_CCM_FLAGS_RDI_MASK,
"Whether the defect indication is communicated "
"by the transmitting MEP",
HFILL
@@ -715,15 +1050,15 @@
HFILL
}
},
+
{ &hf_ieee8021ag_ccm_res1,
- {
- "reserved",
- "ieee8021ag.ccm.res1",
- FT_UINT8, BASE_DEC, NULL, 0x0,
- "",
- HFILL
+ { "reserved", "ieee8021ag.ccm.res1",
+ FT_UINT8, BASE_DEC, NULL,
+ CFM_CCM_FLAGS_RES_MASK,
+ "", HFILL
}
},
+
{ &hf_ieee8021ag_ccm_res2,
{
"reserved",
@@ -773,6 +1108,120 @@
HFILL
}
},
+
+ { &hf_ieee8021ag_ltr_res,
+ { "reserved", "ieee8021ag.ccm.res1",
+ FT_UINT8, BASE_DEC, NULL, CFM_LTR_RES_MASK,
+ "", HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_ltm_trn_num,
+ {
+ "Transaction Number",
+ "ieee8021ag.ltm.trn_num",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "A MEP copies the contents of the nextLTMtransID variable (20.36.1) to this field",
+ HFILL
+ }
+ },
+ { &hf_ieee8021ag_ltm_ttl,
+ {
+ "TTL",
+ "ieee8021ag.ltm.ttl",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "TTL - time to live counter",
+ HFILL
+ }
+ },
+ { &hf_ieee8021ag_ltm_res,
+ { "reserved", "ieee8021ag.ccm.res1",
+ FT_UINT8, BASE_DEC, NULL, CFM_LTM_RES_MASK,
+ "", HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_ltm_use_fdb_only,
+ {
+ "useFDBonly",
+ "ieee8021ag.ltm.use_fdb_only",
+ FT_BOOLEAN, 8, TFS(&yesno), CFM_LTM_USE_FDB_ONLY_MASK,
+ "Only MAC addresses learned in a Bridge’s Filtering Database, and"
+ "not information saved in the MIP CCM Database, is to"
+ "be used to determine the Egress Port",
+ HFILL
+ }
+ },
+ { &hf_ieee8021ag_fwd_yes,
+ {
+ "FwdYes",
+ "ieee8021ag.ltm.fwd_yes",
+ FT_BOOLEAN, 8, TFS(&yesno), CFM_LTR_FWD_YES_MASK,
+ "The LTM was (1) or was not (0) forwarded",
+ HFILL
+ }
+ },
+ { &hf_ieee8021ag_term,
+ {
+ "TerminalMEP",
+ "ieee8021ag.ltm.terminal_mep",
+ FT_BOOLEAN, 8, TFS(&yesno), CFM_LTR_TERM_MEP_MASK,
+ "The MP reported in the Reply Egress TLV (Reply Ingress TLV, if"
+ "the Reply Egress TLV is not present) is a MEP",
+ HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_ltr_relay,
+ {
+ "Relay Action",
+ "ieee8021ag.ltr.relay",
+ FT_UINT8, BASE_DEC, VALS(&ieee8021ag_ltr_relay_names), 0x0,
+ "Reports how the data frame targeted by the LTM would be passed through the MAC Relay Entity to"
+ "the Egress Bridge Port",
+ HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_tlv_type,
+ { "Type", "ieee8021ag.tlv.type",
+ FT_UINT8, BASE_DEC, VALS(ieee8021ag_tlv_type_names), 0x0,
+ "TLV Type", HFILL
+ }
+ },
+ { &hf_ieee8021ag_tlv_len,
+ { "Length", "ieee8021ag.tlv.len",
+ FT_UINT16, BASE_DEC, NULL, 0x0, "TLV Length", HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_tlv_port_status,
+ {
+ "PortStatus",
+ "ieee8021ag.tlv.port_status",
+ FT_UINT8, BASE_DEC, VALS(&port_status_vals), 0x0,
+ "Port Status TLV",
+ HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_tlv_if_status,
+ {
+ "ifStatus",
+ "ieee8021ag.tlv.if_status",
+ FT_UINT8, BASE_DEC, VALS(&if_status_vals), 0x0,
+ "Interface Status TLV",
+ HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_tlv_value,
+ { "Value", "ieee8021ag.tlv.value",
+ FT_BYTES, BASE_NONE, NULL, 0x0, "TLV Value", HFILL
+ }
+ },
+
+
{ &hf_ieee8021ag_ccm_endtlv,
{
"End TLV",
@@ -855,8 +1304,17 @@
static gint *ett[] = {
&ett_ieee8021ag,
+ &ett_ieee8021ag_flag,
&ett_ieee8021ag_ccm,
- &ett_ieee8021ag_maid
+ &ett_ieee8021ag_lbr,
+ &ett_ieee8021ag_lbm,
+ &ett_ieee8021ag_ltr,
+ &ett_ieee8021ag_ltm,
+ &ett_ieee8021ag_dmr,
+ &ett_ieee8021ag_dmm,
+ &ett_ieee8021ag_maid,
+ &ett_ieee8021ag_tlv,
+ &ett_ieee8021ag_time
};
proto_ieee8021ag = proto_register_protocol("IEEE 802.1ag Connectivity "
diff -rBbNu wireshark-0.99.6/epan/dissectors/register.c wireshark-0.99.6.new/epan/dissectors/register.c
--- wireshark-0.99.6/epan/dissectors/register.c 2007-07-05 22:29:43.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/register.c 2007-12-18 10:13:43.000000000 +0200
@@ -302,6 +302,7 @@
{extern void proto_register_icq (void); if(cb) (*cb)(RA_REGISTER, "proto_register_icq", client_data); proto_register_icq ();}
{extern void proto_register_idp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_idp", client_data); proto_register_idp ();}
{extern void proto_register_ieee80211 (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ieee80211", client_data); proto_register_ieee80211 ();}
+ {extern void proto_register_ieee8021ag (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ieee8021ag", client_data); proto_register_ieee8021ag ();}
{extern void proto_register_ieee802a (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ieee802a", client_data); proto_register_ieee802a ();}
{extern void proto_register_ifcp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ifcp", client_data); proto_register_ifcp ();}
{extern void proto_register_igap (void); if(cb) (*cb)(RA_REGISTER, "proto_register_igap", client_data); proto_register_igap ();}
@@ -1006,6 +1007,7 @@
{extern void proto_reg_handoff_icq (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_icq", client_data); proto_reg_handoff_icq ();}
{extern void proto_reg_handoff_idp (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_idp", client_data); proto_reg_handoff_idp ();}
{extern void proto_reg_handoff_ieee80211 (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ieee80211", client_data); proto_reg_handoff_ieee80211 ();}
+ {extern void proto_reg_handoff_ieee8021ag (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ieee8021ag", client_data); proto_reg_handoff_ieee8021ag ();}
{extern void proto_reg_handoff_ieee802_3 (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ieee802_3", client_data); proto_reg_handoff_ieee802_3 ();}
{extern void proto_reg_handoff_ieee802a (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ieee802a", client_data); proto_reg_handoff_ieee802a ();}
{extern void proto_reg_handoff_ifcp (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ifcp", client_data); proto_reg_handoff_ifcp ();}
@@ -1412,6 +1414,6 @@
gulong register_count(void)
{
- return 715 + 683;
+ return 716 + 684;
}
diff -rBbNu wireshark-0.99.6/epan/etypes.h wireshark-0.99.6.new/epan/etypes.h
--- wireshark-0.99.6/epan/etypes.h 2007-07-05 22:25:05.000000000 +0300
+++ wireshark-0.99.6.new/epan/etypes.h 2007-12-18 14:12:55.000000000 +0200
@@ -344,6 +344,10 @@
#define ETHERTYPE_FCOE 0x8906 /* Fibre Channel over Ethernet */
#endif
+#ifndef ETHERTYPE_IEEE_802_1AG
+#define ETHERTYPE_IEEE_802_1AG 0x89e2
+#endif
+
#ifndef ETHERTYPE_LOOP
#define ETHERTYPE_LOOP 0x9000 /* used for layer 2 testing (do i see my own frames on the wire) */
#endif
From: alex rozin <arozin@xxxxxxx>
To: maulkin@xxxxxxxx
Sent: Wednesday, December 19, 2007 2:21:29 AM
Subject: [Wireshark-dev] Adding CFM plugin and requesting review.
Hi,
I am a newby in wireshark (while in ethereal I participated in MSTP
dissector).
I looked for an option to debug my 802.1ag implementation and found some
code in
http://www.mail-archive.com/wireshark-dev@xxxxxxxxxxxxx/msg07229/packet-ieee8021ag.c
Good work!
I fixed a few of little bugs in this code and supplemented it with TLV
parsing, LBM/LBR, DMM/DMR and LTM/LTR. I also did operation code
oriented parsing of the field FLAGS.
The patch I attached to this message.
Let me know if you want to have the complete file instead of a patch.
Sure you free to use it at your discretion. I'd be glad to have it in a
next version of wireshark.
Thanks & regards,
Alex
-----Inline Attachment Follows-----
diff -rBbNu wireshark-0.99.6/epan/dissectors/Makefile.common wireshark-0.99.6.new/epan/dissectors/Makefile.common
--- wireshark-0.99.6/epan/dissectors/Makefile.common 2007-07-05 22:24:58.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/Makefile.common 2007-12-13 11:13:40.000000000 +0200
@@ -228,6 +228,7 @@
packet-catapult-dct2000.c \
packet-ccsds.c \
packet-cdp.c \
+ packet-ieee8021ag.c \
packet-cgmp.c \
packet-chdlc.c \
packet-cigi.c \
@@ -753,6 +754,7 @@
packet-scsi-osd.c \
packet-sctp.c \
packet-ssl-utils.c \
+ packet-ieee8021ag.c \
packet-user_encap.c
# corresponding headers
diff -rBbNu wireshark-0.99.6/epan/dissectors/Makefile.in wireshark-0.99.6.new/epan/dissectors/Makefile.in
--- wireshark-0.99.6/epan/dissectors/Makefile.in 2007-07-05 22:26:07.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/Makefile.in 2007-12-13 11:15:51.000000000 +0200
@@ -211,6 +211,7 @@
libcleandissectors_la-packet-catapult-dct2000.lo \
libcleandissectors_la-packet-ccsds.lo \
libcleandissectors_la-packet-cdp.lo \
+ libcleandissectors_la-packet-ieee8021ag.lo \
libcleandissectors_la-packet-cgmp.lo \
libcleandissectors_la-packet-chdlc.lo \
libcleandissectors_la-packet-cigi.lo \
@@ -1218,6 +1219,7 @@
packet-catapult-dct2000.c \
packet-ccsds.c \
packet-cdp.c \
+ packet-ieee8021ag.c \
packet-cgmp.c \
packet-chdlc.c \
packet-cigi.c \
@@ -2258,6 +2260,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-catapult-dct2000.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-ccsds.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-cdp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-cgmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-chdlc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcleandissectors_la-packet-cigi.Plo@am__quote@
@@ -3471,6 +3474,13 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -c -o libcleandissectors_la-packet-cdp.lo `test -f 'packet-cdp.c' || echo '$(srcdir)/'`packet-cdp.c
+libcleandissectors_la-packet-ieee8021ag.lo: packet-ieee8021ag.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -MT libcleandissectors_la-packet-ieee8021ag.lo -MD -MP -MF "$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Tpo" -c -o libcleandissectors_la-packet-ieee8021ag.lo `test -f 'packet-ieee8021ag.c' || echo '$(srcdir)/'`packet-ieee8021ag.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Tpo" "$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Plo"; else rm -f "$(DEPDIR)/libcleandissectors_la-packet-ieee8021ag.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet-ieee8021ag.c' object='libcleandissectors_la-packet-ieee8021ag.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -c -o libcleandissectors_la-packet-ieee8021ag.lo `test -f 'packet-ieee8021ag.c' || echo '$(srcdir)/'`packet-ieee8021ag.c
+
libcleandissectors_la-packet-cgmp.lo: packet-cgmp.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcleandissectors_la_CFLAGS) $(CFLAGS) -MT libcleandissectors_la-packet-cgmp.lo -MD -MP -MF "$(DEPDIR)/libcleandissectors_la-packet-cgmp.Tpo" -c -o libcleandissectors_la-packet-cgmp.lo `test -f 'packet-cgmp.c' || echo '$(srcdir)/'`packet-cgmp.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libcleandissectors_la-packet-cgmp.Tpo" "$(DEPDIR)/libcleandissectors_la-packet-cgmp.Plo"; else rm -f "$(DEPDIR)/libcleandissectors_la-packet-cgmp.Tpo"; exit 1; fi
diff -rBbNu wireshark-0.99.6/epan/dissectors/packet-chdlc.c wireshark-0.99.6.new/epan/dissectors/packet-chdlc.c
--- wireshark-0.99.6/epan/dissectors/packet-chdlc.c 2007-07-05 22:25:03.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/packet-chdlc.c 2007-12-13 13:50:19.000000000 +0200
@@ -103,6 +103,7 @@
{CHDLCTYPE_OSI, "OSI" },
{ETHERTYPE_MPLS, "MPLS unicast"},
{ETHERTYPE_MPLS_MULTI, "MPLS multicast"},
+ {ETHERTYPE_IEEE_802_1AG, "802.1ag CFM"},
{0, NULL}
};
diff -rBbNu wireshark-0.99.6/epan/dissectors/packet-ethertype.c wireshark-0.99.6.new/epan/dissectors/packet-ethertype.c
--- wireshark-0.99.6/epan/dissectors/packet-ethertype.c 2007-07-05 22:24:56.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/packet-ethertype.c 2007-12-13 13:53:14.000000000 +0200
@@ -131,6 +131,7 @@
{PPP_PAP, "PPP Password Authentication Protocol" },
{PPP_CCP, "PPP Compression Control Protocol" },
{ETHERTYPE_LLT, "Veritas Low Latency Transport (not officially registered)"},
+ {ETHERTYPE_IEEE_802_1AG, "802.1ag CFM"},
{ETHERTYPE_FCOE, "Fibre Channel over Ethernet" },
{0, NULL } };
diff -rBbNu wireshark-0.99.6/epan/dissectors/packet-ieee8021ag.c wireshark-0.99.6.new/epan/dissectors/packet-ieee8021ag.c
--- wireshark-0.99.6/epan/dissectors/packet-ieee8021ag.c 2007-12-18 11:43:43.000000000 +0200
+++ wireshark-0.99.6.new/epan/dissectors/packet-ieee8021ag.c 2007-12-18 11:40:10.000000000 +0200
@@ -1,5 +1,8 @@
/* packet-ieee8021ag.h
* Routines for IEEE 802.1ag dissection
+ *
+ * Copyright (C) 2007 Alex Rizin, MRV, <arozin dot mrv com>
+ *
* Copyright 2007 _FF_
* Francesco Fondelli <francesco dot fondelli, gmail dot com>
*
@@ -57,7 +60,15 @@
#define IEEE8021AG_MAID_LEN 48
-static const guint32 flags_offset = 2;
+#define CFM_CCM_FLAGS_RDI_MASK 0x80
+#define CFM_CCM_FLAGS_RES_MASK 0x78
+#define CFM_CCM_FLAGS_INTERVAL_MASK 0x07
+
+#define CFM_LTM_USE_FDB_ONLY_MASK 0x80
+#define CFM_LTM_RES_MASK 0x7f
+#define CFM_LTR_FWD_YES_MASK 0x40
+#define CFM_LTR_TERM_MEP_MASK 0x20
+#define CFM_LTR_RES_MASK 0x1f
static const guint32 flags_size = 1;
static const guint32 ftlvo_offset = 3;
static const guint32 ftlvo_size = 1;
@@ -83,6 +94,19 @@
static int hf_ieee8021ag_ccm_txfcf = -1;
static int hf_ieee8021ag_ccm_rxfcb = -1;
static int hf_ieee8021ag_ccm_txfcb = -1;
+static int hf_ieee8021ag_ltm_trn_num = -1;
+static int hf_ieee8021ag_ltm_ttl = -1;
+static int hf_ieee8021ag_ltm_use_fdb_only = -1;
+static int hf_ieee8021ag_fwd_yes = -1;
+static int hf_ieee8021ag_term = -1;
+static int hf_ieee8021ag_ltr_res = -1;
+static int hf_ieee8021ag_ltr_relay = -1;
+static int hf_ieee8021ag_ltm_res = -1;
+static int hf_ieee8021ag_tlv_type = -1;
+static int hf_ieee8021ag_tlv_len = -1;
+static int hf_ieee8021ag_tlv_value = -1;
+static int hf_ieee8021ag_tlv_port_status = -1;
+static int hf_ieee8021ag_tlv_if_status = -1;
static int hf_ieee8021ag_ccm_endtlv = -1;
/* maid fields */
@@ -99,7 +123,16 @@
/* subtree pointers */
static gint ett_ieee8021ag = -1;
static gint ett_ieee8021ag_ccm = -1;
+static gint ett_ieee8021ag_ltm = -1;
+static gint ett_ieee8021ag_ltr = -1;
+static gint ett_ieee8021ag_lbm = -1;
+static gint ett_ieee8021ag_lbr = -1;
+static gint ett_ieee8021ag_dmr = -1;
+static gint ett_ieee8021ag_dmm = -1;
static gint ett_ieee8021ag_maid = -1;
+static gint ett_ieee8021ag_tlv = -1;
+static gint ett_ieee8021ag_time = -1;
+static gint ett_ieee8021ag_flag = -1;
/* IEEE802.1ag/Y.1731, OpCode values */
static const range_string op_code_long_rvals[] = {
@@ -205,6 +238,42 @@
{ 0, 0, NULL }
};
+static const value_string ieee8021ag_ltr_relay_names[] = {
+ { 1, "RlyHit" },
+ { 2, "RlyFDB" },
+ { 3, "RlyMPDP"},
+};
+
+// find tlv_type
+//
+typedef enum {
+ eee8021ag_end_tlv = 0,
+ eee8021ag_sender_id_tlv,
+ eee8021ag_port_status_tlv,
+ eee8021ag_data_tlv,
+ eee8021ag_interface_status_tlv,
+ eee8021ag_reply_ingress_id_tlv,
+ eee8021ag_reply_egress_id_tlv,
+ eee8021ag_ltm_egress_id_tlv,
+ eee8021ag_ltr_egress_id_tlv,
+ eee8021ag_organization_specific_tlv = 31,
+ eee8021ag_test_tlv = 32,
+} ieee8021ag_tlv_t;
+
+static const value_string ieee8021ag_tlv_type_names[] = {
+ { eee8021ag_end_tlv, "End TLV" },
+ { eee8021ag_sender_id_tlv, "SenderId TLV" },
+ { eee8021ag_port_status_tlv, "PortStatus TLV" },
+ { eee8021ag_data_tlv, "Data TLV" },
+ { eee8021ag_interface_status_tlv, "InterfaceStatus TLV" },
+ { eee8021ag_reply_ingress_id_tlv, "ReplyIngress TLV" },
+ { eee8021ag_reply_egress_id_tlv, "Reply Egress TLV" },
+ { eee8021ag_ltm_egress_id_tlv, "LTM Egress TLV" },
+ { eee8021ag_ltr_egress_id_tlv, "LTR Egress TLV" },
+ { eee8021ag_organization_specific_tlv, "Organization Specific TLV" },
+ { eee8021ag_test_tlv, "Test TLV" },
+};
+
/* IEEE802.1ag/Y.1731, Association Name format type */
static const range_string maid_sformat_type_rvals[] = {
@@ -222,6 +291,27 @@
{ 0, 0, NULL }
};
+static const true_false_string yesno = {
+ "Yes",
+ "No"
+};
+
+static const value_string port_status_vals[] = {
+ { 0, "Invalid" },
+ { 1, "psBlocked" },
+ { 2, "psUp" },
+};
+
+static const value_string if_status_vals[] = {
+ { 0, "Invalid" },
+ { 1, "isUp" },
+ { 2, "isDown" },
+ { 3, "isTesting" },
+ { 4, "isUnknown" },
+ { 5, "isDormant" },
+ { 6, "isNotPresent" },
+ { 7, "isLowerLayerDown" },
+};
static void
dissect_maid(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
@@ -350,64 +440,110 @@
offset += pad_size;
}
-static void
-dissect_ccm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
+static void dissect_tlv (proto_tree *tree, tvbuff_t *tvb, guint32 *offset)
{
- guint8 rdi = 0;
- guint8 res1 = 0;
- guint32 res2 = 0;
- guint8 interval = 0;
- guint8 ftlvo = 0;
- guint32 seq_num = 0;
- guint16 mepid = 0;
- guint8 endtlv = 0;
+ guint8 tlv_type = 0;
+ guint16 tlv_length = 0;
+ guint8 t8 = 0;
proto_item *ti = NULL;
- proto_tree *ccm_tree = NULL;
+ proto_tree *subtree = NULL;
- /* create ccm subtree */
- ti = proto_tree_add_text(tree, tvb, offset, -1, "CCM");
- ccm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_ccm);
+ for (;;) {
+ if (! tvb_bytes_exist(tvb, *offset, 1)) {
+ proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed, tvb, *offset, 0, TRUE);
+ proto_tree_add_text(tree, tvb, *offset, -1, "Error: Packet does not have End TLV");
+ return;
+ }
+ tlv_type = tvb_get_guint8(tvb, *offset);
+ if (! tlv_type) {
+ proto_tree_add_uint(tree, hf_ieee8021ag_tlv_type, tvb, *offset, 1, tlv_type);
+ *offset += 1;
+ return; /* End TLV */
+ }
+ *offset += 1;
+ tlv_length = tvb_get_ntohs(tvb, *offset);
+ ti = proto_tree_add_text(tree, tvb, *offset, tlv_length, match_strval(tlv_type, ieee8021ag_tlv_type_names));
+ subtree = proto_item_add_subtree(ti, ett_ieee8021ag_tlv);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_tlv_type, tvb, *offset - 1, 1, tlv_type);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_tlv_len, tvb, *offset, 2, tlv_length);
+ *offset += 2;
+ switch (tlv_type) {
+ case eee8021ag_sender_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_port_status_tlv:
+ t8 = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_tlv_port_status, tvb, *offset, 1, t8);
+ break;
+ case eee8021ag_data_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_interface_status_tlv:
+ t8 = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_tlv_if_status, tvb, *offset, 1, t8);
+ break;
+ case eee8021ag_reply_ingress_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_reply_egress_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_ltm_egress_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_ltr_egress_id_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_organization_specific_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ case eee8021ag_test_tlv:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
+ default:
+ proto_tree_add_item(subtree, hf_ieee8021ag_tlv_value, tvb, *offset, tlv_length, FALSE);
+ break;
- /* reinterpret flags field in ccm case */
- rdi = tvb_get_guint8(tvb, flags_offset) & 0x80;
- proto_tree_add_boolean(ccm_tree, hf_ieee8021ag_ccm_rdi,
- tvb, flags_offset, flags_size, rdi);
-
- res1 = tvb_get_guint8(tvb, flags_offset) & 0x78;
- proto_tree_add_uint_hidden(ccm_tree, hf_ieee8021ag_ccm_res1,
- tvb, flags_offset, flags_size, res1);
- if (res1 != 0) {
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, flags_offset, flags_size, TRUE);
- proto_tree_add_text(ccm_tree, tvb, flags_offset, flags_size,
- "Error: bit 7, 6, 5 and 4 of "
- "Flags field should be zero");
}
+ *offset += tlv_length;
+ }
+}
- interval = tvb_get_guint8(tvb, flags_offset) & 0x07;
- proto_tree_add_item(ccm_tree, hf_ieee8021ag_ccm_interval,
- tvb, flags_offset, flags_size, interval);
+static void check_specific_ftlvo (tvbuff_t *tvb, guint32 offset, proto_tree *tree, guint8 must_by_ftlvo)
+{
+ guint8 ftlvo;
/* check first tlv offset field */
ftlvo = tvb_get_guint8(tvb, ftlvo_offset);
- if (ftlvo < 70) {
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, ftlvo_offset, ftlvo_size, TRUE);
- proto_tree_add_text(ccm_tree, tvb, ftlvo_offset, ftlvo_size,
- "Error: First TLV Offset field "
- "should be >= 70");
- }
/* check advertised size agaist real pkt size */
if (!tvb_bytes_exist(tvb, offset, ftlvo + 1)) {
-
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, offset, 0, TRUE);
- proto_tree_add_text(ccm_tree, tvb, offset, -1,
- "Error: Packet too short");
+ proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed, tvb, offset, 0, TRUE);
+ proto_tree_add_text(tree, tvb, offset, -1, "Error: Packet too short");
THROW(ReportedBoundsError);
}
+ if (ftlvo < must_by_ftlvo) {
+ proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed, tvb, ftlvo_offset, ftlvo_size, TRUE);
+ proto_tree_add_text(tree, tvb, ftlvo_offset, ftlvo_size, "Error: First TLV Offset field should be >= %d", (int) must_by_ftlvo);
+ }
+}
+
+static void
+dissect_ccm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint32 res2 = 0;
+ guint32 seq_num = 0;
+ guint16 mepid = 0;
+ proto_item *ti = NULL;
+ proto_tree *ccm_tree = NULL;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "CCM");
+ ccm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_ccm);
+
+ check_specific_ftlvo (tvb, offset, ccm_tree, 70);
+
/* and finally others ccm fields */
seq_num = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(ccm_tree, hf_ieee8021ag_ccm_seq_num,
@@ -463,26 +599,74 @@
* d) Organization-Specific TLV (21.5.2).
*/
- /* there must be only one more byte: the stop byte (End TLV) */
- endtlv = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(ccm_tree, hf_ieee8021ag_ccm_endtlv,
- tvb, offset, 1, FALSE);
- if (endtlv != 0) {
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, offset, 1, TRUE);
- proto_tree_add_text(ccm_tree, tvb, offset, 1,
- "Error: End TLV octect "
- "should be set to zero");
+ dissect_tlv (ccm_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
}
- offset += 1;
+}
+
+static void dissect_timestamp (tvbuff_t *tvb, guint32 *offset, proto_tree *tree, const char * stamp_name)
+{
+ proto_item *ti = NULL;
+ proto_tree *subtree = NULL;
+
+ ti = proto_tree_add_text(tree, tvb, *offset, 8, stamp_name);
+ subtree = proto_item_add_subtree(ti, ett_ieee8021ag_time);
+ proto_tree_add_text(subtree, tvb, *offset, 4, "tv_sec: %lu sec.", (unsigned long) tvb_get_letohl(tvb, *offset));
+ *offset += 4;
+ proto_tree_add_text(subtree, tvb, *offset, 4, "tv_usec: %lu nanosec.", (unsigned long) tvb_get_letohl(tvb, *offset));
+ *offset += 4;
+}
+
+static void
+dissect_dmr(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *ti = NULL;
+ proto_tree *dmr_tree = NULL;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "DMR");
+ dmr_tree = proto_item_add_subtree(ti, ett_ieee8021ag_dmr);
+
+ check_specific_ftlvo (tvb, offset, dmr_tree, 32);
+
+ dissect_timestamp (tvb, &offset, dmr_tree, "T1");
+ dissect_timestamp (tvb, &offset, dmr_tree, "T2");
+ dissect_timestamp (tvb, &offset, dmr_tree, "T3");
+ dissect_timestamp (tvb, &offset, dmr_tree, "T4");
+
+ dissect_tlv (dmr_tree, tvb, &offset);
/* extra check: no more data should be present */
if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
+}
- proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
- tvb, offset, 0, TRUE);
- proto_tree_add_text(ccm_tree, tvb, offset, -1,
- "Error: Packet too long");
+static void
+dissect_dmm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ proto_item *ti = NULL;
+ proto_tree *dmm_tree = NULL;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "DMM");
+ dmm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_dmm);
+
+ check_specific_ftlvo (tvb, offset, dmm_tree, 32);
+
+ dissect_timestamp (tvb, &offset, dmm_tree, "T1");
+ dissect_timestamp (tvb, &offset, dmm_tree, "T2");
+ dissect_timestamp (tvb, &offset, dmm_tree, "T3");
+ dissect_timestamp (tvb, &offset, dmm_tree, "T4");
+
+ dissect_tlv (dmm_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
}
}
@@ -489,28 +674,164 @@
static void
dissect_lbr(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
{
- assert(tvb); assert(offset); assert(pinfo); assert(tree); //temp
+ proto_item *ti = NULL;
+ proto_tree *lbr_tree = NULL;
+ guint32 seq_num = 0;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "LBR");
+ lbr_tree = proto_item_add_subtree(ti, ett_ieee8021ag_lbr);
+
+ check_specific_ftlvo (tvb, offset, lbr_tree, 4);
+
+ seq_num = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(lbr_tree, hf_ieee8021ag_ccm_seq_num, tvb, offset, 4, seq_num);
+ offset += 4;
+
+ dissect_tlv (lbr_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
}
static void
dissect_lbm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
{
- assert(tvb); assert(offset); assert(pinfo); assert(tree); //temp
+ proto_item *ti = NULL;
+ proto_tree *lbm_tree = NULL;
+ guint32 seq_num = 0;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "LBM");
+ lbm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_lbm);
+
+ check_specific_ftlvo (tvb, offset, lbm_tree, 4);
+
+ seq_num = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(lbm_tree, hf_ieee8021ag_ccm_seq_num, tvb, offset, 4, seq_num);
+ offset += 4;
+
+ dissect_tlv (lbm_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
}
static void
dissect_ltr(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
{
- assert(tvb); assert(offset); assert(pinfo); assert(tree); //temp
-}
+ guint8 t8 = 0;
+ guint32 seq_num = 0;
+ proto_item *ti = NULL;
+ proto_tree *ltr_tree = NULL;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "LTR");
+ ltr_tree = proto_item_add_subtree(ti, ett_ieee8021ag_ltr);
+
+ check_specific_ftlvo (tvb, offset, ltr_tree, 6);
+
+ seq_num = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(ltr_tree, hf_ieee8021ag_ltm_trn_num, tvb, offset, 4, seq_num);
+ offset += 4;
+
+ t8 = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(ltr_tree, hf_ieee8021ag_ltm_ttl, tvb, offset, 1, t8);
+ offset += 1;
+
+ t8 = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(ltr_tree, hf_ieee8021ag_ltr_relay, tvb, offset, 1, t8);
+ offset += 1;
+
+ dissect_tlv (ltr_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
+} /* ltr end */
static void
dissect_ltm(tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree)
{
- assert(tvb); assert(offset); assert(pinfo); assert(tree); //temp
+ guint8 ttl = 0;
+ guint32 seq_num = 0;
+ proto_item *ti = NULL;
+ proto_tree *ltm_tree = NULL;
+ const guint8 *mac_addr;
+ gchar *mac_addr_str;
+
+ /* create ccm subtree */
+ ti = proto_tree_add_text(tree, tvb, offset, -1, "LTM");
+ ltm_tree = proto_item_add_subtree(ti, ett_ieee8021ag_ltm);
+
+ check_specific_ftlvo (tvb, offset, ltm_tree, 17);
+
+ seq_num = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(ltm_tree, hf_ieee8021ag_ltm_trn_num, tvb, offset, 4, seq_num);
+ offset += 4;
+
+ ttl = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(ltm_tree, hf_ieee8021ag_ltm_ttl, tvb, offset, 1, ttl);
+ offset += 1;
+
+ mac_addr = tvb_get_ptr(tvb, offset, 6);
+ mac_addr_str = ether_to_str(mac_addr);
+ proto_tree_add_text(ltm_tree, tvb, offset, 6, "Original MAC Address %s", mac_addr_str);
+ offset += 6;
+
+ mac_addr = tvb_get_ptr(tvb, offset, 6);
+ mac_addr_str = ether_to_str(mac_addr);
+ proto_tree_add_text(ltm_tree, tvb, offset, 6, "Target MAC Address %s", mac_addr_str);
+ offset += 6;
+
+ dissect_tlv (ltm_tree, tvb, &offset);
+
+ /* extra check: no more data should be present */
+ if (tvb_bytes_exist(tvb, offset, 1)) {
+ proto_tree_add_text(tree, tvb, offset, -1, "Padding");
+ }
}
+static void dissect_flags (tvbuff_t *tvb, proto_tree *ieee8021ag_tree, guint8 opcode, guint32 offset)
+{
+ proto_item *ti = NULL;
+ proto_tree *subtree = NULL;
+ guint8 flags = 0;
+
+ flags = tvb_get_guint8(tvb, offset);
+ ti = proto_tree_add_item(ieee8021ag_tree, hf_ieee8021ag_flags, tvb, offset, 1, FALSE);
+ subtree = proto_item_add_subtree(ti, ett_ieee8021ag_flag);
+ switch (opcode) {
+ case 1:
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_ccm_rdi, tvb, offset, 1, flags);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_ccm_res1, tvb, offset, 1, flags);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_ccm_interval, tvb, offset, 1, flags);
+ break;
+ case 2: /* lbr */
+ break;
+ case 3: /* lbr */
+ break;
+ case 4: /* ltr */
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_ltm_use_fdb_only, tvb, offset, 1, flags);
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_fwd_yes, tvb, offset, 1, flags);
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_term, tvb, offset, 1, flags);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_ltr_res, tvb, offset, 1, flags);
+ break;
+ case 5: /* ltm */
+ proto_tree_add_boolean(subtree, hf_ieee8021ag_ltm_use_fdb_only, tvb, offset, 1, flags);
+ proto_tree_add_uint(subtree, hf_ieee8021ag_ltm_res, tvb, offset, 1, flags);
+ break;
+ default:
+ break;
+ }
+}
+
static void
dissect_ieee8021ag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
@@ -522,6 +843,7 @@
/* get at least a full message header */
if (!tvb_bytes_exist(tvb, 0, IEEE8021AG_HDR_LEN_MIN)) {
+ printf ("%s(%d) - %s\n", __FILE__, __LINE__, __FUNCTION__);
if (tree) {
proto_tree_add_boolean_hidden(tree, hf_ieee8021ag_malformed,
tvb, offset, 0, TRUE);
@@ -550,6 +872,7 @@
if (!tree) {
/* nothing to do, col info and proto info already done */
+ printf ("%s(%d) - %s\n", __FILE__, __LINE__, __FUNCTION__);
return;
}
@@ -571,8 +894,11 @@
opcode = tvb_get_guint8(tvb, offset);
proto_tree_add_item(ieee8021ag_tree, hf_ieee8021ag_op_code,
tvb, offset, 1, FALSE);
- offset += 1;
+ offset += 1;
+#if 1
+ dissect_flags (tvb, ieee8021ag_tree, opcode, offset);
+#else
/*
* FF: The rest is opCode specific. Please note that "Flags" field is
* hemmm "a placeholder where you can put whatever you want with
@@ -583,6 +909,7 @@
*/
proto_tree_add_item(ieee8021ag_tree, hf_ieee8021ag_flags,
tvb, offset, 1, FALSE);
+#endif
offset += 1;
proto_tree_add_item(ieee8021ag_tree, hf_ieee8021ag_ftlv_offset,
@@ -605,6 +933,12 @@
case 5:
return dissect_ltm(tvb, offset, pinfo, ieee8021ag_tree);
break;
+ case 46:
+ return dissect_dmr(tvb, offset, pinfo, ieee8021ag_tree);
+ break;
+ case 47:
+ return dissect_dmm(tvb, offset, pinfo, ieee8021ag_tree);
+ break;
default:
/* reserved pdu type, I can't do much */
if (tvb_bytes_exist(tvb, offset, 1)) {
@@ -680,7 +1014,7 @@
{
"Interval",
"ieee8021ag.ccm.interval",
- FT_UINT8, BASE_DEC, VALS(&ccm_interval_vals), 0x0,
+ FT_UINT8, BASE_DEC, VALS(&ccm_interval_vals), CFM_CCM_FLAGS_INTERVAL_MASK,
"The CCM transmission interval",
HFILL
}
@@ -709,7 +1043,8 @@
{
"RDI",
"ieee8021ag.ccm.rdi",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, 8, TFS(&yesno),
+ CFM_CCM_FLAGS_RDI_MASK,
"Whether the defect indication is communicated "
"by the transmitting MEP",
HFILL
@@ -715,15 +1050,15 @@
HFILL
}
},
+
{ &hf_ieee8021ag_ccm_res1,
- {
- "reserved",
- "ieee8021ag.ccm.res1",
- FT_UINT8, BASE_DEC, NULL, 0x0,
- "",
- HFILL
+ { "reserved", "ieee8021ag.ccm.res1",
+ FT_UINT8, BASE_DEC, NULL,
+ CFM_CCM_FLAGS_RES_MASK,
+ "", HFILL
}
},
+
{ &hf_ieee8021ag_ccm_res2,
{
"reserved",
@@ -773,6 +1108,120 @@
HFILL
}
},
+
+ { &hf_ieee8021ag_ltr_res,
+ { "reserved", "ieee8021ag.ccm.res1",
+ FT_UINT8, BASE_DEC, NULL, CFM_LTR_RES_MASK,
+ "", HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_ltm_trn_num,
+ {
+ "Transaction Number",
+ "ieee8021ag.ltm.trn_num",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "A MEP copies the contents of the nextLTMtransID variable (20.36.1) to this field",
+ HFILL
+ }
+ },
+ { &hf_ieee8021ag_ltm_ttl,
+ {
+ "TTL",
+ "ieee8021ag.ltm.ttl",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "TTL - time to live counter",
+ HFILL
+ }
+ },
+ { &hf_ieee8021ag_ltm_res,
+ { "reserved", "ieee8021ag.ccm.res1",
+ FT_UINT8, BASE_DEC, NULL, CFM_LTM_RES_MASK,
+ "", HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_ltm_use_fdb_only,
+ {
+ "useFDBonly",
+ "ieee8021ag.ltm.use_fdb_only",
+ FT_BOOLEAN, 8, TFS(&yesno), CFM_LTM_USE_FDB_ONLY_MASK,
+ "Only MAC addresses learned in a Bridge’s Filtering Database, and"
+ "not information saved in the MIP CCM Database, is to"
+ "be used to determine the Egress Port",
+ HFILL
+ }
+ },
+ { &hf_ieee8021ag_fwd_yes,
+ {
+ "FwdYes",
+ "ieee8021ag.ltm.fwd_yes",
+ FT_BOOLEAN, 8, TFS(&yesno), CFM_LTR_FWD_YES_MASK,
+ "The LTM was (1) or was not (0) forwarded",
+ HFILL
+ }
+ },
+ { &hf_ieee8021ag_term,
+ {
+ "TerminalMEP",
+ "ieee8021ag.ltm.terminal_mep",
+ FT_BOOLEAN, 8, TFS(&yesno), CFM_LTR_TERM_MEP_MASK,
+ "The MP reported in the Reply Egress TLV (Reply Ingress TLV, if"
+ "the Reply Egress TLV is not present) is a MEP",
+ HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_ltr_relay,
+ {
+ "Relay Action",
+ "ieee8021ag.ltr.relay",
+ FT_UINT8, BASE_DEC, VALS(&ieee8021ag_ltr_relay_names), 0x0,
+ "Reports how the data frame targeted by the LTM would be passed through the MAC Relay Entity to"
+ "the Egress Bridge Port",
+ HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_tlv_type,
+ { "Type", "ieee8021ag.tlv.type",
+ FT_UINT8, BASE_DEC, VALS(ieee8021ag_tlv_type_names), 0x0,
+ "TLV Type", HFILL
+ }
+ },
+ { &hf_ieee8021ag_tlv_len,
+ { "Length", "ieee8021ag.tlv.len",
+ FT_UINT16, BASE_DEC, NULL, 0x0, "TLV Length", HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_tlv_port_status,
+ {
+ "PortStatus",
+ "ieee8021ag.tlv.port_status",
+ FT_UINT8, BASE_DEC, VALS(&port_status_vals), 0x0,
+ "Port Status TLV",
+ HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_tlv_if_status,
+ {
+ "ifStatus",
+ "ieee8021ag.tlv.if_status",
+ FT_UINT8, BASE_DEC, VALS(&if_status_vals), 0x0,
+ "Interface Status TLV",
+ HFILL
+ }
+ },
+
+ { &hf_ieee8021ag_tlv_value,
+ { "Value", "ieee8021ag.tlv.value",
+ FT_BYTES, BASE_NONE, NULL, 0x0, "TLV Value", HFILL
+ }
+ },
+
+
{ &hf_ieee8021ag_ccm_endtlv,
{
"End TLV",
@@ -855,8 +1304,17 @@
static gint *ett[] = {
&ett_ieee8021ag,
+ &ett_ieee8021ag_flag,
&ett_ieee8021ag_ccm,
- &ett_ieee8021ag_maid
+ &ett_ieee8021ag_lbr,
+ &ett_ieee8021ag_lbm,
+ &ett_ieee8021ag_ltr,
+ &ett_ieee8021ag_ltm,
+ &ett_ieee8021ag_dmr,
+ &ett_ieee8021ag_dmm,
+ &ett_ieee8021ag_maid,
+ &ett_ieee8021ag_tlv,
+ &ett_ieee8021ag_time
};
proto_ieee8021ag = proto_register_protocol("IEEE 802.1ag Connectivity "
diff -rBbNu wireshark-0.99.6/epan/dissectors/register.c wireshark-0.99.6.new/epan/dissectors/register.c
--- wireshark-0.99.6/epan/dissectors/register.c 2007-07-05 22:29:43.000000000 +0300
+++ wireshark-0.99.6.new/epan/dissectors/register.c 2007-12-18 10:13:43.000000000 +0200
@@ -302,6 +302,7 @@
{extern void proto_register_icq (void); if(cb) (*cb)(RA_REGISTER, "proto_register_icq", client_data); proto_register_icq ();}
{extern void proto_register_idp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_idp", client_data); proto_register_idp ();}
{extern void proto_register_ieee80211 (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ieee80211", client_data); proto_register_ieee80211 ();}
+ {extern void proto_register_ieee8021ag (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ieee8021ag", client_data); proto_register_ieee8021ag ();}
{extern void proto_register_ieee802a (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ieee802a", client_data); proto_register_ieee802a ();}
{extern void proto_register_ifcp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ifcp", client_data); proto_register_ifcp ();}
{extern void proto_register_igap (void); if(cb) (*cb)(RA_REGISTER, "proto_register_igap", client_data); proto_register_igap ();}
@@ -1006,6 +1007,7 @@
{extern void proto_reg_handoff_icq (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_icq", client_data); proto_reg_handoff_icq ();}
{extern void proto_reg_handoff_idp (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_idp", client_data); proto_reg_handoff_idp ();}
{extern void proto_reg_handoff_ieee80211 (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ieee80211", client_data); proto_reg_handoff_ieee80211 ();}
+ {extern void proto_reg_handoff_ieee8021ag (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ieee8021ag", client_data); proto_reg_handoff_ieee8021ag ();}
{extern void proto_reg_handoff_ieee802_3 (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ieee802_3", client_data); proto_reg_handoff_ieee802_3 ();}
{extern void proto_reg_handoff_ieee802a (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ieee802a", client_data); proto_reg_handoff_ieee802a ();}
{extern void proto_reg_handoff_ifcp (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ifcp", client_data); proto_reg_handoff_ifcp ();}
@@ -1412,6 +1414,6 @@
gulong register_count(void)
{
- return 715 + 683;
+ return 716 + 684;
}
diff -rBbNu wireshark-0.99.6/epan/etypes.h wireshark-0.99.6.new/epan/etypes.h
--- wireshark-0.99.6/epan/etypes.h 2007-07-05 22:25:05.000000000 +0300
+++ wireshark-0.99.6.new/epan/etypes.h 2007-12-18 14:12:55.000000000 +0200
@@ -344,6 +344,10 @@
#define ETHERTYPE_FCOE 0x8906 /* Fibre Channel over Ethernet */
#endif
+#ifndef ETHERTYPE_IEEE_802_1AG
+#define ETHERTYPE_IEEE_802_1AG 0x89e2
+#endif
+
#ifndef ETHERTYPE_LOOP
#define ETHERTYPE_LOOP 0x9000 /* used for layer 2 testing (do i see my own frames on the wire) */
#endif
Looking for the perfect gift? Give the gift of Flickr!
- Prev by Date: Re: [Wireshark-dev] Invalid PDU length and TCP reassembly
- Next by Date: Re: [Wireshark-dev] crash with Preference in Plugin
- Previous by thread: Re: [Wireshark-dev] Invalid PDU length and TCP reassembly
- Next by thread: [Wireshark-dev] Packet display columns enhancement
- Index(es):