/src/wireshark/epan/dissectors/packet-realtek.c
Line | Count | Source |
1 | | /* packet-realtek.c |
2 | | * Routines for Realtek layer 2 protocols dissection |
3 | | * |
4 | | * Based on code from a 2004 submission |
5 | | * Copyright 2004, Horst Kronstorfer <hkronsto@frequentis.com> |
6 | | * but significantly modernized. |
7 | | * |
8 | | * Wireshark - Network traffic analyzer |
9 | | * By Gerald Combs <gerald@ethereal.com> |
10 | | * Copyright 1998 Gerald Combs |
11 | | * |
12 | | * SPDX-License-Identifier: GPL-2.0-or-later |
13 | | */ |
14 | | |
15 | | #include "config.h" |
16 | | |
17 | | #include <string.h> |
18 | | #include <epan/packet.h> |
19 | | #include <etypes.h> |
20 | | |
21 | | void proto_register_realtek(void); |
22 | | void proto_reg_handoff_realtek(void); |
23 | | |
24 | 1 | #define RTL_PROTOCOL_RRCP 0x01 /* RRCP */ |
25 | 1 | #define RTL_PROTOCOL_REP 0x02 /* REP */ |
26 | 2 | #define RTL_PROTOCOL_RLDP 0x03 /* RLDP */ |
27 | 1 | #define RTL_PROTOCOL_RLDP2 0x23 /* also RLDP */ |
28 | | #define RTL_PROTOCOL_XXX_DSA 0x04 /* DSA protocol for some chip(s) */ |
29 | | |
30 | | /* |
31 | | * Values for the upper 4 bits of the protocol field, for |
32 | | * protocols where the lower 4 bits contain protocol data. |
33 | | * |
34 | | * See section 8.10 "CPU Tag Function" of |
35 | | * |
36 | | * http://realtek.info/pdf/rtl8306sd%28m%29_datasheet_1.1.pdf |
37 | | * |
38 | | * for the RTL8306 DSA protocol tag format. |
39 | | */ |
40 | | #define RTL_PROTOCOL_8306_DSA 0x9 /* RTL8306 DSA protocol */ |
41 | | #define RTL_PROTOCOL_8366RB_DSA 0xA /* RTL8366RB DSA protocol */ |
42 | | |
43 | | enum { |
44 | | RRCP_OPCODE_HELLO = 0, |
45 | | RRCP_OPCODE_GET = 1, |
46 | | RRCP_OPCODE_SET = 2 |
47 | | }; |
48 | | |
49 | | /* HELLO, HELLO_REPLY, GET, GET_REPLY, SET */ |
50 | 0 | #define RRCP_OPCODE_FIELD_LENGTH 1 |
51 | 0 | #define RRCP_REPLY_FIELD_LENGTH RRCP_OPCODE_FIELD_LENGTH |
52 | 15 | #define RRCP_REPLY_MASK 0x80 |
53 | | #define RRCP_REPLY_BIT_POS 7 |
54 | 15 | #define RRCP_OPCODE_MASK 0x7f |
55 | 0 | #define RRCP_AUTHKEY_FIELD_LENGTH 2 |
56 | | /* GET, GET_REPLY, SET */ |
57 | 0 | #define RRCP_REGADDR_FIELD_LENGTH 2 |
58 | | /* GET_REPLY, SET */ |
59 | 0 | #define RRCP_REGDATA_FIELD_LENGTH 2 |
60 | | /* HELLO_REPLY */ |
61 | 0 | #define RRCP_DLPORT_FIELD_LENGTH 1 |
62 | 0 | #define RRCP_ULPORT_FIELD_LENGTH 1 |
63 | 0 | #define RRCP_ULMAC_FIELD_LENGTH 6 |
64 | 0 | #define RRCP_CHIPID_FIELD_LENGTH 2 |
65 | 0 | #define RRCP_VENDID_FIELD_LENGTH 4 |
66 | | |
67 | | #define RRCP_HELLO_PACKET_LENGTH 4 |
68 | | #define RRCP_HELLO_REPLY_PACKET_LENGTH 18 |
69 | | #define RRCP_GET_SET_PACKET_LENGTH 8 |
70 | | |
71 | | static const value_string rrcp_opcode_names[] = { |
72 | | { RRCP_OPCODE_HELLO, "Hello" }, |
73 | | { RRCP_OPCODE_GET, "Get" }, |
74 | | { RRCP_OPCODE_SET, "Set" }, |
75 | | {0, NULL} |
76 | | }; |
77 | | |
78 | | static dissector_handle_t realtek_handle; |
79 | | |
80 | | static int proto_realtek; |
81 | | |
82 | | static int hf_realtek_packet; |
83 | | |
84 | | static int proto_rrcp; |
85 | | |
86 | | static int hf_rrcp_protocol; |
87 | | static int hf_rrcp_reply; |
88 | | static int hf_rrcp_opcode; |
89 | | static int hf_rrcp_authkey; |
90 | | static int hf_rrcp_regaddr; |
91 | | static int hf_rrcp_regdata; |
92 | | static int hf_rrcp_hello_reply_dl_port; |
93 | | static int hf_rrcp_hello_reply_ul_port; |
94 | | static int hf_rrcp_hello_reply_ul_mac; |
95 | | static int hf_rrcp_hello_reply_chip_id; |
96 | | static int hf_rrcp_hello_reply_vendor_id; |
97 | | |
98 | | static int proto_rep; |
99 | | static int hf_rep_protocol; |
100 | | |
101 | | static int proto_rldp; |
102 | | static int hf_rldp_protocol; |
103 | | |
104 | | static int ett_realtek; |
105 | | static int ett_rrcp; |
106 | | static int ett_rep; |
107 | | static int ett_rldp; |
108 | | |
109 | | static heur_dissector_list_t realtek_heur_subdissector_list; |
110 | | |
111 | | static const uint8_t ether_mac_bcast[] = { |
112 | | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff |
113 | | }; |
114 | | |
115 | | /* Code to actually dissect the Realtek protocols */ |
116 | | static int |
117 | | dissect_realtek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
118 | 1 | { |
119 | 1 | proto_item *ti; |
120 | 1 | proto_tree *realtek_tree; |
121 | 1 | heur_dtbl_entry_t *hdtbl_entry; |
122 | | |
123 | 1 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Realtek"); |
124 | 1 | col_clear(pinfo->cinfo, COL_INFO); |
125 | | |
126 | 1 | ti = proto_tree_add_item(tree, proto_realtek, tvb, 0, -1, ENC_NA); |
127 | 1 | realtek_tree = proto_item_add_subtree(ti, ett_realtek); |
128 | | |
129 | 1 | if (!dissector_try_heuristic(realtek_heur_subdissector_list, tvb, pinfo, |
130 | 1 | tree, &hdtbl_entry, NULL)) { |
131 | 1 | proto_tree_add_item(realtek_tree, hf_realtek_packet, tvb, 0, -1, ENC_NA); |
132 | 1 | } |
133 | 1 | return tvb_captured_length(tvb); |
134 | 1 | } |
135 | | |
136 | | /* |
137 | | * See section 8.20 "Realtek Remote Control Protocol" of |
138 | | * |
139 | | * http://realtek.info/pdf/rtl8324.pdf |
140 | | * |
141 | | * and section 7.22 "Realtek Remote Control Protocol" of |
142 | | * |
143 | | * http://realtek.info/pdf/rtl8326.pdf |
144 | | * |
145 | | * and this page on the OpenRRCP Wiki: |
146 | | * |
147 | | * http://openrrcp.org.ru/wiki/rrcp_protocol |
148 | | * |
149 | | * for information on RRCP. |
150 | | */ |
151 | | static bool |
152 | | dissect_rrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
153 | 1 | { |
154 | 1 | proto_item *ti; |
155 | 1 | proto_tree *rrcp_tree; |
156 | 1 | uint8_t proto; |
157 | 1 | int offset = 0; |
158 | 1 | bool reply; |
159 | 1 | uint32_t opcode; |
160 | | |
161 | 1 | if (!tvb_bytes_exist(tvb, 0, 1)) |
162 | 0 | return false; |
163 | 1 | proto = tvb_get_uint8(tvb, 0); |
164 | 1 | if (proto != RTL_PROTOCOL_RRCP) |
165 | 1 | return false; |
166 | | |
167 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "RRCP"); |
168 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
169 | |
|
170 | 0 | ti = proto_tree_add_item(tree, proto_rrcp, tvb, 0, -1, ENC_NA); |
171 | 0 | rrcp_tree = proto_item_add_subtree(ti, ett_rrcp); |
172 | |
|
173 | 0 | proto_tree_add_uint(rrcp_tree, hf_rrcp_protocol, tvb, offset, 1, |
174 | 0 | proto); |
175 | 0 | offset += 1; |
176 | 0 | proto_tree_add_item_ret_boolean(rrcp_tree, hf_rrcp_reply, tvb, |
177 | 0 | offset, RRCP_REPLY_FIELD_LENGTH, |
178 | 0 | ENC_NA, &reply); |
179 | 0 | proto_tree_add_item_ret_uint(rrcp_tree, hf_rrcp_opcode, tvb, |
180 | 0 | offset, RRCP_OPCODE_FIELD_LENGTH, |
181 | 0 | ENC_NA, &opcode); |
182 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", |
183 | 0 | val_to_str(pinfo->pool, opcode, rrcp_opcode_names, "Unknown (%u)"), |
184 | 0 | (reply) ? "Reply" : "Request"); |
185 | 0 | offset += RRCP_OPCODE_FIELD_LENGTH; |
186 | |
|
187 | 0 | proto_tree_add_item(rrcp_tree, hf_rrcp_authkey, tvb, offset, |
188 | 0 | RRCP_AUTHKEY_FIELD_LENGTH, ENC_BIG_ENDIAN); |
189 | 0 | offset += RRCP_AUTHKEY_FIELD_LENGTH; |
190 | |
|
191 | 0 | if ((RRCP_OPCODE_GET == opcode) || (RRCP_OPCODE_SET == opcode)) { |
192 | 0 | proto_tree_add_item(rrcp_tree, hf_rrcp_regaddr, tvb, offset, |
193 | 0 | RRCP_REGADDR_FIELD_LENGTH, ENC_BIG_ENDIAN); |
194 | 0 | offset += RRCP_REGADDR_FIELD_LENGTH; |
195 | 0 | proto_tree_add_item(rrcp_tree, hf_rrcp_regdata, tvb, offset, |
196 | 0 | RRCP_REGDATA_FIELD_LENGTH, ENC_BIG_ENDIAN); |
197 | 0 | offset += RRCP_REGDATA_FIELD_LENGTH; |
198 | 0 | } |
199 | 0 | else if (RRCP_OPCODE_HELLO == opcode) { |
200 | 0 | if (reply) { |
201 | 0 | proto_tree_add_item(rrcp_tree, hf_rrcp_hello_reply_dl_port, tvb, |
202 | 0 | offset, RRCP_DLPORT_FIELD_LENGTH, ENC_NA); |
203 | 0 | offset += RRCP_DLPORT_FIELD_LENGTH; |
204 | 0 | proto_tree_add_item(rrcp_tree, hf_rrcp_hello_reply_ul_port, tvb, |
205 | 0 | offset, RRCP_ULPORT_FIELD_LENGTH, ENC_NA); |
206 | 0 | offset += RRCP_ULPORT_FIELD_LENGTH; |
207 | 0 | proto_tree_add_item(rrcp_tree, hf_rrcp_hello_reply_ul_mac, tvb, |
208 | 0 | offset, RRCP_ULMAC_FIELD_LENGTH, ENC_NA); |
209 | 0 | offset += RRCP_ULMAC_FIELD_LENGTH; |
210 | 0 | proto_tree_add_item(rrcp_tree, hf_rrcp_hello_reply_chip_id, tvb, |
211 | 0 | offset, RRCP_CHIPID_FIELD_LENGTH, ENC_BIG_ENDIAN); |
212 | 0 | offset += RRCP_CHIPID_FIELD_LENGTH; |
213 | 0 | proto_tree_add_item(rrcp_tree, hf_rrcp_hello_reply_vendor_id, tvb, |
214 | 0 | offset, RRCP_VENDID_FIELD_LENGTH, ENC_BIG_ENDIAN); |
215 | 0 | offset += RRCP_VENDID_FIELD_LENGTH; |
216 | 0 | } |
217 | 0 | } |
218 | 0 | proto_item_set_end(ti, tvb, offset); |
219 | | /* Let 'packet-eth' provide trailer/pad-bytes info */ |
220 | 0 | tvb_set_reported_length(tvb, offset); |
221 | 0 | return true; |
222 | 1 | } |
223 | | |
224 | | /* |
225 | | * See section 8.22 "Realtek Echo Protocol" of |
226 | | * |
227 | | * http://realtek.info/pdf/rtl8324.pdf |
228 | | * |
229 | | * and section 7.24 "Realtek Echo Protocol" of |
230 | | * |
231 | | * http://realtek.info/pdf/rtl8326.pdf |
232 | | * |
233 | | * for information on REP. |
234 | | */ |
235 | | static bool |
236 | | dissect_rep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
237 | 1 | { |
238 | 1 | proto_item *ti; |
239 | 1 | proto_tree *rep_tree; |
240 | 1 | uint8_t proto; |
241 | 1 | int offset = 0; |
242 | 1 | bool bcast; |
243 | | |
244 | 1 | if (!tvb_bytes_exist(tvb, 0, 1)) |
245 | 0 | return false; |
246 | 1 | proto = tvb_get_uint8(tvb, 0); |
247 | 1 | if (proto != RTL_PROTOCOL_REP) |
248 | 1 | return false; |
249 | | |
250 | 0 | ti = proto_tree_add_item(tree, proto_rep, tvb, 0, -1, ENC_NA); |
251 | 0 | rep_tree = proto_item_add_subtree(ti, ett_rep); |
252 | |
|
253 | 0 | bcast = (pinfo->dst.type == AT_ETHER && |
254 | 0 | memcmp(pinfo->dst.data, ether_mac_bcast, 6) == 0); |
255 | |
|
256 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "REP"); |
257 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
258 | 0 | "Echo %s", (bcast) ? "Request" : "Reply"); |
259 | |
|
260 | 0 | proto_tree_add_uint(rep_tree, hf_rep_protocol, tvb, offset, 1, |
261 | 0 | proto); |
262 | 0 | offset += 1; |
263 | |
|
264 | 0 | proto_item_set_end(ti, tvb, offset); |
265 | | /* Let 'packet-eth' provide trailer/pad-bytes info */ |
266 | 0 | tvb_set_reported_length(tvb, offset); |
267 | 0 | return true; |
268 | 1 | } |
269 | | |
270 | | /* |
271 | | * See section 8.21 "Network Loop Connection Fault Detection" of |
272 | | * |
273 | | * http://realtek.info/pdf/rtl8324.pdf |
274 | | * |
275 | | * and section 7.23 "Network Loop Connection Fault Detection" of |
276 | | * |
277 | | * http://realtek.info/pdf/rtl8326.pdf |
278 | | * |
279 | | * for information on RLDP. |
280 | | * |
281 | | * See also section 7.3.8 "Loop Detection" of |
282 | | * |
283 | | * http://www.ibselectronics.com/ibsstore/datasheet/RTL8306E-CG.pdf |
284 | | * |
285 | | * (revision 1.1 of the RTL8306E-CG datasheet), which describes a loop |
286 | | * detection protocol for which the payload has a 16-bit (presumably |
287 | | * big-endian) field containing the value 0x0300, followed by what is |
288 | | * presumably a 16-bit big-endian field the upper 12 bits of which are 0 |
289 | | * and the lower 4 bits of which are a TTL value, followed by zeroes to |
290 | | * pad the packet out to the minimum Ethernet packet size. |
291 | | * |
292 | | * See also section 7.3.13 "Loop Detection" of |
293 | | * |
294 | | * http://realtek.info/pdf/rtl8305sb.pdf |
295 | | * |
296 | | * (revision 1.3 of the RTL8305SB datasheet), which describes a similar |
297 | | * loop detection protocol that lacks the TTL field - all the bytes |
298 | | * after 0x0300 are zero. |
299 | | * |
300 | | * See also section 7.3.7 "Loop Detection" of |
301 | | * |
302 | | * https://datasheet.lcsc.com/lcsc/1810221720_Realtek-Semicon-RTL8305NB-CG_C52146.pdf |
303 | | * |
304 | | * (revision 1.0 of the RTL8305NB-CT datasheet), which describes a loop |
305 | | * detection protocol similar to the one from the RTL8306E-CG datasheet, |
306 | | * except that the first value is 0x2300, not 0x0300. |
307 | | * |
308 | | * And, on top of all that, I've seen packets where the first octet of |
309 | | * the packet is 0x23, and that's followed by 6 unknown octets (a MAC |
310 | | * address of some sort? It differs from packet to packet in a capture), |
311 | | * followed by the MAC address that appears in the source address in the |
312 | | * Ethernet header (possibly the originator, in case the packet is forwarded, |
313 | | * in which case the forwarded packets won't have the source address from |
314 | | * the Ethernet header there), followed by unknown stuff (0x0d followed by |
315 | | * zeroes for all such packets in one capture, 0x01 followed by zeroes for |
316 | | * all such packets in another capture, 0x07 followed by 0x20's for all |
317 | | * such packets in yet another capture). The OpenRRCP issue at |
318 | | * https://github.com/illarionov/OpenRRCP/issues/3 shows a capture |
319 | | * similar to the last of those, but with 0x02 instead of 0x07. Or is that |
320 | | * just crap in the buffer in which the chip constructed the packet, left |
321 | | * over from something else? |
322 | | */ |
323 | | static bool |
324 | | dissect_rldp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
325 | 1 | { |
326 | 1 | proto_item *ti; |
327 | 1 | proto_tree *rldp_tree; |
328 | 1 | uint8_t proto; |
329 | 1 | int offset = 0; |
330 | | |
331 | 1 | if (!tvb_bytes_exist(tvb, 0, 1)) |
332 | 0 | return false; |
333 | 1 | proto = tvb_get_uint8(tvb, 0); |
334 | 1 | if (proto != RTL_PROTOCOL_RLDP && proto != RTL_PROTOCOL_RLDP2) |
335 | 1 | return false; |
336 | | |
337 | 0 | ti = proto_tree_add_item(tree, proto_rldp, tvb, 0, -1, ENC_NA); |
338 | 0 | rldp_tree = proto_item_add_subtree(ti, ett_rep); |
339 | |
|
340 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLDP"); |
341 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Network Loop Detection"); |
342 | |
|
343 | 0 | proto_tree_add_uint(rldp_tree, hf_rldp_protocol, tvb, offset, 1, |
344 | 0 | proto); |
345 | 0 | offset += 1; |
346 | |
|
347 | 0 | proto_item_set_end(ti, tvb, offset); |
348 | | /* Let 'packet-eth' provide trailer/pad-bytes info */ |
349 | 0 | tvb_set_reported_length(tvb, offset); |
350 | 0 | return true; |
351 | 1 | } |
352 | | |
353 | | /* Register the protocol with Ethereal */ |
354 | | void |
355 | | proto_register_realtek(void) |
356 | 15 | { |
357 | 15 | static hf_register_info hf_realtek[] = { |
358 | 15 | { &hf_realtek_packet, { |
359 | 15 | "Unknown packet", "realtek.packet", FT_BYTES, BASE_NONE, |
360 | 15 | NULL, 0x0, NULL, HFILL }}, |
361 | 15 | }; |
362 | | |
363 | 15 | static hf_register_info hf_rrcp[] = { |
364 | 15 | { &hf_rrcp_protocol, { |
365 | 15 | "Protocol", "rrcp.protocol", FT_UINT8, BASE_HEX, |
366 | 15 | NULL, 0x0, NULL, HFILL }}, |
367 | 15 | { &hf_rrcp_reply, { |
368 | 15 | "Reply", "rrcp.reply", FT_BOOLEAN, 8, |
369 | 15 | NULL, RRCP_REPLY_MASK, "RRCP reply flag", HFILL}}, |
370 | 15 | { &hf_rrcp_opcode, { |
371 | 15 | "Opcode", "rrcp.opcode", FT_UINT8, BASE_HEX, |
372 | 15 | VALS(rrcp_opcode_names), RRCP_OPCODE_MASK, "RRCP operation code", |
373 | 15 | HFILL }}, |
374 | 15 | { &hf_rrcp_authkey, { |
375 | 15 | "Authentication key", "rrcp.authkey", FT_UINT16, BASE_HEX, |
376 | 15 | NULL, 0, "RRCP authentication key", HFILL }}, |
377 | 15 | { &hf_rrcp_regaddr, { |
378 | 15 | "Register address", "rrcp.regaddr", FT_UINT16, BASE_HEX, |
379 | 15 | NULL, 0, "RRCP register address", HFILL }}, |
380 | 15 | { &hf_rrcp_regdata, { |
381 | 15 | "Register data", "rrcp.regdata", FT_UINT16, BASE_HEX, |
382 | 15 | NULL, 0, "RRCP register data", HFILL }}, |
383 | 15 | { &hf_rrcp_hello_reply_dl_port, { |
384 | 15 | "Downlink port number", "rrcp.hello_reply.downlink_port", |
385 | 15 | FT_UINT8, BASE_DEC, NULL, 0, "RRCP hello reply downlink port", HFILL }}, |
386 | 15 | { &hf_rrcp_hello_reply_ul_port, { |
387 | 15 | "Uplink port number", "rrcp.hello_reply.uplink_port", FT_UINT8, |
388 | 15 | BASE_DEC, NULL, 0, "RRCP hello reply uplink port", HFILL }}, |
389 | 15 | { &hf_rrcp_hello_reply_ul_mac, { |
390 | 15 | "Uplink MAC address", "rrcp.hello_reply.uplink_mac", FT_ETHER, |
391 | 15 | BASE_NONE, NULL, 0, "RRCP hello reply uplink MAC address", HFILL }}, |
392 | 15 | { &hf_rrcp_hello_reply_chip_id, { |
393 | 15 | "Chip ID", "rrcp.hello_reply.chip_id", FT_UINT16, |
394 | 15 | BASE_HEX, NULL, 0, "RRCP hello reply chip ID", HFILL }}, |
395 | 15 | { &hf_rrcp_hello_reply_vendor_id, { |
396 | 15 | "Vendor ID", "rrcp.hello_reply.vendor_id", FT_UINT32, BASE_HEX, |
397 | 15 | NULL, 0, "RRCP hello reply vendor ID", HFILL }} |
398 | 15 | }; |
399 | | |
400 | 15 | static hf_register_info hf_rep[] = { |
401 | 15 | { &hf_rep_protocol, { |
402 | 15 | "Protocol", "rep.protocol", FT_UINT8, BASE_HEX, |
403 | 15 | NULL, 0x0, NULL, HFILL }}, |
404 | 15 | }; |
405 | | |
406 | 15 | static hf_register_info hf_rldp[] = { |
407 | 15 | { &hf_rldp_protocol, { |
408 | 15 | "Protocol", "rldp.protocol", FT_UINT8, BASE_HEX, |
409 | 15 | NULL, 0x0, NULL, HFILL }}, |
410 | 15 | }; |
411 | | |
412 | 15 | static int *ett[] = { |
413 | 15 | &ett_realtek, |
414 | 15 | &ett_rrcp, |
415 | 15 | &ett_rep, |
416 | 15 | &ett_rldp |
417 | 15 | }; |
418 | | |
419 | 15 | proto_realtek = proto_register_protocol("Realtek Layer 2 Protocols", |
420 | 15 | "Realtek", "realtek"); |
421 | 15 | realtek_handle = register_dissector("realtek", dissect_realtek, proto_realtek); |
422 | 15 | proto_register_field_array(proto_realtek, hf_realtek, array_length(hf_realtek)); |
423 | 15 | realtek_heur_subdissector_list = register_heur_dissector_list_with_description("realtek", |
424 | 15 | "Realtek Layer 2 payload", |
425 | 15 | proto_realtek); |
426 | | |
427 | 15 | proto_rrcp = proto_register_protocol("Realtek Remote Control Protocol", |
428 | 15 | "RRCP", "rrcp"); |
429 | 15 | proto_register_field_array(proto_rrcp, hf_rrcp, array_length(hf_rrcp)); |
430 | | |
431 | 15 | proto_rep = proto_register_protocol("Realtek Echo Protocol", |
432 | 15 | "REP", "rep"); |
433 | 15 | proto_register_field_array(proto_rrcp, hf_rep, array_length(hf_rep)); |
434 | | |
435 | 15 | proto_rldp = proto_register_protocol("Realtek Loop Detection Protocol", |
436 | 15 | "RLDP", "rldp"); |
437 | 15 | proto_register_field_array(proto_rrcp, hf_rldp, array_length(hf_rldp)); |
438 | | |
439 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
440 | 15 | } |
441 | | |
442 | | /* Sub-dissector registration */ |
443 | | void |
444 | | proto_reg_handoff_realtek(void) |
445 | 15 | { |
446 | 15 | dissector_add_uint("ethertype", ETHERTYPE_REALTEK, realtek_handle); |
447 | | |
448 | 15 | heur_dissector_add("realtek", dissect_rrcp, "Realtek Remote Control Protocol", |
449 | 15 | "rrcp", proto_rrcp, HEURISTIC_ENABLE); |
450 | | |
451 | 15 | heur_dissector_add("realtek", dissect_rep, "Realtek Echo Protocol", |
452 | 15 | "rep", proto_rep, HEURISTIC_ENABLE); |
453 | | |
454 | 15 | heur_dissector_add("realtek", dissect_rldp, "Realtek Loop Detection Protocol", |
455 | 15 | "rldp", proto_rldp, HEURISTIC_ENABLE); |
456 | 15 | } |