Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-caneth.c
blob6433cc6886d934953e0cd3c45ef3a955f000395e
1 /* packet-caneth.c
2 * Routines for Controller Area Network over Ethernet dissection
3 * Copyright 2018, Lazar Sumar <bugzilla@lazar.co.nz>
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
13 * The CAN-ETH protocol is used for transmitting the Controller Area Network
14 * (CAN) protocol over UDP.
16 * The protocol definition can be found at http://www.proconx.com/assets/files/products/caneth/canframe.pdf
19 #include <config.h>
21 #include <epan/packet.h>
22 #include "packet-udp.h"
23 #include "packet-socketcan.h"
25 #define CAN_FRAME_LEN 15
27 #define CAN_ID_OFFSET 0
28 #define CAN_DLC_OFFSET 4
29 #define CAN_DATA_OFFSET 5
30 #define CAN_EXT_FLAG_OFFSET 13
31 #define CAN_RTR_FLAG_OFFSET 14
33 static const char magic[] = "ISO11898";
35 void proto_reg_handoff_caneth(void);
36 void proto_register_caneth(void);
38 static dissector_handle_t caneth_handle;
40 static int proto_caneth;
41 static int hf_caneth_magic;
42 static int hf_caneth_version;
43 static int hf_caneth_frames;
44 static int hf_caneth_options;
46 static int hf_caneth_can_ident_ext;
47 static int hf_caneth_can_ident_std;
48 static int hf_caneth_can_extflag;
49 static int hf_caneth_can_rtrflag;
50 static int hf_caneth_can_len;
51 static int hf_caneth_can_padding;
53 #define CANETH_UDP_PORT 11898
55 static int ett_caneth;
56 static int ett_caneth_frames;
57 static int ett_caneth_can;
59 static int proto_can; // use CAN protocol for consistent filtering
61 /* A sample #define of the minimum length (in bytes) of the protocol data.
62 * If data is received with fewer than this many bytes it is rejected by
63 * the current dissector. */
64 #define CANETH_MIN_LENGTH 10
66 static bool
67 test_caneth(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
69 /* Check that we have enough length for the Magic, Version, and Length */
70 if (tvb_reported_length(tvb) < CANETH_MIN_LENGTH)
71 return false;
72 /* Check that the magic id matches */
73 if (tvb_strneql(tvb, offset, magic, 8) != 0)
74 return false;
75 /* Check that the version is 1 as that is the only supported version */
76 if (tvb_get_uint8(tvb, offset+8) != 1)
77 return false;
78 /* Check that the version 1 limit of 16 can frames is respected */
79 if (tvb_get_uint8(tvb, offset+9) > 16)
80 return false;
81 return true;
84 static unsigned
85 get_caneth_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
87 return (unsigned) tvb_get_ntohs(tvb, offset+3);
90 static int
91 dissect_caneth_can(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
93 proto_tree *can_tree;
94 proto_item *ti;
95 uint32_t raw_can_id;
96 int8_t ext_flag;
97 int8_t rtr_flag;
98 tvbuff_t* next_tvb;
99 struct can_info can_info;
101 ti = proto_tree_add_item(tree, proto_can, tvb, 0, -1, ENC_NA);
102 can_tree = proto_item_add_subtree(ti, ett_caneth_can);
104 ext_flag = tvb_get_uint8(tvb, CAN_EXT_FLAG_OFFSET);
105 rtr_flag = tvb_get_uint8(tvb, CAN_RTR_FLAG_OFFSET);
107 if (ext_flag)
109 proto_tree_add_item_ret_uint(can_tree, hf_caneth_can_ident_ext, tvb, CAN_ID_OFFSET, 4, ENC_LITTLE_ENDIAN, &raw_can_id);
110 can_info.id = raw_can_id & CAN_EFF_MASK;
112 else
114 proto_tree_add_item_ret_uint(can_tree, hf_caneth_can_ident_std, tvb, CAN_ID_OFFSET, 4, ENC_LITTLE_ENDIAN, &raw_can_id);
115 can_info.id = raw_can_id & CAN_SFF_MASK;
118 can_info.id |= (ext_flag ? CAN_EFF_FLAG : 0) | (rtr_flag ? CAN_RTR_FLAG : 0);
119 can_info.fd = CAN_TYPE_CAN_CLASSIC;
120 can_info.bus_id = 0; /* see get_bus_id in packet-socketcan.c? */
122 proto_tree_add_item_ret_uint(can_tree, hf_caneth_can_len, tvb, CAN_DLC_OFFSET, 1, ENC_NA, &can_info.len);
123 proto_tree_add_item(can_tree, hf_caneth_can_extflag, tvb, CAN_EXT_FLAG_OFFSET, 1, ENC_NA);
124 proto_tree_add_item(can_tree, hf_caneth_can_rtrflag, tvb, CAN_RTR_FLAG_OFFSET, 1, ENC_NA);
126 next_tvb = tvb_new_subset_length(tvb, CAN_DATA_OFFSET, can_info.len);
128 if (!socketcan_call_subdissectors(next_tvb, pinfo, tree, &can_info, false)) {
129 call_data_dissector(next_tvb, pinfo, tree);
132 if (tvb_captured_length_remaining(tvb, CAN_DATA_OFFSET + can_info.len) > 0)
134 proto_tree_add_item(can_tree, hf_caneth_can_padding, tvb, CAN_DATA_OFFSET + can_info.len, -1, ENC_NA);
136 return tvb_captured_length(tvb);
139 static int
140 dissect_caneth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
142 proto_tree *caneth_tree;
143 proto_item *ti;
144 uint32_t frame_count, offset;
145 tvbuff_t* next_tvb;
147 if (!test_caneth(pinfo, tvb, 0, data))
148 return 0;
150 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CAN-ETH");
151 col_clear(pinfo->cinfo, COL_INFO);
153 ti = proto_tree_add_item(tree, proto_caneth, tvb, 0, -1, ENC_NA);
154 caneth_tree = proto_item_add_subtree(ti, ett_caneth);
156 proto_tree_add_item(caneth_tree, hf_caneth_magic, tvb, 0, 8, ENC_ASCII);
157 proto_tree_add_item(caneth_tree, hf_caneth_version, tvb, 8, 1, ENC_NA);
158 proto_tree_add_item_ret_uint(caneth_tree, hf_caneth_frames, tvb, 9, 1, ENC_NA, &frame_count);
160 for (offset = 10; frame_count-- > 0; offset += CAN_FRAME_LEN)
162 next_tvb = tvb_new_subset_length(tvb, offset, CAN_FRAME_LEN);
163 dissect_caneth_can(next_tvb, pinfo, tree, data);
166 if (tvb_captured_length_remaining(tvb, offset) > 0)
168 proto_tree_add_item(caneth_tree, hf_caneth_options, tvb, offset, -1, ENC_NA);
171 return tvb_captured_length(tvb);
174 static bool
175 dissect_caneth_heur_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
177 return (udp_dissect_pdus(tvb, pinfo, tree, CANETH_MIN_LENGTH, test_caneth,
178 get_caneth_len, dissect_caneth, data) != 0);
181 void
182 proto_register_caneth(void)
184 static hf_register_info hf[] = {
186 &hf_caneth_magic,
188 "Magic", "caneth.magic",
189 FT_STRING, BASE_NONE,
190 NULL, 0x0,
191 "The magic identifier used to denote the start of a CAN-ETH packet", HFILL
195 &hf_caneth_version,
197 "Version", "caneth.version",
198 FT_UINT8, BASE_DEC,
199 NULL, 0x0,
200 NULL, HFILL
204 &hf_caneth_frames,
206 "CAN Frames", "caneth.frames",
207 FT_UINT8, BASE_DEC,
208 NULL, 0x0,
209 "Number of enclosed CAN frames", HFILL
213 &hf_caneth_options,
215 "Options (Reserved)", "caneth.options",
216 FT_BYTES, BASE_NONE,
217 NULL, 0x0,
218 "Options field, reserved for future use, should be empty", HFILL
222 &hf_caneth_can_ident_ext,
224 "Identifier", "can.id",
225 FT_UINT32, BASE_HEX,
226 NULL, CAN_EFF_MASK,
227 NULL, HFILL
231 &hf_caneth_can_ident_std,
233 "Identifier", "can.id",
234 FT_UINT32, BASE_HEX,
235 NULL, CAN_SFF_MASK,
236 NULL, HFILL
240 &hf_caneth_can_extflag,
242 "Extended Flag", "can.flags.xtd",
243 FT_BOOLEAN, BASE_NONE,
244 NULL, 0,
245 NULL, HFILL
249 &hf_caneth_can_rtrflag,
251 "Remote Transmission Request Flag", "can.flags.rtr",
252 FT_BOOLEAN, BASE_NONE,
253 NULL, 0,
254 NULL, HFILL
258 &hf_caneth_can_len,
260 "Frame-Length", "can.len",
261 FT_UINT8, BASE_DEC,
262 NULL, 0x0,
263 NULL, HFILL
267 &hf_caneth_can_padding,
269 "Padding", "caneth.can.padding",
270 FT_BYTES, BASE_NONE,
271 NULL, 0x0,
272 NULL, HFILL
277 static int *ett[] = {
278 &ett_caneth,
279 &ett_caneth_frames,
280 &ett_caneth_can,
283 proto_caneth = proto_register_protocol("Controller Area Network over Ethernet", "CAN-ETH", "caneth");
285 proto_register_field_array(proto_caneth, hf, array_length(hf));
286 proto_register_subtree_array(ett, array_length(ett));
288 caneth_handle = register_dissector("caneth", dissect_caneth, proto_caneth);
291 void
292 proto_reg_handoff_caneth(void)
294 dissector_add_uint_with_preference("udp.port", CANETH_UDP_PORT, caneth_handle);
296 heur_dissector_add("udp", dissect_caneth_heur_udp, "CAN-ETH over UDP", "caneth_udp", proto_caneth, HEURISTIC_ENABLE);
298 proto_can = proto_get_id_by_filter_name("can");
302 * Editor modelines - https://www.wireshark.org/tools/modelines.html
304 * Local variables:
305 * c-basic-offset: 4
306 * tab-width: 8
307 * indent-tabs-mode: nil
308 * End:
310 * vi: set shiftwidth=4 tabstop=8 expandtab:
311 * :indentSize=4:tabSize=8:noTabs=true: