Wireshark-dev: Re: [Wireshark-dev] [PATCH] New plugin for Homeplug

From: Sebastien Tandel <sebastien@xxxxxxxxx>
Date: Tue, 05 Dec 2006 02:25:46 +0100

I've done the necessary changes for the regular dissector.
Concerning the ptvcursor, I will first see how it works ;)

Sebastien

Jaap Keuter wrote:
> Hi,
>
> I've looked at the code. Some things you can improve on.
> 1. Get rid of the C++ style comments
> 2. Make it into a regular dissector, getting rid of all the plugin
> wiring.
> 3. Add the ether type to etypes.h i.s.o. defining it yourself
>   
> BTW: It's such a simple protocol you could consider using ptvcursor.
>
> Thanks,
> Jaap
>
>
> On Mon, 4 Dec 2006, Sebastien Tandel wrote:
>
>   
>> Hi,
>>
>>     Here is a patch for the plugin supporting the dissection of the
>> intellon homeplug powerline protocol based on INT51X1 specification.
>>
>> Sebastien Tandel
>>
>>     
>
> _______________________________________________
> Wireshark-dev mailing list
> Wireshark-dev@xxxxxxxxxxxxx
> http://www.wireshark.org/mailman/listinfo/wireshark-dev
>   

--- svn-copy/epan/dissectors/Makefile.common	2006-12-04 22:06:16.000000000 +0100
+++ svn-working/epan/dissectors/Makefile.common	2006-12-05 00:46:12.000000000 +0100
@@ -352,6 +352,7 @@
 	packet-h450.c	\
 	packet-hci_h4.c	\
 	packet-hclnfsd.c	\
+	packet-homeplug.c \
 	packet-hpext.c	\
 	packet-hpsw.c	\
 	packet-hsrp.c	\
--- svn-copy/epan/dissectors/packet-homeplug.c	1970-01-01 01:00:00.000000000 +0100
+++ svn-working/epan/dissectors/packet-homeplug.c	2006-12-05 01:44:15.000000000 +0100
@@ -0,0 +1,726 @@
+/* ==================================================================
+* @(#)packet-homeplug.c
+*
+* @author  Sebastien Tandel (sebastien@xxxxxxxxx)
+*
+* @date 09/09/2005
+* @lastdate 04/12/2006
+*
+* 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.
+*
+* 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
+================================================================== */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/etypes.h>
+
+
+/* METYPE Values */
+#define HOMEPLUG_MME_RCE      0x00
+#define HOMEPLUG_MME_CER      0x01
+#define HOMEPLUG_MME_RPS      0x07
+#define HOMEPLUG_MME_PSR      0x08
+#define HOMEPLUG_MME_NS	      0x1A
+
+/* Bit mask Operation */
+#define HOMEPLUG_MCTRL_RSVD   0x80
+#define HOMEPLUG_MCTRL_NE     0x7F
+
+#define HOMEPLUG_MEHDR_MEV    0xE0
+#define HOMEPLUG_MEHDR_METYPE 0x1F
+
+#define HOMEPLUG_NS_AC	      0x80
+#define HOMEPLUG_NS_ICID      0x7F
+
+#define HOMEPLUG_RCE_CEV      0xF0
+#define HOMEPLUG_RCE_RSVD     0x0F
+
+#define HOMEPLUG_CER_CERV     0xF0
+#define HOMEPLUG_CER_RSVD     0x0FE0
+#define HOMEPLUG_CER_RXTMI    0x1F
+#define HOMEPLUG_CER_RATE     0x80
+#define HOMEPLUG_CER_BP	      0x40
+#define HOMEPLUG_CER_VT11     0x0F
+#define HOMEPLUG_CER_RSVD2    0x80
+#define HOMEPLUG_CER_NBDAS    0x7F
+
+
+/* Length of Network Statistics Response defines whether it is the Basic or the
+ * Extended Response */
+#define HOMEPLUG_NS_BASIC_LEN 187
+#define HOMEPLUG_NS_EXT_LEN   199
+
+/* forward reference */
+void proto_reg_handoff_homeplug();
+
+static int proto_homeplug= -1;
+static dissector_handle_t homeplug_handle;
+
+static int hf_homeplug_mctrl		= -1;
+  static int hf_homeplug_mctrl_reserved = -1;
+  static int hf_homeplug_mctrl_ne	= -1;
+static int hf_homeplug_mehdr		= -1;
+  static int hf_homeplug_mehdr_mev		= -1;
+  static int hf_homeplug_mehdr_metype		= -1;
+static int hf_homeplug_melen		= -1;
+static int hf_homeplug_mme		= -1;
+  /* Request Channel Estimation */
+  static int hf_homeplug_rce		= -1;
+    static int hf_homeplug_rce_cev	= -1;
+    static int hf_homeplug_rce_rsvd	= -1;
+  /* Channel Estimation Response */
+  static int hf_homeplug_cer		= -1;
+    static int hf_homeplug_cer_cerv	= -1;
+    static int hf_homeplug_cer_rsvd1	= -1;
+    static int hf_homeplug_cer_rxtmi	= -1;
+    static int hf_homeplug_cer_vt	= -1;
+    static int hf_homeplug_cer_rate	= -1;
+    static int hf_homeplug_cer_bp	= -1;
+    static int hf_homeplug_cer_mod	= -1;
+    static int hf_homeplug_cer_vt11	= -1;
+    static int hf_homeplug_cer_rsvd2	= -1;
+    static int hf_homeplug_cer_nbdas	= -1;
+    static int hf_homeplug_cer_bda	= -1;
+  /* Request Parameters and Statistics */
+  static int hf_homeplug_rps		= -1;
+  /* Parameters and Statistics Response */
+  static int hf_homeplug_psr		= -1;
+    static int hf_homeplug_psr_txack	= -1;
+    static int hf_homeplug_psr_txnack	= -1;
+    static int hf_homeplug_psr_txfail	= -1;
+    static int hf_homeplug_psr_txcloss	= -1;
+    static int hf_homeplug_psr_txcoll	= -1;
+    static int hf_homeplug_psr_txca3lat	= -1;
+    static int hf_homeplug_psr_txca2lat = -1;
+    static int hf_homeplug_psr_txca1lat	= -1;
+    static int hf_homeplug_psr_txca0lat = -1;
+    static int hf_homeplug_psr_rxbp40	= -1;
+  /* Network Statistics */
+      /* Basic */
+  static int hf_homeplug_ns		= -1;
+    static int hf_homeplug_ns_netw_ctrl_ac  = -1;
+    static int hf_homeplug_ns_netw_ctrl_icid= -1;
+    static int hf_homeplug_ns_netw_ctrl_icid_rsvd= -1;
+    static int hf_homeplug_ns_bytes40_robo  = -1;
+    static int hf_homeplug_ns_fails_robo    = -1;
+    static int hf_homeplug_ns_drops_robo    = -1;
+    static int hf_homeplug_ns_netw_da	    = -1;
+    static int hf_homeplug_ns_bytes40	    = -1;
+    static int hf_homeplug_ns_fails	    = -1;
+    static int hf_homeplug_ns_drops	    = -1;
+    /* array of 15 elements */
+/*    static int hf_homeplug_ns_bytes40_1	    = -1;
+    static int hf_homeplug_ns_bytes40_1 */
+      /* Extended */
+    /* array of 6 elements */
+/*    static int hf_homeplug_ns_tx_bfr_0_state = -1;*/
+
+static gint ett_homeplug		= -1;
+static gint ett_homeplug_mctrl		= -1;
+static gint ett_homeplug_mehdr		= -1;
+static gint ett_homeplug_mme		= -1;
+static gint ett_homeplug_rce		= -1;
+static gint ett_homeplug_cer		= -1;
+static gint ett_homeplug_rps		= -1;
+static gint ett_homeplug_psr		= -1;
+static gint ett_homeplug_ns		= -1;
+static gint ett_homeplug_tone		= -1;
+
+static guint8 homeplug_ne = 0;
+static guint8 homeplug_melen = 0;
+static guint8 homeplug_metype = 0;
+
+static guint32	homeplug_offset = 0;
+
+/* IC_ID Values */
+#define HOMEPLUG_NS_ICID5130A1		0x00
+#define HOMEPLUG_NS_ICID51X1USB		0x01
+#define HOMEPLUG_NS_ICID51X1PHY		0x02
+#define HOMEPLUG_NS_ICID51X1HOST	0x03
+#define HOMEPLUG_NS_ICID5130A2		0x04
+#define HOMEPLUG_NS_ICID_RSVD1		0x05
+#define HOMEPLUG_NS_ICID_RSVD2		0x06
+#define HOMEPLUG_NS_ICID_RSVD3		0x07
+/* ICID Bit Mask */
+#define HOMEPLUG_NS_ICID_MASK		0x07
+#define HOMEPLUG_NS_ICID_RSVD_MASK	0x78
+/* string values in function of IC_ID values */
+static const value_string homeplug_ns_icid_vals[] = {
+    { HOMEPLUG_NS_ICID5130A1, "INT5130A1" },
+    { HOMEPLUG_NS_ICID51X1USB, "INT51X1 (USB Option)" },
+    { HOMEPLUG_NS_ICID51X1PHY, "INT51X1 (PHY Option)" },
+    { HOMEPLUG_NS_ICID51X1HOST, "INT51X1 (Host/DTE Option)" },
+    { HOMEPLUG_NS_ICID5130A2, "INT5130A2" },
+    { HOMEPLUG_NS_ICID_RSVD1, "Reserved"},
+    { HOMEPLUG_NS_ICID_RSVD2, "Reserved"},
+    { HOMEPLUG_NS_ICID_RSVD3, "Reserved"},
+    { 0,      NULL }
+};
+
+/* Modulation Method Bit Mask */
+#define HOMEPLUG_CER_MOD_MASK	        0x30
+/* Modulation Method Values */
+#define HOMEPLUG_CER_MOD_ROBO		0x00
+#define HOMEPLUG_CER_MOD_DBPSK		0x01
+#define HOMEPLUG_CER_MOD_DQPSK		0x02
+#define	HOMEPLUG_CER_MOD_RSVD		0x03
+/* string values in function of Modulation Method Values */
+static const value_string homeplug_cer_mod_vals[] = {
+  { HOMEPLUG_CER_MOD_ROBO, "ROBO Modulation"},
+  { HOMEPLUG_CER_MOD_DBPSK, "DBPSK Modulation"},
+  { HOMEPLUG_CER_MOD_DQPSK, "DQPSK Modulation"},
+  { HOMEPLUG_CER_MOD_RSVD, "Reserved"},
+  { 0, NULL}
+};
+
+
+void
+proto_register_homeplug(void)
+{
+  static hf_register_info hf[] = {
+    /* MAC Control Field */
+    { &hf_homeplug_mctrl,
+      { "MAC Control Field", "homeplug.mctrl",
+      FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_mctrl_reserved, 
+      { "Reserved", "homeplug.mctrl.rsvd",
+	FT_NONE, BASE_DEC, NULL, HOMEPLUG_MCTRL_RSVD, "", HFILL }
+    },
+
+    { &hf_homeplug_mctrl_ne, 
+      { "Number of MAC Data Entries", "homeplug.mctrl.ne",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_MCTRL_NE, "", HFILL }
+    },
+
+    /* MAC Entry Header */
+    { &hf_homeplug_mehdr,
+      { "MAC Management Entry Header", "homeplug.mehdr",
+	FT_NONE, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_mehdr_mev,
+      { "MAC Entry Version", "homeplug.mehdr.mev",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_MEHDR_MEV, "", HFILL }
+    },
+
+    { &hf_homeplug_mehdr_metype,
+      { "MAC Entry Type", "homeplug.mehdr.metype",
+	FT_UINT8, BASE_HEX, NULL, HOMEPLUG_MEHDR_METYPE, "", HFILL }
+    },
+
+    /* MAC Entry Len */
+    { &hf_homeplug_melen,
+      { "MAC Management Entry Length", "homeplug.melen",
+	FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    /* MAC Management Entry */
+    { &hf_homeplug_mme,
+      { "MAC Management Entry Data", "homeplug.mmentry",
+	FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    /* Request Channel Estimation */
+    { &hf_homeplug_rce,
+      { "Request Channel Estimation", "homeplug.rce",
+	FT_NONE, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_rce_cev,
+      { "Channel Estimation Version", "homeplug.rce.cev",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_RCE_CEV, "", HFILL }
+    },
+
+    { &hf_homeplug_rce_rsvd,
+      { "Reserved", "homeplug.rce.rsvd",
+	FT_NONE, BASE_DEC, NULL, HOMEPLUG_RCE_RSVD, "", HFILL }
+    },
+
+    /* Channel Estimation Response */
+    { &hf_homeplug_cer,
+      { "Channel Estimation Response", "homeplug.cer",
+	FT_NONE, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_cerv,
+      { "Channel Estimation Response Version", "homeplug.cer.cerv",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_CERV, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_rsvd1,
+      { "Reserved", "homeplug.cer.rsvd1",
+	FT_NONE, BASE_DEC, NULL, HOMEPLUG_CER_RSVD, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_rxtmi,
+      { "Receive Tone Map Index", "homeplug.cer.rxtmi",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RXTMI, "", HFILL }
+    },
+
+    /* TODO must append vt[79-0] */
+
+    { &hf_homeplug_cer_vt, 
+      {"Valid Tone Flags", "homeplug.cer.vt",
+	FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_rate,
+      { "FEC Rate", "homeplug.cer.rate",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RATE, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_bp,
+      { "Bridge Proxy", "homeplug.cer.bp",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_BP, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_mod,
+      { "Modulation Method", "homeplug.cer.mod",
+	FT_UINT8, BASE_DEC, VALS(&homeplug_cer_mod_vals), HOMEPLUG_CER_MOD_MASK, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_vt11,
+      { "Valid Tone Flags [83-80]", "homeplug.cer.vt11",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_VT11, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_rsvd2,
+      { "Reserved", "homeplug.cer.rsvd2",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RSVD2, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_nbdas,
+      { "Number Bridged Destination Addresses", "homeplug.cer.nbdas",
+	FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_NBDAS, "", HFILL }
+    },
+
+    { &hf_homeplug_cer_bda,
+      { "Bridged Destination Address", "homeplug.cer.bda",
+	FT_ETHER, BASE_HEX, NULL, 0x0, "", HFILL }
+    },
+
+    /* Request Parameters and Statistics */
+    { &hf_homeplug_rps,
+      { "Request Parameters and Statistics", "homeplug.rps",
+	FT_NONE, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+	
+    /* Parameters and Statistics Response */
+    { &hf_homeplug_psr,
+      { "Parameters and Statistics Response", "homeplug.psr",
+	FT_NONE, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_psr_txack,
+      { "Transmit ACK Counter", "homeplug.psr.txack",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_psr_txnack,
+      { "Transmit NACK Counter", "homeplug.psr.txnack",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_psr_txfail,
+      { "Transmit FAIL Counter", "homeplug.psr.txfail",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_psr_txcloss,
+      { "Transmit Contention Loss Counter", "homeplug.psr.txcloss",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_psr_txcoll,
+      { "Transmit Collision Counter", "homeplug.psr.txcoll",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_psr_txca3lat,
+      { "Transmit CA3 Latency Counter", "homeplug.psr.txca3lat",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_psr_txca2lat,
+      { "Transmit CA2 Latency Counter", "homeplug.psr.txca2lat",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+    { &hf_homeplug_psr_txca1lat,
+      { "Transmit CA1 Latency Counter", "homeplug.psr.txca1lat",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+    { &hf_homeplug_psr_txca0lat,
+      { "Transmit CA0 Latency Counter", "homeplug.psr.txca0lat",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_psr_rxbp40,
+      { "Receive Cumulative Bytes per 40-symbol", "homeplug.psr.rxbp40",
+	FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    /* Network Statistics Basic */
+    { &hf_homeplug_ns,
+      { "Network Statistics Basic", "homeplug.ns",
+	FT_NONE, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_ns_netw_ctrl_ac, 
+      { "Action Control", "homeplug.ns.ac",
+      FT_BOOLEAN, BASE_DEC, NULL, HOMEPLUG_NS_AC, "", HFILL }
+    },
+    
+    { &hf_homeplug_ns_netw_ctrl_icid,
+      { "IC_ID", "homeplug.ns.icid",
+      FT_UINT8, BASE_HEX, VALS(&homeplug_ns_icid_vals), HOMEPLUG_NS_ICID_MASK, "", HFILL }
+    },
+
+    { &hf_homeplug_ns_netw_ctrl_icid_rsvd,
+      { "IC_ID Reserved", "homeplug.ns.icid",
+	FT_NONE, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_ns_bytes40_robo,
+      { "Bytes in 40 symbols in ROBO", "homeplug.ns.bytes40_robo",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_ns_fails_robo,
+      { "Fails Received in ROBO", "homeplug.ns.fails_robo",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_ns_drops_robo,
+      { "Frame Drops in ROBO", "homeplug.ns.drops_robo",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    /* TODO NETW_DA1 ... */
+    { &hf_homeplug_ns_netw_da,
+      { "Address of Network DA", "homeplug.ns.netw_da",
+	FT_ETHER, BASE_HEX, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_ns_bytes40,
+      { "Bytes in 40 symbols", "homeplug.ns.bytes40",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_ns_fails,
+      { "Fails Received", "homeplug.ns.fails",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    },
+
+    { &hf_homeplug_ns_drops,
+      { "Frame Drops", "homeplug.ns.drops",
+	FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+    }
+
+    /* TODO Network Statistics Extended */
+  };
+
+  /* Setup protocol subtree array */
+  static gint *ett[] = {
+    &ett_homeplug,
+    &ett_homeplug_mctrl,
+    &ett_homeplug_mehdr,
+    &ett_homeplug_rce,
+    &ett_homeplug_cer,
+    &ett_homeplug_rps,
+    &ett_homeplug_psr,
+    &ett_homeplug_ns,
+    &ett_homeplug_tone,
+  };
+
+  proto_homeplug= proto_register_protocol(
+			    "HomePlug protocol",  /* Name */
+			    "HomePlug",		  /* Short Name */
+			    "homeplug"		  /* Abbrev */
+			    );
+  proto_register_field_array(proto_homeplug,
+			       hf, array_length(hf));
+  proto_register_subtree_array(ett, array_length(ett));
+}
+
+/* Dissection of MCTRL */
+static void dissect_homeplug_mctrl(tvbuff_t * tvb, proto_tree * tree)
+{
+  proto_item * it = NULL;
+  proto_tree * additional_tree = NULL;
+  
+  it = proto_tree_add_item(tree, hf_homeplug_mctrl, tvb, 0, 1, FALSE);
+  additional_tree = proto_item_add_subtree(it, ett_homeplug_mctrl);
+    proto_tree_add_item(additional_tree, hf_homeplug_mctrl_reserved, tvb, 0, 1, FALSE);
+    proto_tree_add_item(additional_tree, hf_homeplug_mctrl_ne, tvb, 0, 1, FALSE);
+
+  homeplug_ne = tvb_get_guint8(tvb, 0) & HOMEPLUG_MCTRL_NE;
+
+  homeplug_offset += 1;
+  
+}
+
+/* Dissection of MEHDR */
+static void dissect_homeplug_mehdr(tvbuff_t * tvb, proto_tree * tree)
+{
+  proto_item * it = NULL;
+  proto_tree * additional_tree = NULL;
+  
+  it = proto_tree_add_item (tree, hf_homeplug_mehdr, tvb, homeplug_offset, 1, FALSE);
+  additional_tree = proto_item_add_subtree(it, ett_homeplug_mehdr);
+    proto_tree_add_item(additional_tree, hf_homeplug_mehdr_mev, tvb, homeplug_offset, 1, FALSE);
+    proto_tree_add_item(additional_tree, hf_homeplug_mehdr_metype, tvb, homeplug_offset, 1, FALSE);
+
+  homeplug_metype = tvb_get_guint8(tvb, homeplug_offset) & HOMEPLUG_MEHDR_METYPE;
+
+  homeplug_offset += 1;
+}
+
+/* dissection of MELEN */
+static void dissect_homeplug_melen(tvbuff_t * tvb, proto_tree * tree)
+{
+  proto_tree_add_item(tree, hf_homeplug_melen, tvb, homeplug_offset, 1, FALSE);
+
+  homeplug_melen = tvb_get_guint8(tvb, homeplug_offset); 
+
+  homeplug_offset += 1;
+}
+
+/* Dissection of Request Channel Estimation MME */
+static void dissect_homeplug_rce(tvbuff_t * tvb, proto_tree * tree)
+{
+  proto_item * it = NULL;
+  proto_tree * additional_tree= NULL;
+
+  it = proto_tree_add_item(tree, hf_homeplug_rce, tvb, homeplug_offset, homeplug_melen, FALSE);
+  additional_tree = proto_item_add_subtree(it , ett_homeplug_rce);
+    proto_tree_add_item(additional_tree, hf_homeplug_rce_cev, tvb, homeplug_offset, 1, FALSE);
+    proto_tree_add_item(additional_tree, hf_homeplug_rce_rsvd, tvb, homeplug_offset, 1, FALSE);
+
+  homeplug_offset += 1;
+}
+
+/* Dissection of Channel Estimation Response MME */
+static void dissect_homeplug_cer(tvbuff_t * tvb, proto_tree * tree)
+{
+  proto_item * it = NULL;
+  proto_tree * additional_tree = NULL;
+  guint8 iTone = 0;
+  guint8 BP = 0;
+  guint8 iNBDA = 0;
+
+  it = proto_tree_add_item(tree, hf_homeplug_cer, tvb, homeplug_offset, homeplug_melen, FALSE);
+  additional_tree = proto_item_add_subtree(it, ett_homeplug_cer);
+    proto_tree_add_item(additional_tree, hf_homeplug_cer_cerv, tvb, homeplug_offset, 1, FALSE);
+    proto_tree_add_item(additional_tree, hf_homeplug_cer_rsvd1, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 1;
+    proto_tree_add_item(additional_tree, hf_homeplug_cer_rxtmi, tvb, homeplug_offset, 1, FALSE);
+    homeplug_offset += 1;
+    while (iTone < 10) {
+      proto_tree_add_item(additional_tree, hf_homeplug_cer_vt, tvb, homeplug_offset, 1, FALSE);
+      homeplug_offset += 1;
+      iTone ++;
+    }
+    proto_tree_add_item(additional_tree, hf_homeplug_cer_rate, tvb, homeplug_offset, 1, FALSE);
+    proto_tree_add_item(additional_tree, hf_homeplug_cer_bp, tvb, homeplug_offset, 1, FALSE);
+    BP = tvb_get_guint8(tvb, homeplug_offset) & HOMEPLUG_CER_BP;
+    proto_tree_add_item(additional_tree, hf_homeplug_cer_mod, tvb, homeplug_offset, 1, FALSE);
+    proto_tree_add_item(additional_tree, hf_homeplug_cer_vt11, tvb, homeplug_offset, 1, FALSE);
+    homeplug_offset += 1;
+    proto_tree_add_item(additional_tree, hf_homeplug_cer_rsvd2, tvb, homeplug_offset, 1, FALSE);
+    if (BP) {
+      proto_tree_add_item(additional_tree, hf_homeplug_cer_nbdas, tvb, homeplug_offset, 1, FALSE);
+      iNBDA = tvb_get_guint8(tvb, homeplug_offset) & HOMEPLUG_CER_NBDAS;
+      homeplug_offset += 1;
+      /* TODO : Check on iNBDA! INT51X1 up to 16 dba. But up to 32 for INT51X1 (Host/DTE) */
+      while (iNBDA > 0) {
+	proto_tree_add_item(additional_tree, hf_homeplug_cer_bda, tvb, homeplug_offset, 6, FALSE);
+	homeplug_offset += 6;
+	iNBDA--;
+      }
+    }
+}
+
+/* Dissection of Request Parameters and Statistics MME */
+static void dissect_homeplug_rps(tvbuff_t * tvb, proto_tree * tree)
+{
+  proto_tree_add_item(tree, hf_homeplug_rps, tvb, homeplug_offset, homeplug_melen, FALSE);
+}
+
+/* Dissection of Parameters and Statistics Response MME */
+static void dissect_homeplug_psr(tvbuff_t * tvb, proto_tree * tree)
+{
+  proto_item * it = NULL;
+  proto_tree * additional_tree=NULL;
+  
+  it = proto_tree_add_item(tree, hf_homeplug_psr, tvb, homeplug_offset, homeplug_melen, FALSE); 
+  additional_tree = proto_item_add_subtree(it, ett_homeplug_psr);
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txack, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txnack, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txfail, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txcloss, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txcoll, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txca3lat, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txca2lat, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txca1lat, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_txca0lat, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_psr_rxbp40, tvb, homeplug_offset, 4, FALSE);
+    homeplug_offset += 4;
+}
+
+/* Dissection of the Network Statistic MME */
+static void dissect_homeplug_ns(tvbuff_t * tvb, proto_tree * tree)
+{
+  proto_item * it = NULL;
+  proto_tree * additional_tree=NULL, * tree_tone = NULL;
+  guint8 homeplug_ns_icid_rsvd = 0;
+  guint8 iTone = 0;
+
+  /* TODO : test length of the MME : differentiation of NS Basic and Extended */
+  it = proto_tree_add_item(tree, hf_homeplug_ns, tvb, homeplug_offset, homeplug_melen, FALSE);
+  additional_tree = proto_item_add_subtree(it, ett_homeplug_ns);
+    proto_tree_add_item(additional_tree, hf_homeplug_ns_netw_ctrl_ac, tvb, homeplug_offset, 1, FALSE);
+    homeplug_ns_icid_rsvd = tvb_get_guint8(tvb, homeplug_offset) & HOMEPLUG_NS_ICID_RSVD_MASK; 
+    if (homeplug_ns_icid_rsvd)
+      proto_tree_add_item(additional_tree, hf_homeplug_ns_netw_ctrl_icid_rsvd, tvb, homeplug_offset, 1, FALSE);
+    else
+      proto_tree_add_item(additional_tree, hf_homeplug_ns_netw_ctrl_icid, tvb, homeplug_offset, 1, FALSE);
+    homeplug_offset += 1;
+    /* TODO : Represents MHz by bytes40/42 */
+    proto_tree_add_item(additional_tree, hf_homeplug_ns_bytes40_robo, tvb, homeplug_offset, 2, TRUE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_ns_fails_robo, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    proto_tree_add_item(additional_tree, hf_homeplug_ns_drops_robo, tvb, homeplug_offset, 2, FALSE);
+    homeplug_offset += 2;
+    while (iTone < 15) {
+      it = proto_tree_add_text(additional_tree, tvb, homeplug_offset, 12, "Tone Map #%d", iTone+1);
+      tree_tone = proto_item_add_subtree(it, ett_homeplug_tone);
+	/* TODO : check if the (da == 01:00:00:00:00:00). It tell us that following data are not valid. */
+	proto_tree_add_item(tree_tone, hf_homeplug_ns_netw_da, tvb, homeplug_offset, 6, FALSE);
+	homeplug_offset += 6;
+	/* TODO : Represents MHz by bytes40/42 */
+	proto_tree_add_item(tree_tone, hf_homeplug_ns_bytes40, tvb, homeplug_offset, 2, TRUE);
+	homeplug_offset += 2;
+	proto_tree_add_item(tree_tone, hf_homeplug_ns_fails, tvb, homeplug_offset, 2, TRUE);
+	homeplug_offset += 2;
+	proto_tree_add_item(tree_tone, hf_homeplug_ns_drops, tvb, homeplug_offset, 2, TRUE);
+	homeplug_offset += 2;
+
+      iTone++;
+    }
+}
+
+static void dissect_homeplug_mme(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+
+  switch(homeplug_metype) {
+    case HOMEPLUG_MME_RCE:
+      if (check_col(pinfo->cinfo, COL_INFO)) {
+	col_clear(pinfo->cinfo, COL_INFO);
+	col_set_str(pinfo->cinfo, COL_INFO, "Request Channel Estimation");
+      }
+      dissect_homeplug_rce(tvb, tree);
+      break;
+    case HOMEPLUG_MME_CER:
+      if (check_col(pinfo->cinfo, COL_INFO)) {
+	col_clear(pinfo->cinfo, COL_INFO);
+	col_set_str(pinfo->cinfo, COL_INFO, "Channel Estimation Response");
+      }
+      dissect_homeplug_cer(tvb, tree);
+      break;
+    case HOMEPLUG_MME_RPS:
+      if (check_col(pinfo->cinfo, COL_INFO)) {
+	col_clear(pinfo->cinfo, COL_INFO);
+	col_set_str(pinfo->cinfo, COL_INFO, "Request Parameters and Statistics");
+      } 
+      dissect_homeplug_rps(tvb, tree);
+      break;
+    case HOMEPLUG_MME_PSR:
+      if (check_col(pinfo->cinfo, COL_INFO)) {
+	col_clear(pinfo->cinfo, COL_INFO);
+	col_set_str(pinfo->cinfo, COL_INFO, "Parameters and Statistics Response");
+      }
+      dissect_homeplug_psr(tvb, tree);
+      break;
+    case HOMEPLUG_MME_NS:
+      if (check_col(pinfo->cinfo, COL_INFO)) {
+	col_clear(pinfo->cinfo, COL_INFO);
+	col_set_str(pinfo->cinfo, COL_INFO, "Network Statistics");
+      }
+      dissect_homeplug_ns(tvb, tree);
+      break;
+  }
+}
+
+static int
+dissect_homeplug(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+  proto_item * it= NULL;
+  proto_tree * homeplug_tree= NULL;
+
+  if (check_col(pinfo->cinfo, COL_PROTOCOL))
+    col_set_str(pinfo->cinfo, COL_PROTOCOL, "HomePlug");
+  /* Clear out stuff in the info column */
+  if (check_col(pinfo->cinfo, COL_INFO)) {
+    col_clear(pinfo->cinfo, COL_INFO);
+    col_set_str(pinfo->cinfo, COL_INFO, "MAC Management");
+  }
+
+  if (tree) {
+    homeplug_offset = 0;
+    it= proto_tree_add_item(tree, proto_homeplug, tvb, homeplug_offset, -1, FALSE);
+    homeplug_tree = proto_item_add_subtree(it, ett_homeplug);
+
+    dissect_homeplug_mctrl(tvb, homeplug_tree);
+    /*proto_item * it = NULL;
+    proto_tree * additional_tree = NULL;*/
+
+    /* homeplug_ne indicates the number of MME entries. This field is fetched
+     * from MCTRL. */
+    while (homeplug_ne > 0) {
+      dissect_homeplug_mehdr(tvb, homeplug_tree);
+
+      dissect_homeplug_melen(tvb, homeplug_tree);
+
+      dissect_homeplug_mme(tvb, pinfo, homeplug_tree);
+
+      homeplug_ne--;
+    }
+  }
+  return tvb_length(tvb);
+}
+
+void
+proto_reg_handoff_homeplug(void)
+{
+    homeplug_handle = new_create_dissector_handle(dissect_homeplug, proto_homeplug);
+    dissector_add("ethertype", ETHERTYPE_HOMEPLUG, homeplug_handle);
+}
--- svn-copy/epan/etypes.h	2006-12-04 22:06:20.000000000 +0100
+++ svn-working/epan/etypes.h	2006-12-05 01:04:02.000000000 +0100
@@ -246,6 +246,11 @@
 #define ETHERTYPE_MS_NLB_HEARTBEAT	0x886f	/* MS Network Load Balancing heartbeat http://www.microsoft.com/technet/treeview/default.asp?url=/TechNet/prodtechnol/windows2000serv/deploy/confeat/nlbovw.asp */
 #endif
 
+
+#ifndef ETHERTYPE_HOMEPLUG
+#define ETHERTYPE_HOMEPLUG    0x887B  /* IEEE assigned Ethertype */
+#endif
+
 #ifndef ETHERTYPE_CDMA2000_A10_UBS
 #define ETHERTYPE_CDMA2000_A10_UBS	0x8881	/* the byte stream protocol that is used for IP based micro-mobility bearer interfaces (A10) in CDMA2000(R)-based wireless networks */
 #endif