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
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
{
52 } iso10681_identifier_t
;
54 typedef struct iso10681_frame
{
60 uint16_t last_frag_id
;
61 uint8_t frag_id_high
[16];
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"},
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"},
83 static const value_string iso10681_start_type2_values
[] = {
84 {0, "Unacknowledged"},
89 static const value_string iso10681_fc_bc_scexp_values
[] = {
101 static const value_string iso10681_fc_ack_values
[] = {
103 {1, "Retry Request"},
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 */
179 iso10681_seqnum(uint32_t frame_id
, bool new_seqnum
) {
182 ret
= (uint32_t *)wmem_map_lookup(iso10681_seq_table
, GUINT_TO_POINTER(frame_id
));
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
);
190 (*ret
) = next_seqnum
++;
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
;
205 iso10681_identifier_t
* iso10681_info
;
206 bool fragmented
= false;
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
);
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)"));
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
);
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
);
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
);
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
);
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
);
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
);
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
,
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
);
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
);
317 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (Flow Status: %s)", val_to_str(flow_status
, iso10681_flow_status_values
, "unknown (0x%x)"));
321 expert_add_info_format(pinfo
, ti_type
, &ei_iso10681_message_type_bad
, "Bad Message Type value %u", type
);
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
, ' '));
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);
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
,
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
;
389 /* This is a complete TVB to dissect */
393 next_tvb
= tvb_new_subset_length(tvb
, offset
, data_length
);
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
);
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
));
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
[] = {
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
);
527 proto_reg_handoff_iso10681(void) {
528 static bool initialized
= false;
531 dissector_add_for_decode_as("flexray.subdissector", iso10681_handle_flexray
);
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
547 * indent-tabs-mode: nil
550 * vi: set shiftwidth=4 tabstop=8 expandtab:
551 * :indentSize=4:tabSize=8:noTabs=true: