Coverage Report

Created: 2026-11-12 07:01

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