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):