2 * Routines for homeplug dissection
4 * Copyright 2006, Sebastien Tandel <sebastien[AT]tandel.be>
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>
35 #include <epan/etypes.h>
37 #include <epan/proto.h>
38 #include <epan/ptvcursor.h>
40 /* forward reference */
41 void proto_reg_handoff_homeplug(void);
43 static int proto_homeplug = -1;
45 static int hf_homeplug_mctrl = -1;
46 static int hf_homeplug_mctrl_reserved = -1;
47 static int hf_homeplug_mctrl_ne = -1;
48 static int hf_homeplug_mehdr = -1;
49 static int hf_homeplug_mehdr_mev = -1;
50 static int hf_homeplug_mehdr_metype = -1;
51 static int hf_homeplug_melen = -1;
52 static int hf_homeplug_mme = -1;
53 /* Request Channel Estimation */
54 static int hf_homeplug_rce = -1;
55 static int hf_homeplug_rce_cev = -1;
56 static int hf_homeplug_rce_rsvd = -1;
57 /* Channel Estimation Response */
58 static int hf_homeplug_cer = -1;
59 static int hf_homeplug_cer_cerv = -1;
60 static int hf_homeplug_cer_rsvd1 = -1;
61 static int hf_homeplug_cer_rxtmi = -1;
62 static int hf_homeplug_cer_vt = -1;
63 static int hf_homeplug_cer_rate = -1;
64 static int hf_homeplug_cer_bp = -1;
65 static int hf_homeplug_cer_mod = -1;
66 static int hf_homeplug_cer_vt11 = -1;
67 static int hf_homeplug_cer_rsvd2 = -1;
68 static int hf_homeplug_cer_nbdas = -1;
69 static int hf_homeplug_cer_bda = -1;
70 /* Request Parameters and Statistics */
71 static int hf_homeplug_rps = -1;
72 /* Parameters and Statistics Response */
73 static int hf_homeplug_psr = -1;
74 static int hf_homeplug_psr_txack = -1;
75 static int hf_homeplug_psr_txnack = -1;
76 static int hf_homeplug_psr_txfail = -1;
77 static int hf_homeplug_psr_txcloss = -1;
78 static int hf_homeplug_psr_txcoll = -1;
79 static int hf_homeplug_psr_txca3lat = -1;
80 static int hf_homeplug_psr_txca2lat = -1;
81 static int hf_homeplug_psr_txca1lat = -1;
82 static int hf_homeplug_psr_txca0lat = -1;
83 static int hf_homeplug_psr_rxbp40 = -1;
84 /* Network Statistics */
86 static int hf_homeplug_ns = -1;
87 static int hf_homeplug_ns_netw_ctrl_ac = -1;
88 static int hf_homeplug_ns_netw_ctrl_icid = -1;
89 static int hf_homeplug_ns_netw_ctrl_icid_rsvd = -1;
90 static int hf_homeplug_ns_bytes40_robo = -1;
91 static int hf_homeplug_ns_fails_robo = -1;
92 static int hf_homeplug_ns_drops_robo = -1;
93 static int hf_homeplug_ns_netw_da = -1;
94 static int hf_homeplug_ns_bytes40 = -1;
95 static int hf_homeplug_ns_fails = -1;
96 static int hf_homeplug_ns_drops = -1;
97 /* array of 15 elements */
98 /* static int hf_homeplug_ns_bytes40_1 = -1;
99 static int hf_homeplug_ns_bytes40_1 */
101 /* array of 6 elements */
102 /* static int hf_homeplug_ns_tx_bfr_0_state = -1;*/
103 static int hf_homeplug_data = -1;
105 static gint ett_homeplug = -1;
106 static gint ett_homeplug_mctrl = -1;
107 static gint ett_homeplug_mehdr = -1;
108 static gint ett_homeplug_rce = -1;
109 static gint ett_homeplug_cer = -1;
110 static gint ett_homeplug_rps = -1;
111 static gint ett_homeplug_psr = -1;
112 static gint ett_homeplug_ns = -1;
113 static gint ett_homeplug_tone = -1;
116 static guint8 homeplug_ne = 0;
117 static guint8 homeplug_melen = 0;
118 static guint8 homeplug_metype = 0;
120 static guint32 homeplug_offset = 0;
124 #define HOMEPLUG_MME_RCE 0x00
125 #define HOMEPLUG_MME_CER 0x01
126 #define HOMEPLUG_MME_VS 0x02
127 #define HOMEPLUG_MME_RBA 0x03
128 #define HOMEPLUG_MME_SNK 0x04
129 #define HOMEPLUG_MME_MWR 0x05
130 #define HOMEPLUG_MME_CNK 0x06
131 #define HOMEPLUG_MME_RPS 0x07
132 #define HOMEPLUG_MME_PSR 0x08
133 #define HOMEPLUG_MME_SLP 0x19
134 #define HOMEPLUG_MME_NS 0x1A
135 #define HOMEPLUG_MME_RES 0x1B
136 #define HOMEPLUG_MME_PS 0x1C
137 #define HOMEPLUG_MME_SLO 0x1D
138 #define HOMEPLUG_MME_BC 0x1E
139 #define HOMEPLUG_MME_STC 0x1F
140 static const value_string homeplug_metype_vals[] = {
141 { HOMEPLUG_MME_RCE, "Request Channel Estimation" },
142 { HOMEPLUG_MME_CER, "Channel Estimation Response" },
143 { HOMEPLUG_MME_VS , "Vendor Specific" },
144 { HOMEPLUG_MME_RBA, "Replace Bridge Address" },
145 { HOMEPLUG_MME_SNK, "Set Network Encryption Key" },
146 { HOMEPLUG_MME_MWR, "Multicast With Response" },
147 { HOMEPLUG_MME_CNK, "Confirm Network Encryption Key" },
148 { HOMEPLUG_MME_RPS, "Request Parameters and Statistics" },
149 { HOMEPLUG_MME_PSR, "Parameters and Statistics Response" },
150 { HOMEPLUG_MME_SLP, "Set Local Parameters" },
151 { HOMEPLUG_MME_NS , "Network Statistics" },
152 { HOMEPLUG_MME_RES, "Reserved" },
153 { HOMEPLUG_MME_PS , "Performance Statistics" },
154 { HOMEPLUG_MME_SLO, "Set Local Overrides" },
155 { HOMEPLUG_MME_BC , "Bridging Characteristics" },
156 { HOMEPLUG_MME_STC, "Set Transmit Characteristics" },
160 /* Bit mask Operation */
161 #define HOMEPLUG_MCTRL_RSVD 0x80
162 #define HOMEPLUG_MCTRL_NE 0x7F
164 #define HOMEPLUG_MEHDR_MEV 0xE0
165 #define HOMEPLUG_MEHDR_METYPE 0x1F
167 #define HOMEPLUG_NS_AC 0x80
168 #define HOMEPLUG_NS_ICID 0x7F
170 #define HOMEPLUG_RCE_CEV 0xF0
171 #define HOMEPLUG_RCE_RSVD 0x0F
173 #define HOMEPLUG_CER_CERV 0xF0
174 #define HOMEPLUG_CER_RSVD 0x0FE0
175 #define HOMEPLUG_CER_RXTMI 0x1F
176 #define HOMEPLUG_CER_RATE 0x80
177 #define HOMEPLUG_CER_BP 0x40
178 #define HOMEPLUG_CER_VT11 0x0F
179 #define HOMEPLUG_CER_RSVD2 0x80
180 #define HOMEPLUG_CER_NBDAS 0x7F
183 /* Length of Network Statistics Response defines whether it is the Basic or
184 * the Extended Response */
185 #define HOMEPLUG_NS_BASIC_LEN 187
186 #define HOMEPLUG_NS_EXT_LEN 199
189 #define HOMEPLUG_NS_ICID5130A1 0x00
190 #define HOMEPLUG_NS_ICID51X1USB 0x01
191 #define HOMEPLUG_NS_ICID51X1PHY 0x02
192 #define HOMEPLUG_NS_ICID51X1HOST 0x03
193 #define HOMEPLUG_NS_ICID5130A2 0x04
194 #define HOMEPLUG_NS_ICID_RSVD1 0x05
195 #define HOMEPLUG_NS_ICID_RSVD2 0x06
196 #define HOMEPLUG_NS_ICID_RSVD3 0x07
198 #define HOMEPLUG_NS_ICID_MASK 0x07
199 #define HOMEPLUG_NS_ICID_RSVD_MASK 0x78
200 /* string values in function of IC_ID values */
201 static const value_string homeplug_ns_icid_vals[] = {
202 { HOMEPLUG_NS_ICID5130A1, "INT5130A1" },
203 { HOMEPLUG_NS_ICID51X1USB, "INT51X1 (USB Option)" },
204 { HOMEPLUG_NS_ICID51X1PHY, "INT51X1 (PHY Option)" },
205 { HOMEPLUG_NS_ICID51X1HOST, "INT51X1 (Host/DTE Option)" },
206 { HOMEPLUG_NS_ICID5130A2, "INT5130A2" },
207 { HOMEPLUG_NS_ICID_RSVD1, "Reserved"},
208 { HOMEPLUG_NS_ICID_RSVD2, "Reserved"},
209 { HOMEPLUG_NS_ICID_RSVD3, "Reserved"},
213 /* Modulation Method Bit Mask */
214 #define HOMEPLUG_CER_MOD_MASK 0x30
215 /* Modulation Method Values */
216 #define HOMEPLUG_CER_MOD_ROBO 0x00
217 #define HOMEPLUG_CER_MOD_DBPSK 0x01
218 #define HOMEPLUG_CER_MOD_DQPSK 0x02
219 #define HOMEPLUG_CER_MOD_RSVD 0x03
220 /* string values in function of Modulation Method Values */
221 static const value_string homeplug_cer_mod_vals[] = {
222 { HOMEPLUG_CER_MOD_ROBO, "ROBO Modulation"},
223 { HOMEPLUG_CER_MOD_DBPSK, "DBPSK Modulation"},
224 { HOMEPLUG_CER_MOD_DQPSK, "DQPSK Modulation"},
225 { HOMEPLUG_CER_MOD_RSVD, "Reserved"},
229 #define HOMEPLUG_MCTRL_LEN 1
230 #define HOMEPLUG_MEHDR_LEN 1
231 #define HOMEPLUG_MELEN_LEN 1
234 proto_register_homeplug(void)
237 static hf_register_info hf[] = {
238 /* MAC Control Field */
239 { &hf_homeplug_mctrl,
240 { "MAC Control Field", "homeplug.mctrl",
241 FT_UINT8, BASE_DEC, NULL, 0x0, "MAC Control Field", HFILL }
244 { &hf_homeplug_mctrl_reserved,
245 { "Reserved", "homeplug.mctrl.rsvd",
246 FT_NONE, BASE_DEC, NULL, HOMEPLUG_MCTRL_RSVD, "Reserved", HFILL }
249 { &hf_homeplug_mctrl_ne,
250 { "Number of MAC Data Entries", "homeplug.mctrl.ne",
251 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_MCTRL_NE, "Number of MAC Data Entries", HFILL }
254 /* MAC Entry Header */
255 { &hf_homeplug_mehdr,
256 { "MAC Management Entry Header", "homeplug.mehdr",
257 FT_NONE, BASE_DEC, NULL, 0x0, "MAC Management Entry Header", HFILL }
260 { &hf_homeplug_mehdr_mev,
261 { "MAC Entry Version", "homeplug.mehdr.mev",
262 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_MEHDR_MEV, "MAC Entry Version", HFILL }
265 { &hf_homeplug_mehdr_metype,
266 { "MAC Entry Type", "homeplug.mehdr.metype",
267 FT_UINT8, BASE_HEX, VALS(homeplug_metype_vals), HOMEPLUG_MEHDR_METYPE, "MAC Entry Type", HFILL }
271 { &hf_homeplug_melen,
272 { "MAC Management Entry Length", "homeplug.melen",
273 FT_UINT8, BASE_DEC, NULL, 0x0, "MAC Management Entry Length", HFILL }
276 /* MAC Management Entry */
278 { "MAC Management Entry Data", "homeplug.mmentry",
279 FT_UINT8, BASE_DEC, NULL, 0x0, "MAC Management Entry Data", HFILL }
282 /* Request Channel Estimation */
284 { "Request Channel Estimation", "homeplug.rce",
285 FT_NONE, BASE_DEC, NULL, 0x0, "Request Channel Estimation", HFILL }
288 { &hf_homeplug_rce_cev,
289 { "Channel Estimation Version", "homeplug.rce.cev",
290 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_RCE_CEV, "Channel Estimation Version", HFILL }
293 { &hf_homeplug_rce_rsvd,
294 { "Reserved", "homeplug.rce.rsvd",
295 FT_NONE, BASE_DEC, NULL, HOMEPLUG_RCE_RSVD, "Reserved", HFILL }
298 /* Channel Estimation Response */
300 { "Channel Estimation Response", "homeplug.cer",
301 FT_NONE, BASE_DEC, NULL, 0x0, "Channel Estimation Response", HFILL }
304 { &hf_homeplug_cer_cerv,
305 { "Channel Estimation Response Version", "homeplug.cer.cerv",
306 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_CERV, "Channel Estimation Response Version", HFILL }
309 { &hf_homeplug_cer_rsvd1,
310 { "Reserved", "homeplug.cer.rsvd1",
311 FT_NONE, BASE_DEC, NULL, HOMEPLUG_CER_RSVD, "Reserved", HFILL }
314 { &hf_homeplug_cer_rxtmi,
315 { "Receive Tone Map Index", "homeplug.cer.rxtmi",
316 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RXTMI, "Receive Tone Map Index", HFILL }
319 /* TODO must append vt[79-0] */
321 { &hf_homeplug_cer_vt,
322 {"Valid Tone Flags", "homeplug.cer.vt",
323 FT_UINT8, BASE_HEX, NULL, 0x0, "Valid Tone Flags", HFILL }
326 { &hf_homeplug_cer_rate,
327 { "FEC Rate", "homeplug.cer.rate",
328 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RATE, "FEC Rate", HFILL }
331 { &hf_homeplug_cer_bp,
332 { "Bridge Proxy", "homeplug.cer.bp",
333 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_BP, "Bridge Proxy", HFILL }
336 { &hf_homeplug_cer_mod,
337 { "Modulation Method", "homeplug.cer.mod",
338 FT_UINT8, BASE_DEC, VALS(&homeplug_cer_mod_vals), HOMEPLUG_CER_MOD_MASK,
339 "Modulation Method", HFILL }
342 { &hf_homeplug_cer_vt11,
343 { "Valid Tone Flags [83-80]", "homeplug.cer.vt11",
344 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_VT11, "Valid Tone Flags [83-80]", HFILL }
347 { &hf_homeplug_cer_rsvd2,
348 { "Reserved", "homeplug.cer.rsvd2",
349 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_RSVD2, "Reserved", HFILL }
352 { &hf_homeplug_cer_nbdas,
353 { "Number Bridged Destination Addresses", "homeplug.cer.nbdas",
354 FT_UINT8, BASE_DEC, NULL, HOMEPLUG_CER_NBDAS, "Number Bridged Destination Addresses", HFILL }
357 { &hf_homeplug_cer_bda,
358 { "Bridged Destination Address", "homeplug.cer.bda",
359 FT_ETHER, BASE_HEX, NULL, 0x0, "Bridged Destination Address", HFILL }
362 /* Request Parameters and Statistics */
364 { "Request Parameters and Statistics", "homeplug.rps",
365 FT_NONE, BASE_DEC, NULL, 0x0, "Request Parameters and Statistics", HFILL }
368 /* Parameters and Statistics Response */
370 { "Parameters and Statistics Response", "homeplug.psr",
371 FT_NONE, BASE_DEC, NULL, 0x0, "Parameters and Statistics Response", HFILL }
374 { &hf_homeplug_psr_txack,
375 { "Transmit ACK Counter", "homeplug.psr.txack",
376 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit ACK Counter", HFILL }
379 { &hf_homeplug_psr_txnack,
380 { "Transmit NACK Counter", "homeplug.psr.txnack",
381 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit NACK Counter", HFILL }
384 { &hf_homeplug_psr_txfail,
385 { "Transmit FAIL Counter", "homeplug.psr.txfail",
386 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit FAIL Counter", HFILL }
389 { &hf_homeplug_psr_txcloss,
390 { "Transmit Contention Loss Counter", "homeplug.psr.txcloss",
391 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit Contention Loss Counter", HFILL }
394 { &hf_homeplug_psr_txcoll,
395 { "Transmit Collision Counter", "homeplug.psr.txcoll",
396 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit Collision Counter", HFILL }
399 { &hf_homeplug_psr_txca3lat,
400 { "Transmit CA3 Latency Counter", "homeplug.psr.txca3lat",
401 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA3 Latency Counter", HFILL }
404 { &hf_homeplug_psr_txca2lat,
405 { "Transmit CA2 Latency Counter", "homeplug.psr.txca2lat",
406 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA2 Latency Counter", HFILL }
408 { &hf_homeplug_psr_txca1lat,
409 { "Transmit CA1 Latency Counter", "homeplug.psr.txca1lat",
410 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA1 Latency Counter", HFILL }
412 { &hf_homeplug_psr_txca0lat,
413 { "Transmit CA0 Latency Counter", "homeplug.psr.txca0lat",
414 FT_UINT16, BASE_DEC, NULL, 0x0, "Transmit CA0 Latency Counter", HFILL }
417 { &hf_homeplug_psr_rxbp40,
418 { "Receive Cumulative Bytes per 40-symbol", "homeplug.psr.rxbp40",
419 FT_UINT32, BASE_DEC, NULL, 0x0, "Receive Cumulative Bytes per 40-symbol", HFILL }
422 /* Network Statistics Basic */
424 { "Network Statistics Basic", "homeplug.ns",
425 FT_NONE, BASE_DEC, NULL, 0x0, "Network Statistics Basic", HFILL }
428 { &hf_homeplug_ns_netw_ctrl_ac,
429 { "Action Control", "homeplug.ns.ac",
430 FT_BOOLEAN, BASE_DEC, NULL, HOMEPLUG_NS_AC, "Action Control", HFILL }
433 { &hf_homeplug_ns_netw_ctrl_icid,
434 { "IC_ID", "homeplug.ns.icid",
435 FT_UINT8, BASE_HEX, VALS(&homeplug_ns_icid_vals), HOMEPLUG_NS_ICID_MASK, "IC_ID", HFILL }
438 { &hf_homeplug_ns_netw_ctrl_icid_rsvd,
439 { "IC_ID Reserved", "homeplug.ns.icid",
440 FT_NONE, BASE_DEC, NULL, 0x0, "IC_ID Reserved", HFILL }
443 { &hf_homeplug_ns_bytes40_robo,
444 { "Bytes in 40 symbols in ROBO", "homeplug.ns.bytes40_robo",
445 FT_UINT16, BASE_DEC, NULL, 0x0, "Bytes in 40 symbols in ROBO", HFILL }
448 { &hf_homeplug_ns_fails_robo,
449 { "Fails Received in ROBO", "homeplug.ns.fails_robo",
450 FT_UINT16, BASE_DEC, NULL, 0x0, "Fails Received in ROBO", HFILL }
453 { &hf_homeplug_ns_drops_robo,
454 { "Frame Drops in ROBO", "homeplug.ns.drops_robo",
455 FT_UINT16, BASE_DEC, NULL, 0x0, "Frame Drops in ROBO", HFILL }
458 /* TODO NETW_DA1 ... */
459 { &hf_homeplug_ns_netw_da,
460 { "Address of Network DA", "homeplug.ns.netw_da",
461 FT_ETHER, BASE_HEX, NULL, 0x0, "Address of Network DA", HFILL }
464 { &hf_homeplug_ns_bytes40,
465 { "Bytes in 40 symbols", "homeplug.ns.bytes40",
466 FT_UINT16, BASE_DEC, NULL, 0x0, "Bytes in 40 symbols", HFILL }
469 { &hf_homeplug_ns_fails,
470 { "Fails Received", "homeplug.ns.fails",
471 FT_UINT16, BASE_DEC, NULL, 0x0, "Fails Received", HFILL }
474 { &hf_homeplug_ns_drops,
475 { "Frame Drops", "homeplug.ns.drops",
476 FT_UINT16, BASE_DEC, NULL, 0x0, "Frame Drops", HFILL }
479 /* TODO Network Statistics Extended */
482 { "Data", "homeplug.data",
483 FT_BYTES, BASE_NONE, NULL, 0x0, "Data", HFILL }
487 /* Setup protocol subtree array */
488 static gint *ett[] = {
500 proto_homeplug = proto_register_protocol("HomePlug protocol", "HomePlug", "homeplug");
502 proto_register_field_array(proto_homeplug, hf, array_length(hf));
504 proto_register_subtree_array(ett, array_length(ett));
507 /* Dissection of MCTRL */
508 static void dissect_homeplug_mctrl(ptvcursor_t * cursor)
510 proto_item * it = NULL;
512 if (!ptvcursor_tree(cursor))
515 it = ptvcursor_add_no_advance(cursor, hf_homeplug_mctrl, 1, FALSE);
516 homeplug_ne = tvb_get_guint8(ptvcursor_tvbuff(cursor),
517 ptvcursor_current_offset(cursor)) & HOMEPLUG_MCTRL_NE;
519 ptvcursor_push_subtree(cursor, it, ett_homeplug_mctrl);
520 ptvcursor_add_no_advance(cursor, hf_homeplug_mctrl_reserved, 1, FALSE);
521 ptvcursor_add(cursor, hf_homeplug_mctrl_ne, 1, FALSE);
523 ptvcursor_pop_subtree(cursor);
526 /* Dissection of MEHDR */
527 static void dissect_homeplug_mehdr(ptvcursor_t * cursor)
529 proto_item * it = NULL;
531 if (!ptvcursor_tree(cursor))
534 it = ptvcursor_add_no_advance(cursor, hf_homeplug_mehdr, 1, FALSE);
535 homeplug_metype = tvb_get_guint8(ptvcursor_tvbuff(cursor),
536 ptvcursor_current_offset(cursor)) & HOMEPLUG_MEHDR_METYPE;
538 ptvcursor_push_subtree(cursor, it, ett_homeplug_mehdr);
539 ptvcursor_add_no_advance(cursor, hf_homeplug_mehdr_mev, 1, FALSE);
540 ptvcursor_add(cursor, hf_homeplug_mehdr_metype, 1, FALSE);
542 ptvcursor_pop_subtree(cursor);
545 /* dissection of MELEN */
546 static void dissect_homeplug_melen(ptvcursor_t * cursor)
548 if (!ptvcursor_tree(cursor))
551 homeplug_melen = tvb_get_guint8(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));
552 ptvcursor_add(cursor, hf_homeplug_melen, 1, FALSE);
556 /* Dissection of Request Channel Estimation MME */
557 static void dissect_homeplug_rce(ptvcursor_t * cursor)
559 proto_item * it = NULL;
561 if (!ptvcursor_tree(cursor))
564 it = ptvcursor_add_no_advance(cursor, hf_homeplug_rce, homeplug_melen, FALSE);
566 ptvcursor_push_subtree(cursor, it, ett_homeplug_rce);
567 ptvcursor_add_no_advance(cursor, hf_homeplug_rce_cev, 1, FALSE);
568 ptvcursor_add(cursor, hf_homeplug_rce_rsvd, 1, FALSE);
570 ptvcursor_pop_subtree(cursor);
573 /* Dissection of Channel Estimation Response MME */
574 static void dissect_homeplug_cer(ptvcursor_t * cursor)
576 proto_item * it = NULL;
581 if (!ptvcursor_tree(cursor))
584 it = ptvcursor_add_no_advance(cursor, hf_homeplug_cer_cerv, homeplug_melen, FALSE);
586 ptvcursor_push_subtree(cursor, it, ett_homeplug_cer);
587 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_cerv, 1, FALSE);
588 ptvcursor_add(cursor, hf_homeplug_cer_rsvd1, 2, FALSE);
589 ptvcursor_add(cursor, hf_homeplug_cer_rxtmi, 1, FALSE);
591 for (;iTone < 10; iTone++) {
592 ptvcursor_add(cursor, hf_homeplug_cer_vt, 1, FALSE);
595 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_rate, 1, FALSE);
596 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_bp, 1, FALSE);
597 BP = tvb_get_guint8(ptvcursor_tvbuff(cursor),
598 ptvcursor_current_offset(cursor)) & HOMEPLUG_CER_BP;
599 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_mod, 1, FALSE);
600 ptvcursor_add(cursor, hf_homeplug_cer_vt11, 1, FALSE);
601 ptvcursor_add_no_advance(cursor, hf_homeplug_cer_rsvd2, 1, FALSE);
604 iNBDA = tvb_get_guint8(ptvcursor_tvbuff(cursor),
605 ptvcursor_current_offset(cursor)) & HOMEPLUG_CER_NBDAS;
606 ptvcursor_add(cursor, hf_homeplug_cer_nbdas, 1, FALSE);
607 /* TODO : Check on iNBDA! INT51X1 up to 16 dba. But up to 32 for INT51X1 (Host/DTE) */
608 for (;iNBDA > 0; iNBDA--) {
609 ptvcursor_add(cursor, hf_homeplug_cer_bda, 6, FALSE);
612 ptvcursor_pop_subtree(cursor);
616 /* Dissection of Request Parameters and Statistics MME */
617 static void dissect_homeplug_rps(ptvcursor_t * cursor)
619 if (!ptvcursor_tree(cursor))
622 ptvcursor_add(cursor, hf_homeplug_rps, 4, FALSE);
625 /* Dissection of Parameters and Statistics Response MME */
626 static void dissect_homeplug_psr(ptvcursor_t * cursor)
628 proto_item * it = NULL;
630 if (!ptvcursor_tree(cursor))
633 it = ptvcursor_add_no_advance(cursor, hf_homeplug_psr, homeplug_melen, FALSE);
635 ptvcursor_push_subtree(cursor, it, ett_homeplug_psr);
636 ptvcursor_add(cursor, hf_homeplug_psr_txack, 2, FALSE);
637 ptvcursor_add(cursor, hf_homeplug_psr_txnack, 2, FALSE);
638 ptvcursor_add(cursor, hf_homeplug_psr_txfail, 2, FALSE);
639 ptvcursor_add(cursor, hf_homeplug_psr_txcloss, 2, FALSE);
640 ptvcursor_add(cursor, hf_homeplug_psr_txcoll, 2, FALSE);
641 ptvcursor_add(cursor, hf_homeplug_psr_txca3lat, 2, FALSE);
642 ptvcursor_add(cursor, hf_homeplug_psr_txca2lat, 2, FALSE);
643 ptvcursor_add(cursor, hf_homeplug_psr_txca1lat, 2, FALSE);
644 ptvcursor_add(cursor, hf_homeplug_psr_txca0lat, 2, FALSE);
645 ptvcursor_add(cursor, hf_homeplug_psr_rxbp40, 4, FALSE);
647 ptvcursor_pop_subtree(cursor);
650 /* Dissection of the Network Statistic MME */
651 static void dissect_homeplug_ns(ptvcursor_t * cursor)
653 guint8 homeplug_ns_icid_rsvd = 0;
656 guint16 ns_bytes40= 0;
658 #define NEWT_DA_INEXISTANT G_GINT64_CONSTANT(010000000000U)
660 if (!ptvcursor_tree(cursor))
663 /* TODO : test length of the MME : differentiation of NS Basic and Extended */
664 ptvcursor_add_with_subtree(cursor, hf_homeplug_ns, SUBTREE_UNDEFINED_LENGTH, FALSE, ett_homeplug_ns);
666 /*it = ptvcursor_add_no_advance(cursor, hf_homeplug_ns, homeplug_melen, FALSE);
668 ptvcursor_push_subtree(cursor, it, ett_homeplug_ns);*/
669 ptvcursor_add_no_advance(cursor, hf_homeplug_ns_netw_ctrl_ac, 1, FALSE);
670 homeplug_ns_icid_rsvd = tvb_get_guint8(ptvcursor_tvbuff(cursor),
671 ptvcursor_current_offset(cursor)) & HOMEPLUG_NS_ICID_RSVD_MASK;
672 if (homeplug_ns_icid_rsvd)
673 ptvcursor_add(cursor, hf_homeplug_ns_netw_ctrl_icid_rsvd, 1, FALSE);
675 ptvcursor_add(cursor, hf_homeplug_ns_netw_ctrl_icid, 1, FALSE);
677 ptvcursor_add_no_advance(cursor, hf_homeplug_ns_bytes40_robo, 2, TRUE);
678 ns_bytes40 = tvb_get_letohs(ptvcursor_tvbuff(cursor),
679 ptvcursor_current_offset(cursor));
680 proto_tree_add_text(ptvcursor_tree(cursor), ptvcursor_tvbuff(cursor),
681 ptvcursor_current_offset(cursor), 2, "MHz : %.3f", (float)(ns_bytes40)/42);
682 ptvcursor_advance(cursor, 2);
684 ptvcursor_add(cursor, hf_homeplug_ns_fails_robo, 2, TRUE);
685 ptvcursor_add(cursor, hf_homeplug_ns_drops_robo, 2, TRUE);
688 newt_da = ((gint64)tvb_get_ntoh24(ptvcursor_tvbuff(cursor),
689 ptvcursor_current_offset(cursor))) << 24;
690 newt_da |= tvb_get_ntoh24(ptvcursor_tvbuff(cursor),
691 ptvcursor_current_offset(cursor)+3);
693 if (newt_da != NEWT_DA_INEXISTANT) {
694 ptvcursor_add_text_with_subtree(cursor, SUBTREE_UNDEFINED_LENGTH,
695 ett_homeplug_tone, "Tone Map #%d", iTone+1);
697 ptvcursor_add(cursor, hf_homeplug_ns_netw_da, 6, FALSE);
699 ptvcursor_add_no_advance(cursor, hf_homeplug_ns_bytes40, 2, TRUE);
700 ns_bytes40 = tvb_get_letohs(ptvcursor_tvbuff(cursor),
701 ptvcursor_current_offset(cursor));
702 proto_tree_add_text(ptvcursor_tree(cursor), ptvcursor_tvbuff(cursor),
703 ptvcursor_current_offset(cursor), 2, "MHz : %.3f", (float)(ns_bytes40)/42);
704 ptvcursor_advance(cursor, 2);
706 ptvcursor_add(cursor, hf_homeplug_ns_fails, 2, TRUE);
707 ptvcursor_add(cursor, hf_homeplug_ns_drops, 2, TRUE);
709 ptvcursor_pop_subtree(cursor);
711 proto_tree_add_text(ptvcursor_tree(cursor), ptvcursor_tvbuff(cursor),
712 ptvcursor_current_offset(cursor), 12, "Tone Map #%d does not exist", iTone+1);
717 ptvcursor_pop_subtree(cursor);
720 /* Dissection of unknown tags */
721 static void dissect_homeplug_unknown(ptvcursor_t * cursor)
723 ptvcursor_add(cursor, hf_homeplug_data, homeplug_melen, FALSE);
726 static void dissect_homeplug_mme(ptvcursor_t * cursor, packet_info * pinfo)
728 if (check_col(pinfo->cinfo, COL_INFO)) {
729 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(homeplug_metype, homeplug_metype_vals, "Unknown %u"));
732 switch(homeplug_metype) {
733 case HOMEPLUG_MME_RCE:
734 dissect_homeplug_rce(cursor);
736 case HOMEPLUG_MME_CER:
737 dissect_homeplug_cer(cursor);
739 case HOMEPLUG_MME_RPS:
740 dissect_homeplug_rps(cursor);
742 case HOMEPLUG_MME_PSR:
743 dissect_homeplug_psr(cursor);
745 case HOMEPLUG_MME_NS:
746 dissect_homeplug_ns(cursor);
749 dissect_homeplug_unknown(cursor);
754 #define TVB_LEN_GREATEST 1
755 #define TVB_LEN_UNDEF 0
756 #define TVB_LEN_SHORTEST -1
757 static int check_tvb_length(ptvcursor_t *cursor, const gint length)
760 return TVB_LEN_UNDEF;
762 if (tvb_reported_length_remaining(ptvcursor_tvbuff(cursor),
763 ptvcursor_current_offset(cursor)) < length)
764 return TVB_LEN_SHORTEST;
766 return TVB_LEN_GREATEST;
770 dissect_homeplug(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
772 proto_item * it= NULL;
773 proto_tree * homeplug_tree= NULL;
774 ptvcursor_t * cursor= NULL;
776 if (check_col(pinfo->cinfo, COL_PROTOCOL))
777 col_set_str(pinfo->cinfo, COL_PROTOCOL, "HomePlug");
778 /* Clear out stuff in the info column */
779 if (check_col(pinfo->cinfo, COL_INFO)) {
780 col_clear(pinfo->cinfo, COL_INFO);
781 col_set_str(pinfo->cinfo, COL_INFO, "MAC Management");
787 it = proto_tree_add_item(tree, proto_homeplug, tvb, homeplug_offset, -1, FALSE);
788 homeplug_tree = proto_item_add_subtree(it, ett_homeplug);
789 cursor = ptvcursor_new(homeplug_tree, tvb, 0);
792 /* We do not have enough data to read mctrl field stop the dissection */
793 if (check_tvb_length(cursor, HOMEPLUG_MCTRL_LEN) != TVB_LEN_SHORTEST) {
795 dissect_homeplug_mctrl(cursor);
797 /** homeplug_ne indicates the number of MME entries. This field is fetched
800 if ((homeplug_ne > 0) && check_col(pinfo->cinfo, COL_INFO)) {
801 col_clear(pinfo->cinfo, COL_INFO);
803 for (; homeplug_ne > 0; homeplug_ne--) {
805 /* Check we have enough data in tvb to read MEHDR */
806 if (check_tvb_length(cursor, HOMEPLUG_MEHDR_LEN) == TVB_LEN_SHORTEST)
808 dissect_homeplug_mehdr(cursor);
810 /* Check we have enough data in tvb to read MELEN */
811 if (check_tvb_length(cursor, HOMEPLUG_MELEN_LEN) == TVB_LEN_SHORTEST)
813 dissect_homeplug_melen(cursor);
815 dissect_homeplug_mme(cursor, pinfo);
820 ptvcursor_free(cursor);
825 proto_reg_handoff_homeplug(void)
827 dissector_handle_t homeplug_handle;
829 homeplug_handle = create_dissector_handle(dissect_homeplug, proto_homeplug);
830 dissector_add("ethertype", ETHERTYPE_HOMEPLUG, homeplug_handle);