2 * Routines for homeplug dissection
4 * Copyright 2006, Sebastien Tandel <sebastien[AT]tandel.be>
6 * $Id: packet-sccp.c 20220 2006-12-26 22:27:46Z morriss $
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include <epan/packet.h>
34 #include <epan/prefs.h>
36 #include <epan/etypes.h>
38 #include <epan/proto.h>
39 #include <epan/ptvcursor.h>
44 #define HOMEPLUG_MME_RCE 0x00
45 #define HOMEPLUG_MME_CER 0x01
46 #define HOMEPLUG_MME_RPS 0x07
47 #define HOMEPLUG_MME_PSR 0x08
48 #define HOMEPLUG_MME_NS 0x1A
50 /* Bit mask Operation */
51 #define HOMEPLUG_MCTRL_RSVD 0x80
52 #define HOMEPLUG_MCTRL_NE 0x7F
54 #define HOMEPLUG_MEHDR_MEV 0xE0
55 #define HOMEPLUG_MEHDR_METYPE 0x1F
57 #define HOMEPLUG_NS_AC 0x80
58 #define HOMEPLUG_NS_ICID 0x7F
60 #define HOMEPLUG_RCE_CEV 0xF0
61 #define HOMEPLUG_RCE_RSVD 0x0F
63 #define HOMEPLUG_CER_CERV 0xF0
64 #define HOMEPLUG_CER_RSVD 0x0FE0
65 #define HOMEPLUG_CER_RXTMI 0x1F
66 #define HOMEPLUG_CER_RATE 0x80
67 #define HOMEPLUG_CER_BP 0x40
68 #define HOMEPLUG_CER_VT11 0x0F
69 #define HOMEPLUG_CER_RSVD2 0x80
70 #define HOMEPLUG_CER_NBDAS 0x7F
73 /* Length of Network Statistics Response defines whether it is the Basic or
74 * the Extended Response
76 #define HOMEPLUG_NS_BASIC_LEN 187
77 #define HOMEPLUG_NS_EXT_LEN 199
79 /* forward reference */
80 void proto_reg_handoff_homeplug();
82 static int proto_homeplug = -1;
84 static int hf_homeplug_mctrl = -1;
85 static int hf_homeplug_mctrl_reserved = -1;
86 static int hf_homeplug_mctrl_ne = -1;
87 static int hf_homeplug_mehdr = -1;
88 static int hf_homeplug_mehdr_mev = -1;
89 static int hf_homeplug_mehdr_metype = -1;
90 static int hf_homeplug_melen = -1;
91 static int hf_homeplug_mme = -1;
92 /* Request Channel Estimation */
93 static int hf_homeplug_rce = -1;
94 static int hf_homeplug_rce_cev = -1;
95 static int hf_homeplug_rce_rsvd = -1;
96 /* Channel Estimation Response */
97 static int hf_homeplug_cer = -1;
98 static int hf_homeplug_cer_cerv = -1;
99 static int hf_homeplug_cer_rsvd1 = -1;
100 static int hf_homeplug_cer_rxtmi = -1;
101 static int hf_homeplug_cer_vt = -1;
102 static int hf_homeplug_cer_rate = -1;
103 static int hf_homeplug_cer_bp = -1;
104 static int hf_homeplug_cer_mod = -1;
105 static int hf_homeplug_cer_vt11 = -1;
106 static int hf_homeplug_cer_rsvd2 = -1;
107 static int hf_homeplug_cer_nbdas = -1;
108 static int hf_homeplug_cer_bda = -1;
109 /* Request Parameters and Statistics */
110 static int hf_homeplug_rps = -1;
111 /* Parameters and Statistics Response */
112 static int hf_homeplug_psr = -1;
113 static int hf_homeplug_psr_txack = -1;
114 static int hf_homeplug_psr_txnack = -1;
115 static int hf_homeplug_psr_txfail = -1;
116 static int hf_homeplug_psr_txcloss = -1;
117 static int hf_homeplug_psr_txcoll = -1;
118 static int hf_homeplug_psr_txca3lat = -1;
119 static int hf_homeplug_psr_txca2lat = -1;
120 static int hf_homeplug_psr_txca1lat = -1;
121 static int hf_homeplug_psr_txca0lat = -1;
122 static int hf_homeplug_psr_rxbp40 = -1;
123 /* Network Statistics */
125 static int hf_homeplug_ns = -1;
126 static int hf_homeplug_ns_netw_ctrl_ac = -1;
127 static int hf_homeplug_ns_netw_ctrl_icid = -1;
128 static int hf_homeplug_ns_netw_ctrl_icid_rsvd= -1;
129 static int hf_homeplug_ns_bytes40_robo = -1;
130 static int hf_homeplug_ns_fails_robo = -1;
131 static int hf_homeplug_ns_drops_robo = -1;
132 static int hf_homeplug_ns_netw_da = -1;
133 static int hf_homeplug_ns_bytes40 = -1;
134 static int hf_homeplug_ns_fails = -1;
135 static int hf_homeplug_ns_drops = -1;
136 /* array of 15 elements */
137 /* static int hf_homeplug_ns_bytes40_1 = -1;
138 static int hf_homeplug_ns_bytes40_1 */
140 /* array of 6 elements */
141 /* static int hf_homeplug_ns_tx_bfr_0_state = -1;*/
143 static gint ett_homeplug = -1;
144 static gint ett_homeplug_mctrl = -1;
145 static gint ett_homeplug_mehdr = -1;
146 /* for a later use */
147 /* static gint ett_homeplug_mme = -1; */
148 static gint ett_homeplug_rce = -1;
149 static gint ett_homeplug_cer = -1;
150 static gint ett_homeplug_rps = -1;
151 static gint ett_homeplug_psr = -1;
152 static gint ett_homeplug_ns = -1;
153 static gint ett_homeplug_tone = -1;
155 static guint8 homeplug_ne = 0;
156 static guint8 homeplug_melen = 0;
157 static guint8 homeplug_metype = 0;
159 static guint32 homeplug_offset = 0;
162 #define HOMEPLUG_NS_ICID5130A1 0x00
163 #define HOMEPLUG_NS_ICID51X1USB 0x01
164 #define HOMEPLUG_NS_ICID51X1PHY 0x02
165 #define HOMEPLUG_NS_ICID51X1HOST 0x03
166 #define HOMEPLUG_NS_ICID5130A2 0x04
167 #define HOMEPLUG_NS_ICID_RSVD1 0x05
168 #define HOMEPLUG_NS_ICID_RSVD2 0x06
169 #define HOMEPLUG_NS_ICID_RSVD3 0x07
171 #define HOMEPLUG_NS_ICID_MASK 0x07
172 #define HOMEPLUG_NS_ICID_RSVD_MASK 0x78
173 /* string values in function of IC_ID values */
174 static const value_string homeplug_ns_icid_vals[] = {
175 { HOMEPLUG_NS_ICID5130A1, "INT5130A1" },
176 { HOMEPLUG_NS_ICID51X1USB, "INT51X1 (USB Option)" },
177 { HOMEPLUG_NS_ICID51X1PHY, "INT51X1 (PHY Option)" },
178 { HOMEPLUG_NS_ICID51X1HOST, "INT51X1 (Host/DTE Option)" },
179 { HOMEPLUG_NS_ICID5130A2, "INT5130A2" },
180 { HOMEPLUG_NS_ICID_RSVD1, "Reserved"},
181 { HOMEPLUG_NS_ICID_RSVD2, "Reserved"},
182 { HOMEPLUG_NS_ICID_RSVD3, "Reserved"},
186 /* Modulation Method Bit Mask */
187 #define HOMEPLUG_CER_MOD_MASK 0x30
188 /* Modulation Method Values */
189 #define HOMEPLUG_CER_MOD_ROBO 0x00
190 #define HOMEPLUG_CER_MOD_DBPSK 0x01
191 #define HOMEPLUG_CER_MOD_DQPSK 0x02
192 #define HOMEPLUG_CER_MOD_RSVD 0x03
193 /* string values in function of Modulation Method Values */
194 static const value_string homeplug_cer_mod_vals[] = {
195 { HOMEPLUG_CER_MOD_ROBO, "ROBO Modulation"},
196 { HOMEPLUG_CER_MOD_DBPSK, "DBPSK Modulation"},
197 { HOMEPLUG_CER_MOD_DQPSK, "DQPSK Modulation"},
198 { HOMEPLUG_CER_MOD_RSVD, "Reserved"},
202 #define HOMEPLUG_MCTRL_LEN 1
203 #define HOMEPLUG_MEHDR_LEN 1
204 #define HOMEPLUG_MELEN_LEN 1
208 proto_register_homeplug(void)
210 static hf_register_info hf[] = {
211 /* MAC Control Field */
212 { &hf_homeplug_mctrl,
213 { "MAC Control Field", "homeplug.mctrl",
214 FT_UINT8, BASE_DEC, NULL, 0x0, "MAC Control Field", HFILL }
217 { &hf_homeplug_mctrl_reserved,
218 { "Reserved", "homeplug.mctrl.rsvd",
219 FT_NONE, BASE_DEC, NULL, HOMEPLUG_MCTRL_RSVD, "Reserved", HFILL }
222 { &hf_homeplug_mctrl_ne,
223 { "Number of MAC Data Entries", "homeplug.mctrl.ne",
224 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_MCTRL_NE, "Number of MAC Data Entries", HFILL }
227 /* MAC Entry Header */
228 { &hf_homeplug_mehdr,
229 { "MAC Management Entry Header", "homeplug.mehdr",
230 FT_NONE, BASE_DEC, NULL, 0x0, "MAC Management Entry Header", HFILL }
233 { &hf_homeplug_mehdr_mev,
234 { "MAC Entry Version", "homeplug.mehdr.mev",
235 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_MEHDR_MEV, "MAC Entry Version", HFILL }
238 { &hf_homeplug_mehdr_metype,
239 { "MAC Entry Type", "homeplug.mehdr.metype",
240 FT_UINT8, BASE_HEX, NULL, HOMEPLUG_MEHDR_METYPE, "MAC Entry Type", HFILL }
244 { &hf_homeplug_melen,
245 { "MAC Management Entry Length", "homeplug.melen",
246 FT_UINT8, BASE_DEC, NULL, 0x0, "MAC Management Entry Length", HFILL }
249 /* MAC Management Entry */
251 { "MAC Management Entry Data", "homeplug.mmentry",
252 FT_UINT8, BASE_DEC, NULL, 0x0, "MAC Management Entry Data", HFILL }
255 /* Request Channel Estimation */
257 { "Request Channel Estimation", "homeplug.rce",
258 FT_NONE, BASE_DEC, NULL, 0x0, "Request Channel Estimation", HFILL }
261 { &hf_homeplug_rce_cev,
262 { "Channel Estimation Version", "homeplug.rce.cev",
263 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_RCE_CEV, "Channel Estimation Version", HFILL }
266 { &hf_homeplug_rce_rsvd,
267 { "Reserved", "homeplug.rce.rsvd",
268 FT_NONE, BASE_DEC, NULL, HOMEPLUG_RCE_RSVD, "Reserved", HFILL }
271 /* Channel Estimation Response */
273 { "Channel Estimation Response", "homeplug.cer",
274 FT_NONE, BASE_DEC, NULL, 0x0, "Channel Estimation Response", HFILL }
277 { &hf_homeplug_cer_cerv,
278 { "Channel Estimation Response Version", "homeplug.cer.cerv",
279 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_CERV, "Channel Estimation Response Version", HFILL }
282 { &hf_homeplug_cer_rsvd1,
283 { "Reserved", "homeplug.cer.rsvd1",
284 FT_NONE, BASE_DEC, NULL, HOMEPLUG_CER_RSVD, "Reserved", HFILL }
287 { &hf_homeplug_cer_rxtmi,
288 { "Receive Tone Map Index", "homeplug.cer.rxtmi",
289 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RXTMI, "Receive Tone Map Index", HFILL }
292 /* TODO must append vt[79-0] */
294 { &hf_homeplug_cer_vt,
295 {"Valid Tone Flags", "homeplug.cer.vt",
296 FT_UINT8, BASE_HEX, NULL, 0x0, "Valid Tone Flags", HFILL }
299 { &hf_homeplug_cer_rate,
300 { "FEC Rate", "homeplug.cer.rate",
301 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RATE, "FEC Rate", HFILL }
304 { &hf_homeplug_cer_bp,
305 { "Bridge Proxy", "homeplug.cer.bp",
306 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_BP, "Bridge Proxy", HFILL }
309 { &hf_homeplug_cer_mod,
310 { "Modulation Method", "homeplug.cer.mod",
311 FT_UINT8, BASE_DEC, VALS(&homeplug_cer_mod_vals), HOMEPLUG_CER_MOD_MASK,
312 "Modulation Method", HFILL }
315 { &hf_homeplug_cer_vt11,
316 { "Valid Tone Flags [83-80]", "homeplug.cer.vt11",
317 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_VT11, "Valid Tone Flags [83-80]", HFILL }
320 { &hf_homeplug_cer_rsvd2,
321 { "Reserved", "homeplug.cer.rsvd2",
322 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RSVD2, "Reserved", HFILL }
325 { &hf_homeplug_cer_nbdas,
326 { "Number Bridged Destination Addresses", "homeplug.cer.nbdas",
327 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_NBDAS, "Number Bridged Destination Addresses", HFILL }
330 { &hf_homeplug_cer_bda,
331 { "Bridged Destination Address", "homeplug.cer.bda",
332 FT_ETHER, BASE_HEX, NULL, 0x0, "Bridged Destination Address", HFILL }
335 /* Request Parameters and Statistics */
337 { "Request Parameters and Statistics", "homeplug.rps",
338 FT_NONE, BASE_DEC, NULL, 0x0, "Request Parameters and Statistics", HFILL }
341 /* Parameters and Statistics Response */
343 { "Parameters and Statistics Response", "homeplug.psr",
344 FT_NONE, BASE_DEC, NULL, 0x0, "Parameters and Statistics Response", HFILL }
347 { &hf_homeplug_psr_txack,
348 { "Transmit ACK Counter", "homeplug.psr.txack",
349 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit ACK Counter", HFILL }
352 { &hf_homeplug_psr_txnack,
353 { "Transmit NACK Counter", "homeplug.psr.txnack",
354 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit NACK Counter", HFILL }
357 { &hf_homeplug_psr_txfail,
358 { "Transmit FAIL Counter", "homeplug.psr.txfail",
359 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit FAIL Counter", HFILL }
362 { &hf_homeplug_psr_txcloss,
363 { "Transmit Contention Loss Counter", "homeplug.psr.txcloss",
364 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit Contention Loss Counter", HFILL }
367 { &hf_homeplug_psr_txcoll,
368 { "Transmit Collision Counter", "homeplug.psr.txcoll",
369 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit Collision Counter", HFILL }
372 { &hf_homeplug_psr_txca3lat,
373 { "Transmit CA3 Latency Counter", "homeplug.psr.txca3lat",
374 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA3 Latency Counter", HFILL }
377 { &hf_homeplug_psr_txca2lat,
378 { "Transmit CA2 Latency Counter", "homeplug.psr.txca2lat",
379 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA2 Latency Counter", HFILL }
381 { &hf_homeplug_psr_txca1lat,
382 { "Transmit CA1 Latency Counter", "homeplug.psr.txca1lat",
383 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA1 Latency Counter", HFILL }
385 { &hf_homeplug_psr_txca0lat,
386 { "Transmit CA0 Latency Counter", "homeplug.psr.txca0lat",
387 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA0 Latency Counter", HFILL }
390 { &hf_homeplug_psr_rxbp40,
391 { "Receive Cumulative Bytes per 40-symbol", "homeplug.psr.rxbp40",
392 FT_UINT32, BASE_DEC, NULL, 0x0, "Receive Cumulative Bytes per 40-symbol", HFILL }
395 /* Network Statistics Basic */
397 { "Network Statistics Basic", "homeplug.ns",
398 FT_NONE, BASE_DEC, NULL, 0x0, "Network Statistics Basic", HFILL }
401 { &hf_homeplug_ns_netw_ctrl_ac,
402 { "Action Control", "homeplug.ns.ac",
403 FT_BOOLEAN, BASE_DEC, NULL, HOMEPLUG_NS_AC, "Action Control", HFILL }
406 { &hf_homeplug_ns_netw_ctrl_icid,
407 { "IC_ID", "homeplug.ns.icid",
408 FT_UINT8, BASE_HEX, VALS(&homeplug_ns_icid_vals), HOMEPLUG_NS_ICID_MASK, "IC_ID", HFILL }
411 { &hf_homeplug_ns_netw_ctrl_icid_rsvd,
412 { "IC_ID Reserved", "homeplug.ns.icid",
413 FT_NONE, BASE_DEC, NULL, 0x0, "IC_ID Reserved", HFILL }
416 { &hf_homeplug_ns_bytes40_robo,
417 { "Bytes in 40 symbols in ROBO", "homeplug.ns.bytes40_robo",
418 FT_UINT16, BASE_DEC, NULL, 0x0, "Bytes in 40 symbols in ROBO", HFILL }
421 { &hf_homeplug_ns_fails_robo,
422 { "Fails Received in ROBO", "homeplug.ns.fails_robo",
423 FT_UINT16, BASE_DEC, NULL, 0x0, "Fails Received in ROBO", HFILL }
426 { &hf_homeplug_ns_drops_robo,
427 { "Frame Drops in ROBO", "homeplug.ns.drops_robo",
428 FT_UINT16, BASE_DEC, NULL, 0x0, "Frame Drops in ROBO", HFILL }
431 /* TODO NETW_DA1 ... */
432 { &hf_homeplug_ns_netw_da,
433 { "Address of Network DA", "homeplug.ns.netw_da",
434 FT_ETHER, BASE_HEX, NULL, 0x0, "Address of Network DA", HFILL }
437 { &hf_homeplug_ns_bytes40,
438 { "Bytes in 40 symbols", "homeplug.ns.bytes40",
439 FT_UINT16, BASE_DEC, NULL, 0x0, "Bytes in 40 symbols", HFILL }
442 { &hf_homeplug_ns_fails,
443 { "Fails Received", "homeplug.ns.fails",
444 FT_UINT16, BASE_DEC, NULL, 0x0, "Fails Received", HFILL }
447 { &hf_homeplug_ns_drops,
448 { "Frame Drops", "homeplug.ns.drops",
449 FT_UINT16, BASE_DEC, NULL, 0x0, "Frame Drops", HFILL }
452 /* TODO Network Statistics Extended */
455 /* Setup protocol subtree array */
456 static gint *ett[] = {
468 proto_homeplug = proto_register_protocol(
469 "HomePlug protocol", /* Name */
470 "HomePlug", /* Short Name */
471 "homeplug" /* Abbrev */
474 proto_register_field_array(proto_homeplug, hf, array_length(hf));
476 proto_register_subtree_array(ett, array_length(ett));
480 /* Dissection of MCTRL */
481 static void dissect_homeplug_mctrl(ptvcursor_t * cursor)
483 proto_tree *initial_tree = NULL;
484 proto_tree *additional_tree = NULL;
485 proto_item *it = NULL;
487 if (!cursor || !ptvcursor_tree(cursor))
490 initial_tree = ptvcursor_tree(cursor);
492 it = ptvcursor_add_no_advance(cursor, hf_homeplug_mctrl, 1, FALSE);
493 homeplug_ne = tvb_get_guint8(ptvcursor_tvbuff(cursor),
494 ptvcursor_current_offset(cursor))
497 additional_tree = proto_item_add_subtree(it, ett_homeplug_mctrl);
498 ptvcursor_set_tree(cursor, additional_tree);
499 ptvcursor_add_no_advance(cursor, hf_homeplug_mctrl_reserved, 1, FALSE);
500 ptvcursor_add(cursor, hf_homeplug_mctrl_ne, 1, FALSE);
502 ptvcursor_set_tree(cursor, initial_tree);
505 /* Dissection of MEHDR */
506 static void dissect_homeplug_mehdr(ptvcursor_t * cursor)
508 proto_tree *initial_tree = NULL;
509 proto_tree *additional_tree = NULL;
510 proto_item *it = NULL;
512 if (!cursor || !ptvcursor_tree(cursor))
515 initial_tree = ptvcursor_tree(cursor);
517 it = ptvcursor_add_no_advance(cursor, hf_homeplug_mehdr, 0, FALSE);
518 homeplug_metype = tvb_get_guint8(ptvcursor_tvbuff(cursor),
519 ptvcursor_current_offset(cursor))
520 & HOMEPLUG_MEHDR_METYPE;
522 additional_tree = proto_item_add_subtree(it, ett_homeplug_mehdr);
523 ptvcursor_set_tree(cursor, additional_tree);
524 ptvcursor_add_no_advance(cursor, hf_homeplug_mehdr_mev, 1, FALSE);
525 ptvcursor_add(cursor, hf_homeplug_mehdr_metype, 1, FALSE);
527 ptvcursor_set_tree(cursor, initial_tree);
531 /* dissection of MELEN */
532 static void dissect_homeplug_melen(ptvcursor_t *cursor)
534 if (!cursor || !ptvcursor_tree(cursor))
537 homeplug_melen = tvb_get_guint8(ptvcursor_tvbuff(cursor),
538 ptvcursor_current_offset(cursor));
539 ptvcursor_add(cursor, hf_homeplug_melen, 1, FALSE);
542 /* Dissection of Request Channel Estimation MME */
543 static void dissect_homeplug_rce(ptvcursor_t *cursor)
545 proto_tree *initial_tree = NULL;
546 proto_tree *additional_tree = NULL;
547 proto_item *it = NULL;
549 if (!cursor || !ptvcursor_tree(cursor))
552 initial_tree = ptvcursor_tree(cursor);
554 it = ptvcursor_add_no_advance(cursor, hf_homeplug_rce, homeplug_melen, FALSE);
556 additional_tree = proto_item_add_subtree(it , ett_homeplug_rce);
557 ptvcursor_set_tree(cursor, additional_tree);
558 ptvcursor_add_no_advance(cursor, hf_homeplug_rce_cev, 1, FALSE);
559 ptvcursor_add(cursor, hf_homeplug_rce_rsvd, 1, FALSE);
561 ptvcursor_set_tree(cursor, initial_tree);
564 /* Dissection of Channel Estimation Response MME */
565 static void dissect_homeplug_cer(ptvcursor_t *cursor)
567 proto_tree *initial_tree = NULL;
568 proto_tree *additional_tree = NULL;
569 proto_item *it = NULL;
574 if (!cursor || !ptvcursor_tree(cursor))
577 initial_tree = ptvcursor_tree(cursor);
579 it = ptvcursor_add_no_advance(cursor, hf_homeplug_cer_cerv, homeplug_melen, FALSE);
581 additional_tree = proto_item_add_subtree(it, ett_homeplug_cer);
582 ptvcursor_set_tree(cursor, additional_tree);
583 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_cerv, 1, FALSE);
584 ptvcursor_add(cursor, hf_homeplug_cer_rsvd1, 2, FALSE);
585 ptvcursor_add(cursor, hf_homeplug_cer_rxtmi, 1, FALSE);
587 for (iTone = 0; iTone < 10; iTone++) {
588 ptvcursor_add(cursor, hf_homeplug_cer_vt, 1, FALSE);
591 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_rate, 1, FALSE);
592 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_bp, 1, FALSE);
593 BP = tvb_get_guint8(ptvcursor_tvbuff(cursor),
594 ptvcursor_current_offset(cursor)) & HOMEPLUG_CER_BP;
595 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_mod, 1, FALSE);
596 ptvcursor_add(cursor, hf_homeplug_cer_vt11, 1, FALSE);
597 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_rsvd2, 1, FALSE);
600 iNBDA = tvb_get_guint8(ptvcursor_tvbuff(cursor),
601 ptvcursor_current_offset(cursor))
602 & HOMEPLUG_CER_NBDAS;
603 ptvcursor_add(cursor, hf_homeplug_cer_nbdas, 1, FALSE);
604 /* TODO : Check on iNBDA! INT51X1 up to 16 dba. But up to 32 for INT51X1 (Host/DTE) */
605 for (;iNBDA > 0; iNBDA--) {
606 ptvcursor_add(cursor, hf_homeplug_cer_bda, 6, FALSE);
610 ptvcursor_set_tree(cursor, initial_tree);
614 /* Dissection of Request Parameters and Statistics MME */
615 static void dissect_homeplug_rps(ptvcursor_t *cursor)
617 if (!cursor || !ptvcursor_tree(cursor))
620 ptvcursor_add(cursor, hf_homeplug_rps, 4, FALSE);
623 /* Dissection of Parameters and Statistics Response MME */
624 static void dissect_homeplug_psr(ptvcursor_t *cursor)
626 proto_tree *initial_tree = NULL;
627 proto_tree *additional_tree = NULL;
628 proto_item *it = NULL;
630 if (!cursor || !ptvcursor_tree(cursor))
633 initial_tree = ptvcursor_tree(cursor);
635 it = ptvcursor_add_no_advance(cursor, hf_homeplug_psr, homeplug_melen, FALSE);
637 additional_tree = proto_item_add_subtree(it, ett_homeplug_psr);
638 ptvcursor_set_tree(cursor, additional_tree);
639 ptvcursor_add(cursor, hf_homeplug_psr_txack, 2, FALSE);
640 ptvcursor_add(cursor, hf_homeplug_psr_txnack, 2, FALSE);
641 ptvcursor_add(cursor, hf_homeplug_psr_txfail, 2, FALSE);
642 ptvcursor_add(cursor, hf_homeplug_psr_txcloss, 2, FALSE);
643 ptvcursor_add(cursor, hf_homeplug_psr_txcoll, 2, FALSE);
644 ptvcursor_add(cursor, hf_homeplug_psr_txca3lat, 2, FALSE);
645 ptvcursor_add(cursor, hf_homeplug_psr_txca2lat, 2, FALSE);
646 ptvcursor_add(cursor, hf_homeplug_psr_txca1lat, 2, FALSE);
647 ptvcursor_add(cursor, hf_homeplug_psr_txca0lat, 2, FALSE);
648 ptvcursor_add(cursor, hf_homeplug_psr_rxbp40, 4, FALSE);
650 ptvcursor_set_tree(cursor, initial_tree);
653 /* Dissection of the Network Statistic MME */
654 static void dissect_homeplug_ns(ptvcursor_t *cursor)
656 proto_item *it = NULL;
657 proto_tree *additional_tree = NULL, *tree_tone = NULL;
658 proto_tree *initial_tree = NULL;
659 guint8 homeplug_ns_icid_rsvd = 0;
661 guint16 ns_bytes40 = 0;
663 #define NEWT_DA_INEXISTANT G_GINT64_CONSTANT(010000000000U)
665 if (!cursor || !ptvcursor_tree(cursor))
668 initial_tree = ptvcursor_tree(cursor);
670 /* TODO : test length of the MME : differentiation of NS Basic and Extended */
671 it = ptvcursor_add_no_advance(cursor, hf_homeplug_ns, homeplug_melen, FALSE);
673 additional_tree = proto_item_add_subtree(it, ett_homeplug_ns);
674 ptvcursor_set_tree(cursor, additional_tree);
675 ptvcursor_add_no_advance(cursor, hf_homeplug_ns_netw_ctrl_ac, 1, FALSE);
676 homeplug_ns_icid_rsvd = tvb_get_guint8(ptvcursor_tvbuff(cursor),
677 ptvcursor_current_offset(cursor))
678 & HOMEPLUG_NS_ICID_RSVD_MASK;
680 if (homeplug_ns_icid_rsvd)
681 ptvcursor_add(cursor, hf_homeplug_ns_netw_ctrl_icid_rsvd, 1, FALSE);
683 ptvcursor_add(cursor, hf_homeplug_ns_netw_ctrl_icid, 1, FALSE);
685 ptvcursor_add_no_advance(cursor, hf_homeplug_ns_bytes40_robo, 2, TRUE);
686 ns_bytes40 = tvb_get_letohs(ptvcursor_tvbuff(cursor),
687 ptvcursor_current_offset(cursor));
688 it = proto_tree_add_text(additional_tree, ptvcursor_tvbuff(cursor),
689 ptvcursor_current_offset(cursor), 2, "MHz : %.3f",
690 (float)(ns_bytes40)/42);
691 ptvcursor_advance(cursor, 2);
693 ptvcursor_add(cursor, hf_homeplug_ns_fails_robo, 2, TRUE);
694 ptvcursor_add(cursor, hf_homeplug_ns_drops_robo, 2, TRUE);
697 newt_da = ((gint64)tvb_get_ntoh24(ptvcursor_tvbuff(cursor),
698 ptvcursor_current_offset(cursor))) << 24;
699 newt_da |= tvb_get_ntoh24(ptvcursor_tvbuff(cursor),
700 ptvcursor_current_offset(cursor)+3);
702 if (newt_da != NEWT_DA_INEXISTANT) {
703 it = proto_tree_add_text(additional_tree, ptvcursor_tvbuff(cursor),
704 ptvcursor_current_offset(cursor), 12,
705 "Tone Map #%d", iTone+1);
707 tree_tone = proto_item_add_subtree(it, ett_homeplug_tone);
708 ptvcursor_set_tree(cursor, tree_tone);
710 ptvcursor_add(cursor, hf_homeplug_ns_netw_da, 6, FALSE);
712 ptvcursor_add_no_advance(cursor, hf_homeplug_ns_bytes40, 2, TRUE);
713 ns_bytes40 = tvb_get_letohs(ptvcursor_tvbuff(cursor),
714 ptvcursor_current_offset(cursor));
715 it = proto_tree_add_text(ptvcursor_tree(cursor), ptvcursor_tvbuff(cursor),
716 ptvcursor_current_offset(cursor), 2,
717 "MHz : %.3f", (float)(ns_bytes40)/42);
718 ptvcursor_advance(cursor, 2);
720 ptvcursor_add(cursor, hf_homeplug_ns_fails, 2, TRUE);
721 ptvcursor_add(cursor, hf_homeplug_ns_drops, 2, TRUE);
723 it = proto_tree_add_text(additional_tree, ptvcursor_tvbuff(cursor),
724 ptvcursor_current_offset(cursor), 12,
725 "Tone Map #%d does not exist", iTone+1);
730 ptvcursor_set_tree(cursor, initial_tree);
733 static void dissect_homeplug_mme(ptvcursor_t *cursor, packet_info *pinfo)
735 switch(homeplug_metype) {
736 case HOMEPLUG_MME_RCE:
737 if (check_col(pinfo->cinfo, COL_INFO)) {
738 col_clear(pinfo->cinfo, COL_INFO);
739 col_set_str(pinfo->cinfo, COL_INFO, "Request Channel Estimation");
741 dissect_homeplug_rce(cursor);
744 case HOMEPLUG_MME_CER:
745 if (check_col(pinfo->cinfo, COL_INFO)) {
746 col_clear(pinfo->cinfo, COL_INFO);
747 col_set_str(pinfo->cinfo, COL_INFO, "Channel Estimation Response");
749 dissect_homeplug_cer(cursor);
752 case HOMEPLUG_MME_RPS:
753 if (check_col(pinfo->cinfo, COL_INFO)) {
754 col_clear(pinfo->cinfo, COL_INFO);
755 col_set_str(pinfo->cinfo, COL_INFO, "Request Parameters and Statistics");
757 dissect_homeplug_rps(cursor);
760 case HOMEPLUG_MME_PSR:
761 if (check_col(pinfo->cinfo, COL_INFO)) {
762 col_clear(pinfo->cinfo, COL_INFO);
763 col_set_str(pinfo->cinfo, COL_INFO, "Parameters and Statistics Response");
765 dissect_homeplug_psr(cursor);
768 case HOMEPLUG_MME_NS:
769 if (check_col(pinfo->cinfo, COL_INFO)) {
770 col_clear(pinfo->cinfo, COL_INFO);
771 col_set_str(pinfo->cinfo, COL_INFO, "Network Statistics");
773 dissect_homeplug_ns(cursor);
778 #define TVB_LEN_GREATEST 1
779 #define TVB_LEN_UNDEF 0
780 #define TVB_LEN_SHORTEST -1
781 static int check_tvb_length(ptvcursor_t *cursor, const gint length)
784 return TVB_LEN_UNDEF;
786 if (tvb_reported_length_remaining(ptvcursor_tvbuff(cursor),
787 ptvcursor_current_offset(cursor)) < length)
788 return TVB_LEN_SHORTEST;
790 return TVB_LEN_GREATEST;
794 dissect_homeplug(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
796 proto_item *it = NULL;
797 proto_tree *homeplug_tree = NULL;
798 ptvcursor_t *cursor = NULL;
800 if (check_col(pinfo->cinfo, COL_PROTOCOL))
801 col_set_str(pinfo->cinfo, COL_PROTOCOL, "HomePlug");
803 /* Clear out stuff in the info column */
804 if (check_col(pinfo->cinfo, COL_INFO)) {
805 col_clear(pinfo->cinfo, COL_INFO);
806 col_set_str(pinfo->cinfo, COL_INFO, "MAC Management");
812 it = proto_tree_add_item(tree, proto_homeplug, tvb, homeplug_offset, -1, FALSE);
813 homeplug_tree = proto_item_add_subtree(it, ett_homeplug);
814 cursor = ptvcursor_new(homeplug_tree, tvb, 0);
817 /* We do not have enough data to read mctrl field stop the dissection */
818 if (check_tvb_length(cursor, HOMEPLUG_MCTRL_LEN) != TVB_LEN_SHORTEST) {
820 dissect_homeplug_mctrl(cursor);
822 /* homeplug_ne indicates the number of MME entries. This field is fetched
825 for (; homeplug_ne > 0; homeplug_ne--) {
827 /* Check we have enough data in tvb to read MEHDR */
828 if (check_tvb_length(cursor, HOMEPLUG_MEHDR_LEN) == TVB_LEN_SHORTEST)
830 dissect_homeplug_mehdr(cursor);
832 /* Check we have enough data in tvb to read MELEN */
833 if (check_tvb_length(cursor, HOMEPLUG_MELEN_LEN) == TVB_LEN_SHORTEST)
835 dissect_homeplug_melen(cursor);
837 dissect_homeplug_mme(cursor, pinfo);
842 ptvcursor_free(cursor);
845 static dissector_handle_t homeplug_handle;
848 proto_reg_handoff_homeplug(void)
850 static gboolean initialised = FALSE;
853 homeplug_handle = create_dissector_handle(dissect_homeplug, proto_homeplug);
854 dissector_add("ethertype", ETHERTYPE_HOMEPLUG, homeplug_handle);