Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-epon.c
blobc0bb3ebde63aa4faf0e888cb7b5e764226413051
1 /* packet-epon.c
2 * Routines for Ethernet Passive Optical Network dissection
3 * Copyright 2014, Philip Rosenberg-Watt <p.rosenberg-watt[at]cablelabs.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 /* 2014-04 Philip Rosenberg-Watt <p.rosenberg-watt[at]cablelabs.com>
13 * + EPON preamble with CableLabs DPoE securty byte.
14 * See IEEE 802.3-2012 Section 5, Clause 65 and
15 * CableLabs DPoE SEC 1.0 specification.
18 #include "config.h"
20 #include <epan/packet.h>
21 #include <epan/expert.h>
22 #include <epan/tfs.h>
24 #include <epan/addr_resolv.h>
25 #include <epan/crc8-tvb.h>
27 void proto_register_epon(void);
28 void proto_reg_handoff_epon(void);
30 static dissector_handle_t epon_handle;
32 static int proto_epon;
33 static int hf_epon_dpoe_security;
34 static int hf_epon_dpoe_encrypted;
35 static int hf_epon_dpoe_reserved;
36 static int hf_epon_dpoe_encrypted_data;
37 static int hf_epon_dpoe_keyid;
38 static int hf_epon_mode;
39 static int hf_epon_llid;
40 static int hf_epon_checksum;
41 static int hf_epon_checksum_status;
43 static expert_field ei_epon_sld_bad;
44 static expert_field ei_epon_dpoe_reserved_bad;
45 static expert_field ei_epon_dpoe_bad;
46 static expert_field ei_epon_dpoe_encrypted_data;
47 static expert_field ei_epon_checksum_bad;
49 static dissector_handle_t eth_maybefcs_handle;
51 static int ett_epon;
52 static int ett_epon_sec;
53 static int ett_epon_checksum;
55 static const true_false_string epon_mode_tfs = {
56 "Broadcast/Multicast",
57 "Unicast"
60 static int
61 dissect_epon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
62 void *data _U_)
64 proto_tree *epon_tree;
65 proto_item *ti;
66 proto_item *item;
67 proto_tree *sec_tree;
68 tvbuff_t *next_tvb;
69 unsigned checksum;
70 unsigned sent_checksum;
71 unsigned offset = 0;
72 unsigned dpoe_sec_byte;
73 bool dpoe_encrypted = false;
75 /* Start_of_Packet delimiter (/S/) can happen in byte 1, 2 or 3,
76 * making the captured preamble 8, 7 or 6 bytes in length. If the
77 * preamble starts with 0x55, then /S/ happened in byte 1, making the
78 * captured preamble 7 bytes in length.
80 if (tvb_get_ntohl(tvb, 0) == 0x5555D555) {
81 offset += 2;
82 } else if (tvb_get_ntoh24(tvb, 0) == 0x55D555) {
83 offset += 1;
84 } else if (tvb_get_ntohs(tvb, 0) == 0xD555) {
85 offset += 0;
86 } else {
87 item = proto_tree_add_item(tree, proto_epon, tvb, offset, 0, ENC_NA);
88 expert_add_info(pinfo, item, &ei_epon_sld_bad);
89 return 0;
92 /* Set the columns */
93 col_set_str(pinfo->cinfo, COL_PROTOCOL, "EPON");
94 col_set_str(pinfo->cinfo, COL_INFO, "EPON Preamble");
96 /* Create display subtree for the protocol */
97 ti = proto_tree_add_item(tree, proto_epon, tvb, 0+offset, 6, ENC_NA);
98 epon_tree = proto_item_add_subtree(ti, ett_epon);
100 /* Decode byte 5 of the preamble according to CableLabs DPoE specification.
101 * If security is disabled, the DPoE byte will remain 0x55 and no decoding
102 * is necessary.
104 dpoe_sec_byte = tvb_get_uint8(tvb, 2+offset);
105 if (dpoe_sec_byte != 0x55) {
106 unsigned dpoe_keyid;
107 unsigned dpoe_reserved;
109 item = proto_tree_add_item(epon_tree, hf_epon_dpoe_security,
110 tvb, 2+offset, 1, ENC_BIG_ENDIAN);
111 sec_tree = proto_item_add_subtree(item, ett_epon_sec);
113 /* The DPoE security byte is split into three fields:
114 * bits 7-2 are reserved in 1G mode
115 * bit 1 is the encryption mode
116 * bit 0 is the key ID
118 dpoe_reserved = dpoe_sec_byte & 0xFC;
119 dpoe_encrypted = dpoe_sec_byte & 0x02;
120 dpoe_keyid = dpoe_sec_byte & 0x01;
122 /* Add encryption status text to sec_tree subtree
124 proto_item_append_text(item, " (Encrypted: ");
125 if (dpoe_encrypted) {
126 proto_item_append_text(item, "True, Key ID: %x", dpoe_keyid);
127 } else {
128 proto_item_append_text(item, "False");
130 proto_item_append_text(item, ")");
132 /* We don't need to see the reserved bits of the DPoE security byte unless
133 * there's something wrong with them.
135 if (dpoe_reserved != 0x54) {
136 proto_tree_add_item(sec_tree, hf_epon_dpoe_reserved, tvb, 2+offset, 1,
137 ENC_BIG_ENDIAN);
138 expert_add_info(pinfo, sec_tree, &ei_epon_dpoe_reserved_bad);
141 /* Add encryption and key ID bits
142 * Error if encryption is disabled but key bit is not 1
144 proto_tree_add_item(sec_tree, hf_epon_dpoe_encrypted, tvb, 2+offset, 1,
145 ENC_BIG_ENDIAN);
146 proto_tree_add_item(sec_tree, hf_epon_dpoe_keyid, tvb, 2+offset, 1,
147 ENC_BIG_ENDIAN);
148 if (!dpoe_encrypted && (dpoe_keyid == 0)) {
149 expert_add_info(pinfo, sec_tree, &ei_epon_dpoe_bad);
154 /* Mode bit
156 proto_tree_add_item(epon_tree, hf_epon_mode, tvb, 3+offset, 2,
157 ENC_BIG_ENDIAN);
159 /* LLID
161 proto_tree_add_item(epon_tree, hf_epon_llid, tvb, 3+offset, 2,
162 ENC_BIG_ENDIAN);
164 /* Verify the CRC-8 checksum
166 sent_checksum = tvb_get_uint8(tvb, 5+offset);
167 checksum = get_crc8_ieee8023_epon(tvb, 5, 0+offset);
169 proto_tree_add_checksum(epon_tree, tvb, 5+offset, hf_epon_checksum, hf_epon_checksum_status, &ei_epon_checksum_bad, pinfo, checksum, ENC_NA, PROTO_CHECKSUM_VERIFY);
170 if (sent_checksum != checksum) {
171 col_append_str(pinfo->cinfo, COL_INFO, " [EPON PREAMBLE CHECKSUM INCORRECT]");
174 /* Do not bother parsing encrypted data, otherwise send the rest on to the
175 * eth dissector.
177 if (dpoe_encrypted) {
178 item = proto_tree_add_item(tree, hf_epon_dpoe_encrypted_data, tvb,
179 6+offset, -1, ENC_NA);
180 expert_add_info(pinfo, item, &ei_epon_dpoe_encrypted_data);
181 col_append_str(pinfo->cinfo, COL_INFO, " [ENCRYPTED]");
182 } else {
183 next_tvb = tvb_new_subset_remaining(tvb, 6+offset);
185 * XXX - is it guaranteed whether the capture will, or won't, have
186 * an FCS?
188 call_dissector(eth_maybefcs_handle, next_tvb, pinfo, tree);
191 return tvb_captured_length(tvb);
194 void
195 proto_register_epon(void)
197 expert_module_t *expert_epon;
199 static hf_register_info hf[] = {
200 { &hf_epon_dpoe_security,
201 { "DPoE security", "epon.dpoe.sec", FT_UINT8, BASE_HEX, NULL, 0x0,
202 "DPoE security octet", HFILL }
204 { &hf_epon_dpoe_reserved,
205 { "Reserved", "epon.dpoe.reserved", FT_UINT8, BASE_DEC, NULL, 0xFC,
206 "Reserved in 1G mode", HFILL }
208 { &hf_epon_dpoe_encrypted,
209 { "Encryption enabled", "epon.dpoe.encrypted", FT_BOOLEAN, 8, NULL, 0x02,
210 "Specifies if this is an encrypted frame", HFILL }
212 { &hf_epon_dpoe_keyid,
213 { "Key ID", "epon.dpoe.keyid", FT_UINT8, BASE_HEX, NULL, 0x01,
214 "Identification number of the key used to encrypt this frame",
215 HFILL }
217 { &hf_epon_dpoe_encrypted_data,
218 { "Encrypted data", "epon.dpoe.encrypted.data", FT_BYTES, BASE_NONE,
219 NULL, 0x0, "DPoE encrypted data", HFILL }
221 { &hf_epon_mode,
222 { "Mode", "epon.mode", FT_BOOLEAN, 16, TFS(&epon_mode_tfs), 0x8000,
223 "Broadcast/multicast if true, unicast if false", HFILL }
225 { &hf_epon_llid,
226 { "LLID", "epon.llid", FT_UINT16, BASE_DEC_HEX, NULL, 0x7FFF,
227 "Logical Link ID", HFILL }
229 { &hf_epon_checksum,
230 { "Frame check sequence", "epon.checksum", FT_UINT8, BASE_HEX, NULL,
231 0x0, "EPON preamble checksum", HFILL }
233 { &hf_epon_checksum_status,
234 { "Frame check sequence Status", "epon.checksum.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals),
235 0x0, NULL, HFILL }
239 static int *ett[] = {
240 &ett_epon,
241 &ett_epon_sec,
242 &ett_epon_checksum
245 /* Setup protocol expert items */
246 static ei_register_info ei[] = {
247 { &ei_epon_checksum_bad,
248 { "epon.checksum_bad.expert", PI_CHECKSUM, PI_ERROR,
249 "Bad checksum", EXPFILL }
251 { &ei_epon_sld_bad,
252 { "epon.sld_bad.expert", PI_MALFORMED, PI_ERROR,
253 "Unable to locate SLD or invalid byte sequence: preamble must start with 0xD555", EXPFILL }
255 { &ei_epon_dpoe_reserved_bad,
256 { "epon.dpoe.encrypted.expert", PI_MALFORMED, PI_ERROR,
257 "Bits 7-2 of DPoE security byte must be 010101 in 1G mode.", EXPFILL }
259 { &ei_epon_dpoe_bad,
260 { "epon.dpoe.expert", PI_MALFORMED, PI_ERROR,
261 "DPoE security byte must be 0x55 if encryption is disabled.", EXPFILL }
263 { &ei_epon_dpoe_encrypted_data,
264 { "epon.dpoe.encrypted.expert", PI_UNDECODED, PI_NOTE,
265 "Remaining data is encrypted and will not decode.", EXPFILL }
269 proto_epon = proto_register_protocol("IEEE 802.3 EPON Preamble",
270 "EPON", "epon");
272 proto_register_field_array(proto_epon, hf, array_length(hf));
273 proto_register_subtree_array(ett, array_length(ett));
275 expert_epon = expert_register_protocol(proto_epon);
276 expert_register_field_array(expert_epon, ei, array_length(ei));
278 epon_handle = register_dissector("epon", dissect_epon, proto_epon);
281 void
282 proto_reg_handoff_epon(void)
284 dissector_add_uint("wtap_encap", WTAP_ENCAP_EPON, epon_handle);
286 eth_maybefcs_handle = find_dissector_add_dependency("eth_maybefcs", proto_epon);
290 * Editor modelines - https://www.wireshark.org/tools/modelines.html
292 * Local Variables:
293 * c-basic-offset: 2
294 * tab-width: 8
295 * indent-tabs-mode: nil
296 * End:
298 * ex: set shiftwidth=2 tabstop=8 expandtab:
299 * :indentSize=2:tabSize=8:noTabs=true: