/src/wireshark/epan/dissectors/packet-busmirroring.c
Line | Count | Source |
1 | | /* packet-busmirroring.c |
2 | | * Routines for BusMirroring protocol packet disassembly |
3 | | * Copyright 2023, Haiyun Liu <liu0hy@gmail.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | |
11 | | * Bus Mirroring is an AUTOSAR Basic Software module. Its purpose is the replication of |
12 | | * the traffic and the state of internal buses to an external bus, such that a tester |
13 | | * connected to that external bus can monitor internal buses for debugging purposes. |
14 | | * When mirroring to an IP destination bus like Ethernet, the Bus Mirroring module applies |
15 | | * a protocol to pack several smaller frames (e.g. CAN, LIN or FlexRay) into one large |
16 | | * frame of the destination bus. |
17 | | * For more information, see AUTOSAR "Specification of Bus Mirroring", Section 7.4 |
18 | | * "Mirroring to FlexRay, IP, and CDD": |
19 | | * https://www.autosar.org/fileadmin/standards/R22-11/CP/AUTOSAR_SWS_BusMirroring.pdf |
20 | | */ |
21 | | |
22 | | #include "config.h" |
23 | | #include <epan/packet.h> |
24 | | #include <epan/expert.h> |
25 | | #include <epan/tfs.h> |
26 | | |
27 | 16 | #define BUSMIRRORING_UDP_PORT 30511 |
28 | | |
29 | | enum network_type |
30 | | { |
31 | | NETWORK_TYPE_INVALID = 0x00, |
32 | | NETWORK_TYPE_CAN = 0x01, |
33 | | NETWORK_TYPE_LIN = 0x02, |
34 | | NETWORK_TYPE_FLEXRAY = 0x03, |
35 | | NETWORK_TYPE_ETHERNET = 0x04 |
36 | | }; |
37 | | |
38 | | static int proto_busmirroring; |
39 | | static int hf_protocol_version; |
40 | | static int hf_sequence_number; |
41 | | static int hf_header_timestamp; |
42 | | static int hf_seconds; |
43 | | static int hf_nanoseconds; |
44 | | static int hf_data_length; |
45 | | static int hf_timestamp; |
46 | | static int hf_network_state_available; |
47 | | static int hf_frame_id_available; |
48 | | static int hf_payload_available; |
49 | | static int hf_network_type; |
50 | | static int hf_frames_lost; |
51 | | static int hf_bus_online; |
52 | | static int hf_can_error_passive; |
53 | | static int hf_can_bus_off; |
54 | | static int hf_can_tx_error_count; |
55 | | static int hf_lin_header_tx_error; |
56 | | static int hf_lin_tx_error; |
57 | | static int hf_lin_rx_error; |
58 | | static int hf_lin_rx_no_response; |
59 | | static int hf_flexray_bus_synchronous; |
60 | | static int hf_flexray_normal_active; |
61 | | static int hf_flexray_syntax_error; |
62 | | static int hf_flexray_content_error; |
63 | | static int hf_flexray_boundary_violation; |
64 | | static int hf_flexray_tx_conflict; |
65 | | static int hf_network_id; |
66 | | static int hf_network_state; |
67 | | static int hf_frame_id; |
68 | | static int hf_can_id_type; |
69 | | static int hf_can_frame_type; |
70 | | static int hf_can_id; |
71 | | static int hf_lin_pid; |
72 | | static int hf_flexray_channel_b; |
73 | | static int hf_flexray_channel_a; |
74 | | static int hf_flexray_slot_valid; |
75 | | static int hf_flexray_slot_id; |
76 | | static int hf_flexray_cycle; |
77 | | static int hf_payload_length; |
78 | | static int hf_payload; |
79 | | static int ett_busmirroring; |
80 | | static int ett_header_timestamp; |
81 | | static int ett_data_item; |
82 | | static int ett_network_state; |
83 | | static int ett_frame_id; |
84 | | static expert_field ei_data_incomplete; |
85 | | static expert_field ei_data_item_incomplete; |
86 | | static expert_field ei_network_type_invalid; |
87 | | static expert_field ei_can_id_invalid; |
88 | | static expert_field ei_lin_pid_invalid; |
89 | | static expert_field ei_can_length_invalid; |
90 | | static expert_field ei_lin_length_invalid; |
91 | | |
92 | | static const uint8_t pid_table[] = { |
93 | | 0x80, 0xC1, 0x42, 0x03, 0xC4, 0x85, 0x06, 0x47, |
94 | | 0x08, 0x49, 0xCA, 0x8B, 0x4C, 0x0D, 0x8E, 0xCF, |
95 | | 0x50, 0x11, 0x92, 0xD3, 0x14, 0x55, 0xD6, 0x97, |
96 | | 0xD8, 0x99, 0x1A, 0x5B, 0x9C, 0xDD, 0x5E, 0x1F, |
97 | | 0x20, 0x61, 0xE2, 0xA3, 0x64, 0x25, 0xA6, 0xE7, |
98 | | 0xA8, 0xE9, 0x6A, 0x2B, 0xEC, 0xAD, 0x2E, 0x6F, |
99 | | 0xF0, 0xB1, 0x32, 0x73, 0xB4, 0xF5, 0x76, 0x37, |
100 | | 0x78, 0x39, 0xBA, 0xFB, 0x3C, 0x7D, 0xFE, 0xBF |
101 | | }; |
102 | | |
103 | 181 | static bool is_lin_pid_valid(uint8_t pid) { |
104 | 181 | return pid == pid_table[pid & 0x3F]; |
105 | 181 | } |
106 | | |
107 | | static int |
108 | | dissect_busmirroring(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) |
109 | 124 | { |
110 | 124 | static const uint32_t header_size = 14; |
111 | 124 | uint32_t buffer_length = tvb_captured_length(tvb); |
112 | 124 | if (buffer_length < header_size) |
113 | 1 | { |
114 | 1 | return 0; |
115 | 1 | } |
116 | 123 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "BUSMIRRORING"); |
117 | | |
118 | 123 | proto_item *ti = proto_tree_add_item(tree, proto_busmirroring, tvb, 0, -1, ENC_NA); |
119 | 123 | proto_tree *busmirroring_tree = proto_item_add_subtree(ti, ett_busmirroring); |
120 | 123 | proto_tree_add_item(busmirroring_tree, hf_protocol_version, tvb, 0, 1, ENC_BIG_ENDIAN); |
121 | 123 | proto_tree_add_item(busmirroring_tree, hf_sequence_number, tvb, 1, 1, ENC_BIG_ENDIAN); |
122 | 123 | nstime_t header_timestamp = {0, 0}; |
123 | 123 | header_timestamp.secs = tvb_get_uint48(tvb, 2, ENC_BIG_ENDIAN); |
124 | 123 | header_timestamp.nsecs = tvb_get_uint32(tvb, 8, ENC_BIG_ENDIAN); |
125 | 123 | proto_item *ht_item = proto_tree_add_time(busmirroring_tree, hf_header_timestamp, tvb, 2, 10, &header_timestamp); |
126 | 123 | proto_tree *ht_tree = proto_item_add_subtree(ht_item, ett_header_timestamp); |
127 | 123 | proto_tree_add_item(ht_tree, hf_seconds, tvb, 2, 6, ENC_BIG_ENDIAN); |
128 | 123 | proto_tree_add_item(ht_tree, hf_nanoseconds, tvb, 8, 4, ENC_BIG_ENDIAN); |
129 | 123 | uint32_t data_length = 0; |
130 | 123 | proto_tree_add_item_ret_uint(busmirroring_tree, hf_data_length, tvb, 12, 2, ENC_BIG_ENDIAN, &data_length); |
131 | 123 | if (header_size + data_length > buffer_length) { |
132 | 94 | expert_add_info(pinfo, ti, &ei_data_incomplete); |
133 | 94 | } |
134 | | |
135 | 123 | int data_item_index = 0; |
136 | 123 | uint32_t offset = header_size; |
137 | 2.67k | while (offset < buffer_length) |
138 | 2.65k | { |
139 | 2.65k | int data_item_start = offset; |
140 | 2.65k | proto_item *data_item = proto_tree_add_item(busmirroring_tree, proto_busmirroring, tvb, offset, 0, ENC_NA); |
141 | 2.65k | proto_item_set_text(data_item, "Data Item #%d", data_item_index); |
142 | 2.65k | ++data_item_index; |
143 | 2.65k | col_clear(pinfo->cinfo, COL_INFO); |
144 | 2.65k | col_add_fstr(pinfo->cinfo, COL_INFO, "Busmirroring Seq=%u Len=%u DataItem=%u", |
145 | 2.65k | tvb_get_uint8(tvb, 1), tvb_get_uint16(tvb, 12, ENC_BIG_ENDIAN), data_item_index); |
146 | 2.65k | if (offset + 2 > buffer_length) { |
147 | 12 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
148 | 12 | return buffer_length; |
149 | 12 | } |
150 | 2.63k | proto_tree *data_tree = proto_item_add_subtree(data_item, ett_data_item); |
151 | 2.63k | proto_tree_add_item(data_tree, hf_timestamp, tvb, offset, 2, ENC_BIG_ENDIAN); |
152 | 2.63k | offset += 2; |
153 | 2.63k | proto_item_set_len(data_item, offset - data_item_start); |
154 | | |
155 | 2.63k | if (offset + 1 > buffer_length) { |
156 | 9 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
157 | 9 | return buffer_length; |
158 | 9 | } |
159 | 2.62k | uint8_t flags = tvb_get_uint8(tvb, offset); |
160 | 2.62k | proto_tree_add_item(data_tree, hf_network_state_available, tvb, offset, 1, ENC_BIG_ENDIAN); |
161 | 2.62k | proto_tree_add_item(data_tree, hf_frame_id_available, tvb, offset, 1, ENC_BIG_ENDIAN); |
162 | 2.62k | proto_tree_add_item(data_tree, hf_payload_available, tvb, offset, 1, ENC_BIG_ENDIAN); |
163 | 2.62k | proto_tree_add_item(data_tree, hf_network_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
164 | 2.62k | offset += 1; |
165 | 2.62k | proto_item_set_len(data_item, offset - data_item_start); |
166 | | |
167 | 2.62k | if (offset + 1 > buffer_length) { |
168 | 13 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
169 | 13 | return buffer_length; |
170 | 13 | } |
171 | 2.61k | proto_tree_add_item(data_tree, hf_network_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
172 | 2.61k | offset += 1; |
173 | 2.61k | proto_item_set_len(data_item, offset - data_item_start); |
174 | | |
175 | 2.61k | bool is_can_fd = false; |
176 | 2.61k | uint8_t type = flags & 0x1F; |
177 | 2.61k | switch (type) |
178 | 2.61k | { |
179 | 286 | case NETWORK_TYPE_CAN: |
180 | 286 | { |
181 | 286 | proto_item_append_text(data_item, ": CAN"); |
182 | 286 | } |
183 | 286 | break; |
184 | 322 | case NETWORK_TYPE_LIN: |
185 | 322 | { |
186 | 322 | proto_item_append_text(data_item, ": LIN"); |
187 | 322 | } |
188 | 322 | break; |
189 | 197 | case NETWORK_TYPE_FLEXRAY: |
190 | 197 | { |
191 | 197 | proto_item_append_text(data_item, ": FlexRay"); |
192 | 197 | } |
193 | 197 | break; |
194 | 1.81k | default: |
195 | 1.81k | expert_add_info(pinfo, data_item, &ei_network_type_invalid); |
196 | 1.81k | break; |
197 | 2.61k | } |
198 | 2.61k | uint8_t has_network_state = flags & 0x80; |
199 | 2.61k | if (has_network_state) |
200 | 573 | { |
201 | 573 | if (offset + 1 > buffer_length) { |
202 | 2 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
203 | 2 | return buffer_length; |
204 | 2 | } |
205 | 571 | proto_item *ns_item = proto_tree_add_item(data_item, hf_network_state, tvb, offset, 1, ENC_BIG_ENDIAN); |
206 | 571 | proto_tree *ns_tree = proto_item_add_subtree(ns_item, ett_network_state); |
207 | 571 | proto_tree_add_item(ns_tree, hf_frames_lost, tvb, offset, 1, ENC_BIG_ENDIAN); |
208 | 571 | proto_tree_add_item(ns_tree, hf_bus_online, tvb, offset, 1, ENC_BIG_ENDIAN); |
209 | 571 | switch (type) |
210 | 571 | { |
211 | 62 | case NETWORK_TYPE_CAN: |
212 | 62 | { |
213 | 62 | proto_tree_add_item(ns_tree, hf_can_error_passive, tvb, offset, 1, ENC_BIG_ENDIAN); |
214 | 62 | proto_tree_add_item(ns_tree, hf_can_bus_off, tvb, offset, 1, ENC_BIG_ENDIAN); |
215 | 62 | proto_tree_add_item(ns_tree, hf_can_tx_error_count, tvb, offset, 1, ENC_BIG_ENDIAN); |
216 | 62 | } |
217 | 62 | break; |
218 | 79 | case NETWORK_TYPE_LIN: |
219 | 79 | { |
220 | 79 | proto_tree_add_item(ns_tree, hf_lin_header_tx_error, tvb, offset, 1, ENC_BIG_ENDIAN); |
221 | 79 | proto_tree_add_item(ns_tree, hf_lin_tx_error, tvb, offset, 1, ENC_BIG_ENDIAN); |
222 | 79 | proto_tree_add_item(ns_tree, hf_lin_rx_error, tvb, offset, 1, ENC_BIG_ENDIAN); |
223 | 79 | proto_tree_add_item(ns_tree, hf_lin_rx_no_response, tvb, offset, 1, ENC_BIG_ENDIAN); |
224 | 79 | } |
225 | 79 | break; |
226 | 99 | case NETWORK_TYPE_FLEXRAY: |
227 | 99 | { |
228 | 99 | proto_tree_add_item(ns_tree, hf_flexray_bus_synchronous, tvb, offset, 1, ENC_BIG_ENDIAN); |
229 | 99 | proto_tree_add_item(ns_tree, hf_flexray_normal_active, tvb, offset, 1, ENC_BIG_ENDIAN); |
230 | 99 | proto_tree_add_item(ns_tree, hf_flexray_syntax_error, tvb, offset, 1, ENC_BIG_ENDIAN); |
231 | 99 | proto_tree_add_item(ns_tree, hf_flexray_content_error, tvb, offset, 1, ENC_BIG_ENDIAN); |
232 | 99 | proto_tree_add_item(ns_tree, hf_flexray_boundary_violation, tvb, offset, 1, ENC_BIG_ENDIAN); |
233 | 99 | proto_tree_add_item(ns_tree, hf_flexray_tx_conflict, tvb, offset, 1, ENC_BIG_ENDIAN); |
234 | 99 | } |
235 | 430 | default: |
236 | 430 | break; |
237 | 571 | } |
238 | 571 | offset += 1; |
239 | 571 | proto_item_set_len(data_item, offset - data_item_start); |
240 | 571 | } |
241 | 2.61k | uint8_t has_frame_id = flags & 0x40; |
242 | 2.61k | if (has_frame_id) |
243 | 961 | { |
244 | 961 | switch (type) |
245 | 961 | { |
246 | 85 | case NETWORK_TYPE_CAN: |
247 | 85 | { |
248 | 85 | if (offset + 4 > buffer_length) { |
249 | 2 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
250 | 2 | return buffer_length; |
251 | 2 | } |
252 | 83 | proto_item *frame_id_item = proto_tree_add_item(data_item, hf_frame_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
253 | 83 | proto_tree *frame_id_tree = proto_item_add_subtree(frame_id_item, ett_frame_id); |
254 | 83 | uint8_t can_id_type = tvb_get_uint8(tvb, offset) & 0x80; |
255 | 83 | is_can_fd = tvb_get_uint8(tvb, offset) & 0x40; |
256 | 83 | proto_tree_add_item(frame_id_tree, hf_can_id_type, tvb, offset, 4, ENC_BIG_ENDIAN); |
257 | 83 | proto_tree_add_item(frame_id_tree, hf_can_frame_type, tvb, offset, 4, ENC_BIG_ENDIAN); |
258 | 83 | uint32_t can_id = 0; |
259 | 83 | proto_tree_add_item_ret_uint(frame_id_tree, hf_can_id, tvb, offset, 4, ENC_BIG_ENDIAN, &can_id); |
260 | 83 | if (can_id_type == 0 && can_id > 0x7FF) { |
261 | 46 | expert_add_info(pinfo, frame_id_item, &ei_can_id_invalid); |
262 | 46 | } |
263 | 83 | offset += 4; |
264 | 83 | proto_item_set_len(data_item, offset - data_item_start); |
265 | 83 | } |
266 | 0 | break; |
267 | 182 | case NETWORK_TYPE_LIN: |
268 | 182 | { |
269 | 182 | if (offset + 1 > buffer_length) { |
270 | 1 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
271 | 1 | return buffer_length; |
272 | 1 | } |
273 | 181 | proto_item *frame_id_item = proto_tree_add_item(data_item, hf_frame_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
274 | 181 | proto_tree *frame_id_tree = proto_item_add_subtree(frame_id_item, ett_frame_id); |
275 | 181 | proto_tree_add_item(frame_id_tree, hf_lin_pid, tvb, offset, 1, ENC_BIG_ENDIAN); |
276 | 181 | uint8_t pid = tvb_get_uint8(tvb, offset); |
277 | 181 | if (!is_lin_pid_valid(pid)) { |
278 | 73 | expert_add_info(pinfo, frame_id_item, &ei_lin_pid_invalid); |
279 | 73 | } |
280 | 181 | offset += 1; |
281 | 181 | proto_item_set_len(data_item, offset - data_item_start); |
282 | 181 | } |
283 | 0 | break; |
284 | 65 | case NETWORK_TYPE_FLEXRAY: |
285 | 65 | { |
286 | 65 | if (offset + 3 > buffer_length) { |
287 | 3 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
288 | 3 | return buffer_length; |
289 | 3 | } |
290 | 62 | proto_item* frame_id_item = proto_tree_add_item(data_item, hf_frame_id, tvb, offset, 3, ENC_BIG_ENDIAN); |
291 | 62 | proto_tree *frame_id_tree = proto_item_add_subtree(frame_id_item, ett_frame_id); |
292 | 62 | proto_tree_add_item(frame_id_tree, hf_flexray_channel_b, tvb, offset, 2, ENC_BIG_ENDIAN); |
293 | 62 | proto_tree_add_item(frame_id_tree, hf_flexray_channel_a, tvb, offset, 2, ENC_BIG_ENDIAN); |
294 | 62 | proto_tree_add_item(frame_id_tree, hf_flexray_slot_valid, tvb, offset, 2, ENC_BIG_ENDIAN); |
295 | 62 | proto_tree_add_item(frame_id_tree, hf_flexray_slot_id, tvb, offset, 2, ENC_BIG_ENDIAN); |
296 | 62 | offset += 2; |
297 | 62 | proto_tree_add_item(frame_id_tree, hf_flexray_cycle, tvb, offset, 1, ENC_BIG_ENDIAN); |
298 | 62 | offset += 1; |
299 | 62 | proto_item_set_len(data_item, offset - data_item_start); |
300 | 62 | } |
301 | 0 | break; |
302 | 629 | default: |
303 | 629 | break; |
304 | 961 | } |
305 | 961 | } |
306 | 2.60k | uint8_t has_payload = flags & 0x20; |
307 | 2.60k | if (has_payload) |
308 | 376 | { |
309 | 376 | if (offset + 1 > buffer_length) { |
310 | 7 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
311 | 7 | return buffer_length; |
312 | 7 | } |
313 | 369 | uint32_t length = 0; |
314 | 369 | proto_item* pi = proto_tree_add_item_ret_uint(data_item, hf_payload_length, tvb, offset, 1, ENC_BIG_ENDIAN, &length); |
315 | 369 | switch (type) |
316 | 369 | { |
317 | 73 | case NETWORK_TYPE_CAN: |
318 | 73 | { |
319 | 73 | if (is_can_fd) { |
320 | 33 | if (length > 8 && length!=12 && length!=16 && length !=20 && |
321 | 14 | length !=24 && length != 32 && length!=48 && length!=64 ) { |
322 | 13 | expert_add_info(pinfo, pi, &ei_can_length_invalid); |
323 | 13 | } |
324 | 40 | } else{ |
325 | 40 | if (length > 8) { |
326 | 22 | expert_add_info(pinfo, pi, &ei_can_length_invalid); |
327 | 22 | } |
328 | 40 | } |
329 | 73 | } |
330 | 73 | break; |
331 | 53 | case NETWORK_TYPE_LIN: |
332 | 53 | { |
333 | 53 | if (length > 8) { |
334 | 40 | expert_add_info(pinfo, pi, &ei_lin_length_invalid); |
335 | 40 | } |
336 | 53 | } |
337 | 53 | break; |
338 | 243 | default: |
339 | 243 | break; |
340 | 369 | } |
341 | 369 | offset += 1; |
342 | 369 | proto_item_set_len(data_item, offset - data_item_start); |
343 | 369 | if (offset + length > buffer_length) { |
344 | 52 | expert_add_info(pinfo, data_item, &ei_data_item_incomplete); |
345 | 52 | return buffer_length; |
346 | 52 | } |
347 | 317 | proto_tree_add_item(data_item, hf_payload, tvb, offset, length, ENC_NA); |
348 | 317 | offset += length; |
349 | 317 | proto_item_set_len(data_item, offset - data_item_start); |
350 | 317 | } |
351 | | |
352 | 2.60k | } // while |
353 | | |
354 | 22 | return buffer_length; |
355 | 123 | } |
356 | | |
357 | | void proto_register_busmirroring(void) |
358 | 16 | { |
359 | 16 | static const true_false_string can_id_type_names = {"Extended", "Standard"}; |
360 | 16 | static const true_false_string can_frame_type_names = {"CAN FD", "CAN 2.0"}; |
361 | 16 | static const value_string network_type_names[] = { |
362 | 16 | {1, "CAN"}, |
363 | 16 | {2, "LIN"}, |
364 | 16 | {3, "FlexRay"}, |
365 | 16 | {4, "Ethernet"}, |
366 | 16 | {0, NULL} }; |
367 | 16 | static hf_register_info hf[] = { |
368 | 16 | {&hf_protocol_version, |
369 | 16 | {"Protocol Version", "busmirroring.protocol_version", |
370 | 16 | FT_UINT8, BASE_DEC, |
371 | 16 | NULL, 0x0, |
372 | 16 | NULL, HFILL}}, |
373 | 16 | {&hf_sequence_number, |
374 | 16 | {"Sequence Number", "busmirroring.sequence_number", |
375 | 16 | FT_UINT8, BASE_DEC, |
376 | 16 | NULL, 0x0, |
377 | 16 | NULL, HFILL}}, |
378 | 16 | {&hf_header_timestamp, |
379 | 16 | {"Timestamp", "busmirroring.header_timestamp", |
380 | 16 | FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, |
381 | 16 | NULL, 0x0, |
382 | 16 | NULL, HFILL}}, |
383 | 16 | {&hf_seconds, |
384 | 16 | {"Seconds", "busmirroring.seconds", |
385 | 16 | FT_UINT48, BASE_DEC, |
386 | 16 | NULL, 0x0, |
387 | 16 | NULL, HFILL}}, |
388 | 16 | {&hf_nanoseconds, |
389 | 16 | {"Nanoseconds", "busmirroring.nanoseconds", |
390 | 16 | FT_UINT32, BASE_DEC, |
391 | 16 | NULL, 0x0, |
392 | 16 | NULL, HFILL}}, |
393 | 16 | {&hf_data_length, |
394 | 16 | {"Data Length", "busmirroring.data_length", |
395 | 16 | FT_UINT16, BASE_DEC, |
396 | 16 | NULL, 0x0, |
397 | 16 | NULL, HFILL}}, |
398 | 16 | {&hf_timestamp, |
399 | 16 | {"Timestamp(10 µs)", "busmirroring.timestamp", |
400 | 16 | FT_UINT16, BASE_DEC, |
401 | 16 | NULL, 0x0, |
402 | 16 | NULL, HFILL}}, |
403 | 16 | {&hf_network_state_available, |
404 | 16 | {"Network State", "busmirroring.network_state_available", |
405 | 16 | FT_BOOLEAN, 8, |
406 | 16 | TFS(&tfs_available_not_available), 0x80, |
407 | 16 | NULL, HFILL}}, |
408 | 16 | {&hf_frame_id_available, |
409 | 16 | {"Frame ID", "busmirroring.frame_id_available", |
410 | 16 | FT_BOOLEAN, 8, |
411 | 16 | TFS(&tfs_available_not_available), 0x40, |
412 | 16 | NULL, HFILL}}, |
413 | 16 | {&hf_payload_available, |
414 | 16 | {"Payload", "busmirroring.payload_available", |
415 | 16 | FT_BOOLEAN, 8, |
416 | 16 | TFS(&tfs_available_not_available), 0x20, |
417 | 16 | NULL, HFILL}}, |
418 | 16 | {&hf_network_type, |
419 | 16 | {"Network Type", "busmirroring.network_type", |
420 | 16 | FT_UINT8, BASE_DEC, |
421 | 16 | VALS(network_type_names), 0x1F, |
422 | 16 | NULL, HFILL}}, |
423 | 16 | {&hf_network_id, |
424 | 16 | {"Network ID", "busmirroring.network_id", |
425 | 16 | FT_UINT8, BASE_DEC, |
426 | 16 | NULL, 0x0, |
427 | 16 | NULL, HFILL}}, |
428 | 16 | {&hf_network_state, |
429 | 16 | {"Network State", "busmirroring.network_state", |
430 | 16 | FT_UINT8, BASE_HEX, |
431 | 16 | NULL, 0x0, |
432 | 16 | NULL, HFILL}}, |
433 | 16 | {&hf_frames_lost, |
434 | 16 | {"Frames Lost", "busmirroring.frames_lost", |
435 | 16 | FT_BOOLEAN, 8, |
436 | 16 | NULL, 0x80, |
437 | 16 | NULL, HFILL}}, |
438 | 16 | {&hf_bus_online, |
439 | 16 | {"Bus Online", "busmirroring.bus_online", |
440 | 16 | FT_BOOLEAN, 8, |
441 | 16 | NULL, 0x40, |
442 | 16 | NULL, HFILL}}, |
443 | 16 | {&hf_can_error_passive, |
444 | 16 | {"Error-Passive", "busmirroring.can_error_passive", |
445 | 16 | FT_BOOLEAN, 8, |
446 | 16 | NULL, 0x20, |
447 | 16 | NULL, HFILL}}, |
448 | 16 | {&hf_can_bus_off, |
449 | 16 | {"Bus-Off", "busmirroring.can_bus_off", |
450 | 16 | FT_BOOLEAN, 8, |
451 | 16 | NULL, 0x10, |
452 | 16 | NULL, HFILL}}, |
453 | 16 | {&hf_can_tx_error_count, |
454 | 16 | {"Tx Error Count(divided by 8)", "busmirroring.can_tx_error_count", |
455 | 16 | FT_UINT8, BASE_DEC, |
456 | 16 | NULL, 0x0F, |
457 | 16 | NULL, HFILL}}, |
458 | 16 | {&hf_lin_header_tx_error, |
459 | 16 | {"Header Tx Error", "busmirroring.lin_header_tx_error", |
460 | 16 | FT_BOOLEAN, 8, |
461 | 16 | NULL, 0x08, |
462 | 16 | NULL, HFILL}}, |
463 | 16 | {&hf_lin_tx_error, |
464 | 16 | {"Tx Error", "busmirroring.lin_tx_error", |
465 | 16 | FT_BOOLEAN, 8, |
466 | 16 | NULL, 0x04, |
467 | 16 | NULL, HFILL}}, |
468 | 16 | {&hf_lin_rx_error, |
469 | 16 | {"Rx Error", "busmirroring.lin_rx_error", |
470 | 16 | FT_BOOLEAN, 8, |
471 | 16 | NULL, 0x02, |
472 | 16 | NULL, HFILL}}, |
473 | 16 | {&hf_lin_rx_no_response, |
474 | 16 | {"Rx No Response", "busmirroring.lin_rx_no_response", |
475 | 16 | FT_BOOLEAN, 8, |
476 | 16 | NULL, 0x01, |
477 | 16 | NULL, HFILL}}, |
478 | 16 | {&hf_flexray_bus_synchronous, |
479 | 16 | {"Bus Synchronous", "busmirroring.flexray_bus_synchronous", |
480 | 16 | FT_BOOLEAN, 8, |
481 | 16 | NULL, 0x20, |
482 | 16 | NULL, HFILL}}, |
483 | 16 | {&hf_flexray_normal_active, |
484 | 16 | {"Normal Active", "busmirroring.flexray_normal_active", |
485 | 16 | FT_BOOLEAN, 8, |
486 | 16 | NULL, 0x10, |
487 | 16 | NULL, HFILL}}, |
488 | 16 | {&hf_flexray_syntax_error, |
489 | 16 | {"Syntax Error", "busmirroring.flexray_syntax_error", |
490 | 16 | FT_BOOLEAN, 8, |
491 | 16 | NULL, 0x08, |
492 | 16 | NULL, HFILL}}, |
493 | 16 | {&hf_flexray_content_error, |
494 | 16 | {"Content Error", "busmirroring.flexray_content_error", |
495 | 16 | FT_BOOLEAN, 8, |
496 | 16 | NULL, 0x04, |
497 | 16 | NULL, HFILL}}, |
498 | 16 | {&hf_flexray_boundary_violation, |
499 | 16 | {"Boundary Violation", "busmirroring.flexray_boundary_violation", |
500 | 16 | FT_BOOLEAN, 8, |
501 | 16 | NULL, 0x02, |
502 | 16 | NULL, HFILL}}, |
503 | 16 | {&hf_flexray_tx_conflict, |
504 | 16 | {"Tx Conflict", "busmirroring.flexray_tx_conflict", |
505 | 16 | FT_BOOLEAN, 8, |
506 | 16 | NULL, 0x01, |
507 | 16 | NULL, HFILL}}, |
508 | 16 | {&hf_frame_id, |
509 | 16 | {"Frame ID", "busmirroring.frame_id", |
510 | 16 | FT_UINT32, BASE_HEX, |
511 | 16 | NULL, 0x0, |
512 | 16 | NULL, HFILL}}, |
513 | 16 | {&hf_can_id_type, |
514 | 16 | {"CAN ID Type", "busmirroring.can_id_type", |
515 | 16 | FT_BOOLEAN, 32, |
516 | 16 | TFS(&can_id_type_names), 0x80000000, |
517 | 16 | NULL, HFILL}}, |
518 | 16 | {&hf_can_frame_type, |
519 | 16 | {"CAN Frame Type", "busmirroring.can_frame_type", |
520 | 16 | FT_BOOLEAN, 32, |
521 | 16 | TFS(&can_frame_type_names), 0x40000000, |
522 | 16 | NULL, HFILL}}, |
523 | 16 | {&hf_can_id, |
524 | 16 | {"CAN ID", "busmirroring.can_id", |
525 | 16 | FT_UINT32, BASE_HEX_DEC, |
526 | 16 | NULL, 0x1FFFFFFF, |
527 | 16 | NULL, HFILL}}, |
528 | 16 | {&hf_lin_pid, |
529 | 16 | {"LIN PID", "busmirroring.lin_pid", |
530 | 16 | FT_UINT8, BASE_HEX_DEC, |
531 | 16 | NULL, 0x0, |
532 | 16 | NULL, HFILL}}, |
533 | 16 | {&hf_flexray_channel_b, |
534 | 16 | {"Channel B", "busmirroring.flexray_channel_b", |
535 | 16 | FT_BOOLEAN, 16, |
536 | 16 | TFS(&tfs_available_not_available), 0x8000, |
537 | 16 | NULL, HFILL}}, |
538 | 16 | {&hf_flexray_channel_a, |
539 | 16 | {"Channel A", "busmirroring.flexray_channel_a", |
540 | 16 | FT_BOOLEAN, 16, |
541 | 16 | TFS(&tfs_available_not_available), 0x4000, |
542 | 16 | NULL, HFILL}}, |
543 | 16 | {&hf_flexray_slot_valid, |
544 | 16 | {"Slot", "busmirroring.flexray_slot_valid", |
545 | 16 | FT_BOOLEAN, 16, |
546 | 16 | TFS(&tfs_valid_not_valid), 0x0800, |
547 | 16 | NULL, HFILL}}, |
548 | 16 | {&hf_flexray_slot_id, |
549 | 16 | {"Slot ID", "busmirroring.flexray_slot_id", |
550 | 16 | FT_UINT16, BASE_HEX_DEC, |
551 | 16 | NULL, 0x07FF, |
552 | 16 | NULL, HFILL}}, |
553 | 16 | {&hf_flexray_cycle, |
554 | 16 | {"Cycle", "busmirroring.flexray_cycle", |
555 | 16 | FT_UINT8, BASE_DEC, |
556 | 16 | NULL, 0x0, |
557 | 16 | NULL, HFILL}}, |
558 | 16 | {&hf_payload_length, |
559 | 16 | {"Payload Length", "busmirroring.payload_length", |
560 | 16 | FT_UINT8, BASE_DEC, |
561 | 16 | NULL, 0x0, |
562 | 16 | NULL, HFILL}}, |
563 | 16 | {&hf_payload, |
564 | 16 | {"Payload", "busmirroring.payload", |
565 | 16 | FT_BYTES, BASE_NONE, |
566 | 16 | NULL, 0x0, |
567 | 16 | NULL, HFILL}}}; |
568 | | |
569 | | /* Setup protocol subtree array */ |
570 | 16 | static int *ett[] = { |
571 | 16 | &ett_busmirroring, |
572 | 16 | &ett_header_timestamp, |
573 | 16 | &ett_data_item, |
574 | 16 | &ett_network_state, |
575 | 16 | &ett_frame_id}; |
576 | | |
577 | 16 | proto_busmirroring = proto_register_protocol("Bus Mirroring Protocol", "BusMirroring", "busmirroring"); |
578 | | |
579 | 16 | proto_register_field_array(proto_busmirroring, hf, array_length(hf)); |
580 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
581 | | |
582 | 16 | static ei_register_info ei[] = { |
583 | 16 | { |
584 | 16 | &ei_data_incomplete, |
585 | 16 | { "busmirroring.data_incomplete", PI_UNDECODED, PI_WARN, |
586 | 16 | "Data is incomplete", EXPFILL } |
587 | 16 | }, |
588 | 16 | { |
589 | 16 | &ei_data_item_incomplete, |
590 | 16 | { "busmirroring.data_item_incomplete", PI_UNDECODED, PI_WARN, |
591 | 16 | "Data item is incomplete", EXPFILL } |
592 | 16 | }, |
593 | 16 | { |
594 | 16 | &ei_network_type_invalid, |
595 | 16 | { "busmirroring.network_type_invalid", PI_PROTOCOL, PI_WARN, |
596 | 16 | "Network type is invalid", EXPFILL } |
597 | 16 | }, |
598 | 16 | { |
599 | 16 | &ei_can_id_invalid, |
600 | 16 | { "busmirroring.can_id_invalid", PI_PROTOCOL, PI_WARN, |
601 | 16 | "ID of CAN frame is invalid", EXPFILL } |
602 | 16 | }, |
603 | 16 | { |
604 | 16 | &ei_lin_pid_invalid, |
605 | 16 | { "busmirroring.lin_pid_invalid", PI_PROTOCOL, PI_WARN, |
606 | 16 | "PID of LIN frame is invalid", EXPFILL } |
607 | 16 | }, |
608 | 16 | { |
609 | 16 | &ei_can_length_invalid, |
610 | 16 | { "busmirroring.can_length_invalid", PI_PROTOCOL, PI_WARN, |
611 | 16 | "Length of CAN frame is invalid", EXPFILL } |
612 | 16 | }, |
613 | 16 | { |
614 | 16 | &ei_lin_length_invalid, |
615 | 16 | { "busmirroring.lin_length_invalid", PI_PROTOCOL, PI_WARN, |
616 | 16 | "Length of LIN frame is invalid", EXPFILL } |
617 | 16 | } |
618 | 16 | }; |
619 | | |
620 | 16 | expert_module_t* expert_busmirroring = expert_register_protocol(proto_busmirroring); |
621 | 16 | expert_register_field_array(expert_busmirroring, ei, array_length(ei)); |
622 | 16 | } |
623 | | |
624 | | void proto_reg_handoff_busmirroring(void) |
625 | 16 | { |
626 | 16 | static dissector_handle_t busmirroring_handle; |
627 | | |
628 | 16 | busmirroring_handle = create_dissector_handle(dissect_busmirroring, proto_busmirroring); |
629 | 16 | dissector_add_uint_with_preference("udp.port", BUSMIRRORING_UDP_PORT, busmirroring_handle); |
630 | 16 | dissector_add_for_decode_as("udp.port", busmirroring_handle); |
631 | 16 | } |
632 | | |
633 | | /* |
634 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
635 | | * |
636 | | * Local Variables: |
637 | | * c-basic-offset: 2 |
638 | | * tab-width: 8 |
639 | | * indent-tabs-mode: nil |
640 | | * End: |
641 | | * |
642 | | * ex: set shiftwidth=2 tabstop=8 expandtab: |
643 | | * :indentSize=2:tabSize=8:noTabs=true: |
644 | | */ |