/src/wireshark/epan/dissectors/packet-iso10681.c
Line | Count | Source |
1 | | /* packet-iso10681.c |
2 | | * ISO 10681-2 ISO FlexRay TP |
3 | | * By Dr. Lars Voelker <lars.voelker@technica-engineering.de> |
4 | | * Copyright 2021-2023 Dr. Lars Voelker |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | * |
12 | | * Also see packet-iso15765.c / packet-iso15765.h |
13 | | */ |
14 | | |
15 | | #include "config.h" |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include <epan/prefs.h> |
19 | | #include <epan/decode_as.h> |
20 | | #include <epan/reassemble.h> |
21 | | #include <epan/expert.h> |
22 | | #include <epan/proto_data.h> |
23 | | |
24 | | #include "packet-iso10681.h" |
25 | | #include "packet-flexray.h" |
26 | | |
27 | | void proto_register_iso10681(void); |
28 | | void proto_reg_handoff_iso10681(void); |
29 | | |
30 | | /* StartFrame or StartFrameAck */ |
31 | 16 | #define ISO10681_TYPE_MASK 0xF0 |
32 | 0 | #define ISO10681_TYPE_START_FRAME 4 |
33 | 0 | #define ISO10681_TYPE_CONSECUTIVE_FRAME_1 5 |
34 | 0 | #define ISO10681_TYPE_CONSECUTIVE_FRAME_2 6 |
35 | 0 | #define ISO10681_TYPE_CONSECUTIVE_FRAME_EOB 7 |
36 | 0 | #define ISO10681_TYPE_FLOW_CONTROL 8 |
37 | 0 | #define ISO10681_TYPE_LAST_FRAME 9 |
38 | | |
39 | 48 | #define ISO10681_TYPE_PART2_MASK 0x0F |
40 | | |
41 | 0 | #define ISO10681_FLOW_STATUS_CTS 3 |
42 | 0 | #define ISO10681_FLOW_STATUS_ACK_RETRY 4 |
43 | | #define ISO10681_FLOW_STATUS_WAIT 5 |
44 | | #define ISO10681_FLOW_STATUS_ABORT 6 |
45 | | #define ISO10681_FLOW_STATUS_OVERFLOW 7 |
46 | | |
47 | | typedef struct iso10681_identifier { |
48 | | uint32_t id; |
49 | | uint32_t seq; |
50 | | uint16_t frag_id; |
51 | | bool last; |
52 | | } iso10681_identifier_t; |
53 | | |
54 | | typedef struct iso10681_frame { |
55 | | uint32_t seq; |
56 | | uint32_t offset; |
57 | | uint32_t len; |
58 | | bool error; |
59 | | bool complete; |
60 | | uint16_t last_frag_id; |
61 | | uint8_t frag_id_high[16]; |
62 | | } iso10681_frame_t; |
63 | | |
64 | | static const value_string iso10681_message_types[] = { |
65 | | {ISO10681_TYPE_START_FRAME, "Start Frame"}, |
66 | | {ISO10681_TYPE_CONSECUTIVE_FRAME_1, "Consecutive Frame 1"}, |
67 | | {ISO10681_TYPE_CONSECUTIVE_FRAME_2, "Consecutive Frame 2"}, |
68 | | {ISO10681_TYPE_CONSECUTIVE_FRAME_EOB, "Consecutive Frame EOB"}, |
69 | | {ISO10681_TYPE_FLOW_CONTROL, "Flow Control"}, |
70 | | {ISO10681_TYPE_LAST_FRAME, "Last Frame"}, |
71 | | {0, NULL} |
72 | | }; |
73 | | |
74 | | static const value_string iso10681_flow_status_values[] = { |
75 | | {ISO10681_FLOW_STATUS_CTS, "Continue to Send"}, |
76 | | {ISO10681_FLOW_STATUS_ACK_RETRY, "Ack/Retry"}, |
77 | | {ISO10681_FLOW_STATUS_WAIT, "Wait"}, |
78 | | {ISO10681_FLOW_STATUS_ABORT, "Abort"}, |
79 | | {ISO10681_FLOW_STATUS_OVERFLOW, "Overflow"}, |
80 | | {0, NULL} |
81 | | }; |
82 | | |
83 | | static const value_string iso10681_start_type2_values[] = { |
84 | | {0, "Unacknowledged"}, |
85 | | {1, "Acknowledged"}, |
86 | | {0, NULL} |
87 | | }; |
88 | | |
89 | | static const value_string iso10681_fc_bc_scexp_values[] = { |
90 | | {0, "0 cycles"}, |
91 | | {1, "1 cycle"}, |
92 | | {2, "3 cycles"}, |
93 | | {3, "7 cycles"}, |
94 | | {4, "15 cycles"}, |
95 | | {5, "31 cycles"}, |
96 | | {6, "63 cycles"}, |
97 | | {7, "127 cycles"}, |
98 | | {0, NULL} |
99 | | }; |
100 | | |
101 | | static const value_string iso10681_fc_ack_values[] = { |
102 | | {0, "Acknowledge"}, |
103 | | {1, "Retry Request"}, |
104 | | {0, NULL} |
105 | | }; |
106 | | |
107 | | static int hf_iso10681_target_address; |
108 | | static int hf_iso10681_source_address; |
109 | | static int hf_iso10681_type; |
110 | | static int hf_iso10681_type2; |
111 | | static int hf_iso10681_frame_payload_length; |
112 | | static int hf_iso10681_message_length; |
113 | | static int hf_iso10681_sequence_number; |
114 | | static int hf_iso10681_fc_flow_status; |
115 | | static int hf_iso10681_fc_bandwidth_control; |
116 | | static int hf_iso10681_fc_bc_separation_cycle_exp; |
117 | | static int hf_iso10681_fc_bc_max_num_pdu_per_cycle; |
118 | | static int hf_iso10681_fc_buffer_size; |
119 | | static int hf_iso10681_fc_ack; |
120 | | static int hf_iso10681_fc_byte_position; |
121 | | |
122 | | |
123 | | static int ett_iso10681; |
124 | | static int ett_iso10681_bandwidth_control; |
125 | | |
126 | | static expert_field ei_iso10681_message_type_bad; |
127 | | |
128 | | static int proto_iso10681; |
129 | | static dissector_handle_t iso10681_handle_flexray; |
130 | | |
131 | | static dissector_table_t subdissector_table; |
132 | | |
133 | | static range_t *iso10681_flexray_ids; |
134 | | static bool iso10681_spread_over_multiple_cycles = true; |
135 | | |
136 | | static reassembly_table iso10681_reassembly_table; |
137 | | static wmem_map_t *iso10681_frame_table; |
138 | | static wmem_map_t *iso10681_seq_table; |
139 | | static uint32_t next_seqnum; |
140 | | |
141 | | |
142 | | static int hf_iso10681_fragments; |
143 | | static int hf_iso10681_fragment; |
144 | | static int hf_iso10681_fragment_overlap; |
145 | | static int hf_iso10681_fragment_overlap_conflicts; |
146 | | static int hf_iso10681_fragment_multiple_tails; |
147 | | static int hf_iso10681_fragment_too_long_fragment; |
148 | | static int hf_iso10681_fragment_error; |
149 | | static int hf_iso10681_fragment_count; |
150 | | static int hf_iso10681_reassembled_in; |
151 | | static int hf_iso10681_reassembled_length; |
152 | | |
153 | | static int ett_iso10681_fragment; |
154 | | static int ett_iso10681_fragments; |
155 | | |
156 | | static const fragment_items iso10681_frag_items = { |
157 | | /* Fragment subtrees */ |
158 | | &ett_iso10681_fragment, |
159 | | &ett_iso10681_fragments, |
160 | | /* Fragment fields */ |
161 | | &hf_iso10681_fragments, |
162 | | &hf_iso10681_fragment, |
163 | | &hf_iso10681_fragment_overlap, |
164 | | &hf_iso10681_fragment_overlap_conflicts, |
165 | | &hf_iso10681_fragment_multiple_tails, |
166 | | &hf_iso10681_fragment_too_long_fragment, |
167 | | &hf_iso10681_fragment_error, |
168 | | &hf_iso10681_fragment_count, |
169 | | /* Reassembled in field */ |
170 | | &hf_iso10681_reassembled_in, |
171 | | /* Reassembled length field */ |
172 | | &hf_iso10681_reassembled_length, |
173 | | /* Reassembled data field */ |
174 | | NULL, |
175 | | "ISO10681 fragments" |
176 | | }; |
177 | | |
178 | | static uint32_t |
179 | 0 | iso10681_seqnum(uint32_t frame_id, bool new_seqnum) { |
180 | 0 | uint32_t *ret; |
181 | |
|
182 | 0 | ret = (uint32_t *)wmem_map_lookup(iso10681_seq_table, GUINT_TO_POINTER(frame_id)); |
183 | |
|
184 | 0 | if (ret == NULL) { |
185 | 0 | ret = wmem_new0(wmem_file_scope(), uint32_t); |
186 | 0 | *ret = next_seqnum++; |
187 | 0 | wmem_map_insert(iso10681_seq_table, GUINT_TO_POINTER(frame_id), ret); |
188 | 0 | } else { |
189 | 0 | if (new_seqnum) { |
190 | 0 | (*ret) = next_seqnum++; |
191 | 0 | } |
192 | 0 | } |
193 | |
|
194 | 0 | return *ret; |
195 | 0 | } |
196 | | |
197 | | static int |
198 | 0 | dissect_iso10681(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t frame_id, uint32_t frame_length _U_) { |
199 | 0 | proto_tree *iso10681_tree; |
200 | 0 | proto_item *ti; |
201 | 0 | proto_item *ti_type; |
202 | 0 | uint32_t type; |
203 | 0 | uint32_t offset; |
204 | |
|
205 | 0 | iso10681_identifier_t* iso10681_info; |
206 | 0 | bool fragmented = false; |
207 | 0 | uint32_t seqnum = 0; |
208 | |
|
209 | 0 | uint32_t data_length = 0; |
210 | 0 | uint32_t full_len = 0; |
211 | 0 | uint32_t target_addr = 0; |
212 | 0 | uint32_t source_addr = 0; |
213 | |
|
214 | 0 | tvbuff_t* next_tvb = NULL; |
215 | 0 | bool complete = false; |
216 | |
|
217 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISO10681"); |
218 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
219 | |
|
220 | 0 | iso10681_info = (iso10681_identifier_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_iso10681, 0); |
221 | |
|
222 | 0 | if (!iso10681_info) { |
223 | 0 | iso10681_info = wmem_new0(wmem_file_scope(), iso10681_identifier_t); |
224 | 0 | iso10681_info->id = frame_id; |
225 | 0 | iso10681_info->last = false; |
226 | 0 | p_add_proto_data(wmem_file_scope(), pinfo, proto_iso10681, 0, iso10681_info); |
227 | 0 | } |
228 | |
|
229 | 0 | ti = proto_tree_add_item(tree, proto_iso10681, tvb, 0, -1, ENC_NA); |
230 | 0 | iso10681_tree = proto_item_add_subtree(ti, ett_iso10681); |
231 | |
|
232 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_target_address, tvb, 0, 2, ENC_BIG_ENDIAN, &target_addr); |
233 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_source_address, tvb, 2, 2, ENC_BIG_ENDIAN, &source_addr); |
234 | 0 | offset = 4; |
235 | |
|
236 | 0 | ti_type = proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_type, tvb, offset, 1, ENC_BIG_ENDIAN, &type); |
237 | 0 | col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, type, iso10681_message_types, "Unknown (0x%02x)")); |
238 | |
|
239 | 0 | switch (type) { |
240 | 0 | case ISO10681_TYPE_START_FRAME: { |
241 | 0 | uint32_t type2_value; |
242 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_type2, tvb, offset, 1, ENC_BIG_ENDIAN, &type2_value); |
243 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str(pinfo->pool, type2_value, iso10681_start_type2_values, "Unknown (0x%x)")); |
244 | |
|
245 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_frame_payload_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN, &data_length); |
246 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &full_len); |
247 | 0 | offset += 4; |
248 | |
|
249 | 0 | fragmented = true; |
250 | 0 | seqnum = 0; |
251 | |
|
252 | 0 | if (!(pinfo->fd->visited)) { |
253 | 0 | iso10681_frame_t *iso10681_frame = wmem_new0(wmem_file_scope(), iso10681_frame_t); |
254 | 0 | iso10681_frame->seq = iso10681_info->seq = iso10681_seqnum(frame_id, true); |
255 | 0 | iso10681_frame->len = full_len; |
256 | |
|
257 | 0 | wmem_map_insert(iso10681_frame_table, GUINT_TO_POINTER(iso10681_info->seq), iso10681_frame); |
258 | 0 | } |
259 | |
|
260 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (Segment Length: %d, Total Len: %d)", data_length, full_len); |
261 | |
|
262 | 0 | break; |
263 | 0 | } |
264 | 0 | case ISO10681_TYPE_CONSECUTIVE_FRAME_1: |
265 | 0 | case ISO10681_TYPE_CONSECUTIVE_FRAME_2: |
266 | 0 | case ISO10681_TYPE_CONSECUTIVE_FRAME_EOB: { |
267 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_sequence_number, tvb, offset, 1, ENC_BIG_ENDIAN, &seqnum); |
268 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_frame_payload_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN, &data_length); |
269 | 0 | offset += 2; |
270 | |
|
271 | 0 | fragmented = true; |
272 | |
|
273 | 0 | if (!(pinfo->fd->visited)) { |
274 | 0 | iso10681_info->seq = iso10681_seqnum(frame_id, false); |
275 | 0 | } |
276 | |
|
277 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (Segment Length: %d, Sequence Number: %d)", data_length, seqnum); |
278 | 0 | break; |
279 | 0 | } |
280 | 0 | case ISO10681_TYPE_LAST_FRAME: { |
281 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_frame_payload_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN, &data_length); |
282 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &full_len); |
283 | 0 | offset += 4; |
284 | |
|
285 | 0 | fragmented = true; |
286 | |
|
287 | 0 | if (!(pinfo->fd->visited)) { |
288 | 0 | iso10681_info->seq = iso10681_seqnum(frame_id, false); |
289 | 0 | } |
290 | |
|
291 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (Segment Length: %d, Total Len: %d)", data_length, full_len); |
292 | 0 | break; |
293 | 0 | } |
294 | 0 | case ISO10681_TYPE_FLOW_CONTROL: { |
295 | 0 | unsigned flow_status = 0; |
296 | 0 | proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_fc_flow_status, tvb, offset, 1, ENC_BIG_ENDIAN, &flow_status); |
297 | |
|
298 | 0 | switch (flow_status) { |
299 | 0 | case ISO10681_FLOW_STATUS_CTS: { |
300 | 0 | static int * const bandwidth_control[] = { |
301 | 0 | &hf_iso10681_fc_bc_max_num_pdu_per_cycle, |
302 | 0 | &hf_iso10681_fc_bc_separation_cycle_exp, |
303 | 0 | NULL |
304 | 0 | }; |
305 | |
|
306 | 0 | proto_tree_add_bitmask(iso10681_tree, tvb, offset + 1, hf_iso10681_fc_bandwidth_control, ett_iso10681_bandwidth_control, |
307 | 0 | bandwidth_control, ENC_BIG_ENDIAN); |
308 | 0 | proto_tree_add_item(iso10681_tree, hf_iso10681_fc_buffer_size, tvb, offset + 2, 2, ENC_BIG_ENDIAN); |
309 | 0 | break; |
310 | 0 | } |
311 | 0 | case ISO10681_FLOW_STATUS_ACK_RETRY: |
312 | 0 | proto_tree_add_item(iso10681_tree, hf_iso10681_fc_ack, tvb, offset + 1, 1, ENC_BIG_ENDIAN); |
313 | 0 | proto_tree_add_item(iso10681_tree, hf_iso10681_fc_byte_position, tvb, offset + 2, 2, ENC_BIG_ENDIAN); |
314 | 0 | break; |
315 | 0 | } |
316 | | |
317 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (Flow Status: %s)", val_to_str(pinfo->pool, flow_status, iso10681_flow_status_values, "unknown (0x%x)")); |
318 | 0 | break; |
319 | 0 | } |
320 | 0 | default: |
321 | 0 | expert_add_info_format(pinfo, ti_type, &ei_iso10681_message_type_bad, "Bad Message Type value %u", type); |
322 | 0 | return offset; |
323 | 0 | } |
324 | | |
325 | | /* show data */ |
326 | 0 | if (data_length > 0) { |
327 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tvb_bytes_to_str_punct(pinfo->pool, tvb, offset, data_length, ' ')); |
328 | 0 | } |
329 | |
|
330 | 0 | if (fragmented) { |
331 | 0 | tvbuff_t *new_tvb = NULL; |
332 | 0 | iso10681_frame_t *iso10681_frame; |
333 | 0 | uint16_t frag_id = seqnum; |
334 | | |
335 | | /* Get frame information */ |
336 | 0 | iso10681_frame = (iso10681_frame_t *)wmem_map_lookup(iso10681_frame_table, GUINT_TO_POINTER(iso10681_info->seq)); |
337 | 0 | if (iso10681_frame != NULL) { |
338 | 0 | if (type == ISO10681_TYPE_LAST_FRAME) { |
339 | 0 | frag_id = iso10681_frame->last_frag_id + 1; |
340 | 0 | } |
341 | |
|
342 | 0 | if (!(pinfo->fd->visited)) { |
343 | 0 | DISSECTOR_ASSERT(frag_id < 16); |
344 | 0 | uint16_t tmp = iso10681_frame->frag_id_high[frag_id]++; |
345 | | /* Make sure that we assert on using more than 4096 (16*255) segments.*/ |
346 | 0 | DISSECTOR_ASSERT(iso10681_frame->frag_id_high[frag_id] != 0); |
347 | 0 | frag_id += tmp * 16; |
348 | | |
349 | | /* Save the frag_id for subsequent dissection */ |
350 | 0 | iso10681_info->frag_id = frag_id; |
351 | 0 | } |
352 | |
|
353 | 0 | if (!iso10681_frame->error) { |
354 | 0 | bool save_fragmented = pinfo->fragmented; |
355 | 0 | uint32_t len = data_length; |
356 | 0 | fragment_head *frag_msg; |
357 | | |
358 | | /* Check if it's the last packet */ |
359 | 0 | if (!(pinfo->fd->visited)) { |
360 | | /* Update the last_frag_id */ |
361 | 0 | if (frag_id > iso10681_frame->last_frag_id) { |
362 | 0 | iso10681_frame->last_frag_id = frag_id; |
363 | 0 | } |
364 | |
|
365 | 0 | iso10681_frame->offset += len; |
366 | 0 | if (iso10681_frame->offset >= iso10681_frame->len) { |
367 | 0 | iso10681_info->last = true; |
368 | 0 | iso10681_frame->complete = true; |
369 | 0 | len -= (iso10681_frame->offset - iso10681_frame->len); |
370 | 0 | } |
371 | 0 | } |
372 | 0 | pinfo->fragmented = true; |
373 | | |
374 | | /* Add fragment to fragment table */ |
375 | 0 | frag_msg = fragment_add_seq_check(&iso10681_reassembly_table, tvb, offset, pinfo, iso10681_info->seq, NULL, |
376 | 0 | iso10681_info->frag_id, len, !iso10681_info->last); |
377 | |
|
378 | 0 | new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Message", frag_msg, &iso10681_frag_items, NULL, |
379 | 0 | iso10681_tree); |
380 | |
|
381 | 0 | if (frag_msg && frag_msg->reassembled_in != pinfo->num) { |
382 | 0 | col_append_frame_number(pinfo, COL_INFO, " [Reassembled in #%u]", frag_msg->reassembled_in); |
383 | 0 | } |
384 | |
|
385 | 0 | pinfo->fragmented = save_fragmented; |
386 | 0 | } |
387 | |
|
388 | 0 | if (new_tvb) { |
389 | | /* This is a complete TVB to dissect */ |
390 | 0 | next_tvb = new_tvb; |
391 | 0 | complete = true; |
392 | 0 | } else { |
393 | 0 | next_tvb = tvb_new_subset_length(tvb, offset, data_length); |
394 | 0 | } |
395 | 0 | } |
396 | 0 | } |
397 | |
|
398 | 0 | if (next_tvb) { |
399 | 0 | iso10681_info_t iso10681data; |
400 | 0 | iso10681data.id = frame_id; |
401 | 0 | iso10681data.len = frame_length; |
402 | 0 | iso10681data.target_address = target_addr; |
403 | 0 | iso10681data.source_address = source_addr; |
404 | |
|
405 | 0 | if (!complete || !dissector_try_payload_with_data(subdissector_table, next_tvb, pinfo, tree, true, &iso10681data)) { |
406 | 0 | call_data_dissector(next_tvb, pinfo, tree); |
407 | 0 | } |
408 | 0 | } |
409 | |
|
410 | 0 | return tvb_captured_length(tvb); |
411 | 0 | } |
412 | | |
413 | | static int |
414 | 0 | dissect_iso10681_flexray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { |
415 | 0 | DISSECTOR_ASSERT(data); |
416 | 0 | flexray_info_t *flexray_info = (flexray_info_t *)data; |
417 | 0 | uint32_t id = flexray_flexrayinfo_to_flexrayid(flexray_info); |
418 | |
|
419 | 0 | if (iso10681_spread_over_multiple_cycles) { |
420 | | /* masking out the cycle */ |
421 | 0 | id |= FLEXRAY_ID_CYCLE_MASK; |
422 | 0 | } |
423 | |
|
424 | 0 | return dissect_iso10681(tvb, pinfo, tree, id, tvb_captured_length(tvb)); |
425 | 0 | } |
426 | | |
427 | | void |
428 | 16 | proto_register_iso10681(void) { |
429 | 16 | module_t *iso10681_module; |
430 | | |
431 | 16 | static hf_register_info hf[] = { |
432 | 16 | { &hf_iso10681_source_address, { |
433 | 16 | "Source Address", "iso10681.source_address", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, |
434 | 16 | { &hf_iso10681_target_address, { |
435 | 16 | "Target Address", "iso10681.target_address", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, |
436 | 16 | { &hf_iso10681_type, { |
437 | 16 | "Type", "iso10681.type", FT_UINT8, BASE_HEX, VALS(iso10681_message_types), ISO10681_TYPE_MASK, NULL, HFILL } }, |
438 | 16 | { &hf_iso10681_type2, { |
439 | 16 | "Type Ack", "iso10681.type_ack", FT_UINT8, BASE_HEX, VALS(iso10681_start_type2_values), ISO10681_TYPE_PART2_MASK, NULL, HFILL } }, |
440 | 16 | { &hf_iso10681_frame_payload_length, { |
441 | 16 | "Frame Payload Length", "iso10681.frame_payload_length", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
442 | 16 | { &hf_iso10681_message_length, { |
443 | 16 | "Message Length", "iso10681.message_length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } }, |
444 | 16 | { &hf_iso10681_sequence_number, { |
445 | 16 | "Sequence Number", "iso10681.sequence_number", FT_UINT8, BASE_DEC, NULL, ISO10681_TYPE_PART2_MASK, NULL, HFILL } }, |
446 | 16 | { &hf_iso10681_fc_flow_status, { |
447 | 16 | "Flow Status", "iso10681.flow_status", FT_UINT8, BASE_DEC, VALS(iso10681_flow_status_values), ISO10681_TYPE_PART2_MASK, NULL, HFILL } }, |
448 | 16 | { &hf_iso10681_fc_bandwidth_control, { |
449 | 16 | "Bandwidth Control", "iso10681.bandwidth_control", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
450 | 16 | { &hf_iso10681_fc_bc_separation_cycle_exp, { |
451 | 16 | "Separation Cycle Exp", "iso10681.bandwidth_control.separation_cycle_exp", FT_UINT8, BASE_DEC, VALS(iso10681_fc_bc_scexp_values), 0x07, NULL, HFILL } }, |
452 | 16 | { &hf_iso10681_fc_bc_max_num_pdu_per_cycle, { |
453 | 16 | "Max Number of PDUs per Cycle", "iso10681.bandwidth_control.max_number_pdus_per_cycle", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL } }, |
454 | 16 | { &hf_iso10681_fc_buffer_size, { |
455 | 16 | "Buffer Size", "iso10681.buffer_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } }, |
456 | 16 | { &hf_iso10681_fc_ack, { |
457 | 16 | "Ack", "iso10681.ack", FT_UINT8, BASE_HEX, VALS(iso10681_fc_ack_values), 0, NULL, HFILL } }, |
458 | 16 | { &hf_iso10681_fc_byte_position, { |
459 | 16 | "Byte Position", "iso10681.byte_position", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, |
460 | | |
461 | 16 | { &hf_iso10681_fragments, { |
462 | 16 | "Message fragments", "iso10681.fragments", FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
463 | 16 | { &hf_iso10681_fragment, { |
464 | 16 | "Message fragment", "iso10681.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
465 | 16 | { &hf_iso10681_fragment_overlap, { |
466 | 16 | "Message fragment overlap", "iso10681.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
467 | 16 | { &hf_iso10681_fragment_overlap_conflicts, { |
468 | 16 | "Message fragment overlapping with conflicting data", "iso10681.fragment.overlap.conflicts", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
469 | 16 | { &hf_iso10681_fragment_multiple_tails, { |
470 | 16 | "Message has multiple tail fragments", "iso10681.fragment.multiple_tails", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
471 | 16 | { &hf_iso10681_fragment_too_long_fragment, { |
472 | 16 | "Message fragment too long", "iso10681.fragment.too_long_fragment", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
473 | 16 | { &hf_iso10681_fragment_error, { |
474 | 16 | "Message defragmentation error", "iso10681.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
475 | 16 | { &hf_iso10681_fragment_count, { |
476 | 16 | "Message fragment count", "iso10681.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, |
477 | 16 | { &hf_iso10681_reassembled_in, { |
478 | 16 | "Reassembled in", "iso10681.reassembled.in", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
479 | 16 | { &hf_iso10681_reassembled_length, { |
480 | 16 | "Reassembled length", "iso10681.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, |
481 | 16 | }; |
482 | | |
483 | | /* Setup protocol subtree array */ |
484 | 16 | static int *ett[] = { |
485 | 16 | &ett_iso10681, |
486 | 16 | &ett_iso10681_bandwidth_control, |
487 | 16 | &ett_iso10681_fragment, |
488 | 16 | &ett_iso10681_fragments, |
489 | 16 | }; |
490 | | |
491 | 16 | static ei_register_info ei[] = { |
492 | 16 | { |
493 | 16 | &ei_iso10681_message_type_bad, { "iso10681.message_type.bad", PI_MALFORMED, PI_ERROR, "Bad Message Type value", EXPFILL } |
494 | 16 | }, |
495 | 16 | }; |
496 | | |
497 | 16 | expert_module_t* expert_iso10681; |
498 | | |
499 | 16 | proto_iso10681 = proto_register_protocol("ISO10681 Protocol", "ISO 10681", "iso10681"); |
500 | 16 | iso10681_handle_flexray = register_dissector("iso10681", dissect_iso10681_flexray, proto_iso10681); |
501 | | |
502 | | /* Register configuration options */ |
503 | 16 | iso10681_module = prefs_register_protocol(proto_iso10681, proto_reg_handoff_iso10681); |
504 | 16 | prefs_register_range_preference(iso10681_module, "flexray.flexrayids", "FlexRay IDs", |
505 | 16 | "FlexRay IDs (combined) - 4bit Bus-ID (0 any), 4bit Channel, 16bit Frame-ID, 8bit Cycle (0xff any)", |
506 | 16 | &iso10681_flexray_ids, 0xffffffff); |
507 | | |
508 | 16 | prefs_register_bool_preference(iso10681_module, "spread_over_cycles", "Ignore Cycle when matching", |
509 | 16 | "TP frames are spread over multiple cycles. Cycle is ignored for matching.", |
510 | 16 | &iso10681_spread_over_multiple_cycles); |
511 | | |
512 | 16 | proto_register_field_array(proto_iso10681, hf, array_length(hf)); |
513 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
514 | | |
515 | 16 | expert_iso10681 = expert_register_protocol(proto_iso10681); |
516 | 16 | expert_register_field_array(expert_iso10681, ei, array_length(ei)); |
517 | | |
518 | 16 | iso10681_seq_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal); |
519 | 16 | iso10681_frame_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal); |
520 | | |
521 | 16 | reassembly_table_register(&iso10681_reassembly_table, &addresses_reassembly_table_functions); |
522 | | |
523 | 16 | subdissector_table = register_decode_as_next_proto(proto_iso10681, "iso10681.subdissector", "ISO10681 next level dissector", NULL); |
524 | 16 | } |
525 | | |
526 | | void |
527 | 16 | proto_reg_handoff_iso10681(void) { |
528 | 16 | static bool initialized = false; |
529 | | |
530 | 16 | if (!initialized) { |
531 | 16 | dissector_add_for_decode_as("flexray.subdissector", iso10681_handle_flexray); |
532 | | |
533 | 16 | initialized = true; |
534 | 16 | } else { |
535 | 0 | dissector_delete_all("flexray.combined_id", iso10681_handle_flexray); |
536 | 0 | } |
537 | | |
538 | 16 | dissector_add_uint_range("flexray.combined_id", iso10681_flexray_ids, iso10681_handle_flexray); |
539 | 16 | } |
540 | | |
541 | | /* |
542 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
543 | | * |
544 | | * Local variables: |
545 | | * c-basic-offset: 4 |
546 | | * tab-width: 8 |
547 | | * indent-tabs-mode: nil |
548 | | * End: |
549 | | * |
550 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
551 | | * :indentSize=4:tabSize=8:noTabs=true: |
552 | | */ |