Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */