Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/file-ttl.c
Line
Count
Source
1
/* file-ttl.c
2
 *
3
 * TTX Logger (TTL) file format from TTTech Computertechnik AG dissector by
4
 * Giovanni Musto <giovanni.musto@italdesign.it>
5
 * Copyright 2024-2026 Giovanni Musto
6
 *
7
 * This dissector allows to parse TTL files.
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
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
#include "config.h"
15
16
#include <epan/proto.h>
17
#include <epan/packet.h>
18
#include <epan/expert.h>
19
#include <epan/tvbuff.h>
20
21
#include <wiretap/ttl.h>
22
23
static int proto_file_ttl;
24
25
static dissector_handle_t ttl_handle;
26
static dissector_handle_t xml_handle;
27
28
static int hf_ttl_header;
29
static int hf_ttl_header_magic;
30
static int hf_ttl_header_file_format_version;
31
static int hf_ttl_header_block_size;
32
static int hf_ttl_header_header_size;
33
static int hf_ttl_header_logfile_info;
34
35
static int hf_ttl_header_logfile_info_logger_sn;
36
static int hf_ttl_header_logfile_info_logger_sw_version;
37
static int hf_ttl_header_logfile_info_measurement_creation_date;
38
static int hf_ttl_header_logfile_info_measurement_creation_timestamp;
39
static int hf_ttl_header_logfile_info_supplier_name;
40
static int hf_ttl_header_logfile_info_description;
41
static int hf_ttl_header_logfile_info_hw_version;
42
static int hf_ttl_header_logfile_info_configuration_file_name;
43
static int hf_ttl_header_logfile_info_tracefile_sorted;
44
static int hf_ttl_header_logfile_info_tracefile_split_index;
45
static int hf_ttl_header_logfile_info_completion_date;
46
static int hf_ttl_header_logfile_info_completion_timestamp;
47
static int hf_ttl_header_logfile_info_tc_sw_bootloader_version;
48
static int hf_ttl_header_logfile_info_tc_sw_firmware_version;
49
static int hf_ttl_header_logfile_info_most25_fw_version;
50
static int hf_ttl_header_logfile_info_most150_fw_version;
51
static int hf_ttl_header_logfile_info_split_file_creation_date;
52
static int hf_ttl_header_logfile_info_split_file_creation_timestamp;
53
static int hf_ttl_header_logfile_info_unused_bytes;
54
static int hf_ttl_header_logfile_info_sleep_counter;
55
static int hf_ttl_header_logfile_info_reserved_bytes;
56
static int hf_ttl_header_configuration;
57
58
static int hf_ttl_trace_data;
59
static int hf_ttl_block;
60
61
static expert_field ei_ttl_block_size_too_short;
62
static expert_field ei_ttl_header_size_too_short;
63
static expert_field ei_ttl_header_size_implausible;
64
static expert_field ei_ttl_header_logfile_info_too_short;
65
66
static int ett_ttl;
67
static int ett_ttl_header;
68
static int ett_ttl_header_logfile_info;
69
static int ett_ttl_header_configuration;
70
static int ett_ttl_trace_data;
71
static int ett_ttl_block;
72
73
static const value_string hf_ttl_header_logfile_info_tracefile_sorted_vals[] = {
74
    { '0',  "Not Sorted" },
75
    { '1',  "Sorted" },
76
    { 0, NULL }
77
};
78
79
void proto_register_file_ttl(void);
80
void proto_reg_handoff_file_ttl(void);
81
82
0
#define TTL_MAGIC_SIZE 4
83
static const uint8_t ttl_magic[TTL_MAGIC_SIZE] = { 'T', 'T', 'L', ' ' };
84
85
static proto_item*
86
0
dissect_ttl_sw_version(proto_tree* tree, int hf, tvbuff_t* tvb, int offset, int length) {
87
0
    uint8_t             major, minor, build, patch;
88
0
    header_field_info*  hfinfo;
89
90
0
    major = tvb_get_uint8(tvb, offset);
91
0
    minor = tvb_get_uint8(tvb, offset + 1);
92
0
    build = tvb_get_uint8(tvb, offset + 2);
93
0
    patch = tvb_get_uint8(tvb, offset + 3);
94
95
0
    hfinfo = proto_registrar_get_nth(hf);
96
97
0
    return proto_tree_add_bytes_format(tree, hf, tvb, offset, length, NULL, "%s: %d.%d.%d.%d",
98
0
        hfinfo->name, major, minor, build, patch);
99
0
}
100
101
static proto_item*
102
0
dissect_ttl_hw_version(proto_tree* tree, int hf, tvbuff_t* tvb, int offset, int length) {
103
0
    uint16_t            major, minor;
104
0
    header_field_info*  hfinfo;
105
106
0
    major = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
107
0
    minor = tvb_get_uint16(tvb, offset + 2, ENC_LITTLE_ENDIAN);
108
109
0
    hfinfo = proto_registrar_get_nth(hf);
110
111
0
    return proto_tree_add_bytes_format(tree, hf, tvb, offset, length, NULL, "%s: %d.%d",
112
0
        hfinfo->name, major, minor);
113
0
}
114
115
static proto_item*
116
0
dissect_ttl_tc_sw_version(proto_tree* tree, int hf, tvbuff_t* tvb, int offset, int length) {
117
0
    uint8_t             major, minor;
118
0
    header_field_info*  hfinfo;
119
120
0
    major = tvb_get_uint8(tvb, offset);
121
0
    minor = tvb_get_uint8(tvb, offset + 1);
122
123
0
    hfinfo = proto_registrar_get_nth(hf);
124
125
0
    return proto_tree_add_bytes_format(tree, hf, tvb, offset, length, NULL, "%s: %d.%d",
126
0
        hfinfo->name, major, minor);
127
0
}
128
129
static int
130
0
dissect_ttl_logfile_information(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree, int offset) {
131
0
    int orig_offset = offset;
132
133
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_logger_sn, tvb, offset, 20, ENC_NA);
134
0
    offset += 20;
135
0
    dissect_ttl_sw_version(tree, hf_ttl_header_logfile_info_logger_sw_version, tvb, offset, 4);
136
0
    offset += 4;
137
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_measurement_creation_date, tvb, offset, 20, ENC_NA);
138
0
    offset += 20;
139
0
    proto_tree_add_time_item(tree, hf_ttl_header_logfile_info_measurement_creation_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN|ENC_TIME_USECS, NULL, NULL, NULL);
140
0
    offset += 8;
141
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_supplier_name, tvb, offset, 28, ENC_NA);
142
0
    offset += 28;
143
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_description, tvb, offset, 128, ENC_NA);
144
0
    offset += 128;
145
0
    dissect_ttl_hw_version(tree, hf_ttl_header_logfile_info_hw_version, tvb, offset, 4);
146
0
    offset += 4;
147
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_configuration_file_name, tvb, offset, 64, ENC_NA);
148
0
    offset += 64;
149
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_tracefile_sorted, tvb, offset, 1, ENC_NA);
150
0
    offset += 1;
151
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_tracefile_split_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
152
0
    offset += 2;
153
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_completion_date, tvb, offset, 20, ENC_NA);
154
0
    offset += 20;
155
0
    proto_tree_add_time_item(tree, hf_ttl_header_logfile_info_completion_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN|ENC_TIME_USECS, NULL, NULL, NULL);
156
0
    offset += 8;
157
0
    dissect_ttl_tc_sw_version(tree, hf_ttl_header_logfile_info_tc_sw_bootloader_version, tvb, offset, 2);
158
0
    offset += 2;
159
0
    dissect_ttl_tc_sw_version(tree, hf_ttl_header_logfile_info_tc_sw_firmware_version, tvb, offset, 2);
160
0
    offset += 2;
161
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_most25_fw_version, tvb, offset, 32, ENC_NA);
162
0
    offset += 32;
163
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_most150_fw_version, tvb, offset, 32, ENC_NA);
164
0
    offset += 32;
165
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_split_file_creation_date, tvb, offset, 20, ENC_NA);
166
0
    offset += 20;
167
0
    proto_tree_add_time_item(tree, hf_ttl_header_logfile_info_split_file_creation_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN|ENC_TIME_USECS, NULL, NULL, NULL);
168
0
    offset += 8;
169
0
    proto_tree_add_bytes_item(tree, hf_ttl_header_logfile_info_unused_bytes, tvb, offset, 512, ENC_NA, NULL, NULL, NULL);
170
0
    offset += 512;
171
0
    proto_tree_add_item(tree, hf_ttl_header_logfile_info_sleep_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
172
0
    offset += 4;
173
0
    proto_tree_add_bytes_item(tree, hf_ttl_header_logfile_info_reserved_bytes, tvb, offset, 3161, ENC_NA, NULL, NULL, NULL);
174
0
    offset += 3161;
175
176
0
    return offset - orig_offset;
177
0
}
178
179
static int
180
0
dissect_ttl_block(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset, int size) {
181
0
    proto_tree* block_subtree;
182
0
    proto_item* ti;
183
0
    tvbuff_t* new_tvb;
184
0
    int orig_offset = offset;
185
0
    int dissected;
186
187
0
    if (size > 0) {
188
0
        ti = proto_tree_add_item(tree, hf_ttl_block, tvb, offset, size, ENC_NA);
189
0
        block_subtree = proto_item_add_subtree(ti, ett_ttl_block);
190
191
0
        if (ttl_handle) {
192
0
            while (size >= (int)sizeof(ttl_entryheader_t)) {
193
0
                new_tvb = tvb_new_subset_length(tvb, offset, size);
194
0
                dissected = call_dissector(ttl_handle, new_tvb, pinfo, block_subtree);
195
0
                offset += dissected;
196
0
                size -= dissected;
197
0
            }
198
0
        }
199
0
    }
200
201
0
    return offset - orig_offset;
202
0
}
203
204
static int
205
0
dissect_file_ttl(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) {
206
0
    unsigned        offset = 0;
207
0
    proto_tree     *ttl_tree, *header_subtree, *logfile_info_subtree, *configuration_subtree, *trace_data_subtree;
208
0
    proto_item*     ti;
209
0
    uint32_t        format_version, header_length, block_size;
210
0
    unsigned        logfile_info_length, xml_length, remaining;
211
212
0
    if (tvb_captured_length(tvb) < sizeof(ttl_fileheader_t) || tvb_memeql(tvb, 0, ttl_magic, TTL_MAGIC_SIZE) != 0) {
213
0
        return 0;
214
0
    }
215
216
0
    ti = proto_tree_add_item(tree, proto_file_ttl, tvb, offset, -1, ENC_NA);
217
0
    ttl_tree = proto_item_add_subtree(ti, ett_ttl);
218
0
    header_length = tvb_get_uint32(tvb, 12, ENC_LITTLE_ENDIAN);
219
220
0
    ti = proto_tree_add_item(ttl_tree, hf_ttl_header, tvb, offset, header_length, ENC_NA);
221
0
    header_subtree = proto_item_add_subtree(ti, ett_ttl_header);
222
223
0
    proto_tree_add_item(header_subtree, hf_ttl_header_magic, tvb, offset, 4, ENC_NA);
224
0
    offset += 4;
225
0
    proto_tree_add_item_ret_uint(header_subtree, hf_ttl_header_file_format_version, tvb, offset, 4, ENC_LITTLE_ENDIAN, &format_version);
226
0
    offset += 4;
227
0
    ti = proto_tree_add_item_ret_uint(header_subtree, hf_ttl_header_block_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &block_size);
228
0
    offset += 4;
229
0
    if (block_size == 0) {
230
0
        expert_add_info(pinfo, ti, &ei_ttl_block_size_too_short);
231
0
    }
232
0
    ti = proto_tree_add_item(header_subtree, hf_ttl_header_header_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
233
0
    offset += 4;
234
0
    if (header_length < sizeof(ttl_fileheader_t)) {
235
0
        expert_add_info(pinfo, ti, &ei_ttl_header_size_too_short);
236
0
    }
237
0
    else if (header_length > INT32_MAX) {
238
0
        expert_add_info(pinfo, ti, &ei_ttl_header_size_implausible);
239
0
    }
240
0
    else {
241
0
        logfile_info_length = MIN(MIN(tvb_captured_length_remaining(tvb, offset), header_length - offset), TTL_LOGFILE_INFO_SIZE);
242
0
        ti = proto_tree_add_item(header_subtree, hf_ttl_header_logfile_info, tvb, offset, logfile_info_length, ENC_NA);
243
0
        logfile_info_subtree = proto_item_add_subtree(ti, ett_ttl_header_logfile_info);
244
245
0
        if ((logfile_info_length < TTL_LOGFILE_INFO_SIZE) && format_version >= 10) {
246
            /* Starting from format version 10, the header is at least TTL_LOGFILE_INFO_SIZE bytes */
247
0
            expert_add_info(pinfo, ti, &ei_ttl_header_logfile_info_too_short);
248
0
        }
249
250
0
        offset += dissect_ttl_logfile_information(tvb, pinfo, logfile_info_subtree, offset);
251
252
0
        if (format_version >= 10 && header_length > offset) {
253
0
            xml_length = MIN(tvb_captured_length_remaining(tvb, offset), header_length - offset);
254
0
            ti = proto_tree_add_item(header_subtree, hf_ttl_header_configuration, tvb, offset, xml_length, ENC_NA);
255
256
0
            if (xml_handle) {
257
0
                configuration_subtree = proto_item_add_subtree(ti, ett_ttl_header_configuration);
258
0
                tvbuff_t* new_tvb = tvb_new_subset_length(tvb, offset, xml_length);
259
0
                call_dissector(xml_handle, new_tvb, pinfo, configuration_subtree);
260
0
            }
261
0
        }
262
263
0
        offset = header_length;
264
265
0
        ti = proto_tree_add_item(ttl_tree, hf_ttl_trace_data, tvb, offset, -1, ENC_NA);
266
0
        trace_data_subtree = proto_item_add_subtree(ti, ett_ttl_trace_data);
267
268
0
        if (block_size != 0) {
269
0
            while ((remaining = tvb_captured_length_remaining(tvb, offset)) > 0) {
270
0
                dissect_ttl_block(tvb, pinfo, trace_data_subtree, offset, MIN(block_size, remaining));
271
0
                offset += block_size;
272
0
            }
273
0
        }
274
275
0
    }
276
277
0
    return offset;
278
0
}
279
280
static bool
281
0
dissect_file_ttl_heur(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data) {
282
0
    return dissect_file_ttl(tvb, pinfo, tree, data) > 0;
283
0
}
284
285
void
286
15
proto_register_file_ttl(void) {
287
15
    expert_module_t* expert_file_ttl;
288
289
15
    static hf_register_info hf[] = {
290
15
        { &hf_ttl_header,
291
15
            { "Header Section", "ttl.header", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
292
15
        { &hf_ttl_header_magic,
293
15
            { "Magic", "ttl.header.magic", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
294
15
        { &hf_ttl_header_file_format_version,
295
15
            { "File Format Version", "ttl.header.version", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } },
296
15
        { &hf_ttl_header_block_size,
297
15
            { "Block Size", "ttl.header.block_size", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } },
298
15
        { &hf_ttl_header_header_size,
299
15
            { "Header Size", "ttl.header.header_size", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } },
300
15
        { &hf_ttl_header_logfile_info,
301
15
            { "Logfile Information", "ttl.header.logfile_info", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
302
303
15
        { &hf_ttl_header_logfile_info_logger_sn,
304
15
            { "Logger Serial Number", "ttl.header.logfile_info.logger_sn", FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL } },
305
15
        { &hf_ttl_header_logfile_info_logger_sw_version,
306
15
            { "Logger Software Version", "ttl.header.logfile_info.logger_sw_version", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
307
15
        { &hf_ttl_header_logfile_info_measurement_creation_date,
308
15
            { "Measurement Creation Date", "ttl.header.logfile_info.measurement_creation_date", FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL } },
309
15
        { &hf_ttl_header_logfile_info_measurement_creation_timestamp,
310
15
            { "Measurement Creation Timestamp", "ttl.header.logfile_info.measurement_creation_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
311
15
        { &hf_ttl_header_logfile_info_supplier_name,
312
15
            { "Supplier Name", "ttl.header.logfile_info.supplier_name", FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL } },
313
15
        { &hf_ttl_header_logfile_info_description,
314
15
            { "Description", "ttl.header.logfile_info.description", FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL } },
315
15
        { &hf_ttl_header_logfile_info_hw_version,
316
15
            { "Hardware Version", "ttl.header.logfile_info.hw_version", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
317
15
        { &hf_ttl_header_logfile_info_configuration_file_name,
318
15
            { "Configuration File Name", "ttl.header.logfile_info.config_filename", FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL } },
319
15
        { &hf_ttl_header_logfile_info_tracefile_sorted,
320
15
            { "Tracefile Sorted", "ttl.header.logfile_info.tracefile_sorted", FT_UINT8, BASE_HEX, VALS(hf_ttl_header_logfile_info_tracefile_sorted_vals), 0x0, NULL, HFILL} },
321
15
        { &hf_ttl_header_logfile_info_tracefile_split_index,
322
15
            { "Tracefile Split Index", "ttl.header.logfile_info.tracefile_split_index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
323
15
        { &hf_ttl_header_logfile_info_completion_date,
324
15
            { "Completion Date", "ttl.header.logfile_info.completion_date", FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL } },
325
15
        { &hf_ttl_header_logfile_info_completion_timestamp,
326
15
            { "Completion Timestamp", "ttl.header.logfile_info.completion_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
327
15
        { &hf_ttl_header_logfile_info_tc_sw_bootloader_version,
328
15
            { "TC SW Bootloader Version", "ttl.header.logfile_info.tc_sw_bootloader_version", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
329
15
        { &hf_ttl_header_logfile_info_tc_sw_firmware_version,
330
15
            { "TC SW Firmware Version", "ttl.header.logfile_info.tc_sw_firmware_version", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
331
15
        { &hf_ttl_header_logfile_info_most25_fw_version,
332
15
            { "MOST25 Piggy Firmware Version", "ttl.header.logfile_info.most25_fw_version", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
333
15
        { &hf_ttl_header_logfile_info_most150_fw_version,
334
15
            { "MOST150 Piggy Firmware Version", "ttl.header.logfile_info.most150_fw_version", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
335
15
        { &hf_ttl_header_logfile_info_split_file_creation_date,
336
15
            { "Split File Creation Date", "ttl.header.logfile_info.split_file_creation_date", FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL } },
337
15
        { &hf_ttl_header_logfile_info_split_file_creation_timestamp,
338
15
            { "Split File Creation Timestamp", "ttl.header.logfile_info.split_file_creation_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
339
15
        { &hf_ttl_header_logfile_info_unused_bytes,
340
15
            { "Unused Bytes", "ttl.header.logfile_info.unused", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
341
15
        { &hf_ttl_header_logfile_info_sleep_counter,
342
15
            { "Sleep Counter", "ttl.header.logfile_info.sleep_counter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
343
15
        { &hf_ttl_header_logfile_info_reserved_bytes,
344
15
            { "Reserved Bytes", "ttl.header.logfile_info.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
345
15
        { &hf_ttl_header_configuration,
346
15
            { "Configuration", "ttl.header.configuration", FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL } },
347
348
15
        { &hf_ttl_trace_data,
349
15
            { "Trace Data Section", "ttl.trace_data", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
350
15
        { &hf_ttl_block,
351
15
            { "Trace Data Block", "ttl.trace_data_block", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
352
15
    };
353
354
15
    static ei_register_info ei[] = {
355
15
        { &ei_ttl_block_size_too_short,
356
15
            { "ttl.block_size_too_short", PI_MALFORMED, PI_ERROR,
357
15
                "block size is too short",
358
15
                EXPFILL }},
359
15
        { &ei_ttl_header_size_too_short,
360
15
            { "ttl.header_size_too_short", PI_MALFORMED, PI_ERROR,
361
15
                "header size is too short",
362
15
                EXPFILL }},
363
15
        { &ei_ttl_header_size_implausible,
364
15
            { "ttl.header_size_implausible", PI_MALFORMED, PI_ERROR,
365
15
                "header size is implausible",
366
15
                EXPFILL }},
367
15
        { &ei_ttl_header_logfile_info_too_short,
368
15
            { "ttl.header.logfile_info_too_short", PI_MALFORMED, PI_ERROR,
369
15
                "logfile info is too short",
370
15
                EXPFILL }},
371
15
    };
372
373
15
    static int* ett[] = {
374
15
        &ett_ttl,
375
15
        &ett_ttl_header,
376
15
        &ett_ttl_header_logfile_info,
377
15
        &ett_ttl_header_configuration,
378
15
        &ett_ttl_trace_data,
379
15
        &ett_ttl_block,
380
15
    };
381
382
15
    proto_file_ttl = proto_register_protocol("TTL File Format", "File-TTL", "file-ttl");
383
15
    expert_file_ttl = expert_register_protocol(proto_file_ttl);
384
15
    expert_register_field_array(expert_file_ttl, ei, array_length(ei));
385
386
15
    proto_register_field_array(proto_file_ttl, hf, array_length(hf));
387
15
    proto_register_subtree_array(ett, array_length(ett));
388
389
15
    register_dissector("file-ttl", dissect_file_ttl, proto_file_ttl);
390
15
}
391
392
void
393
15
proto_reg_handoff_file_ttl(void) {
394
15
    heur_dissector_add("wtap_file", dissect_file_ttl_heur, "TTL File", "ttl_wtap", proto_file_ttl, HEURISTIC_ENABLE);
395
15
    ttl_handle = find_dissector_add_dependency("ttl", proto_file_ttl);
396
15
    xml_handle = find_dissector_add_dependency("xml", proto_file_ttl);
397
15
}
398
399
/*
400
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
401
 *
402
 * Local Variables:
403
 * c-basic-offset: 4
404
 * tab-width: 8
405
 * indent-tabs-mode: nil
406
 * End:
407
 *
408
 * ex: set shiftwidth=4 tabstop=8 expandtab:
409
 * :indentSize=4:tabSize=8:noTabs=true:
410
 */