Wireshark-dev: [Wireshark-dev] [PATCH][UPDATE] ptvcursor and subtrees
From: Sebastien Tandel <sebastien@xxxxxxxxx>
Date: Thu, 15 Mar 2007 01:11:01 +0100
Hi,
Series of three patches concerning the creation of subtrees via the
ptvcursor API :
1) ptvcursor-subtrees.diff : Update to get rid of potential memory leaks
with g_renew but also with g_new in ptvcursor_new().
New features supported by ptvcursor API :
- ptvcursor_push_subtree(), ptvcursor_pop_subtree() for pushing/popping subtrees. Multiple levels of subtrees (256 max.), allocation per 8 levels.
- Two new functions creating an item in the tree and pushing a subtree at the same time. These two functions accept an undefined length (SUBTREE_UNDEFINED_LENGTH). The length of the item is set at the next pop.
1) ptvcursor_add_with_subtree
2) ptvcursor_add_text_with_subtree
2) ptvcursor-subtrees-doc.diff : documentation of the new ptvcursor functions in README.developer
3) homeplug-ptvcursor-subtrees.diff : update of the homeplug dissector using the new ptvcursor functions.
Index: epan/dissectors/packet-homeplug.c
===================================================================
--- epan/dissectors/packet-homeplug.c (révision 21032)
+++ epan/dissectors/packet-homeplug.c (copie de travail)
@@ -39,7 +39,6 @@
#include <epan/ptvcursor.h>
-
/* METYPE Values */
#define HOMEPLUG_MME_RCE 0x00
#define HOMEPLUG_MME_CER 0x01
@@ -70,16 +69,15 @@
#define HOMEPLUG_CER_NBDAS 0x7F
-/* Length of Network Statistics Response defines whether it is the Basic or
- * the Extended Response
- */
+/* 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 proto_homeplug = -1;
static int hf_homeplug_mctrl = -1;
static int hf_homeplug_mctrl_reserved = -1;
@@ -122,29 +120,28 @@
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;
+ 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 = -1;
static int hf_homeplug_ns_bytes40_1 */
/* Extended */
/* array of 6 elements */
-/* static int hf_homeplug_ns_tx_bfr_0_state = -1;*/
+/* 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_mme = -1;
static gint ett_homeplug_rce = -1;
static gint ett_homeplug_cer = -1;
static gint ett_homeplug_rps = -1;
@@ -172,15 +169,15 @@
#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_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 }
+ { 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 */
@@ -196,17 +193,17 @@
{ HOMEPLUG_CER_MOD_DBPSK, "DBPSK Modulation"},
{ HOMEPLUG_CER_MOD_DQPSK, "DQPSK Modulation"},
{ HOMEPLUG_CER_MOD_RSVD, "Reserved"},
- { 0, NULL}
+ { 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,
@@ -216,186 +213,186 @@
{ &hf_homeplug_mctrl_reserved,
{ "Reserved", "homeplug.mctrl.rsvd",
- FT_NONE, BASE_DEC, NULL, HOMEPLUG_MCTRL_RSVD, "Reserved", HFILL }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ FT_NONE, BASE_DEC, NULL, 0x0, "Network Statistics Basic", HFILL }
},
{ &hf_homeplug_ns_netw_ctrl_ac,
@@ -410,43 +407,43 @@
{ &hf_homeplug_ns_netw_ctrl_icid_rsvd,
{ "IC_ID Reserved", "homeplug.ns.icid",
- FT_NONE, BASE_DEC, NULL, 0x0, "IC_ID Reserved", HFILL }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ 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 }
+ FT_UINT16, BASE_DEC, NULL, 0x0, "Frame Drops", HFILL }
}
/* TODO Network Statistics Extended */
@@ -462,7 +459,7 @@
&ett_homeplug_rps,
&ett_homeplug_psr,
&ett_homeplug_ns,
- &ett_homeplug_tone,
+ &ett_homeplug_tone
};
proto_homeplug = proto_register_protocol(
@@ -476,261 +473,219 @@
proto_register_subtree_array(ett, array_length(ett));
}
-
/* Dissection of MCTRL */
static void dissect_homeplug_mctrl(ptvcursor_t * cursor)
{
- proto_tree *initial_tree = NULL;
- proto_tree *additional_tree = NULL;
- proto_item *it = NULL;
+ proto_item * it = NULL;
- if (!cursor || !ptvcursor_tree(cursor))
+ if (!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;
+ 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_push_subtree(cursor, it, ett_homeplug_mctrl);
+ 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);
+ ptvcursor_pop_subtree(cursor);
}
/* Dissection of MEHDR */
static void dissect_homeplug_mehdr(ptvcursor_t * cursor)
{
- proto_tree *initial_tree = NULL;
- proto_tree *additional_tree = NULL;
- proto_item *it = NULL;
+ proto_item * it = NULL;
- if (!cursor || !ptvcursor_tree(cursor))
+ if (!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;
+ 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_push_subtree(cursor, it, ett_homeplug_mehdr);
+ 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);
+ ptvcursor_pop_subtree(cursor);
}
-
/* dissection of MELEN */
-static void dissect_homeplug_melen(ptvcursor_t *cursor)
+static void dissect_homeplug_melen(ptvcursor_t * cursor)
{
- if (!cursor || !ptvcursor_tree(cursor))
+ if (!ptvcursor_tree(cursor))
return;
- homeplug_melen = tvb_get_guint8(ptvcursor_tvbuff(cursor),
- ptvcursor_current_offset(cursor));
+ 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)
+static void dissect_homeplug_rce(ptvcursor_t * cursor)
{
- proto_tree *initial_tree = NULL;
- proto_tree *additional_tree = NULL;
- proto_item *it = NULL;
+ proto_item * it = NULL;
- if (!cursor || !ptvcursor_tree(cursor))
+ if (!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_push_subtree(cursor, it, ett_homeplug_rce);
+ 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);
+ ptvcursor_pop_subtree(cursor);
}
/* Dissection of Channel Estimation Response MME */
-static void dissect_homeplug_cer(ptvcursor_t *cursor)
+static void dissect_homeplug_cer(ptvcursor_t * cursor)
{
- proto_tree *initial_tree = NULL;
- proto_tree *additional_tree = NULL;
- proto_item *it = NULL;
- guint8 iTone;
+ proto_item * it = NULL;
+ guint8 iTone = 0;
guint8 BP = 0;
guint8 iNBDA = 0;
- if (!cursor || !ptvcursor_tree(cursor))
+ if (!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);
+ ptvcursor_push_subtree(cursor, it, ett_homeplug_cer);
+ 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 = 0; iTone < 10; iTone++) {
- ptvcursor_add(cursor, hf_homeplug_cer_vt, 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);
+ 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);
+ 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);
+ ptvcursor_pop_subtree(cursor);
}
/* Dissection of Request Parameters and Statistics MME */
-static void dissect_homeplug_rps(ptvcursor_t *cursor)
+static void dissect_homeplug_rps(ptvcursor_t * cursor)
{
- if (!cursor || !ptvcursor_tree(cursor))
+ if (!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)
+static void dissect_homeplug_psr(ptvcursor_t * cursor)
{
- proto_tree *initial_tree = NULL;
- proto_tree *additional_tree = NULL;
- proto_item *it = NULL;
+ proto_item * it = NULL;
- if (!cursor || !ptvcursor_tree(cursor))
+ if (!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_push_subtree(cursor, it, ett_homeplug_psr);
+ 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);
+ ptvcursor_pop_subtree(cursor);
}
/* Dissection of the Network Statistic MME */
-static void dissect_homeplug_ns(ptvcursor_t *cursor)
+static void dissect_homeplug_ns(ptvcursor_t * cursor)
{
- proto_item *it = NULL;
- proto_tree *additional_tree = NULL, *tree_tone = NULL;
- proto_tree *initial_tree = NULL;
guint8 homeplug_ns_icid_rsvd = 0;
guint8 iTone = 0;
- guint16 ns_bytes40 = 0;
- guint64 newt_da = 0;
+
+ guint16 ns_bytes40= 0;
+ guint64 newt_da= 0;
#define NEWT_DA_INEXISTANT G_GINT64_CONSTANT(010000000000U)
- if (!cursor || !ptvcursor_tree(cursor))
+ if (!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);
+ ptvcursor_add_with_subtree(cursor, hf_homeplug_ns, SUBTREE_UNDEFINED_LENGTH, FALSE, ett_homeplug_ns);
- 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;
+ /*it = ptvcursor_add_no_advance(cursor, hf_homeplug_ns, homeplug_melen, FALSE);
- 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_push_subtree(cursor, it, ett_homeplug_ns);*/
+ 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_no_advance(cursor, hf_homeplug_ns_bytes40_robo, 2, TRUE);
+ ns_bytes40 = tvb_get_letohs(ptvcursor_tvbuff(cursor),
+ ptvcursor_current_offset(cursor));
+ 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_robo, 2, TRUE);
- ptvcursor_add(cursor, hf_homeplug_ns_drops_robo, 2, TRUE);
+ 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);
+ 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);
+ if (newt_da != NEWT_DA_INEXISTANT) {
+ ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH,
+ ett_homeplug_tone, "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(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));
+ 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_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);
- 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);
+ ptvcursor_pop_subtree(cursor);
+ } else
+ proto_tree_add_text(ptvcursor_tree(cursor), ptvcursor_tvbuff(cursor),
+ ptvcursor_current_offset(cursor), 12, "Tone Map #%d does not exist", iTone+1);
iTone++;
- }
-
- ptvcursor_set_tree(cursor, initial_tree);
+ }
+ ptvcursor_pop_subtree(cursor);
}
-static void dissect_homeplug_mme(ptvcursor_t *cursor, packet_info *pinfo)
+static void dissect_homeplug_mme(ptvcursor_t * cursor, packet_info * pinfo)
{
switch(homeplug_metype) {
case HOMEPLUG_MME_RCE:
@@ -740,7 +695,6 @@
}
dissect_homeplug_rce(cursor);
break;
-
case HOMEPLUG_MME_CER:
if (check_col(pinfo->cinfo, COL_INFO)) {
col_clear(pinfo->cinfo, COL_INFO);
@@ -748,15 +702,13 @@
}
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);
@@ -764,7 +716,6 @@
}
dissect_homeplug_psr(cursor);
break;
-
case HOMEPLUG_MME_NS:
if (check_col(pinfo->cinfo, COL_INFO)) {
col_clear(pinfo->cinfo, COL_INFO);
@@ -776,7 +727,7 @@
}
#define TVB_LEN_GREATEST 1
-#define TVB_LEN_UNDEF 0
+#define TVB_LEN_UNDEF 0
#define TVB_LEN_SHORTEST -1
static int check_tvb_length(ptvcursor_t *cursor, const gint length)
{
@@ -784,22 +735,21 @@
return TVB_LEN_UNDEF;
if (tvb_reported_length_remaining(ptvcursor_tvbuff(cursor),
- ptvcursor_current_offset(cursor)) < length)
+ 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)
+dissect_homeplug(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
- proto_item *it = NULL;
- proto_tree *homeplug_tree = NULL;
- ptvcursor_t *cursor = NULL;
+ 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);
@@ -819,26 +769,26 @@
dissect_homeplug_mctrl(cursor);
- /* homeplug_ne indicates the number of MME entries. This field is fetched
- * from MCTRL.
+ /** 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;
+ 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;
+ break;
dissect_homeplug_melen(cursor);
dissect_homeplug_mme(cursor, pinfo);
}
}
- if (cursor)
+ if (cursor)
ptvcursor_free(cursor);
}
Index: epan/proto.c
===================================================================
--- epan/proto.c (révision 21032)
+++ epan/proto.c (copie de travail)
@@ -44,7 +44,20 @@
#include "tvbuff.h"
#include "emem.h"
+#define SUBTREE_ONCE_ALLOCATION_NUMBER 8
+#define SUBTREE_MAX_LEVELS 256
+
+
+typedef struct __subtree_lvl {
+ gint cursor_offset;
+ proto_item * it;
+ proto_tree * tree;
+}subtree_lvl;
+
struct ptvcursor {
+ subtree_lvl *pushed_tree;
+ guint8 pushed_tree_index;
+ guint8 pushed_tree_max;
proto_tree *tree;
tvbuff_t *tvb;
gint offset;
@@ -596,6 +609,30 @@
return g_tree_lookup(gpa_name_tree, field_name);
}
+
+void ptvcursor_new_subtree_levels(ptvcursor_t * ptvc)
+{
+ subtree_lvl * pushed_tree;
+
+ DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
+ ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
+
+ pushed_tree = ep_alloc(sizeof(subtree_lvl) * ptvc->pushed_tree_max);
+ DISSECTOR_ASSERT(pushed_tree != NULL);
+ if (ptvc->pushed_tree)
+ memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
+ ptvc->pushed_tree = pushed_tree;
+}
+
+void ptvcursor_free_subtree_levels(ptvcursor_t * ptvc)
+{
+ /*g_free(ptvc->pushed_tree);*/
+ ptvc->pushed_tree = NULL;
+ ptvc->pushed_tree_max = 0;
+ DISSECTOR_ASSERT(ptvc->pushed_tree_index ==0);
+ ptvc->pushed_tree_index = 0;
+}
+
/* Allocates an initializes a ptvcursor_t with 3 variables:
* proto_tree, tvbuff, and offset. */
ptvcursor_t*
@@ -603,18 +640,23 @@
{
ptvcursor_t *ptvc;
- ptvc = g_new(ptvcursor_t, 1);
+ ptvc = ep_alloc(sizeof(ptvcursor_t));
ptvc->tree = tree;
ptvc->tvb = tvb;
ptvc->offset = offset;
+ ptvc->pushed_tree= NULL;
+ ptvc->pushed_tree_max= 0;
+ ptvc->pushed_tree_index= 0;
return ptvc;
}
+
/* Frees memory for ptvcursor_t, but nothing deeper than that. */
void
ptvcursor_free(ptvcursor_t *ptvc)
{
- g_free(ptvc);
+ ptvcursor_free_subtree_levels(ptvc);
+ /*g_free(ptvc);*/
}
/* Returns tvbuff. */
@@ -634,7 +676,10 @@
proto_tree*
ptvcursor_tree(ptvcursor_t* ptvc)
{
- return ptvc->tree;
+ if (!ptvc)
+ return NULL;
+
+ return ptvc->tree;
}
void
@@ -643,6 +688,102 @@
ptvc->tree = tree;
}
+/* creates a subtree, sets it as the working tree and pushes the old working tree */
+proto_tree*
+ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
+{
+ subtree_lvl * subtree;
+ if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
+ ptvcursor_new_subtree_levels(ptvc);
+
+ subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
+ subtree->tree = ptvc->tree;
+ subtree->it= NULL;
+ ptvc->pushed_tree_index++;
+ return ptvcursor_set_subtree(ptvc, it, ett_subtree);
+}
+
+/* pops a subtree */
+void
+ptvcursor_pop_subtree(ptvcursor_t *ptvc)
+{
+ subtree_lvl * subtree;
+ if (ptvc->pushed_tree_index <= 0)
+ return;
+
+ ptvc->pushed_tree_index--;
+ subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
+ if (subtree->it != NULL)
+ proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
+ ptvc->tree = subtree->tree;
+}
+
+/* saves the current tvb offset and the item in the current subtree level */
+void ptvcursor_subtree_set_item(ptvcursor_t * ptvc, proto_item * it)
+{
+ subtree_lvl * subtree;
+
+ DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
+
+ subtree = ptvc->pushed_tree+ptvc->pushed_tree_index-1;
+ subtree->it = it;
+ subtree->cursor_offset = ptvcursor_current_offset(ptvc);
+}
+
+/* Creates a subtree and adds it to the cursor as the working tree but does not
+ * save the old working tree */
+proto_tree*
+ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
+{
+ ptvc->tree = proto_item_add_subtree(it, ett_subtree);
+ return ptvc->tree;
+}
+
+proto_tree* ptvcursor_add_subtree_item(ptvcursor_t * ptvc, proto_item * it, gint ett_subtree, gint length)
+{
+ ptvcursor_push_subtree(ptvc, it, ett_subtree);
+ if (length == SUBTREE_UNDEFINED_LENGTH)
+ ptvcursor_subtree_set_item(ptvc, it);
+ return ptvcursor_tree(ptvc);
+}
+
+/* Add an item to the tree and create a subtree
+ * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
+ * In this case, when the subtree will be closed, the parent item length will
+ * be equal to the advancement of the cursor since the creation of the subtree.
+ */
+proto_tree* ptvcursor_add_with_subtree(ptvcursor_t * ptvc, int hfindex, gint length,
+gboolean little_endian, gint ett_subtree)
+{
+ proto_item * it;
+ it = ptvcursor_add_no_advance(ptvc, hfindex, length, little_endian);
+ return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
+}
+
+static proto_item *
+proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
+
+/* Add a text node to the tree and create a subtree
+ * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
+ * In this case, when the subtree will be closed, the item length will be equal
+ * to the advancement of the cursor since the creation of the subtree.
+ */
+proto_tree * ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length,
+ gint ett_subtree, const char *format, ...)
+{
+ proto_item * it;
+ va_list ap;
+
+ it = proto_tree_add_text_node(ptvcursor_tree(ptvc), ptvcursor_tvbuff(ptvc),
+ ptvcursor_current_offset(ptvc), length);
+
+ va_start(ap, format);
+ proto_tree_set_representation(it, format, ap);
+ va_end(ap);
+
+ return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
+}
+
/* Add a text-only node, leaving it to our caller to fill the text in */
static proto_item *
proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
Index: epan/ptvcursor.h
===================================================================
--- epan/ptvcursor.h (révision 21032)
+++ epan/ptvcursor.h (copie de travail)
@@ -34,6 +34,8 @@
#include <glib.h>
#include <epan/packet.h>
+#define SUBTREE_UNDEFINED_LENGTH -1
+
typedef struct ptvcursor ptvcursor_t;
/* Allocates an initializes a ptvcursor_t with 3 variables:
@@ -77,4 +79,32 @@
void
ptvcursor_set_tree(ptvcursor_t* ptvc, proto_tree *tree);
+/* push a subtree in the tree stack of the cursor */
+proto_tree*
+ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree);
+
+/* pop a subtree in the tree stack of the cursor */
+void ptvcursor_pop_subtree(ptvcursor_t *ptvc);
+
+/* Add an item to the tree and create a subtree
+ * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
+ * In this case, when the subtree will be closed, the parent item length will
+ * be equal to the advancement of the cursor since the creation of the subtree.
+ */
+proto_tree* ptvcursor_add_with_subtree(ptvcursor_t * ptvc, int hfindex, gint length,
+gboolean little_endian, gint ett_subtree);
+
+/* Add a text node to the tree and create a subtree
+ * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
+ * In this case, when the subtree will be closed, the item length will be equal
+ * to the advancement of the cursor since the creation of the subtree.
+ */
+proto_tree * ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length,
+ gint ett_subtree, const char *format, ...);
+
+/* Creates a subtree and adds it to the cursor as the working tree but does not
+ * save the old working tree */
+proto_tree*
+ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree);
+
#endif /* __PTVCURSOR_H__ */
Index: doc/README.developer
===================================================================
--- doc/README.developer (révision 21032)
+++ doc/README.developer (copie de travail)
@@ -3395,6 +3395,17 @@
2. Add fields with multiple calls of ptvcursor_add()
3. Delete the ptvcursor with ptvcursor_free()
+ptvcursor offers the possibility to add subtrees in the tree as well. It can be
+done in very simple steps :
+ 1. Create a new subtree with ptvcursor_push_subtree(). The old subtree is
+ pushed in a stack and the new subtree will be used by ptvcursor.
+ 2. Add fields with multiple calls of ptvcursor_add(). The fields will be
+ added in the new subtree created at the previous step.
+ 3. Pop the previous subtree with ptvcursor_pop_subtree(). The previous
+ subtree is again used by ptvcursor.
+Note that at the end of the parsing of a packet you must have popped each
+subtree you pushed. If it's not the case, the dissector will generate an error.
+
To use the ptvcursor API, include the "ptvcursor.h" file. The PGM dissector
is an example of how to use it. You don't need to look at it as a guide;
instead, the API description here should be good enough.
@@ -3429,6 +3440,34 @@
Frees the memory associated with the ptvcursor. You must call this
after your dissection with the ptvcursor API is completed.
+
+proto_tree*
+ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
+ Pushes the current subtree in the tree stack of the cursor, creates a new
+ one and sets this one as the working tree.
+
+void
+ptvcursor_pop_subtree(ptvcursor_t *ptvc);
+ Pops a subtree in the tree stack of the cursor
+
+proto_tree*
+ptvcursor_add_with_subtree(ptvcursor_t * ptvc, int hfindex, gint length,
+ gboolean little_endian, gint ett_subtree);
+ Adds an item to the tree and creates a subtree.
+ If the length is unknown, length may be defined as
+ SUBTREE_UNDEFINED_LENGTH. In this case, at the next pop, the item length
+ will be equal to the advancement of the cursor since the creation of the
+ subtree.
+
+proto_tree *
+ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length,
+ gint ett_subtree, const char *format, ...);
+ Add a text node to the tree and create a subtree
+ If the length is unknown, length may be defined as
+ SUBTREE_UNDEFINED_LENGTH. In this case, at the next pop, the item length
+ will be equal to the advancement of the cursor since the creation of the
+ subtree.
+
2.8.2 Miscellaneous functions.
tvbuff_t*
- Prev by Date: Re: [Wireshark-dev] Opinions on solving bug #1375: Capture Options with many IP addresses scrolls off screen
- Next by Date: [Wireshark-dev] Query Regarding compilation of wireshark
- Previous by thread: Re: [Wireshark-dev] Opinions on solving bug #1375: Capture Options with many IP addresses scrolls off screen
- Next by thread: [Wireshark-dev] Query Regarding compilation of wireshark
- Index(es):