Wireshark-dev: [Wireshark-dev] [PATCH] new dissector : Homeplug
From: Sebastien Tandel <sebastien@xxxxxxxxx>
Date: Tue, 16 Jan 2007 21:06:53 +0100
Hi all, a re-post for the Homeplug dissector. (fuzz-tested) Regards, Sebastien Tandel
Index: epan/etypes.h =================================================================== --- epan/etypes.h (revision 20454) +++ epan/etypes.h (working copy) @@ -246,6 +246,10 @@ #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 Index: epan/dissectors/packet-homeplug.c =================================================================== --- epan/dissectors/packet-homeplug.c (revision 0) +++ epan/dissectors/packet-homeplug.c (revision 0) @@ -0,0 +1,836 @@ +/* packet-homeplug.c + * Routines for homeplug dissection + * + * Copyright 2006, Sebastien Tandel <sebastien@xxxxxxxxx> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@xxxxxxxxxxxxx> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> + +#include <epan/packet.h> +#include <epan/prefs.h> + +#include <epan/etypes.h> + +#include <epan/proto.h> +#include <epan/ptvcursor.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 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; +/* for a later use */ +/* 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} +}; + +#define HOMEPLUG_MCTRL_LEN 1 +#define HOMEPLUG_MEHDR_LEN 1 +#define HOMEPLUG_MELEN_LEN 1 + + +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, "MAC Control Field", HFILL } + }, + + { &hf_homeplug_mctrl_reserved, + { "Reserved", "homeplug.mctrl.rsvd", + FT_NONE, BASE_DEC, NULL, HOMEPLUG_MCTRL_RSVD, "Reserved", HFILL } + }, + + { &hf_homeplug_mctrl_ne, + { "Number of MAC Data Entries", "homeplug.mctrl.ne", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_MCTRL_NE, "Number of MAC Data Entries", HFILL } + }, + + /* MAC Entry Header */ + { &hf_homeplug_mehdr, + { "MAC Management Entry Header", "homeplug.mehdr", + FT_NONE, BASE_DEC, NULL, 0x0, "MAC Management Entry Header", HFILL } + }, + + { &hf_homeplug_mehdr_mev, + { "MAC Entry Version", "homeplug.mehdr.mev", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_MEHDR_MEV, "MAC Entry Version", HFILL } + }, + + { &hf_homeplug_mehdr_metype, + { "MAC Entry Type", "homeplug.mehdr.metype", + FT_UINT8, BASE_HEX, NULL, HOMEPLUG_MEHDR_METYPE, "MAC Entry Type", HFILL } + }, + + /* MAC Entry Len */ + { &hf_homeplug_melen, + { "MAC Management Entry Length", "homeplug.melen", + FT_UINT8, BASE_DEC, NULL, 0x0, "MAC Management Entry Length", HFILL } + }, + + /* MAC Management Entry */ + { &hf_homeplug_mme, + { "MAC Management Entry Data", "homeplug.mmentry", + FT_UINT8, BASE_DEC, NULL, 0x0, "MAC Management Entry Data", HFILL } + }, + + /* Request Channel Estimation */ + { &hf_homeplug_rce, + { "Request Channel Estimation", "homeplug.rce", + FT_NONE, BASE_DEC, NULL, 0x0, "Request Channel Estimation", HFILL } + }, + + { &hf_homeplug_rce_cev, + { "Channel Estimation Version", "homeplug.rce.cev", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_RCE_CEV, "Channel Estimation Version", HFILL } + }, + + { &hf_homeplug_rce_rsvd, + { "Reserved", "homeplug.rce.rsvd", + FT_NONE, BASE_DEC, NULL, HOMEPLUG_RCE_RSVD, "Reserved", HFILL } + }, + + /* Channel Estimation Response */ + { &hf_homeplug_cer, + { "Channel Estimation Response", "homeplug.cer", + FT_NONE, BASE_DEC, NULL, 0x0, "Channel Estimation Response", HFILL } + }, + + { &hf_homeplug_cer_cerv, + { "Channel Estimation Response Version", "homeplug.cer.cerv", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_CERV, "Channel Estimation Response Version", HFILL } + }, + + { &hf_homeplug_cer_rsvd1, + { "Reserved", "homeplug.cer.rsvd1", + FT_NONE, BASE_DEC, NULL, HOMEPLUG_CER_RSVD, "Reserved", HFILL } + }, + + { &hf_homeplug_cer_rxtmi, + { "Receive Tone Map Index", "homeplug.cer.rxtmi", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RXTMI, "Receive Tone Map Index", HFILL } + }, + + /* TODO must append vt[79-0] */ + + { &hf_homeplug_cer_vt, + {"Valid Tone Flags", "homeplug.cer.vt", + FT_UINT8, BASE_HEX, NULL, 0x0, "Valid Tone Flags", HFILL } + }, + + { &hf_homeplug_cer_rate, + { "FEC Rate", "homeplug.cer.rate", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RATE, "FEC Rate", HFILL } + }, + + { &hf_homeplug_cer_bp, + { "Bridge Proxy", "homeplug.cer.bp", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_BP, "Bridge Proxy", HFILL } + }, + + { &hf_homeplug_cer_mod, + { "Modulation Method", "homeplug.cer.mod", + FT_UINT8, BASE_DEC, VALS(&homeplug_cer_mod_vals), HOMEPLUG_CER_MOD_MASK, + "Modulation Method", HFILL } + }, + + { &hf_homeplug_cer_vt11, + { "Valid Tone Flags [83-80]", "homeplug.cer.vt11", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_VT11, "Valid Tone Flags [83-80]", HFILL } + }, + + { &hf_homeplug_cer_rsvd2, + { "Reserved", "homeplug.cer.rsvd2", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RSVD2, "Reserved", HFILL } + }, + + { &hf_homeplug_cer_nbdas, + { "Number Bridged Destination Addresses", "homeplug.cer.nbdas", + FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_NBDAS, "Number Bridged Destination Addresses", HFILL } + }, + + { &hf_homeplug_cer_bda, + { "Bridged Destination Address", "homeplug.cer.bda", + FT_ETHER, BASE_HEX, NULL, 0x0, "Bridged Destination Address", HFILL } + }, + + /* Request Parameters and Statistics */ + { &hf_homeplug_rps, + { "Request Parameters and Statistics", "homeplug.rps", + FT_NONE, BASE_DEC, NULL, 0x0, "Request Parameters and Statistics", HFILL } + }, + + /* Parameters and Statistics Response */ + { &hf_homeplug_psr, + { "Parameters and Statistics Response", "homeplug.psr", + FT_NONE, BASE_DEC, NULL, 0x0, "Parameters and Statistics Response", HFILL } + }, + + { &hf_homeplug_psr_txack, + { "Transmit ACK Counter", "homeplug.psr.txack", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit ACK Counter", HFILL } + }, + + { &hf_homeplug_psr_txnack, + { "Transmit NACK Counter", "homeplug.psr.txnack", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit NACK Counter", HFILL } + }, + + { &hf_homeplug_psr_txfail, + { "Transmit FAIL Counter", "homeplug.psr.txfail", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit FAIL Counter", HFILL } + }, + + { &hf_homeplug_psr_txcloss, + { "Transmit Contention Loss Counter", "homeplug.psr.txcloss", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit Contention Loss Counter", HFILL } + }, + + { &hf_homeplug_psr_txcoll, + { "Transmit Collision Counter", "homeplug.psr.txcoll", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit Collision Counter", HFILL } + }, + + { &hf_homeplug_psr_txca3lat, + { "Transmit CA3 Latency Counter", "homeplug.psr.txca3lat", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA3 Latency Counter", HFILL } + }, + + { &hf_homeplug_psr_txca2lat, + { "Transmit CA2 Latency Counter", "homeplug.psr.txca2lat", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA2 Latency Counter", HFILL } + }, + { &hf_homeplug_psr_txca1lat, + { "Transmit CA1 Latency Counter", "homeplug.psr.txca1lat", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA1 Latency Counter", HFILL } + }, + { &hf_homeplug_psr_txca0lat, + { "Transmit CA0 Latency Counter", "homeplug.psr.txca0lat", + FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA0 Latency Counter", HFILL } + }, + + { &hf_homeplug_psr_rxbp40, + { "Receive Cumulative Bytes per 40-symbol", "homeplug.psr.rxbp40", + FT_UINT32, BASE_DEC, NULL, 0x0, "Receive Cumulative Bytes per 40-symbol", HFILL } + }, + + /* Network Statistics Basic */ + { &hf_homeplug_ns, + { "Network Statistics Basic", "homeplug.ns", + FT_NONE, BASE_DEC, NULL, 0x0, "Network Statistics Basic", HFILL } + }, + + { &hf_homeplug_ns_netw_ctrl_ac, + { "Action Control", "homeplug.ns.ac", + FT_BOOLEAN, BASE_DEC, NULL, HOMEPLUG_NS_AC, "Action Control", 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, "IC_ID", HFILL } + }, + + { &hf_homeplug_ns_netw_ctrl_icid_rsvd, + { "IC_ID Reserved", "homeplug.ns.icid", + FT_NONE, BASE_DEC, NULL, 0x0, "IC_ID Reserved", HFILL } + }, + + { &hf_homeplug_ns_bytes40_robo, + { "Bytes in 40 symbols in ROBO", "homeplug.ns.bytes40_robo", + FT_UINT16, BASE_DEC, NULL, 0x0, "Bytes in 40 symbols in ROBO", HFILL } + }, + + { &hf_homeplug_ns_fails_robo, + { "Fails Received in ROBO", "homeplug.ns.fails_robo", + FT_UINT16, BASE_DEC, NULL, 0x0, "Fails Received in ROBO", HFILL } + }, + + { &hf_homeplug_ns_drops_robo, + { "Frame Drops in ROBO", "homeplug.ns.drops_robo", + FT_UINT16, BASE_DEC, NULL, 0x0, "Frame Drops in ROBO", HFILL } + }, + + /* TODO NETW_DA1 ... */ + { &hf_homeplug_ns_netw_da, + { "Address of Network DA", "homeplug.ns.netw_da", + FT_ETHER, BASE_HEX, NULL, 0x0, "Address of Network DA", HFILL } + }, + + { &hf_homeplug_ns_bytes40, + { "Bytes in 40 symbols", "homeplug.ns.bytes40", + FT_UINT16, BASE_DEC, NULL, 0x0, "Bytes in 40 symbols", HFILL } + }, + + { &hf_homeplug_ns_fails, + { "Fails Received", "homeplug.ns.fails", + FT_UINT16, BASE_DEC, NULL, 0x0, "Fails Received", HFILL } + }, + + { &hf_homeplug_ns_drops, + { "Frame Drops", "homeplug.ns.drops", + FT_UINT16, BASE_DEC, NULL, 0x0, "Frame Drops", 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(ptvcursor_t * cursor) +{ + proto_tree *additional_tree= NULL; + proto_item * it = NULL; + + proto_tree *initial_tree= NULL; + if (!cursor || !ptvcursor_tree(cursor)) + return; + + initial_tree= ptvcursor_tree(cursor); + + it = ptvcursor_add_no_advance(cursor, hf_homeplug_mctrl, 1, FALSE); + homeplug_ne = tvb_get_guint8(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)) & HOMEPLUG_MCTRL_NE; + + additional_tree = proto_item_add_subtree(it, ett_homeplug_mctrl); + ptvcursor_set_tree(cursor, additional_tree); + ptvcursor_add_no_advance(cursor, hf_homeplug_mctrl_reserved, 1, FALSE); + ptvcursor_add(cursor, hf_homeplug_mctrl_ne, 1, FALSE); + + ptvcursor_set_tree(cursor, initial_tree); +} + +/* Dissection of MEHDR */ +static void dissect_homeplug_mehdr(ptvcursor_t * cursor) +{ + proto_tree *additional_tree= NULL; + proto_item * it = NULL; + + proto_tree *initial_tree= NULL; + if (!cursor || !ptvcursor_tree(cursor)) + return; + + initial_tree= ptvcursor_tree(cursor); + + it = ptvcursor_add_no_advance(cursor, hf_homeplug_mehdr, 0, FALSE); + homeplug_metype = tvb_get_guint8(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)) & HOMEPLUG_MEHDR_METYPE; + + additional_tree = proto_item_add_subtree(it, ett_homeplug_mehdr); + ptvcursor_set_tree(cursor, additional_tree); + ptvcursor_add_no_advance(cursor, hf_homeplug_mehdr_mev, 1, FALSE); + ptvcursor_add(cursor, hf_homeplug_mehdr_metype, 1, FALSE); + + ptvcursor_set_tree(cursor, initial_tree); +} + + +/* dissection of MELEN */ +static void dissect_homeplug_melen(ptvcursor_t * cursor) +{ + if (!cursor || !ptvcursor_tree(cursor)) + return; + + homeplug_melen = tvb_get_guint8(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor)); + ptvcursor_add(cursor, hf_homeplug_melen, 1, FALSE); +} + +/* Dissection of Request Channel Estimation MME */ +static void dissect_homeplug_rce(ptvcursor_t * cursor) +{ + proto_tree *additional_tree= NULL; + proto_item * it = NULL; + + proto_tree *initial_tree= NULL; + if (!cursor || !ptvcursor_tree(cursor)) + return; + + initial_tree= ptvcursor_tree(cursor); + + it = ptvcursor_add_no_advance(cursor, hf_homeplug_rce, homeplug_melen, FALSE); + + additional_tree = proto_item_add_subtree(it , ett_homeplug_rce); + ptvcursor_set_tree(cursor, additional_tree); + ptvcursor_add_no_advance(cursor, hf_homeplug_rce_cev, 1, FALSE); + ptvcursor_add(cursor, hf_homeplug_rce_rsvd, 1, FALSE); + + ptvcursor_set_tree(cursor, initial_tree); +} + +/* Dissection of Channel Estimation Response MME */ +static void dissect_homeplug_cer(ptvcursor_t * cursor) +{ + proto_tree * additional_tree = NULL; + proto_item * it = NULL; + guint8 iTone = 0; + guint8 BP = 0; + guint8 iNBDA = 0; + + proto_tree *initial_tree= NULL; + if (!cursor || !ptvcursor_tree(cursor)) + return; + + initial_tree= ptvcursor_tree(cursor); + + it = ptvcursor_add_no_advance(cursor, hf_homeplug_cer_cerv, homeplug_melen, FALSE); + + additional_tree = proto_item_add_subtree(it, ett_homeplug_cer); + ptvcursor_set_tree(cursor, additional_tree); + ptvcursor_add_no_advance(cursor, hf_homeplug_cer_cerv, 1, FALSE); + ptvcursor_add(cursor, hf_homeplug_cer_rsvd1, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_cer_rxtmi, 1, FALSE); + + for (;iTone < 10; iTone++) { + ptvcursor_add(cursor, hf_homeplug_cer_vt, 1, FALSE); + } + + ptvcursor_add_no_advance(cursor, hf_homeplug_cer_rate, 1, FALSE); + ptvcursor_add_no_advance(cursor, hf_homeplug_cer_bp, 1, FALSE); + BP = tvb_get_guint8(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)) & HOMEPLUG_CER_BP; + ptvcursor_add_no_advance(cursor, hf_homeplug_cer_mod, 1, FALSE); + ptvcursor_add(cursor, hf_homeplug_cer_vt11, 1, FALSE); + ptvcursor_add_no_advance(cursor, hf_homeplug_cer_rsvd2, 1, FALSE); + + if (BP) { + iNBDA = tvb_get_guint8(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)) & HOMEPLUG_CER_NBDAS; + ptvcursor_add(cursor, hf_homeplug_cer_nbdas, 1, FALSE); + /* TODO : Check on iNBDA! INT51X1 up to 16 dba. But up to 32 for INT51X1 (Host/DTE) */ + for (;iNBDA > 0; iNBDA--) { + ptvcursor_add(cursor, hf_homeplug_cer_bda, 6, FALSE); + } + } + ptvcursor_set_tree(cursor, initial_tree); +} + + +/* Dissection of Request Parameters and Statistics MME */ +static void dissect_homeplug_rps(ptvcursor_t * cursor) +{ + if (!cursor || !ptvcursor_tree(cursor)) + return; + + ptvcursor_add(cursor, hf_homeplug_rps, 4, FALSE); +} + +/* Dissection of Parameters and Statistics Response MME */ +static void dissect_homeplug_psr(ptvcursor_t * cursor) +{ + proto_tree *additional_tree =NULL; + proto_item * it = NULL; + + proto_tree *initial_tree= NULL; + if (!cursor || !ptvcursor_tree(cursor)) + return; + + initial_tree= ptvcursor_tree(cursor); + + it = ptvcursor_add_no_advance(cursor, hf_homeplug_psr, homeplug_melen, FALSE); + + additional_tree = proto_item_add_subtree(it, ett_homeplug_psr); + ptvcursor_set_tree(cursor, additional_tree); + ptvcursor_add(cursor, hf_homeplug_psr_txack, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_txnack, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_txfail, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_txcloss, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_txcoll, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_txca3lat, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_txca2lat, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_txca1lat, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_txca0lat, 2, FALSE); + ptvcursor_add(cursor, hf_homeplug_psr_rxbp40, 4, FALSE); + + ptvcursor_set_tree(cursor, initial_tree); +} + +/* Dissection of the Network Statistic MME */ +static void dissect_homeplug_ns(ptvcursor_t * cursor) +{ + proto_item * it = NULL; + proto_tree * additional_tree=NULL, * tree_tone = NULL; + guint8 homeplug_ns_icid_rsvd = 0; + guint8 iTone = 0; + + guint16 ns_bytes40= 0; + guint64 newt_da= 0; +#define NEWT_DA_INEXISTANT G_GINT64_CONSTANT(010000000000U) + + proto_tree *initial_tree= NULL; + if (!cursor || !ptvcursor_tree(cursor)) + return; + + initial_tree= ptvcursor_tree(cursor); + + /* TODO : test length of the MME : differentiation of NS Basic and Extended */ + it = ptvcursor_add_no_advance(cursor, hf_homeplug_ns, homeplug_melen, FALSE); + + additional_tree = proto_item_add_subtree(it, ett_homeplug_ns); + ptvcursor_set_tree(cursor, additional_tree); + ptvcursor_add_no_advance(cursor, hf_homeplug_ns_netw_ctrl_ac, 1, FALSE); + homeplug_ns_icid_rsvd = tvb_get_guint8(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)) & HOMEPLUG_NS_ICID_RSVD_MASK; + if (homeplug_ns_icid_rsvd) + ptvcursor_add(cursor, hf_homeplug_ns_netw_ctrl_icid_rsvd, 1, FALSE); + else + ptvcursor_add(cursor, hf_homeplug_ns_netw_ctrl_icid, 1, FALSE); + + ptvcursor_add_no_advance(cursor, hf_homeplug_ns_bytes40_robo, 2, TRUE); + ns_bytes40 = tvb_get_letohs(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)); + it = proto_tree_add_text(additional_tree, ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor), 2, "MHz : %.3f", (float)(ns_bytes40)/42); + ptvcursor_advance(cursor, 2); + + ptvcursor_add(cursor, hf_homeplug_ns_fails_robo, 2, TRUE); + ptvcursor_add(cursor, hf_homeplug_ns_drops_robo, 2, TRUE); + + while (iTone < 15) { + newt_da = ((gint64)tvb_get_ntoh24(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor))) << 24; + newt_da |= tvb_get_ntoh24(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)+3); + + if (newt_da != NEWT_DA_INEXISTANT) { + it = proto_tree_add_text(additional_tree, ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor), 12, "Tone Map #%d", iTone+1); + + tree_tone = proto_item_add_subtree(it, ett_homeplug_tone); + ptvcursor_set_tree(cursor, tree_tone); + + ptvcursor_add(cursor, hf_homeplug_ns_netw_da, 6, FALSE); + + ptvcursor_add_no_advance(cursor, hf_homeplug_ns_bytes40, 2, TRUE); + ns_bytes40 = tvb_get_letohs(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)); + it = proto_tree_add_text(ptvcursor_tree(cursor), ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor), 2, "MHz : %.3f", (float)(ns_bytes40)/42); + ptvcursor_advance(cursor, 2); + + ptvcursor_add(cursor, hf_homeplug_ns_fails, 2, TRUE); + ptvcursor_add(cursor, hf_homeplug_ns_drops, 2, TRUE); + } else + it = proto_tree_add_text(additional_tree, ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor), 12, "Tone Map #%d does not exist", iTone+1); + + iTone++; + } + ptvcursor_set_tree(cursor, initial_tree); +} + +static void dissect_homeplug_mme(ptvcursor_t * cursor, packet_info * pinfo) +{ + 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(cursor); + 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(cursor); + 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(cursor); + 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(cursor); + 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(cursor); + break; + } +} + +#define TVB_LEN_GREATEST 1 +#define TVB_LEN_UNDEF 0 +#define TVB_LEN_SHORTEST -1 +static int check_tvb_length(ptvcursor_t * cursor, const guint length) +{ + if (!cursor) + return TVB_LEN_UNDEF; + + if (tvb_reported_length_remaining(ptvcursor_tvbuff(cursor), + ptvcursor_current_offset(cursor)) < length) + return TVB_LEN_SHORTEST; + + return TVB_LEN_GREATEST; +} + +static void +dissect_homeplug(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) +{ + proto_item * it= NULL; + proto_tree * homeplug_tree= NULL; + ptvcursor_t * cursor= 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"); + } + + homeplug_offset = 0; + if (tree) { + it= proto_tree_add_item(tree, proto_homeplug, tvb, homeplug_offset, -1, FALSE); + homeplug_tree = proto_item_add_subtree(it, ett_homeplug); + cursor = ptvcursor_new(homeplug_tree, tvb, 0); + } + + /* We do not have enough data to read mctrl field + * stop the dissection*/ + if (check_tvb_length(cursor, HOMEPLUG_MCTRL_LEN) != TVB_LEN_SHORTEST) { + dissect_homeplug_mctrl(cursor); + + /* homeplug_ne indicates the number of MME entries. This field is fetched + * from MCTRL. */ + for (; homeplug_ne > 0; homeplug_ne--) { + + /* Check we have enough data in tvb to read MEHDR */ + if (check_tvb_length(cursor, HOMEPLUG_MEHDR_LEN) == TVB_LEN_SHORTEST) + break; + dissect_homeplug_mehdr(cursor); + + /* Check we have enough data in tvb to read MELEN */ + if (check_tvb_length(cursor, HOMEPLUG_MELEN_LEN) == TVB_LEN_SHORTEST) + break; + dissect_homeplug_melen(cursor); + + dissect_homeplug_mme(cursor, pinfo); + } + } + + if (cursor) + ptvcursor_free(cursor); +} + +static dissector_handle_t homeplug_handle; + +void +proto_reg_handoff_homeplug(void) +{ + static gboolean initialised= FALSE; + + if (!initialised) { + homeplug_handle = create_dissector_handle(dissect_homeplug, proto_homeplug); + dissector_add("ethertype", ETHERTYPE_HOMEPLUG, homeplug_handle); + initialised= TRUE; + } +} Index: epan/dissectors/Makefile.common =================================================================== --- epan/dissectors/Makefile.common (revision 20454) +++ epan/dissectors/Makefile.common (working copy) @@ -353,6 +353,7 @@ packet-h450.c \ packet-hci_h4.c \ packet-hclnfsd.c \ + packet-homeplug.c \ packet-hpext.c \ packet-hpsw.c \ packet-hsrp.c \
- Follow-Ups:
- Re: [Wireshark-dev] [PATCH] new dissector : Homeplug
- From: Jeff Morriss
- Re: [Wireshark-dev] [PATCH] new dissector : Homeplug
- Prev by Date: [Wireshark-dev] [PATCH] proto_tree_add_item and range_string
- Next by Date: Re: [Wireshark-dev] TCP packets reassemble mechanism
- Previous by thread: [Wireshark-dev] [PATCH] proto_tree_add_item and range_string
- Next by thread: Re: [Wireshark-dev] [PATCH] new dissector : Homeplug
- Index(es):