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