Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-cesoeth.c
blobc65242420f05a90ff0f9c02462ee7074195dcb67
1 /* packet-cesoeth.c
2 * Dissection of Circuit Emulation Service over Ethernet (MEF 8)
3 * www.mef.net
5 * Copyright 2018, AimValley B.V.
6 * Jaap Keuter <jkeuter@aimvalley.nl>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include "config.h"
17 #include <epan/packet.h>
18 #include <epan/prefs.h>
19 #include <epan/expert.h>
20 #include <epan/etypes.h>
21 #include "packet-rtp.h"
23 void proto_register_cesoeth(void);
24 void proto_reg_handoff_cesoeth(void);
26 static dissector_handle_t cesoeth_handle;
28 static int proto_cesoeth;
29 static int hf_cesoeth_pw_ecid;
30 static int hf_cesoeth_pw_res;
31 static int hf_cesoeth_cw;
32 static int hf_cesoeth_cw_reserved1;
33 static int hf_cesoeth_cw_l;
34 static int hf_cesoeth_cw_r;
35 static int hf_cesoeth_cw_l0_m;
36 static int hf_cesoeth_cw_l1_m;
37 static int hf_cesoeth_cw_frg;
38 static int hf_cesoeth_cw_len;
39 static int hf_cesoeth_cw_seq;
40 static int hf_cesoeth_padding;
42 static int ett_cesoeth;
43 static int ett_cesoeth_cw;
45 static expert_field ei_cesoeth_reserved;
46 static expert_field ei_cesoeth_length;
48 static int* const cesoeth_l0_cw[] =
50 &hf_cesoeth_cw_reserved1,
51 &hf_cesoeth_cw_l,
52 &hf_cesoeth_cw_r,
53 &hf_cesoeth_cw_l0_m,
54 &hf_cesoeth_cw_frg,
55 &hf_cesoeth_cw_len,
56 &hf_cesoeth_cw_seq,
57 NULL
60 static int* const cesoeth_l1_cw[] =
62 &hf_cesoeth_cw_reserved1,
63 &hf_cesoeth_cw_l,
64 &hf_cesoeth_cw_r,
65 &hf_cesoeth_cw_l1_m,
66 &hf_cesoeth_cw_frg,
67 &hf_cesoeth_cw_len,
68 &hf_cesoeth_cw_seq,
69 NULL
72 static const value_string frg_names[] =
74 { 0, "No fragmentation" },
75 { 1, "First fragment" },
76 { 2, "Last fragment" },
77 { 3, "Intermediate fragment" },
78 { 0, NULL }
81 static const value_string l0_m_names[] =
83 { 0, "No local TDM defect" },
84 { 1, "Reserved" },
85 { 2, "RDI on TDM input" },
86 { 3, "Non-TDM data" },
87 { 0, NULL }
90 static const value_string l1_m_names[] =
92 { 0, "TDM defect" },
93 { 1, "Reserved" },
94 { 2, "Reserved" },
95 { 3, "Reserved" },
96 { 0, NULL }
99 /* Preferences */
100 static bool has_rtp_header;
101 static bool heuristic_rtp_header = true;
104 static int
105 dissect_cesoeth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
107 proto_tree *cesoeth_tree;
108 proto_item *cesoeth_ti;
109 proto_item *bitmask_ti;
110 int offset = 0;
111 uint32_t ecid, reserved;
112 bool l_bit, r_bit;
113 uint8_t m_bits, frg;
114 int cw_len, padding_len, tail_len, payload_len;
115 uint16_t sn;
116 tvbuff_t *next_tvb;
118 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CESoETH");
119 col_clear(pinfo->cinfo, COL_INFO);
121 cesoeth_ti = proto_tree_add_item(tree, proto_cesoeth, tvb, 0, -1, ENC_NA);
122 cesoeth_tree = proto_item_add_subtree(cesoeth_ti, ett_cesoeth);
124 proto_tree_add_item_ret_uint(cesoeth_tree, hf_cesoeth_pw_ecid, tvb, offset, 4, ENC_BIG_ENDIAN, &ecid);
125 col_append_fstr(pinfo->cinfo, COL_INFO, "ECID: 0x%05x", ecid);
126 bitmask_ti = proto_tree_add_item_ret_uint(cesoeth_tree, hf_cesoeth_pw_res, tvb, offset, 4, ENC_BIG_ENDIAN, &reserved);
127 if (reserved != 0x102)
128 expert_add_info_format(pinfo, bitmask_ti, &ei_cesoeth_reserved, "Reserved field must be 0x102");
129 offset += 4;
132 * CES header control word
134 * bits name description
135 * 31-28 reserved set to 0
136 * 27 L-bit set to 1 to indicate local TDM failure
137 * 26 R-bit set to 1 to indicate remote loss of frame
138 * 25-24 M-bits modifier bits
139 * 23-22 FRG bits fragmentation bits
140 * 21-16 length length (0 if no padding applied)
141 * 15-0 sequence sequence number
144 l_bit = (tvb_get_uint8(tvb, offset) & 0x08) ? true : false;
145 r_bit = (tvb_get_uint8(tvb, offset) & 0x04) ? true : false;
146 m_bits = (tvb_get_uint8(tvb, offset) & 0x03);
147 frg = tvb_get_bits8(tvb, 40, 2);
148 cw_len = tvb_get_bits8(tvb, 42, 6);
149 sn = tvb_get_ntohs(tvb, offset + 2);
151 col_append_fstr(pinfo->cinfo, COL_INFO, ", SN: %u", sn);
153 if (l_bit)
155 bitmask_ti = proto_tree_add_bitmask(cesoeth_tree, tvb, offset, hf_cesoeth_cw, ett_cesoeth_cw, cesoeth_l1_cw, ENC_NA);
156 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s", val_to_str_const(m_bits, l1_m_names, "Unknown"));
157 } else {
158 bitmask_ti = proto_tree_add_bitmask(cesoeth_tree, tvb, offset, hf_cesoeth_cw, ett_cesoeth_cw, cesoeth_l0_cw, ENC_NA);
159 if (m_bits)
160 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s", val_to_str_const(m_bits, l0_m_names, "Unknown"));
163 if (cw_len >= 42)
166 * Now we have to go spelunking in the bitmask tree for the length item
167 * in order to add an expert item to it.
169 proto_tree *bm_tree = proto_item_get_subtree(bitmask_ti);
170 if (bm_tree) {
171 proto_item *pi;
173 for (pi = tree->first_child; pi; pi = pi->next)
175 field_info *fi;
176 fi = PITEM_FINFO(pi);
177 if (fi && (fi->hfinfo->id == hf_cesoeth_cw_len))
178 break;
181 expert_add_info_format(pinfo, pi, &ei_cesoeth_length, "Length can not be 42 or larger");
184 cw_len = 0; /* Put a stop to this madness */
187 if (r_bit)
188 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Remote loss of frame");
190 if (frg)
191 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s", val_to_str_const(frg, frg_names, "Unknown"));
193 offset += 4;
196 * When L is set the TDM payload MAY be missing.
197 * But also when snap value is used on capture.
198 * Will the optional RTP header be there when the TDM payload is missing? I guess so.
199 * Length includes the size of the CW (being 4), the optional RTP header (being 12) and
200 * the TDM payload, as long as it doesn't exceed 42 octets. Length > 0 indicates padding,
201 * which must NOT be passed to the RTP dissector, it's not RTP padding.
204 padding_len = (cw_len > 0) ? (42 - cw_len) : 0;
205 tail_len = tvb_reported_length_remaining(tvb, offset);
206 payload_len = tail_len - padding_len;
208 if (payload_len > 0)
210 next_tvb = tvb_new_subset_length(tvb, offset, payload_len);
212 if ((has_rtp_header) ||
213 ((heuristic_rtp_header) &&
214 /* Check for RTP version 2, the other fields must be zero */
215 (tvb_get_uint8(tvb, offset) == 0x80) &&
216 /* Check the marker is zero. Unfortunately PT is not always from the dynamic range */
217 ((tvb_get_uint8(tvb, offset + 1) & 0x80) == 0) &&
218 /* The sequence numbers from cw and RTP header must match */
219 (tvb_get_ntohs(tvb, offset + 2) == sn)))
221 struct _rtp_info rtp_info;
223 int rtp_header_len = dissect_rtp_shim_header(tvb, offset, pinfo, cesoeth_tree, &rtp_info);
225 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CESoETH (w RTP)");
226 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "RTP PT: %u, SSRC: 0x%X, Seq: %u, Time=%u",
227 rtp_info.info_payload_type,
228 rtp_info.info_sync_src,
229 rtp_info.info_seq_num,
230 rtp_info.info_timestamp
233 next_tvb = tvb_new_subset_length(tvb, offset + rtp_header_len, payload_len - rtp_header_len);
236 call_data_dissector(next_tvb, pinfo, tree);
238 offset += payload_len;
241 if (padding_len > 0)
243 proto_tree_add_item(cesoeth_tree, hf_cesoeth_padding, tvb, offset, padding_len, ENC_NA);
245 offset += padding_len;
248 return offset;
251 void
252 proto_register_cesoeth(void)
254 static hf_register_info hf[] = {
255 { &hf_cesoeth_pw_ecid,
256 { "ECID", "cesoeth.ecid", FT_UINT32, BASE_HEX,
257 NULL, 0xFFFFF000, NULL, HFILL }},
258 { &hf_cesoeth_pw_res,
259 { "Reserved", "cesoeth.res", FT_UINT32, BASE_HEX,
260 NULL, 0x00000FFF, "Reserved (0x102)", HFILL }},
262 { &hf_cesoeth_cw,
263 { "Control word", "cesoeth.cw", FT_UINT32, BASE_HEX,
264 NULL, 0x0, NULL, HFILL }},
266 { &hf_cesoeth_cw_reserved1,
267 { "Reserved", "cesoeth.cw.reserved", FT_UINT32, BASE_HEX,
268 NULL, 0xF0000000, NULL, HFILL }},
269 { &hf_cesoeth_cw_l,
270 { "L-bit", "cesoeth.cw.l", FT_BOOLEAN, 32,
271 NULL, 0x08000000, "Local TDM failure", HFILL }},
272 { &hf_cesoeth_cw_r,
273 { "R-bit", "cesoeth.cw.r", FT_BOOLEAN, 32,
274 NULL, 0x04000000, "Remote Loss of Frames indication", HFILL }},
275 { &hf_cesoeth_cw_l0_m,
276 { "M-bits", "cesoeth.cw.m", FT_UINT32, BASE_HEX,
277 VALS(l0_m_names), 0x03000000, "Modifier bits", HFILL }},
278 { &hf_cesoeth_cw_l1_m,
279 { "M-bits", "cesoeth.cw.m", FT_UINT32, BASE_HEX,
280 VALS(l1_m_names), 0x03000000, "Modifier bits", HFILL }},
281 { &hf_cesoeth_cw_frg,
282 { "Frg", "cesoeth.cw.frg", FT_UINT32, BASE_HEX,
283 VALS(frg_names), 0x00C00000, "Fragmentation bits", HFILL }},
284 { &hf_cesoeth_cw_len,
285 { "Len", "cesoeth.cw.len", FT_UINT32, BASE_DEC,
286 NULL, 0x003F0000, "Length", HFILL }},
287 { &hf_cesoeth_cw_seq,
288 { "SN", "cesoeth.cw.sn", FT_UINT32, BASE_DEC,
289 NULL, 0x0000FFFF, "Sequence number", HFILL }},
291 { &hf_cesoeth_padding,
292 { "Padding", "cesoeth.padding", FT_BYTES, BASE_NONE,
293 NULL, 0x0, NULL, HFILL }}
296 static int *ett[] = {
297 &ett_cesoeth,
298 &ett_cesoeth_cw
301 static ei_register_info ei[] = {
302 { &ei_cesoeth_reserved,
303 { "cesoeth.reserved", PI_PROTOCOL, PI_WARN,
304 "Reserved field", EXPFILL }},
305 { &ei_cesoeth_length,
306 { "cesoeth.length", PI_PROTOCOL, PI_WARN,
307 "Length field", EXPFILL }}
310 module_t *cesoeth_module;
311 expert_module_t* expert_cesoeth;
313 proto_cesoeth = proto_register_protocol("Circuit Emulation Service over Ethernet", "CESoETH", "cesoeth");
314 proto_register_field_array(proto_cesoeth, hf, array_length(hf));
315 proto_register_subtree_array(ett, array_length(ett));
316 expert_cesoeth = expert_register_protocol(proto_cesoeth);
317 expert_register_field_array(expert_cesoeth, ei, array_length(ei));
319 cesoeth_module = prefs_register_protocol(proto_cesoeth, NULL);
321 prefs_register_bool_preference(cesoeth_module, "rtp_header", "RTP header in CES payload",
322 "Whether or not the RTP header is present in the CES payload.", &has_rtp_header);
324 prefs_register_bool_preference(cesoeth_module, "rtp_header_heuristic", "Try to find RTP header in CES payload",
325 "Heuristically determine if an RTP header is present in the CES payload.", &heuristic_rtp_header);
328 cesoeth_handle = register_dissector("cesoeth", dissect_cesoeth, proto_cesoeth);
331 void
332 proto_reg_handoff_cesoeth(void)
334 dissector_add_uint("ethertype", ETHERTYPE_CESOETH, cesoeth_handle);
338 * Editor modelines - https://www.wireshark.org/tools/modelines.html
340 * Local variables:
341 * c-basic-offset: 4
342 * tab-width: 8
343 * indent-tabs-mode: nil
344 * End:
346 * vi: set shiftwidth=4 tabstop=8 expandtab:
347 * :indentSize=4:tabSize=8:noTabs=true: