Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/wiretap/ttl.c
Line
Count
Source
1
/* ttl.c
2
 *
3
 * Wiretap Library
4
 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
5
 *
6
 * TTX Logger (TTL) file format from TTTech Computertechnik AG decoder
7
 * for the Wiretap library.
8
 * You can find the PDF with the documentation of the format at
9
 * https://servicearea.tttech-auto.com/ (registration and approval required).
10
 *
11
 * Copyright (c) 2024 by Giovanni Musto <giovanni.musto@partner.italdesign.it>
12
 *
13
 * SPDX-License-Identifier: GPL-2.0-or-later
14
 */
15
16
#include "config.h"
17
0
#define WS_LOG_DOMAIN LOG_DOMAIN_WIRETAP
18
19
#include "ttl.h"
20
21
#include <string.h>
22
#include <epan/dissectors/packet-socketcan.h>
23
#include <epan/dissectors/packet-lin.h>
24
#include <epan/dissectors/packet-flexray.h>
25
#include <wsutil/wslog.h>
26
#include <wsutil/report_message.h>
27
#include <wsutil/filesystem.h>
28
#include <wsutil/strtoi.h>
29
#include <wsutil/pint.h>
30
#include <libxml/tree.h>
31
#include <libxml/parser.h>
32
#include <libxml/xpath.h>
33
#include "file_wrappers.h"
34
#include "wtap_module.h"
35
36
static const uint8_t ttl_magic[] = { 'T', 'T', 'L', ' ' };
37
38
static int ttl_file_type_subtype = -1;
39
40
32
#define TTL_ADDRESS_NAME_PREFS      "file_format_ttl_names"
41
32
#define TTL_ADDRESS_MASTER_PREFS    "file_format_ttl_masters"
42
0
#define TTL_MAX_CORRUPTED_BLOCKS    1024
43
44
void register_ttl(void);
45
static bool ttl_read(wtap* wth, wtap_rec* rec, int* err, char** err_info, int64_t* data_offset);
46
static bool ttl_seek_read(wtap* wth, int64_t seek_off, wtap_rec* rec, int* err, char** err_info);
47
static void ttl_close(wtap* wth);
48
49
typedef struct ttl_data {
50
    uint32_t    block_size;
51
    uint32_t    header_size;
52
    uint32_t    next_interface_id;
53
54
    GHashTable* address_to_iface_ht;
55
    GHashTable* address_to_master_ht;
56
    GHashTable* address_to_name_ht;
57
    GHashTable* segmented_frames_ht;
58
    GHashTable* reassembled_frames_ht;
59
} ttl_t;
60
61
typedef enum ttl_read_validity {
62
    VALIDITY_FH = 1,
63
    VALIDITY_BUF = 2
64
} ttl_read_validity_t;
65
66
/*
67
 * Usually, 'fh' is valid and is used by ttl_read_bytes, but in case of
68
 * segmented entries, 'buf' will be set to the reassembled nested entry.
69
 */
70
typedef struct ttl_read {
71
    union {
72
        FILE_T  fh;
73
        struct {
74
            uint8_t*    buf;
75
            uint32_t    size;
76
            uint32_t    cur_pos;
77
        };
78
    };
79
    ttl_read_validity_t validity;
80
} ttl_read_t;
81
82
/*
83
 * Values smaller than 0 indicate errors, 0 means OK, 1 means everything is
84
 * good, but the entry is unsupported. 2 means that the file looks corrupted
85
 * or unaligned and our caller should try to fix the situation.
86
 */
87
typedef enum {
88
    TTL_ERROR = -1,
89
    TTL_NO_ERROR = 0,
90
    TTL_UNSUPPORTED = 1,
91
    TTL_CORRUPTED = 2
92
} ttl_result_t;
93
94
static ttl_result_t ttl_read_entry(wtap* wth, wtap_rec* rec, int* err, char** err_info, ttl_read_t* in, int64_t offset, int64_t end);
95
96
/*
97
 * This struct is used to map the source address of an entry to an actual
98
 * interface.
99
 *
100
 * The field 'channelB' has meaning only for FlexRay and it means that the
101
 * packet belongs to FlexRay's Channel B.
102
 */
103
typedef struct ttl_addr_to_iface_entry {
104
    int         pkt_encap;
105
    bool        channelB;
106
107
    uint32_t    interface_id;
108
} ttl_addr_to_iface_entry_t;
109
110
typedef struct ttl_segmented_entry {
111
    uint64_t        timestamp;
112
    uint32_t        size;   /* Full size of the reassembled entry */
113
    uint32_t        type;   /* Type of the entry */
114
115
    uint32_t        size_so_far;
116
    uint8_t         next_segment;
117
    unsigned char*  buf;
118
} ttl_segmented_entry_t;
119
120
typedef struct ttl_reassembled_entry {
121
    uint64_t        timestamp;
122
    uint32_t        size;
123
    unsigned char*  buf;
124
} ttl_reassembled_entry_t;
125
126
void
127
0
ttl_free_segmented_entry(void* data) {
128
0
    ttl_segmented_entry_t* item;
129
0
    if (data != NULL) {
130
0
        item = (ttl_segmented_entry_t*)data;
131
0
        if (item->buf != NULL) {
132
0
            g_free(item->buf);
133
0
        }
134
0
        g_free(data);
135
0
    }
136
0
}
137
138
void
139
0
ttl_free_reassembled_entry(void* data) {
140
0
    ttl_reassembled_entry_t* item;
141
0
    if (data != NULL) {
142
0
        item = (ttl_reassembled_entry_t*)data;
143
0
        if (item->buf != NULL) {
144
0
            g_free(item->buf);
145
0
        }
146
0
        g_free(data);
147
0
    }
148
0
}
149
150
static void
151
0
fix_endianness_ttl_fileheader(ttl_fileheader_t* header) {
152
0
    header->version = GUINT32_FROM_LE(header->version);
153
0
    header->block_size = GUINT32_FROM_LE(header->block_size);
154
0
    header->header_size = GUINT32_FROM_LE(header->header_size);
155
0
}
156
157
static void
158
0
fix_endianness_ttl_entryheader(ttl_entryheader_t* header) {
159
0
    header->size_type = GUINT16_FROM_LE(header->size_type);
160
0
    header->dest_addr = GUINT16_FROM_LE(header->dest_addr);
161
0
    header->src_addr = GUINT16_FROM_LE(header->src_addr);
162
0
    header->status_info = GUINT16_FROM_LE(header->status_info);
163
0
}
164
165
/*
166
 * This function returns the "master" address of coupled addresses.
167
 *
168
 * The output is different from the input in two cases:
169
 * 1. Coupled Ethernet channel, such as the slave side of a tap
170
 * 2. FlexRay Channel B, in order to couple it to Channel A
171
 *
172
 * In both cases, the returned address is the one of the "main" channel, so
173
 * that both addresses can be mapped to the same interface.
174
 *
175
 * If a hash table is passed as input, and an entry is present for addr,
176
 * then the stored result is returned. If there's no match, or no hash table
177
 * is passed as input, then the default behaviour applies:
178
 * - For FlexRay, always return corresponding Channel A if addr is Channel B.
179
 * - For Ethernet:
180
 *   - Return the same address if cascade is 0 (i.e. the channel belongs to
181
 *     the logger).
182
 *   - Return the address of the master if addr belongs to a tap (cascade != 0)
183
 */
184
0
uint16_t ttl_get_master_address(GHashTable* ht, uint16_t addr) {
185
0
    uint8_t function = ttl_addr_get_function(addr);
186
187
0
    if (ht != NULL) {
188
0
        void* master;
189
0
        if (g_hash_table_lookup_extended(ht, GUINT_TO_POINTER(addr), NULL, &master)) {
190
0
            return (uint16_t)GPOINTER_TO_UINT(master);
191
0
        }
192
0
    }
193
194
0
    if (ttl_addr_get_cascade(addr) == 0) {  /* The address refers to the logger itself */
195
0
        switch (ttl_addr_get_device(addr))
196
0
        {
197
0
        case TTL_LOGGER_DEVICE_FPGA:
198
0
            switch (function) {
199
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHA_CH2:
200
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHB_CH2:
201
0
                return (addr - 45);
202
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHA_CH3:
203
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHB_CH3:
204
0
                return (addr - 47);
205
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY1B:
206
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY2B:
207
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY3B:
208
0
                return (addr - 1);
209
0
            default:
210
0
                break;
211
0
            }
212
0
            break;
213
0
        case TTL_LOGGER_DEVICE_TRICORE1:
214
0
        case TTL_LOGGER_DEVICE_TRICORE2:
215
0
        case TTL_LOGGER_DEVICE_TRICORE3:
216
0
            if (function == TTL_LOGGER_TRICORE_FUNCTION_FLEXRAYB) {
217
0
                return (addr - 1);
218
0
            }
219
0
            break;
220
0
        case TTL_LOGGER_DEVICE_TDA4x:
221
0
            if (function == TTL_LOGGER_TDA4x_FUNCTION_FLEXRAY1B) {
222
0
                return (addr - 1);
223
0
            }
224
0
            break;
225
0
        case TTL_LOGGER_DEVICE_FPGAA:
226
0
            if (function == TTL_LOGGER_FPGAA_FUNCTION_FLEXRAY1B) {
227
0
                return (addr - 1);
228
0
            }
229
0
            break;
230
0
        case TTL_LOGGER_DEVICE_FPGAB:
231
0
            switch (function) {
232
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHA_CH2:
233
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHB_CH2:
234
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1a_CH2:
235
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1b_CH2:
236
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2a_CH2:
237
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2b_CH2:
238
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3a_CH2:
239
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3b_CH2:
240
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4a_CH2:
241
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4b_CH2:
242
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5a_CH2:
243
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5b_CH2:
244
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6a_CH2:
245
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6b_CH2:
246
0
                return (addr - 14);
247
0
            default:
248
0
                break;
249
0
            }
250
0
            break;
251
0
        default:
252
0
            break;
253
0
        }
254
0
    }
255
0
    else {  /* The address refers to a TAP */
256
0
        switch (ttl_addr_get_device(addr)) {
257
0
        case TTL_TAP_DEVICE_PT15_FPGA:
258
0
            switch (function) {
259
0
            case TTL_PT15_FPGA_FUNCTION_BrdR1b:
260
0
            case TTL_PT15_FPGA_FUNCTION_BrdR2b:
261
0
            case TTL_PT15_FPGA_FUNCTION_BrdR3b:
262
0
            case TTL_PT15_FPGA_FUNCTION_BrdR4b:
263
0
            case TTL_PT15_FPGA_FUNCTION_BrdR5b:
264
0
            case TTL_PT15_FPGA_FUNCTION_BrdR6b:
265
0
                return (addr - 1);
266
0
            default:
267
0
                break;
268
0
            }
269
0
            break;
270
0
        case TTL_TAP_DEVICE_PT20_FPGA:
271
0
            switch (function) {
272
0
            case TTL_PT20_FPGA_FUNCTION_GbEth1b:
273
0
            case TTL_PT20_FPGA_FUNCTION_GbEth2b:
274
0
            case TTL_PT20_FPGA_FUNCTION_GbEth3b:
275
0
                return (addr - 1);
276
0
            default:
277
0
                break;
278
0
            }
279
0
            break;
280
0
        case TTL_TAP_DEVICE_PC3_FPGA:
281
0
            if (function == TTL_PC3_FPGA_FUNCTION_BrdR1b) {
282
0
                return (addr - 1);
283
0
            }
284
0
            break;
285
0
        case TTL_TAP_DEVICE_PC3_AURIX:
286
0
            switch (function) {
287
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY1B:
288
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY2B:
289
0
                return (addr - 1);
290
0
            default:
291
0
                break;
292
0
            }
293
0
            break;
294
0
        default:
295
0
            break;
296
0
        }
297
0
    }
298
299
0
    return addr;
300
0
}
301
302
0
bool ttl_is_chb_addr(uint16_t addr) {
303
0
    uint8_t function = ttl_addr_get_function(addr);
304
305
0
    if (ttl_addr_get_cascade(addr) == 0) {  /* The address refers to the logger itself */
306
0
        switch (ttl_addr_get_device(addr))
307
0
        {
308
0
        case TTL_LOGGER_DEVICE_FPGA:
309
0
            switch (function) {
310
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY1B:
311
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY2B:
312
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY3B:
313
0
                return true;
314
0
            default:
315
0
                break;
316
0
            }
317
0
            break;
318
0
        case TTL_LOGGER_DEVICE_TRICORE1:
319
0
        case TTL_LOGGER_DEVICE_TRICORE2:
320
0
        case TTL_LOGGER_DEVICE_TRICORE3:
321
0
            if (function == TTL_LOGGER_TRICORE_FUNCTION_FLEXRAYB) {
322
0
                return true;
323
0
            }
324
0
            break;
325
0
        case TTL_LOGGER_DEVICE_FPGAA:
326
0
            if (function == TTL_LOGGER_FPGAA_FUNCTION_FLEXRAY1B) {
327
0
                return true;
328
0
            }
329
0
            break;
330
0
        default:
331
0
            break;
332
0
        }
333
0
    }
334
0
    else {  /* The address refers to a TAP */
335
0
        switch (ttl_addr_get_device(addr)) {
336
0
        case TTL_TAP_DEVICE_PC3_AURIX:
337
0
            switch (function) {
338
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY1B:
339
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY2B:
340
0
                return true;
341
0
            default:
342
0
                break;
343
0
            }
344
0
            break;
345
0
        default:
346
0
            break;
347
0
        }
348
0
    }
349
350
0
    return false;
351
0
}
352
353
68
int ttl_get_address_iface_type(uint16_t addr) {
354
68
    uint8_t function = ttl_addr_get_function(addr);
355
356
68
    if (ttl_addr_get_cascade(addr) == 0) { /* The address refers to the logger itself */
357
39
        switch (ttl_addr_get_device(addr))
358
39
        {
359
11
        case TTL_LOGGER_DEVICE_FPGA:
360
11
            switch (function) {
361
0
            case TTL_LOGGER_FPGA_FUNCTION_EXT0_MOST25:
362
0
            case TTL_LOGGER_FPGA_FUNCTION_EXT0_MOST150:
363
0
            case TTL_LOGGER_FPGA_FUNCTION_EXT1_MOST25:
364
0
                return WTAP_ENCAP_MOST;
365
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHA_CH1:
366
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHB_CH1:
367
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHA_CH2:
368
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHB_CH2:
369
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHA_CH3:
370
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHB_CH3:
371
0
                return WTAP_ENCAP_ETHERNET;
372
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY1A:
373
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY1B:
374
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY2A:
375
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY2B:
376
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY3A:
377
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY3B:
378
0
                return WTAP_ENCAP_FLEXRAY;
379
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN1:
380
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN2:
381
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN3:
382
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN4:
383
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN5:
384
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN6:
385
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN7:
386
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN8:
387
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN9:
388
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN10:
389
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN11:
390
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN12:
391
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN13:
392
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN14:
393
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN15:
394
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN16:
395
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN17:
396
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN18:
397
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN19:
398
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN20:
399
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN21:
400
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN22:
401
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN23:
402
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN24:
403
0
                return WTAP_ENCAP_SOCKETCAN;
404
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN1:
405
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN2:
406
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN3:
407
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN4:
408
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN5:
409
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN6:
410
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN7:
411
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN8:
412
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN9:
413
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN10:
414
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN11:
415
1
            case TTL_LOGGER_FPGA_FUNCTION_LIN12:
416
1
                return WTAP_ENCAP_LIN;
417
10
            default:
418
10
                break;
419
11
            }
420
421
10
            break;
422
10
        case TTL_LOGGER_DEVICE_ATOM:
423
6
            switch (function) {
424
0
            case TTL_LOGGER_ATOM_FUNCTION_ETHA:
425
0
            case TTL_LOGGER_ATOM_FUNCTION_ETHB:
426
0
                return WTAP_ENCAP_ETHERNET;
427
6
            default:
428
6
                break;
429
6
            }
430
431
6
            break;
432
10
        case TTL_LOGGER_DEVICE_TRICORE1:
433
10
            switch (function) {
434
0
            case TTL_LOGGER_TRICORE1_FUNCTION_FLEXRAY1A:
435
0
            case TTL_LOGGER_TRICORE1_FUNCTION_FLEXRAY1B:
436
0
            case TTL_LOGGER_TRICORE1_FUNCTION_FLEXRAY1:
437
0
            case TTL_LOGGER_TRICORE1_FUNCTION_FLEXRAY1AB:
438
0
                return WTAP_ENCAP_FLEXRAY;
439
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CAN1:
440
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CAN2:
441
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CAN3:
442
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CAN4:
443
0
                return WTAP_ENCAP_SOCKETCAN;
444
10
            default:
445
10
                break;
446
10
            }
447
448
10
            break;
449
10
        case TTL_LOGGER_DEVICE_TRICORE2:
450
1
            switch (function) {
451
0
            case TTL_LOGGER_TRICORE2_FUNCTION_FLEXRAY2A:
452
0
            case TTL_LOGGER_TRICORE2_FUNCTION_FLEXRAY2B:
453
0
            case TTL_LOGGER_TRICORE2_FUNCTION_FLEXRAY2:
454
0
            case TTL_LOGGER_TRICORE2_FUNCTION_FLEXRAY2AB:
455
0
                return WTAP_ENCAP_FLEXRAY;
456
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CAN6:
457
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CAN7:
458
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CAN10:
459
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CAN12:
460
0
                return WTAP_ENCAP_SOCKETCAN;
461
1
            default:
462
1
                break;
463
1
            }
464
465
1
            break;
466
3
        case TTL_LOGGER_DEVICE_TRICORE3:
467
3
            switch (function) {
468
2
            case TTL_LOGGER_TRICORE3_FUNCTION_FLEXRAY3A:
469
2
            case TTL_LOGGER_TRICORE3_FUNCTION_FLEXRAY3B:
470
2
            case TTL_LOGGER_TRICORE3_FUNCTION_FLEXRAY3:
471
2
            case TTL_LOGGER_TRICORE3_FUNCTION_FLEXRAY3AB:
472
2
                return WTAP_ENCAP_FLEXRAY;
473
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CAN5:
474
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CAN8:
475
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CAN9:
476
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CAN11:
477
0
                return WTAP_ENCAP_SOCKETCAN;
478
1
            default:
479
1
                break;
480
3
            }
481
482
1
            break;
483
1
        case TTL_LOGGER_DEVICE_TDA4x:
484
1
            switch (function) {
485
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN1:
486
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN2:
487
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN3:
488
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN4:
489
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN5:
490
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN6:
491
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN7:
492
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN8:
493
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN9:
494
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN10:
495
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN11:
496
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN12:
497
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN13:
498
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN14:
499
0
                return WTAP_ENCAP_SOCKETCAN;
500
1
            default:
501
1
                break;
502
1
            }
503
504
1
            break;
505
1
        case TTL_LOGGER_DEVICE_FPGAA:
506
1
            switch (function) {
507
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN1:
508
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN2:
509
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN3:
510
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN4:
511
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN5:
512
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN6:
513
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN7:
514
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN8:
515
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN9:
516
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN10:
517
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN11:
518
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN12:
519
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN13:
520
1
            case TTL_LOGGER_FPGAA_FUNCTION_CAN14:
521
1
                return WTAP_ENCAP_SOCKETCAN;
522
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN1:
523
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN2:
524
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN3:
525
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN4:
526
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN5:
527
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN6:
528
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN7:
529
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN8:
530
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN9:
531
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN10:
532
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN11:
533
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN12:
534
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN13:
535
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN14:
536
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN15:
537
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN16:
538
0
                return WTAP_ENCAP_LIN;
539
0
            case TTL_LOGGER_FPGAA_FUNCTION_FLEXRAY1A:
540
0
            case TTL_LOGGER_FPGAA_FUNCTION_FLEXRAY1B:
541
0
                return WTAP_ENCAP_FLEXRAY;
542
0
            default:
543
0
                break;
544
1
            }
545
546
0
            break;
547
0
        case TTL_LOGGER_DEVICE_FPGAB:
548
0
            switch (function) {
549
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHA_CH1:
550
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHB_CH1:
551
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1a_CH1:
552
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1b_CH1:
553
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2a_CH1:
554
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2b_CH1:
555
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3a_CH1:
556
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3b_CH1:
557
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4a_CH1:
558
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4b_CH1:
559
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5a_CH1:
560
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5b_CH1:
561
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6a_CH1:
562
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6b_CH1:
563
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHA_CH2:
564
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHB_CH2:
565
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1a_CH2:
566
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1b_CH2:
567
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2a_CH2:
568
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2b_CH2:
569
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3a_CH2:
570
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3b_CH2:
571
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4a_CH2:
572
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4b_CH2:
573
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5a_CH2:
574
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5b_CH2:
575
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6a_CH2:
576
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6b_CH2:
577
0
                return WTAP_ENCAP_ETHERNET;
578
0
            default:
579
0
                break;
580
0
            }
581
582
0
            break;
583
6
        default:
584
6
            break;
585
39
        }
586
39
    }
587
29
    else {  /* The address refers to a TAP */
588
29
        switch (ttl_addr_get_device(addr)) {
589
3
        case TTL_TAP_DEVICE_PT15_FPGA:
590
3
            switch (function) {
591
0
            case TTL_PT15_FPGA_FUNCTION_CAN1:
592
0
            case TTL_PT15_FPGA_FUNCTION_CAN2:
593
0
                return WTAP_ENCAP_SOCKETCAN;
594
0
            case TTL_PT15_FPGA_FUNCTION_BrdR1a:
595
0
            case TTL_PT15_FPGA_FUNCTION_BrdR1b:
596
0
            case TTL_PT15_FPGA_FUNCTION_BrdR2a:
597
0
            case TTL_PT15_FPGA_FUNCTION_BrdR2b:
598
0
            case TTL_PT15_FPGA_FUNCTION_BrdR3a:
599
0
            case TTL_PT15_FPGA_FUNCTION_BrdR3b:
600
0
            case TTL_PT15_FPGA_FUNCTION_BrdR4a:
601
0
            case TTL_PT15_FPGA_FUNCTION_BrdR4b:
602
0
            case TTL_PT15_FPGA_FUNCTION_BrdR5a:
603
0
            case TTL_PT15_FPGA_FUNCTION_BrdR5b:
604
0
            case TTL_PT15_FPGA_FUNCTION_BrdR6a:
605
0
            case TTL_PT15_FPGA_FUNCTION_BrdR6b:
606
0
                return WTAP_ENCAP_ETHERNET;
607
0
            case TTL_PT15_FPGA_FUNCTION_MDIO:   /* TODO: Support this */
608
3
            default:
609
3
                break;
610
3
            }
611
612
3
            break;
613
3
        case TTL_TAP_DEVICE_PT20_FPGA:
614
3
            switch (function) {
615
0
            case TTL_PT20_FPGA_FUNCTION_CAN1:
616
2
            case TTL_PT20_FPGA_FUNCTION_CAN2:
617
2
            case TTL_PT20_FPGA_FUNCTION_CAN3:
618
2
            case TTL_PT20_FPGA_FUNCTION_CAN4:
619
2
            case TTL_PT20_FPGA_FUNCTION_CAN5:
620
2
                return WTAP_ENCAP_SOCKETCAN;
621
0
            case TTL_PT20_FPGA_FUNCTION_GbEth1a:
622
0
            case TTL_PT20_FPGA_FUNCTION_GbEth1b:
623
0
            case TTL_PT20_FPGA_FUNCTION_GbEth2a:
624
0
            case TTL_PT20_FPGA_FUNCTION_GbEth2b:
625
0
            case TTL_PT20_FPGA_FUNCTION_GbEth3a:
626
0
            case TTL_PT20_FPGA_FUNCTION_GbEth3b:
627
0
                return WTAP_ENCAP_ETHERNET;
628
0
            case TTL_PT20_FPGA_FUNCTION_MDIO:   /* TODO: Support this */
629
1
            default:
630
1
                break;
631
3
            }
632
633
1
            break;
634
4
        case TTL_TAP_DEVICE_PC3_FPGA:
635
4
            switch (function) {
636
0
            case TTL_PC3_FPGA_FUNCTION_BrdR1a:
637
0
            case TTL_PC3_FPGA_FUNCTION_BrdR1b:
638
0
                return WTAP_ENCAP_ETHERNET;
639
4
            default:
640
4
                break;
641
4
            }
642
643
4
            break;
644
4
        case TTL_TAP_DEVICE_PC3_AURIX:
645
1
            switch (function) {
646
0
            case TTL_PC3_AURIX_FUNCTION_CAN1:
647
0
            case TTL_PC3_AURIX_FUNCTION_CAN2:
648
0
            case TTL_PC3_AURIX_FUNCTION_CAN3:
649
0
            case TTL_PC3_AURIX_FUNCTION_CAN4:
650
0
                return WTAP_ENCAP_SOCKETCAN;
651
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY1A:
652
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY1B:
653
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY2A:
654
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY2B:
655
0
                return WTAP_ENCAP_FLEXRAY;
656
1
            default:
657
1
                break;
658
1
            }
659
660
1
            break;
661
2
        case TTL_TAP_DEVICE_ZELDA_CANFD:
662
2
            switch (function) {
663
0
            case TTL_TAP_DEVICE_ZELDA_CANFD1:
664
0
            case TTL_TAP_DEVICE_ZELDA_CANFD2:
665
0
            case TTL_TAP_DEVICE_ZELDA_CANFD3:
666
0
            case TTL_TAP_DEVICE_ZELDA_CANFD4:
667
0
            case TTL_TAP_DEVICE_ZELDA_CANFD5:
668
0
            case TTL_TAP_DEVICE_ZELDA_CANFD6:
669
0
            case TTL_TAP_DEVICE_ZELDA_CANFD7:
670
0
            case TTL_TAP_DEVICE_ZELDA_CANFD8:
671
0
            case TTL_TAP_DEVICE_ZELDA_CANFD9:
672
0
            case TTL_TAP_DEVICE_ZELDA_CANFD10:
673
0
            case TTL_TAP_DEVICE_ZELDA_CANFD11:
674
1
            case TTL_TAP_DEVICE_ZELDA_CANFD12:
675
1
            case TTL_TAP_DEVICE_ZELDA_CANFD13:
676
1
            case TTL_TAP_DEVICE_ZELDA_CANFD14:
677
1
            case TTL_TAP_DEVICE_ZELDA_CANFD15:
678
1
                return WTAP_ENCAP_SOCKETCAN;
679
1
            default:
680
1
                break;
681
2
            }
682
683
1
            break;
684
12
        case TTL_TAP_DEVICE_ZELDA_LIN:
685
12
            switch (function) {
686
4
            case TTL_TAP_DEVICE_ZELDA_LIN1:
687
4
            case TTL_TAP_DEVICE_ZELDA_LIN2:
688
4
            case TTL_TAP_DEVICE_ZELDA_LIN3:
689
4
            case TTL_TAP_DEVICE_ZELDA_LIN4:
690
4
            case TTL_TAP_DEVICE_ZELDA_LIN5:
691
6
            case TTL_TAP_DEVICE_ZELDA_LIN6:
692
6
            case TTL_TAP_DEVICE_ZELDA_LIN7:
693
6
            case TTL_TAP_DEVICE_ZELDA_LIN8:
694
6
            case TTL_TAP_DEVICE_ZELDA_LIN9:
695
6
            case TTL_TAP_DEVICE_ZELDA_LIN10:
696
6
            case TTL_TAP_DEVICE_ZELDA_LIN11:
697
6
            case TTL_TAP_DEVICE_ZELDA_LIN12:
698
6
            case TTL_TAP_DEVICE_ZELDA_LIN13:
699
6
            case TTL_TAP_DEVICE_ZELDA_LIN14:
700
6
            case TTL_TAP_DEVICE_ZELDA_LIN15:
701
6
            case TTL_TAP_DEVICE_ZELDA_LIN16:
702
6
            case TTL_TAP_DEVICE_ZELDA_LIN17:
703
6
            case TTL_TAP_DEVICE_ZELDA_LIN18:
704
6
            case TTL_TAP_DEVICE_ZELDA_LIN19:
705
6
            case TTL_TAP_DEVICE_ZELDA_LIN20:
706
6
            case TTL_TAP_DEVICE_ZELDA_LIN21:
707
6
            case TTL_TAP_DEVICE_ZELDA_LIN22:
708
6
            case TTL_TAP_DEVICE_ZELDA_LIN23:
709
6
            case TTL_TAP_DEVICE_ZELDA_LIN24:
710
6
                return WTAP_ENCAP_LIN;
711
6
            default:
712
6
                break;
713
12
            }
714
715
6
            break;
716
6
        default:
717
4
            break;
718
29
        }
719
29
    }
720
721
55
    return WTAP_ENCAP_UNKNOWN;
722
68
}
723
724
static const char* const ttl_cascade_names[] = { "Logger", "Tap1", "Tap2", "Tap3", "Tap4", "Tap5", "Tap6", "Tap7" };
725
726
0
const char* ttl_get_cascade_name(uint16_t addr) {
727
0
    return ttl_cascade_names[ttl_addr_get_cascade(addr)];
728
0
}
729
730
0
const char* ttl_get_device_name(uint16_t addr) {
731
0
    if (ttl_addr_get_cascade(addr) == 0) {
732
0
        switch (ttl_addr_get_device(addr)) {
733
0
        case TTL_LOGGER_DEVICE_FPGA:
734
0
        case TTL_LOGGER_DEVICE_FPGAA:
735
0
        case TTL_LOGGER_DEVICE_FPGAB:
736
0
            return "FPGA";
737
0
        case TTL_LOGGER_DEVICE_ATOM:
738
0
            return "Atom";
739
0
        case TTL_LOGGER_DEVICE_TRICORE1:
740
0
        case TTL_LOGGER_DEVICE_TRICORE2:
741
0
        case TTL_LOGGER_DEVICE_TRICORE3:
742
0
            return "Tricore";
743
0
        case TTL_LOGGER_DEVICE_TDA4x:
744
0
            return "TDA4x";
745
0
        default:
746
0
            break;
747
0
        }
748
0
    }
749
0
    else {
750
0
        switch (ttl_addr_get_device(addr)) {
751
0
        case TTL_TAP_DEVICE_PT15_FPGA:
752
0
        case TTL_TAP_DEVICE_PT15_HPS_LINUX:
753
0
            return "PT15";
754
0
        case TTL_TAP_DEVICE_PT20_FPGA:
755
0
        case TTL_TAP_DEVICE_PT20_HPS_LINUX:
756
0
            return "PT20";
757
0
        case TTL_TAP_DEVICE_PC3_FPGA:
758
0
        case TTL_TAP_DEVICE_PC3_HPS_LINUX:
759
0
        case TTL_TAP_DEVICE_PC3_AURIX:
760
0
            return "PC3";
761
0
        case TTL_TAP_DEVICE_ZELDA_CANFD:
762
0
        case TTL_TAP_DEVICE_ZELDA_LIN:
763
0
            return "Zelda";
764
0
        default:
765
0
            break;
766
0
        }
767
0
    }
768
769
0
    return "Unknown";
770
0
}
771
772
0
const char* ttl_get_function_name(uint16_t addr) {
773
0
    uint8_t function = ttl_addr_get_function(addr);
774
775
0
    if (ttl_addr_get_cascade(addr) == 0) {
776
0
        switch (ttl_addr_get_device(addr)) {
777
0
        case TTL_LOGGER_DEVICE_FPGA:
778
0
            switch (function) {
779
0
            case TTL_LOGGER_FPGA_FUNCTION_CORE:
780
0
                return "Core";
781
0
            case TTL_LOGGER_FPGA_FUNCTION_EXT0_MOST25:
782
0
                return "Ext0_MOST25";
783
0
            case TTL_LOGGER_FPGA_FUNCTION_EXT0_MOST150:
784
0
                return "MOST150";
785
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHA_CH1:
786
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHA_CH2:
787
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHA_CH3:
788
0
                return "EthernetA";
789
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHB_CH1:
790
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHB_CH2:
791
0
            case TTL_LOGGER_FPGA_FUNCTION_ETHB_CH3:
792
0
                return "EthernetB";
793
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY1A:
794
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY1B:
795
0
                return "FlexRay1";
796
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY2A:
797
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY2B:
798
0
                return "FlexRay2";
799
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY3A:
800
0
            case TTL_LOGGER_FPGA_FUNCTION_FLEXRAY3B:
801
0
                return "FlexRay3";
802
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN1:
803
0
                return "CAN1";
804
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN2:
805
0
                return "CAN2";
806
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN3:
807
0
                return "CAN3";
808
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN4:
809
0
                return "CAN4";
810
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN5:
811
0
                return "CAN5";
812
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN6:
813
0
                return "CAN6";
814
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN7:
815
0
                return "CAN7";
816
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN8:
817
0
                return "CAN8";
818
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN9:
819
0
                return "CAN9";
820
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN10:
821
0
                return "CAN10";
822
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN11:
823
0
                return "CAN11";
824
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN12:
825
0
                return "CAN12";
826
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN13:
827
0
                return "CAN13";
828
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN14:
829
0
                return "CAN14";
830
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN15:
831
0
                return "CAN15";
832
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN16:
833
0
                return "CAN16";
834
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN17:
835
0
                return "CAN17";
836
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN18:
837
0
                return "CAN18";
838
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN19:
839
0
                return "CAN19";
840
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN20:
841
0
                return "CAN20";
842
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN21:
843
0
                return "CAN21";
844
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN22:
845
0
                return "CAN22";
846
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN23:
847
0
                return "CAN23";
848
0
            case TTL_LOGGER_FPGA_FUNCTION_CAN24:
849
0
                return "CAN24";
850
0
            case TTL_LOGGER_FPGA_FUNCTION_EXT1_MOST25:
851
0
                return "MOST25";
852
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN1:
853
0
                return "LIN1";
854
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN2:
855
0
                return "LIN2";
856
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN3:
857
0
                return "LIN3";
858
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN4:
859
0
                return "LIN4";
860
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN5:
861
0
                return "LIN5";
862
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN6:
863
0
                return "LIN6";
864
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN7:
865
0
                return "LIN7";
866
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN8:
867
0
                return "LIN8";
868
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN9:
869
0
                return "LIN9";
870
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN10:
871
0
                return "LIN10";
872
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN11:
873
0
                return "LIN11";
874
0
            case TTL_LOGGER_FPGA_FUNCTION_LIN12:
875
0
                return "LIN12";
876
0
            default:
877
0
                break;
878
0
            }
879
0
            break;
880
0
        case TTL_LOGGER_DEVICE_ATOM:
881
0
            switch (function) {
882
0
            case TTL_LOGGER_ATOM_FUNCTION_ETHA:
883
0
                return "EthernetA";
884
0
            case TTL_LOGGER_ATOM_FUNCTION_ETHB:
885
0
                return "EthernetB";
886
0
            default:
887
0
                break;
888
0
            }
889
0
            break;
890
0
        case TTL_LOGGER_DEVICE_TRICORE1:
891
0
            switch (function) {
892
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CORE:
893
0
                return "Core1";
894
0
            case TTL_LOGGER_TRICORE1_FUNCTION_FLEXRAY1A:
895
0
            case TTL_LOGGER_TRICORE1_FUNCTION_FLEXRAY1B:
896
0
            case TTL_LOGGER_TRICORE1_FUNCTION_FLEXRAY1:
897
0
            case TTL_LOGGER_TRICORE1_FUNCTION_FLEXRAY1AB:
898
0
                return "FlexRay1";
899
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CAN1:
900
0
                return "CAN1";
901
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CAN2:
902
0
                return "CAN2";
903
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CAN3:
904
0
                return "CAN3";
905
0
            case TTL_LOGGER_TRICORE1_FUNCTION_CAN4:
906
0
                return "CAN4";
907
0
            case TTL_LOGGER_TRICORE1_FUNCTION_ANALOGOUT1:
908
0
                return "AnalogOut1";
909
0
            case TTL_LOGGER_TRICORE1_FUNCTION_DIGITALOUT5:
910
0
                return "DigitalOut5";
911
0
            case TTL_LOGGER_TRICORE1_FUNCTION_DIGITALOUT6:
912
0
                return "DigitalOut6";
913
0
            case TTL_LOGGER_TRICORE1_FUNCTION_SERIAL1:
914
0
                return "Serial1";
915
0
            case TTL_LOGGER_TRICORE1_FUNCTION_SERIAL2:
916
0
                return "Serial2";
917
0
            case TTL_LOGGER_TRICORE1_FUNCTION_ANALOGIN6:
918
0
                return "AnalogIn6";
919
0
            case TTL_LOGGER_TRICORE1_FUNCTION_ANALOGIN8:
920
0
                return "AnalogIn8";
921
0
            case TTL_LOGGER_TRICORE1_FUNCTION_ANALOGIN11:
922
0
                return "AnalogIn11";
923
0
            case TTL_LOGGER_TRICORE1_FUNCTION_ANALOGIN14:
924
0
                return "AnalogIn14";
925
0
            case TTL_LOGGER_TRICORE1_FUNCTION_ANALOGIN15:
926
0
                return "AnalogIn15";
927
0
            case TTL_LOGGER_TRICORE1_FUNCTION_DIGITALIN8:
928
0
                return "DigitalIn8";
929
0
            case TTL_LOGGER_TRICORE1_FUNCTION_DIGITALIN10:
930
0
                return "DigitalIn10";
931
0
            case TTL_LOGGER_TRICORE1_FUNCTION_DIGITALIN11:
932
0
                return "DigitalIn11";
933
0
            case TTL_LOGGER_TRICORE1_FUNCTION_DIGITALIN12:
934
0
                return "DigitalIn12";
935
0
            case TTL_LOGGER_TRICORE1_FUNCTION_DIGITALIN13:
936
0
                return "DigitalIn13";
937
0
            case TTL_LOGGER_TRICORE1_FUNCTION_KL15IN:
938
0
                return "KL15";
939
0
            case TTL_LOGGER_TRICORE1_FUNCTION_KL30IN:
940
0
                return "KL30";
941
0
            default:
942
0
                break;
943
0
            }
944
0
            break;
945
0
        case TTL_LOGGER_DEVICE_TRICORE2:
946
0
            switch (function) {
947
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CORE:
948
0
                return "Core2";
949
0
            case TTL_LOGGER_TRICORE2_FUNCTION_FLEXRAY2A:
950
0
            case TTL_LOGGER_TRICORE2_FUNCTION_FLEXRAY2B:
951
0
            case TTL_LOGGER_TRICORE2_FUNCTION_FLEXRAY2:
952
0
            case TTL_LOGGER_TRICORE2_FUNCTION_FLEXRAY2AB:
953
0
                return "FlexRay2";
954
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CAN6:
955
0
                return "CAN6";
956
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CAN7:
957
0
                return "CAN7";
958
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CAN10:
959
0
                return "CAN10";
960
0
            case TTL_LOGGER_TRICORE2_FUNCTION_CAN12:
961
0
                return "CAN12";
962
0
            case TTL_LOGGER_TRICORE2_FUNCTION_ANALOGOUT2:
963
0
                return "AnalogOut2";
964
0
            case TTL_LOGGER_TRICORE2_FUNCTION_DIGITALOUT3:
965
0
                return "DigitalOut3";
966
0
            case TTL_LOGGER_TRICORE2_FUNCTION_DIGITALOUT4:
967
0
                return "DigitalOut4";
968
0
            case TTL_LOGGER_TRICORE2_FUNCTION_SERIAL3:
969
0
                return "Serial3";
970
0
            case TTL_LOGGER_TRICORE2_FUNCTION_SERIAL4:
971
0
                return "Serial4";
972
0
            case TTL_LOGGER_TRICORE2_FUNCTION_ANALOGIN3:
973
0
                return "AnalogIn3";
974
0
            case TTL_LOGGER_TRICORE2_FUNCTION_ANALOGIN4:
975
0
                return "AnalogIn4";
976
0
            case TTL_LOGGER_TRICORE2_FUNCTION_ANALOGIN5:
977
0
                return "AnalogIn5";
978
0
            case TTL_LOGGER_TRICORE2_FUNCTION_ANALOGIN7:
979
0
                return "AnalogIn7";
980
0
            case TTL_LOGGER_TRICORE2_FUNCTION_ANALOGIN9:
981
0
                return "AnalogIn9";
982
0
            case TTL_LOGGER_TRICORE2_FUNCTION_DIGITALIN6:
983
0
                return "DigitalIn6";
984
0
            case TTL_LOGGER_TRICORE2_FUNCTION_DIGITALIN7:
985
0
                return "DigitalIn7";
986
0
            case TTL_LOGGER_TRICORE2_FUNCTION_DIGITALIN9:
987
0
                return "DigitalIn9";
988
0
            case TTL_LOGGER_TRICORE2_FUNCTION_DIGITALIN14:
989
0
                return "DigitalIn14";
990
0
            case TTL_LOGGER_TRICORE2_FUNCTION_DIGITALIN15:
991
0
                return "DigitalIn15";
992
0
            default:
993
0
                break;
994
0
            }
995
0
            break;
996
0
        case TTL_LOGGER_DEVICE_TRICORE3:
997
0
            switch (function) {
998
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CORE:
999
0
                return "Core3";
1000
0
            case TTL_LOGGER_TRICORE3_FUNCTION_FLEXRAY3A:
1001
0
            case TTL_LOGGER_TRICORE3_FUNCTION_FLEXRAY3B:
1002
0
            case TTL_LOGGER_TRICORE3_FUNCTION_FLEXRAY3:
1003
0
            case TTL_LOGGER_TRICORE3_FUNCTION_FLEXRAY3AB:
1004
0
                return "FlexRay3";
1005
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CAN5:
1006
0
                return "CAN5";
1007
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CAN8:
1008
0
                return "CAN8";
1009
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CAN9:
1010
0
                return "CAN9";
1011
0
            case TTL_LOGGER_TRICORE3_FUNCTION_CAN11:
1012
0
                return "CAN11";
1013
0
            case TTL_LOGGER_TRICORE3_FUNCTION_ANALOGOUT3:
1014
0
                return "AnalogOut3";
1015
0
            case TTL_LOGGER_TRICORE3_FUNCTION_DIGITALOUT1:
1016
0
                return "DigitalOut1";
1017
0
            case TTL_LOGGER_TRICORE3_FUNCTION_DIGITALOUT2:
1018
0
                return "DigitalOut2";
1019
0
            case TTL_LOGGER_TRICORE3_FUNCTION_SERIAL5:
1020
0
                return "Serial5";
1021
0
            case TTL_LOGGER_TRICORE3_FUNCTION_SERIAL6:
1022
0
                return "Serial6";
1023
0
            case TTL_LOGGER_TRICORE3_FUNCTION_ANALOGIN1:
1024
0
                return "AnalogIn1";
1025
0
            case TTL_LOGGER_TRICORE3_FUNCTION_ANALOGIN2:
1026
0
                return "AnalogIn2";
1027
0
            case TTL_LOGGER_TRICORE3_FUNCTION_ANALOGIN10:
1028
0
                return "AnalogIn10";
1029
0
            case TTL_LOGGER_TRICORE3_FUNCTION_ANALOGIN12:
1030
0
                return "AnalogIn12";
1031
0
            case TTL_LOGGER_TRICORE3_FUNCTION_ANALOGIN13:
1032
0
                return "AnalogIn13";
1033
0
            case TTL_LOGGER_TRICORE3_FUNCTION_DIGITALIN1:
1034
0
                return "DigitalIn1";
1035
0
            case TTL_LOGGER_TRICORE3_FUNCTION_DIGITALIN2:
1036
0
                return "DigitalIn2";
1037
0
            case TTL_LOGGER_TRICORE3_FUNCTION_DIGITALIN3:
1038
0
                return "DigitalIn3";
1039
0
            case TTL_LOGGER_TRICORE3_FUNCTION_DIGITALIN4:
1040
0
                return "DigitalIn4";
1041
0
            case TTL_LOGGER_TRICORE3_FUNCTION_DIGITALIN5:
1042
0
                return "DigitalIn5";
1043
0
            default:
1044
0
                break;
1045
0
            }
1046
0
            break;
1047
0
        case TTL_LOGGER_DEVICE_TDA4x:
1048
0
            switch (function) {
1049
0
            case TTL_LOGGER_TDA4x_FUNCTION_CORE:
1050
0
                return "Core";
1051
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN1:
1052
0
                return "CAN1";
1053
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN2:
1054
0
                return "CAN2";
1055
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN3:
1056
0
                return "CAN3";
1057
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN4:
1058
0
                return "CAN4";
1059
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN5:
1060
0
                return "CAN5";
1061
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN6:
1062
0
                return "CAN6";
1063
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN7:
1064
0
                return "CAN7";
1065
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN8:
1066
0
                return "CAN8";
1067
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN9:
1068
0
                return "CAN9";
1069
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN10:
1070
0
                return "CAN10";
1071
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN11:
1072
0
                return "CAN11";
1073
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL1:
1074
0
                return "Serial1";
1075
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL2:
1076
0
                return "Serial2";
1077
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL3:
1078
0
                return "Serial3";
1079
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL4:
1080
0
                return "Serial4";
1081
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL5:
1082
0
                return "Serial5";
1083
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL6:
1084
0
                return "Serial6";
1085
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL7:
1086
0
                return "Serial7";
1087
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL8:
1088
0
                return "Serial8";
1089
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL9:
1090
0
                return "Serial9";
1091
0
            case TTL_LOGGER_TDA4x_FUNCTION_SERIAL10:
1092
0
                return "Serial10";
1093
0
            case TTL_LOGGER_TDA4x_FUNCTION_ANALOGIN1:
1094
0
                return "AnalogIn1";
1095
0
            case TTL_LOGGER_TDA4x_FUNCTION_ANALOGIN2:
1096
0
                return "AnalogIn2";
1097
0
            case TTL_LOGGER_TDA4x_FUNCTION_ANALOGIN3:
1098
0
                return "AnalogIn3";
1099
0
            case TTL_LOGGER_TDA4x_FUNCTION_ANALOGIN4:
1100
0
                return "AnalogIn4";
1101
0
            case TTL_LOGGER_TDA4x_FUNCTION_ANALOGIN5:
1102
0
                return "AnalogIn5";
1103
0
            case TTL_LOGGER_TDA4x_FUNCTION_ANALOGIN6:
1104
0
                return "AnalogIn6";
1105
0
            case TTL_LOGGER_TDA4x_FUNCTION_ANALOGOUT1:
1106
0
                return "AnalogOut1";
1107
0
            case TTL_LOGGER_TDA4x_FUNCTION_ANALOGOUT2:
1108
0
                return "AnalogOut2";
1109
0
            case TTL_LOGGER_TDA4x_FUNCTION_KL15IN:
1110
0
                return "KL15";
1111
0
            case TTL_LOGGER_TDA4x_FUNCTION_KL30IN:
1112
0
                return "KL30";
1113
0
            case TTL_LOGGER_TDA4x_FUNCTION_FLEXRAY1A:
1114
0
            case TTL_LOGGER_TDA4x_FUNCTION_FLEXRAY1B:
1115
0
            case TTL_LOGGER_TDA4x_FUNCTION_FLEXRAY1AB:
1116
0
                return "FlexRay1";
1117
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN12:
1118
0
                return "CAN12";
1119
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN13:
1120
0
                return "CAN13";
1121
0
            case TTL_LOGGER_TDA4x_FUNCTION_CAN14:
1122
0
                return "CAN14";
1123
1124
0
            default:
1125
0
                break;
1126
0
            }
1127
0
            break;
1128
0
        case TTL_LOGGER_DEVICE_FPGAA:
1129
0
            switch (function) {
1130
0
            case TTL_LOGGER_FPGAA_FUNCTION_CORE:
1131
0
                return "Core";
1132
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN1:
1133
0
                return "CAN1";
1134
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN2:
1135
0
                return "CAN2";
1136
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN3:
1137
0
                return "CAN3";
1138
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN4:
1139
0
                return "CAN4";
1140
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN5:
1141
0
                return "CAN5";
1142
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN6:
1143
0
                return "CAN6";
1144
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN7:
1145
0
                return "CAN7";
1146
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN8:
1147
0
                return "CAN8";
1148
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN9:
1149
0
                return "CAN9";
1150
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN10:
1151
0
                return "CAN10";
1152
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN11:
1153
0
                return "CAN11";
1154
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN1:
1155
0
                return "LIN1";
1156
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN2:
1157
0
                return "LIN2";
1158
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN3:
1159
0
                return "LIN3";
1160
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN4:
1161
0
                return "LIN4";
1162
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN5:
1163
0
                return "LIN5";
1164
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN6:
1165
0
                return "LIN6";
1166
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN7:
1167
0
                return "LIN7";
1168
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN8:
1169
0
                return "LIN8";
1170
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN9:
1171
0
                return "LIN9";
1172
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN10:
1173
0
                return "LIN10";
1174
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN11:
1175
0
                return "LIN11";
1176
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN12:
1177
0
                return "LIN12";
1178
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN13:
1179
0
                return "LIN13";
1180
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN14:
1181
0
                return "LIN14";
1182
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN15:
1183
0
                return "LIN15";
1184
0
            case TTL_LOGGER_FPGAA_FUNCTION_LIN16:
1185
0
                return "LIN16";
1186
0
            case TTL_LOGGER_FPGAA_FUNCTION_FLEXRAY1A:
1187
0
            case TTL_LOGGER_FPGAA_FUNCTION_FLEXRAY1B:
1188
0
                return "FlexRay1";
1189
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL1:
1190
0
                return "Serial1";
1191
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL2:
1192
0
                return "Serial2";
1193
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL3:
1194
0
                return "Serial3";
1195
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL4:
1196
0
                return "Serial4";
1197
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL5:
1198
0
                return "Serial5";
1199
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL6:
1200
0
                return "Serial6";
1201
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL7:
1202
0
                return "Serial7";
1203
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL8:
1204
0
                return "Serial8";
1205
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL9:
1206
0
                return "Serial9";
1207
0
            case TTL_LOGGER_FPGAA_FUNCTION_SERIAL10:
1208
0
                return "Serial10";
1209
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN12:
1210
0
                return "CAN12";
1211
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN13:
1212
0
                return "CAN13";
1213
0
            case TTL_LOGGER_FPGAA_FUNCTION_CAN14:
1214
0
                return "CAN14";
1215
0
            default:
1216
0
                break;
1217
0
            }
1218
0
            break;
1219
0
        case TTL_LOGGER_DEVICE_FPGAB:
1220
0
            switch (function) {
1221
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHA_CH1:
1222
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHA_CH2:
1223
0
                return "EthernetA";
1224
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHB_CH1:
1225
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHB_CH2:
1226
0
                return "EthernetB";
1227
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1a_CH1:
1228
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1a_CH2:
1229
0
                return "AutomotiveEthernet1a";
1230
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1b_CH1:
1231
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1b_CH2:
1232
0
                return "AutomotiveEthernet1b";
1233
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2a_CH1:
1234
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2a_CH2:
1235
0
                return "AutomotiveEthernet2a";
1236
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2b_CH1:
1237
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2b_CH2:
1238
0
                return "AutomotiveEthernet2b";
1239
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3a_CH1:
1240
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3a_CH2:
1241
0
                return "AutomotiveEthernet3a";
1242
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3b_CH1:
1243
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3b_CH2:
1244
0
                return "AutomotiveEthernet3b";
1245
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4a_CH1:
1246
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4a_CH2:
1247
0
                return "AutomotiveEthernet4a";
1248
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4b_CH1:
1249
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4b_CH2:
1250
0
                return "AutomotiveEthernet4b";
1251
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5a_CH1:
1252
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5a_CH2:
1253
0
                return "AutomotiveEthernet5a";
1254
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5b_CH1:
1255
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5b_CH2:
1256
0
                return "AutomotiveEthernet5b";
1257
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6a_CH1:
1258
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6a_CH2:
1259
0
                return "AutomotiveEthernet6a";
1260
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6b_CH1:
1261
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6b_CH2:
1262
0
                return "AutomotiveEthernet6b";
1263
0
            default:
1264
0
                break;
1265
0
            }
1266
0
            break;
1267
0
        default:
1268
0
            break;
1269
0
        }
1270
0
    }
1271
0
    else {
1272
0
        switch (ttl_addr_get_device(addr)) {
1273
0
        case TTL_TAP_DEVICE_PT15_FPGA:
1274
0
            switch (function) {
1275
0
            case TTL_PT15_FPGA_FUNCTION_CORE:
1276
0
                return "Core";
1277
0
            case TTL_PT15_FPGA_FUNCTION_CAN1:
1278
0
                return "CAN1";
1279
0
            case TTL_PT15_FPGA_FUNCTION_CAN2:
1280
0
                return "CAN2";
1281
0
            case TTL_PT15_FPGA_FUNCTION_BrdR1a:
1282
0
                return "BR1a";
1283
0
            case TTL_PT15_FPGA_FUNCTION_BrdR1b:
1284
0
                return "BR1b";
1285
0
            case TTL_PT15_FPGA_FUNCTION_BrdR2a:
1286
0
                return "BR2a";
1287
0
            case TTL_PT15_FPGA_FUNCTION_BrdR2b:
1288
0
                return "BR2b";
1289
0
            case TTL_PT15_FPGA_FUNCTION_BrdR3a:
1290
0
                return "BR3a";
1291
0
            case TTL_PT15_FPGA_FUNCTION_BrdR3b:
1292
0
                return "BR3b";
1293
0
            case TTL_PT15_FPGA_FUNCTION_BrdR4a:
1294
0
                return "BR4a";
1295
0
            case TTL_PT15_FPGA_FUNCTION_BrdR4b:
1296
0
                return "BR4b";
1297
0
            case TTL_PT15_FPGA_FUNCTION_BrdR5a:
1298
0
                return "BR5a";
1299
0
            case TTL_PT15_FPGA_FUNCTION_BrdR5b:
1300
0
                return "BR5b";
1301
0
            case TTL_PT15_FPGA_FUNCTION_BrdR6a:
1302
0
                return "BR6a";
1303
0
            case TTL_PT15_FPGA_FUNCTION_BrdR6b:
1304
0
                return "BR6b";
1305
0
            case TTL_PT15_FPGA_FUNCTION_MDIO:
1306
0
                return "MDIO";
1307
0
            default:
1308
0
                break;
1309
0
            }
1310
0
            break;
1311
0
        case TTL_TAP_DEVICE_PT20_FPGA:
1312
0
            switch (function) {
1313
0
            case TTL_PT20_FPGA_FUNCTION_CORE:
1314
0
                return "Core";
1315
0
            case TTL_PT20_FPGA_FUNCTION_CAN1:
1316
0
                return "CAN1";
1317
0
            case TTL_PT20_FPGA_FUNCTION_CAN2:
1318
0
                return "CAN2";
1319
0
            case TTL_PT20_FPGA_FUNCTION_CAN3:
1320
0
                return "CAN3";
1321
0
            case TTL_PT20_FPGA_FUNCTION_CAN4:
1322
0
                return "CAN4";
1323
0
            case TTL_PT20_FPGA_FUNCTION_CAN5:
1324
0
                return "CAN5";
1325
0
            case TTL_PT20_FPGA_FUNCTION_GbEth1a:
1326
0
                return "GbEth1a";
1327
0
            case TTL_PT20_FPGA_FUNCTION_GbEth1b:
1328
0
                return "GbEth1b";
1329
0
            case TTL_PT20_FPGA_FUNCTION_GbEth2a:
1330
0
                return "GbEth2a";
1331
0
            case TTL_PT20_FPGA_FUNCTION_GbEth2b:
1332
0
                return "GbEth2b";
1333
0
            case TTL_PT20_FPGA_FUNCTION_GbEth3a:
1334
0
                return "GbEth3a";
1335
0
            case TTL_PT20_FPGA_FUNCTION_GbEth3b:
1336
0
                return "GbEth3b";
1337
0
            case TTL_PT20_FPGA_FUNCTION_MDIO:
1338
0
                return "MDIO";
1339
0
            default:
1340
0
                break;
1341
0
            }
1342
0
            break;
1343
0
        case TTL_TAP_DEVICE_PC3_FPGA:
1344
0
            switch (function) {
1345
0
            case TTL_PC3_FPGA_FUNCTION_CORE:
1346
0
                return "FPGA_Core";
1347
0
            case TTL_PC3_FPGA_FUNCTION_BrdR1a:
1348
0
                return "BR1a";
1349
0
            case TTL_PC3_FPGA_FUNCTION_BrdR1b:
1350
0
                return "BR1b";
1351
0
            default:
1352
0
                break;
1353
0
            }
1354
0
            break;
1355
0
        case TTL_TAP_DEVICE_PC3_AURIX:
1356
0
            switch (function) {
1357
0
            case TTL_PC3_AURIX_FUNCTION_CORE:
1358
0
                return "Aurix_Core";
1359
0
            case TTL_PC3_AURIX_FUNCTION_CAN1:
1360
0
                return "CAN1";
1361
0
            case TTL_PC3_AURIX_FUNCTION_CAN2:
1362
0
                return "CAN2";
1363
0
            case TTL_PC3_AURIX_FUNCTION_CAN3:
1364
0
                return "CAN3";
1365
0
            case TTL_PC3_AURIX_FUNCTION_CAN4:
1366
0
                return "CAN4";
1367
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY1A:
1368
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY1B:
1369
0
                return "FlexRay1";
1370
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY2A:
1371
0
            case TTL_PC3_AURIX_FUNCTION_FLEXRAY2B:
1372
0
                return "FlexRay2";
1373
0
            case TTL_PC3_AURIX_FUNCTION_DIGITALIN1:
1374
0
                return "DigitalIn1";
1375
0
            case TTL_PC3_AURIX_FUNCTION_DIGITALIN2:
1376
0
                return "DigitalIn2";
1377
0
            case TTL_PC3_AURIX_FUNCTION_DIGITALOUT1:
1378
0
                return "DigitalOut1";
1379
0
            case TTL_PC3_AURIX_FUNCTION_DIGITALOUT2:
1380
0
                return "DigitalOut2";
1381
0
            default:
1382
0
                break;
1383
0
            }
1384
0
            break;
1385
0
        case TTL_TAP_DEVICE_ZELDA_CANFD:
1386
0
            switch (function) {
1387
0
            case TTL_TAP_DEVICE_ZELDA_CORE:
1388
0
                return "CANFD_Core";
1389
0
            case TTL_TAP_DEVICE_ZELDA_CANFD1:
1390
0
                return "CANFD1";
1391
0
            case TTL_TAP_DEVICE_ZELDA_CANFD2:
1392
0
                return "CANFD2";
1393
0
            case TTL_TAP_DEVICE_ZELDA_CANFD3:
1394
0
                return "CANFD3";
1395
0
            case TTL_TAP_DEVICE_ZELDA_CANFD4:
1396
0
                return "CANFD4";
1397
0
            case TTL_TAP_DEVICE_ZELDA_CANFD5:
1398
0
                return "CANFD5";
1399
0
            case TTL_TAP_DEVICE_ZELDA_CANFD6:
1400
0
                return "CANFD6";
1401
0
            case TTL_TAP_DEVICE_ZELDA_CANFD7:
1402
0
                return "CANFD7";
1403
0
            case TTL_TAP_DEVICE_ZELDA_CANFD8:
1404
0
                return "CANFD8";
1405
0
            case TTL_TAP_DEVICE_ZELDA_CANFD9:
1406
0
                return "CANFD9";
1407
0
            case TTL_TAP_DEVICE_ZELDA_CANFD10:
1408
0
                return "CANFD10";
1409
0
            case TTL_TAP_DEVICE_ZELDA_CANFD11:
1410
0
                return "CANFD11";
1411
0
            case TTL_TAP_DEVICE_ZELDA_CANFD12:
1412
0
                return "CANFD12";
1413
0
            case TTL_TAP_DEVICE_ZELDA_CANFD13:
1414
0
                return "CANFD13";
1415
0
            case TTL_TAP_DEVICE_ZELDA_CANFD14:
1416
0
                return "CANFD14";
1417
0
            case TTL_TAP_DEVICE_ZELDA_CANFD15:
1418
0
                return "CANFD15";
1419
0
            default:
1420
0
                break;
1421
0
            }
1422
0
            break;
1423
0
        case TTL_TAP_DEVICE_ZELDA_LIN:
1424
0
            switch (function) {
1425
0
            case TTL_TAP_DEVICE_ZELDA_CORE:
1426
0
                return "LIN_Core";
1427
0
            case TTL_TAP_DEVICE_ZELDA_LIN1:
1428
0
                return "LIN1";
1429
0
            case TTL_TAP_DEVICE_ZELDA_LIN2:
1430
0
                return "LIN2";
1431
0
            case TTL_TAP_DEVICE_ZELDA_LIN3:
1432
0
                return "LIN3";
1433
0
            case TTL_TAP_DEVICE_ZELDA_LIN4:
1434
0
                return "LIN4";
1435
0
            case TTL_TAP_DEVICE_ZELDA_LIN5:
1436
0
                return "LIN5";
1437
0
            case TTL_TAP_DEVICE_ZELDA_LIN6:
1438
0
                return "LIN6";
1439
0
            case TTL_TAP_DEVICE_ZELDA_LIN7:
1440
0
                return "LIN7";
1441
0
            case TTL_TAP_DEVICE_ZELDA_LIN8:
1442
0
                return "LIN8";
1443
0
            case TTL_TAP_DEVICE_ZELDA_LIN9:
1444
0
                return "LIN9";
1445
0
            case TTL_TAP_DEVICE_ZELDA_LIN10:
1446
0
                return "LIN10";
1447
0
            case TTL_TAP_DEVICE_ZELDA_LIN11:
1448
0
                return "LIN11";
1449
0
            case TTL_TAP_DEVICE_ZELDA_LIN12:
1450
0
                return "LIN12";
1451
0
            case TTL_TAP_DEVICE_ZELDA_LIN13:
1452
0
                return "LIN13";
1453
0
            case TTL_TAP_DEVICE_ZELDA_LIN14:
1454
0
                return "LIN14";
1455
0
            case TTL_TAP_DEVICE_ZELDA_LIN15:
1456
0
                return "LIN15";
1457
0
            case TTL_TAP_DEVICE_ZELDA_LIN16:
1458
0
                return "LIN16";
1459
0
            case TTL_TAP_DEVICE_ZELDA_LIN17:
1460
0
                return "LIN17";
1461
0
            case TTL_TAP_DEVICE_ZELDA_LIN18:
1462
0
                return "LIN18";
1463
0
            case TTL_TAP_DEVICE_ZELDA_LIN19:
1464
0
                return "LIN19";
1465
0
            case TTL_TAP_DEVICE_ZELDA_LIN20:
1466
0
                return "LIN20";
1467
0
            case TTL_TAP_DEVICE_ZELDA_LIN21:
1468
0
                return "LIN21";
1469
0
            case TTL_TAP_DEVICE_ZELDA_LIN22:
1470
0
                return "LIN22";
1471
0
            case TTL_TAP_DEVICE_ZELDA_LIN23:
1472
0
                return "LIN23";
1473
0
            case TTL_TAP_DEVICE_ZELDA_LIN24:
1474
0
                return "LIN24";
1475
0
            default:
1476
0
                break;
1477
0
            }
1478
0
            break;
1479
0
        default:
1480
0
            break;
1481
0
        }
1482
0
    }
1483
1484
0
    return "Unknown";
1485
0
}
1486
1487
static wtap_opttype_return_val
1488
0
ttl_add_interface_name(wtap_block_t int_data, uint16_t addr, const char* name) {
1489
0
    if (name != NULL) {
1490
0
        return wtap_block_add_string_option(int_data, OPT_IDB_NAME, name, strlen(name));
1491
0
    }
1492
1493
0
    return wtap_block_add_string_option_format(int_data, OPT_IDB_NAME, "%s::%s::%s",
1494
0
                                               ttl_get_cascade_name(addr),
1495
0
                                               ttl_get_device_name(addr),
1496
0
                                               ttl_get_function_name(addr));
1497
0
}
1498
1499
/*
1500
 * This function will create the interface and populate the
1501
 * 'address_to_iface_ht' hash table.
1502
 */
1503
static bool
1504
0
ttl_create_interface(wtap* wth, int pkt_encap, uint16_t addr, const char* name) {
1505
0
    wtap_block_t int_data;
1506
0
    wtapng_if_descr_mandatory_t* if_descr_mand;
1507
1508
0
    if (wth == NULL) {
1509
0
        return false;
1510
0
    }
1511
1512
0
    int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
1513
0
    if_descr_mand = wtap_block_get_mandatory_data(int_data);
1514
1515
0
    if_descr_mand->wtap_encap = pkt_encap;
1516
0
    ttl_add_interface_name(int_data, addr, name);
1517
1518
0
    if_descr_mand->time_units_per_second = 1000 * 1000;
1519
0
    if_descr_mand->tsprecision = WTAP_TSPREC_USEC;
1520
0
    wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 6);
1521
0
    if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;
1522
0
    if_descr_mand->num_stat_entries = 0;
1523
0
    if_descr_mand->interface_statistics = NULL;
1524
0
    wtap_add_idb(wth, int_data);
1525
1526
0
    if (wth->file_encap == WTAP_ENCAP_NONE) {
1527
0
        wth->file_encap = if_descr_mand->wtap_encap;
1528
0
    }
1529
0
    else if (wth->file_encap != if_descr_mand->wtap_encap) {
1530
0
        wth->file_encap = WTAP_ENCAP_PER_PACKET;
1531
0
    }
1532
1533
0
    return true;
1534
0
}
1535
1536
0
#define TTL_LOOKUP_INTERFACE_MAX_ITERATIONS 2
1537
0
#define ttl_lookup_interface(...)   ttl_lookup_interface_int(__VA_ARGS__, 0)
1538
1539
// NOLINTNEXTLINE(misc-no-recursion)
1540
0
static const ttl_addr_to_iface_entry_t* ttl_lookup_interface_int(wtap* wth, uint16_t addr, int* err, char** err_info, int iteration) {
1541
0
    ttl_addr_to_iface_entry_t* item;
1542
0
    ttl_t*      ttl;
1543
0
    uint32_t    iface_id;
1544
0
    uint16_t    master_addr;
1545
0
    int         pkt_encap;
1546
1547
0
    if (wth == NULL) {
1548
0
        return NULL;
1549
0
    }
1550
1551
0
    ttl = (ttl_t*)wth->priv;
1552
0
    if (ttl == NULL || ttl->address_to_iface_ht == NULL) {
1553
0
        return NULL;
1554
0
    }
1555
1556
    /* Recursion limit to avoid coding errors. */
1557
0
    if (iteration > TTL_LOOKUP_INTERFACE_MAX_ITERATIONS) {
1558
0
        *err = WTAP_ERR_BAD_FILE;
1559
0
        *err_info = ws_strdup_printf("ttl: more iterations than allowed: %d (max. %d)", iteration, TTL_LOOKUP_INTERFACE_MAX_ITERATIONS);
1560
0
        return NULL;
1561
0
    }
1562
1563
0
    item = g_hash_table_lookup(ttl->address_to_iface_ht, GUINT_TO_POINTER(addr));
1564
0
    if (item != NULL) {
1565
0
        return item;
1566
0
    }
1567
1568
0
    pkt_encap = ttl_get_address_iface_type(addr);
1569
0
    if (pkt_encap <= WTAP_ENCAP_UNKNOWN) {
1570
0
        return NULL;
1571
0
    }
1572
1573
0
    master_addr = ttl_get_master_address(ttl->address_to_master_ht, addr);
1574
0
    if (addr != master_addr) {   /* The interface ID is the "slave" one */
1575
0
        const ttl_addr_to_iface_entry_t* master_item = ttl_lookup_interface_int(wth, master_addr, err, err_info, iteration + 1);
1576
0
        if (master_item == NULL) {
1577
0
            return NULL;
1578
0
        }
1579
1580
0
        iface_id = master_item->interface_id;
1581
0
    }
1582
0
    else {  /* Create a new interface */
1583
0
        const char* saved_name = g_hash_table_lookup(ttl->address_to_name_ht, GUINT_TO_POINTER(addr));
1584
0
        bool ret = ttl_create_interface(wth, pkt_encap, addr, saved_name);
1585
1586
0
        if (saved_name != NULL) {
1587
0
            g_hash_table_remove(ttl->address_to_name_ht, GUINT_TO_POINTER(addr));
1588
0
        }
1589
1590
0
        if (!ret) {
1591
0
            return NULL;
1592
0
        }
1593
1594
0
        iface_id = ttl->next_interface_id++;
1595
0
    }
1596
1597
    /* Create the entry */
1598
0
    item = g_new(ttl_addr_to_iface_entry_t, 1);
1599
0
    item->interface_id = iface_id;
1600
0
    item->pkt_encap = pkt_encap;
1601
0
    item->channelB = ttl_is_chb_addr(addr);
1602
0
    g_hash_table_insert(ttl->address_to_iface_ht, GUINT_TO_POINTER(addr), item);
1603
1604
0
    return item;
1605
0
}
1606
1607
static void
1608
0
ttl_init_rec(wtap_rec* rec, uint64_t timestamp, uint16_t addr, int pkt_encap, uint32_t iface_id, uint32_t caplen, uint32_t len) {
1609
0
    wtap_setup_packet_rec(rec, pkt_encap);
1610
0
    rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
1611
0
    rec->presence_flags = WTAP_HAS_CAP_LEN | WTAP_HAS_INTERFACE_ID | WTAP_HAS_TS;
1612
0
    rec->tsprec = WTAP_TSPREC_USEC;
1613
0
    rec->ts.secs = timestamp / (1000 * 1000);
1614
0
    rec->ts.nsecs = 1000 * (timestamp % (1000 * 1000));
1615
0
    rec->rec_header.packet_header.caplen = caplen;
1616
0
    rec->rec_header.packet_header.len = len;
1617
1618
0
    rec->rec_header.packet_header.interface_id = iface_id;
1619
1620
0
    wtap_block_add_uint32_option(rec->block, OPT_PKT_QUEUE, addr);
1621
0
}
1622
1623
static bool
1624
0
ttl_read_bytes(ttl_read_t* in, void* out, uint16_t size, int* err, char** err_info) {
1625
0
    switch (in->validity) {
1626
0
    case VALIDITY_FH:
1627
0
        if (!wtap_read_bytes_or_eof(in->fh, out, size, err, err_info)) {
1628
0
            ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err);
1629
0
            return false;
1630
0
        }
1631
0
        break;
1632
0
    case VALIDITY_BUF:
1633
0
        if (size != 0) {
1634
0
            if ((in->cur_pos + size) > in->size) {
1635
0
                *err = WTAP_ERR_SHORT_READ;
1636
0
                *err_info = ws_strdup("ttl: Attempt to read beyond buffer end");
1637
0
                return false;
1638
0
            }
1639
0
            if (out != NULL) {
1640
0
                memcpy(out, in->buf + in->cur_pos, size);
1641
0
            }
1642
0
            in->cur_pos += size;
1643
0
        }
1644
0
        break;
1645
0
    default:
1646
0
        *err = WTAP_ERR_INTERNAL;
1647
0
        *err_info = ws_strdup_printf("ttl: ttl_read_t unknown validity flags: %d", in->validity);
1648
0
        return false;
1649
0
    }
1650
1651
0
    return true;
1652
0
}
1653
1654
static bool
1655
0
ttl_read_bytes_buffer(ttl_read_t* in, Buffer* buf, uint16_t size, int* err, char** err_info) {
1656
0
    ws_buffer_assure_space(buf, size);
1657
0
    if (!ttl_read_bytes(in, ws_buffer_end_ptr(buf), size, err, err_info)) {
1658
0
        return false;
1659
0
    }
1660
0
    ws_buffer_increase_length(buf, size);
1661
0
    return true;
1662
0
}
1663
1664
static bool
1665
0
ttl_skip_bytes(ttl_read_t* in, uint16_t size, int* err, char** err_info) {
1666
0
    return ttl_read_bytes(in, NULL, size, err, err_info);
1667
0
}
1668
1669
static void
1670
0
ttl_add_eth_dir_option(wtap_rec* rec, uint16_t status) {
1671
0
    uint32_t opt = PACK_FLAGS_DIRECTION_UNKNOWN;
1672
1673
0
    switch (status) {
1674
0
    case TTL_ETH_STATUS_VALID_FRAME:
1675
0
    case TTL_ETH_STATUS_CRC_ERROR_FRAME:
1676
0
    case TTL_ETH_STATUS_LENGTH_ERROR_FRAME:
1677
0
    case TTL_ETH_STATUS_PHY_ERROR_FRAME:
1678
0
        opt = PACK_FLAGS_DIRECTION_INBOUND;
1679
0
        break;
1680
0
    case TTL_ETH_STATUS_TX_ERROR_FRAME:
1681
0
    case TTL_ETH_STATUS_TX_FREEMEM_INFO_FRAME:
1682
0
    case TTL_ETH_STATUS_TX_FRAME:
1683
0
        opt = PACK_FLAGS_DIRECTION_OUTBOUND;
1684
0
        break;
1685
0
    default:
1686
0
        break;
1687
0
    }
1688
1689
0
    wtap_block_add_uint32_option(rec->block, OPT_PKT_FLAGS, opt);
1690
0
}
1691
1692
static ttl_result_t
1693
ttl_read_eth_data_entry(wtap_rec* rec, int* err, char** err_info, ttl_read_t* in, uint16_t size, uint16_t addr,
1694
0
                        const ttl_addr_to_iface_entry_t* item, uint16_t status, uint64_t timestamp) {
1695
0
    if (item == NULL) {
1696
0
        *err = WTAP_ERR_INTERNAL;
1697
0
        *err_info = ws_strdup("ttl_read_eth_data_entry called with NULL item");
1698
0
        return TTL_ERROR;
1699
0
    }
1700
1701
0
    if (status == TTL_ETH_STATUS_PHY_STATUS) {  /* TODO */
1702
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
1703
0
            return TTL_ERROR;
1704
0
        }
1705
0
        return TTL_UNSUPPORTED;
1706
0
    }
1707
1708
0
    if (size < 2) { /* 2 unused bytes */
1709
0
        return TTL_CORRUPTED;
1710
0
    }
1711
0
    if (!ttl_skip_bytes(in, 2, err, err_info)) {
1712
0
        return TTL_ERROR;
1713
0
    }
1714
0
    size -= 2;
1715
1716
0
    if (size != 0 && !ttl_read_bytes_buffer(in, &rec->data, size, err, err_info)) {
1717
0
        return TTL_ERROR;
1718
0
    }
1719
1720
0
    ttl_init_rec(rec, timestamp, addr, item->pkt_encap, item->interface_id, size, size);
1721
0
    ttl_add_eth_dir_option(rec, status);
1722
1723
0
    return TTL_NO_ERROR;
1724
0
}
1725
1726
static void
1727
0
ttl_add_can_dir_option(wtap_rec* rec) {
1728
0
    uint32_t opt = PACK_FLAGS_DIRECTION_INBOUND;    /* For the moment, we only support this */
1729
1730
0
    wtap_block_add_uint32_option(rec->block, OPT_PKT_FLAGS, opt);
1731
0
}
1732
1733
static const uint8_t canfd_dlc_to_length[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64 };
1734
1735
static ttl_result_t
1736
ttl_read_can_data_entry(wtap_rec* rec, int* err, char** err_info, ttl_read_t* in, uint16_t size, uint16_t addr,
1737
0
                        const ttl_addr_to_iface_entry_t* item, uint16_t status, uint64_t timestamp) {
1738
0
    uint32_t    can_id = 0;
1739
0
    uint8_t     dlc, error_code, len, canfd_flags = 0;
1740
0
    uint8_t     can_header[8], can_error_payload[CAN_ERR_DLC] = {0};
1741
1742
0
    if (item == NULL) {
1743
0
        *err = WTAP_ERR_INTERNAL;
1744
0
        *err_info = ws_strdup("ttl_read_can_data_entry called with NULL item");
1745
0
        return TTL_ERROR;
1746
0
    }
1747
1748
0
    dlc = (status & TTL_CAN_STATUS_DLC_MASK) >> TTL_CAN_STATUS_DLC_POS;
1749
0
    error_code = (status & TTL_CAN_STATUS_ERROR_CODE_MASK) >> TTL_CAN_STATUS_ERROR_CODE_POS;
1750
1751
0
    if (status & TTL_CAN_STATUS_VALID_BIT_MASK) {   /* DLC, ID and Payload are valid */
1752
0
        if (size < sizeof(uint32_t)) {    /* No more data */
1753
0
            return TTL_CORRUPTED;
1754
0
        }
1755
1756
0
        if (!ttl_read_bytes(in, &can_id, sizeof(uint32_t), err, err_info)) {
1757
0
            return TTL_ERROR;
1758
0
        }
1759
0
        can_id = GUINT32_FROM_LE(can_id);
1760
0
        size -= sizeof(uint32_t);
1761
0
    }
1762
1763
0
    if (error_code) {
1764
0
        can_id = CAN_ERR_FLAG;
1765
0
        if (status & TTL_CAN_STATUS_BUSOFF_MASK) can_id |= CAN_ERR_BUSOFF;
1766
0
        len = CAN_ERR_DLC;
1767
1768
0
        switch (error_code) {
1769
0
        case TTL_CAN_ERROR_STUFF_ERROR:
1770
0
            can_id |= CAN_ERR_PROT;
1771
0
            can_error_payload[2] = CAN_ERR_PROT_STUFF;
1772
0
            break;
1773
0
        case TTL_CAN_ERROR_FORM_ERROR:
1774
0
            can_id |= CAN_ERR_PROT;
1775
0
            can_error_payload[2] = CAN_ERR_PROT_FORM;
1776
0
            break;
1777
0
        case TTL_CAN_ERROR_ACK_ERROR:
1778
0
            can_id |= CAN_ERR_ACK;
1779
0
            break;
1780
0
        case TTL_CAN_ERROR_BIT1_ERROR:
1781
0
            can_id |= CAN_ERR_PROT;
1782
0
            can_error_payload[2] = CAN_ERR_PROT_BIT1;
1783
0
            break;
1784
0
        case TTL_CAN_ERROR_BIT0_ERROR:
1785
0
            can_id |= CAN_ERR_PROT;
1786
0
            can_error_payload[2] = CAN_ERR_PROT_BIT0;
1787
0
            break;
1788
0
        case TTL_CAN_ERROR_CRC_ERROR:
1789
0
            can_id |= CAN_ERR_PROT;
1790
0
            can_error_payload[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
1791
0
            break;
1792
0
        case TTL_CAN_ERROR_INVALID_DLC:
1793
0
            can_id |= CAN_ERR_PROT;
1794
0
            can_error_payload[3] = CAN_ERR_PROT_LOC_DLC;
1795
0
            break;
1796
0
        }
1797
0
    }
1798
0
    else {
1799
0
        if (status & TTL_CAN_STATUS_RTR_BIT_MASK) can_id |= CAN_RTR_FLAG;
1800
0
        if (status & TTL_CAN_STATUS_IDE_BIT_MASK) can_id |= CAN_EFF_FLAG;
1801
0
        if (status & TTL_CAN_STATUS_EDL_BIT_MASK) {
1802
0
            canfd_flags |= CANFD_FDF;
1803
0
            len = canfd_dlc_to_length[dlc];
1804
0
        }
1805
0
        else {
1806
0
            len = MIN(dlc, 8);
1807
0
        }
1808
0
        if (status & TTL_CAN_STATUS_BRS_BIT_MASK) canfd_flags |= CANFD_BRS;
1809
0
        if (status & TTL_CAN_STATUS_ESI_BIT_MASK) canfd_flags |= CANFD_ESI;
1810
0
    }
1811
1812
0
    phtonu32(&can_header[0], can_id);
1813
0
    phtonu8(&can_header[4], len);
1814
0
    phtonu8(&can_header[5], canfd_flags);
1815
0
    phtonu8(&can_header[6], 0);
1816
0
    phtonu8(&can_header[7], 0);
1817
1818
0
    ws_buffer_append(&rec->data, can_header, sizeof(can_header));
1819
1820
0
    if (error_code) {
1821
0
        ws_buffer_append(&rec->data, can_error_payload, sizeof(can_error_payload));
1822
0
        if (size != 0 && !ttl_skip_bytes(in, size, err, err_info)) {
1823
0
            return TTL_ERROR;
1824
0
        }
1825
0
        ttl_init_rec(rec, timestamp, addr, item->pkt_encap, item->interface_id,
1826
0
                     sizeof(can_header) + sizeof(can_error_payload), sizeof(can_header) + sizeof(can_error_payload));
1827
0
    }
1828
0
    else {
1829
0
        if (size != 0 && !ttl_read_bytes_buffer(in, &rec->data, size, err, err_info)) {
1830
0
            return TTL_ERROR;
1831
0
        }
1832
0
        ttl_init_rec(rec, timestamp, addr, item->pkt_encap, item->interface_id, size + sizeof(can_header), len + sizeof(can_header));
1833
0
    }
1834
1835
0
    ttl_add_can_dir_option(rec);
1836
1837
0
    return TTL_NO_ERROR;
1838
0
}
1839
1840
static void
1841
0
ttl_add_lin_dir_option(wtap_rec* rec) {
1842
0
    uint32_t opt = PACK_FLAGS_DIRECTION_INBOUND;    /* For the moment, we only support this */
1843
1844
0
    wtap_block_add_uint32_option(rec->block, OPT_PKT_FLAGS, opt);
1845
0
}
1846
1847
static ttl_result_t
1848
ttl_read_lin_data_entry(wtap_rec* rec, int* err, char** err_info, ttl_read_t* in, uint16_t size, uint16_t addr,
1849
0
                        const ttl_addr_to_iface_entry_t* item, uint16_t status, uint64_t timestamp) {
1850
0
    uint8_t     lin_header[8], lin_payload[8];
1851
0
    uint8_t     dlc;
1852
1853
0
    if (item == NULL) {
1854
0
        *err = WTAP_ERR_INTERNAL;
1855
0
        *err_info = ws_strdup("ttl_read_lin_data_entry called with NULL item");
1856
0
        return TTL_ERROR;
1857
0
    }
1858
1859
0
    dlc = size != 0 ? MIN((size - 1), 8) : 0;
1860
1861
0
    lin_header[0] = 1; /* message format rev = 1 */
1862
0
    lin_header[1] = 0; /* reserved */
1863
0
    lin_header[2] = 0; /* reserved */
1864
0
    lin_header[3] = 0; /* reserved */
1865
0
    lin_header[4] = (dlc << 4) | (LIN_MSG_TYPE_FRAME << 2); /* dlc (4bit) | type (2bit) | checksum type (2bit) */
1866
0
    lin_header[5] = status & TTL_LIN_STATUS_PID_MASK;  /* parity (2bit) | id (6bit) */
1867
0
    lin_header[6] = 0; /* checksum */
1868
0
    lin_header[7] = 0; /* errors */
1869
1870
0
    if (status & TTL_LIN_ERROR_PARITY_ERROR) lin_header[7] |= 0x04;
1871
0
    if (status & TTL_LIN_ERROR_SYNC_ERROR) lin_header[7] |= 0x02;  /* Is this correct? */
1872
0
    if (status & TTL_LIN_ERROR_NO_DATA_ERROR) lin_header[7] |= 0x01;
1873
0
    if (status & TTL_LIN_ERROR_ABORT_ERROR) lin_header[7] |= 0x02; /* Is this correct? */
1874
    /* Set the checksum error if the checksum is wrong with respect to both types */
1875
0
    if ((status & TTL_LIN_ERROR_ANY_CHECKSUM) == TTL_LIN_ERROR_ANY_CHECKSUM) lin_header[7] |= 0x08;
1876
1877
0
    if (dlc != 0) {
1878
0
        if (!ttl_read_bytes(in, &lin_payload[0], dlc, err, err_info)) {
1879
0
            return TTL_ERROR;
1880
0
        }
1881
0
        size -= dlc;
1882
0
    }
1883
1884
0
    if (size != 0) {
1885
0
        if (!ttl_read_bytes(in, &lin_header[6], 1, err, err_info)) {
1886
0
            return TTL_ERROR;
1887
0
        }
1888
0
        size -= 1;
1889
0
    }
1890
1891
0
    if (size != 0) {    /* Skip any extra byte */
1892
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
1893
0
            return TTL_ERROR;
1894
0
        }
1895
0
    }
1896
1897
0
    ws_buffer_append(&rec->data, lin_header, sizeof(lin_header));
1898
1899
0
    if (dlc != 0) {
1900
0
        ws_buffer_append(&rec->data, lin_payload, dlc);
1901
0
    }
1902
1903
0
    ttl_init_rec(rec, timestamp, addr, item->pkt_encap, item->interface_id, dlc + sizeof(lin_header), dlc + sizeof(lin_header));
1904
0
    ttl_add_lin_dir_option(rec);
1905
1906
0
    return TTL_NO_ERROR;
1907
0
}
1908
1909
static void
1910
0
ttl_add_flexray_dir_option(wtap_rec* rec) {
1911
0
    uint32_t opt = PACK_FLAGS_DIRECTION_INBOUND;    /* For the moment, we only support this */
1912
1913
0
    wtap_block_add_uint32_option(rec->block, OPT_PKT_FLAGS, opt);
1914
0
}
1915
1916
static ttl_result_t
1917
ttl_read_flexray_data_entry(wtap_rec* rec, int* err, char** err_info, ttl_read_t* in, uint16_t size, uint16_t addr,
1918
0
                            const ttl_addr_to_iface_entry_t* item, uint16_t status, uint64_t timestamp) {
1919
0
    uint8_t     fr_item;
1920
0
    uint8_t     fr_header[2];
1921
1922
0
    if (item == NULL) {
1923
0
        *err = WTAP_ERR_INTERNAL;
1924
0
        *err_info = ws_strdup("ttl_read_flexray_data_entry called with NULL item");
1925
0
        return TTL_ERROR;
1926
0
    }
1927
1928
0
    fr_item = status & TTL_FLEXRAY_ITEM_MASK;
1929
1930
0
    if (fr_item != TTL_FLEXRAY_ITEM_REGULAR_FRAME && fr_item != TTL_FLEXRAY_ITEM_ABORTED_FRAME) {   /* TODO */
1931
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
1932
0
            return TTL_ERROR;
1933
0
        }
1934
0
        return TTL_UNSUPPORTED;
1935
0
    }
1936
1937
0
    fr_header[0] = FLEXRAY_FRAME;
1938
0
    fr_header[1] = 0;   /* Errors */
1939
1940
0
    if (item->channelB) fr_header[0] |= 0x80;
1941
1942
0
    if (status & (TTL_FLEXRAY_FSS_ERROR_MASK | TTL_FLEXRAY_BSS_ERROR_MASK)) fr_header[1] |= 0x02;
1943
0
    if (status & TTL_FLEXRAY_FES_ERROR_MASK) fr_header[1] |= 0x04;
1944
0
    if (status & TTL_FLEXRAY_FRAME_CRC_ERROR_MASK) fr_header[1] |= 0x10;
1945
0
    if (status & TTL_FLEXRAY_HEADER_CRC_ERROR_MASK) fr_header[1] |= 0x08;
1946
1947
0
    ws_buffer_append(&rec->data, fr_header, sizeof(fr_header));
1948
1949
0
    if (size != 0 && !ttl_read_bytes_buffer(in, &rec->data, size, err, err_info)) {
1950
0
        return TTL_ERROR;
1951
0
    }
1952
1953
0
    ttl_init_rec(rec, timestamp, addr, item->pkt_encap, item->interface_id, size + sizeof(fr_header), size + sizeof(fr_header));
1954
0
    ttl_add_flexray_dir_option(rec);
1955
1956
0
    return TTL_NO_ERROR;
1957
0
}
1958
1959
static ttl_result_t
1960
0
ttl_read_data_entry(wtap* wth, wtap_rec* rec, int* err, char** err_info, ttl_read_t* in, uint16_t size, uint16_t src, uint16_t status) {
1961
0
    const ttl_addr_to_iface_entry_t* item;
1962
0
    int         pkt_encap = ttl_get_address_iface_type(src);
1963
0
    uint64_t    timestamp;
1964
1965
0
    if (pkt_encap <= WTAP_ENCAP_UNKNOWN) {
1966
0
        ws_debug("ttl_read_data_entry: Unsupported source address found in TTL_BUS_DATA_ENTRY: 0x%X", src);
1967
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
1968
0
            return TTL_ERROR;
1969
0
        }
1970
0
        return TTL_UNSUPPORTED;
1971
0
    }
1972
1973
0
    *err = 0;
1974
0
    item = ttl_lookup_interface(wth, src, err, err_info);
1975
0
    if (*err) {
1976
0
        return TTL_ERROR;
1977
0
    }
1978
1979
0
    if (size < sizeof(uint64_t)) {
1980
0
        return TTL_CORRUPTED;
1981
0
    }
1982
0
    if (!ttl_read_bytes(in, &timestamp, sizeof(uint64_t), err, err_info)) {
1983
0
        return TTL_ERROR;
1984
0
    }
1985
0
    timestamp = GUINT64_FROM_LE(timestamp);
1986
0
    size -= sizeof(uint64_t);
1987
1988
0
    switch (pkt_encap) {
1989
0
    case WTAP_ENCAP_ETHERNET:
1990
0
        return ttl_read_eth_data_entry(rec, err, err_info, in, size, src, item, status, timestamp);
1991
0
    case WTAP_ENCAP_SOCKETCAN:
1992
0
        return ttl_read_can_data_entry(rec, err, err_info, in, size, src, item, status, timestamp);
1993
0
    case WTAP_ENCAP_LIN:
1994
0
        return ttl_read_lin_data_entry(rec, err, err_info, in, size, src, item, status, timestamp);
1995
0
    case WTAP_ENCAP_FLEXRAY:
1996
0
        return ttl_read_flexray_data_entry(rec, err, err_info, in, size, src, item, status, timestamp);
1997
0
    default:
1998
0
        ws_debug("ttl_read_data_entry: Unsupported packet type found in TTL_BUS_DATA_ENTRY: %d", pkt_encap);
1999
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
2000
0
            return TTL_ERROR;
2001
0
        }
2002
0
        return TTL_UNSUPPORTED;
2003
0
    }
2004
2005
0
}
2006
2007
static bool
2008
0
ttl_check_segmented_message_recursion(const ttl_read_t* in, int* err, char** err_info) {
2009
0
    ttl_entryheader_t header;
2010
2011
0
    if (in->validity != VALIDITY_BUF) {
2012
0
        *err = WTAP_ERR_INTERNAL;
2013
0
        *err_info = ws_strdup("ttl: input buffer is not valid");
2014
0
        return false;
2015
0
    }
2016
2017
0
    if (sizeof(ttl_entryheader_t) > in->size - in->cur_pos) {
2018
0
        *err = WTAP_ERR_BAD_FILE;
2019
0
        *err_info = ws_strdup("ttl: input buffer too short");
2020
0
        return false;
2021
0
    }
2022
0
    memcpy(&header, in->buf + in->cur_pos, sizeof(ttl_entryheader_t));
2023
0
    fix_endianness_ttl_entryheader(&header);
2024
2025
0
    if ((header.size_type >> 12) == TTL_SEGMENTED_MESSAGE_ENTRY) {
2026
0
        return false;
2027
0
    }
2028
2029
0
    return true;
2030
0
}
2031
2032
/*
2033
 * For some reason, the timestamp of the nested frame is garbage.
2034
 * Copy the timestamp of the first segment in its place.
2035
 */
2036
static bool
2037
0
ttl_fix_segmented_message_entry_timestamp(const ttl_read_t* in, uint64_t timestamp, int* err, char** err_info) {
2038
0
    ttl_entryheader_t header;
2039
2040
0
    if (in->validity != VALIDITY_BUF) {
2041
0
        *err = WTAP_ERR_INTERNAL;
2042
0
        *err_info = ws_strdup("ttl: input buffer is not valid");
2043
0
        return false;
2044
0
    }
2045
2046
0
    if (sizeof(ttl_entryheader_t) > in->size - in->cur_pos) {
2047
0
        goto buf_too_small;
2048
0
    }
2049
0
    memcpy(&header, in->buf + in->cur_pos, sizeof(ttl_entryheader_t));
2050
0
    fix_endianness_ttl_entryheader(&header);
2051
2052
0
    if ((header.size_type >> 12) == TTL_BUS_DATA_ENTRY) {
2053
0
        if (sizeof(uint64_t) > in->size - (in->cur_pos + sizeof(ttl_entryheader_t))) {
2054
0
        buf_too_small:
2055
0
            *err = WTAP_ERR_BAD_FILE;
2056
0
            *err_info = ws_strdup("ttl: input buffer too short");
2057
0
            return false;
2058
0
        }
2059
0
        timestamp = GUINT64_TO_LE(timestamp);
2060
0
        memcpy(in->buf + in->cur_pos + sizeof(ttl_entryheader_t), &timestamp, sizeof(uint64_t));
2061
0
    }
2062
2063
0
    return true;
2064
0
}
2065
2066
// NOLINTNEXTLINE(misc-no-recursion)
2067
static ttl_result_t ttl_read_segmented_message_entry(wtap* wth, wtap_rec* rec, int* err, char** err_info, ttl_read_t* in,
2068
0
                                                     uint16_t size, uint16_t src, uint16_t status, int64_t offset) {
2069
0
    ttl_segmented_entry_t* item;
2070
0
    ttl_reassembled_entry_t* reassembled_item;
2071
0
    ttl_t*      ttl = (ttl_t*)wth->priv;
2072
0
    uint64_t    timestamp;
2073
0
    uint8_t     frame_num = status & 0x000f;
2074
0
    uint8_t     seg_frame_id = (status >> 4) & 0x000f;
2075
0
    uint32_t    key = ((uint32_t)seg_frame_id << 16) | src;
2076
0
    ttl_read_t  new_in;
2077
2078
0
    if (status == 0xFFFF) { /* Reserved for future use */
2079
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
2080
0
            return TTL_ERROR;
2081
0
        }
2082
0
        return TTL_UNSUPPORTED;
2083
0
    }
2084
2085
0
    reassembled_item = g_hash_table_lookup(ttl->reassembled_frames_ht, &offset);
2086
2087
0
    if (reassembled_item == NULL) {
2088
0
        if (size < sizeof(uint64_t)) {
2089
0
            return TTL_CORRUPTED;
2090
0
        }
2091
0
        if (!ttl_read_bytes(in, &timestamp, sizeof(uint64_t), err, err_info)) {
2092
0
            return TTL_ERROR;
2093
0
        }
2094
0
        timestamp = GUINT64_FROM_LE(timestamp);
2095
0
        size -= sizeof(uint64_t);
2096
2097
0
        item = g_hash_table_lookup(ttl->segmented_frames_ht, GUINT_TO_POINTER(key));
2098
2099
0
        if (frame_num == 0) {   /* This is the first segment */
2100
0
            if (item != NULL) { /* New header with reassemble in progress */
2101
0
                ws_debug("ttl_read_segmented_message_entry: Found new header while reassembly was in progress for SRC %d, FRAME ID %d", src, seg_frame_id);
2102
0
                g_hash_table_remove(ttl->segmented_frames_ht, GUINT_TO_POINTER(key));
2103
0
            }
2104
2105
0
            if (size < (2 * sizeof(uint32_t))) {    /* Size and type below */
2106
0
                return TTL_CORRUPTED;
2107
0
            }
2108
2109
0
            item = (ttl_segmented_entry_t*)g_new0(ttl_segmented_entry_t, 1);
2110
0
            item->timestamp = timestamp;
2111
2112
0
            if (!ttl_read_bytes(in, &item->size, sizeof(uint32_t), err, err_info)) {
2113
0
                g_free(item);
2114
0
                return TTL_ERROR;
2115
0
            }
2116
0
            item->size = GUINT32_FROM_LE(item->size);
2117
0
            size -= sizeof(uint32_t);
2118
2119
0
            if (!ttl_read_bytes(in, &item->type, sizeof(uint32_t), err, err_info)) {
2120
0
                g_free(item);
2121
0
                return TTL_ERROR;
2122
0
            }
2123
0
            item->type = GUINT32_FROM_LE(item->type);
2124
0
            size -= sizeof(uint32_t);
2125
2126
            /* If the reassembled size is too big, we go on as usual, but without a buffer.
2127
             * This way we avoid problems with segments later.
2128
             */
2129
0
            if (item->size <= WTAP_MAX_PACKET_SIZE_STANDARD) {
2130
0
                item->buf = g_try_malloc(item->size);
2131
0
                if (item->buf == NULL) {
2132
0
                    g_free(item);
2133
0
                    *err = WTAP_ERR_INTERNAL;
2134
0
                    *err_info = ws_strdup("ttl_read_segmented_message_entry: cannot allocate memory");
2135
0
                    return TTL_ERROR;
2136
0
                }
2137
0
            }
2138
2139
0
            g_hash_table_insert(ttl->segmented_frames_ht, GUINT_TO_POINTER(key), item);
2140
0
        }
2141
0
        else {
2142
0
            if (item == NULL) {
2143
0
                ws_debug("ttl_read_segmented_message_entry: Found frame number %d without header for SRC %d, FRAME ID %d", frame_num, src, seg_frame_id);
2144
0
                if (!ttl_skip_bytes(in, size, err, err_info)) {
2145
0
                    return TTL_ERROR;
2146
0
                }
2147
0
                return TTL_UNSUPPORTED;
2148
0
            }
2149
2150
0
            if (item->next_segment != frame_num) {
2151
0
                ws_debug("ttl_read_segmented_message_entry: Found out of order segment (expected %d, found %d) for SRC %d, FRAME ID %d",
2152
0
                    item->next_segment, frame_num, src, seg_frame_id);
2153
0
                if (!ttl_skip_bytes(in, size, err, err_info)) {
2154
0
                    return TTL_ERROR;
2155
0
                }
2156
0
                return TTL_UNSUPPORTED;
2157
0
            }
2158
0
        }
2159
2160
0
        if ((item->size_so_far + size) > item->size) {
2161
0
            g_hash_table_remove(ttl->segmented_frames_ht, GUINT_TO_POINTER(key));
2162
0
            return TTL_CORRUPTED;
2163
0
        }
2164
2165
0
        void* dest_buf = item->buf != NULL ? item->buf + item->size_so_far : NULL;
2166
0
        if (!ttl_read_bytes(in, dest_buf, size, err, err_info)) {
2167
0
            g_hash_table_remove(ttl->segmented_frames_ht, GUINT_TO_POINTER(key));
2168
0
            return TTL_ERROR;
2169
0
        }
2170
0
        item->size_so_far += size;
2171
0
        item->next_segment++;
2172
2173
0
        if (item->size_so_far >= item->size) {  /* Reassemble complete */
2174
0
            if (item->buf == NULL) {
2175
                /* Silently discard packets we reassembled without data */
2176
0
                g_hash_table_remove(ttl->segmented_frames_ht, GUINT_TO_POINTER(key));
2177
0
                return TTL_UNSUPPORTED;
2178
0
            }
2179
2180
0
            if (item->type != TTL_SEGMENTED_MESSAGE_ENTRY_TYPE_NESTED_FRAME) {
2181
0
                ws_debug("ttl_read_segmented_message_entry: Unsupported type found: %d", item->type);
2182
0
                g_hash_table_remove(ttl->segmented_frames_ht, GUINT_TO_POINTER(key));
2183
0
                return TTL_UNSUPPORTED;
2184
0
            }
2185
2186
0
            reassembled_item = (ttl_reassembled_entry_t*)g_new(ttl_reassembled_entry_t, 1);
2187
0
            reassembled_item->timestamp = item->timestamp;
2188
0
            reassembled_item->size = item->size;
2189
0
            reassembled_item->buf = item->buf;
2190
2191
0
            item->buf = NULL;   /* Dereference it so that it doesn't get destroyed */
2192
0
            g_hash_table_remove(ttl->segmented_frames_ht, GUINT_TO_POINTER(key));
2193
0
            int64_t* new_off = g_new(int64_t, 1);
2194
0
            *new_off = offset;
2195
0
            g_hash_table_insert(ttl->reassembled_frames_ht, new_off, reassembled_item);
2196
0
        }
2197
0
        else {  /* Reassemble not complete, wait for the rest */
2198
0
            return TTL_UNSUPPORTED;
2199
0
        }
2200
0
    }
2201
0
    else {
2202
        /* We already have the reassembled item, maybe we're re-visiting this entry. Simply skip to the end. */
2203
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
2204
0
            return TTL_ERROR;
2205
0
        }
2206
0
    }
2207
2208
    /* If we're here, we have our reassembled entry */
2209
0
    new_in.buf = reassembled_item->buf;
2210
0
    new_in.size = reassembled_item->size;
2211
0
    new_in.cur_pos = 0;
2212
0
    new_in.validity = VALIDITY_BUF;
2213
2214
    /* Avoid recursion by not supporting nested segmented entries */
2215
0
    *err = 0;
2216
0
    if (!ttl_check_segmented_message_recursion(&new_in, err, err_info)) {
2217
0
        g_hash_table_remove(ttl->reassembled_frames_ht, &offset);
2218
2219
0
        if (*err) {
2220
0
            return TTL_ERROR;
2221
0
        }
2222
0
        return TTL_UNSUPPORTED;
2223
0
    }
2224
2225
0
    if (!ttl_fix_segmented_message_entry_timestamp(&new_in, reassembled_item->timestamp, err, err_info)) {
2226
0
        g_hash_table_remove(ttl->reassembled_frames_ht, &offset);
2227
0
        return TTL_ERROR;
2228
0
    }
2229
2230
    /* Read it as if it was a normal entry, but passing the buffer
2231
     * as input instead of the file handler.
2232
     */
2233
0
    return ttl_read_entry(wth, rec, err, err_info, &new_in, 0, new_in.size);
2234
0
}
2235
2236
static ttl_result_t
2237
0
ttl_read_padding_entry(int* err, char** err_info, ttl_read_t* in, uint16_t size) {
2238
0
    if (!ttl_skip_bytes(in, size, err, err_info)) {
2239
0
        return TTL_ERROR;
2240
0
    }
2241
0
    return TTL_UNSUPPORTED;
2242
0
}
2243
2244
// NOLINTNEXTLINE(misc-no-recursion)
2245
0
static ttl_result_t ttl_read_entry(wtap* wth, wtap_rec* rec, int* err, char** err_info, ttl_read_t* in, int64_t offset, int64_t end) {
2246
0
    ttl_entryheader_t header;
2247
0
    uint16_t    size;
2248
0
    uint16_t    src_addr;
2249
0
    uint8_t     type;
2250
2251
0
    if ((end - offset) < (int64_t)sizeof(ttl_entryheader_t)) {
2252
        /*
2253
         * We probably have a corrupted file, try to recover our alignment
2254
         * by skipping to the next block.
2255
         *
2256
         * Note this doesn't read bytes, so wth->fh->eof might not get set
2257
         * even offset is past the end of the file.
2258
         */
2259
0
        return TTL_CORRUPTED;
2260
0
    }
2261
2262
    /* Try to read the (next) entry header */
2263
0
    if (!ttl_read_bytes(in, &header, sizeof(ttl_entryheader_t), err, err_info)) {
2264
0
        return TTL_ERROR;
2265
0
    }
2266
0
    fix_endianness_ttl_entryheader(&header);
2267
2268
0
    type = header.size_type >> 12;
2269
0
    size = header.size_type & TTL_SIZE_MASK;
2270
0
    src_addr = header.src_addr & TTL_ADDRESS_MASK;
2271
2272
0
    if (size < sizeof(ttl_entryheader_t) || size > (end - offset)) {
2273
        /*
2274
         * Hope the file is simply unaligned and skipping to the next block
2275
         * will fix everything. This could also be the sign of a malformed
2276
         * file; in that case, this error will repeat itself many times.
2277
         */
2278
0
        return TTL_CORRUPTED;
2279
0
    }
2280
2281
0
    size -= sizeof(ttl_entryheader_t);
2282
2283
0
    if (header.dest_addr & TTL_META1_COMPRESSED_FORMAT_MASK) {
2284
        /* We do not support this kind of entries yet. */
2285
0
        ws_debug("ttl_read_entry: Skipping entry with compressed timestamp");
2286
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
2287
0
            return TTL_ERROR;
2288
0
        }
2289
0
        return TTL_UNSUPPORTED;
2290
0
    }
2291
2292
0
    switch (type) {
2293
0
    case TTL_BUS_DATA_ENTRY:
2294
0
        return ttl_read_data_entry(wth, rec, err, err_info, in, size, src_addr, header.status_info);
2295
0
    case TTL_SEGMENTED_MESSAGE_ENTRY:
2296
        /* Recursion is avoided inside ttl_read_segmented_message_entry() */
2297
0
        return ttl_read_segmented_message_entry(wth, rec, err, err_info, in, size, src_addr, header.status_info, offset);
2298
0
    case TTL_PADDING_ENTRY:
2299
0
        return ttl_read_padding_entry(err, err_info, in, size);
2300
0
    default:
2301
0
        ws_debug("ttl_read_entry: Unknown Entry type: %u", type);
2302
0
        if (!ttl_skip_bytes(in, size, err, err_info)) {
2303
0
            return TTL_ERROR;
2304
0
        }
2305
0
        return TTL_UNSUPPORTED;
2306
0
    }
2307
2308
0
}
2309
2310
static bool
2311
0
ttl_xml_node_get_number(xmlNodePtr node, xmlXPathContextPtr ctx, double *ret) {
2312
0
    xmlXPathObjectPtr result;
2313
0
    double val;
2314
2315
0
    if (ret == NULL) {
2316
0
        return false;
2317
0
    }
2318
2319
0
    result = xmlXPathNodeEval(node, (const xmlChar*)"./Number[1]/text()", ctx);
2320
0
    if (result && result->type == XPATH_NODESET && !xmlXPathNodeSetIsEmpty(result->nodesetval)) {
2321
0
        val = xmlXPathCastToNumber(result);
2322
0
        if (!xmlXPathIsNaN(val)) {
2323
0
            *ret = val;
2324
0
            xmlXPathFreeObject(result);
2325
0
            return true;
2326
0
        }
2327
0
    }
2328
2329
0
    xmlXPathFreeObject(result);
2330
0
    return false;
2331
0
}
2332
2333
static bool
2334
0
ttl_xml_node_get_string(xmlNodePtr node, xmlXPathContextPtr ctx, const char* name, char** ret) {
2335
0
    xmlXPathObjectPtr result;
2336
0
    char* str;
2337
2338
0
    if (name == NULL || ret == NULL) {
2339
0
        return false;
2340
0
    }
2341
2342
0
    str = ws_strdup_printf("./%s[1]/text()", name);
2343
2344
0
    result = xmlXPathNodeEval(node, (const xmlChar*)str, ctx);
2345
0
    g_free(str);
2346
0
    if (result && result->type == XPATH_NODESET && !xmlXPathNodeSetIsEmpty(result->nodesetval)) {
2347
0
        str = (char*)xmlXPathCastToString(result);
2348
0
        xmlXPathFreeObject(result);
2349
0
        *ret = ws_strdup(str);
2350
0
        xmlFree(str);
2351
0
        return true;
2352
0
    }
2353
2354
0
    xmlXPathFreeObject(result);
2355
0
    return false;
2356
0
}
2357
2358
static bool
2359
0
ttl_process_xml_config(ttl_t* ttl, const char* text, int size) {
2360
0
    xmlDocPtr           doc;
2361
0
    xmlXPathContextPtr  ctx;
2362
0
    xmlXPathObjectPtr   cascades, devices, functions;
2363
0
    int         i, j, k;
2364
0
    double      val;
2365
0
    uint16_t    cascade, device, function, addr;
2366
0
    char*       user_defined_name = NULL;
2367
2368
0
    doc = xmlParseMemory(text, size);
2369
0
    if (doc == NULL) {
2370
0
        return false;
2371
0
    }
2372
2373
0
    if (xmlDocGetRootElement(doc) == NULL) {
2374
0
        xmlFreeDoc(doc);
2375
0
        return false;   /* Empty XML */
2376
0
    }
2377
2378
0
    ctx = xmlXPathNewContext(doc);
2379
0
    cascades = xmlXPathEvalExpression((const xmlChar*)"/LoggerConfiguration/HWList/Cascades/Cascade", ctx);
2380
0
    if (cascades && cascades->type == XPATH_NODESET && !xmlXPathNodeSetIsEmpty(cascades->nodesetval)) {
2381
0
        for (i = 0; i < cascades->nodesetval->nodeNr; i++) {
2382
0
            if (ttl_xml_node_get_number(cascades->nodesetval->nodeTab[i], ctx, &val) && val >= 0 && val <= 7) {
2383
0
                cascade = (uint16_t)val;
2384
0
                if (val == 0) { /* Only the configuration of the logger is inside the TTL file. The TAPs have their own configuration */
2385
2386
0
                    devices = xmlXPathNodeEval(cascades->nodesetval->nodeTab[i], (const xmlChar*)"./Devices/Device", ctx);
2387
0
                    if (devices && devices->type == XPATH_NODESET && !xmlXPathNodeSetIsEmpty(devices->nodesetval)) {
2388
0
                        for (j = 0; j < devices->nodesetval->nodeNr; j++) {
2389
0
                            if (ttl_xml_node_get_number(devices->nodesetval->nodeTab[j], ctx, &val) && val >= 0 && val <= 15) {
2390
0
                                device = (uint16_t)val;
2391
2392
0
                                functions = xmlXPathNodeEval(devices->nodesetval->nodeTab[j], (const xmlChar*)"./Functions/Function", ctx);
2393
0
                                if (functions && functions->type == XPATH_NODESET && !xmlXPathNodeSetIsEmpty(functions->nodesetval)) {
2394
0
                                    for (k = 0; k < functions->nodesetval->nodeNr; k++) {
2395
0
                                        if (ttl_xml_node_get_number(functions->nodesetval->nodeTab[k], ctx, &val) && val >= 0 && val <= 63) {
2396
0
                                            function = (uint16_t)val;
2397
0
                                            addr = cascade << 10 | device << 6 | function;
2398
2399
0
                                            if (g_hash_table_lookup(ttl->address_to_name_ht, GUINT_TO_POINTER(addr)) == NULL) {
2400
                                                /* Get the name only if we don't already have it */
2401
0
                                                if (ttl_xml_node_get_string(functions->nodesetval->nodeTab[k], ctx, "UserDefinedName", &user_defined_name)) {
2402
0
                                                    g_hash_table_insert(ttl->address_to_name_ht, GUINT_TO_POINTER(addr), user_defined_name);
2403
                                                    /* XXX - At this point, we should check if the interface (in case of Ethernet)
2404
                                                     * is a standalone interface or it's a coupled interface. Since getting this
2405
                                                     * information from the XML is a pain, and the configuration will never be
2406
                                                     * exhaustive, give up and rely on the user setting the mapping themself.
2407
                                                     */
2408
0
                                                }
2409
0
                                            }
2410
2411
0
                                        }
2412
0
                                    }
2413
0
                                }
2414
0
                                xmlXPathFreeObject(functions);
2415
0
                            }
2416
0
                        }
2417
0
                    }
2418
0
                    xmlXPathFreeObject(devices);
2419
0
                }
2420
0
            }
2421
0
        }
2422
0
    }
2423
0
    xmlXPathFreeObject(cascades);
2424
2425
0
    xmlXPathFreeContext(ctx);
2426
0
    xmlFreeDoc(doc);
2427
0
    return true;
2428
0
}
2429
2430
/* Maximum supported line length of preference files */
2431
#define MAX_LINELEN     1024
2432
2433
/** Read a line without trailing (CR)LF. Returns -1 on failure.  */
2434
static int
2435
fgetline(char* buf, int size, FILE* fp)
2436
0
{
2437
0
    if (fgets(buf, size, fp)) {
2438
0
        int len = (int)strcspn(buf, "\r\n");
2439
0
        buf[len] = '\0';
2440
0
        return len;
2441
0
    }
2442
0
    return -1;
2443
2444
0
} /* fgetline */
2445
2446
static bool
2447
0
ttl_is_master_slave_relation_correct(uint16_t master, uint16_t slave) {
2448
0
    uint8_t function = ttl_addr_get_function(master);
2449
2450
0
    if (ttl_addr_get_cascade(master) == 0) {
2451
0
        switch (ttl_addr_get_device(master)) {
2452
0
        case TTL_LOGGER_DEVICE_FPGA:
2453
0
            if (function == TTL_LOGGER_FPGA_FUNCTION_ETHA_CH1) {
2454
0
                return (slave == (master + 1));
2455
0
            }
2456
0
            break;
2457
0
        case TTL_LOGGER_DEVICE_ATOM:
2458
0
            if (function == TTL_LOGGER_ATOM_FUNCTION_ETHA) {
2459
0
                return (slave == (master + 1));
2460
0
            }
2461
0
            break;
2462
0
        case TTL_LOGGER_DEVICE_FPGAB:
2463
0
            switch (function) {
2464
0
            case TTL_LOGGER_FPGAB_FUNCTION_ETHA_CH1:
2465
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH1a_CH1:
2466
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH2a_CH1:
2467
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH3a_CH1:
2468
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH4a_CH1:
2469
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH5a_CH1:
2470
0
            case TTL_LOGGER_FPGAB_FUNCTION_AETH6a_CH1:
2471
0
                return (slave == (master + 1));
2472
0
            default:
2473
0
                break;
2474
0
            }
2475
0
            break;
2476
0
        default:
2477
0
            break;
2478
0
        }
2479
0
    }
2480
0
    else {
2481
0
        switch (ttl_addr_get_device(master)) {
2482
0
        case TTL_TAP_DEVICE_PT15_FPGA:
2483
0
            switch (function) {
2484
0
            case TTL_PT15_FPGA_FUNCTION_BrdR1a:
2485
0
            case TTL_PT15_FPGA_FUNCTION_BrdR2a:
2486
0
            case TTL_PT15_FPGA_FUNCTION_BrdR3a:
2487
0
            case TTL_PT15_FPGA_FUNCTION_BrdR4a:
2488
0
            case TTL_PT15_FPGA_FUNCTION_BrdR5a:
2489
0
            case TTL_PT15_FPGA_FUNCTION_BrdR6a:
2490
0
                return (slave == (master + 1));
2491
0
            default:
2492
0
                break;
2493
0
            }
2494
0
            break;
2495
0
        case TTL_TAP_DEVICE_PT20_FPGA:
2496
0
            switch (function) {
2497
0
            case TTL_PT20_FPGA_FUNCTION_GbEth1a:
2498
0
            case TTL_PT20_FPGA_FUNCTION_GbEth2a:
2499
0
            case TTL_PT20_FPGA_FUNCTION_GbEth3a:
2500
0
                return (slave == (master + 1));
2501
0
            default:
2502
0
                break;
2503
0
            }
2504
0
            break;
2505
0
        case TTL_TAP_DEVICE_PC3_FPGA:
2506
0
            if (function == TTL_PC3_FPGA_FUNCTION_BrdR1a) {
2507
0
                return (slave == (master + 1));
2508
0
            }
2509
0
            break;
2510
0
        default:
2511
0
            break;
2512
0
        }
2513
0
    }
2514
2515
0
    return false;
2516
0
}
2517
2518
static bool
2519
32
ttl_parse_masters_pref_file(GHashTable* ht, const char* path) {
2520
32
    FILE*       fp;
2521
32
    char        line[MAX_LINELEN];
2522
32
    char*       cp;
2523
32
    uint16_t    addr, tmp;
2524
2525
32
    if (ht == NULL || path == NULL) {
2526
0
        return false;
2527
0
    }
2528
2529
32
    fp = ws_fopen(path, "r");
2530
32
    if (fp == NULL) {
2531
32
        return false;
2532
32
    }
2533
2534
0
    while (fgetline(line, sizeof(line), fp) >= 0) {
2535
0
        if ((cp = strchr(line, '#')))
2536
0
            *cp = '\0';
2537
2538
0
        cp = strtok(line, " \t");
2539
0
        if (cp == NULL || !ws_strtou16(cp, NULL, &tmp) || tmp > 7) {
2540
0
            continue;   /* Invalid cascade */
2541
0
        }
2542
0
        addr = tmp << 10;
2543
2544
0
        cp = strtok(NULL, " \t");
2545
0
        if (cp == NULL || !ws_strtou16(cp, NULL, &tmp) || tmp > 15) {
2546
0
            continue;   /* Invalid device */
2547
0
        }
2548
0
        addr |= tmp << 6;
2549
2550
0
        cp = strtok(NULL, " \t");
2551
0
        if (cp == NULL || !ws_strtou16(cp, NULL, &tmp) || tmp > 63) {
2552
0
            continue;   /* Invalid function */
2553
0
        }
2554
0
        addr |= tmp;
2555
2556
0
        cp = strtok(NULL, " \t");
2557
0
        if (cp == NULL || !ws_strtou16(cp, NULL, &tmp) || tmp > 1) {
2558
0
            continue;   /* Invalid flag */
2559
0
        }
2560
2561
0
        if (tmp) {  /* The address is coupled to the master */
2562
0
            if (addr != 0 && ttl_is_master_slave_relation_correct(addr - 1, addr)) {
2563
0
                g_hash_table_insert(ht, GUINT_TO_POINTER(addr), GUINT_TO_POINTER(addr - 1));
2564
0
            }
2565
0
        }
2566
0
        else {  /* The address is independent from the master */
2567
0
            g_hash_table_insert(ht, GUINT_TO_POINTER(addr), GUINT_TO_POINTER(addr));
2568
0
        }
2569
0
    }
2570
2571
0
    fclose(fp);
2572
0
    return true;
2573
32
}
2574
2575
/*
2576
 * This function gets the working mode of the Ethernet interfaces from a
2577
 * configuration file. This only applies to the interfaces that can be
2578
 * configured both as the second side of a tap and independent interfaces.
2579
 * The entry format is the following:   Cascade  Device  Function    Flag
2580
 * A flag value of 0 means independent interface, while 1 means coupled with
2581
 * its master. If an entry is not present, the interface will be treated
2582
 * by ttl_lookup_interface() according to the default behaviour (currently,
2583
 * independent interface for the logger and coupled interface for the taps).
2584
 */
2585
16
bool ttl_init_masters_from_pref_file(GHashTable* ht, const char* app_env_var_prefix) {
2586
16
    char*   pref_file;
2587
16
    bool    ret;
2588
2589
16
    pref_file = get_persconffile_path(TTL_ADDRESS_MASTER_PREFS, true, app_env_var_prefix);
2590
16
    ret = ttl_parse_masters_pref_file(ht, pref_file);
2591
16
    g_free(pref_file);
2592
16
    if (!ret) {
2593
16
        pref_file = get_persconffile_path(TTL_ADDRESS_MASTER_PREFS, false, app_env_var_prefix);
2594
16
        ret = ttl_parse_masters_pref_file(ht, pref_file);
2595
16
        g_free(pref_file);
2596
16
    }
2597
2598
16
    return ret;
2599
16
}
2600
2601
static bool
2602
32
ttl_parse_names_pref_file(GHashTable* ht, const char* path) {
2603
32
    FILE*       fp;
2604
32
    char        line[MAX_LINELEN];
2605
32
    char*       cp;
2606
32
    uint16_t    addr, tmp;
2607
32
    char*       name;
2608
2609
32
    if (ht == NULL || path == NULL) {
2610
0
        return false;
2611
0
    }
2612
2613
32
    fp = ws_fopen(path, "r");
2614
32
    if (fp == NULL) {
2615
32
        return false;
2616
32
    }
2617
2618
0
    while (fgetline(line, sizeof(line), fp) >= 0) {
2619
0
        if ((cp = strchr(line, '#')))
2620
0
            *cp = '\0';
2621
2622
0
        cp = strtok(line, " \t");
2623
0
        if (cp == NULL || !ws_strtou16(cp, NULL, &tmp) || tmp > 7) {
2624
0
            continue;   /* Invalid cascade */
2625
0
        }
2626
0
        addr = tmp << 10;
2627
2628
0
        cp = strtok(NULL, " \t");
2629
0
        if (cp == NULL || !ws_strtou16(cp, NULL, &tmp) || tmp > 15) {
2630
0
            continue;   /* Invalid device */
2631
0
        }
2632
0
        addr |= tmp << 6;
2633
2634
0
        cp = strtok(NULL, " \t");
2635
0
        if (cp == NULL || !ws_strtou16(cp, NULL, &tmp) || tmp > 63) {
2636
0
            continue;   /* Invalid function */
2637
0
        }
2638
0
        addr |= tmp;
2639
2640
0
        cp = strtok(NULL, " \t");
2641
0
        if (cp != NULL && strlen(cp) != 0) {
2642
0
            name = ws_strdup(cp);
2643
0
            g_hash_table_insert(ht, GUINT_TO_POINTER(addr), name);
2644
0
        }
2645
0
    }
2646
2647
0
    fclose(fp);
2648
0
    return true;
2649
32
}
2650
2651
/*
2652
 * This function gets the names of the interfaces from a configuration file.
2653
 * The entry format is the following:   Cascade  Device  Function    Name
2654
 * If an entry is not present, the value from the configuration XML in the file
2655
 * is used. If also that is not present, a meaningful name is generated in
2656
 * ttl_add_interface_name() starting from the interface address.
2657
 */
2658
16
bool ttl_init_names_from_pref_file(GHashTable* ht, const char* app_env_var_prefix) {
2659
16
    char*   pref_file;
2660
16
    bool    ret;
2661
2662
16
    pref_file = get_persconffile_path(TTL_ADDRESS_NAME_PREFS, true, app_env_var_prefix);
2663
16
    ret = ttl_parse_names_pref_file(ht, pref_file);
2664
16
    g_free(pref_file);
2665
16
    if (!ret) {
2666
16
        pref_file = get_persconffile_path(TTL_ADDRESS_NAME_PREFS, false, app_env_var_prefix);
2667
16
        ret = ttl_parse_names_pref_file(ht, pref_file);
2668
16
        g_free(pref_file);
2669
16
    }
2670
2671
16
    return ret;
2672
16
}
2673
2674
static void
2675
0
ttl_cleanup(ttl_t* ttl) {
2676
0
    if (ttl != NULL) {
2677
0
        if (ttl->address_to_iface_ht != NULL) {
2678
0
            g_hash_table_destroy(ttl->address_to_iface_ht);
2679
0
        }
2680
0
        if (ttl->address_to_master_ht != NULL) {
2681
0
            g_hash_table_destroy(ttl->address_to_master_ht);
2682
0
        }
2683
0
        if (ttl->address_to_name_ht != NULL) {
2684
0
            g_hash_table_destroy(ttl->address_to_name_ht);
2685
0
        }
2686
0
        if (ttl->segmented_frames_ht != NULL) {
2687
0
            g_hash_table_destroy(ttl->segmented_frames_ht);
2688
0
        }
2689
0
        if (ttl->reassembled_frames_ht != NULL) {
2690
0
            g_hash_table_destroy(ttl->reassembled_frames_ht);
2691
0
        }
2692
0
        g_free(ttl);
2693
0
    }
2694
0
}
2695
2696
wtap_open_return_val
2697
0
ttl_open(wtap* wth, int* err, char** err_info) {
2698
0
    ttl_fileheader_t    header;
2699
0
    ttl_t*              ttl;
2700
0
    unsigned int        offset;
2701
2702
0
    ws_debug("opening file");
2703
2704
0
    if (!wtap_read_bytes_or_eof(wth->fh, &header, sizeof(ttl_fileheader_t), err, err_info)) {
2705
2706
0
        ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err);
2707
0
        if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
2708
            /*
2709
             * Short read or EOF.
2710
             *
2711
             * We're reading this as part of an open, so
2712
             * the file is too short to be a ttl file.
2713
             */
2714
0
            *err = 0;
2715
0
            g_free(*err_info);
2716
0
            *err_info = NULL;
2717
0
            return WTAP_OPEN_NOT_MINE;
2718
0
        }
2719
0
        return WTAP_OPEN_ERROR;
2720
0
    }
2721
2722
0
    fix_endianness_ttl_fileheader(&header);
2723
2724
0
    if (memcmp(header.magic, ttl_magic, sizeof(ttl_magic))) {
2725
0
        return WTAP_OPEN_NOT_MINE;
2726
0
    }
2727
    /* This seems to be a TLL! */
2728
2729
    /* Check for valid block size */
2730
0
    if (header.block_size < sizeof(ttl_entryheader_t)) {
2731
0
        *err = WTAP_ERR_BAD_FILE;
2732
0
        *err_info = ws_strdup("ttl: entry block size cannot be smaller than an entry header");
2733
0
        return WTAP_OPEN_ERROR;
2734
0
    }
2735
    /* Check for a valid header length */
2736
0
    if (header.header_size < sizeof(ttl_fileheader_t)) {
2737
0
        *err = WTAP_ERR_BAD_FILE;
2738
0
        *err_info = ws_strdup("ttl: file header length too short");
2739
0
        return WTAP_OPEN_ERROR;
2740
0
    }
2741
2742
0
    offset = (unsigned int)sizeof(ttl_fileheader_t);
2743
2744
    /* Prepare our private context. */
2745
0
    ttl = g_new(ttl_t, 1);
2746
0
    ttl->next_interface_id = 0;
2747
0
    ttl->block_size = header.block_size;
2748
0
    ttl->header_size = header.header_size;
2749
0
    ttl->address_to_iface_ht = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
2750
0
    ttl->address_to_master_ht = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
2751
0
    ttl->address_to_name_ht = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
2752
0
    ttl->segmented_frames_ht = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, ttl_free_segmented_entry);
2753
0
    ttl->reassembled_frames_ht = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, ttl_free_reassembled_entry);
2754
2755
0
    if (header.version >= 10) {
2756
0
        if (header.header_size < (offset + TTL_LOGFILE_INFO_SIZE)) {
2757
0
            report_warning("Found TTL file version %u with shorter header length than expected.", header.version);
2758
0
        }
2759
0
        else {
2760
            /* TODO: Extract needed info from the rest of the header. */
2761
0
            if (!wtap_read_bytes(wth->fh, NULL, TTL_LOGFILE_INFO_SIZE, err, err_info)) {
2762
0
                ttl_cleanup(ttl);
2763
0
                return WTAP_OPEN_ERROR;
2764
0
            }
2765
0
            offset += TTL_LOGFILE_INFO_SIZE;
2766
0
            unsigned int xml_len = header.header_size - offset;
2767
0
            if (xml_len != 0) {
2768
0
                char* xml = g_try_malloc(xml_len);
2769
0
                if (xml == NULL) {
2770
0
                    *err = WTAP_ERR_INTERNAL;
2771
0
                    *err_info = ws_strdup("ttl: cannot allocate memory");
2772
0
                    ttl_cleanup(ttl);
2773
0
                    return false;
2774
0
                }
2775
0
                if (!wtap_read_bytes(wth->fh, xml, xml_len, err, err_info)) {
2776
0
                    g_free(xml);
2777
0
                    ttl_cleanup(ttl);
2778
0
                    return WTAP_OPEN_ERROR;
2779
0
                }
2780
0
                if (!ttl_process_xml_config(ttl, xml, xml_len)) {
2781
0
                    report_warning("Cannot extract information from TTL XML.");
2782
0
                }
2783
0
                g_free(xml);
2784
0
                offset += xml_len;
2785
0
            }
2786
0
        }
2787
0
    }
2788
2789
0
    if ((header.header_size - offset) != 0) {
2790
0
        if (!wtap_read_bytes(wth->fh, NULL, header.header_size - offset, err, err_info)) {
2791
0
            ttl_cleanup(ttl);
2792
0
            return WTAP_OPEN_ERROR;
2793
0
        }
2794
0
    }
2795
2796
0
    ttl_init_masters_from_pref_file(ttl->address_to_master_ht, wth->app_env_var_prefix);
2797
0
    ttl_init_names_from_pref_file(ttl->address_to_name_ht, wth->app_env_var_prefix);
2798
2799
0
    wth->priv = (void*)ttl;
2800
0
    wth->file_encap = WTAP_ENCAP_NONE;
2801
0
    wth->snapshot_length = 0;
2802
0
    wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
2803
0
    wth->subtype_read = ttl_read;
2804
0
    wth->subtype_seek_read = ttl_seek_read;
2805
0
    wth->subtype_close = ttl_close;
2806
0
    wth->file_type_subtype = ttl_file_type_subtype;
2807
2808
0
    return WTAP_OPEN_MINE;
2809
0
}
2810
2811
static inline int64_t
2812
0
ttl_next_block(const ttl_t* ttl, int64_t pos) {
2813
0
    if (ttl == NULL || pos < 0 || pos < ttl->header_size) {
2814
0
        return pos;
2815
0
    }
2816
2817
    // ttl_open should assure this
2818
0
    ws_assert(ttl->block_size >= sizeof(ttl_entryheader_t));
2819
0
    return pos + ttl->block_size - ((pos - ttl->header_size) % ttl->block_size);
2820
0
}
2821
2822
0
static bool ttl_read(wtap* wth, wtap_rec* rec, int* err, char** err_info, int64_t* data_offset) {
2823
0
    ttl_read_t      input;
2824
0
    int64_t         pos, end;
2825
0
    ttl_result_t    res;
2826
0
    unsigned        corrupted_blocks = 0;
2827
2828
0
    input.fh = wth->fh;
2829
0
    input.validity = VALIDITY_FH;
2830
2831
0
    do {
2832
0
        pos = file_tell(wth->fh);
2833
0
        end = ttl_next_block((ttl_t*)wth->priv, pos);
2834
2835
0
        res = ttl_read_entry(wth, rec, err, err_info, &input, pos, end);
2836
0
        if (G_UNLIKELY(res == TTL_CORRUPTED)) {
2837
0
            if (++corrupted_blocks > TTL_MAX_CORRUPTED_BLOCKS) {
2838
0
                *err = WTAP_ERR_BAD_FILE;
2839
0
                *err_info = ws_strdup("ttl: too many consecutive corrupted blocks");
2840
0
                return false;
2841
0
            }
2842
0
            ws_warning("ttl_read(): Unaligned block found, skipping to next block offset: 0x%" PRIx64, end);
2843
0
            report_warning("Found unaligned TTL block. Skipping to the next one.");
2844
0
            if (file_seek(wth->fh, end, SEEK_SET, err) < 0) {
2845
0
                return false;   /* Seek error */
2846
0
            }
2847
0
        }
2848
        /*
2849
         * XXX - For now we simply skip over any entry we don't understand,
2850
         * but in the future we might want an easy way to report warnings
2851
         * without spamming the user with dialog boxes.
2852
         */
2853
0
    } while (res > TTL_NO_ERROR);
2854
2855
0
    if (G_LIKELY(res == TTL_NO_ERROR)) {
2856
0
        *data_offset = pos;
2857
0
        return true;
2858
0
    }
2859
2860
0
    return false;
2861
0
}
2862
2863
0
static bool ttl_seek_read(wtap* wth, int64_t seek_off, wtap_rec* rec, int* err, char** err_info) {
2864
0
    ttl_read_t      input;
2865
0
    ttl_result_t    res;
2866
2867
0
    input.fh = wth->random_fh;
2868
0
    input.validity = VALIDITY_FH;
2869
2870
    /* seek to the right file position */
2871
0
    if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
2872
0
        return false;   /* Seek error */
2873
0
    }
2874
2875
0
    res = ttl_read_entry(wth, rec, err, err_info, &input, seek_off, ttl_next_block((ttl_t*)wth->priv, seek_off));
2876
0
    if (G_LIKELY(res == TTL_NO_ERROR)) {
2877
0
        return true;
2878
0
    }
2879
2880
0
    if (res > TTL_NO_ERROR) {
2881
        /*
2882
         * If we're here, there has been an error during the first pass and we
2883
         * returned true on an unsupported or unaligned entry.
2884
         */
2885
0
        *err = WTAP_ERR_INTERNAL;
2886
0
        *err_info = ws_strdup_printf("ttl_seek_read called with invalid offset: 0x%" PRIx64, seek_off);
2887
0
    }
2888
2889
0
    return false;
2890
0
}
2891
2892
0
static void ttl_close(wtap* wth) {
2893
0
    if (wth != NULL) {
2894
0
        ttl_cleanup((ttl_t*)wth->priv);
2895
0
        wth->priv = NULL;
2896
0
    }
2897
0
}
2898
2899
 /* Options for interface blocks. */
2900
static const struct supported_option_type interface_block_options_supported[] = {
2901
    /* No comments, just an interface name. */
2902
    { OPT_IDB_NAME, ONE_OPTION_SUPPORTED }
2903
};
2904
2905
static const struct supported_block_type ttl_blocks_supported[] = {
2906
    { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED },
2907
    { WTAP_BLOCK_IF_ID_AND_INFO, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_block_options_supported) },
2908
};
2909
2910
static const struct file_type_subtype_info ttl_info = {
2911
        "TTTech Computertechnik TTX Logger (TTL) logfile", "ttl", "ttl", NULL,
2912
        false, BLOCKS_SUPPORTED(ttl_blocks_supported),
2913
        NULL, NULL, NULL
2914
};
2915
2916
void register_ttl(void)
2917
16
{
2918
16
    ttl_file_type_subtype = wtap_register_file_type_subtype(&ttl_info);
2919
2920
    /*
2921
     * Register name for backwards compatibility with the
2922
     * wtap_filetypes table in Lua.
2923
     */
2924
16
    wtap_register_backwards_compatibility_lua_name("TTL", ttl_file_type_subtype);
2925
16
}
2926
2927
2928
 /*
2929
  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2930
  *
2931
  * Local variables:
2932
  * c-basic-offset: 4
2933
  * tab-width: 8
2934
  * indent-tabs-mode: nil
2935
  * End:
2936
  *
2937
  * vi: set shiftwidth=4 tabstop=8 expandtab:
2938
  * :indentSize=4:tabSize=8:noTabs=true:
2939
  */