2 * Routines for CableLabs Layer-3 Protocol Dissection
3 * Copyright 2019 Jon Dennis <j.dennis[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
11 * Dissector for IEEE-Registered CableLabs EtherType 0xB4E3
14 * http://standards-oui.ieee.org/ethertype/eth.txt
16 * CableLabs Specifications Can Be Found At:
17 * https://www.cablelabs.com/specs
18 * Note: As of writing this, the spec is in the process of being published.
19 * Initially, this will be published under the Dual Channel Wi-Fi spec,
20 * but may split off into its own spec in the future.
21 * Eventually a direct link to the spec should be put here.
25 #include <epan/packet.h>
26 #include <epan/expert.h>
28 #include <epan/etypes.h>
30 #include <wsutil/str_util.h>
33 void proto_register_cl3(void);
34 void proto_reg_handoff_cl3(void);
36 static dissector_handle_t cl3_handle
;
38 /* persistent handles for this dissector */
40 static dissector_table_t cl3_command_table
;
42 static int hf_cl3_version
;
43 static int hf_cl3_headerlen
;
44 static int hf_cl3_subproto
;
45 static int hf_cl3_payload
;
46 static expert_field ei_cl3_badheaderlen
;
47 static expert_field ei_cl3_unsup_ver
;
50 /* Known CL3 (sub-)protocol type strings: */
51 static const value_string cl3_protocols
[] = {
52 {0x00DC, "Dual-Channel Wi-Fi Messaging" },
57 /* called for each incoming framing matching the CL3 ethertype with a version number of 1: */
65 uint16_t header_length
68 dissector_handle_t dh
;
71 uint16_t subprotocol_id
;
73 /* ensure the header length is valid for version 1 */
74 if (header_length
!= 4) {
75 expert_add_info(pinfo
, ti
, &ei_cl3_badheaderlen
);
78 /* parse the sub-protocol id */
79 subprotocol_id
= tvb_get_ntohs(tvb
, 2);
81 /* append the subprotocol id to the "packet summary view" fields */
82 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "[Subprotocol 0x%04X]", (unsigned)subprotocol_id
);
84 /* add elements to the CL3 tree...
85 CL3 version 1 fields: (pretty much just the sub protocol id) */
86 proto_tree_add_uint(cl3_tree
, hf_cl3_subproto
, tvb
, 2, 2, subprotocol_id
);
88 /* call CL (sub-)protocol dissector */
89 dh
= dissector_get_uint_handle(cl3_command_table
, subprotocol_id
);
91 tvb_sub
= tvb_new_subset_remaining(tvb
, header_length
);
92 call_dissector(dh
, tvb_sub
, pinfo
, tree
);
96 /* called for each incoming framing matching the CL3 ethertype: */
98 dissect_cl3(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
) {
101 proto_tree
*cl3_tree
;
104 uint16_t header_length
;
105 uint32_t payload_length
;
107 /* parse the header fields */
108 version
= header_length
= tvb_get_ntohs(tvb
, 0);
111 header_length
&= 0x0F;
113 payload_length
= tvb_captured_length(tvb
) - header_length
;
115 /* setup the "packet summary view" fields */
116 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CL3");
117 col_clear(pinfo
->cinfo
, COL_INFO
);
118 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "CableLabs Layer-3 Protocol (Ver %u)", (unsigned)version
);
120 /* create a tree node for us... */
121 ti
= proto_tree_add_protocol_format(tree
, proto_cl3
, tvb
, 0, header_length
, "CableLabs Layer-3 Protocol (CL3) Version %u", (unsigned)version
);
122 cl3_tree
= proto_item_add_subtree(ti
, ett_cl3
);
124 /* CL3 version agnostic fields: (pretty much just the first byte; like ipv4, version + length) */
125 proto_tree_add_item(cl3_tree
, hf_cl3_version
, tvb
, 0, 1, ENC_NA
);
126 proto_tree_add_uint_bits_format_value(cl3_tree
, hf_cl3_headerlen
, tvb
, 0 + 4, 4, header_length
,
127 ENC_BIG_ENDIAN
, "%u bytes (%u)", header_length
, header_length
>> 2);
129 /* validate the header length... */
130 if ((header_length
< 1) || (header_length
> tvb_captured_length(tvb
))) {
131 expert_add_info(pinfo
, ti
, &ei_cl3_badheaderlen
);
134 /* version-specific dissection... */
137 dissect_cl3_v1(tvb
, pinfo
, tree
, ti
, cl3_tree
, header_length
);
140 expert_add_info(pinfo
, ti
, &ei_cl3_unsup_ver
);
144 /* add a byte reference to the payload we are carrying */
145 proto_tree_add_item(cl3_tree
, hf_cl3_payload
, tvb
, header_length
, payload_length
, ENC_NA
);
147 return tvb_captured_length(tvb
);
151 /* initializes this dissector */
153 proto_register_cl3(void) {
154 static hf_register_info hf
[] = {
156 { "Version", "cl3.version",
157 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
158 "The CableLabs layer-3 protocol version number", HFILL
}},
160 { "Header Length", "cl3.headerlen",
161 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
162 "The length of the CableLabs layer-3 protocol header", HFILL
}},
164 { "Subprotocol", "cl3.subprotocol",
165 FT_UINT16
, BASE_HEX
, VALS(cl3_protocols
), 0x0,
166 "The subprotocol number the CableLabs layer-3 protocol is carrying", HFILL
}},
168 { "CL3 Payload", "cl3.payload",
169 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
170 "The payload carried by this CableLabs layer-3 protocol packet", HFILL
}},
172 static int *ett
[] = {
175 static ei_register_info ei
[] = {
176 { &ei_cl3_badheaderlen
, { "cl3.badheaderlen", PI_MALFORMED
, PI_ERROR
, "Bad Header Length", EXPFILL
}},
177 { &ei_cl3_unsup_ver
, { "cl3.unsup_ver", PI_UNDECODED
, PI_WARN
, "Unknown protocol version", EXPFILL
}},
180 expert_module_t
* expert_cl3
;
182 proto_cl3
= proto_register_protocol("CableLabs Layer 3 Protocol", "CL3", "cl3");
184 proto_register_field_array(proto_cl3
, hf
, array_length(hf
));
185 proto_register_subtree_array(ett
, array_length(ett
));
186 expert_cl3
= expert_register_protocol(proto_cl3
);
187 expert_register_field_array(expert_cl3
, ei
, array_length(ei
));
189 /* register the dissector */
190 cl3_handle
= register_dissector("cl3", &dissect_cl3
, proto_cl3
);
192 /* subdissector code... */
193 cl3_command_table
= register_dissector_table("cl3.subprotocol", "CableLabs Subprotocol", proto_cl3
, FT_UINT16
, BASE_DEC
);
196 /* hooks in our dissector to be called on matching ethertype */
198 proto_reg_handoff_cl3(void) {
199 dissector_add_uint("ethertype", ETHERTYPE_CABLELABS
, cl3_handle
);
203 * Editor modelines - https://www.wireshark.org/tools/modelines.html
208 * indent-tabs-mode: nil
211 * vi: set shiftwidth=2 tabstop=8 expandtab:
212 * :indentSize=2:tabSize=8:noTabs=true: