Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-iso10681.c
blobdc7bef4136827a0a973fa0e8e0ad64e600e6b96a
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
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Also see packet-iso15765.c / packet-iso15765.h
15 #include "config.h"
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>
24 #include "packet-iso10681.h"
25 #include "packet-flexray.h"
27 void proto_register_iso10681(void);
28 void proto_reg_handoff_iso10681(void);
30 /* StartFrame or StartFrameAck */
31 #define ISO10681_TYPE_MASK 0xF0
32 #define ISO10681_TYPE_START_FRAME 4
33 #define ISO10681_TYPE_CONSECUTIVE_FRAME_1 5
34 #define ISO10681_TYPE_CONSECUTIVE_FRAME_2 6
35 #define ISO10681_TYPE_CONSECUTIVE_FRAME_EOB 7
36 #define ISO10681_TYPE_FLOW_CONTROL 8
37 #define ISO10681_TYPE_LAST_FRAME 9
39 #define ISO10681_TYPE_PART2_MASK 0x0F
41 #define ISO10681_FLOW_STATUS_CTS 3
42 #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
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;
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;
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}
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}
83 static const value_string iso10681_start_type2_values[] = {
84 {0, "Unacknowledged"},
85 {1, "Acknowledged"},
86 {0, NULL}
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}
101 static const value_string iso10681_fc_ack_values[] = {
102 {0, "Acknowledge"},
103 {1, "Retry Request"},
104 {0, NULL}
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;
123 static int ett_iso10681;
124 static int ett_iso10681_bandwidth_control;
126 static expert_field ei_iso10681_message_type_bad;
128 static int proto_iso10681;
129 static dissector_handle_t iso10681_handle_flexray;
131 static dissector_table_t subdissector_table;
133 static range_t *iso10681_flexray_ids;
134 static bool iso10681_spread_over_multiple_cycles = true;
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;
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;
153 static int ett_iso10681_fragment;
154 static int ett_iso10681_fragments;
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"
178 static uint32_t
179 iso10681_seqnum(uint32_t frame_id, bool new_seqnum) {
180 uint32_t *ret;
182 ret = (uint32_t *)wmem_map_lookup(iso10681_seq_table, GUINT_TO_POINTER(frame_id));
184 if (ret == NULL) {
185 ret = wmem_new0(wmem_file_scope(), uint32_t);
186 *ret = next_seqnum++;
187 wmem_map_insert(iso10681_seq_table, GUINT_TO_POINTER(frame_id), ret);
188 } else {
189 if (new_seqnum) {
190 (*ret) = next_seqnum++;
194 return *ret;
197 static int
198 dissect_iso10681(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t frame_id, uint32_t frame_length _U_) {
199 proto_tree *iso10681_tree;
200 proto_item *ti;
201 proto_item *ti_type;
202 uint32_t type;
203 uint32_t offset;
205 iso10681_identifier_t* iso10681_info;
206 bool fragmented = false;
207 uint32_t seqnum = 0;
209 uint32_t data_length = 0;
210 uint32_t full_len = 0;
211 uint32_t target_addr = 0;
212 uint32_t source_addr = 0;
214 tvbuff_t* next_tvb = NULL;
215 bool complete = false;
217 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISO10681");
218 col_clear(pinfo->cinfo, COL_INFO);
220 iso10681_info = (iso10681_identifier_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_iso10681, 0);
222 if (!iso10681_info) {
223 iso10681_info = wmem_new0(wmem_file_scope(), iso10681_identifier_t);
224 iso10681_info->id = frame_id;
225 iso10681_info->last = false;
226 p_add_proto_data(wmem_file_scope(), pinfo, proto_iso10681, 0, iso10681_info);
229 ti = proto_tree_add_item(tree, proto_iso10681, tvb, 0, -1, ENC_NA);
230 iso10681_tree = proto_item_add_subtree(ti, ett_iso10681);
232 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_target_address, tvb, 0, 2, ENC_BIG_ENDIAN, &target_addr);
233 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_source_address, tvb, 2, 2, ENC_BIG_ENDIAN, &source_addr);
234 offset = 4;
236 ti_type = proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_type, tvb, offset, 1, ENC_BIG_ENDIAN, &type);
237 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(type, iso10681_message_types, "Unknown (0x%02x)"));
239 switch (type) {
240 case ISO10681_TYPE_START_FRAME: {
241 uint32_t type2_value;
242 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_type2, tvb, offset, 1, ENC_BIG_ENDIAN, &type2_value);
243 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str(type2_value, iso10681_start_type2_values, "Unknown (0x%x)"));
245 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_frame_payload_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN, &data_length);
246 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &full_len);
247 offset += 4;
249 fragmented = true;
250 seqnum = 0;
252 if (!(pinfo->fd->visited)) {
253 iso10681_frame_t *iso10681_frame = wmem_new0(wmem_file_scope(), iso10681_frame_t);
254 iso10681_frame->seq = iso10681_info->seq = iso10681_seqnum(frame_id, true);
255 iso10681_frame->len = full_len;
257 wmem_map_insert(iso10681_frame_table, GUINT_TO_POINTER(iso10681_info->seq), iso10681_frame);
260 col_append_fstr(pinfo->cinfo, COL_INFO, " (Segment Length: %d, Total Len: %d)", data_length, full_len);
262 break;
264 case ISO10681_TYPE_CONSECUTIVE_FRAME_1:
265 case ISO10681_TYPE_CONSECUTIVE_FRAME_2:
266 case ISO10681_TYPE_CONSECUTIVE_FRAME_EOB: {
267 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_sequence_number, tvb, offset, 1, ENC_BIG_ENDIAN, &seqnum);
268 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_frame_payload_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN, &data_length);
269 offset += 2;
271 fragmented = true;
273 if (!(pinfo->fd->visited)) {
274 iso10681_info->seq = iso10681_seqnum(frame_id, false);
277 col_append_fstr(pinfo->cinfo, COL_INFO, " (Segment Length: %d, Sequence Number: %d)", data_length, seqnum);
278 break;
280 case ISO10681_TYPE_LAST_FRAME: {
281 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_frame_payload_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN, &data_length);
282 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &full_len);
283 offset += 4;
285 fragmented = true;
287 if (!(pinfo->fd->visited)) {
288 iso10681_info->seq = iso10681_seqnum(frame_id, false);
291 col_append_fstr(pinfo->cinfo, COL_INFO, " (Segment Length: %d, Total Len: %d)", data_length, full_len);
292 break;
294 case ISO10681_TYPE_FLOW_CONTROL: {
295 unsigned flow_status = 0;
296 proto_tree_add_item_ret_uint(iso10681_tree, hf_iso10681_fc_flow_status, tvb, offset, 1, ENC_BIG_ENDIAN, &flow_status);
298 switch (flow_status) {
299 case ISO10681_FLOW_STATUS_CTS: {
300 static int * const bandwidth_control[] = {
301 &hf_iso10681_fc_bc_max_num_pdu_per_cycle,
302 &hf_iso10681_fc_bc_separation_cycle_exp,
303 NULL
306 proto_tree_add_bitmask(iso10681_tree, tvb, offset + 1, hf_iso10681_fc_bandwidth_control, ett_iso10681_bandwidth_control,
307 bandwidth_control, ENC_BIG_ENDIAN);
308 proto_tree_add_item(iso10681_tree, hf_iso10681_fc_buffer_size, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
309 break;
311 case ISO10681_FLOW_STATUS_ACK_RETRY:
312 proto_tree_add_item(iso10681_tree, hf_iso10681_fc_ack, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
313 proto_tree_add_item(iso10681_tree, hf_iso10681_fc_byte_position, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
314 break;
317 col_append_fstr(pinfo->cinfo, COL_INFO, " (Flow Status: %s)", val_to_str(flow_status, iso10681_flow_status_values, "unknown (0x%x)"));
318 break;
320 default:
321 expert_add_info_format(pinfo, ti_type, &ei_iso10681_message_type_bad, "Bad Message Type value %u", type);
322 return offset;
325 /* show data */
326 if (data_length > 0) {
327 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tvb_bytes_to_str_punct(pinfo->pool, tvb, offset, data_length, ' '));
330 if (fragmented) {
331 tvbuff_t *new_tvb = NULL;
332 iso10681_frame_t *iso10681_frame;
333 uint16_t frag_id = seqnum;
335 /* Get frame information */
336 iso10681_frame = (iso10681_frame_t *)wmem_map_lookup(iso10681_frame_table, GUINT_TO_POINTER(iso10681_info->seq));
337 if (iso10681_frame != NULL) {
338 if (type == ISO10681_TYPE_LAST_FRAME) {
339 frag_id = iso10681_frame->last_frag_id + 1;
342 if (!(pinfo->fd->visited)) {
343 DISSECTOR_ASSERT(frag_id < 16);
344 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 DISSECTOR_ASSERT(iso10681_frame->frag_id_high[frag_id] != 0);
347 frag_id += tmp * 16;
349 /* Save the frag_id for subsequent dissection */
350 iso10681_info->frag_id = frag_id;
353 if (!iso10681_frame->error) {
354 bool save_fragmented = pinfo->fragmented;
355 uint32_t len = data_length;
356 fragment_head *frag_msg;
358 /* Check if it's the last packet */
359 if (!(pinfo->fd->visited)) {
360 /* Update the last_frag_id */
361 if (frag_id > iso10681_frame->last_frag_id) {
362 iso10681_frame->last_frag_id = frag_id;
365 iso10681_frame->offset += len;
366 if (iso10681_frame->offset >= iso10681_frame->len) {
367 iso10681_info->last = true;
368 iso10681_frame->complete = true;
369 len -= (iso10681_frame->offset - iso10681_frame->len);
372 pinfo->fragmented = true;
374 /* Add fragment to fragment table */
375 frag_msg = fragment_add_seq_check(&iso10681_reassembly_table, tvb, offset, pinfo, iso10681_info->seq, NULL,
376 iso10681_info->frag_id, len, !iso10681_info->last);
378 new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Message", frag_msg, &iso10681_frag_items, NULL,
379 iso10681_tree);
381 if (frag_msg && frag_msg->reassembled_in != pinfo->num) {
382 col_append_frame_number(pinfo, COL_INFO, " [Reassembled in #%u]", frag_msg->reassembled_in);
385 pinfo->fragmented = save_fragmented;
388 if (new_tvb) {
389 /* This is a complete TVB to dissect */
390 next_tvb = new_tvb;
391 complete = true;
392 } else {
393 next_tvb = tvb_new_subset_length(tvb, offset, data_length);
398 if (next_tvb) {
399 iso10681_info_t iso10681data;
400 iso10681data.id = frame_id;
401 iso10681data.len = frame_length;
402 iso10681data.target_address = target_addr;
403 iso10681data.source_address = source_addr;
405 if (!complete || !dissector_try_payload_with_data(subdissector_table, next_tvb, pinfo, tree, true, &iso10681data)) {
406 call_data_dissector(next_tvb, pinfo, tree);
410 return tvb_captured_length(tvb);
413 static int
414 dissect_iso10681_flexray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) {
415 DISSECTOR_ASSERT(data);
416 flexray_info_t *flexray_info = (flexray_info_t *)data;
417 uint32_t id = flexray_flexrayinfo_to_flexrayid(flexray_info);
419 if (iso10681_spread_over_multiple_cycles) {
420 /* masking out the cycle */
421 id |= FLEXRAY_ID_CYCLE_MASK;
424 return dissect_iso10681(tvb, pinfo, tree, id, tvb_captured_length(tvb));
427 void
428 proto_register_iso10681(void) {
429 module_t *iso10681_module;
431 static hf_register_info hf[] = {
432 { &hf_iso10681_source_address, {
433 "Source Address", "iso10681.source_address", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
434 { &hf_iso10681_target_address, {
435 "Target Address", "iso10681.target_address", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
436 { &hf_iso10681_type, {
437 "Type", "iso10681.type", FT_UINT8, BASE_HEX, VALS(iso10681_message_types), ISO10681_TYPE_MASK, NULL, HFILL } },
438 { &hf_iso10681_type2, {
439 "Type Ack", "iso10681.type_ack", FT_UINT8, BASE_HEX, VALS(iso10681_start_type2_values), ISO10681_TYPE_PART2_MASK, NULL, HFILL } },
440 { &hf_iso10681_frame_payload_length, {
441 "Frame Payload Length", "iso10681.frame_payload_length", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
442 { &hf_iso10681_message_length, {
443 "Message Length", "iso10681.message_length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
444 { &hf_iso10681_sequence_number, {
445 "Sequence Number", "iso10681.sequence_number", FT_UINT8, BASE_DEC, NULL, ISO10681_TYPE_PART2_MASK, NULL, HFILL } },
446 { &hf_iso10681_fc_flow_status, {
447 "Flow Status", "iso10681.flow_status", FT_UINT8, BASE_DEC, VALS(iso10681_flow_status_values), ISO10681_TYPE_PART2_MASK, NULL, HFILL } },
448 { &hf_iso10681_fc_bandwidth_control, {
449 "Bandwidth Control", "iso10681.bandwidth_control", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
450 { &hf_iso10681_fc_bc_separation_cycle_exp, {
451 "Separation Cycle Exp", "iso10681.bandwidth_control.separation_cycle_exp", FT_UINT8, BASE_DEC, VALS(iso10681_fc_bc_scexp_values), 0x07, NULL, HFILL } },
452 { &hf_iso10681_fc_bc_max_num_pdu_per_cycle, {
453 "Max Number of PDUs per Cycle", "iso10681.bandwidth_control.max_number_pdus_per_cycle", FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL } },
454 { &hf_iso10681_fc_buffer_size, {
455 "Buffer Size", "iso10681.buffer_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
456 { &hf_iso10681_fc_ack, {
457 "Ack", "iso10681.ack", FT_UINT8, BASE_HEX, VALS(iso10681_fc_ack_values), 0, NULL, HFILL } },
458 { &hf_iso10681_fc_byte_position, {
459 "Byte Position", "iso10681.byte_position", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
461 { &hf_iso10681_fragments, {
462 "Message fragments", "iso10681.fragments", FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
463 { &hf_iso10681_fragment, {
464 "Message fragment", "iso10681.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
465 { &hf_iso10681_fragment_overlap, {
466 "Message fragment overlap", "iso10681.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
467 { &hf_iso10681_fragment_overlap_conflicts, {
468 "Message fragment overlapping with conflicting data", "iso10681.fragment.overlap.conflicts", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
469 { &hf_iso10681_fragment_multiple_tails, {
470 "Message has multiple tail fragments", "iso10681.fragment.multiple_tails", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
471 { &hf_iso10681_fragment_too_long_fragment, {
472 "Message fragment too long", "iso10681.fragment.too_long_fragment", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
473 { &hf_iso10681_fragment_error, {
474 "Message defragmentation error", "iso10681.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
475 { &hf_iso10681_fragment_count, {
476 "Message fragment count", "iso10681.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
477 { &hf_iso10681_reassembled_in, {
478 "Reassembled in", "iso10681.reassembled.in", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
479 { &hf_iso10681_reassembled_length, {
480 "Reassembled length", "iso10681.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
483 /* Setup protocol subtree array */
484 static int *ett[] = {
485 &ett_iso10681,
486 &ett_iso10681_bandwidth_control,
487 &ett_iso10681_fragment,
488 &ett_iso10681_fragments,
491 static ei_register_info ei[] = {
493 &ei_iso10681_message_type_bad, { "iso10681.message_type.bad", PI_MALFORMED, PI_ERROR, "Bad Message Type value", EXPFILL }
497 expert_module_t* expert_iso10681;
499 proto_iso10681 = proto_register_protocol("ISO10681 Protocol", "ISO 10681", "iso10681");
500 iso10681_handle_flexray = register_dissector("iso10681", dissect_iso10681_flexray, proto_iso10681);
502 /* Register configuration options */
503 iso10681_module = prefs_register_protocol(proto_iso10681, proto_reg_handoff_iso10681);
504 prefs_register_range_preference(iso10681_module, "flexray.flexrayids", "FlexRay IDs",
505 "FlexRay IDs (combined) - 4bit Bus-ID (0 any), 4bit Channel, 16bit Frame-ID, 8bit Cycle (0xff any)",
506 &iso10681_flexray_ids, 0xffffffff);
508 prefs_register_bool_preference(iso10681_module, "spread_over_cycles", "Ignore Cycle when matching",
509 "TP frames are spread over multiple cycles. Cycle is ignored for matching.",
510 &iso10681_spread_over_multiple_cycles);
512 proto_register_field_array(proto_iso10681, hf, array_length(hf));
513 proto_register_subtree_array(ett, array_length(ett));
515 expert_iso10681 = expert_register_protocol(proto_iso10681);
516 expert_register_field_array(expert_iso10681, ei, array_length(ei));
518 iso10681_seq_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal);
519 iso10681_frame_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal);
521 reassembly_table_register(&iso10681_reassembly_table, &addresses_reassembly_table_functions);
523 subdissector_table = register_decode_as_next_proto(proto_iso10681, "iso10681.subdissector", "ISO10681 next level dissector", NULL);
526 void
527 proto_reg_handoff_iso10681(void) {
528 static bool initialized = false;
530 if (!initialized) {
531 dissector_add_for_decode_as("flexray.subdissector", iso10681_handle_flexray);
533 initialized = true;
534 } else {
535 dissector_delete_all("flexray.combined_id", iso10681_handle_flexray);
538 dissector_add_uint_range("flexray.combined_id", iso10681_flexray_ids, iso10681_handle_flexray);
542 * Editor modelines - https://www.wireshark.org/tools/modelines.html
544 * Local variables:
545 * c-basic-offset: 4
546 * tab-width: 8
547 * indent-tabs-mode: nil
548 * End:
550 * vi: set shiftwidth=4 tabstop=8 expandtab:
551 * :indentSize=4:tabSize=8:noTabs=true: