Bug Summary

File:builds/wireshark/wireshark/wiretap/blf.c
Warning:line 2269, column 13
Value stored to 'object_length' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name blf.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D wiretap_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -I /builds/wireshark/wireshark/build/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-11-03-100334-3662-1 -x c /builds/wireshark/wireshark/wiretap/blf.c
1/* blf.c
2 *
3 * Wiretap Library
4 * Copyright (c) 1998 by Gilbert Ramirez <[email protected]>
5 *
6 * File format support for the Binary Log File (BLF) file format from
7 * Vector Informatik decoder
8 * Copyright (c) 2021-2025 by Dr. Lars Völker <[email protected]>
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 /*
14 * The following was used as a reference for the file format:
15 * https://bitbucket.org/tobylorenz/vector_blf
16 * The repo above includes multiple examples files as well.
17 */
18
19#include "config.h"
20#define WS_LOG_DOMAIN"Wiretap" LOG_DOMAIN_WIRETAP"Wiretap"
21
22#include "blf.h"
23
24#include <epan/dissectors/packet-socketcan.h>
25#include <epan/dissectors/packet-flexray.h>
26#include <epan/dissectors/packet-lin.h>
27#include <string.h>
28#include <errno(*__errno_location ()).h>
29#include <wsutil/value_string.h>
30#include <wiretap/wtap.h>
31#include <wiretap/wtap_opttypes.h>
32#include <wsutil/wslog.h>
33#include <wsutil/exported_pdu_tlvs.h>
34#include <wsutil/pint.h>
35#include <wsutil/report_message.h>
36#include <wsutil/strtoi.h>
37#include <wsutil/time_util.h>
38#include <wsutil/zlib_compat.h>
39#include <wsutil/pint.h>
40#include <wsutil/ws_assert.h>
41#include <libxml/tree.h>
42#include <libxml/parser.h>
43#include <libxml/xpath.h>
44#include "file_wrappers.h"
45#include "wtap_module.h"
46
47static const uint8_t blf_magic[] = { 'L', 'O', 'G', 'G' };
48static const uint8_t blf_obj_magic[] = { 'L', 'O', 'B', 'J' };
49
50static const value_string blf_application_names[] = {
51 { 0, "Unknown" },
52 { 1, "Vector CANalyzer" },
53 { 2, "Vector CANoe" },
54 { 3, "Vector CANstress" },
55 { 4, "Vector CANlog" },
56 { 5, "Vector CANape" },
57 { 6, "Vector CANcaseXL log" },
58 { 7, "Vector Logger Configurator" },
59 { 200, "Porsche Logger" },
60 { 201, "CAETEC Logger" },
61 { 202, "Vector Network Simulator" },
62 { 203, "IPETRONIK logger" },
63 { 204, "RT PK" },
64 { 205, "PikeTec" },
65 { 206, "Sparks" },
66 { 0, NULL((void*)0) }
67};
68
69static int blf_file_type_subtype = -1;
70
71void register_blf(void);
72
73static bool_Bool blf_read(wtap *wth, wtap_rec *rec, int *err, char **err_info, int64_t *data_offset);
74static bool_Bool blf_seek_read(wtap *wth, int64_t seek_off, wtap_rec* rec, int *err, char **err_info);
75static void blf_close(wtap *wth);
76
77/*
78 * The virtual buffer looks like this (skips all headers):
79 * uncompressed log container data
80 * uncompressed log container data
81 * ...
82 *
83 * The "real" positions, length, etc. reference this layout and not the file.
84 */
85typedef struct blf_log_container {
86 int64_t infile_start_pos; /* start position of log container in file */
87 uint64_t infile_length; /* length of log container in file */
88 uint64_t infile_data_start; /* start position of data in log container in file */
89
90 uint64_t real_start_pos; /* decompressed (virtual) start position including header */
91 uint64_t real_length; /* decompressed length */
92
93 uint16_t compression_method; /* 0: uncompressed, 2: zlib */
94
95 unsigned char *real_data; /* cache for decompressed data */
96} blf_log_container_t;
97
98typedef struct blf_data {
99 int64_t start_of_last_obj;
100 int64_t current_real_seek_pos;
101 uint64_t start_offset_ns;
102 uint64_t end_offset_ns;
103
104 GArray *log_containers;
105
106 GHashTable *channel_to_iface_ht;
107 GHashTable *channel_to_name_ht;
108 uint32_t next_interface_id;
109} blf_t;
110
111typedef struct blf_params {
112 wtap *wth;
113 wtap_rec *rec;
114 FILE_T fh;
115 bool_Bool random;
116 bool_Bool pipe;
117
118 blf_t *blf_data;
119} blf_params_t;
120
121typedef struct blf_channel_to_iface_entry {
122 int pkt_encap;
123 uint16_t channel;
124 uint16_t hwchannel;
125 uint32_t interface_id;
126} blf_channel_to_iface_entry_t;
127
128typedef struct blf_metadata_info {
129 size_t metadata_cont;
130 size_t payload_start;
131 bool_Bool valid;
132} blf_metadata_info_t;
133
134static void
135blf_free_key(void *key) {
136 g_free(key)(__builtin_object_size ((key), 0) != ((size_t) - 1)) ? g_free_sized
(key, __builtin_object_size ((key), 0)) : (g_free) (key)
;
137}
138
139static void
140blf_free_channel_to_iface_entry(void *data) {
141 g_free(data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
142}
143
144static void
145blf_free_channel_to_name_entry(void *data) {
146 g_free(data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
147}
148
149static int64_t
150blf_calc_key_value(int pkt_encap, uint16_t channel, uint16_t hwchannel) {
151 return (int64_t)(((uint64_t)pkt_encap << 32) | ((uint64_t)hwchannel << 16) | (uint64_t)channel);
152}
153
154static time_t
155blf_date_to_sec(const blf_date_t *date) {
156 struct tm timestamp;
157 timestamp.tm_year = (date->year > 1970) ? date->year - 1900 : 70;
158 timestamp.tm_mon = date->month - 1;
159 timestamp.tm_mday = date->day;
160 timestamp.tm_hour = date->hour;
161 timestamp.tm_min = date->mins;
162 timestamp.tm_sec = date->sec;
163 timestamp.tm_isdst = -1;
164
165 return mktime(&timestamp);
166}
167
168/** Return the Epoch ns time of the blf date
169 *
170 * This is not intended to fully validate the date and time,
171 * but just to check if the values are plausible.
172 */
173static uint64_t
174blf_data_to_ns(const blf_date_t *date) {
175 if (date != NULL((void*)0) &&
176 (date->year < 2484) && /* max_uint64 / ns_per_year */
177 (date->month >= 1 && date->month <= 12) &&
178 (date->day >= 1 && date->day <= 31) &&
179 (date->hour <= 23) && (date->mins <= 59) &&
180 (date->sec <= 61) /* Apparently can be up to 61 on certain systems */
181 ) { /* Not checking if milliseconds are actually less than 1000 */
182 time_t offset_s = blf_date_to_sec(date);
183 if (offset_s >= 0) {
184 return (1000 * 1000 * (date->ms + (1000 * (uint64_t)offset_s)));
185 }
186 }
187
188 return 0;
189}
190
191static void add_interface_name(wtap_block_t int_data, int pkt_encap, uint16_t channel, uint16_t hwchannel, char *name) {
192 if (name != NULL((void*)0)) {
193 wtap_block_add_string_option_format(int_data, OPT_IDB_NAME2, "%s", name);
194 } else {
195 switch (pkt_encap) {
196 case WTAP_ENCAP_ETHERNET1:
197 /* we use UINT16_MAX to encode no hwchannel */
198 if (hwchannel == UINT16_MAX(65535)) {
199 wtap_block_add_string_option_format(int_data, OPT_IDB_NAME2, "ETH-%u", channel);
200 } else {
201 wtap_block_add_string_option_format(int_data, OPT_IDB_NAME2, "ETH-%u-%u", channel, hwchannel);
202 }
203 break;
204 case WTAP_ENCAP_IEEE_802_1120:
205 wtap_block_add_string_option_format(int_data, OPT_IDB_NAME2, "WLAN-%u", channel);
206 break;
207 case WTAP_ENCAP_FLEXRAY106:
208 wtap_block_add_string_option_format(int_data, OPT_IDB_NAME2, "FR-%u", channel);
209 break;
210 case WTAP_ENCAP_LIN107:
211 wtap_block_add_string_option_format(int_data, OPT_IDB_NAME2, "LIN-%u", channel);
212 break;
213 case WTAP_ENCAP_SOCKETCAN125:
214 wtap_block_add_string_option_format(int_data, OPT_IDB_NAME2, "CAN-%u", channel);
215 break;
216 default:
217 wtap_block_add_string_option_format(int_data, OPT_IDB_NAME2, "ENCAP_%d-%u", pkt_encap, channel);
218 }
219 }
220
221 /* Add a defined description format to recover the original channel/hwchannel mapping, when we ever convert back to BLF */
222 /* Changing the names might break the BLF writing! */
223 switch (pkt_encap) {
224 case WTAP_ENCAP_ETHERNET1:
225 wtap_block_add_string_option_format(int_data, OPT_IDB_DESCRIPTION3, "BLF-ETH-0x%04x-0x%04x", channel, hwchannel);
226 break;
227 case WTAP_ENCAP_IEEE_802_1120:
228 wtap_block_add_string_option_format(int_data, OPT_IDB_DESCRIPTION3, "BLF-WLAN-0x%04x", channel);
229 break;
230 case WTAP_ENCAP_FLEXRAY106:
231 wtap_block_add_string_option_format(int_data, OPT_IDB_DESCRIPTION3, "BLF-FR-0x%04x", channel);
232 break;
233 case WTAP_ENCAP_LIN107:
234 wtap_block_add_string_option_format(int_data, OPT_IDB_DESCRIPTION3, "BLF-LIN-0x%04x", channel);
235 break;
236 case WTAP_ENCAP_SOCKETCAN125:
237 wtap_block_add_string_option_format(int_data, OPT_IDB_DESCRIPTION3, "BLF-CAN-0x%04x", channel);
238 break;
239 default:
240 wtap_block_add_string_option_format(int_data, OPT_IDB_DESCRIPTION3, "BLF-ENCAP_%d-0x%04x-0x%04x", pkt_encap, channel, hwchannel);
241 }
242}
243
244static uint32_t
245blf_add_interface(blf_params_t *params, int pkt_encap, uint32_t channel, uint16_t hwchannel, char *name) {
246 wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
247 wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
248 blf_channel_to_iface_entry_t *item = NULL((void*)0);
249
250 if_descr_mand->wtap_encap = pkt_encap;
251 add_interface_name(int_data, pkt_encap, channel, hwchannel, name);
252 /*
253 * The time stamp resolution in these files can be per-record;
254 * the maximum resolution is nanoseconds, so we specify that
255 * as the interface's resolution.
256 *
257 * We set the resolution for a record on a per-record basis,
258 * based on what the record specifies.
259 */
260 if_descr_mand->time_units_per_second = 1000 * 1000 * 1000;
261 if_descr_mand->tsprecision = WTAP_TSPREC_NSEC9;
262 wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL9, 9);
263 if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD262144U;
264 if_descr_mand->num_stat_entries = 0;
265 if_descr_mand->interface_statistics = NULL((void*)0);
266 wtap_add_idb(params->wth, int_data);
267
268 if (params->wth->file_encap == WTAP_ENCAP_NONE-2) {
269 params->wth->file_encap = if_descr_mand->wtap_encap;
270 } else {
271 if (params->wth->file_encap != if_descr_mand->wtap_encap) {
272 params->wth->file_encap = WTAP_ENCAP_PER_PACKET-1;
273 }
274 }
275
276 int64_t *key = NULL((void*)0);
277 key = g_new(int64_t, 1)((int64_t *) g_malloc_n ((1), sizeof (int64_t)));
278 *key = blf_calc_key_value(pkt_encap, channel, hwchannel);
279
280 item = g_new(blf_channel_to_iface_entry_t, 1)((blf_channel_to_iface_entry_t *) g_malloc_n ((1), sizeof (blf_channel_to_iface_entry_t
)))
;
281 item->channel = channel;
282 item->hwchannel = hwchannel;
283 item->pkt_encap = pkt_encap;
284 item->interface_id = params->blf_data->next_interface_id++;
285 g_hash_table_insert(params->blf_data->channel_to_iface_ht, key, item);
286
287 return item->interface_id;
288}
289
290/** This is used to save the interface name without creating it.
291 *
292 * This approach allows up to update the name of the interface
293 * up until the first captured packet.
294 */
295static bool_Bool
296// NOLINTNEXTLINE(misc-no-recursion)
297blf_prepare_interface_name(blf_params_t* params, int pkt_encap, uint16_t channel, uint16_t hwchannel, const char* name, bool_Bool force_new_name) {
298 int64_t key = blf_calc_key_value(pkt_encap, channel, hwchannel);
299 char* old_name;
300 char* new_name;
301 char* iface_name;
302 int64_t* new_key;
303 bool_Bool ret;
304
305 if (params->blf_data->channel_to_name_ht == NULL((void*)0)) {
306 return false0;
307 }
308
309 old_name = (char *)g_hash_table_lookup(params->blf_data->channel_to_name_ht, &key);
310
311 if (old_name != NULL((void*)0) && force_new_name) {
312 if (!g_hash_table_remove(params->blf_data->channel_to_name_ht, &key)) {
313 return false0;
314 }
315
316 old_name = NULL((void*)0);
317 }
318
319 if (old_name == NULL((void*)0) && name != NULL((void*)0)) {
320 new_key = g_new(int64_t, 1)((int64_t *) g_malloc_n ((1), sizeof (int64_t)));
321 *new_key = key;
322 new_name = ws_strdup(name)wmem_strdup(((void*)0), name);
323 if (!g_hash_table_insert(params->blf_data->channel_to_name_ht, new_key, new_name)) {
324 return false0;
325 }
326 } else {
327 new_name = old_name;
328 }
329
330 if (pkt_encap == WTAP_ENCAP_ETHERNET1) {
331 /* Just for Ethernet, prepare the equivalent STATUS interface */
332 iface_name = new_name != NULL((void*)0) ? ws_strdup_printf("STATUS-%s", new_name)wmem_strdup_printf(((void*)0), "STATUS-%s", new_name) : NULL((void*)0);
333
334 // We recurse here once.
335 ret = blf_prepare_interface_name(params, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, channel, hwchannel, iface_name, force_new_name);
336 if (iface_name) {
337 g_free(iface_name)(__builtin_object_size ((iface_name), 0) != ((size_t) - 1)) ?
g_free_sized (iface_name, __builtin_object_size ((iface_name
), 0)) : (g_free) (iface_name)
;
338 }
339 if (!ret) {
340 return false0;
341 }
342 }
343
344 return true1;
345}
346
347static uint32_t
348blf_lookup_interface(blf_params_t *params, int pkt_encap, uint16_t channel, uint16_t hwchannel, char *name) {
349 int64_t key = blf_calc_key_value(pkt_encap, channel, hwchannel);
350 blf_channel_to_iface_entry_t* item;
351 char* saved_name;
352 uint32_t ret;
353
354 if (params->blf_data->channel_to_iface_ht == NULL((void*)0)) {
355 return 0;
356 }
357
358 item = (blf_channel_to_iface_entry_t *)g_hash_table_lookup(params->blf_data->channel_to_iface_ht, &key);
359
360 if (item != NULL((void*)0)) {
361 return item->interface_id;
362 } else {
363 saved_name = (char*)g_hash_table_lookup(params->blf_data->channel_to_name_ht, &key);
364
365 if (saved_name != NULL((void*)0)) {
366 ret = blf_add_interface(params, pkt_encap, channel, hwchannel, saved_name);
367 g_hash_table_remove(params->blf_data->channel_to_name_ht, &key);
368
369 return ret;
370 } else {
371 return blf_add_interface(params, pkt_encap, channel, hwchannel, name);
372 }
373 }
374}
375
376static void
377fix_endianness_blf_date(blf_date_t *date) {
378 date->year = GUINT16_FROM_LE(date->year)(((guint16) (date->year)));
379 date->month = GUINT16_FROM_LE(date->month)(((guint16) (date->month)));
380 date->dayofweek = GUINT16_FROM_LE(date->dayofweek)(((guint16) (date->dayofweek)));
381 date->day = GUINT16_FROM_LE(date->day)(((guint16) (date->day)));
382 date->hour = GUINT16_FROM_LE(date->hour)(((guint16) (date->hour)));
383 date->mins = GUINT16_FROM_LE(date->mins)(((guint16) (date->mins)));
384 date->sec = GUINT16_FROM_LE(date->sec)(((guint16) (date->sec)));
385 date->ms = GUINT16_FROM_LE(date->ms)(((guint16) (date->ms)));
386}
387
388static void
389fix_endianness_blf_fileheader(blf_fileheader_t *header) {
390 header->header_length = GUINT32_FROM_LE(header->header_length)(((guint32) (header->header_length)));
391 header->api_version = GUINT32_FROM_LE(header->api_version)(((guint32) (header->api_version)));
392 header->len_compressed = GUINT64_FROM_LE(header->len_compressed)(((guint64) (header->len_compressed)));
393 header->len_uncompressed = GUINT64_FROM_LE(header->len_uncompressed)(((guint64) (header->len_uncompressed)));
394 header->obj_count = GUINT32_FROM_LE(header->obj_count)(((guint32) (header->obj_count)));
395 header->application_build = GUINT32_FROM_LE(header->application_build)(((guint32) (header->application_build)));
396 fix_endianness_blf_date(&(header->start_date));
397 fix_endianness_blf_date(&(header->end_date));
398 header->restore_point_offset = GUINT32_FROM_LE(header->restore_point_offset)(((guint32) (header->restore_point_offset)));
399}
400
401static void
402fix_endianness_blf_blockheader(blf_blockheader_t *header) {
403 header->header_length = GUINT16_FROM_LE(header->header_length)(((guint16) (header->header_length)));
404 header->header_type = GUINT16_FROM_LE(header->header_type)(((guint16) (header->header_type)));
405 header->object_length = GUINT32_FROM_LE(header->object_length)(((guint32) (header->object_length)));
406 header->object_type = GUINT32_FROM_LE(header->object_type)(((guint32) (header->object_type)));
407}
408
409static void
410fix_endianness_blf_logcontainerheader(blf_logcontainerheader_t *header) {
411 header->compression_method = GUINT16_FROM_LE(header->compression_method)(((guint16) (header->compression_method)));
412 header->res1 = GUINT16_FROM_LE(header->res1)(((guint16) (header->res1)));
413 header->res2 = GUINT32_FROM_LE(header->res2)(((guint32) (header->res2)));
414 header->uncompressed_size = GUINT32_FROM_LE(header->uncompressed_size)(((guint32) (header->uncompressed_size)));
415 header->res4 = GUINT32_FROM_LE(header->res4)(((guint32) (header->res4)));
416}
417
418static void
419fix_endianness_blf_logobjectheader(blf_logobjectheader_t *header) {
420 header->flags = GUINT32_FROM_LE(header->flags)(((guint32) (header->flags)));
421 header->client_index = GUINT16_FROM_LE(header->client_index)(((guint16) (header->client_index)));
422 header->object_version = GUINT16_FROM_LE(header->object_version)(((guint16) (header->object_version)));
423 header->object_timestamp = GUINT64_FROM_LE(header->object_timestamp)(((guint64) (header->object_timestamp)));
424}
425
426static void
427fix_endianness_blf_logobjectheader2(blf_logobjectheader2_t *header) {
428 header->flags = GUINT32_FROM_LE(header->flags)(((guint32) (header->flags)));
429 header->object_version = GUINT16_FROM_LE(header->object_version)(((guint16) (header->object_version)));
430 header->object_timestamp = GUINT64_FROM_LE(header->object_timestamp)(((guint64) (header->object_timestamp)));
431 header->original_timestamp = GUINT64_FROM_LE(header->object_timestamp)(((guint64) (header->object_timestamp)));
432}
433
434static void
435fix_endianness_blf_logobjectheader3(blf_logobjectheader3_t *header) {
436 header->flags = GUINT32_FROM_LE(header->flags)(((guint32) (header->flags)));
437 header->static_size = GUINT16_FROM_LE(header->static_size)(((guint16) (header->static_size)));
438 header->object_version = GUINT16_FROM_LE(header->object_version)(((guint16) (header->object_version)));
439 header->object_timestamp = GUINT64_FROM_LE(header->object_timestamp)(((guint64) (header->object_timestamp)));
440}
441
442static void
443fix_endianness_blf_ethernetframeheader(blf_ethernetframeheader_t *header) {
444 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
445 header->direction = GUINT16_FROM_LE(header->direction)(((guint16) (header->direction)));
446 header->ethtype = GUINT16_FROM_LE(header->ethtype)(((guint16) (header->ethtype)));
447 header->tpid = GUINT16_FROM_LE(header->tpid)(((guint16) (header->tpid)));
448 header->tci = GUINT16_FROM_LE(header->tci)(((guint16) (header->tci)));
449 header->payloadlength = GUINT16_FROM_LE(header->payloadlength)(((guint16) (header->payloadlength)));
450}
451
452static void
453fix_endianness_blf_ethernetframeheader_ex(blf_ethernetframeheader_ex_t *header) {
454 header->struct_length = GUINT16_FROM_LE(header->struct_length)(((guint16) (header->struct_length)));
455 header->flags = GUINT16_FROM_LE(header->flags)(((guint16) (header->flags)));
456 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
457 header->hw_channel = GUINT16_FROM_LE(header->hw_channel)(((guint16) (header->hw_channel)));
458 header->frame_duration = GUINT64_FROM_LE(header->frame_duration)(((guint64) (header->frame_duration)));
459 header->frame_checksum = GUINT32_FROM_LE(header->frame_checksum)(((guint32) (header->frame_checksum)));
460 header->direction = GUINT16_FROM_LE(header->direction)(((guint16) (header->direction)));
461 header->frame_length = GUINT16_FROM_LE(header->frame_length)(((guint16) (header->frame_length)));
462 header->frame_handle = GUINT32_FROM_LE(header->frame_handle)(((guint32) (header->frame_handle)));
463 header->error = GUINT32_FROM_LE(header->error)(((guint32) (header->error)));
464}
465
466static void
467fix_endianness_blf_ethernet_rxerror(blf_ethernet_rxerror_t* header) {
468 header->struct_length = GUINT16_FROM_LE(header->struct_length)(((guint16) (header->struct_length)));
469 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
470 header->direction = GUINT16_FROM_LE(header->direction)(((guint16) (header->direction)));
471 header->hw_channel = GUINT16_FROM_LE(header->hw_channel)(((guint16) (header->hw_channel)));
472 header->frame_checksum = GUINT32_FROM_LE(header->frame_checksum)(((guint32) (header->frame_checksum)));
473 header->frame_length = GUINT16_FROM_LE(header->frame_length)(((guint16) (header->frame_length)));
474 header->error = GUINT32_FROM_LE(header->error)(((guint32) (header->error)));
475}
476
477static void
478fix_endianness_blf_wlanframeheader(blf_wlanframeheader_t* header) {
479 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
480 header->flags = GUINT16_FROM_LE(header->flags)(((guint16) (header->flags)));
481 header->signal_strength = GUINT16_FROM_LE(header->signal_strength)(((guint16) (header->signal_strength)));
482 header->signal_quality = GUINT16_FROM_LE(header->signal_quality)(((guint16) (header->signal_quality)));
483 header->frame_length = GUINT16_FROM_LE(header->frame_length)(((guint16) (header->frame_length)));
484}
485
486static void
487fix_endianness_blf_canmessage(blf_canmessage_t *header) {
488 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
489 header->id = GUINT32_FROM_LE(header->id)(((guint32) (header->id)));
490}
491
492static void
493fix_endianness_blf_canmessage2_trailer(blf_canmessage2_trailer_t *header) {
494 header->frameLength_in_ns = GUINT32_FROM_LE(header->frameLength_in_ns)(((guint32) (header->frameLength_in_ns)));
495 header->reserved2 = GUINT16_FROM_LE(header->reserved1)(((guint16) (header->reserved1)));
496}
497
498static void
499fix_endianness_blf_canfdmessage(blf_canfdmessage_t *header) {
500 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
501 header->id = GUINT32_FROM_LE(header->id)(((guint32) (header->id)));
502 header->frameLength_in_ns = GUINT32_FROM_LE(header->frameLength_in_ns)(((guint32) (header->frameLength_in_ns)));
503 header->reservedCanFdMessage2 = GUINT32_FROM_LE(header->reservedCanFdMessage2)(((guint32) (header->reservedCanFdMessage2)));
504}
505
506static void
507fix_endianness_blf_canfdmessage64(blf_canfdmessage64_t *header) {
508 header->id = GUINT32_FROM_LE(header->id)(((guint32) (header->id)));
509 header->frameLength_in_ns = GUINT32_FROM_LE(header->frameLength_in_ns)(((guint32) (header->frameLength_in_ns)));
510 header->flags = GUINT32_FROM_LE(header->flags)(((guint32) (header->flags)));
511 header->btrCfgArb = GUINT32_FROM_LE(header->btrCfgArb)(((guint32) (header->btrCfgArb)));
512 header->btrCfgData = GUINT32_FROM_LE(header->btrCfgData)(((guint32) (header->btrCfgData)));
513 header->timeOffsetBrsNs = GUINT32_FROM_LE(header->timeOffsetBrsNs)(((guint32) (header->timeOffsetBrsNs)));
514 header->timeOffsetCrcDelNs = GUINT32_FROM_LE(header->timeOffsetCrcDelNs)(((guint32) (header->timeOffsetCrcDelNs)));
515 header->bitCount = GUINT16_FROM_LE(header->bitCount)(((guint16) (header->bitCount)));
516 header->crc = GUINT32_FROM_LE(header->crc)(((guint32) (header->crc)));
517}
518
519static void
520fix_endianness_blf_canerror(blf_canerror_t *header) {
521 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
522 header->length = GUINT16_FROM_LE(header->length)(((guint16) (header->length)));
523}
524
525static void
526fix_endianness_blf_canerrorext(blf_canerrorext_t *header) {
527 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
528 header->length = GUINT16_FROM_LE(header->length)(((guint16) (header->length)));
529 header->flags = GUINT32_FROM_LE(header->flags)(((guint32) (header->flags)));
530 header->frameLength_in_ns = GUINT32_FROM_LE(header->frameLength_in_ns)(((guint32) (header->frameLength_in_ns)));
531 header->id = GUINT32_FROM_LE(header->id)(((guint32) (header->id)));
532 header->errorCodeExt = GUINT16_FROM_LE(header->errorCodeExt)(((guint16) (header->errorCodeExt)));
533}
534
535static void
536fix_endianness_blf_canfderror64(blf_canfderror64_t *header) {
537 header->flags = GUINT16_FROM_LE(header->flags)(((guint16) (header->flags)));
538 header->errorCodeExt = GUINT16_FROM_LE(header->errorCodeExt)(((guint16) (header->errorCodeExt)));
539 header->extFlags = GUINT16_FROM_LE(header->extFlags)(((guint16) (header->extFlags)));
540 header->id = GUINT32_FROM_LE(header->id)(((guint32) (header->id)));
541 header->frameLength_in_ns = GUINT32_FROM_LE(header->frameLength_in_ns)(((guint32) (header->frameLength_in_ns)));
542 header->btrCfgArb = GUINT32_FROM_LE(header->btrCfgArb)(((guint32) (header->btrCfgArb)));
543 header->btrCfgData = GUINT32_FROM_LE(header->btrCfgData)(((guint32) (header->btrCfgData)));
544 header->timeOffsetBrsNs = GUINT32_FROM_LE(header->timeOffsetBrsNs)(((guint32) (header->timeOffsetBrsNs)));
545 header->timeOffsetCrcDelNs = GUINT32_FROM_LE(header->timeOffsetCrcDelNs)(((guint32) (header->timeOffsetCrcDelNs)));
546 header->crc = GUINT32_FROM_LE(header->crc)(((guint32) (header->crc)));
547 header->errorPosition = GUINT16_FROM_LE(header->errorPosition)(((guint16) (header->errorPosition)));
548}
549
550static void
551fix_endianness_blf_canxlchannelframe(blf_canxlchannelframe_t *header) {
552 header->frameLength_in_ns = GUINT32_FROM_LE(header->frameLength_in_ns)(((guint32) (header->frameLength_in_ns)));
553 header->bitCount = GUINT16_FROM_LE(header->bitCount)(((guint16) (header->bitCount)));
554 header->res2 = GUINT16_FROM_LE(header->res2)(((guint16) (header->res2)));
555 header->frameIdentifier = GUINT32_FROM_LE(header->frameIdentifier)(((guint32) (header->frameIdentifier)));
556 header->dlc = GUINT16_FROM_LE(header->dlc)(((guint16) (header->dlc)));
557 header->dataLength = GUINT16_FROM_LE(header->dataLength)(((guint16) (header->dataLength)));
558 header->stuffBitCount = GUINT16_FROM_LE(header->stuffBitCount)(((guint16) (header->stuffBitCount)));
559 header->prefaceCRC = GUINT16_FROM_LE(header->prefaceCRC)(((guint16) (header->prefaceCRC)));
560 header->acceptanceField = GUINT32_FROM_LE(header->acceptanceField)(((guint32) (header->acceptanceField)));
561 header->res5 = GUINT16_FROM_LE(header->res5)(((guint16) (header->res5)));
562 header->crc = GUINT32_FROM_LE(header->crc)(((guint32) (header->crc)));
563 header->timeOffsetBrsNs = GUINT32_FROM_LE(header->timeOffsetBrsNs)(((guint32) (header->timeOffsetBrsNs)));
564 header->timeOffsetCrcDelNs = GUINT32_FROM_LE(header->timeOffsetCrcDelNs)(((guint32) (header->timeOffsetCrcDelNs)));
565 header->flags = GUINT32_FROM_LE(header->flags)(((guint32) (header->flags)));
566 header->reserved = GUINT32_FROM_LE(header->reserved)(((guint32) (header->reserved)));
567 header->arbitrationDataBitTimingConfig = GUINT64_FROM_LE(header->arbitrationDataBitTimingConfig)(((guint64) (header->arbitrationDataBitTimingConfig)));
568 header->arbitrationDataHwChannelSettings = GUINT64_FROM_LE(header->arbitrationDataHwChannelSettings)(((guint64) (header->arbitrationDataHwChannelSettings)));
569 header->fdPhaseBitTimingConfig = GUINT64_FROM_LE(header->fdPhaseBitTimingConfig)(((guint64) (header->fdPhaseBitTimingConfig)));
570 header->fdPhaseHwChannelSettings = GUINT64_FROM_LE(header->fdPhaseHwChannelSettings)(((guint64) (header->fdPhaseHwChannelSettings)));
571 header->xlPhaseBitTimingConfig = GUINT64_FROM_LE(header->xlPhaseBitTimingConfig)(((guint64) (header->xlPhaseBitTimingConfig)));
572 header->xlPhaseHwChannelSettings = GUINT64_FROM_LE(header->xlPhaseHwChannelSettings)(((guint64) (header->xlPhaseHwChannelSettings)));
573}
574
575
576static void
577fix_endianness_blf_flexraydata(blf_flexraydata_t *header) {
578 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
579 header->messageId = GUINT16_FROM_LE(header->messageId)(((guint16) (header->messageId)));
580 header->crc = GUINT16_FROM_LE(header->crc)(((guint16) (header->crc)));
581 header->reservedFlexRayData2 = GUINT16_FROM_LE(header->reservedFlexRayData2)(((guint16) (header->reservedFlexRayData2)));
582}
583
584static void
585fix_endianness_blf_flexraymessage(blf_flexraymessage_t *header) {
586 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
587 header->fpgaTick = GUINT32_FROM_LE(header->fpgaTick)(((guint32) (header->fpgaTick)));
588 header->fpgaTickOverflow = GUINT32_FROM_LE(header->fpgaTickOverflow)(((guint32) (header->fpgaTickOverflow)));
589 header->clientIndexFlexRayV6Message = GUINT32_FROM_LE(header->clientIndexFlexRayV6Message)(((guint32) (header->clientIndexFlexRayV6Message)));
590 header->clusterTime = GUINT32_FROM_LE(header->clusterTime)(((guint32) (header->clusterTime)));
591 header->frameId = GUINT16_FROM_LE(header->frameId)(((guint16) (header->frameId)));
592 header->headerCrc = GUINT16_FROM_LE(header->headerCrc)(((guint16) (header->headerCrc)));
593 header->frameState = GUINT16_FROM_LE(header->frameState)(((guint16) (header->frameState)));
594 header->reservedFlexRayV6Message2 = GUINT16_FROM_LE(header->reservedFlexRayV6Message2)(((guint16) (header->reservedFlexRayV6Message2)));
595}
596
597static void
598fix_endianness_blf_flexrayrcvmessage(blf_flexrayrcvmessage_t *header) {
599 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
600 header->version = GUINT16_FROM_LE(header->version)(((guint16) (header->version)));
601 header->channelMask = GUINT16_FROM_LE(header->channelMask)(((guint16) (header->channelMask)));
602 header->dir = GUINT16_FROM_LE(header->dir)(((guint16) (header->dir)));
603 header->clientIndex = GUINT32_FROM_LE(header->clientIndex)(((guint32) (header->clientIndex)));
604 header->clusterNo = GUINT32_FROM_LE(header->clusterNo)(((guint32) (header->clusterNo)));
605 header->frameId = GUINT16_FROM_LE(header->frameId)(((guint16) (header->frameId)));
606 header->headerCrc1 = GUINT16_FROM_LE(header->headerCrc1)(((guint16) (header->headerCrc1)));
607 header->headerCrc2 = GUINT16_FROM_LE(header->headerCrc2)(((guint16) (header->headerCrc2)));
608 header->payloadLength = GUINT16_FROM_LE(header->payloadLength)(((guint16) (header->payloadLength)));
609 header->payloadLengthValid = GUINT16_FROM_LE(header->payloadLengthValid)(((guint16) (header->payloadLengthValid)));
610 header->cycle = GUINT16_FROM_LE(header->cycle)(((guint16) (header->cycle)));
611 header->tag = GUINT32_FROM_LE(header->tag)(((guint32) (header->tag)));
612 header->data = GUINT32_FROM_LE(header->data)(((guint32) (header->data)));
613 header->frameFlags = GUINT32_FROM_LE(header->frameFlags)(((guint32) (header->frameFlags)));
614 header->appParameter = GUINT32_FROM_LE(header->appParameter)(((guint32) (header->appParameter)));
615/* this would be extra for ext format:
616 header->frameCRC = GUINT32_FROM_LE(header->frameCRC);
617 header->frameLengthInNs = GUINT32_FROM_LE(header->frameLengthInNs);
618 header->frameId1 = GUINT16_FROM_LE(header->frameId1);
619 header->pduOffset = GUINT16_FROM_LE(header->pduOffset);
620 header->blfLogMask = GUINT16_FROM_LE(header->blfLogMask);
621*/
622}
623
624static void
625fix_endianness_blf_linmessage(blf_linmessage_t* message) {
626 message->channel = GUINT16_FROM_LE(message->channel)(((guint16) (message->channel)));
627 message->crc = GUINT16_FROM_LE(message->crc)(((guint16) (message->crc)));
628/* skip the optional part
629 message->res2 = GUINT32_FROM_LE(message->res2);
630*/
631}
632
633static void
634fix_endianness_blf_linbusevent(blf_linbusevent_t* linbusevent) {
635 linbusevent->sof = GUINT64_FROM_LE(linbusevent->sof)(((guint64) (linbusevent->sof)));
636 linbusevent->eventBaudrate = GUINT32_FROM_LE(linbusevent->eventBaudrate)(((guint32) (linbusevent->eventBaudrate)));
637 linbusevent->channel = GUINT16_FROM_LE(linbusevent->channel)(((guint16) (linbusevent->channel)));
638}
639
640static void
641fix_endianness_blf_linsynchfieldevent(blf_linsynchfieldevent_t* linsynchfieldevent) {
642 fix_endianness_blf_linbusevent(&linsynchfieldevent->linBusEvent);
643 linsynchfieldevent->synchBreakLength = GUINT64_FROM_LE(linsynchfieldevent->synchBreakLength)(((guint64) (linsynchfieldevent->synchBreakLength)));
644 linsynchfieldevent->synchDelLength = GUINT64_FROM_LE(linsynchfieldevent->synchDelLength)(((guint64) (linsynchfieldevent->synchDelLength)));
645}
646
647static void
648fix_endianness_blf_linmessagedescriptor(blf_linmessagedescriptor_t* linmessagedescriptor) {
649 fix_endianness_blf_linsynchfieldevent(&linmessagedescriptor->linSynchFieldEvent);
650 linmessagedescriptor->supplierId = GUINT16_FROM_LE(linmessagedescriptor->supplierId)(((guint16) (linmessagedescriptor->supplierId)));
651 linmessagedescriptor->messageId = GUINT16_FROM_LE(linmessagedescriptor->messageId)(((guint16) (linmessagedescriptor->messageId)));
652}
653
654static void
655fix_endianness_blf_lindatabytetimestampevent(blf_lindatabytetimestampevent_t* lindatabytetimestampevent) {
656 int i;
657 fix_endianness_blf_linmessagedescriptor(&lindatabytetimestampevent->linMessageDescriptor);
658 for (i = 0; i < 9; i++) {
659 lindatabytetimestampevent->databyteTimestamps[i] = GUINT64_FROM_LE(lindatabytetimestampevent->databyteTimestamps[i])(((guint64) (lindatabytetimestampevent->databyteTimestamps
[i])))
;
660 }
661}
662
663static void
664fix_endianness_blf_linmessage2(blf_linmessage2_t* message) {
665 fix_endianness_blf_lindatabytetimestampevent(&message->linDataByteTimestampEvent);
666 message->crc = GUINT16_FROM_LE(message->crc)(((guint16) (message->crc)));
667/* skip the optional part
668 message->respBaudrate = GUINT32_FROM_LE(message->respBaudrate);
669 message->exactHeaderBaudrate = GUINT64_FROM_LE(message->exactHeaderBaudrate);
670 message->earlyStopBitOffset = GUINT32_FROM_LE(message->earlyStopBitOffset);
671 message->earlyStopBitOffsetResponse = GUINT32_FROM_LE(message->earlyStopBitOffsetResponse);
672*/
673}
674
675static void
676fix_endianness_blf_lincrcerror2(blf_lincrcerror2_t* message) {
677 fix_endianness_blf_lindatabytetimestampevent(&message->linDataByteTimestampEvent);
678 message->crc = GUINT16_FROM_LE(message->crc)(((guint16) (message->crc)));
679/* skip the optional part
680 message->respBaudrate = GUINT32_FROM_LE(message->respBaudrate);
681 message->exactHeaderBaudrate = GUINT64_FROM_LE(message->exactHeaderBaudrate);
682 message->earlyStopBitOffset = GUINT32_FROM_LE(message->earlyStopBitOffset);
683 message->earlyStopBitOffsetResponse = GUINT32_FROM_LE(message->earlyStopBitOffsetResponse);
684*/
685}
686
687static void
688fix_endianness_blf_linrcverror2(blf_linrcverror2_t* message) {
689 fix_endianness_blf_lindatabytetimestampevent(&message->linDataByteTimestampEvent);
690/* skip the optional part
691 message->respBaudrate = GUINT32_FROM_LE(message->respBaudrate);
692 message->exactHeaderBaudrate = GUINT64_FROM_LE(message->exactHeaderBaudrate);
693 message->earlyStopBitOffset = GUINT32_FROM_LE(message->earlyStopBitOffset);
694 message->earlyStopBitOffsetResponse = GUINT32_FROM_LE(message->earlyStopBitOffsetResponse);
695*/
696}
697
698static void
699fix_endianness_blf_linsenderror2(blf_linsenderror2_t* message) {
700 fix_endianness_blf_linmessagedescriptor(&message->linMessageDescriptor);
701 message->eoh = GUINT64_FROM_LE(message->eoh)(((guint64) (message->eoh)));
702/* skip the optional part
703 message->exactHeaderBaudrate = GUINT64_FROM_LE(message->exactHeaderBaudrate);
704 message->earlyStopBitOffset = GUINT32_FROM_LE(message->earlyStopBitOffset);
705*/
706}
707
708static void
709fix_endianness_blf_linwakeupevent2(blf_linwakeupevent2_t* message) {
710 fix_endianness_blf_linbusevent(&message->linBusEvent);
711}
712
713static void
714fix_endianness_blf_apptext_header(blf_apptext_t *header) {
715 header->source = GUINT32_FROM_LE(header->source)(((guint32) (header->source)));
716 header->reservedAppText1 = GUINT32_FROM_LE(header->reservedAppText1)(((guint32) (header->reservedAppText1)));
717 header->textLength = GUINT32_FROM_LE(header->textLength)(((guint32) (header->textLength)));
718 header->reservedAppText2 = GUINT32_FROM_LE(header->reservedAppText2)(((guint32) (header->reservedAppText2)));
719}
720
721static void
722fix_endianness_blf_ethernet_status_header(blf_ethernet_status_t* header) {
723 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
724 header->flags = GUINT16_FROM_LE(header->flags)(((guint16) (header->flags)));
725 /*uint8_t linkStatus;*/
726 /*uint8_t ethernetPhy;*/
727 /*uint8_t duplex;*/
728 /*uint8_t mdi;*/
729 /*uint8_t connector;*/
730 /*uint8_t clockMode;*/
731 /*uint8_t pairs;*/
732 /*uint8_t hardwareChannel;*/
733 header->bitrate = GUINT32_FROM_LE(header->bitrate)(((guint32) (header->bitrate)));
734}
735
736static void
737fix_endianness_blf_ethernet_phystate_header(blf_ethernet_phystate_t* header) {
738 header->channel = GUINT16_FROM_LE(header->channel)(((guint16) (header->channel)));
739 header->flags = GUINT16_FROM_LE(header->flags)(((guint16) (header->flags)));
740}
741
742static void
743blf_init_logcontainer(blf_log_container_t *tmp) {
744 tmp->infile_start_pos = 0;
745 tmp->infile_length = 0;
746 tmp->infile_data_start = 0;
747 tmp->real_start_pos = 0;
748 tmp->real_length = 0;
749 tmp->real_data = NULL((void*)0);
750 tmp->compression_method = 0;
751}
752
753int
754blf_logcontainers_cmp(const void *a, const void *b) {
755 const blf_log_container_t* container_a = (blf_log_container_t*)a;
756 const blf_log_container_t* container_b = (blf_log_container_t*)b;
757
758 if (container_a->real_start_pos < container_b->real_start_pos) {
759 return -1;
760 } else if (container_a->real_start_pos > container_b->real_start_pos) {
761 return 1;
762 } else {
763 return 0;
764 }
765}
766
767int
768blf_logcontainers_search(const void *a, const void *b) {
769 const blf_log_container_t* container_a = (blf_log_container_t*)a;
770 uint64_t pos = *(uint64_t*)b;
771
772 if (container_a->real_start_pos > pos) {
773 return 1;
774 } else if (pos >= container_a->real_start_pos + container_a->real_length) {
775 return -1;
776 } else {
777 return 0;
778 }
779}
780
781#ifdef USE_ZLIB_OR_ZLIBNG
782
783static uint8_t*
784blf_decompress_zlib(uint8_t *compressed_data, unsigned compressed_len, uint64_t decompressed_len, int *err, char **err_info)
785{
786 /* decompressed_len is just read from packet data, and could be bogus.
787 * It's stored in real_length as a 64-bit integer, but appears to
788 * be read from packet data as a 32-bit quantity only. In any case,
789 * we only allocate a 32-bit chunk at a time, and zlib/zlib-ng only
790 * allow avail_out to be a 32-bit unsigned integer. */
791 uint32_t bufsize;
792
793 /* z_stream->total_out is an unsigned long in Zlib, which is always
794 * 32-bits on Windows (LLP). In Zlib-ng it's a size_t, which is 32-bits
795 * on 32-bit platforms. */
796 uint64_t total_out = 0;
797
798 if (decompressed_len == 0 || compressed_len == 0) {
799 *err = WTAP_ERR_BAD_FILE-13;
800 *err_info = ws_strdup("blf: compressed or decompressed container has 0 length")wmem_strdup(((void*)0), "blf: compressed or decompressed container has 0 length"
)
;
801 return NULL((void*)0);
802 }
803
804 /* Typical compression ratios are between 2:1-5:1; the theoretical max
805 * is somewhat above 1030:1; depending on what's being compressed, that
806 * could actually be legitimate (sometimes there are long runs of zeros),
807 * but we might want to just refuse past a certain point. Since the
808 * decompressed_len in reality seems to be 32-bit, that imposes a limit. */
809 uint64_t ratio = decompressed_len / compressed_len;
810 if (ratio > 1032) {
811 /* This is just impossible, so go ahead and stop now. */
812 *err = WTAP_ERR_BAD_FILE-13;
813 *err_info = ws_strdup_printf("blf: uncompressed data has wrong length (%" PRIu64 " with a compressed size of %u is a compression ratio of %" PRIu64 ", greater than the theoretical max of 1032)", decompressed_len, compressed_len, ratio)wmem_strdup_printf(((void*)0), "blf: uncompressed data has wrong length (%"
"l" "u" " with a compressed size of %u is a compression ratio of %"
"l" "u" ", greater than the theoretical max of 1032)", decompressed_len
, compressed_len, ratio)
;
814 return NULL((void*)0);
815 } else if (ratio > 5) {
816 if (ckd_mul(&bufsize, compressed_len, 5)__builtin_mul_overflow((compressed_len), (5), (&bufsize))) {
817 bufsize = INT32_MAX(2147483647);
818 }
819 } else {
820 bufsize = (unsigned)MIN(decompressed_len, INT32_MAX)(((decompressed_len) < ((2147483647))) ? (decompressed_len
) : ((2147483647)))
;
821 }
822
823 unsigned char *buf = g_try_malloc(bufsize);
824 if (buf == NULL((void*)0)) {
825 *err = WTAP_ERR_INTERNAL-21;
826 *err_info = ws_strdup("blf: cannot allocate memory")wmem_strdup(((void*)0), "blf: cannot allocate memory");
827 return NULL((void*)0);
828 }
829 zlib_stream infstream = {0};
830
831 infstream.avail_in = compressed_len;
832 infstream.next_in = compressed_data;
833 infstream.avail_out = bufsize;
834
835 /* the actual DE-compression work. */
836 if (Z_OK0 != ZLIB_PREFIX(inflateInit)(&infstream)inflateInit_((&infstream), "1.3.1", (int)sizeof(z_stream)
)
) {
837 /*
838 * XXX - check the error code and handle this appropriately.
839 */
840 g_free(buf)(__builtin_object_size ((buf), 0) != ((size_t) - 1)) ? g_free_sized
(buf, __builtin_object_size ((buf), 0)) : (g_free) (buf)
;
841 *err = WTAP_ERR_INTERNAL-21;
842 if (infstream.msg != NULL((void*)0)) {
843 *err_info = ws_strdup_printf("blf: inflateInit failed for LogContainer, message\"%s\"",wmem_strdup_printf(((void*)0), "blf: inflateInit failed for LogContainer, message\"%s\""
, infstream.msg)
844 infstream.msg)wmem_strdup_printf(((void*)0), "blf: inflateInit failed for LogContainer, message\"%s\""
, infstream.msg)
;
845 } else {
846 *err_info = ws_strdup("blf: inflateInit failed for LogContainer")wmem_strdup(((void*)0), "blf: inflateInit failed for LogContainer"
)
;
847 }
848 ws_debug("inflateInit failed for LogContainer")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 848, __func__, "inflateInit failed for LogContainer"); } } while
(0)
;
849 if (infstream.msg != NULL((void*)0)) {
850 ws_debug("inflateInit returned: \"%s\"", infstream.msg)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 850, __func__, "inflateInit returned: \"%s\"", infstream.msg
); } } while (0)
;
851 }
852 return NULL((void*)0);
853 }
854
855 int ret;
856
857
858 do {
859 infstream.next_out = &buf[total_out];
860 ret = ZLIB_PREFIX(inflate)inflate(&infstream, Z_NO_FLUSH0);
861
862 switch (ret) {
863 case Z_OK0:
864 case Z_STREAM_END1:
865 total_out += (bufsize - infstream.avail_out);
866
867 /* Presumably need more space. */
868 if (total_out > decompressed_len) {
869 *err = WTAP_ERR_BAD_FILE-13;
870 *err_info = ws_strdup_printf("blf: uncompressed data has wrong length (%" PRIu64 " > %" PRIu64")", total_out, decompressed_len)wmem_strdup_printf(((void*)0), "blf: uncompressed data has wrong length (%"
"l" "u" " > %" "l" "u"")", total_out, decompressed_len)
;
871 break;
872 }
873 if (infstream.avail_out == 0) {
874 /* Increase the total buffer */
875 bufsize = (uint32_t)MIN(total_out, INT32_MAX)(((total_out) < ((2147483647))) ? (total_out) : ((2147483647
)))
;
876 bufsize = (uint32_t)MIN(decompressed_len - total_out, bufsize)(((decompressed_len - total_out) < (bufsize)) ? (decompressed_len
- total_out) : (bufsize))
;
877
878 buf = (uint8_t*)g_realloc(buf, total_out + bufsize);
879 infstream.avail_out = bufsize;
880 }
881 continue;
882
883 case Z_NEED_DICT2:
884 *err = WTAP_ERR_DECOMPRESS-20;
885 *err_info = ws_strdup("blf: preset dictionary needed to decompress")wmem_strdup(((void*)0), "blf: preset dictionary needed to decompress"
)
;
886 break;
887
888 case Z_STREAM_ERROR(-2):
889 *err = WTAP_ERR_INTERNAL-21;
890 *err_info = ws_strdup_printf("blf: Z_STREAM_ERROR from inflate(), message \"%s\"",wmem_strdup_printf(((void*)0), "blf: Z_STREAM_ERROR from inflate(), message \"%s\""
, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)")
891 (infstream.msg != NULL) ? infstream.msg : "(none)")wmem_strdup_printf(((void*)0), "blf: Z_STREAM_ERROR from inflate(), message \"%s\""
, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)")
;
892 break;
893
894 case Z_MEM_ERROR(-4):
895 /* This means "not enough memory". */
896 *err = ENOMEM12;
897 *err_info = NULL((void*)0);
898 break;
899
900 case Z_DATA_ERROR(-3):
901 /* This means "deflate stream invalid" */
902 *err = WTAP_ERR_DECOMPRESS-20;
903 *err_info = (infstream.msg != NULL((void*)0)) ? ws_strdup(infstream.msg)wmem_strdup(((void*)0), infstream.msg) : NULL((void*)0);
904 break;
905
906 case Z_BUF_ERROR(-5):
907 /* XXX - this is recoverable; what should we do here? */
908 *err = WTAP_ERR_INTERNAL-21;
909 *err_info = ws_strdup_printf("blf: Z_BUF_ERROR from inflate(), message \"%s\"",wmem_strdup_printf(((void*)0), "blf: Z_BUF_ERROR from inflate(), message \"%s\""
, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)")
910 (infstream.msg != NULL) ? infstream.msg : "(none)")wmem_strdup_printf(((void*)0), "blf: Z_BUF_ERROR from inflate(), message \"%s\""
, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)")
;
911 break;
912
913 case Z_VERSION_ERROR(-6):
914 *err = WTAP_ERR_INTERNAL-21;
915 *err_info = ws_strdup_printf("blf: Z_VERSION_ERROR from inflate(), message \"%s\"",wmem_strdup_printf(((void*)0), "blf: Z_VERSION_ERROR from inflate(), message \"%s\""
, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)")
916 (infstream.msg != NULL) ? infstream.msg : "(none)")wmem_strdup_printf(((void*)0), "blf: Z_VERSION_ERROR from inflate(), message \"%s\""
, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)")
;
917 break;
918
919 default:
920 *err = WTAP_ERR_INTERNAL-21;
921 *err_info = ws_strdup_printf("blf: unexpected error %d from inflate(), message \"%s\"",wmem_strdup_printf(((void*)0), "blf: unexpected error %d from inflate(), message \"%s\""
, ret, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)"
)
922 ret,wmem_strdup_printf(((void*)0), "blf: unexpected error %d from inflate(), message \"%s\""
, ret, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)"
)
923 (infstream.msg != NULL) ? infstream.msg : "(none)")wmem_strdup_printf(((void*)0), "blf: unexpected error %d from inflate(), message \"%s\""
, ret, (infstream.msg != ((void*)0)) ? infstream.msg : "(none)"
)
;
924 break;
925 }
926 g_free(buf)(__builtin_object_size ((buf), 0) != ((size_t) - 1)) ? g_free_sized
(buf, __builtin_object_size ((buf), 0)) : (g_free) (buf)
;
927 ws_debug("inflate failed (return code %d) for LogContainer", ret)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 927, __func__, "inflate failed (return code %d) for LogContainer"
, ret); } } while (0)
;
928 if (infstream.msg != NULL((void*)0)) {
929 ws_debug("inflate returned: \"%s\"", infstream.msg)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 929, __func__, "inflate returned: \"%s\"", infstream.msg); }
} while (0)
;
930 }
931 /* Free up any dynamically-allocated memory in infstream */
932 ZLIB_PREFIX(inflateEnd)inflateEnd(&infstream);
933 return NULL((void*)0);
934 } while (ret != Z_STREAM_END1);
935
936 if (Z_OK0 != ZLIB_PREFIX(inflateEnd)inflateEnd(&infstream)) {
937 /*
938 * The zlib manual says this only returns Z_OK on success
939 * and Z_STREAM_ERROR if the stream state was inconsistent.
940 *
941 * It's not clear what useful information can be reported
942 * for Z_STREAM_ERROR; a look at the 1.2.11 source indicates
943 * that no string is returned to indicate what the problem
944 * was.
945 *
946 * It's also not clear what to do about infstream if this
947 * fails.
948 */
949 *err = WTAP_ERR_INTERNAL-21;
950 *err_info = ws_strdup("blf: inflateEnd failed for LogContainer")wmem_strdup(((void*)0), "blf: inflateEnd failed for LogContainer"
)
;
951 g_free(buf)(__builtin_object_size ((buf), 0) != ((size_t) - 1)) ? g_free_sized
(buf, __builtin_object_size ((buf), 0)) : (g_free) (buf)
;
952 ws_debug("inflateEnd failed for LogContainer")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 952, __func__, "inflateEnd failed for LogContainer"); } } while
(0)
;
953 if (infstream.msg != NULL((void*)0)) {
954 ws_debug("inflateEnd returned: \"%s\"", infstream.msg)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 954, __func__, "inflateEnd returned: \"%s\"", infstream.msg
); } } while (0)
;
955 }
956 return NULL((void*)0);
957 }
958
959 if (total_out < decompressed_len) {
960 /* Decompressed fewer bytes than claimed. */
961 g_free(buf)(__builtin_object_size ((buf), 0) != ((size_t) - 1)) ? g_free_sized
(buf, __builtin_object_size ((buf), 0)) : (g_free) (buf)
;
962 *err = WTAP_ERR_BAD_FILE-13;
963 *err_info = ws_strdup_printf("blf: uncompressed data has wrong length (%" PRIu64 " < %" PRIu64")", total_out, decompressed_len)wmem_strdup_printf(((void*)0), "blf: uncompressed data has wrong length (%"
"l" "u" " < %" "l" "u"")", total_out, decompressed_len)
;
964 return NULL((void*)0);
965 }
966
967 return buf;
968}
969#endif /* USE_ZLIB_OR_ZLIBNG */
970
971/** Ensures the given log container is in memory
972 *
973 * If the log container already is not already in memory,
974 * it reads it from the current seek position, allocating a
975 * properly sized buffer.
976 * The file offset must be set to the start of the container
977 * data (container->infile_data_start) before calling this function.
978 */
979static bool_Bool
980blf_pull_logcontainer_into_memory(blf_params_t *params, blf_log_container_t *container, int *err, char **err_info) {
981
982 if (container == NULL((void*)0)) {
983 *err = WTAP_ERR_INTERNAL-21;
984 *err_info = ws_strdup("blf_pull_logcontainer_into_memory called with NULL container")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory called with NULL container"
)
;
985 return false0;
986 }
987
988 if (container->real_data != NULL((void*)0)) {
989 return true1;
990 }
991
992 /* pull compressed data into buffer */
993 if (container->infile_start_pos < 0) {
994 /*
995 * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
996 * malformed file (WTAP_ERR_BAD_FILE)?
997 */
998 *err = WTAP_ERR_INTERNAL-21;
999 *err_info = ws_strdup_printf("blf_pull_logcontainer_into_memory: container.infile_start_pos (%" PRId64 ") < 0",wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: container.infile_start_pos (%"
"l" "d" ") < 0", container->infile_start_pos)
1000 container->infile_start_pos)wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: container.infile_start_pos (%"
"l" "d" ") < 0", container->infile_start_pos)
;
1001 return false0;
1002 }
1003 if (container->infile_data_start < (uint64_t)container->infile_start_pos) {
1004 /*
1005 * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
1006 * malformed file (WTAP_ERR_BAD_FILE)?
1007 */
1008 *err = WTAP_ERR_INTERNAL-21;
1009 *err_info = ws_strdup_printf("blf_pull_logcontainer_into_memory: container.infile_data_start (%" PRIu64 ") < container.infile_start_pos (%" PRId64 ")",wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: container.infile_data_start (%"
"l" "u" ") < container.infile_start_pos (%" "l" "d" ")", container
->infile_data_start, container->infile_start_pos)
1010 container->infile_data_start, container->infile_start_pos)wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: container.infile_data_start (%"
"l" "u" ") < container.infile_start_pos (%" "l" "d" ")", container
->infile_data_start, container->infile_start_pos)
;
1011 return false0;
1012 }
1013 if (container->infile_length < container->infile_data_start - (uint64_t)container->infile_start_pos) {
1014 /* The object length comes from the file, and is only checked
1015 * against the block header length, not the container header. */
1016 *err = WTAP_ERR_BAD_FILE-13;
1017 *err_info = ws_strdup_printf("blf_pull_logcontainer_into_memory: container.infile_length (%" PRIu64 ") < (container.infile_data_start (%" PRIu64 ") - container.infile_start_pos (%" PRId64 ")) = %" PRIu64,wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: container.infile_length (%"
"l" "u" ") < (container.infile_data_start (%" "l" "u" ") - container.infile_start_pos (%"
"l" "d" ")) = %" "l" "u", container->infile_length, container
->infile_data_start, container->infile_start_pos, container
->infile_data_start - (uint64_t)container->infile_start_pos
)
1018 container->infile_length,wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: container.infile_length (%"
"l" "u" ") < (container.infile_data_start (%" "l" "u" ") - container.infile_start_pos (%"
"l" "d" ")) = %" "l" "u", container->infile_length, container
->infile_data_start, container->infile_start_pos, container
->infile_data_start - (uint64_t)container->infile_start_pos
)
1019 container->infile_data_start, container->infile_start_pos,wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: container.infile_length (%"
"l" "u" ") < (container.infile_data_start (%" "l" "u" ") - container.infile_start_pos (%"
"l" "d" ")) = %" "l" "u", container->infile_length, container
->infile_data_start, container->infile_start_pos, container
->infile_data_start - (uint64_t)container->infile_start_pos
)
1020 container->infile_data_start - (uint64_t)container->infile_start_pos)wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: container.infile_length (%"
"l" "u" ") < (container.infile_data_start (%" "l" "u" ") - container.infile_start_pos (%"
"l" "d" ")) = %" "l" "u", container->infile_length, container
->infile_data_start, container->infile_start_pos, container
->infile_data_start - (uint64_t)container->infile_start_pos
)
;
1021 return false0;
1022 }
1023 uint64_t data_length = container->infile_length - (container->infile_data_start - (uint64_t)container->infile_start_pos);
1024 if (data_length > UINT_MAX(2147483647 *2U +1U)) {
1025 /*
1026 * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
1027 * malformed file (WTAP_ERR_BAD_FILE)?
1028 */
1029 *err = WTAP_ERR_INTERNAL-21;
1030 *err_info = ws_strdup_printf("blf_pull_logcontainer_into_memory: data_length (%" PRIu64 ") > UINT_MAX",wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: data_length (%"
"l" "u" ") > UINT_MAX", data_length)
1031 data_length)wmem_strdup_printf(((void*)0), "blf_pull_logcontainer_into_memory: data_length (%"
"l" "u" ") > UINT_MAX", data_length)
;
1032 return false0;
1033 }
1034
1035 if (container->real_length == 0) {
1036 ws_info("blf_pull_logcontainer_into_memory: found container with 0 length")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_INFO, ((void*)
0), -1, ((void*)0), "blf_pull_logcontainer_into_memory: found container with 0 length"
); } } while (0)
;
1037 /* Skip empty container */
1038 if (!wtap_read_bytes_or_eof(params->fh, NULL((void*)0), (unsigned int)data_length, err, err_info)) {
1039 if (*err == WTAP_ERR_SHORT_READ-12) {
1040 *err_info = ws_strdup("blf_pull_logcontainer_into_memory: short read on 0-length container")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory: short read on 0-length container"
)
;
1041 }
1042 return false0;
1043 }
1044 return true1;
1045 }
1046
1047 if (container->compression_method == BLF_COMPRESSION_NONE0) {
1048 if (data_length != container->real_length) {
1049 *err = WTAP_ERR_BAD_FILE-13;
1050 *err_info = ws_strdup("blf_pull_logcontainer_into_memory: uncompressed data has wrong length")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory: uncompressed data has wrong length"
)
;
1051 return false0;
1052 }
1053 unsigned char* buf = g_try_malloc((size_t)container->real_length);
1054 if (buf == NULL((void*)0)) {
1055 *err = WTAP_ERR_INTERNAL-21;
1056 *err_info = ws_strdup("blf_pull_logcontainer_into_memory: cannot allocate memory")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory: cannot allocate memory"
)
;
1057 return false0;
1058 }
1059 if (!wtap_read_bytes_or_eof(params->fh, buf, (unsigned int)data_length, err, err_info)) {
1060 g_free(buf)(__builtin_object_size ((buf), 0) != ((size_t) - 1)) ? g_free_sized
(buf, __builtin_object_size ((buf), 0)) : (g_free) (buf)
;
1061 if (*err == WTAP_ERR_SHORT_READ-12) {
1062 /*
1063 * XXX - Possible improvement: read as much as we can, instead of
1064 * skipping the last log container entirely.
1065 */
1066 *err_info = ws_strdup("blf_pull_logcontainer_into_memory: short read on uncompressed data")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory: short read on uncompressed data"
)
;
1067 }
1068 return false0;
1069 }
1070 container->real_data = buf;
1071 return true1;
1072
1073 } else if (container->compression_method == BLF_COMPRESSION_ZLIB2) {
1074#ifdef USE_ZLIB_OR_ZLIBNG
1075 if (data_length == 0) {
1076 *err = WTAP_ERR_BAD_FILE-13;
1077 *err_info = ws_strdup("blf_pull_logcontainer_into_memory: compressed container has 0 length")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory: compressed container has 0 length"
)
;
1078 return false0;
1079 }
1080 unsigned char *compressed_data = g_try_malloc((size_t)data_length);
1081 if (compressed_data == NULL((void*)0)) {
1082 *err = WTAP_ERR_INTERNAL-21;
1083 *err_info = ws_strdup("blf_pull_logcontainer_into_memory: cannot allocate memory")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory: cannot allocate memory"
)
;
1084 return false0;
1085 }
1086 if (!wtap_read_bytes_or_eof(params->fh, compressed_data, (unsigned int)data_length, err, err_info)) {
1087 g_free(compressed_data)(__builtin_object_size ((compressed_data), 0) != ((size_t) - 1
)) ? g_free_sized (compressed_data, __builtin_object_size ((compressed_data
), 0)) : (g_free) (compressed_data)
;
1088 if (*err == WTAP_ERR_SHORT_READ-12) {
1089 /*
1090 * XXX - Possible improvement: read as much as we can, instead of
1091 * skipping the last log container entirely.
1092 * In this case, we also need to handle potential errors when inflating.
1093 */
1094 *err_info = ws_strdup("blf_pull_logcontainer_into_memory: short read on compressed data")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory: short read on compressed data"
)
;
1095 }
1096 return false0;
1097 }
1098
1099 container->real_data = blf_decompress_zlib(compressed_data, (unsigned)data_length, container->real_length, err, err_info);
1100 g_free(compressed_data)(__builtin_object_size ((compressed_data), 0) != ((size_t) - 1
)) ? g_free_sized (compressed_data, __builtin_object_size ((compressed_data
), 0)) : (g_free) (compressed_data)
;
1101 if (container->real_data == NULL((void*)0)) {
1102 return false0;
1103 }
1104 return true1;
1105#else /* USE_ZLIB_OR_ZLIBNG */
1106 (void) params;
1107 *err = WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED-26;
1108 *err_info = ws_strdup("blf_pull_logcontainer_into_memory: reading gzip-compressed containers isn't supported")wmem_strdup(((void*)0), "blf_pull_logcontainer_into_memory: reading gzip-compressed containers isn't supported"
)
;
1109 return false0;
1110#endif /* USE_ZLIB_OR_ZLIBNG */
1111 }
1112
1113 return false0;
1114}
1115
1116/** Finds the next log container starting at the current file offset
1117 *
1118 * Adds the container to the containers array for later access
1119 */
1120static bool_Bool
1121blf_find_next_logcontainer(blf_params_t* params, int* err, char** err_info) {
1122 blf_blockheader_t header;
1123 blf_logcontainerheader_t logcontainer_header;
1124 blf_log_container_t tmp;
1125 unsigned char* header_ptr;
1126 unsigned int i;
1127
1128 uint64_t current_real_start;
1129 if (params->blf_data->log_containers->len == 0) {
1130 current_real_start = 0;
1131 } else {
1132 const blf_log_container_t* container = &g_array_index(params->blf_data->log_containers, blf_log_container_t, params->blf_data->log_containers->len - 1)(((blf_log_container_t*) (void *) (params->blf_data->log_containers
)->data) [(params->blf_data->log_containers->len -
1)])
;
1133 current_real_start = container->real_start_pos + container->real_length;
1134 }
1135
1136 header_ptr = (unsigned char*)&header;
1137 i = 0;
1138
1139 /** Find Object
1140 *
1141 * We read one byte at a time so that we don't have to seek backward (allows us to do a linear read)
1142 */
1143 while (i < sizeof(blf_obj_magic)) {
1144 if (!wtap_read_bytes_or_eof(params->fh, &header_ptr[i], 1, err, err_info)) {
1145 ws_debug("we found end of file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1145, __func__, "we found end of file"); } } while (0)
;
1146 return false0;
1147 }
1148 if (header_ptr[i] != blf_obj_magic[i]) {
1149 if (params->pipe) {
1150 ws_debug("container object magic is not LOBJ")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1150, __func__, "container object magic is not LOBJ"); } } while
(0)
;
1151 } else {
1152 ws_debug("container object magic is not LOBJ (pos: 0x%" PRIx64 ")", file_tell(params->fh) - 1)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1152, __func__, "container object magic is not LOBJ (pos: 0x%"
"l" "x" ")", file_tell(params->fh) - 1); } } while (0)
;
1153 }
1154 if (i > 0) {
1155 int j = i;
1156
1157 while (memcmp(&header_ptr[i - j + 1], blf_obj_magic, j)) {
1158 /* Check if the last j bytes match the first j bytes of the magic */
1159 j--;
1160 }
1161
1162 /* The last j bytes match, and the first j bytes are already in the buffer, since j<=i */
1163 i = j;
1164 }
1165 } else {
1166 /* Character matches */
1167 i++;
1168 }
1169 }
1170
1171 if (!wtap_read_bytes_or_eof(params->fh, &header.header_length, sizeof(blf_blockheader_t) - sizeof(blf_obj_magic), err, err_info)) {
1172 ws_debug("we found end of file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1172, __func__, "we found end of file"); } } while (0)
;
1173 return false0;
1174 }
1175
1176 fix_endianness_blf_blockheader(&header);
1177
1178 if (header.header_length < sizeof(blf_blockheader_t)) {
1179 *err = WTAP_ERR_BAD_FILE-13;
1180 *err_info = ws_strdup("blf: header length too short while looking for object")wmem_strdup(((void*)0), "blf: header length too short while looking for object"
)
;
1181 return false0;
1182 }
1183
1184 if (header.header_type != BLF_HEADER_TYPE_DEFAULT1) {
1185 *err = WTAP_ERR_UNSUPPORTED-4;
1186 *err_info = ws_strdup_printf("blf: unknown header type (%u), I know only BLF_HEADER_TYPE_DEFAULT (1)", header.header_type)wmem_strdup_printf(((void*)0), "blf: unknown header type (%u), I know only BLF_HEADER_TYPE_DEFAULT (1)"
, header.header_type)
;
1187 return false0;
1188 }
1189
1190 if (header.object_length < header.header_length) {
1191 *err = WTAP_ERR_BAD_FILE-13;
1192 *err_info = ws_strdup("blf: header object length less than header length while looking for objects")wmem_strdup(((void*)0), "blf: header object length less than header length while looking for objects"
)
;
1193 return false0;
1194 }
1195
1196 if (header.object_type == BLF_OBJTYPE_LOG_CONTAINER10) {
1197 /* skip unknown header part if needed */
1198 if (header.header_length > sizeof(blf_blockheader_t)) {
1199 /* seek over unknown header part */
1200 if (!wtap_read_bytes(params->fh, NULL((void*)0), header.header_length - sizeof(blf_blockheader_t), err, err_info)) {
1201 ws_debug("error skipping unknown header bytes in log container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1201, __func__, "error skipping unknown header bytes in log container"
); } } while (0)
;
1202 return false0;
1203 }
1204 }
1205
1206 /* Read the log container header */
1207 if (!wtap_read_bytes_or_eof(params->fh, &logcontainer_header, sizeof(blf_logcontainerheader_t), err, err_info)) {
1208 ws_debug("not enough bytes for log container header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1208, __func__, "not enough bytes for log container header"
); } } while (0)
;
1209 return false0;
1210 }
1211
1212 fix_endianness_blf_logcontainerheader(&logcontainer_header);
1213
1214 blf_init_logcontainer(&tmp);
1215
1216 if (params->pipe) {
1217 tmp.infile_start_pos = 0;
1218 tmp.infile_data_start = sizeof(blf_logcontainerheader_t) + header.header_length;
1219 } else {
1220 tmp.infile_data_start = file_tell(params->fh);
1221 tmp.infile_start_pos = tmp.infile_data_start - sizeof(blf_logcontainerheader_t) - header.header_length;
1222 }
1223 tmp.infile_length = header.object_length;
1224
1225 tmp.real_start_pos = current_real_start;
1226 tmp.real_length = logcontainer_header.uncompressed_size;
1227 tmp.compression_method = logcontainer_header.compression_method;
1228
1229 ws_debug("found log container with real_pos=0x%" PRIx64 ", real_length=0x%" PRIx64, tmp.real_start_pos, tmp.real_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1229, __func__, "found log container with real_pos=0x%" "l"
"x" ", real_length=0x%" "l" "x", tmp.real_start_pos, tmp.real_length
); } } while (0)
;
1230 } else {
1231 ws_debug("found BLF object without log container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1231, __func__, "found BLF object without log container"); }
} while (0)
;
1232
1233 /* Create a fake log container for the lone object.
1234 * In order to avoid seeking backwards, we need to pull the fake log container now.
1235 */
1236 unsigned char* buf = g_try_malloc((size_t)header.object_length);
1237 if (buf == NULL((void*)0)) {
1238 /*
1239 * XXX - we need an "out of memory" error code here.
1240 */
1241 *err = WTAP_ERR_INTERNAL-21;
1242 *err_info = ws_strdup("blf_find_next_logcontainer: cannot allocate memory")wmem_strdup(((void*)0), "blf_find_next_logcontainer: cannot allocate memory"
)
;
1243 return false0;
1244 }
1245
1246 memcpy(buf, &header, sizeof(blf_blockheader_t));
1247
1248 if (header.object_length > sizeof(blf_blockheader_t)) {
1249 if (!wtap_read_bytes(params->fh, buf + sizeof(blf_blockheader_t), header.object_length - sizeof(blf_blockheader_t), err, err_info)) {
1250 g_free(buf)(__builtin_object_size ((buf), 0) != ((size_t) - 1)) ? g_free_sized
(buf, __builtin_object_size ((buf), 0)) : (g_free) (buf)
;
1251 ws_debug("cannot pull object without log container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1251, __func__, "cannot pull object without log container")
; } } while (0)
;
1252 return false0;
1253 }
1254 }
1255
1256 blf_init_logcontainer(&tmp);
1257
1258 tmp.infile_start_pos = params->pipe ? 0 : (file_tell(params->fh) - header.object_length);
1259 tmp.infile_data_start = tmp.infile_start_pos;
1260 tmp.infile_length = header.object_length;
1261
1262 tmp.real_start_pos = current_real_start;
1263 tmp.real_length = header.object_length;
1264 tmp.compression_method = BLF_COMPRESSION_NONE0;
1265
1266 tmp.real_data = buf;
1267
1268 ws_debug("found non-log-container object with real_pos=0x%" PRIx64 ", real_length=0x%" PRIx64, tmp.real_start_pos, tmp.real_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1268, __func__, "found non-log-container object with real_pos=0x%"
"l" "x" ", real_length=0x%" "l" "x", tmp.real_start_pos, tmp
.real_length); } } while (0)
;
1269 }
1270
1271 g_array_append_val(params->blf_data->log_containers, tmp)g_array_append_vals (params->blf_data->log_containers, &
(tmp), 1)
;
1272
1273 return true1;
1274}
1275
1276static bool_Bool
1277// NOLINTNEXTLINE(misc-no-recursion)
1278blf_pull_next_logcontainer(blf_params_t* params, int* err, char** err_info) {
1279 blf_log_container_t* container;
1280
1281 if (!blf_find_next_logcontainer(params, err, err_info)) {
1282 return false0;
1283 }
1284
1285 /* Is there a next log container to pull? */
1286 if (params->blf_data->log_containers->len == 0) {
1287 /* No. */
1288 return false0;
1289 }
1290
1291 container = &g_array_index(params->blf_data->log_containers, blf_log_container_t, params->blf_data->log_containers->len - 1)(((blf_log_container_t*) (void *) (params->blf_data->log_containers
)->data) [(params->blf_data->log_containers->len -
1)])
;
1292 if (!blf_pull_logcontainer_into_memory(params, container, err, err_info)) {
1293 if (*err == WTAP_ERR_DECOMPRESS-20 || *err == WTAP_ERR_SHORT_READ-12) {
1294 report_warning("Error while decompressing BLF log container number %u (file pos. 0x%" PRIx64"l" "x" "): %s",
1295 params->blf_data->log_containers->len - 1, container->infile_start_pos, *err_info ? *err_info : "(none)");
1296 *err = 0;
1297 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
1298 *err_info = NULL((void*)0);
1299
1300 /* Skip this log container. */
1301 g_array_remove_index(params->blf_data->log_containers, params->blf_data->log_containers->len - 1);
1302 }
1303 switch (*err) {
1304 case WTAP_ERR_DECOMPRESS-20:
1305 /*
1306 * Try to get the next log container. Calling blf_pull_logcontainer_into_memory advances
1307 * the file pointer: eventually we will reach the end of the file and stop recursing.
1308 */
1309 return blf_pull_next_logcontainer(params, err, err_info);
1310 case WTAP_ERR_SHORT_READ-12:
1311 /*
1312 * This can happen if the log container (and consequently the file) was abruptly truncated for any reason.
1313 * We can go on, since the file pointer has already been advanced, so we're already at EOF.
1314 */
1315 return true1;
1316 default:
1317 break;
1318 }
1319
1320 return false0;
1321 }
1322
1323 return true1;
1324}
1325
1326static bool_Bool
1327blf_read_bytes_or_eof(blf_params_t *params, uint64_t real_pos, void *target_buffer, uint64_t count, int *err, char **err_info) {
1328 blf_log_container_t* container;
1329 unsigned container_index;
1330
1331 uint64_t end_pos = real_pos + count;
1332
1333 uint64_t copied = 0;
1334 uint64_t data_left;
1335 uint64_t start_in_buf;
1336
1337 unsigned char *buf = (unsigned char *)target_buffer;
1338
1339 if (count == 0) {
1340 ws_debug("called blf_read_bytes_or_eof with 0 count")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1340, __func__, "called blf_read_bytes_or_eof with 0 count"
); } } while (0)
;
1341 return false0;
1342 }
1343
1344 if (count > UINT32_MAX(4294967295U)) {
1345 ws_debug("trying to read too many bytes")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1345, __func__, "trying to read too many bytes"); } } while
(0)
;
1346 return false0;
1347 }
1348
1349 if (params->random) {
1350 /*
1351 * Do a binary search for the container in which real_pos
1352 * is included.
1353 */
1354 if (!g_array_binary_search(params->blf_data->log_containers, &real_pos, blf_logcontainers_search, &container_index)) {
1355 /*
1356 * XXX - why is this treated as an EOF rather than an error?
1357 * *err appears to be 0, which means our caller treats it as an
1358 * EOF, at least when reading the log object header.
1359 */
1360 ws_debug("cannot read data because start position cannot be mapped")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1360, __func__, "cannot read data because start position cannot be mapped"
); } } while (0)
;
1361 return false0;
1362 }
1363 container = &g_array_index(params->blf_data->log_containers, blf_log_container_t, container_index)(((blf_log_container_t*) (void *) (params->blf_data->log_containers
)->data) [(container_index)])
;
1364 } else {
1365 if (params->blf_data->log_containers->len == 0) {
1366 /*
1367 * This is the first (linear) pass, and we haven't yet
1368 * added any containers. Pull the next log container
1369 * into memory, so that the array isn't empty.
1370 */
1371 if (!blf_pull_next_logcontainer(params, err, err_info)) {
1372 return false0;
1373 }
1374 }
1375
1376 /*
1377 * Search backwards in the array, from the last entry to the
1378 * first, to find the log container in which real_pos is
1379 * included.
1380 */
1381 container_index = params->blf_data->log_containers->len;
1382 do {
1383 container = &g_array_index(params->blf_data->log_containers, blf_log_container_t, --container_index)(((blf_log_container_t*) (void *) (params->blf_data->log_containers
)->data) [(--container_index)])
;
1384 } while (real_pos < container->real_start_pos && container_index > 0); /* For some reason we skipped past the correct container */
1385 }
1386
1387 while (real_pos < end_pos) {
1388
1389 while (real_pos >= container->real_start_pos + container->real_length) {
1390 container_index++;
1391 if (!params->random) { /* First (linear) pass */
1392 if (!blf_pull_next_logcontainer(params, err, err_info)) {
1393 return false0;
1394 }
1395 }
1396 if (container_index >= params->blf_data->log_containers->len) {
1397 ws_debug("cannot find real_pos in container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1397, __func__, "cannot find real_pos in container"); } } while
(0)
;
1398 return false0;
1399 }
1400 container = &g_array_index(params->blf_data->log_containers, blf_log_container_t, container_index)(((blf_log_container_t*) (void *) (params->blf_data->log_containers
)->data) [(container_index)])
;
1401 if (real_pos < container->real_start_pos) {
1402 ws_debug("cannot find real_pos in container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1402, __func__, "cannot find real_pos in container"); } } while
(0)
;
1403 return false0;
1404 }
1405 }
1406
1407 if (real_pos < container->real_start_pos) {
1408 ws_debug("cannot find real_pos in container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1408, __func__, "cannot find real_pos in container"); } } while
(0)
;
1409 return false0;
1410 }
1411
1412 start_in_buf = real_pos - container->real_start_pos;
1413
1414 if (params->random) {
1415 if (file_seek(params->fh, container->infile_data_start, SEEK_SET0, err) == -1) {
1416 return false0;
1417 }
1418 if (!blf_pull_logcontainer_into_memory(params, container, err, err_info)) {
1419 return false0;
1420 }
1421 }
1422
1423 data_left = container->real_length - start_in_buf;
1424
1425 if (data_left < (count - copied)) {
1426 memcpy(buf + copied, container->real_data + start_in_buf, data_left);
1427 copied += data_left;
1428 real_pos += data_left;
1429 } else {
1430 memcpy(buf + copied, container->real_data + start_in_buf, count - copied);
1431 return true1;
1432 }
1433
1434 }
1435
1436 /*
1437 * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
1438 * malformed file (WTAP_ERR_BAD_FILE)?
1439 */
1440 *err = WTAP_ERR_INTERNAL-21;
1441 *err_info = ws_strdup("blf_read_bytes_or_eof: ran out of containers")wmem_strdup(((void*)0), "blf_read_bytes_or_eof: ran out of containers"
)
;
1442 return false0;
1443}
1444
1445static bool_Bool
1446blf_read_bytes(blf_params_t *params, uint64_t real_pos, void *target_buffer, uint64_t count, int *err, char **err_info) {
1447 if (!blf_read_bytes_or_eof(params, real_pos, target_buffer, count, err, err_info)) {
1448 if (*err == 0) {
1449 *err = WTAP_ERR_SHORT_READ-12;
1450 }
1451 return false0;
1452 }
1453 return true1;
1454}
1455
1456static void
1457blf_init_rec(blf_params_t *params, uint32_t flags, uint64_t object_timestamp, int pkt_encap, uint16_t channel, uint16_t hwchannel, unsigned caplen, unsigned len) {
1458 wtap_setup_packet_rec(params->rec, pkt_encap);
1459 params->rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
1460 params->rec->presence_flags = WTAP_HAS_CAP_LEN0x00000002 | WTAP_HAS_INTERFACE_ID0x00000004;
1461 switch (flags) {
1462 case BLF_TIMESTAMP_RESOLUTION_10US1:
1463 params->rec->presence_flags |= WTAP_HAS_TS0x00000001;
1464 params->rec->tsprec = WTAP_TSPREC_10_USEC5;
1465 object_timestamp *= 10000;
1466 object_timestamp += params->blf_data->start_offset_ns;
1467 break;
1468
1469 case BLF_TIMESTAMP_RESOLUTION_1NS2:
1470 params->rec->presence_flags |= WTAP_HAS_TS0x00000001;
1471 params->rec->tsprec = WTAP_TSPREC_NSEC9;
1472 object_timestamp += params->blf_data->start_offset_ns;
1473 break;
1474
1475 default:
1476 /* Metadata objects have both flags and timestamp equal to zero, so that combination is not an error. */
1477 if (flags != 0 || object_timestamp != 0) {
1478 /*
1479 * XXX - report this as an error?
1480 *
1481 * Or provide a mechanism to allow file readers to report
1482 * a warning (an error that the reader tries to work
1483 * around and that the caller should report)?
1484 */
1485 ws_debug("Unknown combination of flags and timestamp (0x%x, %" PRIu64 ")", flags, object_timestamp)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1485, __func__, "Unknown combination of flags and timestamp (0x%x, %"
"l" "u" ")", flags, object_timestamp); } } while (0)
;
1486 object_timestamp = 0;
1487 }
1488 break;
1489 }
1490 params->rec->ts.secs = object_timestamp / (1000 * 1000 * 1000);
1491 params->rec->ts.nsecs = object_timestamp % (1000 * 1000 * 1000);
1492 params->rec->rec_header.packet_header.caplen = caplen;
1493 params->rec->rec_header.packet_header.len = len;
1494
1495 params->rec->rec_header.packet_header.interface_id = blf_lookup_interface(params, pkt_encap, channel, hwchannel, NULL((void*)0));
1496
1497 /* TODO: before we had to remove comments and verdict here to not leak memory but APIs have changed ... */
1498}
1499
1500static void
1501blf_add_direction_option(blf_params_t *params, uint16_t direction) {
1502 uint32_t tmp = PACK_FLAGS_DIRECTION_INBOUND1; /* don't care */
1503
1504 switch (direction) {
1505 case BLF_DIR_RX0:
1506 tmp = PACK_FLAGS_DIRECTION_INBOUND1; /* inbound */
1507 break;
1508 case BLF_DIR_TX1:
1509 case BLF_DIR_TX_RQ2:
1510 tmp = PACK_FLAGS_DIRECTION_OUTBOUND2; /* outbound */
1511 break;
1512 }
1513
1514 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_FLAGS2, tmp);
1515}
1516
1517static bool_Bool
1518blf_read_log_object_header(blf_params_t *params, int *err, char **err_info, int64_t header2_start, int64_t data_start, blf_logobjectheader_t *logheader) {
1519 if (data_start - header2_start < (int64_t)sizeof(blf_logobjectheader_t)) {
1520 *err = WTAP_ERR_BAD_FILE-13;
1521 *err_info = ws_strdup("blf: not enough bytes for log object header")wmem_strdup(((void*)0), "blf: not enough bytes for log object header"
)
;
1522 ws_debug("not enough bytes for timestamp header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1522, __func__, "not enough bytes for timestamp header"); }
} while (0)
;
1523 return false0;
1524 }
1525
1526 if (!blf_read_bytes_or_eof(params, header2_start, logheader, sizeof(*logheader), err, err_info)) {
1527 ws_debug("not enough bytes for logheader")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1527, __func__, "not enough bytes for logheader"); } } while
(0)
;
1528 return false0;
1529 }
1530 fix_endianness_blf_logobjectheader(logheader);
1531 return true1;
1532}
1533
1534static bool_Bool
1535blf_read_log_object_header2(blf_params_t *params, int *err, char **err_info, int64_t header2_start, int64_t data_start, blf_logobjectheader2_t *logheader) {
1536 if (data_start - header2_start < (int64_t)sizeof(blf_logobjectheader2_t)) {
1537 *err = WTAP_ERR_BAD_FILE-13;
1538 *err_info = ws_strdup("blf: not enough bytes for log object header")wmem_strdup(((void*)0), "blf: not enough bytes for log object header"
)
;
1539 ws_debug("not enough bytes for timestamp header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1539, __func__, "not enough bytes for timestamp header"); }
} while (0)
;
1540 return false0;
1541 }
1542
1543 if (!blf_read_bytes_or_eof(params, header2_start, logheader, sizeof(*logheader), err, err_info)) {
1544 ws_debug("not enough bytes for logheader")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1544, __func__, "not enough bytes for logheader"); } } while
(0)
;
1545 return false0;
1546 }
1547 fix_endianness_blf_logobjectheader2(logheader);
1548 return true1;
1549}
1550
1551static bool_Bool
1552blf_read_log_object_header3(blf_params_t *params, int *err, char **err_info, int64_t header2_start, int64_t data_start, blf_logobjectheader3_t *logheader) {
1553 if (data_start - header2_start < (int64_t)sizeof(blf_logobjectheader3_t)) {
1554 *err = WTAP_ERR_BAD_FILE-13;
1555 *err_info = ws_strdup("blf: not enough bytes for log object header")wmem_strdup(((void*)0), "blf: not enough bytes for log object header"
)
;
1556 ws_debug("not enough bytes for timestamp header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1556, __func__, "not enough bytes for timestamp header"); }
} while (0)
;
1557 return false0;
1558 }
1559
1560 if (!blf_read_bytes_or_eof(params, header2_start, logheader, sizeof(*logheader), err, err_info)) {
1561 ws_debug("not enough bytes for logheader")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1561, __func__, "not enough bytes for logheader"); } } while
(0)
;
1562 return false0;
1563 }
1564 fix_endianness_blf_logobjectheader3(logheader);
1565 return true1;
1566}
1567
1568static bool_Bool
1569blf_read_ethernetframe(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
1570 blf_ethernetframeheader_t ethheader;
1571 uint8_t tmpbuf[18];
1572 unsigned caplen, len;
1573
1574 if (object_length < (data_start - block_start) + (int) sizeof(blf_ethernetframeheader_t)) {
1575 *err = WTAP_ERR_BAD_FILE-13;
1576 *err_info = ws_strdup("blf: ETHERNET_FRAME: not enough bytes for ethernet frame header in object")wmem_strdup(((void*)0), "blf: ETHERNET_FRAME: not enough bytes for ethernet frame header in object"
)
;
1577 ws_debug("not enough bytes for ethernet frame header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1577, __func__, "not enough bytes for ethernet frame header in object"
); } } while (0)
;
1578 return false0;
1579 }
1580
1581 if (!blf_read_bytes(params, data_start, &ethheader, sizeof(ethheader), err, err_info)) {
1582 ws_debug("not enough bytes for ethernet frame header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1582, __func__, "not enough bytes for ethernet frame header in file"
); } } while (0)
;
1583 return false0;
1584 }
1585 fix_endianness_blf_ethernetframeheader(&ethheader);
1586
1587 /*
1588 * BLF breaks up and reorders the Ethernet header and VLAN tag fields.
1589 * This is a really bad design and makes this format one of the worst.
1590 * If you want a fast format that keeps your data intact, avoid this format!
1591 * So, lets hope we can reconstruct the original packet successfully.
1592 */
1593
1594 tmpbuf[0] = ethheader.dst_addr[0];
1595 tmpbuf[1] = ethheader.dst_addr[1];
1596 tmpbuf[2] = ethheader.dst_addr[2];
1597 tmpbuf[3] = ethheader.dst_addr[3];
1598 tmpbuf[4] = ethheader.dst_addr[4];
1599 tmpbuf[5] = ethheader.dst_addr[5];
1600
1601 tmpbuf[6] = ethheader.src_addr[0];
1602 tmpbuf[7] = ethheader.src_addr[1];
1603 tmpbuf[8] = ethheader.src_addr[2];
1604 tmpbuf[9] = ethheader.src_addr[3];
1605 tmpbuf[10] = ethheader.src_addr[4];
1606 tmpbuf[11] = ethheader.src_addr[5];
1607
1608 if (ethheader.tpid != 0) { /* A valid VLAN tag can have a TCI of 0. */
1609 phtonu16(tmpbuf + 12, ethheader.tpid);
1610 phtonu16(tmpbuf + 14, ethheader.tci);
1611 phtonu16(tmpbuf + 16, ethheader.ethtype);
1612 ws_buffer_assure_space(&params->rec->data, (size_t)18 + ethheader.payloadlength);
1613 ws_buffer_append(&params->rec->data, tmpbuf, (size_t)18);
1614 caplen = ((uint32_t)18 + ethheader.payloadlength);
1615 len = ((uint32_t)18 + ethheader.payloadlength);
1616 } else {
1617 phtonu16(tmpbuf + 12, ethheader.ethtype);
1618 ws_buffer_assure_space(&params->rec->data, (size_t)14 + ethheader.payloadlength);
1619 ws_buffer_append(&params->rec->data, tmpbuf, (size_t)14);
1620 caplen = ((uint32_t)14 + ethheader.payloadlength);
1621 len = ((uint32_t)14 + ethheader.payloadlength);
1622 }
1623
1624 if (!blf_read_bytes(params, data_start + sizeof(blf_ethernetframeheader_t), ws_buffer_end_ptr(&params->rec->data), ethheader.payloadlength, err, err_info)) {
1625 ws_debug("copying ethernet frame failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1625, __func__, "copying ethernet frame failed"); } } while
(0)
;
1626 return false0;
1627 }
1628 ws_buffer_increase_length(&params->rec->data, ethheader.payloadlength);
1629
1630 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, UINT16_MAX(65535), caplen, len);
1631 blf_add_direction_option(params, ethheader.direction);
1632
1633 return true1;
1634}
1635
1636static bool_Bool
1637blf_read_ethernetframe_ext(blf_params_t *params, int *err, char **err_info, int64_t block_start,int64_t data_start,
1638 int64_t object_length, uint32_t flags, uint64_t object_timestamp, bool_Bool error) {
1639 blf_ethernetframeheader_ex_t ethheader;
1640
1641 if (object_length < (data_start - block_start) + (int) sizeof(blf_ethernetframeheader_ex_t)) {
1642 *err = WTAP_ERR_BAD_FILE-13;
1643 *err_info = ws_strdup_printf("blf: %s: not enough bytes for ethernet frame header in object", error ? "ETHERNET_ERROR_EX" : "ETHERNET_FRAME_EX")wmem_strdup_printf(((void*)0), "blf: %s: not enough bytes for ethernet frame header in object"
, error ? "ETHERNET_ERROR_EX" : "ETHERNET_FRAME_EX")
;
1644 ws_debug("not enough bytes for ethernet frame header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1644, __func__, "not enough bytes for ethernet frame header in object"
); } } while (0)
;
1645 return false0;
1646 }
1647
1648 if (!blf_read_bytes(params, data_start, &ethheader, sizeof(blf_ethernetframeheader_ex_t), err, err_info)) {
1649 ws_debug("not enough bytes for ethernet frame header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1649, __func__, "not enough bytes for ethernet frame header in file"
); } } while (0)
;
1650 return false0;
1651 }
1652 fix_endianness_blf_ethernetframeheader_ex(&ethheader);
1653
1654 if (object_length - (data_start - block_start) - sizeof(blf_ethernetframeheader_ex_t) < ethheader.frame_length) {
1655 *err = WTAP_ERR_BAD_FILE-13;
1656 *err_info = ws_strdup_printf("blf: %s: frame too short", error ? "ETHERNET_ERROR_EX" : "ETHERNET_FRAME_EX")wmem_strdup_printf(((void*)0), "blf: %s: frame too short", error
? "ETHERNET_ERROR_EX" : "ETHERNET_FRAME_EX")
;
1657 ws_debug("frame too short")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1657, __func__, "frame too short"); } } while (0)
;
1658 return false0;
1659 }
1660
1661 ws_buffer_assure_space(&params->rec->data, ethheader.frame_length);
1662
1663 if (!blf_read_bytes(params, data_start + sizeof(blf_ethernetframeheader_ex_t), ws_buffer_end_ptr(&params->rec->data), ethheader.frame_length, err, err_info)) {
1664 ws_debug("copying ethernet frame failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1664, __func__, "copying ethernet frame failed"); } } while
(0)
;
1665 return false0;
1666 }
1667 ws_buffer_increase_length(&params->rec->data, ethheader.frame_length);
1668
1669 if (ethheader.flags & BLF_ETHERNET_EX_HARDWARECHANNEL0x0002) {
1670 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, ethheader.hw_channel, ethheader.frame_length, ethheader.frame_length);
1671 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_QUEUE6, ethheader.hw_channel);
1672 } else {
1673 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, UINT16_MAX(65535), ethheader.frame_length, ethheader.frame_length);
1674 }
1675
1676 blf_add_direction_option(params, ethheader.direction);
1677
1678 return true1;
1679}
1680
1681static bool_Bool
1682blf_read_ethernet_rxerror(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
1683 blf_ethernet_rxerror_t ethheader;
1684
1685 if (object_length < (data_start - block_start) + (int)sizeof(blf_ethernet_rxerror_t)) {
1686 *err = WTAP_ERR_BAD_FILE-13;
1687 *err_info = ws_strdup("blf: ETHERNET_RXERROR: not enough bytes for ethernet frame header in object")wmem_strdup(((void*)0), "blf: ETHERNET_RXERROR: not enough bytes for ethernet frame header in object"
)
;
1688 ws_debug("not enough bytes for ethernet rx error header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1688, __func__, "not enough bytes for ethernet rx error header in object"
); } } while (0)
;
1689 return false0;
1690 }
1691
1692 if (!blf_read_bytes(params, data_start, &ethheader, sizeof(blf_ethernet_rxerror_t), err, err_info)) {
1693 ws_debug("not enough bytes for ethernet rx error header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1693, __func__, "not enough bytes for ethernet rx error header in file"
); } } while (0)
;
1694 return false0;
1695 }
1696 fix_endianness_blf_ethernet_rxerror(&ethheader);
1697
1698 if (object_length - (data_start - block_start) < ethheader.frame_length) {
1699 *err = WTAP_ERR_BAD_FILE-13;
1700 *err_info = ws_strdup("blf: ETHERNET_RXERROR: frame too short")wmem_strdup(((void*)0), "blf: ETHERNET_RXERROR: frame too short"
)
;
1701 ws_debug("frame too short")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1701, __func__, "frame too short"); } } while (0)
;
1702 return false0;
1703 }
1704
1705 ws_buffer_assure_space(&params->rec->data, ethheader.frame_length);
1706
1707 if (!blf_read_bytes(params, data_start + sizeof(blf_ethernet_rxerror_t), ws_buffer_end_ptr(&params->rec->data), ethheader.frame_length, err, err_info)) {
1708 ws_debug("copying ethernet rx error failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1708, __func__, "copying ethernet rx error failed"); } } while
(0)
;
1709 return false0;
1710 }
1711 ws_buffer_increase_length(&params->rec->data, ethheader.frame_length);
1712
1713 if (ethheader.hw_channel != 0) { /* In this object type, a value of 0 is considered invalid. */
1714 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, ethheader.hw_channel, ethheader.frame_length, ethheader.frame_length);
1715 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_QUEUE6, ethheader.hw_channel);
1716 } else {
1717 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, UINT16_MAX(65535), ethheader.frame_length, ethheader.frame_length);
1718 }
1719 blf_add_direction_option(params, ethheader.direction);
1720
1721 return true1;
1722}
1723
1724/*
1725 * XXX - provide radio information to our caller in the pseudo-header.
1726 */
1727static bool_Bool
1728blf_read_wlanframe(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
1729 blf_wlanframeheader_t wlanheader;
1730
1731 if (object_length < (data_start - block_start) + (int)sizeof(blf_wlanframeheader_t)) {
1732 *err = WTAP_ERR_BAD_FILE-13;
1733 *err_info = ws_strdup("blf: WLAN_FRAME: not enough bytes for wlan frame header in object")wmem_strdup(((void*)0), "blf: WLAN_FRAME: not enough bytes for wlan frame header in object"
)
;
1734 ws_debug("not enough bytes for wlan frame header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1734, __func__, "not enough bytes for wlan frame header in object"
); } } while (0)
;
1735 return false0;
1736 }
1737
1738 if (!blf_read_bytes(params, data_start, &wlanheader, sizeof(blf_wlanframeheader_t), err, err_info)) {
1739 ws_debug("not enough bytes for wlan frame header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1739, __func__, "not enough bytes for wlan frame header in file"
); } } while (0)
;
1740 return false0;
1741 }
1742 fix_endianness_blf_wlanframeheader(&wlanheader);
1743
1744 if (object_length - (data_start - block_start) - sizeof(blf_wlanframeheader_t) < wlanheader.frame_length) {
1745 *err = WTAP_ERR_BAD_FILE-13;
1746 *err_info = ws_strdup("blf: WLAN_FRAME: frame too short")wmem_strdup(((void*)0), "blf: WLAN_FRAME: frame too short");
1747 ws_debug("frame too short")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1747, __func__, "frame too short"); } } while (0)
;
1748 return false0;
1749 }
1750
1751 ws_buffer_assure_space(&params->rec->data, wlanheader.frame_length);
1752
1753 if (!blf_read_bytes(params, data_start + sizeof(blf_wlanframeheader_t), ws_buffer_end_ptr(&params->rec->data), wlanheader.frame_length, err, err_info)) {
1754 ws_debug("copying wlan frame failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1754, __func__, "copying wlan frame failed"); } } while (0)
;
1755 return false0;
1756 }
1757 ws_buffer_increase_length(&params->rec->data, wlanheader.frame_length);
1758
1759 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_IEEE_802_1120, wlanheader.channel, UINT16_MAX(65535), wlanheader.frame_length, wlanheader.frame_length);
1760 blf_add_direction_option(params, wlanheader.direction);
1761
1762 return true1;
1763}
1764
1765static const uint8_t can_dlc_to_length[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8 };
1766static const uint8_t canfd_dlc_to_length[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64 };
1767
1768static bool_Bool
1769blf_can_fill_buf_and_rec(blf_params_t *params, int *err, char **err_info, uint32_t canid, uint8_t payload_length, uint8_t payload_length_valid, uint64_t start_position,
1770 uint32_t flags, uint64_t object_timestamp, uint16_t channel, uint8_t canfd_flags) {
1771 uint8_t tmpbuf[8];
1772 unsigned caplen, len;
1773
1774 phtonu32(tmpbuf, canid);
1775 tmpbuf[4] = payload_length;
1776 tmpbuf[5] = canfd_flags;
1777 tmpbuf[6] = 0;
1778 tmpbuf[7] = 0;
1779
1780 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length_valid);
1781 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
1782 caplen = sizeof(tmpbuf) + payload_length_valid;
1783 len = sizeof(tmpbuf) + payload_length;
1784
1785 if (payload_length_valid > 0 && !blf_read_bytes(params, start_position, ws_buffer_end_ptr(&params->rec->data), payload_length_valid, err, err_info)) {
1786 ws_debug("copying can payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1786, __func__, "copying can payload failed"); } } while (0
)
;
1787 return false0;
1788 }
1789 ws_buffer_increase_length(&params->rec->data, payload_length_valid);
1790
1791 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, channel, UINT16_MAX(65535), caplen, len);
1792
1793 return true1;
1794}
1795
1796static bool_Bool
1797blf_read_canmessage(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, bool_Bool can_message2) {
1798 blf_canmessage_t canheader;
1799 blf_canmessage2_trailer_t can2trailer;
1800
1801 uint32_t canid;
1802 uint8_t payload_length;
1803
1804 /* The canheader is followed by 8 bytes, which need to be present! */
1805 if (object_length < (data_start - block_start) + (int) sizeof(canheader) + 8) {
1806 *err = WTAP_ERR_BAD_FILE-13;
1807 *err_info = ws_strdup_printf("blf: %s: not enough bytes for can header in object",wmem_strdup_printf(((void*)0), "blf: %s: not enough bytes for can header in object"
, can_message2 ? "CAN_MESSAGE2" : "CAN_MESSAGE")
1808 can_message2 ? "CAN_MESSAGE2" : "CAN_MESSAGE")wmem_strdup_printf(((void*)0), "blf: %s: not enough bytes for can header in object"
, can_message2 ? "CAN_MESSAGE2" : "CAN_MESSAGE")
;
1809 ws_debug("not enough bytes for can header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1809, __func__, "not enough bytes for can header in object"
); } } while (0)
;
1810 return false0;
1811 }
1812
1813 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
1814 ws_debug("not enough bytes for can header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1814, __func__, "not enough bytes for can header in file");
} } while (0)
;
1815 return false0;
1816 }
1817 fix_endianness_blf_canmessage(&canheader);
1818
1819 canheader.dlc &= 0x0f;
1820
1821 payload_length = canheader.dlc;
1822 if (payload_length > 8) {
1823 ws_debug("regular CAN tries more than 8 bytes? Cutting to 8.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1823, __func__, "regular CAN tries more than 8 bytes? Cutting to 8."
); } } while (0)
;
1824 payload_length = 8;
1825 }
1826
1827 canid = canheader.id;
1828
1829 if ((canheader.flags & BLF_CANMESSAGE_FLAG_RTR0x80) == BLF_CANMESSAGE_FLAG_RTR0x80) {
1830 canid |= CAN_RTR_FLAG0x40000000;
1831 payload_length = 0;
1832 }
1833
1834 if (!blf_can_fill_buf_and_rec(params, err, err_info, canid, payload_length, payload_length, data_start + sizeof(canheader), flags, object_timestamp, canheader.channel, 0)) {
1835 return false0;
1836 }
1837
1838 /* actually, we do not really need the data, right now.... */
1839 if (can_message2) {
1840 if (object_length < (data_start - block_start) + (int) sizeof(canheader) + 8 + (int) sizeof(can2trailer)) {
1841 *err = WTAP_ERR_BAD_FILE-13;
1842 *err_info = ws_strdup("blf: CAN_MESSAGE2: not enough bytes for can message 2 trailer")wmem_strdup(((void*)0), "blf: CAN_MESSAGE2: not enough bytes for can message 2 trailer"
)
;
1843 ws_debug("not enough bytes for can message 2 trailer")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1843, __func__, "not enough bytes for can message 2 trailer"
); } } while (0)
;
1844 return false0;
1845 }
1846 if (!blf_read_bytes(params, data_start + sizeof(canheader) + 8, &can2trailer, sizeof(can2trailer), err, err_info)) {
1847 ws_debug("not enough bytes for can message 2 trailer in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1847, __func__, "not enough bytes for can message 2 trailer in file"
); } } while (0)
;
1848 return false0;
1849 }
1850 fix_endianness_blf_canmessage2_trailer(&can2trailer);
1851 }
1852
1853 blf_add_direction_option(params, (canheader.flags & BLF_CANMESSAGE_FLAG_TX0x01) == BLF_CANMESSAGE_FLAG_TX0x01 ? BLF_DIR_TX1: BLF_DIR_RX0);
1854
1855 return true1;
1856}
1857
1858static bool_Bool
1859blf_read_canfdmessage(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
1860 blf_canfdmessage_t canheader;
1861
1862 bool_Bool canfd;
1863 uint32_t canid;
1864 uint8_t payload_length;
1865 uint8_t payload_length_valid;
1866 uint8_t canfd_flags;
1867
1868 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
1869 *err = WTAP_ERR_BAD_FILE-13;
1870 *err_info = ws_strdup("blf: CAN_FD_MESSAGE: not enough bytes for canfd header in object")wmem_strdup(((void*)0), "blf: CAN_FD_MESSAGE: not enough bytes for canfd header in object"
)
;
1871 ws_debug("not enough bytes for canfd header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1871, __func__, "not enough bytes for canfd header in object"
); } } while (0)
;
1872 return false0;
1873 }
1874
1875 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
1876 ws_debug("not enough bytes for canfd header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1876, __func__, "not enough bytes for canfd header in file"
); } } while (0)
;
1877 return false0;
1878 }
1879 fix_endianness_blf_canfdmessage(&canheader);
1880
1881 canheader.dlc &= 0x0f;
1882
1883 canfd = (canheader.canfdflags & BLF_CANFDMESSAGE_CANFDFLAG_EDL0x01) == BLF_CANFDMESSAGE_CANFDFLAG_EDL0x01;
1884 if (canfd) {
1885 payload_length = canfd_dlc_to_length[canheader.dlc];
1886 canfd_flags = (canheader.canfdflags & BLF_CANFDMESSAGE_CANFDFLAG_EDL0x01) << 2 | (canheader.canfdflags & BLF_CANFDMESSAGE_CANFDFLAG_ESI0x04) >> 1 | (canheader.canfdflags & BLF_CANFDMESSAGE_CANFDFLAG_BRS0x02) >> 1;
1887 } else {
1888 if (canheader.dlc > 8) {
1889 ws_debug("regular CAN tries more than 8 bytes?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1889, __func__, "regular CAN tries more than 8 bytes?"); } }
while (0)
;
1890 }
1891 payload_length = can_dlc_to_length[canheader.dlc];
1892 canfd_flags = 0;
1893 }
1894
1895 if (payload_length > canheader.validDataBytes) {
1896 ws_debug("shortening canfd payload because valid data bytes shorter.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1896, __func__, "shortening canfd payload because valid data bytes shorter."
); } } while (0)
;
1897 payload_length = canheader.validDataBytes;
1898 }
1899
1900 canid = canheader.id;
1901
1902 if (!canfd && (canheader.flags & BLF_CANMESSAGE_FLAG_RTR0x80) == BLF_CANMESSAGE_FLAG_RTR0x80) {
1903 canid |= CAN_RTR_FLAG0x40000000;
1904 payload_length = 0; /* Should already be zero from validDataBytes */
1905 }
1906
1907 payload_length_valid = payload_length;
1908
1909 if (payload_length_valid > object_length - (data_start - block_start) - sizeof(canheader)) {
1910 ws_debug("shortening can payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1910, __func__, "shortening can payload because buffer is too short."
); } } while (0)
;
1911 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - sizeof(canheader));
1912 }
1913
1914 if (!blf_can_fill_buf_and_rec(params, err, err_info, canid, payload_length, payload_length_valid, data_start + sizeof(canheader), flags, object_timestamp, canheader.channel, canfd_flags)) {
1915 return false0;
1916 }
1917
1918 blf_add_direction_option(params, (canheader.flags & BLF_CANMESSAGE_FLAG_TX0x01) == BLF_CANMESSAGE_FLAG_TX0x01 ? BLF_DIR_TX1 : BLF_DIR_RX0);
1919
1920 return true1;
1921}
1922
1923static bool_Bool
1924blf_read_canfdmessage64(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
1925 blf_canfdmessage64_t canheader;
1926
1927 bool_Bool canfd;
1928 uint32_t canid;
1929 uint8_t payload_length;
1930 uint8_t payload_length_valid;
1931 uint8_t canfd_flags;
1932
1933 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
1934 *err = WTAP_ERR_BAD_FILE-13;
1935 *err_info = ws_strdup("blf: CAN_FD_MESSAGE_64: not enough bytes for canfd header in object")wmem_strdup(((void*)0), "blf: CAN_FD_MESSAGE_64: not enough bytes for canfd header in object"
)
;
1936 ws_debug("not enough bytes for canfd header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1936, __func__, "not enough bytes for canfd header in object"
); } } while (0)
;
1937 return false0;
1938 }
1939
1940 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
1941 ws_debug("not enough bytes for canfd header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1941, __func__, "not enough bytes for canfd header in file"
); } } while (0)
;
1942 return false0;
1943 }
1944 fix_endianness_blf_canfdmessage64(&canheader);
1945
1946 canheader.dlc &= 0x0f;
1947
1948 canfd = (canheader.flags & BLF_CANFDMESSAGE64_FLAG_EDL0x001000) == BLF_CANFDMESSAGE64_FLAG_EDL0x001000;
1949 if (canfd) {
1950 payload_length = canfd_dlc_to_length[canheader.dlc];
1951 canfd_flags = (canheader.flags & BLF_CANFDMESSAGE64_FLAG_EDL0x001000) >> 10 | (canheader.flags & BLF_CANFDMESSAGE64_FLAG_ESI0x004000) >> 13 | (canheader.flags & BLF_CANFDMESSAGE64_FLAG_BRS0x002000) >> 13;
1952 } else {
1953 if (canheader.dlc > 8) {
1954 ws_debug("regular CAN tries more than 8 bytes?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1954, __func__, "regular CAN tries more than 8 bytes?"); } }
while (0)
;
1955 }
1956 payload_length = can_dlc_to_length[canheader.dlc];
1957 canfd_flags = 0;
1958 }
1959
1960 if (payload_length > canheader.validDataBytes) {
1961 ws_debug("shortening canfd payload because valid data bytes shorter.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1961, __func__, "shortening canfd payload because valid data bytes shorter."
); } } while (0)
;
1962 payload_length = canheader.validDataBytes;
1963 }
1964
1965 canid = canheader.id;
1966
1967 if (!canfd && (canheader.flags & BLF_CANFDMESSAGE64_FLAG_REMOTE_FRAME0x000010) == BLF_CANFDMESSAGE64_FLAG_REMOTE_FRAME0x000010) {
1968 canid |= CAN_RTR_FLAG0x40000000;
1969 payload_length = 0; /* Should already be zero from validDataBytes */
1970 }
1971
1972 payload_length_valid = payload_length;
1973
1974 if (payload_length_valid > object_length - (data_start - block_start) - sizeof(canheader)) {
1975 ws_debug("shortening can payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1975, __func__, "shortening can payload because buffer is too short."
); } } while (0)
;
1976 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - sizeof(canheader));
1977 }
1978
1979 if (!blf_can_fill_buf_and_rec(params, err, err_info, canid, payload_length, payload_length_valid, data_start + sizeof(canheader), flags, object_timestamp, canheader.channel, canfd_flags)) {
1980 return false0;
1981 }
1982
1983 blf_add_direction_option(params, canheader.dir);
1984
1985 return true1;
1986}
1987
1988static bool_Bool
1989blf_read_canerror(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, bool_Bool overload) {
1990 blf_canerror_t canheader;
1991 uint32_t canid;
1992 uint8_t payload_length;
1993 uint8_t tmpbuf[16] = {0};
1994
1995 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
1996 *err = WTAP_ERR_BAD_FILE-13;
1997 *err_info = ws_strdup("blf: CAN_ERROR: not enough bytes for canerror header in object")wmem_strdup(((void*)0), "blf: CAN_ERROR: not enough bytes for canerror header in object"
)
;
1998 ws_debug("not enough bytes for canerror header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1998, __func__, "not enough bytes for canerror header in object"
); } } while (0)
;
1999 return false0;
2000 }
2001
2002 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
2003 ws_debug("not enough bytes for canerror header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2003, __func__, "not enough bytes for canerror header in file"
); } } while (0)
;
2004 return false0;
2005 }
2006 fix_endianness_blf_canerror(&canheader);
2007
2008 // Set CAN_ERR_FLAG in unused bits of Can ID to indicate error in socketcan
2009 canid = CAN_ERR_FLAG0x20000000;
2010
2011 // Fixed packet data length for socketcan error messages
2012 payload_length = CAN_ERR_DLC8;
2013
2014 if (overload) {
2015 tmpbuf[10] = CAN_ERR_PROT_OVERLOAD0x20;
2016 canid |= CAN_ERR_PROT0x00000008U;
2017 }
2018
2019 phtonu32(tmpbuf, canid);
2020 tmpbuf[4] = payload_length;
2021
2022 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2023
2024 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, canheader.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2025 return true1;
2026}
2027
2028static bool_Bool
2029blf_read_canerrorext(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
2030 blf_canerrorext_t canheader;
2031
2032 bool_Bool err_ack = false0;
2033 bool_Bool err_prot = false0;
2034 bool_Bool direction_tx;
2035 uint32_t canid;
2036 uint8_t payload_length;
2037 uint8_t tmpbuf[16] = {0};
2038
2039 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
2040 *err = WTAP_ERR_BAD_FILE-13;
2041 *err_info = ws_strdup("blf: CAN_ERROR_EXT: not enough bytes for canerrorext header in object")wmem_strdup(((void*)0), "blf: CAN_ERROR_EXT: not enough bytes for canerrorext header in object"
)
;
2042 ws_debug("not enough bytes for canerrorext header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2042, __func__, "not enough bytes for canerrorext header in object"
); } } while (0)
;
2043 return false0;
2044 }
2045
2046 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
2047 ws_debug("not enough bytes for canerrorext header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2047, __func__, "not enough bytes for canerrorext header in file"
); } } while (0)
;
2048 return false0;
2049 }
2050 fix_endianness_blf_canerrorext(&canheader);
2051
2052 if (canheader.flags & BLF_CANERROREXT_FLAG_CANCORE0x02) {
2053 // Map Vector Can Core error codes to compareable socketcan errors
2054 switch ((canheader.errorCodeExt >> 6) & 0x3f) {
2055 case BLF_CANERROREXT_ECC_MEANING_BIT_ERROR0x0:
2056 err_prot = true1;
2057 tmpbuf[10] = CAN_ERR_PROT_BIT0x01;
2058 break;
2059 case BLF_CANERROREXT_ECC_MEANING_FORM_ERROR0x1:
2060 err_prot = true1;
2061 tmpbuf[10] = CAN_ERR_PROT_FORM0x02;
2062 break;
2063 case BLF_CANERROREXT_ECC_MEANING_STUFF_ERROR0x2:
2064 err_prot = true1;
2065 tmpbuf[10] = CAN_ERR_PROT_STUFF0x04;
2066 break;
2067 case BLF_CANERROREXT_ECC_MEANING_CRC_ERROR0x4:
2068 err_prot = true1;
2069 tmpbuf[11] = CAN_ERR_PROT_LOC_CRC_SEQ0x08;
2070 break;
2071 case BLF_CANERROREXT_ECC_MEANING_NACK_ERROR0x7:
2072 err_ack = true1;
2073 tmpbuf[11] = CAN_ERR_PROT_LOC_ACK0x19;
2074 break;
2075 case BLF_CANERROREXT_ECC_MEANING_OVERLOAD0x8:
2076 err_prot = true1;
2077 tmpbuf[10] = CAN_ERR_PROT_OVERLOAD0x20;
2078 break;
2079 default:
2080 err_prot = true1;
2081 tmpbuf[10] = CAN_ERR_PROT_UNSPEC0x00;
2082 break;
2083 }
2084 err_ack = err_ack || (canheader.errorCodeExt & BLF_CANERROREXT_EXTECC_NOT_ACK0x2000) == 0x0;
2085 if (err_ack) {
2086 // Don't set protocol error on ack errors
2087 err_prot = false0;
2088 }
2089 }
2090
2091 // CanID contains error class in socketcan
2092 canid = CAN_ERR_FLAG0x20000000;
2093 canid |= err_prot ? CAN_ERR_PROT0x00000008U : 0;
2094 canid |= err_ack ? CAN_ERR_ACK0x00000020U : 0;
2095
2096 // Fixed packet data length for socketcan error messages
2097 payload_length = CAN_ERR_DLC8;
2098 canheader.dlc = payload_length;
2099
2100 phtonu32(tmpbuf, canid);
2101 tmpbuf[4] = payload_length;
2102
2103 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2104
2105 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, canheader.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2106 if (canheader.flags & BLF_CANERROREXT_FLAG_CANCORE0x02) {
2107 direction_tx = (canheader.errorCodeExt & BLF_CANERROREXT_EXTECC_TX0x1000) == BLF_CANERROREXT_EXTECC_TX0x1000;
2108 blf_add_direction_option(params, direction_tx ? BLF_DIR_TX1: BLF_DIR_RX0);
2109 }
2110 return true1;
2111}
2112
2113static bool_Bool
2114blf_read_canfderror64(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
2115 blf_canfderror64_t canheader;
2116
2117 bool_Bool err_ack = false0;
2118 bool_Bool err_prot = false0;
2119 bool_Bool direction_tx;
2120 uint32_t canid;
2121 uint8_t payload_length;
2122 uint8_t tmpbuf[16] = {0};
2123
2124 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
2125 *err = WTAP_ERR_BAD_FILE-13;
2126 *err_info = ws_strdup("blf: CAN_FD_ERROR_64: not enough bytes for canfderror header in object")wmem_strdup(((void*)0), "blf: CAN_FD_ERROR_64: not enough bytes for canfderror header in object"
)
;
2127 ws_debug("not enough bytes for canfderror header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2127, __func__, "not enough bytes for canfderror header in object"
); } } while (0)
;
2128 return false0;
2129 }
2130
2131 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
2132 ws_debug("not enough bytes for canfderror header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2132, __func__, "not enough bytes for canfderror header in file"
); } } while (0)
;
2133 return false0;
2134 }
2135 fix_endianness_blf_canfderror64(&canheader);
2136
2137 if (canheader.flags & BLF_CANERROREXT_FLAG_CANCORE0x02) {
2138 // Map Vector Can Core error codes to compareable socketcan errors
2139 switch ((canheader.errorCodeExt >> 6) & 0x3f) {
2140 case BLF_CANERROREXT_ECC_MEANING_BIT_ERROR0x0:
2141 err_prot = true1;
2142 tmpbuf[10] = CAN_ERR_PROT_BIT0x01;
2143 break;
2144 case BLF_CANERROREXT_ECC_MEANING_FORM_ERROR0x1:
2145 err_prot = true1;
2146 tmpbuf[10] = CAN_ERR_PROT_FORM0x02;
2147 break;
2148 case BLF_CANERROREXT_ECC_MEANING_STUFF_ERROR0x2:
2149 err_prot = true1;
2150 tmpbuf[10] = CAN_ERR_PROT_STUFF0x04;
2151 break;
2152 case BLF_CANERROREXT_ECC_MEANING_CRC_ERROR0x4:
2153 err_prot = true1;
2154 tmpbuf[11] = CAN_ERR_PROT_LOC_CRC_SEQ0x08;
2155 break;
2156 case BLF_CANERROREXT_ECC_MEANING_NACK_ERROR0x7:
2157 err_ack = true1;
2158 tmpbuf[11] = CAN_ERR_PROT_LOC_ACK0x19;
2159 break;
2160 case BLF_CANERROREXT_ECC_MEANING_OVERLOAD0x8:
2161 err_prot = true1;
2162 tmpbuf[10] = CAN_ERR_PROT_OVERLOAD0x20;
2163 break;
2164 default:
2165 err_prot = true1;
2166 tmpbuf[10] = CAN_ERR_PROT_UNSPEC0x00;
2167 break;
2168 }
2169 err_ack = err_ack || (canheader.errorCodeExt & BLF_CANERROREXT_EXTECC_NOT_ACK0x2000) == 0x0;
2170 if (err_ack) {
2171 // Don't set protocol error on ack errors
2172 err_prot = false0;
2173 }
2174 }
2175
2176 // CanID contains error class in socketcan
2177 canid = CAN_ERR_FLAG0x20000000;
2178 canid |= err_prot ? CAN_ERR_PROT0x00000008U : 0;
2179 canid |= err_ack ? CAN_ERR_ACK0x00000020U : 0;
2180
2181 // Fixed packet data length for socketcan error messages
2182 payload_length = CAN_ERR_DLC8;
2183 canheader.dlc = payload_length;
2184
2185 phtonu32(tmpbuf, canid);
2186 tmpbuf[4] = payload_length;
2187 // Don't set FDF, ESI and BRS flags, since error messages are always encapsulated in Classic CAN frames
2188
2189 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2190
2191 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, canheader.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2192 if (canheader.flags & BLF_CANERROREXT_FLAG_CANCORE0x02) {
2193 direction_tx = (canheader.errorCodeExt & BLF_CANERROREXT_EXTECC_TX0x1000) == BLF_CANERROREXT_EXTECC_TX0x1000;
2194 blf_add_direction_option(params, direction_tx ? BLF_DIR_TX1: BLF_DIR_RX0);
2195 }
2196 return true1;
2197}
2198
2199static bool_Bool
2200blf_read_canxlchannelframe(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
2201 blf_canxlchannelframe_t canxlheader;
2202
2203 if (object_length < (data_start - block_start) + (int)sizeof(canxlheader)) {
2204 *err = WTAP_ERR_BAD_FILE-13;
2205 *err_info = ws_strdup("blf: CAN_XL_CHANNEL_HEADER: not enough bytes for canxlchannelframe header in object")wmem_strdup(((void*)0), "blf: CAN_XL_CHANNEL_HEADER: not enough bytes for canxlchannelframe header in object"
)
;
2206 ws_debug("not enough bytes for canxlchannelframe header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2206, __func__, "not enough bytes for canxlchannelframe header in object"
); } } while (0)
;
2207 return false0;
2208 }
2209
2210 if (!blf_read_bytes(params, data_start, &canxlheader, sizeof(canxlheader), err, err_info)) {
2211 ws_debug("not enough bytes for canxlchannelframe header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2211, __func__, "not enough bytes for canxlchannelframe header in file"
); } } while (0)
;
2212 return false0;
2213 }
2214 fix_endianness_blf_canxlchannelframe(&canxlheader);
2215
2216 uint16_t payload_length = canxlheader.dataLength;
2217 bool_Bool is_canxl = canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000;
2218
2219 if (is_canxl) {
2220 uint16_t canid = canxlheader.frameIdentifier & CAN_SFF_MASK0x000007FF;
2221
2222 uint8_t canxl_flags = 0;
2223 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000) == BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000) {
2224 canxl_flags |= CANXL_XLF0x80;
2225 }
2226
2227 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_SEC0x1000000) == BLF_CANXLCHANNELFRAME_FLAG_SEC0x1000000) {
2228 canxl_flags |= CANXL_SEC0x01;
2229 }
2230
2231 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_RRS0x800000) == BLF_CANXLCHANNELFRAME_FLAG_RRS0x800000) {
2232 canxl_flags |= CANXL_RRS0x02;
2233 }
2234
2235 uint8_t tmpbuf[12] = { 0 };
2236 tmpbuf[1] = canxlheader.virtualControllerAreaNetChannelID;
2237 phtonu16(tmpbuf + 2, canid);
2238 tmpbuf[4] = canxl_flags;
2239 tmpbuf[5] = canxlheader.serviceDataUnitType;
2240 phtoleu16(tmpbuf + 6, payload_length);
2241 phtoleu32(tmpbuf + 8, canxlheader.acceptanceField);
2242
2243 if (object_length < (data_start - block_start) + (int)sizeof(canxlheader) + payload_length) {
2244 *err = WTAP_ERR_BAD_FILE-13;
2245 *err_info = ws_strdup("blf: CAN_XL_CHANNEL_HEADER: not enough bytes for canxl payload in object")wmem_strdup(((void*)0), "blf: CAN_XL_CHANNEL_HEADER: not enough bytes for canxl payload in object"
)
;
2246 ws_debug("not enough bytes for canxl payload in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2246, __func__, "not enough bytes for canxl payload in object"
); } } while (0)
;
2247 return false0;
2248 }
2249
2250 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length);
2251 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2252
2253 if (payload_length > 0 && !blf_read_bytes(params, data_start + sizeof(blf_canxlchannelframe_t), ws_buffer_end_ptr(&params->rec->data), payload_length, err, err_info)) {
2254 ws_debug("copying canxl payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2254, __func__, "copying canxl payload failed"); } } while (
0)
;
2255 return false0;
2256 }
2257 ws_buffer_increase_length(&params->rec->data, payload_length);
2258
2259 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, canxlheader.channel, UINT16_MAX(65535), sizeof(tmpbuf) + payload_length, sizeof(tmpbuf) + payload_length);
2260 } else {
2261 // Support for CAN or CAN-FD in CAN-XL Channel Frame format is experimental as of 2025!
2262 // If you have samples traces, please create a ticket and attach them to it: https://gitlab.com/wireshark/wireshark/-/issues
2263
2264 bool_Bool canfd = canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_FDF0x1000;
2265 uint8_t canfd_flags = 0;
2266
2267 if (object_length < (data_start - block_start) + (int)sizeof(canxlheader) + payload_length) {
2268 ws_debug("shortening canxl for can/canfd payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2268, __func__, "shortening canxl for can/canfd payload because buffer is too short."
); } } while (0)
;
2269 object_length = (data_start - block_start) + (int)sizeof(canxlheader) + payload_length;
Value stored to 'object_length' is never read
2270 }
2271
2272 if (canfd) {
2273 if (payload_length > 64) {
2274 ws_debug("CANFD should not have payload_length > 64. Shortening!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2274, __func__, "CANFD should not have payload_length > 64. Shortening!"
); } } while (0)
;
2275 payload_length = 64;
2276 }
2277
2278 if (canxlheader.dlc > 0x0f) {
2279 ws_debug("CANFD should not have DLC > 0x0f.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2279, __func__, "CANFD should not have DLC > 0x0f."); } }
while (0)
;
2280 } else if (payload_length > canfd_dlc_to_length[canxlheader.dlc]) {
2281 ws_debug("CANFD payload_length and DLC not compatible!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2281, __func__, "CANFD payload_length and DLC not compatible!"
); } } while (0)
;
2282 }
2283
2284
2285 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_BRS0x2000) == BLF_CANXLCHANNELFRAME_FLAG_BRS0x2000) {
2286 canfd_flags |= CANFD_BRS0x01;
2287 }
2288 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_ESI0x4000) == BLF_CANXLCHANNELFRAME_FLAG_ESI0x4000) {
2289 canfd_flags |= CANFD_ESI0x02;
2290 }
2291 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_FDF0x1000) == BLF_CANXLCHANNELFRAME_FLAG_FDF0x1000) {
2292 canfd_flags |= CANFD_FDF0x04;
2293 }
2294 } else {
2295 if (payload_length > 8) {
2296 ws_debug("Regular CAN should not have payload_length > 8. Shortening!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2296, __func__, "Regular CAN should not have payload_length > 8. Shortening!"
); } } while (0)
;
2297 payload_length = 8;
2298 }
2299
2300 if (canxlheader.dlc > 8) {
2301 ws_debug("Regular CAN should not have DLC > 8.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2301, __func__, "Regular CAN should not have DLC > 8.");
} } while (0)
;
2302 } else if (payload_length != canxlheader.dlc) {
2303 ws_debug("CAN payload_length and DLC not compatible!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2303, __func__, "CAN payload_length and DLC not compatible!"
); } } while (0)
;
2304 }
2305
2306 canfd_flags = 0;
2307 }
2308
2309 uint32_t canid = canxlheader.frameIdentifier;
2310
2311 /* Unclear how to reconstruct the EFF Flag. Let's make sure, we set it if the ID is more than 11 bits */
2312 if ((canid & CAN_EFF_MASK0x1FFFFFFF) > CAN_SFF_MASK0x000007FF) {
2313 canid |= CAN_EFF_FLAG0x80000000;
2314 }
2315
2316 if (!canfd && (canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_REMOTE_FRAME0x10) == BLF_CANXLCHANNELFRAME_FLAG_REMOTE_FRAME0x10) {
2317 canid |= CAN_RTR_FLAG0x40000000;
2318 payload_length = 0;
2319 }
2320
2321 if (!blf_can_fill_buf_and_rec(params, err, err_info, canid, (uint8_t)payload_length, (uint8_t)payload_length, data_start + sizeof(canxlheader), flags, object_timestamp, canxlheader.channel, canfd_flags)) {
2322 return false0;
2323 }
2324 }
2325
2326 blf_add_direction_option(params, canxlheader.dir ? BLF_DIR_TX1 : BLF_DIR_RX0);
2327
2328 return true1;
2329}
2330
2331static bool_Bool
2332blf_read_flexraydata(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
2333 blf_flexraydata_t frheader;
2334
2335 uint8_t payload_length;
2336 uint8_t payload_length_valid;
2337 uint8_t tmpbuf[7];
2338 unsigned caplen, len;
2339
2340 if (object_length < (data_start - block_start) + (int) sizeof(frheader)) {
2341 *err = WTAP_ERR_BAD_FILE-13;
2342 *err_info = ws_strdup("blf: FLEXRAY_DATA: not enough bytes for flexrayheader in object")wmem_strdup(((void*)0), "blf: FLEXRAY_DATA: not enough bytes for flexrayheader in object"
)
;
2343 ws_debug("not enough bytes for flexrayheader in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2343, __func__, "not enough bytes for flexrayheader in object"
); } } while (0)
;
2344 return false0;
2345 }
2346
2347 if (!blf_read_bytes(params, data_start, &frheader, sizeof(frheader), err, err_info)) {
2348 ws_debug("not enough bytes for flexrayheader header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2348, __func__, "not enough bytes for flexrayheader header in file"
); } } while (0)
;
2349 return false0;
2350 }
2351 fix_endianness_blf_flexraydata(&frheader);
2352
2353 payload_length = frheader.len;
2354 payload_length_valid = payload_length;
2355
2356 if ((frheader.len & 0x01) == 0x01) {
2357 ws_debug("reading odd length in FlexRay!?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2357, __func__, "reading odd length in FlexRay!?"); } } while
(0)
;
2358 }
2359
2360 if (payload_length_valid > object_length - (data_start - block_start) - sizeof(frheader)) {
2361 ws_debug("shortening FlexRay payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2361, __func__, "shortening FlexRay payload because buffer is too short."
); } } while (0)
;
2362 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - sizeof(frheader));
2363 }
2364
2365 if (frheader.channel != 0 && frheader.channel != 1) {
2366 ws_debug("FlexRay supports only two channels.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2366, __func__, "FlexRay supports only two channels."); } }
while (0)
;
2367 }
2368
2369 /* Measurement Header */
2370 if (frheader.channel == 0) {
2371 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01;
2372 } else {
2373 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01 | BLF_FLEXRAYDATA_CHANNEL_B0x80;
2374 }
2375
2376 /* Error Flags */
2377 tmpbuf[1] = 0;
2378
2379 /* Frame Header */
2380 tmpbuf[2] = 0x20 | ((0x0700 & frheader.messageId) >> 8);
2381 tmpbuf[3] = 0x00ff & frheader.messageId;
2382 tmpbuf[4] = (0xfe & frheader.len) | ((frheader.crc & 0x0400) >> 10);
2383 tmpbuf[5] = (0x03fc & frheader.crc) >> 2;
2384 tmpbuf[6] = ((0x0003 & frheader.crc) << 6) | (0x3f & frheader.mux);
2385
2386 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length_valid);
2387 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2388 caplen = sizeof(tmpbuf) + payload_length_valid;
2389 len = sizeof(tmpbuf) + payload_length;
2390
2391 if (payload_length_valid > 0 && !blf_read_bytes(params, data_start + sizeof(frheader), ws_buffer_end_ptr(&params->rec->data), payload_length_valid, err, err_info)) {
2392 ws_debug("copying flexray payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2392, __func__, "copying flexray payload failed"); } } while
(0)
;
2393 return false0;
2394 }
2395 ws_buffer_increase_length(&params->rec->data, payload_length_valid);
2396
2397 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_FLEXRAY106, frheader.channel, UINT16_MAX(65535), caplen, len);
2398 blf_add_direction_option(params, frheader.dir);
2399
2400 return true1;
2401}
2402
2403static bool_Bool
2404blf_read_flexraymessage(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
2405 blf_flexraymessage_t frheader;
2406
2407 uint8_t payload_length;
2408 uint8_t payload_length_valid;
2409 uint8_t tmpbuf[7];
2410 unsigned caplen, len;
2411
2412 if (object_length < (data_start - block_start) + (int) sizeof(frheader)) {
2413 *err = WTAP_ERR_BAD_FILE-13;
2414 *err_info = ws_strdup("blf: FLEXRAY_MESSAGE: not enough bytes for flexrayheader in object")wmem_strdup(((void*)0), "blf: FLEXRAY_MESSAGE: not enough bytes for flexrayheader in object"
)
;
2415 ws_debug("not enough bytes for flexrayheader in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2415, __func__, "not enough bytes for flexrayheader in object"
); } } while (0)
;
2416 return false0;
2417 }
2418
2419 if (!blf_read_bytes(params, data_start, &frheader, sizeof(frheader), err, err_info)) {
2420 ws_debug("not enough bytes for flexrayheader header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2420, __func__, "not enough bytes for flexrayheader header in file"
); } } while (0)
;
2421 return false0;
2422 }
2423 fix_endianness_blf_flexraymessage(&frheader);
2424
2425 payload_length = frheader.length;
2426 payload_length_valid = payload_length;
2427
2428 if ((frheader.length & 0x01) == 0x01) {
2429 ws_debug("reading odd length in FlexRay!?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2429, __func__, "reading odd length in FlexRay!?"); } } while
(0)
;
2430 }
2431
2432 if (payload_length_valid > object_length - (data_start - block_start) - sizeof(frheader)) {
2433 ws_debug("shortening FlexRay payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2433, __func__, "shortening FlexRay payload because buffer is too short."
); } } while (0)
;
2434 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - sizeof(frheader));
2435 }
2436
2437 if (frheader.channel != 0 && frheader.channel != 1) {
2438 ws_debug("FlexRay supports only two channels.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2438, __func__, "FlexRay supports only two channels."); } }
while (0)
;
2439 }
2440
2441 /* Measurement Header */
2442 if (frheader.channel == 0) {
2443 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01;
2444 } else {
2445 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01 | BLF_FLEXRAYDATA_CHANNEL_B0x80;
2446 }
2447
2448 /* Error Flags */
2449 tmpbuf[1] = 0;
2450
2451 /* Frame Header */
2452 tmpbuf[2] = ((0x0700 & frheader.frameId) >> 8);
2453 if ((frheader.frameState & BLF_FLEXRAYMESSAGE_STATE_PPI0x01) == BLF_FLEXRAYMESSAGE_STATE_PPI0x01) {
2454 tmpbuf[2] |= BLF_DLT_FLEXRAY_PPI0x40;
2455 }
2456
2457 if ((frheader.frameState & BLF_FLEXRAYMESSAGE_STATE_SFI0x02) == BLF_FLEXRAYMESSAGE_STATE_SFI0x02) {
2458 tmpbuf[2] |= BLF_DLT_FLEXRAY_SFI0x10;
2459 }
2460
2461 if ((frheader.frameState & BLF_FLEXRAYMESSAGE_STATE_NFI0x08) != BLF_FLEXRAYMESSAGE_STATE_NFI0x08) {
2462 /* NFI needs to be inversed !? */
2463 tmpbuf[2] |= BLF_DLT_FLEXRAY_NFI0x20;
2464 }
2465
2466 if ((frheader.frameState & BLF_FLEXRAYMESSAGE_STATE_STFI0x10) == BLF_FLEXRAYMESSAGE_STATE_STFI0x10) {
2467 tmpbuf[2] |= BLF_DLT_FLEXRAY_STFI0x08;
2468 }
2469
2470 tmpbuf[3] = 0x00ff & frheader.frameId;
2471 tmpbuf[4] = (0xfe & frheader.length) | ((frheader.headerCrc & 0x0400) >> 10);
2472 tmpbuf[5] = (0x03fc & frheader.headerCrc) >> 2;
2473 tmpbuf[6] = ((0x0003 & frheader.headerCrc) << 6) | (0x3f & frheader.cycle);
2474
2475 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length_valid);
2476 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2477 caplen = sizeof(tmpbuf) + payload_length_valid;
2478 len = sizeof(tmpbuf) + payload_length;
2479
2480 if (payload_length_valid > 0 && !blf_read_bytes(params, data_start + sizeof(frheader), ws_buffer_end_ptr(&params->rec->data), payload_length_valid, err, err_info)) {
2481 ws_debug("copying flexray payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2481, __func__, "copying flexray payload failed"); } } while
(0)
;
2482 return false0;
2483 }
2484 ws_buffer_increase_length(&params->rec->data, payload_length_valid);
2485
2486 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_FLEXRAY106, frheader.channel, UINT16_MAX(65535), caplen, len);
2487 blf_add_direction_option(params, frheader.dir);
2488
2489 return true1;
2490}
2491
2492static bool_Bool
2493blf_read_flexrayrcvmessageex(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, bool_Bool ext) {
2494 blf_flexrayrcvmessage_t frheader;
2495
2496 uint16_t payload_length;
2497 uint16_t payload_length_valid;
2498 uint8_t tmpbuf[7];
2499 int frheadersize = sizeof(frheader);
2500 unsigned caplen, len;
2501
2502 if (ext) {
2503 frheadersize += 40;
2504 }
2505
2506 if ((int64_t)object_length < (data_start - block_start) + frheadersize) {
2507 *err = WTAP_ERR_BAD_FILE-13;
2508 *err_info = ws_strdup_printf("blf: %s: not enough bytes for flexrayheader in object",wmem_strdup_printf(((void*)0), "blf: %s: not enough bytes for flexrayheader in object"
, ext ? "FLEXRAY_RCVMESSAGE_EX" : "FLEXRAY_RCVMESSAGE")
2509 ext ? "FLEXRAY_RCVMESSAGE_EX" : "FLEXRAY_RCVMESSAGE")wmem_strdup_printf(((void*)0), "blf: %s: not enough bytes for flexrayheader in object"
, ext ? "FLEXRAY_RCVMESSAGE_EX" : "FLEXRAY_RCVMESSAGE")
;
2510 ws_debug("not enough bytes for flexrayheader in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2510, __func__, "not enough bytes for flexrayheader in object"
); } } while (0)
;
2511 return false0;
2512 }
2513
2514 if (!blf_read_bytes(params, data_start, &frheader, sizeof(frheader), err, err_info)) {
2515 ws_debug("not enough bytes for flexrayheader header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2515, __func__, "not enough bytes for flexrayheader header in file"
); } } while (0)
;
2516 return false0;
2517 }
2518 fix_endianness_blf_flexrayrcvmessage(&frheader);
2519
2520 if (!ext) {
2521 frheader.dir &= 0xff;
2522 frheader.cycle &= 0xff;
2523 }
2524
2525 payload_length = frheader.payloadLength;
2526 payload_length_valid = frheader.payloadLengthValid;
2527
2528 if ((frheader.payloadLength & 0x01) == 0x01) {
2529 ws_debug("reading odd length in FlexRay!?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2529, __func__, "reading odd length in FlexRay!?"); } } while
(0)
;
2530 }
2531
2532 if (payload_length_valid > object_length - (data_start - block_start) - frheadersize) {
2533 ws_debug("shortening FlexRay payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2533, __func__, "shortening FlexRay payload because buffer is too short."
); } } while (0)
;
2534 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - frheadersize);
2535 }
2536
2537 /* Measurement Header */
2538 /* TODO: It seems that this format support both channels at the same time!? */
2539 if (frheader.channelMask == BLF_FLEXRAYRCVMSG_CHANNELMASK_A0x01) {
2540 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01;
2541 } else {
2542 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01 | BLF_FLEXRAYDATA_CHANNEL_B0x80;
2543 }
2544
2545 /* Error Flags */
2546 tmpbuf[1] = 0;
2547
2548 /* Frame Header */
2549 tmpbuf[2] = ((0x0700 & frheader.frameId) >> 8);
2550 if ((frheader.frameFlags & BLF_FLEXRAYRCVMSG_FRAME_FLAG_PAYLOAD_PREAM0x00000010) == BLF_FLEXRAYRCVMSG_FRAME_FLAG_PAYLOAD_PREAM0x00000010) {
2551 tmpbuf[2] |= BLF_DLT_FLEXRAY_PPI0x40;
2552 }
2553
2554 if ((frheader.frameFlags & BLF_FLEXRAYRCVMSG_FRAME_FLAG_SYNC0x00000004) == BLF_FLEXRAYRCVMSG_FRAME_FLAG_SYNC0x00000004) {
2555 tmpbuf[2] |= BLF_DLT_FLEXRAY_SFI0x10;
2556 }
2557
2558 if ((frheader.frameFlags & BLF_FLEXRAYRCVMSG_FRAME_FLAG_NULL_FRAME0x00000001) != BLF_FLEXRAYRCVMSG_FRAME_FLAG_NULL_FRAME0x00000001) {
2559 /* NFI needs to be inversed !? */
2560 tmpbuf[2] |= BLF_DLT_FLEXRAY_NFI0x20;
2561 }
2562
2563 if ((frheader.frameFlags & BLF_FLEXRAYRCVMSG_FRAME_FLAG_STARTUP0x00000008) == BLF_FLEXRAYRCVMSG_FRAME_FLAG_STARTUP0x00000008) {
2564 tmpbuf[2] |= BLF_DLT_FLEXRAY_STFI0x08;
2565 }
2566
2567 tmpbuf[3] = 0x00ff & frheader.frameId;
2568 tmpbuf[4] = (0xfe & frheader.payloadLength) | ((frheader.headerCrc1 & 0x0400) >> 10);
2569 tmpbuf[5] = (0x03fc & frheader.headerCrc1) >> 2;
2570 tmpbuf[6] = ((0x0003 & frheader.headerCrc1) << 6) | (0x3f & frheader.cycle);
2571
2572 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length_valid);
2573 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2574 caplen = sizeof(tmpbuf) + payload_length_valid;
2575 len = sizeof(tmpbuf) + payload_length;
2576
2577 if (payload_length_valid > 0 && !blf_read_bytes(params, data_start + frheadersize, ws_buffer_end_ptr(&params->rec->data), payload_length_valid, err, err_info)) {
2578 ws_debug("copying flexray payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2578, __func__, "copying flexray payload failed"); } } while
(0)
;
2579 return false0;
2580 }
2581 ws_buffer_increase_length(&params->rec->data, payload_length_valid);
2582
2583 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_FLEXRAY106, frheader.channelMask, UINT16_MAX(65535), caplen, len);
2584 blf_add_direction_option(params, frheader.dir);
2585
2586 return true1;
2587}
2588
2589static bool_Bool
2590blf_read_linmessage(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, bool_Bool crc_error) {
2591 blf_linmessage_t linmessage;
2592
2593 uint8_t payload_length;
2594 unsigned len;
2595
2596 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2597 *err = WTAP_ERR_BAD_FILE-13;
2598 *err_info = ws_strdup_printf("blf: %s: not enough bytes for %s in object", crc_error ? "LIN_CRC_ERROR" : "LIN_MESSAGE", crc_error ? "lincrcerror" : "linmessage")wmem_strdup_printf(((void*)0), "blf: %s: not enough bytes for %s in object"
, crc_error ? "LIN_CRC_ERROR" : "LIN_MESSAGE", crc_error ? "lincrcerror"
: "linmessage")
;
2599 ws_debug("not enough bytes for %s in object", crc_error ? "lincrcerror" : "linmessage")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2599, __func__, "not enough bytes for %s in object", crc_error
? "lincrcerror" : "linmessage"); } } while (0)
;
2600 return false0;
2601 }
2602
2603 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2604 ws_debug("not enough bytes for %s in file", crc_error ? "lincrcerror" : "linmessage")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2604, __func__, "not enough bytes for %s in file", crc_error
? "lincrcerror" : "linmessage"); } } while (0)
;
2605 return false0;
2606 }
2607 fix_endianness_blf_linmessage(&linmessage);
2608
2609 linmessage.dlc &= 0x0f;
2610 linmessage.id &= 0x3f;
2611
2612 payload_length = MIN(linmessage.dlc, 8)(((linmessage.dlc) < (8)) ? (linmessage.dlc) : (8));
2613
2614 uint8_t tmpbuf[8];
2615 tmpbuf[0] = 1; /* message format rev = 1 */
2616 tmpbuf[1] = 0; /* reserved */
2617 tmpbuf[2] = 0; /* reserved */
2618 tmpbuf[3] = 0; /* reserved */
2619 tmpbuf[4] = linmessage.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2620 tmpbuf[5] = linmessage.id; /* parity (2bit) | id (6bit) */
2621 tmpbuf[6] = (uint8_t)(linmessage.crc & 0xff); /* checksum */
2622 tmpbuf[7] = 0; /* errors */
2623
2624 if (crc_error) {
2625 tmpbuf[7] |= 0x08;
2626 }
2627
2628 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2629 ws_buffer_append(&params->rec->data, linmessage.data, payload_length);
2630 len = sizeof(tmpbuf) + payload_length;
2631
2632 /* make sure that the payload is 4 or 8 bytes long */
2633 const uint8_t padding[4] = { 0, 0, 0, 0 };
2634 if (payload_length < 4) {
2635 ws_buffer_append(&params->rec->data, padding, 4 - payload_length);
2636 len += 4 - payload_length;
2637 } else if (payload_length > 4 && payload_length < 8) {
2638 ws_buffer_append(&params->rec->data, padding, 8 - payload_length);
2639 len += 8 - payload_length;
2640 }
2641
2642 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.channel, UINT16_MAX(65535), len, len);
2643 blf_add_direction_option(params, linmessage.dir);
2644
2645 return true1;
2646}
2647
2648static bool_Bool
2649blf_read_linrcverror(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
2650 blf_linrcverror_t linmessage;
2651
2652 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2653 *err = WTAP_ERR_BAD_FILE-13;
2654 *err_info = ws_strdup("blf: LIN_RCV_ERROR: not enough bytes for linrcverror in object")wmem_strdup(((void*)0), "blf: LIN_RCV_ERROR: not enough bytes for linrcverror in object"
)
;
2655 ws_debug("not enough bytes for linrcverror in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2655, __func__, "not enough bytes for linrcverror in object"
); } } while (0)
;
2656 return false0;
2657 }
2658
2659 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2660 ws_debug("not enough bytes for linrcverror in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2660, __func__, "not enough bytes for linrcverror in file")
; } } while (0)
;
2661 return false0;
2662 }
2663 linmessage.channel = GUINT16_FROM_LE(linmessage.channel)(((guint16) (linmessage.channel)));
2664
2665 linmessage.dlc &= 0x0f;
2666 linmessage.id &= 0x3f;
2667
2668 uint8_t tmpbuf[12];
2669 tmpbuf[0] = 1; /* message format rev = 1 */
2670 tmpbuf[1] = 0; /* reserved */
2671 tmpbuf[2] = 0; /* reserved */
2672 tmpbuf[3] = 0; /* reserved */
2673 tmpbuf[4] = linmessage.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2674 tmpbuf[5] = linmessage.id; /* parity (2bit) | id (6bit) */
2675 tmpbuf[6] = 0; /* checksum */
2676 /* XXX - This object can represent many different error types.
2677 * For now we always treat it as framing error,
2678 * but in the future we should expand it. */
2679 tmpbuf[7] = LIN_ERROR_FRAMING_ERROR0x02; /* errors */
2680 tmpbuf[8] = 0;
2681 tmpbuf[9] = 0;
2682 tmpbuf[10] = 0;
2683 tmpbuf[11] = 0;
2684
2685 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2686 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2687
2688 return true1;
2689}
2690
2691static bool_Bool
2692blf_read_linsenderror(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
2693 blf_linsenderror_t linmessage;
2694
2695 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2696 *err = WTAP_ERR_BAD_FILE-13;
2697 *err_info = ws_strdup("blf: LIN_SND_ERROR: not enough bytes for linsenderror in object")wmem_strdup(((void*)0), "blf: LIN_SND_ERROR: not enough bytes for linsenderror in object"
)
;
2698 ws_debug("not enough bytes for linsenderror in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2698, __func__, "not enough bytes for linsenderror in object"
); } } while (0)
;
2699 return false0;
2700 }
2701
2702 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2703 ws_debug("not enough bytes for linsenderror in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2703, __func__, "not enough bytes for linsenderror in file"
); } } while (0)
;
2704 return false0;
2705 }
2706 linmessage.channel = GUINT16_FROM_LE(linmessage.channel)(((guint16) (linmessage.channel)));
2707
2708 linmessage.dlc &= 0x0f;
2709 linmessage.id &= 0x3f;
2710
2711 uint8_t tmpbuf[12];
2712 tmpbuf[0] = 1; /* message format rev = 1 */
2713 tmpbuf[1] = 0; /* reserved */
2714 tmpbuf[2] = 0; /* reserved */
2715 tmpbuf[3] = 0; /* reserved */
2716 tmpbuf[4] = linmessage.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2717 tmpbuf[5] = linmessage.id; /* parity (2bit) | id (6bit) */
2718 tmpbuf[6] = 0; /* checksum */
2719 tmpbuf[7] = LIN_ERROR_NO_SLAVE_RESPONSE0x01; /* errors */
2720 tmpbuf[8] = 0;
2721 tmpbuf[9] = 0;
2722 tmpbuf[10] = 0;
2723 tmpbuf[11] = 0;
2724
2725 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2726 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2727
2728 return true1;
2729}
2730
2731static bool_Bool
2732blf_read_linwakeupevent(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
2733 blf_linwakeupevent_t linevent;
2734
2735 if (object_length < (data_start - block_start) + (int)sizeof(linevent)) {
2736 *err = WTAP_ERR_BAD_FILE-13;
2737 *err_info = ws_strdup("blf: LIN_WAKEUP: not enough bytes for linwakeup in object")wmem_strdup(((void*)0), "blf: LIN_WAKEUP: not enough bytes for linwakeup in object"
)
;
2738 ws_debug("not enough bytes for linwakeup in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2738, __func__, "not enough bytes for linwakeup in object")
; } } while (0)
;
2739 return false0;
2740 }
2741
2742 if (!blf_read_bytes(params, data_start, &linevent, sizeof(linevent), err, err_info)) {
2743 ws_debug("not enough bytes for linwakeup in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2743, __func__, "not enough bytes for linwakeup in file"); }
} while (0)
;
2744 return false0;
2745 }
2746 linevent.channel = GUINT16_FROM_LE(linevent.channel)(((guint16) (linevent.channel)));
2747
2748 uint8_t tmpbuf[12]; /* LIN events have a fixed length of 12 bytes */
2749 tmpbuf[0] = 1; /* message format rev = 1 */
2750 tmpbuf[1] = 0; /* reserved */
2751 tmpbuf[2] = 0; /* reserved */
2752 tmpbuf[3] = 0; /* reserved */
2753 tmpbuf[4] = 3 << 2; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2754 tmpbuf[5] = 0; /* parity (2bit) | id (6bit) */
2755 tmpbuf[6] = 0; /* checksum */
2756 tmpbuf[7] = 0; /* errors */
2757
2758 /* Wake-up event */
2759 tmpbuf[8] = 0xB0;
2760 tmpbuf[9] = 0xB0;
2761 tmpbuf[10] = 0x00;
2762 tmpbuf[11] = 0x04;
2763
2764 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2765
2766 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linevent.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2767
2768 return true1;
2769}
2770
2771static bool_Bool
2772blf_read_linmessage2(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, uint16_t object_version) {
2773 blf_linmessage2_t linmessage;
2774
2775 uint8_t payload_length;
2776 unsigned len;
2777
2778 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2779 *err = WTAP_ERR_BAD_FILE-13;
2780 *err_info = ws_strdup("blf: LIN_MESSAGE2: not enough bytes for linmessage2 in object")wmem_strdup(((void*)0), "blf: LIN_MESSAGE2: not enough bytes for linmessage2 in object"
)
;
2781 ws_debug("not enough bytes for linmessage2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2781, __func__, "not enough bytes for linmessage2 in object"
); } } while (0)
;
2782 return false0;
2783 }
2784
2785 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2786 ws_debug("not enough bytes for linmessage2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2786, __func__, "not enough bytes for linmessage2 in file")
; } } while (0)
;
2787 return false0;
2788 }
2789 fix_endianness_blf_linmessage2(&linmessage);
2790
2791 linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc &= 0x0f;
2792 linmessage.linDataByteTimestampEvent.linMessageDescriptor.id &= 0x3f;
2793
2794 payload_length = MIN(linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc, 8)(((linmessage.linDataByteTimestampEvent.linMessageDescriptor.
dlc) < (8)) ? (linmessage.linDataByteTimestampEvent.linMessageDescriptor
.dlc) : (8))
;
2795
2796 uint8_t tmpbuf[8];
2797 tmpbuf[0] = 1; /* message format rev = 1 */
2798 tmpbuf[1] = 0; /* reserved */
2799 tmpbuf[2] = 0; /* reserved */
2800 tmpbuf[3] = 0; /* reserved */
2801 tmpbuf[4] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2802 if (object_version >= 1) { /* The 'checksumModel' field is valid only if objectVersion >= 1 */
2803 switch (linmessage.linDataByteTimestampEvent.linMessageDescriptor.checksumModel) {
2804 case 0:
2805 tmpbuf[4] |= 1; /* Classic */
2806 break;
2807 case 1:
2808 tmpbuf[4] |= 2; /* Enhanced */
2809 break;
2810 default:
2811 break;
2812 }
2813 }
2814 tmpbuf[5] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.id; /* parity (2bit) | id (6bit) */
2815 tmpbuf[6] = (uint8_t)(linmessage.crc & 0xff); /* checksum */
2816 tmpbuf[7] = 0; /* errors */
2817
2818 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2819 ws_buffer_append(&params->rec->data, linmessage.data, payload_length);
2820 len = sizeof(tmpbuf) + payload_length;
2821
2822 /* make sure that the payload is 4 or 8 bytes long */
2823 const uint8_t padding[4] = { 0, 0, 0, 0 };
2824 if (payload_length < 4) {
2825 ws_buffer_append(&params->rec->data, padding, 4 - payload_length);
2826 len += 4 - payload_length;
2827 } else if (payload_length > 4 && payload_length < 8) {
2828 ws_buffer_append(&params->rec->data, padding, 8 - payload_length);
2829 len += 8 - payload_length;
2830 }
2831
2832 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.linDataByteTimestampEvent.linMessageDescriptor.linSynchFieldEvent.linBusEvent.channel, UINT16_MAX(65535), len, len);
2833 blf_add_direction_option(params, linmessage.dir);
2834
2835 return true1;
2836}
2837
2838static bool_Bool
2839blf_read_lincrcerror2(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, uint16_t object_version) {
2840 blf_lincrcerror2_t linmessage;
2841
2842 uint8_t payload_length;
2843 unsigned len;
2844
2845 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2846 *err = WTAP_ERR_BAD_FILE-13;
2847 *err_info = ws_strdup("blf: LIN_CRC_ERROR2: not enough bytes for lincrcerror2 in object")wmem_strdup(((void*)0), "blf: LIN_CRC_ERROR2: not enough bytes for lincrcerror2 in object"
)
;
2848 ws_debug("not enough bytes for lincrcerror2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2848, __func__, "not enough bytes for lincrcerror2 in object"
); } } while (0)
;
2849 return false0;
2850 }
2851
2852 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2853 ws_debug("not enough bytes for lincrcerror2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2853, __func__, "not enough bytes for lincrcerror2 in file"
); } } while (0)
;
2854 return false0;
2855 }
2856 fix_endianness_blf_lincrcerror2(&linmessage);
2857
2858 linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc &= 0x0f;
2859 linmessage.linDataByteTimestampEvent.linMessageDescriptor.id &= 0x3f;
2860
2861 payload_length = MIN(linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc, 8)(((linmessage.linDataByteTimestampEvent.linMessageDescriptor.
dlc) < (8)) ? (linmessage.linDataByteTimestampEvent.linMessageDescriptor
.dlc) : (8))
;
2862
2863 uint8_t tmpbuf[12];
2864 tmpbuf[0] = 1; /* message format rev = 1 */
2865 tmpbuf[1] = 0; /* reserved */
2866 tmpbuf[2] = 0; /* reserved */
2867 tmpbuf[3] = 0; /* reserved */
2868 tmpbuf[4] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2869 if (object_version >= 1) { /* The 'checksumModel' field is valid only if objectVersion >= 1 */
2870 switch (linmessage.linDataByteTimestampEvent.linMessageDescriptor.checksumModel) {
2871 case 0:
2872 tmpbuf[4] |= 1; /* Classic */
2873 break;
2874 case 1:
2875 tmpbuf[4] |= 2; /* Enhanced */
2876 break;
2877 default:
2878 break;
2879 }
2880 }
2881 tmpbuf[5] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.id; /* parity (2bit) | id (6bit) */
2882 tmpbuf[6] = (uint8_t)(linmessage.crc & 0xff); /* checksum */
2883 tmpbuf[7] = LIN_ERROR_CHECKSUM_ERROR0x08; /* errors */
2884 tmpbuf[8] = 0;
2885 tmpbuf[9] = 0;
2886 tmpbuf[10] = 0;
2887 tmpbuf[11] = 0;
2888
2889 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2890 ws_buffer_append(&params->rec->data, linmessage.data, payload_length);
2891 len = sizeof(tmpbuf) + payload_length;
2892
2893 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.linDataByteTimestampEvent.linMessageDescriptor.linSynchFieldEvent.linBusEvent.channel, UINT16_MAX(65535), len, len);
2894 blf_add_direction_option(params, linmessage.dir);
2895
2896 return true1;
2897}
2898
2899static bool_Bool
2900blf_read_linrcverror2(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, uint16_t object_version) {
2901 blf_linrcverror2_t linmessage;
2902
2903 uint8_t payload_length;
2904 unsigned len;
2905
2906 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2907 *err = WTAP_ERR_BAD_FILE-13;
2908 *err_info = ws_strdup("blf: LIN_RCV_ERROR2: not enough bytes for linrcverror2 in object")wmem_strdup(((void*)0), "blf: LIN_RCV_ERROR2: not enough bytes for linrcverror2 in object"
)
;
2909 ws_debug("not enough bytes for linrcverror2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2909, __func__, "not enough bytes for linrcverror2 in object"
); } } while (0)
;
2910 return false0;
2911 }
2912
2913 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2914 ws_debug("not enough bytes for linrcverror2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2914, __func__, "not enough bytes for linrcverror2 in file"
); } } while (0)
;
2915 return false0;
2916 }
2917 fix_endianness_blf_linrcverror2(&linmessage);
2918
2919 linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc &= 0x0f;
2920 linmessage.linDataByteTimestampEvent.linMessageDescriptor.id &= 0x3f;
2921
2922 if (linmessage.hasDataBytes) {
2923 payload_length = MIN(linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc, 8)(((linmessage.linDataByteTimestampEvent.linMessageDescriptor.
dlc) < (8)) ? (linmessage.linDataByteTimestampEvent.linMessageDescriptor
.dlc) : (8))
;
2924 } else {
2925 payload_length = 0;
2926 }
2927
2928 uint8_t tmpbuf[12];
2929 tmpbuf[0] = 1; /* message format rev = 1 */
2930 tmpbuf[1] = 0; /* reserved */
2931 tmpbuf[2] = 0; /* reserved */
2932 tmpbuf[3] = 0; /* reserved */
2933 tmpbuf[4] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2934 if (object_version >= 1) { /* The 'checksumModel' field is valid only if objectVersion >= 1 */
2935 switch (linmessage.linDataByteTimestampEvent.linMessageDescriptor.checksumModel) {
2936 case 0:
2937 tmpbuf[4] |= 1; /* Classic */
2938 break;
2939 case 1:
2940 tmpbuf[4] |= 2; /* Enhanced */
2941 break;
2942 default:
2943 break;
2944 }
2945 }
2946 tmpbuf[5] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.id; /* parity (2bit) | id (6bit) */
2947 tmpbuf[6] = 0; /* checksum */
2948 /* XXX - This object can represent many different error types.
2949 * For now we always treat it as framing error,
2950 * but in the future we should expand it. */
2951 tmpbuf[7] = LIN_ERROR_FRAMING_ERROR0x02; /* errors */
2952 tmpbuf[8] = 0;
2953 tmpbuf[9] = 0;
2954 tmpbuf[10] = 0;
2955 tmpbuf[11] = 0;
2956
2957 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2958 if (payload_length > 0) {
2959 ws_buffer_append(&params->rec->data, linmessage.data, payload_length);
2960 }
2961 len = sizeof(tmpbuf) + payload_length;
2962
2963 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.linDataByteTimestampEvent.linMessageDescriptor.linSynchFieldEvent.linBusEvent.channel, UINT16_MAX(65535), len, len);
2964
2965 return true1;
2966}
2967
2968static bool_Bool
2969blf_read_linsenderror2(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, uint16_t object_version) {
2970 blf_linsenderror2_t linmessage;
2971
2972 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2973 *err = WTAP_ERR_BAD_FILE-13;
2974 *err_info = ws_strdup("blf: LIN_SND_ERROR2: not enough bytes for linsenderror2 in object")wmem_strdup(((void*)0), "blf: LIN_SND_ERROR2: not enough bytes for linsenderror2 in object"
)
;
2975 ws_debug("not enough bytes for linsenderror2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2975, __func__, "not enough bytes for linsenderror2 in object"
); } } while (0)
;
2976 return false0;
2977 }
2978
2979 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2980 ws_debug("not enough bytes for linsenderror2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2980, __func__, "not enough bytes for linsenderror2 in file"
); } } while (0)
;
2981 return false0;
2982 }
2983 fix_endianness_blf_linsenderror2(&linmessage);
2984
2985 linmessage.linMessageDescriptor.dlc &= 0x0f;
2986 linmessage.linMessageDescriptor.id &= 0x3f;
2987
2988 uint8_t tmpbuf[12];
2989 tmpbuf[0] = 1; /* message format rev = 1 */
2990 tmpbuf[1] = 0; /* reserved */
2991 tmpbuf[2] = 0; /* reserved */
2992 tmpbuf[3] = 0; /* reserved */
2993 tmpbuf[4] = linmessage.linMessageDescriptor.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2994 if (object_version >= 1) { /* The 'checksumModel' field is valid only if objectVersion >= 1 */
2995 switch (linmessage.linMessageDescriptor.checksumModel) {
2996 case 0:
2997 tmpbuf[4] |= 1; /* Classic */
2998 break;
2999 case 1:
3000 tmpbuf[4] |= 2; /* Enhanced */
3001 break;
3002 default:
3003 break;
3004 }
3005 }
3006 tmpbuf[5] = linmessage.linMessageDescriptor.id; /* parity (2bit) | id (6bit) */
3007 tmpbuf[6] = 0; /* checksum */
3008 tmpbuf[7] = LIN_ERROR_NO_SLAVE_RESPONSE0x01; /* errors */
3009 tmpbuf[8] = 0;
3010 tmpbuf[9] = 0;
3011 tmpbuf[10] = 0;
3012 tmpbuf[11] = 0;
3013
3014 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
3015
3016 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.linMessageDescriptor.linSynchFieldEvent.linBusEvent.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
3017
3018 return true1;
3019}
3020
3021static bool_Bool
3022blf_read_linwakeupevent2(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
3023 blf_linwakeupevent2_t linevent;
3024
3025 if (object_length < (data_start - block_start) + (int)sizeof(linevent)) {
3026 *err = WTAP_ERR_BAD_FILE-13;
3027 *err_info = ws_strdup("blf: LIN_WAKEUP2: not enough bytes for linwakeup2 in object")wmem_strdup(((void*)0), "blf: LIN_WAKEUP2: not enough bytes for linwakeup2 in object"
)
;
3028 ws_debug("not enough bytes for linwakeup2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3028, __func__, "not enough bytes for linwakeup2 in object"
); } } while (0)
;
3029 return false0;
3030 }
3031
3032 if (!blf_read_bytes(params, data_start, &linevent, sizeof(linevent), err, err_info)) {
3033 ws_debug("not enough bytes for linwakeup2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3033, __func__, "not enough bytes for linwakeup2 in file");
} } while (0)
;
3034 return false0;
3035 }
3036 fix_endianness_blf_linwakeupevent2(&linevent);
3037
3038 uint8_t tmpbuf[12]; /* LIN events have a fixed length of 12 bytes */
3039 tmpbuf[0] = 1; /* message format rev = 1 */
3040 tmpbuf[1] = 0; /* reserved */
3041 tmpbuf[2] = 0; /* reserved */
3042 tmpbuf[3] = 0; /* reserved */
3043 tmpbuf[4] = 3 << 2; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
3044 tmpbuf[5] = 0; /* parity (2bit) | id (6bit) */
3045 tmpbuf[6] = 0; /* checksum */
3046 tmpbuf[7] = 0; /* errors */
3047
3048 /* Wake-up event */
3049 tmpbuf[8] = 0xB0;
3050 tmpbuf[9] = 0xB0;
3051 tmpbuf[10] = 0x00;
3052 tmpbuf[11] = 0x04;
3053
3054 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
3055
3056 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linevent.linBusEvent.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
3057
3058 return true1;
3059}
3060
3061static bool_Bool
3062blf_read_linsleepmodeevent(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
3063 blf_linsleepmodeevent_t linevent;
3064
3065 if (object_length < (data_start - block_start) + (int)sizeof(linevent)) {
3066 *err = WTAP_ERR_BAD_FILE-13;
3067 *err_info = ws_strdup("blf: LIN_SLEEP: not enough bytes for linsleep in object")wmem_strdup(((void*)0), "blf: LIN_SLEEP: not enough bytes for linsleep in object"
)
;
3068 ws_debug("not enough bytes for linsleep in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3068, __func__, "not enough bytes for linsleep in object");
} } while (0)
;
3069 return false0;
3070 }
3071
3072 if (!blf_read_bytes(params, data_start, &linevent, sizeof(linevent), err, err_info)) {
3073 ws_debug("not enough bytes for linsleep in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3073, __func__, "not enough bytes for linsleep in file"); }
} while (0)
;
3074 return false0;
3075 }
3076 linevent.channel = GUINT16_FROM_LE(linevent.channel)(((guint16) (linevent.channel)));
3077
3078 uint8_t tmpbuf[12]; /* LIN events have a fixed length of 12 bytes */
3079 tmpbuf[0] = 1; /* message format rev = 1 */
3080 tmpbuf[1] = 0; /* reserved */
3081 tmpbuf[2] = 0; /* reserved */
3082 tmpbuf[3] = 0; /* reserved */
3083 tmpbuf[4] = 3 << 2; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
3084 tmpbuf[5] = 0; /* parity (2bit) | id (6bit) */
3085 tmpbuf[6] = 0; /* checksum */
3086 tmpbuf[7] = 0; /* errors */
3087
3088 switch (linevent.reason) {
3089 case BLF_LIN_SLEEP_REASON_GO_TO_SLEEP_FRAME1:
3090 /* Go-to-Sleep event by Go-to-Sleep frame */
3091 tmpbuf[8] = 0xB0;
3092 tmpbuf[9] = 0xB0;
3093 tmpbuf[10] = 0x00;
3094 tmpbuf[11] = 0x01;
3095 break;
3096 case BLF_LIN_SLEEP_REASON_BUS_IDLE_TIMEOUT2:
3097 case BLF_LIN_SLEEP_REASON_SILENT_SLEEPMODE_CMD3:
3098 /* Go-to-Sleep event by Inactivity for more than 4s */
3099 tmpbuf[8] = 0xB0;
3100 tmpbuf[9] = 0xB0;
3101 tmpbuf[10] = 0x00;
3102 tmpbuf[11] = 0x02;
3103 break;
3104 case BLF_LIN_WU_REASON_EXTERNAL_WAKEUP_SIG9:
3105 case BLF_LIN_WU_REASON_INTERNAL_WAKEUP_SIG10:
3106 case BLF_LIN_WU_REASON_BUS_TRAFFIC11: /* There's no "wake-up by bus traffic" event in the LIN packet. */
3107 /* Wake-up event by Wake-up signal */
3108 tmpbuf[8] = 0xB0;
3109 tmpbuf[9] = 0xB0;
3110 tmpbuf[10] = 0x00;
3111 tmpbuf[11] = 0x04;
3112 break;
3113 case BLF_LIN_WU_SLEEP_REASON_START_STATE0:
3114 case BLF_LIN_NO_SLEEP_REASON_BUS_TRAFFIC18:
3115 /* If we're just reporting on the initial state,
3116 * or the interface doesn't want to go to sleep,
3117 * report the current state as "event". */
3118 if (linevent.flags & 0x2) {
3119 /* Wake-up event by Wake-up signal */
3120 tmpbuf[8] = 0xB0;
3121 tmpbuf[9] = 0xB0;
3122 tmpbuf[10] = 0x00;
3123 tmpbuf[11] = 0x04;
3124 } else {
3125 /* Go-to-Sleep event by Inactivity for more than 4s */
3126 tmpbuf[8] = 0xB0;
3127 tmpbuf[9] = 0xB0;
3128 tmpbuf[10] = 0x00;
3129 tmpbuf[11] = 0x02;
3130 }
3131 break;
3132 default:
3133 tmpbuf[8] = 0x00;
3134 tmpbuf[9] = 0x00;
3135 tmpbuf[10] = 0x00;
3136 tmpbuf[11] = 0x00;
3137 break;
3138 }
3139
3140 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
3141
3142 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linevent.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
3143
3144 return true1;
3145}
3146
3147static bool_Bool
3148blf_parse_xml_port(const xmlChar* str, char** name, uint16_t* hwchannel, bool_Bool* simulated) {
3149 static const char name_magic[] = "name=";
3150 static const char hwchannel_magic[] = "hwchannel=";
3151 static const char simulated_magic[] = "simulated=";
3152
3153 if (str == NULL((void*)0)) return false0;
3154
3155 char** tokens = g_strsplit_set((const char*)str, ";", -1);
3156 if (tokens == NULL((void*)0)) {
3157 ws_debug("cannot split XML port data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3157, __func__, "cannot split XML port data"); } } while (0
)
;
3158 return false0;
3159 }
3160
3161 for (int i = 0; tokens[i] != NULL((void*)0); i++) {
3162 const char* token = tokens[i];
3163 if (name && strncmp(token, name_magic, strlen(name_magic)) == 0) {
3164 if (*name == NULL((void*)0)) { /* Avoid memory leak in case of repeated names */
3165 *name = ws_strdup(token + strlen(name_magic))wmem_strdup(((void*)0), token + strlen(name_magic));
3166 }
3167 } else if (hwchannel && strncmp(token, hwchannel_magic, strlen(hwchannel_magic)) == 0) {
3168 if (!ws_strtou16(token + strlen(hwchannel_magic), NULL((void*)0), hwchannel)) {
3169 *hwchannel = UINT16_MAX(65535);
3170 }
3171 } else if (simulated && strncmp(token, simulated_magic, strlen(simulated_magic)) == 0) {
3172 if (strlen(token) > strlen(simulated_magic) && token[strlen(simulated_magic)] != '0') {
3173 *simulated = true1; /* TODO: Find a way to use this information */
3174 }
3175 }
3176 }
3177
3178 g_strfreev(tokens);
3179
3180 return true1;
3181}
3182
3183static int
3184blf_get_xml_pkt_encap(const xmlChar* str) {
3185 if (str == NULL((void*)0)) return 0;
3186
3187 if (xmlStrcmp(str, (const xmlChar*)"CAN") == 0) {
3188 return WTAP_ENCAP_SOCKETCAN125;
3189 }
3190 if (xmlStrcmp(str, (const xmlChar*)"FlexRay") == 0) {
3191 return WTAP_ENCAP_FLEXRAY106;
3192 }
3193 if (xmlStrcmp(str, (const xmlChar*)"LIN") == 0) {
3194 return WTAP_ENCAP_LIN107;
3195 }
3196 if (xmlStrcmp(str, (const xmlChar*)"Ethernet") == 0) {
3197 return WTAP_ENCAP_ETHERNET1;
3198 }
3199 if (xmlStrcmp(str, (const xmlChar*)"WLAN") == 0) { /* Not confirmed with a real capture */
3200 return WTAP_ENCAP_IEEE_802_1120;
3201 }
3202
3203 return WTAP_ENCAP_UNKNOWN0;
3204}
3205
3206
3207/** Extracts the channel and port names from a channels XML.
3208 *
3209 * A sample channels XML looks like this:
3210 *
3211 * <?xml version="1.0" encoding="UTF-8"?>
3212 * <channels version="1">
3213 * <channel number="1" type="CAN" network="CAN01">
3214 * <databases>
3215 * <database file="DB.arxml" path="C:\...\" cluster="CAN01" />
3216 * <database file="DB.dbc" path="C:\...\" cluster="General" />
3217 * </databases>
3218 * </channel>
3219 * <channel number="1" type="LIN" network="LIN01">
3220 * <databases>
3221 * <database file="DB.dbc" path="C:\...\" cluster="General" />
3222 * <database file="DB.ldf" path="C:\...\" cluster="LIN01" />
3223 * </databases>
3224 * </channel>
3225 * <channel number="1" type="Ethernet" network="ETH01">
3226 * <databases>
3227 * <database file="DB.dbc" path="C:\...\" cluster="General" />
3228 * </databases>
3229 * <channel_properties>
3230 * <elist name="ports">
3231 * <eli name="port">name=Port1;hwchannel=11;simulated=1</eli>
3232 * <eli name="port">name=Port2;hwchannel=12;simulated=0</eli>
3233 * </elist>
3234 * </channel_properties>
3235 * </channel>
3236 * </channels>
3237 */
3238static bool_Bool
3239blf_set_xml_channels(blf_params_t* params, const char* text, size_t len) {
3240 xmlDocPtr doc;
3241 xmlNodePtr root_element = NULL((void*)0);
3242 xmlNodePtr channels = NULL((void*)0);
3243
3244 if (text == NULL((void*)0)) return false0;
3245
3246 /* Now it can be parsed into a proper structure */
3247 doc = xmlParseMemory(text, (int)len);
3248 if (doc == NULL((void*)0)) {
3249 ws_debug("invalid xml found")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3249, __func__, "invalid xml found"); } } while (0)
;
3250 return false0;
3251 }
3252
3253 root_element = xmlDocGetRootElement(doc);
3254 if (root_element == NULL((void*)0)) {
3255 ws_debug("empty xml doc")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3255, __func__, "empty xml doc"); } } while (0)
;
3256 xmlFreeDoc(doc);
3257 return false0;
3258 }
3259
3260 if (xmlStrcmp(root_element->name, (const xmlChar*)"channels") == 0) {
3261 channels = root_element;
3262 } else {
3263 for (xmlNodePtr cur = root_element->children; cur != NULL((void*)0); cur = cur->next) {
3264 if (cur->type == XML_ELEMENT_NODE && xmlStrcmp(cur->name, (const xmlChar*)"channels") == 0) {
3265 channels = cur;
3266 break;
3267 }
3268 }
3269 }
3270
3271 if (channels == NULL((void*)0)) {
3272 ws_debug("No channels found")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3272, __func__, "No channels found"); } } while (0)
;
3273 xmlFreeDoc(doc);
3274 return false0;
3275 }
3276
3277 for (xmlNodePtr current_channel_node = channels->children; current_channel_node != NULL((void*)0); current_channel_node = current_channel_node->next) {
3278 if ((current_channel_node->type == XML_ELEMENT_NODE) && (xmlStrcmp(current_channel_node->name, (const xmlChar*)"channel") == 0)) {
3279 /* Reset the found attributes */
3280 int pkt_encap = WTAP_ENCAP_UNKNOWN0;
3281 uint16_t channel = UINT16_MAX(65535);
3282 char* channel_name = NULL((void*)0);
3283
3284 for (xmlAttrPtr attr = current_channel_node->properties; attr; attr = attr->next) {
3285 if (xmlStrcmp(attr->name, (const xmlChar*)"number") == 0) {
3286 xmlChar* str_channel = xmlNodeListGetString(current_channel_node->doc, attr->children, 1);
3287 if (str_channel != NULL((void*)0)) {
3288 ws_strtou16((const char*)str_channel, NULL((void*)0), &channel);
3289 xmlFree(str_channel);
3290 }
3291 } else if (xmlStrcmp(attr->name, (const xmlChar*)"type") == 0) {
3292 xmlChar* str_type = xmlNodeListGetString(current_channel_node->doc, attr->children, 1);
3293 if (str_type != NULL((void*)0)) {
3294 pkt_encap = blf_get_xml_pkt_encap(str_type);
3295 xmlFree(str_type);
3296 }
3297 } else if (xmlStrcmp(attr->name, (const xmlChar*)"network") == 0) {
3298 xmlChar* str_network = xmlNodeListGetString(current_channel_node->doc, attr->children, 1);
3299 if (str_network != NULL((void*)0)) {
3300 if (channel_name == NULL((void*)0)) {
3301 channel_name = ws_strdup((const char*)str_network)wmem_strdup(((void*)0), (const char*)str_network);
3302 }
3303 xmlFree(str_network);
3304 }
3305 }
3306 }
3307
3308 if (pkt_encap != WTAP_ENCAP_UNKNOWN0 && channel != UINT16_MAX(65535) && channel_name != NULL((void*)0)) {
3309 ws_debug("Found channel in XML: PKT_ENCAP: %d, ID: %u, name: %s", pkt_encap, channel, channel_name)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3309, __func__, "Found channel in XML: PKT_ENCAP: %d, ID: %u, name: %s"
, pkt_encap, channel, channel_name); } } while (0)
;
3310 blf_prepare_interface_name(params, pkt_encap, channel, UINT16_MAX(65535), channel_name, true1);
3311
3312 /* Look for ports under the channel properties */
3313 for (xmlNodePtr channel_property = current_channel_node->children; channel_property != NULL((void*)0); channel_property = channel_property->next) {
3314 if ((channel_property->type == XML_ELEMENT_NODE) && (xmlStrcmp(channel_property->name, (const xmlChar*)"channel_properties") == 0)) {
3315 for (xmlNodePtr prop_child = channel_property->children; prop_child != NULL((void*)0); prop_child = prop_child->next) {
3316 if (prop_child->type == XML_ELEMENT_NODE && xmlStrcmp(prop_child->name, (const xmlChar*)"elist") == 0) {
3317 xmlNodePtr elist_node = prop_child;
3318 xmlChar* str_name = xmlGetProp(elist_node, (const xmlChar*)"name");
3319 if (xmlStrcmp(str_name, (const xmlChar*)"ports") == 0) {
3320 for (xmlNodePtr eli_node = elist_node->children; eli_node != NULL((void*)0); eli_node = eli_node->next) {
3321 if (eli_node->type == XML_ELEMENT_NODE && xmlStrcmp(eli_node->name, (const xmlChar*)"eli") == 0) {
3322 xmlChar* eli_name_attr = xmlGetProp(eli_node, (const xmlChar*)"name");
3323 if (xmlStrcmp(eli_name_attr, (const xmlChar*)"port") == 0) {
3324 char* port_name = NULL((void*)0);
3325 uint16_t hwchannel = UINT16_MAX(65535);
3326 bool_Bool simulated = false0;
3327 char* iface_name = NULL((void*)0);
3328 xmlChar* eli_content = xmlNodeGetContent(eli_node);
3329
3330 bool_Bool res = blf_parse_xml_port(eli_content, &port_name, &hwchannel, &simulated);
3331 if (res && port_name != NULL((void*)0) && hwchannel != UINT16_MAX(65535)) {
3332 iface_name = ws_strdup_printf("%s::%s", channel_name, port_name)wmem_strdup_printf(((void*)0), "%s::%s", channel_name, port_name
)
;
3333 ws_debug("Found channel in XML: PKT_ENCAP: %d, ID: %u, HW ID: %u, name: %s", pkt_encap, channel, hwchannel, iface_name)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3333, __func__, "Found channel in XML: PKT_ENCAP: %d, ID: %u, HW ID: %u, name: %s"
, pkt_encap, channel, hwchannel, iface_name); } } while (0)
;
3334 blf_prepare_interface_name(params, pkt_encap, channel, hwchannel, iface_name, true1);
3335 g_free(iface_name)(__builtin_object_size ((iface_name), 0) != ((size_t) - 1)) ?
g_free_sized (iface_name, __builtin_object_size ((iface_name
), 0)) : (g_free) (iface_name)
;
3336 } else {
3337 ws_debug("port with missing or malformed info found in xml")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3337, __func__, "port with missing or malformed info found in xml"
); } } while (0)
;
3338 }
3339 g_free(port_name)(__builtin_object_size ((port_name), 0) != ((size_t) - 1)) ? g_free_sized
(port_name, __builtin_object_size ((port_name), 0)) : (g_free
) (port_name)
;
3340 xmlFree(eli_content);
3341 }
3342 xmlFree(eli_name_attr);
3343 }
3344 }
3345 }
3346 xmlFree(str_name);
3347 }
3348 }
3349 }
3350 }
3351 }
3352 g_free(channel_name)(__builtin_object_size ((channel_name), 0) != ((size_t) - 1))
? g_free_sized (channel_name, __builtin_object_size ((channel_name
), 0)) : (g_free) (channel_name)
;
3353 }
3354 }
3355
3356 xmlFreeDoc(doc);
3357 return true1;
3358}
3359
3360static int
3361blf_read_apptextmessage(blf_params_t *params, int *err, char **err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, blf_metadata_info_t* metadata_info) {
3362 blf_apptext_t apptextheader;
3363
3364 if (object_length < (data_start - block_start) + (int)sizeof(apptextheader)) {
3365 *err = WTAP_ERR_BAD_FILE-13;
3366 *err_info = ws_strdup("blf: APP_TEXT: not enough bytes for apptext header in object")wmem_strdup(((void*)0), "blf: APP_TEXT: not enough bytes for apptext header in object"
)
;
3367 ws_debug("not enough bytes for apptext header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3367, __func__, "not enough bytes for apptext header in object"
); } } while (0)
;
3368 return BLF_APPTEXT_FAILED0x000000FF;
3369 }
3370
3371 if (!blf_read_bytes(params, data_start, &apptextheader, sizeof(apptextheader), err, err_info)) {
3372 ws_debug("not enough bytes for apptext header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3372, __func__, "not enough bytes for apptext header in file"
); } } while (0)
;
3373 return BLF_APPTEXT_FAILED0x000000FF;
3374 }
3375 fix_endianness_blf_apptext_header(&apptextheader);
3376
3377 if (metadata_info->valid && apptextheader.source != BLF_APPTEXT_METADATA0x00000002) {
3378 /* If we're in the middle of a sequence of metadata objects,
3379 * but we get an AppText object from another source,
3380 * skip the previously incomplete object and start fresh.
3381 */
3382 metadata_info->valid = false0;
3383 }
3384
3385 /* Add an extra byte for a terminating '\0' */
3386 char* text = g_try_malloc((size_t)apptextheader.textLength + 1);
3387 if (text == NULL((void*)0)) {
3388 ws_debug("cannot allocate memory")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3388, __func__, "cannot allocate memory"); } } while (0)
;
3389 return BLF_APPTEXT_FAILED0x000000FF;
3390 }
3391
3392 if (!blf_read_bytes(params, data_start + sizeof(apptextheader), text, apptextheader.textLength, err, err_info)) {
3393 ws_debug("not enough bytes for apptext text in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3393, __func__, "not enough bytes for apptext text in file"
); } } while (0)
;
3394 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3395 return BLF_APPTEXT_FAILED0x000000FF;
3396 }
3397 text[apptextheader.textLength] = '\0'; /* Here's the '\0' */
3398
3399 switch (apptextheader.source) {
3400 case BLF_APPTEXT_CHANNEL0x00000001:
3401 {
3402
3403 /* returns a NULL terminated array of NULL terminates strings */
3404 char** tokens = g_strsplit_set(text, ";", -1);
3405
3406 if (tokens == NULL((void*)0) || tokens[0] == NULL((void*)0) || tokens[1] == NULL((void*)0)) {
3407 if (tokens != NULL((void*)0)) {
3408 g_strfreev(tokens);
3409 }
3410 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3411 return BLF_APPTEXT_CHANNEL0x00000001;
3412 }
3413
3414 uint16_t channel = (apptextheader.reservedAppText1 >> 8) & 0xff;
3415 int pkt_encap;
3416
3417 switch ((apptextheader.reservedAppText1 >> 16) & 0xff) {
3418 case BLF_BUSTYPE_CAN1:
3419 pkt_encap = WTAP_ENCAP_SOCKETCAN125;
3420 break;
3421
3422 case BLF_BUSTYPE_FLEXRAY7:
3423 pkt_encap = WTAP_ENCAP_FLEXRAY106;
3424 break;
3425
3426 case BLF_BUSTYPE_LIN5:
3427 pkt_encap = WTAP_ENCAP_LIN107;
3428 break;
3429
3430 case BLF_BUSTYPE_ETHERNET11:
3431 pkt_encap = WTAP_ENCAP_ETHERNET1;
3432 break;
3433
3434 case BLF_BUSTYPE_WLAN13:
3435 pkt_encap = WTAP_ENCAP_IEEE_802_1120;
3436 break;
3437
3438 default:
3439 pkt_encap = WTAP_ENCAP_UNKNOWN0;
3440 break;
3441 }
3442
3443 if (pkt_encap != WTAP_ENCAP_UNKNOWN0) {
3444 /* we use lookup to create interface, if not existing yet */
3445 blf_prepare_interface_name(params, pkt_encap, channel, UINT16_MAX(65535), tokens[1], false0);
3446 }
3447
3448 g_strfreev(tokens);
3449 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3450 return BLF_APPTEXT_CHANNEL0x00000001;
3451 }
3452 case BLF_APPTEXT_METADATA0x00000002:
3453 if (metadata_info->valid) {
3454 /* Set the buffer pointer to the end of the previous object */
3455 params->rec->data.first_free = metadata_info->metadata_cont;
3456 } else {
3457 /* First object of a sequence of one or more */
3458 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_DISSECTOR_NAME12, BLF_APPTEXT_TAG_DISS_DEFAULT"data-text-lines");
3459 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_PROT_TEXT33, BLF_APPTEXT_COL_PROT_TEXT"BLF App text");
3460 switch (((apptextheader.reservedAppText1 >> 24) & 0xff)) {
3461 case BLF_APPTEXT_XML_GENERAL0x01:
3462 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, BLF_APPTEXT_COL_INFO_TEXT_GENERAL"Metadata: General");
3463 break;
3464
3465 case BLF_APPTEXT_XML_CHANNELS0x02:
3466 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, BLF_APPTEXT_COL_INFO_TEXT_CHANNELS"Metadata: Channels");
3467 break;
3468
3469 case BLF_APPTEXT_XML_IDENTITY0x03:
3470 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, BLF_APPTEXT_COL_INFO_TEXT_IDENTITY"Metadata: Identity");
3471 break;
3472
3473 default:
3474 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, BLF_APPTEXT_COL_INFO_TEXT"Metadata");
3475 }
3476 wtap_buffer_append_epdu_end(&params->rec->data);
3477 metadata_info->payload_start = params->rec->data.first_free;
3478 }
3479
3480 ws_buffer_append(&params->rec->data, (const uint8_t*)text, apptextheader.textLength);
3481 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3482
3483 if ((apptextheader.reservedAppText1 & 0x00ffffff) > apptextheader.textLength) {
3484 /* Continues in the next object */
3485 return BLF_APPTEXT_CONT0x000000FE;
3486 }
3487
3488 if (((apptextheader.reservedAppText1 >> 24) & 0xff) == BLF_APPTEXT_XML_CHANNELS0x02) {
3489 blf_set_xml_channels(params, (const char*)(params->rec->data.data + metadata_info->payload_start), params->rec->data.first_free - metadata_info->payload_start);
3490 }
3491
3492 /* Override the timestamp with 0 for metadata objects. Thay can only occur at the beginning of the file, and they usually already have a timestamp of 0. */
3493 blf_init_rec(params, 0, 0, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, 0, UINT16_MAX(65535), (uint32_t)ws_buffer_length(&params->rec->data), (uint32_t)ws_buffer_length(&params->rec->data));
3494 return BLF_APPTEXT_METADATA0x00000002;
3495 case BLF_APPTEXT_COMMENT0x00000000:
3496 case BLF_APPTEXT_ATTACHMENT0x00000003:
3497 case BLF_APPTEXT_TRACELINE0x00000004:
3498 {
3499 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_DISSECTOR_NAME12, BLF_APPTEXT_TAG_DISS_DEFAULT"data-text-lines");
3500 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_PROT_TEXT33, BLF_APPTEXT_COL_PROT_TEXT"BLF App text");
3501
3502 char* info_line = NULL((void*)0);
3503 switch (apptextheader.source) {
3504 case BLF_APPTEXT_COMMENT0x00000000:
3505 info_line = ws_strdup_printf("Comment: %s", text)wmem_strdup_printf(((void*)0), "Comment: %s", text);
3506 break;
3507 case BLF_APPTEXT_ATTACHMENT0x00000003:
3508 info_line = ws_strdup_printf("Attachment: %s", text)wmem_strdup_printf(((void*)0), "Attachment: %s", text);
3509 break;
3510 case BLF_APPTEXT_TRACELINE0x00000004:
3511 info_line = ws_strdup_printf("Trace line%s: %s", (apptextheader.reservedAppText1 & 0x00000010) ? "" : " (hidden)", text)wmem_strdup_printf(((void*)0), "Trace line%s: %s", (apptextheader
.reservedAppText1 & 0x00000010) ? "" : " (hidden)", text)
;
3512 break;
3513 default:
3514 ws_assert_not_reached()ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/blf.c"
, 3514, __func__, "assertion \"not reached\" failed")
;
3515 }
3516
3517 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, info_line);
3518 wtap_buffer_append_epdu_end(&params->rec->data);
3519
3520 size_t text_length = strlen(text); /* The string can contain '\0' before textLength bytes */
3521 ws_buffer_append(&params->rec->data, (const uint8_t*)text, text_length); /* The dissector doesn't need NULL-terminated strings */
3522
3523 /* We'll write this as a WS UPPER PDU packet with a text blob */
3524 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, 0, UINT16_MAX(65535), (uint32_t)ws_buffer_length(&params->rec->data), (uint32_t)ws_buffer_length(&params->rec->data));
3525 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3526 g_free(info_line)(__builtin_object_size ((info_line), 0) != ((size_t) - 1)) ? g_free_sized
(info_line, __builtin_object_size ((info_line), 0)) : (g_free
) (info_line)
;
3527 return apptextheader.source;
3528 }
3529 default:
3530 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3531 return BLF_APPTEXT_CHANNEL0x00000001; /* Cheat - no block to write */;
3532 }
3533 return BLF_APPTEXT_CHANNEL0x00000001; /* Cheat - no block to write */
3534}
3535
3536static bool_Bool
3537blf_read_ethernet_status(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp, uint16_t object_version) {
3538 blf_ethernet_status_t ethernet_status_header;
3539 uint8_t tmpbuf[24];
3540 uint64_t linkUpDuration;
3541
3542 if (object_length < (data_start - block_start) + (int)sizeof(ethernet_status_header) + (int)(object_version >= 1 ? 8 : 0)) {
3543 *err = WTAP_ERR_BAD_FILE-13;
3544 *err_info = ws_strdup("blf: ETHERNET_STATUS: not enough bytes for ethernet status header in object")wmem_strdup(((void*)0), "blf: ETHERNET_STATUS: not enough bytes for ethernet status header in object"
)
;
3545 ws_debug("not enough bytes for ethernet status header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3545, __func__, "not enough bytes for ethernet status header in object"
); } } while (0)
;
3546 return false0;
3547 }
3548
3549 if (!blf_read_bytes(params, data_start, &ethernet_status_header, sizeof(ethernet_status_header), err, err_info)) {
3550 ws_debug("not enough bytes for ethernet_status_header header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3550, __func__, "not enough bytes for ethernet_status_header header in file"
); } } while (0)
;
3551 return false0;
3552 }
3553
3554 if (object_version >= 1) {
3555 if (!blf_read_bytes(params, data_start + sizeof(ethernet_status_header), &linkUpDuration, 8, err, err_info)) {
3556 ws_debug("not enough bytes for ethernet_status_header header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3556, __func__, "not enough bytes for ethernet_status_header header in file"
); } } while (0)
;
3557 return false0;
3558 }
3559 linkUpDuration = GUINT64_FROM_LE(linkUpDuration)(((guint64) (linkUpDuration)));
3560 }
3561
3562 fix_endianness_blf_ethernet_status_header(&ethernet_status_header);
3563
3564 phtonu16(tmpbuf, ethernet_status_header.channel);
3565 phtonu16(tmpbuf + 2, ethernet_status_header.flags);
3566 tmpbuf[4] = (ethernet_status_header.linkStatus);
3567 tmpbuf[5] = (ethernet_status_header.ethernetPhy);
3568 tmpbuf[6] = (ethernet_status_header.duplex);
3569 tmpbuf[7] = (ethernet_status_header.mdi);
3570 tmpbuf[8] = (ethernet_status_header.connector);
3571 tmpbuf[9] = (ethernet_status_header.clockMode);
3572 tmpbuf[10] = (ethernet_status_header.pairs);
3573 tmpbuf[11] = (ethernet_status_header.hardwareChannel);
3574 phtonu32(tmpbuf + 12, ethernet_status_header.bitrate);
3575
3576 if (object_version >= 1) {
3577 phtonu64(tmpbuf + 16, linkUpDuration);
3578 }
3579
3580 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_DISSECTOR_NAME12, BLF_APPTEXT_TAG_DISS_ETHSTATUS"blf-ethernetstatus-obj");
3581 wtap_buffer_append_epdu_end(&params->rec->data);
3582
3583 ws_buffer_append(&params->rec->data, tmpbuf, (size_t)(object_version >= 1 ? 24 : 16));
3584
3585 /* We'll write this as a WS UPPER PDU packet with a data blob */
3586 /* This will create an interface with the "name" of the matching
3587 * WTAP_ENCAP_ETHERNET interface with the same channel and hardware
3588 * channel prefixed with "STATUS" and with a different interface ID,
3589 * because IDBs in pcapng can only have one linktype.
3590 * The other option would be to write everything as UPPER_PDU, including
3591 * the Ethernet data (with one of the "eth_" dissectors.)
3592 */
3593 char* iface_name = ws_strdup_printf("STATUS-ETH-%u-%u", ethernet_status_header.channel, ethernet_status_header.hardwareChannel)wmem_strdup_printf(((void*)0), "STATUS-ETH-%u-%u", ethernet_status_header
.channel, ethernet_status_header.hardwareChannel)
;
3594 blf_lookup_interface(params, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, ethernet_status_header.channel, ethernet_status_header.hardwareChannel, iface_name);
3595 g_free(iface_name)(__builtin_object_size ((iface_name), 0) != ((size_t) - 1)) ?
g_free_sized (iface_name, __builtin_object_size ((iface_name
), 0)) : (g_free) (iface_name)
;
3596 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, ethernet_status_header.channel, ethernet_status_header.hardwareChannel, (uint32_t)ws_buffer_length(&params->rec->data), (uint32_t)ws_buffer_length(&params->rec->data));
3597
3598 if ((ethernet_status_header.flags & BLF_ETH_STATUS_HARDWARECHANNEL0x0100) == BLF_ETH_STATUS_HARDWARECHANNEL0x0100) {
3599 /* If HW channel valid */
3600 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_QUEUE6, ethernet_status_header.hardwareChannel);
3601 }
3602
3603 return true1;
3604}
3605
3606static bool_Bool
3607blf_read_ethernet_phystate(blf_params_t* params, int* err, char** err_info, int64_t block_start, int64_t data_start, int64_t object_length, uint32_t flags, uint64_t object_timestamp) {
3608 blf_ethernet_phystate_t ethernet_phystate_header;
3609 uint8_t tmpbuf[8];
3610
3611 if (object_length < (data_start - block_start) + (int)sizeof(ethernet_phystate_header)) {
3612 *err = WTAP_ERR_BAD_FILE-13;
3613 *err_info = ws_strdup("blf: ETHERNET_PHY_STATE: not enough bytes for ethernet phystate header in object")wmem_strdup(((void*)0), "blf: ETHERNET_PHY_STATE: not enough bytes for ethernet phystate header in object"
)
;
3614 ws_debug("not enough bytes for ethernet phystate header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3614, __func__, "not enough bytes for ethernet phystate header in object"
); } } while (0)
;
3615 return false0;
3616 }
3617
3618 if (!blf_read_bytes(params, data_start, &ethernet_phystate_header, sizeof(ethernet_phystate_header), err, err_info)) {
3619 ws_debug("not enough bytes for ethernet phystate header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3619, __func__, "not enough bytes for ethernet phystate header in file"
); } } while (0)
;
3620 return false0;
3621 }
3622
3623 fix_endianness_blf_ethernet_phystate_header(&ethernet_phystate_header);
3624
3625 phtonu16(tmpbuf, ethernet_phystate_header.channel);
3626 phtonu16(tmpbuf + 2, ethernet_phystate_header.flags);
3627 tmpbuf[4] = (ethernet_phystate_header.phyState);
3628 tmpbuf[5] = (ethernet_phystate_header.phyEvent);
3629 tmpbuf[6] = (ethernet_phystate_header.hardwareChannel);
3630 tmpbuf[7] = (ethernet_phystate_header.res1);
3631
3632 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_DISSECTOR_NAME12, BLF_APPTEXT_TAG_DISS_ETHPHYSTATUS"blf-ethernetphystate-obj");
3633 wtap_buffer_append_epdu_end(&params->rec->data);
3634
3635 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
3636
3637 /* We'll write this as a WS UPPER PDU packet with a data blob */
3638 /* This will create an interface with the "name" of the matching
3639 * WTAP_ENCAP_ETHERNET interface with the same channel and hardware
3640 * channel prefixed with "STATUS" and with a different interface ID,
3641 * because IDBs in pcapng can only have one linktype.
3642 * The other option would be to write everything as UPPER_PDU, including
3643 * the Ethernet data (with one of the "eth_" dissectors.)
3644 */
3645 char* iface_name = ws_strdup_printf("STATUS-ETH-%u-%u", ethernet_phystate_header.channel, ethernet_phystate_header.hardwareChannel)wmem_strdup_printf(((void*)0), "STATUS-ETH-%u-%u", ethernet_phystate_header
.channel, ethernet_phystate_header.hardwareChannel)
;
3646 blf_lookup_interface(params, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, ethernet_phystate_header.channel, ethernet_phystate_header.hardwareChannel, iface_name);
3647 g_free(iface_name)(__builtin_object_size ((iface_name), 0) != ((size_t) - 1)) ?
g_free_sized (iface_name, __builtin_object_size ((iface_name
), 0)) : (g_free) (iface_name)
;
3648 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, ethernet_phystate_header.channel, ethernet_phystate_header.hardwareChannel, (uint32_t)ws_buffer_length(&params->rec->data), (uint32_t)ws_buffer_length(&params->rec->data));
3649
3650 if ((ethernet_phystate_header.flags & BLF_PHY_STATE_HARDWARECHANNEL0x0004) == BLF_PHY_STATE_HARDWARECHANNEL0x0004) {
3651 /* If HW channel valid */
3652 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_QUEUE6, ethernet_phystate_header.hardwareChannel);
3653 }
3654
3655 return true1;
3656}
3657
3658static bool_Bool
3659blf_read_block(blf_params_t *params, int64_t start_pos, int *err, char **err_info) {
3660 blf_blockheader_t header;
3661 blf_logobjectheader_t logheader;
3662 blf_logobjectheader2_t logheader2;
3663 blf_logobjectheader3_t logheader3;
3664 uint32_t flags;
3665 uint64_t object_timestamp;
3666 uint16_t object_version;
3667 blf_metadata_info_t metadata_info = { 0, 0, false0 };
3668 int64_t last_metadata_start = 0;
3669
3670 while (1) {
3671 /* Find Object */
3672
3673 /* Resetting buffer */
3674 params->rec->data.first_free = params->rec->data.start;
3675
3676 while (1) {
3677 if (!blf_read_bytes_or_eof(params, start_pos, &header, sizeof header, err, err_info)) {
3678 ws_debug("not enough bytes for block header or unsupported file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3678, __func__, "not enough bytes for block header or unsupported file"
); } } while (0)
;
3679 if (*err == WTAP_ERR_SHORT_READ-12) {
3680 /* we have found the end that is not a short read therefore. */
3681 *err = 0;
3682 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
3683 *err_info = NULL((void*)0);
3684 }
3685 return false0;
3686 }
3687
3688 fix_endianness_blf_blockheader(&header);
3689
3690 if (memcmp(header.magic, blf_obj_magic, sizeof(blf_obj_magic))) {
3691 ws_debug("object magic is not LOBJ (pos: 0x%" PRIx64 ")", start_pos)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3691, __func__, "object magic is not LOBJ (pos: 0x%" "l" "x"
")", start_pos); } } while (0)
;
3692 } else {
3693 break;
3694 }
3695
3696 /* we are moving back and try again but 1 byte later */
3697 /* TODO: better understand how this paddings works... */
3698 start_pos++;
3699 }
3700 params->blf_data->start_of_last_obj = start_pos;
3701
3702 if (!params->random) {
3703 /* Make sure that we start after this object next time,
3704 * but only if it's a linear read. We can have random reads
3705 * during the linear read, so we have to make sure we don't
3706 * lose track of our position.
3707 */
3708 params->blf_data->current_real_seek_pos = start_pos + MAX(MAX(16, header.object_length), header.header_length)((((((16) > (header.object_length)) ? (16) : (header.object_length
))) > (header.header_length)) ? ((((16) > (header.object_length
)) ? (16) : (header.object_length))) : (header.header_length)
)
;
3709 }
3710
3711 switch (header.header_type) {
3712 case BLF_HEADER_TYPE_DEFAULT1:
3713 if (!blf_read_log_object_header(params, err, err_info, start_pos + sizeof(blf_blockheader_t), start_pos + header.header_length, &logheader)) {
3714 return false0;
3715 }
3716 flags = logheader.flags;
3717 object_timestamp = logheader.object_timestamp;
3718 object_version = logheader.object_version;
3719 break;
3720
3721 case BLF_HEADER_TYPE_22:
3722 if (!blf_read_log_object_header2(params, err, err_info, start_pos + sizeof(blf_blockheader_t), start_pos + header.header_length, &logheader2)) {
3723 return false0;
3724 }
3725 flags = logheader2.flags;
3726 object_timestamp = logheader2.object_timestamp;
3727 object_version = logheader2.object_version;
3728 break;
3729
3730 case BLF_HEADER_TYPE_33:
3731 if (!blf_read_log_object_header3(params, err, err_info, start_pos + sizeof(blf_blockheader_t), start_pos + header.header_length, &logheader3)) {
3732 return false0;
3733 }
3734 flags = logheader3.flags;
3735 object_timestamp = logheader3.object_timestamp;
3736 object_version = logheader3.object_version;
3737 break;
3738
3739 default:
3740 *err = WTAP_ERR_UNSUPPORTED-4;
3741 *err_info = ws_strdup_printf("blf: unknown header type %u", header.header_type)wmem_strdup_printf(((void*)0), "blf: unknown header type %u",
header.header_type)
;
3742 ws_debug("unknown header type")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3742, __func__, "unknown header type"); } } while (0)
;
3743 return false0;
3744 }
3745
3746 if (metadata_info.valid && header.object_type != BLF_OBJTYPE_APP_TEXT65) {
3747 /* If we're in the middle of a sequence of AppText metadata objects,
3748 * but we get an AppText object from another source,
3749 * skip the previous incomplete packet and start fresh.
3750 */
3751 metadata_info.valid = false0;
3752 }
3753
3754 switch (header.object_type) {
3755 case BLF_OBJTYPE_LOG_CONTAINER10:
3756 *err = WTAP_ERR_UNSUPPORTED-4;
3757 *err_info = ws_strdup("blf: log container in log container not supported")wmem_strdup(((void*)0), "blf: log container in log container not supported"
)
;
3758 ws_debug("log container in log container not supported")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3758, __func__, "log container in log container not supported"
); } } while (0)
;
3759 return false0;
3760
3761 case BLF_OBJTYPE_ETHERNET_FRAME71:
3762 return blf_read_ethernetframe(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3763
3764 case BLF_OBJTYPE_ETHERNET_FRAME_EX120:
3765 return blf_read_ethernetframe_ext(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3766
3767 case BLF_OBJTYPE_ETHERNET_RX_ERROR102:
3768 return blf_read_ethernet_rxerror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3769
3770 case BLF_OBJTYPE_ETHERNET_ERROR_EX122:
3771 return blf_read_ethernetframe_ext(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3772
3773 case BLF_OBJTYPE_WLAN_FRAME93:
3774 return blf_read_wlanframe(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3775
3776 case BLF_OBJTYPE_CAN_MESSAGE1:
3777 return blf_read_canmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3778
3779 case BLF_OBJTYPE_CAN_ERROR2:
3780 return blf_read_canerror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3781
3782 case BLF_OBJTYPE_CAN_OVERLOAD3:
3783 return blf_read_canerror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3784
3785 case BLF_OBJTYPE_CAN_MESSAGE286:
3786 return blf_read_canmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3787
3788 case BLF_OBJTYPE_CAN_ERROR_EXT73:
3789 return blf_read_canerrorext(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3790
3791 case BLF_OBJTYPE_CAN_FD_MESSAGE100:
3792 return blf_read_canfdmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3793
3794 case BLF_OBJTYPE_CAN_FD_MESSAGE_64101:
3795 return blf_read_canfdmessage64(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3796
3797 case BLF_OBJTYPE_CAN_FD_ERROR_64104:
3798 return blf_read_canfderror64(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3799
3800 case BLF_OBJTYPE_CAN_XL_CHANNEL_FRAME139:
3801 return blf_read_canxlchannelframe(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3802
3803 case BLF_OBJTYPE_FLEXRAY_DATA29:
3804 return blf_read_flexraydata(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3805
3806 case BLF_OBJTYPE_FLEXRAY_MESSAGE41:
3807 return blf_read_flexraymessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3808
3809 case BLF_OBJTYPE_FLEXRAY_RCVMESSAGE50:
3810 return blf_read_flexrayrcvmessageex(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3811
3812 case BLF_OBJTYPE_FLEXRAY_RCVMESSAGE_EX66:
3813 return blf_read_flexrayrcvmessageex(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3814
3815 case BLF_OBJTYPE_LIN_MESSAGE11:
3816 return blf_read_linmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3817
3818 case BLF_OBJTYPE_LIN_CRC_ERROR12:
3819 return blf_read_linmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3820
3821 case BLF_OBJTYPE_LIN_RCV_ERROR14:
3822 return blf_read_linrcverror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3823
3824 case BLF_OBJTYPE_LIN_SND_ERROR15:
3825 return blf_read_linsenderror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3826
3827 case BLF_OBJTYPE_LIN_WAKEUP21:
3828 return blf_read_linwakeupevent(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3829
3830 case BLF_OBJTYPE_LIN_MESSAGE257:
3831 return blf_read_linmessage2(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, object_version);
3832
3833 case BLF_OBJTYPE_LIN_CRC_ERROR260:
3834 return blf_read_lincrcerror2(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, object_version);
3835
3836 case BLF_OBJTYPE_LIN_RCV_ERROR261:
3837 return blf_read_linrcverror2(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, object_version);
3838
3839 case BLF_OBJTYPE_LIN_SND_ERROR258:
3840 return blf_read_linsenderror2(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, object_version);
3841
3842 case BLF_OBJTYPE_LIN_WAKEUP262:
3843 return blf_read_linwakeupevent2(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3844
3845 case BLF_OBJTYPE_LIN_SLEEP20:
3846 return blf_read_linsleepmodeevent(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3847
3848 case BLF_OBJTYPE_APP_TEXT65:
3849 {
3850 int result = blf_read_apptextmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, &metadata_info);
3851 if (result == BLF_APPTEXT_CONT0x000000FE) {
3852 if (!metadata_info.valid) {
3853 /* First object of a sequence, save its start position */
3854 last_metadata_start = start_pos;
3855 metadata_info.valid = true1;
3856 }
3857 /* Save a pointer to the end of the buffer */
3858 metadata_info.metadata_cont = params->rec->data.first_free;
3859 } else {
3860 if (result == BLF_APPTEXT_METADATA0x00000002 && metadata_info.valid) {
3861 /* Last object of a sequence, restore the start position of the first object */
3862 params->blf_data->start_of_last_obj = last_metadata_start;
3863 }
3864 /* Reset everything and start fresh */
3865 metadata_info.valid = false0;
3866 }
3867 switch (result) {
3868 case BLF_APPTEXT_FAILED0x000000FF:
3869 return false0;
3870 case BLF_APPTEXT_COMMENT0x00000000:
3871 case BLF_APPTEXT_METADATA0x00000002:
3872 case BLF_APPTEXT_ATTACHMENT0x00000003:
3873 case BLF_APPTEXT_TRACELINE0x00000004:
3874 return true1;
3875 case BLF_APPTEXT_CHANNEL0x00000001:
3876 case BLF_APPTEXT_CONT0x000000FE:
3877 default:
3878 /* we do not return since there is no packet to show here */
3879 start_pos += MAX(MAX(16, header.object_length), header.header_length)((((((16) > (header.object_length)) ? (16) : (header.object_length
))) > (header.header_length)) ? ((((16) > (header.object_length
)) ? (16) : (header.object_length))) : (header.header_length)
)
;
3880 break;
3881 }
3882 }
3883 break;
3884
3885 case BLF_OBJTYPE_ETHERNET_STATUS103:
3886 return blf_read_ethernet_status(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, object_version);
3887
3888 case BLF_OBJTYPE_ETHERNET_PHY_STATE133:
3889 return blf_read_ethernet_phystate(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3890
3891 case BLF_OBJTYPE_ENV_INTEGER6:
3892 case BLF_OBJTYPE_ENV_DOUBLE7:
3893 case BLF_OBJTYPE_ENV_STRING8:
3894 case BLF_OBJTYPE_ENV_DATA9:
3895 case BLF_OBJTYPE_SYS_VARIABLE72:
3896 case BLF_OBJTYPE_RESERVED5115: /* Despite the name, this is actually used. Maybe it's worth investigating the content. */
3897 case BLF_OBJTYPE_TEST_STRUCTURE118:
3898 ws_debug("skipping unsupported object type 0x%04x", header.object_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3898, __func__, "skipping unsupported object type 0x%04x", header
.object_type); } } while (0)
;
3899 start_pos += MAX(MAX(16, header.object_length), header.header_length)((((((16) > (header.object_length)) ? (16) : (header.object_length
))) > (header.header_length)) ? ((((16) > (header.object_length
)) ? (16) : (header.object_length))) : (header.header_length)
)
;
3900 break;
3901 default:
3902 ws_info("unknown object type 0x%04x", header.object_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_INFO, ((void*)
0), -1, ((void*)0), "unknown object type 0x%04x", header.object_type
); } } while (0)
;
3903 start_pos += MAX(MAX(16, header.object_length), header.header_length)((((((16) > (header.object_length)) ? (16) : (header.object_length
))) > (header.header_length)) ? ((((16) > (header.object_length
)) ? (16) : (header.object_length))) : (header.header_length)
)
;
3904 break;
3905 }
3906 }
3907 return true1;
3908}
3909
3910static bool_Bool blf_read(wtap *wth, wtap_rec *rec, int *err, char **err_info, int64_t *data_offset) {
3911 blf_params_t blf_tmp;
3912
3913 blf_tmp.wth = wth;
3914 blf_tmp.fh = wth->fh;
3915 blf_tmp.random = false0;
3916 blf_tmp.pipe = wth->ispipe;
3917 blf_tmp.rec = rec;
3918 blf_tmp.blf_data = (blf_t *)wth->priv;
3919
3920 if (!blf_read_block(&blf_tmp, blf_tmp.blf_data->current_real_seek_pos, err, err_info)) {
3921 return false0;
3922 }
3923 *data_offset = blf_tmp.blf_data->start_of_last_obj;
3924
3925 return true1;
3926}
3927
3928static bool_Bool blf_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec, int *err, char **err_info) {
3929 blf_params_t blf_tmp;
3930
3931 blf_tmp.wth = wth;
3932 blf_tmp.fh = wth->random_fh;
3933 blf_tmp.random = true1;
3934 blf_tmp.pipe = wth->ispipe;
3935 blf_tmp.rec = rec;
3936 blf_tmp.blf_data = (blf_t *)wth->priv;
3937
3938 if (!blf_read_block(&blf_tmp, seek_off, err, err_info)) {
3939 ws_debug("couldn't read packet block (err=%d).", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3939, __func__, "couldn't read packet block (err=%d).", *err
); } } while (0)
;
3940 return false0;
3941 }
3942
3943 return true1;
3944}
3945
3946static void blf_free(blf_t *blf) {
3947 if (blf != NULL((void*)0)) {
3948 if (blf->log_containers != NULL((void*)0)) {
3949 for (unsigned i = 0; i < blf->log_containers->len; i++) {
3950 blf_log_container_t* log_container = &g_array_index(blf->log_containers, blf_log_container_t, i)(((blf_log_container_t*) (void *) (blf->log_containers)->
data) [(i)])
;
3951 if (log_container->real_data != NULL((void*)0)) {
3952 g_free(log_container->real_data)(__builtin_object_size ((log_container->real_data), 0) != (
(size_t) - 1)) ? g_free_sized (log_container->real_data, __builtin_object_size
((log_container->real_data), 0)) : (g_free) (log_container
->real_data)
;
3953 }
3954 }
3955 g_array_free(blf->log_containers, true1);
3956 blf->log_containers = NULL((void*)0);
3957 }
3958 if (blf->channel_to_iface_ht != NULL((void*)0)) {
3959 g_hash_table_destroy(blf->channel_to_iface_ht);
3960 blf->channel_to_iface_ht = NULL((void*)0);
3961 }
3962 if (blf->channel_to_name_ht != NULL((void*)0)) {
3963 g_hash_table_destroy(blf->channel_to_name_ht);
3964 blf->channel_to_name_ht = NULL((void*)0);
3965 }
3966 }
3967}
3968
3969static void blf_close(wtap *wth) {
3970 blf_free((blf_t *)wth->priv);
3971
3972 /* TODO: do we need to reverse the wtap_add_idb? how? */
3973}
3974
3975wtap_open_return_val
3976blf_open(wtap *wth, int *err, char **err_info) {
3977 blf_fileheader_t header;
3978 blf_t *blf;
3979
3980 ws_debug("opening file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3980, __func__, "opening file"); } } while (0)
;
3981
3982 if (!wtap_read_bytes_or_eof(wth->fh, &header, sizeof(blf_fileheader_t), err, err_info)) {
3983
3984 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3984, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
3985 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12) {
3986 /*
3987 * Short read or EOF.
3988 *
3989 * We're reading this as part of an open, so
3990 * the file is too short to be a blf file.
3991 */
3992 *err = 0;
3993 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
3994 *err_info = NULL((void*)0);
3995 return WTAP_OPEN_NOT_MINE;
3996 }
3997 return WTAP_OPEN_ERROR;
3998 }
3999
4000 fix_endianness_blf_fileheader(&header);
4001
4002 if (memcmp(header.magic, blf_magic, sizeof(blf_magic))) {
4003 return WTAP_OPEN_NOT_MINE;
4004 }
4005
4006 /* This seems to be an BLF! */
4007 /* Check for a valid header length */
4008 if (header.header_length < sizeof(blf_fileheader_t)) {
4009 *err = WTAP_ERR_BAD_FILE-13;
4010 *err_info = ws_strdup("blf: file header length too short")wmem_strdup(((void*)0), "blf: file header length too short");
4011 return WTAP_OPEN_ERROR;
4012 }
4013
4014 /* skip past the header, which may include padding/reserved space */
4015 if (!wtap_read_bytes(wth->fh, NULL((void*)0), header.header_length - sizeof(blf_fileheader_t), err, err_info)) {
4016 return WTAP_OPEN_ERROR;
4017 }
4018
4019 /* Prepare our private context. */
4020 blf = g_new(blf_t, 1)((blf_t *) g_malloc_n ((1), sizeof (blf_t)));
4021 blf->log_containers = g_array_new(FALSE(0), FALSE(0), sizeof(blf_log_container_t));
4022 blf->current_real_seek_pos = 0;
4023 blf->start_offset_ns = blf_data_to_ns(&header.start_date);
4024 blf->end_offset_ns = blf_data_to_ns(&header.end_date);
4025
4026 blf->channel_to_iface_ht = g_hash_table_new_full(g_int64_hash, g_int64_equal, &blf_free_key, &blf_free_channel_to_iface_entry);
4027 blf->channel_to_name_ht = g_hash_table_new_full(g_int64_hash, g_int64_equal, &blf_free_key, &blf_free_channel_to_name_entry);
4028 blf->next_interface_id = 0;
4029
4030 wth->priv = (void *)blf;
4031 wth->file_encap = WTAP_ENCAP_NONE-2;
4032 wth->snapshot_length = 0;
4033 wth->file_tsprec = WTAP_TSPREC_UNKNOWN-2;
4034 wth->file_start_ts.secs = blf->start_offset_ns / (1000 * 1000 * 1000);
4035 wth->file_start_ts.nsecs = blf->start_offset_ns % (1000 * 1000 * 1000);
4036 wth->file_end_ts.secs = blf->end_offset_ns / (1000 * 1000 * 1000);
4037 wth->file_end_ts.nsecs = blf->end_offset_ns % (1000 * 1000 * 1000);
4038 wth->subtype_read = blf_read;
4039 wth->subtype_seek_read = blf_seek_read;
4040 wth->subtype_close = blf_close;
4041 wth->file_type_subtype = blf_file_type_subtype;
4042
4043 wtap_block_t block = wtap_block_create(WTAP_BLOCK_SECTION);
4044 wtapng_section_mandatory_t *shb_mand = (wtapng_section_mandatory_t *)wtap_block_get_mandatory_data(block);
4045 shb_mand->section_length = UINT64_MAX(18446744073709551615UL);
4046
4047 wtap_block_add_string_option_format(block, OPT_SHB_USERAPPL4, "%s %d.%d.%d", try_val_to_str(header.application, blf_application_names),
4048 header.application_major, header.application_minor, header.application_build);
4049 wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (wth->shb_hdrs)->data) [(0)]
)
, block);
4050 wtap_block_unref(block);
4051
4052 return WTAP_OPEN_MINE;
4053}
4054
4055/* Options for interface blocks. */
4056static const struct supported_option_type interface_block_options_supported[] = {
4057 /* No comments, just an interface name. */
4058 { OPT_IDB_NAME2, ONE_OPTION_SUPPORTED }
4059};
4060
4061static const struct supported_block_type blf_blocks_supported[] = {
4062 { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED0, ((void*)0) },
4063 { WTAP_BLOCK_IF_ID_AND_INFO, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_block_options_supported)(sizeof (interface_block_options_supported) / sizeof (interface_block_options_supported
)[0]), interface_block_options_supported
},
4064};
4065
4066
4067/***********************/
4068/* BLF Writing Support */
4069/***********************/
4070
4071/* 10MB = 10485760 */
4072#define LOG_CONTAINER_BUFFER_SIZE10485760 10485760
4073
4074#define LOG_CONTAINER_NONE(18446744073709551615UL) UINT64_MAX(18446744073709551615UL)
4075
4076typedef struct _blf_writer_data {
4077 GArray *iface_to_channel_array;
4078 bool_Bool iface_to_channel_names_recovered;
4079
4080 blf_fileheader_t *fileheader;
4081 uint32_t object_count;
4082 uint64_t start_time;
4083 uint64_t end_time;
4084
4085 uint64_t logcontainer_start;
4086 blf_blockheader_t logcontainer_block_header;
4087 blf_logcontainerheader_t logcontainer_header;
4088
4089 /* Last object header, file position and content tracked
4090 in case padding is needed at end of log container*/
4091 uint64_t logobject_start;
4092 blf_blockheader_t logobject_block_header;
4093} blf_writer_data_t;
4094
4095static void
4096blf_dump_free(wtap_dumper *wdh)
4097{
4098 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4099
4100 g_array_unref(writer_data->iface_to_channel_array);
4101 g_free(writer_data->fileheader)(__builtin_object_size ((writer_data->fileheader), 0) != (
(size_t) - 1)) ? g_free_sized (writer_data->fileheader, __builtin_object_size
((writer_data->fileheader), 0)) : (g_free) (writer_data->
fileheader)
;
4102}
4103
4104static void
4105blf_dump_init_channel_to_iface_entry(blf_channel_to_iface_entry_t* tmp, unsigned int if_id) {
4106 tmp->channel = 0;
4107 tmp->hwchannel = UINT16_MAX(65535);
4108 tmp->interface_id = if_id;
4109 tmp->pkt_encap = WTAP_ENCAP_NONE-2;
4110}
4111
4112static void
4113blf_dump_expand_interface_mapping(wtap_dumper *wdh, unsigned new_size) {
4114 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4115
4116 unsigned old_size = writer_data->iface_to_channel_array->len;
4117
4118 if (old_size < new_size) {
4119 /* we need to expand array */
4120 g_array_set_size(writer_data->iface_to_channel_array, new_size);
4121
4122 for (unsigned int i = old_size; i < writer_data->iface_to_channel_array->len; i++) {
4123 blf_channel_to_iface_entry_t *tmp = &g_array_index(writer_data->iface_to_channel_array, blf_channel_to_iface_entry_t, i)(((blf_channel_to_iface_entry_t*) (void *) (writer_data->iface_to_channel_array
)->data) [(i)])
;
4124 blf_dump_init_channel_to_iface_entry(tmp, i);
4125 }
4126 }
4127}
4128
4129static bool_Bool
4130blf_dump_set_interface_mapping(wtap_dumper *wdh, uint32_t interface_id, int pkt_encap, uint16_t channel, uint16_t hw_channel) {
4131 if (channel == 0) {
4132 ws_warning("Trying to set channel to 0. That will probably lead to an unreadable file. Replacing by 1 to limit problem.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4132, __func__, "Trying to set channel to 0. That will probably lead to an unreadable file. Replacing by 1 to limit problem."
); } } while (0)
;
4133 channel = 1;
4134 }
4135
4136 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4137
4138 /*
4139 * XXX - will this ever happen add new mappings?
4140 *
4141 * We expand the interface mapping to include all known interfaces
4142 * at the time we open the dump file for writing and every time
4143 * we get notified of a new IDB.
4144 *
4145 * Does that miss any cases?
4146 */
4147 blf_dump_expand_interface_mapping(wdh, interface_id + 1);
4148
4149 blf_channel_to_iface_entry_t *tmp = &g_array_index(writer_data->iface_to_channel_array, blf_channel_to_iface_entry_t, interface_id)(((blf_channel_to_iface_entry_t*) (void *) (writer_data->iface_to_channel_array
)->data) [(interface_id)])
;
4150 tmp->channel = channel;
4151 tmp->hwchannel = hw_channel;
4152 tmp->interface_id = interface_id;
4153 tmp->pkt_encap = pkt_encap;
4154
4155 return true1;
4156}
4157
4158static blf_channel_to_iface_entry_t *
4159blf_dump_get_interface_mapping(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info) {
4160 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4161
4162 uint32_t interface_id = rec->rec_header.packet_header.interface_id;
4163 if (interface_id < writer_data->iface_to_channel_array->len) {
4164 return &g_array_index(writer_data->iface_to_channel_array, blf_channel_to_iface_entry_t, interface_id)(((blf_channel_to_iface_entry_t*) (void *) (writer_data->iface_to_channel_array
)->data) [(interface_id)])
;
4165 }
4166
4167 *err = WTAP_ERR_INTERNAL-21;
4168 *err_info = ws_strdup_printf("blf: cannot find interface mapping for %u", interface_id)wmem_strdup_printf(((void*)0), "blf: cannot find interface mapping for %u"
, interface_id)
;
4169 ws_critical("BLF Interface Mapping cannot be found.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_CRITICAL, "wiretap/blf.c"
, 4169, __func__, "BLF Interface Mapping cannot be found."); }
} while (0)
;
4170
4171 return NULL((void*)0);
4172}
4173
4174static bool_Bool
4175blf_init_file_header(wtap_dumper *wdh, int *err) {
4176 if (wdh == NULL((void*)0) || wdh->priv == NULL((void*)0)) {
4177 *err = WTAP_ERR_INTERNAL-21;
4178 ws_debug("internal error: blf private data not found.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4178, __func__, "internal error: blf private data not found."
); } } while (0)
;
4179 return false0;
4180 }
4181
4182 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4183
4184 /* currently only support 144 byte length*/
4185 writer_data->fileheader = (blf_fileheader_t*)g_malloc0(144);
4186
4187 /* set magic */
4188 int i;
4189 for (i = 0; i < 4; i++) {
4190 writer_data->fileheader->magic[i] = blf_magic[i];
4191 }
4192
4193 /* currently only support 144 byte length*/
4194 writer_data->fileheader->header_length = 144;
4195
4196 writer_data->fileheader->application_major = WIRESHARK_VERSION_MAJOR5;
4197 writer_data->fileheader->application_minor = WIRESHARK_VERSION_MINOR1;
4198 writer_data->fileheader->application_build = WIRESHARK_VERSION_MICRO0;
4199
4200 return true1;
4201}
4202
4203static bool_Bool
4204blf_write_add_padding(wtap_dumper *wdh, int *err, uint8_t count) {
4205 if (count > 0 && count < 4) {
4206 uint8_t padding[3] = { 0 };
4207 if (!wtap_dump_file_write(wdh, &padding, count, err)) {
4208 return false0;
4209 }
4210 }
4211 return true1;
4212}
4213
4214static bool_Bool
4215blf_write_file_header_zeros(wtap_dumper *wdh, int *err) {
4216 /* lets add 144 bytes for the header and padding */
4217 uint8_t padding[144] = { 0 };
4218 if (!wtap_dump_file_write(wdh, &padding, 144, err)) {
4219 return false0;
4220 }
4221
4222 return true1;
4223}
4224
4225static void
4226blf_write_date_to_blf_header(blf_fileheader_t *fileheader, bool_Bool start, uint64_t ns_timestamp) {
4227 struct tm tmp;
4228 const time_t date = (time_t)(ns_timestamp / (1000 * 1000 * 1000));
4229
4230 if (ws_localtime_r(&date, &tmp) != NULL((void*)0)) {
4231 blf_date_t *target = start ? &(fileheader->start_date) : &(fileheader->end_date);
4232 target->year = 1900 + tmp.tm_year;
4233 target->month = tmp.tm_mon + 1;
4234 target->day = tmp.tm_mday;
4235 target->hour = tmp.tm_hour;
4236 target->mins = tmp.tm_min;
4237 target->sec = tmp.tm_sec;
4238
4239 uint64_t tmp_date = blf_data_to_ns((const blf_date_t *)target);
4240
4241 target->ms = (uint16_t)((ns_timestamp - tmp_date) / (1000 * 1000));
4242 }
4243
4244}
4245
4246static bool_Bool
4247blf_finalize_file_header(wtap_dumper *wdh, int *err) {
4248 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4249 blf_fileheader_t *fileheader = writer_data->fileheader;
4250 int64_t bytes_written = wtap_dump_file_tell(wdh, err);
4251 if (bytes_written == -1 || *err != 0) {
4252 return false0;
4253 }
4254
4255 /* update the header and convert all to LE */
4256 fileheader->api_version = (((WIRESHARK_VERSION_MAJOR5 * 100) + WIRESHARK_VERSION_MINOR1) * 100 + WIRESHARK_VERSION_MICRO0) * 100;
4257 fileheader->application_major = WIRESHARK_VERSION_MAJOR5;
4258 fileheader->application_minor = WIRESHARK_VERSION_MINOR1;
4259 fileheader->application_build = WIRESHARK_VERSION_MICRO0;
4260
4261 fileheader->len_compressed = (uint64_t)bytes_written;
4262 fileheader->len_uncompressed = (uint64_t)bytes_written;
4263
4264 fileheader->obj_count = writer_data->object_count;
4265
4266 blf_write_date_to_blf_header(fileheader, true1, writer_data->start_time);
4267 blf_write_date_to_blf_header(fileheader, false0, writer_data->end_time);
4268
4269 fix_endianness_blf_fileheader(fileheader);
4270
4271 /* seek to start of file */
4272 int64_t tmp = wtap_dump_file_seek(wdh, 0, SEEK_SET0, err);
4273 if (*err != 0 || tmp != 0) {
4274 return false0;
4275 }
4276
4277 if (!wtap_dump_file_write(wdh, fileheader, fileheader->header_length, err)) {
4278 return false0;
4279 }
4280
4281 return true1;
4282}
4283
4284static bool_Bool blf_dump_write_logcontainer(wtap_dumper *wdh, int *err, char **err_info _U___attribute__((unused))) {
4285 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4286
4287 if (!wtap_dump_file_write(wdh, &(writer_data->logcontainer_block_header), sizeof(blf_blockheader_t), err)) {
4288 ws_debug("Cannot write Log Container Block Header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4288, __func__, "Cannot write Log Container Block Header");
} } while (0)
;
4289 return false0;
4290 }
4291
4292 if (!wtap_dump_file_write(wdh, &(writer_data->logcontainer_header), sizeof(blf_logcontainerheader_t), err)) {
4293 ws_debug("Cannot write Log Container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4293, __func__, "Cannot write Log Container"); } } while (0
)
;
4294 return false0;
4295 }
4296
4297 return true1;
4298}
4299
4300static bool_Bool blf_dump_pad_last_object(wtap_dumper *wdh, int *err, uint8_t padding_count) {
4301 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4302
4303 int64_t current_position = wtap_dump_file_tell(wdh, err);
4304 if (current_position == -1 || *err != 0) {
4305 return false0;
4306 }
4307
4308 if(!blf_write_add_padding(wdh, err, padding_count)) {
4309 return false0;
4310 }
4311 current_position += padding_count;
4312 writer_data->logobject_block_header.object_length += padding_count;
4313
4314 /* Copy out blockheader before fixing endianness */
4315 blf_blockheader_t blockheader = writer_data->logobject_block_header;
4316 fix_endianness_blf_blockheader(&blockheader);
4317
4318 int64_t tmp = wtap_dump_file_seek(wdh, writer_data->logobject_start, SEEK_SET0, err);
4319 if (*err != 0 || tmp != 0) {
4320 return false0;
4321 }
4322
4323 if (!wtap_dump_file_write(wdh, &(blockheader), sizeof(blf_blockheader_t), err)) {
4324 return false0;
4325 }
4326
4327 tmp = wtap_dump_file_seek(wdh, current_position, SEEK_SET0, err);
4328 if (*err != 0 || tmp != 0) {
4329 return false0;
4330 }
4331
4332 return true1;
4333}
4334
4335static bool_Bool blf_dump_close_logcontainer(wtap_dumper *wdh, int *err, char **err_info) {
4336 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4337
4338 int64_t current_position = wtap_dump_file_tell(wdh, err);
4339 if (current_position == -1 || *err != 0) {
4340 return false0;
4341 }
4342 int64_t logcontainer_length = current_position - writer_data->logcontainer_start;
4343 if (logcontainer_length < 32) {
4344 *err = WTAP_ERR_INTERNAL-21;
4345 }
4346
4347 /* Add padding to last object, to ensure logcontainer ends at 4 byte alignment.
4348 Improves compatibility with other tools. */
4349 uint8_t padding_needed = logcontainer_length % 4;
4350 if (padding_needed != 0) {
4351 padding_needed = 4 - padding_needed;
4352 if (!blf_dump_pad_last_object(wdh, err, padding_needed)) {
4353 return false0;
4354 }
4355 logcontainer_length += padding_needed;
4356 current_position += padding_needed;
4357 }
4358
4359 int64_t tmp = wtap_dump_file_seek(wdh, writer_data->logcontainer_start, SEEK_SET0, err);
4360 if (*err != 0 || tmp != 0) {
4361 return false0;
4362 }
4363
4364 writer_data->logcontainer_block_header.object_length = GUINT32_TO_LE((uint32_t)logcontainer_length)((guint32) ((uint32_t)logcontainer_length));
4365 writer_data->logcontainer_header.uncompressed_size = GUINT32_TO_LE((uint32_t)(logcontainer_length - 32))((guint32) ((uint32_t)(logcontainer_length - 32)));
4366
4367 if (!blf_dump_write_logcontainer(wdh, err, err_info)) {
4368 return false0;
4369 }
4370
4371 tmp = wtap_dump_file_seek(wdh, current_position, SEEK_SET0, err);
4372 if (*err != 0 || tmp != 0) {
4373 return false0;
4374 }
4375
4376 return true1;
4377}
4378
4379static bool_Bool blf_dump_start_logcontainer(wtap_dumper *wdh, int *err, char **err_info) {
4380 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4381
4382 if (writer_data->logcontainer_start != LOG_CONTAINER_NONE(18446744073709551615UL)) {
4383 if (!blf_dump_close_logcontainer(wdh, err, err_info)) {
4384 return false0;
4385 }
4386 }
4387
4388 /* start new log container */
4389 /* set magic */
4390 int i;
4391 for (i = 0; i < 4; i++) {
4392 writer_data->logcontainer_block_header.magic[i] = blf_obj_magic[i];
4393 }
4394 writer_data->logcontainer_block_header.header_length = 16;
4395 writer_data->logcontainer_block_header.header_type = 1;
4396 writer_data->logcontainer_block_header.object_length = 32;
4397 writer_data->logcontainer_block_header.object_type = BLF_OBJTYPE_LOG_CONTAINER10;
4398 fix_endianness_blf_blockheader(&(writer_data->logcontainer_block_header));
4399
4400 writer_data->logcontainer_header.compression_method = 0;
4401 writer_data->logcontainer_header.res1 = 0;
4402 writer_data->logcontainer_header.res2 = 0;
4403 writer_data->logcontainer_header.uncompressed_size = 0;
4404 writer_data->logcontainer_header.res4 = 0;
4405 fix_endianness_blf_logcontainerheader(&(writer_data->logcontainer_header));
4406
4407 writer_data->logcontainer_start = wtap_dump_file_tell(wdh, err);
4408 if (*err != 0) {
4409 return false0;
4410 }
4411
4412 return blf_dump_write_logcontainer(wdh, err, err_info);
4413}
4414
4415static bool_Bool blf_dump_check_logcontainer_full(wtap_dumper *wdh, int *err, char **err_info, uint32_t length) {
4416 const blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4417
4418 uint64_t position = (uint64_t)wtap_dump_file_tell(wdh, err);
4419 if (*err != 0) {
4420 return false0;
4421 }
4422 if (position - writer_data->logcontainer_start + length <= LOG_CONTAINER_BUFFER_SIZE10485760) {
4423 return true1;
4424 }
4425
4426 return blf_dump_start_logcontainer(wdh, err, err_info);
4427}
4428
4429static bool_Bool blf_dump_objheader(wtap_dumper *wdh, int *err, uint64_t obj_timestamp, uint32_t obj_type, uint32_t obj_length) {
4430 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4431 blf_logobjectheader_t logheader;
4432 logheader.flags = BLF_TIMESTAMP_RESOLUTION_1NS2;
4433 logheader.client_index = 0;
4434 logheader.object_version = 1;
4435 logheader.object_timestamp = obj_timestamp;
4436 fix_endianness_blf_logobjectheader(&logheader);
4437
4438 blf_blockheader_t blockheader;
4439 /* set magic */
4440 int i;
4441 for (i = 0; i < 4; i++) {
4442 blockheader.magic[i] = blf_obj_magic[i];
4443 }
4444 blockheader.header_length = sizeof(blf_blockheader_t) + sizeof(blf_logobjectheader_t);
4445 blockheader.header_type = 1;
4446 blockheader.object_length = sizeof(blf_blockheader_t) + sizeof(blf_logobjectheader_t) + obj_length;
4447 blockheader.object_type = obj_type;
4448
4449 /* Track blockheader of object, in case padding is needed at end of log container */
4450 writer_data->logobject_start = wtap_dump_file_tell(wdh, err);
4451 writer_data->logobject_block_header = blockheader;
4452
4453 fix_endianness_blf_blockheader(&blockheader);
4454
4455 if (!wtap_dump_file_write(wdh, &(blockheader), sizeof(blf_blockheader_t), err)) {
4456 return false0;
4457 }
4458
4459 if (!wtap_dump_file_write(wdh, &(logheader), sizeof(blf_logobjectheader_t), err)) {
4460 return false0;
4461 }
4462
4463 /* Successful writing done, time to update count */
4464 writer_data->object_count += 1;
4465
4466 return true1;
4467}
4468
4469/* return standard direction format of BLF, RX on error or unknown */
4470static uint8_t blf_get_direction(const wtap_rec *rec) {
4471 uint32_t tmp_direction = 0;
4472 if (WTAP_OPTTYPE_SUCCESS != wtap_block_get_uint32_option_value(rec->block, OPT_PKT_FLAGS2, &tmp_direction)) {
4473 return BLF_DIR_RX0;
4474 }
4475
4476 if (tmp_direction == PACK_FLAGS_DIRECTION_OUTBOUND2) {
4477 return BLF_DIR_TX1;
4478
4479 }
4480
4481 return BLF_DIR_RX0;
4482}
4483
4484static bool_Bool blf_dump_ethernet(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4485 /* LINKTYPE_ETHERNET */
4486 /* https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html */
4487
4488 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4489 const blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4490 if (iface_entry == NULL((void*)0)) {
4491 return false0;
4492 }
4493
4494 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4495 size_t length = ws_buffer_length(&rec->data);
4496
4497 /* 14 bytes is the full Ethernet Header up to EtherType */
4498 if (length < 14) {
4499 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4500 *err_info = ws_strdup_printf("blf: record length %zu for Ethernet message is less than minimum of 14", length)wmem_strdup_printf(((void*)0), "blf: record length %zu for Ethernet message is less than minimum of 14"
, length)
;
4501 return false0;
4502 }
4503
4504 uint32_t offset = 12;
4505
4506 blf_ethernetframeheader_t ethheader;
4507 ethheader.src_addr[0] = pd[6];
4508 ethheader.src_addr[1] = pd[7];
4509 ethheader.src_addr[2] = pd[8];
4510 ethheader.src_addr[3] = pd[9];
4511 ethheader.src_addr[4] = pd[10];
4512 ethheader.src_addr[5] = pd[11];
4513
4514 ethheader.channel = iface_entry->channel;
4515
4516 ethheader.dst_addr[0] = pd[0];
4517 ethheader.dst_addr[1] = pd[1];
4518 ethheader.dst_addr[2] = pd[2];
4519 ethheader.dst_addr[3] = pd[3];
4520 ethheader.dst_addr[4] = pd[4];
4521 ethheader.dst_addr[5] = pd[5];
4522
4523 ethheader.direction = blf_get_direction(rec);
4524
4525 uint16_t eth_type = pntohu16(pd + offset);
4526 offset += 2;
4527
4528 if (eth_type == 0x8100 || eth_type == 0x9100 || eth_type == 0x88a8) {
4529 if (length < 18) {
4530 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4531 *err_info = ws_strdup_printf("blf: record length %zu for VLAN-tagged Ethernet frame is less than minimum of 18", length)wmem_strdup_printf(((void*)0), "blf: record length %zu for VLAN-tagged Ethernet frame is less than minimum of 18"
, length)
;
4532 return false0;
4533 }
4534 ethheader.tpid = eth_type;
4535 ethheader.tci = pntohu16(pd + offset);
4536 offset += 2;
4537
4538 eth_type = pntohu16(pd + offset);
4539 offset += 2;
4540 } else {
4541 ethheader.tpid = 0;
4542 ethheader.tci = 0;
4543 }
4544
4545 ethheader.ethtype = eth_type;
4546 if (ckd_sub(&ethheader.payloadlength, length, offset)__builtin_sub_overflow((length), (offset), (&ethheader.payloadlength
))
) {
4547 /* Congratulations! You may have spotted a IPv6 Jumbogram (RFC 2675)!
4548 * You're another lucky winner of a Wiretap No-Prize! */
4549 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4550 *err_info = ws_strdup_printf("blf: Ethernet payload length %zu is too big", length - offset)wmem_strdup_printf(((void*)0), "blf: Ethernet payload length %zu is too big"
, length - offset)
;
4551 return false0;
4552 }
4553 ethheader.res = 0;
4554 fix_endianness_blf_ethernetframeheader(&ethheader);
4555
4556 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_ETHERNET_FRAME71, sizeof(blf_ethernetframeheader_t) + ethheader.payloadlength)) {
4557 return false0;
4558 }
4559
4560 if (!wtap_dump_file_write(wdh, &(ethheader), sizeof(blf_ethernetframeheader_t), err)) {
4561 return false0;
4562 }
4563
4564 if (!wtap_dump_file_write(wdh, &(pd[offset]), ethheader.payloadlength, err)) {
4565 return false0;
4566 }
4567
4568 /* Add strange padding to 4 bytes. */
4569 uint8_t padding_needed = (sizeof(blf_ethernetframeheader_t) + ethheader.payloadlength) % 4;
4570 return blf_write_add_padding(wdh, err, padding_needed);
4571}
4572
4573static bool_Bool blf_dump_socketcanxl(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp,
4574 const uint8_t *pd, size_t length, bool_Bool is_rx, bool_Bool is_tx) {
4575 /* LINKTYPE_CAN_SOCKETCAN */
4576 /* https://www.tcpdump.org/linktypes/LINKTYPE_CAN_SOCKETCAN.html */
4577
4578 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4579 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4580 if (iface_entry == NULL((void*)0)) {
4581 return false0;
4582 }
4583
4584 if (length < 12) {
4585 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4586 *err_info = ws_strdup_printf("blf: record length %u for Socket CAN XL message header is lower than minimum of 12", (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: record length %u for Socket CAN XL message header is lower than minimum of 12"
, (uint32_t)length)
;
4587 ws_debug("LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4587, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL)."
); } } while (0)
;
4588 return false0;
4589 }
4590
4591 uint8_t socketcan_vcid = pd[1];
4592 uint16_t socketcan_id = pntohu16(pd + 2) & CAN_SFF_MASK0x000007FF;
4593 uint8_t socketcan_flags = pd[4];
4594 uint8_t socketcan_sdut = pd[5];
4595 uint16_t socketcan_payload_length = pletohu16(pd + 6);
4596
4597 if ((socketcan_flags & CANXL_XLF0x80) != CANXL_XLF0x80) {
4598 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4599 *err_info = ws_strdup_printf("blf: Socket CAN XL message does not have XL Flag set.")wmem_strdup_printf(((void*)0), "blf: Socket CAN XL message does not have XL Flag set."
)
;
4600 ws_debug("LINKTYPE_CAN_SOCKETCAN CAN XL flag not set for CAN XL?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4600, __func__, "LINKTYPE_CAN_SOCKETCAN CAN XL flag not set for CAN XL?"
); } } while (0)
;
4601 return false0;
4602 }
4603
4604 if (length < (size_t)socketcan_payload_length + 12) {
4605 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4606 *err_info = ws_strdup_printf("blf: Socket CAN message (length %u) does not contain full payload (%u) (CAN XL)", (uint32_t)length, socketcan_payload_length)wmem_strdup_printf(((void*)0), "blf: Socket CAN message (length %u) does not contain full payload (%u) (CAN XL)"
, (uint32_t)length, socketcan_payload_length)
;
4607 ws_debug("LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4607, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL)."
); } } while (0)
;
4608 return false0;
4609 }
4610 uint32_t socketcan_acceptance_field = pletohu32(pd + 8);
4611
4612 /* LINKTYPE_LINUX_SLL would have set is_tx or is_rx */
4613 uint8_t frame_dir = is_tx ? BLF_DIR_TX1 : BLF_DIR_RX0;
4614 if (!is_rx && !is_tx) {
4615 frame_dir = blf_get_direction(rec);
4616 }
4617
4618 blf_canxlchannelframe_t canxl = {0};
4619 canxl.channel = (uint8_t)iface_entry->channel;
4620 canxl.dir = frame_dir;
4621 canxl.frameIdentifier = socketcan_id;
4622 canxl.serviceDataUnitType = socketcan_sdut;
4623 canxl.dlc = socketcan_payload_length - 1;
4624 canxl.dataLength = socketcan_payload_length;
4625 canxl.virtualControllerAreaNetChannelID = socketcan_vcid;
4626 canxl.acceptanceField = socketcan_acceptance_field;
4627
4628 if ((socketcan_flags & CANXL_XLF0x80) == CANXL_XLF0x80) {
4629 /* should be always true but we might refactor */
4630 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000;
4631 }
4632 if ((socketcan_flags & CANXL_SEC0x01) == CANXL_SEC0x01) {
4633 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_SEC0x1000000;
4634 }
4635 if ((socketcan_flags & CANXL_RRS0x02) == CANXL_RRS0x02) {
4636 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_RRS0x800000;
4637 }
4638
4639 fix_endianness_blf_canxlchannelframe(&canxl);
4640
4641 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_XL_CHANNEL_FRAME139, sizeof(blf_canxlchannelframe_t) + socketcan_payload_length)) {
4642 return false0;
4643 }
4644
4645 if (!wtap_dump_file_write(wdh, &(canxl), sizeof(blf_canxlchannelframe_t), err)) {
4646 return false0;
4647 }
4648
4649 if (!wtap_dump_file_write(wdh, &(pd[12]), socketcan_payload_length, err)) {
4650 return false0;
4651 }
4652
4653 return true1;
4654}
4655
4656static const uint8_t canfd_length_to_dlc[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 9, 0, 0, 0,
4657 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
4658 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4659 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4660 15 };
4661
4662static bool_Bool blf_dump_socketcan(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp,
4663 const uint8_t *pd, size_t length, bool_Bool is_can, bool_Bool is_canfd, bool_Bool is_rx, bool_Bool is_tx) {
4664 /* LINKTYPE_CAN_SOCKETCAN */
4665 /* https://www.tcpdump.org/linktypes/LINKTYPE_CAN_SOCKETCAN.html */
4666
4667 if (length < 8) {
4668 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4669 *err_info = ws_strdup_printf("blf: record length %u for Socket CAN message header is lower than minimum of 8", (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: record length %u for Socket CAN message header is lower than minimum of 8"
, (uint32_t)length)
;
4670 ws_debug("LINKTYPE_CAN_SOCKETCAN header is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4670, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short."
); } } while (0)
;
4671 return false0;
4672 }
4673
4674 /* check for CAN-XL */
4675 if ((pd[4] & CANXL_XLF0x80) == CANXL_XLF0x80) {
4676 return blf_dump_socketcanxl(wdh, rec, err, err_info, obj_timestamp, pd, length, is_rx, is_tx);
4677 }
4678
4679 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4680 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4681 if (iface_entry == NULL((void*)0)) {
4682 return false0;
4683 }
4684
4685 uint8_t payload_length = pd[4];
4686
4687 if (length < (size_t)payload_length + 8) {
4688 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4689 *err_info = ws_strdup_printf("blf: Socket CAN message (length %u) does not contain full payload (%u)", (uint32_t)length, payload_length)wmem_strdup_printf(((void*)0), "blf: Socket CAN message (length %u) does not contain full payload (%u)"
, (uint32_t)length, payload_length)
;
4690 ws_debug("LINKTYPE_CAN_SOCKETCAN header is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4690, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short."
); } } while (0)
;
4691 return false0;
4692 }
4693
4694 /* LINKTYPE_LINUX_SLL would have set is_tx or is_rx */
4695 uint8_t frame_dir = is_tx ? BLF_DIR_TX1 : BLF_DIR_RX0;
4696 if (!is_rx && !is_tx) {
4697 frame_dir = blf_get_direction(rec);
4698 }
4699
4700 bool_Bool canfd = is_canfd;
4701
4702 /* LINKTYPE_LINUX_SLL would have set one */
4703 if (!is_can && !is_canfd) {
4704 if ((pd[5] & CANFD_FDF0x04) == CANFD_FDF0x04) {
4705 canfd = true1;
4706 } else {
4707 /* heuristic. if longer than header + 8 bytes data, its CAN-FD*/
4708 canfd = rec->rec_header.packet_header.caplen > 16;
4709 }
4710 }
4711
4712 /* XXX endianness is not defined. Assuming BE as this seems the common choice*/
4713 uint32_t can_id = pntohu32(pd);
4714
4715 /* lets check if can_id makes sense
4716 * 29bit CAN ID mask 0x1fffffff CAN_EFF_MASK
4717 * 11bit CAN ID mask 0x000007ff CAN_SFF_MASK
4718 * 29 only bits 0x1ffff800 CAN_EFF_MASK & !CAN_SFF_MASK
4719 */
4720 if (((can_id & CAN_EFF_FLAG0x80000000) == 0) && ((can_id & (CAN_EFF_MASK0x1FFFFFFF & (!CAN_SFF_MASK0x000007FF))) != 0)) {
4721 ws_message("CAN-ID 0x%08x seems to be in wrong byte order, changing to little-endian", can_id)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_MESSAGE, ((void
*)0), -1, ((void*)0), "CAN-ID 0x%08x seems to be in wrong byte order, changing to little-endian"
, can_id); } } while (0)
;
4722 can_id = pletohu32(pd);
4723 }
4724
4725 bool_Bool err_flag = (can_id & CAN_ERR_FLAG0x20000000) == CAN_ERR_FLAG0x20000000;
4726 bool_Bool rtr_flag = (can_id & CAN_RTR_FLAG0x40000000) == CAN_RTR_FLAG0x40000000;
4727 //bool ext_id_flag = (can_id & CAN_EFF_FLAG) == CAN_EFF_FLAG;
4728 can_id &= (CAN_EFF_MASK0x1FFFFFFF | CAN_EFF_FLAG0x80000000);
4729
4730 if (canfd) {
4731 /* CAN-FD */
4732 bool_Bool brs_flag = (pd[5] & CANFD_BRS0x01) == CANFD_BRS0x01;
4733 bool_Bool esi_flag = (pd[5] & CANFD_ESI0x02) == CANFD_ESI0x02;
4734 bool_Bool fdf_flag = (pd[5] & CANFD_FDF0x04) == CANFD_FDF0x04;
4735
4736 blf_canfdmessage64_t canfdmsg;
4737 canfdmsg.channel = (uint8_t)iface_entry->channel;
4738
4739 canfdmsg.dlc = (payload_length <= 64) ? canfd_length_to_dlc[payload_length] : 0;
4740 canfdmsg.validDataBytes = payload_length;
4741 canfdmsg.txCount = 0;
4742 canfdmsg.id = can_id;
4743 canfdmsg.frameLength_in_ns = 0;
4744 canfdmsg.flags = 0;
4745
4746 /* TODO: fdf_flag is not always set for CAN-FD */
4747 if (fdf_flag) {
4748 canfdmsg.flags = BLF_CANFDMESSAGE64_FLAG_EDL0x001000; // CAN-FD
4749 } else {
4750 ws_warning("CAN-FD has not CANFD_FDF set. File not correct.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4750, __func__, "CAN-FD has not CANFD_FDF set. File not correct."
); } } while (0)
;
4751 }
4752 if (brs_flag) {
4753 canfdmsg.flags |= BLF_CANFDMESSAGE64_FLAG_BRS0x002000;
4754 }
4755 if (esi_flag) {
4756 canfdmsg.flags |= BLF_CANFDMESSAGE64_FLAG_ESI0x004000;
4757 }
4758
4759 canfdmsg.btrCfgArb = 0;
4760 canfdmsg.btrCfgData = 0;
4761 canfdmsg.timeOffsetBrsNs = 0;
4762 canfdmsg.timeOffsetCrcDelNs = 0;
4763 canfdmsg.bitCount = 0;
4764 canfdmsg.dir = frame_dir;
4765 canfdmsg.extDataOffset = 0;
4766 canfdmsg.crc = 0;
4767
4768 fix_endianness_blf_canfdmessage64(&canfdmsg);
4769
4770 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_FD_MESSAGE_64101, sizeof(blf_canfdmessage64_t) + payload_length)) {
4771 return false0;
4772 }
4773
4774 if (!wtap_dump_file_write(wdh, &(canfdmsg), sizeof(blf_canfdmessage64_t), err)) {
4775 return false0;
4776 }
4777 } else {
4778 /* CAN */
4779 blf_canmessage_t canmsg;
4780
4781 if (payload_length > 8) {
4782 ws_warning("CAN frames can only have up to 8 bytes of payload! We have %d bytes", payload_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4782, __func__, "CAN frames can only have up to 8 bytes of payload! We have %d bytes"
, payload_length); } } while (0)
;
4783 payload_length = 8;
4784 }
4785
4786 canmsg.dlc = payload_length;
4787 canmsg.channel = iface_entry->channel;
4788
4789 canmsg.flags = 0;
4790 if (frame_dir == BLF_DIR_TX1) {
4791 canmsg.flags |= BLF_CANMESSAGE_FLAG_TX0x01;
4792 }
4793
4794 if (err_flag) {
4795 // TODO: we need to implement CAN ERROR, ignore for now
4796 return true1;
4797 //canmsg.flags |= BLF_CANMESSAGE_FLAG_NERR; - NERR is not error
4798 }
4799
4800 if (rtr_flag) {
4801 canmsg.flags |= BLF_CANMESSAGE_FLAG_RTR0x80;
4802 }
4803
4804 canmsg.id = can_id;
4805
4806 fix_endianness_blf_canmessage(&canmsg);
4807
4808 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_MESSAGE1, sizeof(blf_canmessage_t) + 8)) {
4809 return false0;
4810 }
4811
4812 if (!wtap_dump_file_write(wdh, &(canmsg), sizeof(blf_canmessage_t), err)) {
4813 return false0;
4814 }
4815 }
4816
4817 if (!wtap_dump_file_write(wdh, &(pd[8]), payload_length, err)) {
4818 return false0;
4819 }
4820
4821 if (!canfd && payload_length < 8) {
4822 uint8_t padding[8] = { 0 };
4823 if (!wtap_dump_file_write(wdh, &padding, 8 - payload_length, err)) {
4824 return false0;
4825 }
4826 }
4827
4828 /* no padding */
4829
4830 return true1;
4831}
4832
4833static bool_Bool blf_dump_sll(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4834 /* Linux Cooked CAN / CAN-FD */
4835 /* https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html */
4836
4837 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4838 size_t length = ws_buffer_length(&rec->data);
4839
4840 if (length < 16) {
4841 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4842 *err_info = ws_strdup_printf("blf: record length %u for CAN message header (LINKTYPE_LINUX_SLL) is lower than minimum of 16", (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: record length %u for CAN message header (LINKTYPE_LINUX_SLL) is lower than minimum of 16"
, (uint32_t)length)
;
4843 ws_debug("LINKTYPE_LINUX_SLL header is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4843, __func__, "LINKTYPE_LINUX_SLL header is too short.");
} } while (0)
;
4844 return false0;
4845 }
4846
4847 bool_Bool frame_tx = false0;
4848 if (pd[0] == 0 && pd[1] == 4) {
4849 frame_tx = true1;
4850 }
4851
4852 uint16_t protocol_type = pntohu16(pd + 14);
4853
4854 switch (protocol_type) {
4855 case 0x000C: /* CAN */
4856 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, true1, false0, !frame_tx, frame_tx);
4857 break;
4858 case 0x000D: /* CAN-FD */
4859 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, false0, true1, !frame_tx, frame_tx);
4860 break;
4861 case 0x000E: /* CAN-XL */
4862 return blf_dump_socketcanxl(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, !frame_tx, frame_tx);
4863 break;
4864 default:
4865 return false0;
4866 }
4867
4868 /* not reachable? */
4869 return true1;
4870}
4871
4872static bool_Bool blf_dump_flexray(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4873 /* FlexRay */
4874 /* https://www.tcpdump.org/linktypes/LINKTYPE_FLEXRAY.html */
4875
4876 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4877 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4878 if (iface_entry == NULL((void*)0)) {
4879 return false0;
4880 }
4881
4882 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4883 size_t length = ws_buffer_length(&rec->data);
4884
4885 if (length < 1) {
4886 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4887 *err_info = ws_strdup_printf("blf: record length %u for FlexRay header (LINKTYPE_FLEXRAY) is lower than minimum of 1", (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: record length %u for FlexRay header (LINKTYPE_FLEXRAY) is lower than minimum of 1"
, (uint32_t)length)
;
4888 ws_debug("LINKTYPE_FLEXRAY header is too short (< 1 Byte).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4888, __func__, "LINKTYPE_FLEXRAY header is too short (< 1 Byte)."
); } } while (0)
;
4889 return false0;
4890 }
4891
4892 /* Check Measurement Header for Type */
4893 if ((pd[0] & FLEXRAY_TYPE_MASK0x7f) == FLEXRAY_SYMBOL0x02) {
4894 /* Symbol */
4895
4896 if (length < 2) {
4897 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4898 *err_info = ws_strdup_printf("blf: record length %u for FlexRay Symbol (LINKTYPE_FLEXRAY) is lower than minimum of 2", (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: record length %u for FlexRay Symbol (LINKTYPE_FLEXRAY) is lower than minimum of 2"
, (uint32_t)length)
;
4899 ws_debug("LINKTYPE_FLEXRAY Symbol is too short (< 2 Byte).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4899, __func__, "LINKTYPE_FLEXRAY Symbol is too short (< 2 Byte)."
); } } while (0)
;
4900 return false0;
4901 }
4902
4903 /* TODO: SYMBOL */
4904
4905 return true1;
4906 }
4907
4908 if ((pd[0] & FLEXRAY_TYPE_MASK0x7f) == FLEXRAY_FRAME0x01) {
4909 /* Frame */
4910
4911 if (length < 2 + FLEXRAY_HEADER_LENGTH5) {
4912 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4913 *err_info = ws_strdup_printf("blf: record length %u for FlexRay Frame header (LINKTYPE_FLEXRAY) is lower than minimum of 7", (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: record length %u for FlexRay Frame header (LINKTYPE_FLEXRAY) is lower than minimum of 7"
, (uint32_t)length)
;
4914 ws_debug("LINKTYPE_FLEXRAY Frame Header is too short (< 7 Byte).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4914, __func__, "LINKTYPE_FLEXRAY Frame Header is too short (< 7 Byte)."
); } } while (0)
;
4915 return false0;
4916 }
4917
4918 uint8_t payload_length = pd[4] & FLEXRAY_LENGTH_MASK0xfe;
4919
4920 /* FLEXRAY FRAME */
4921 blf_flexrayrcvmessage_t frmsg;
4922
4923 frmsg.channel = (uint16_t)iface_entry->channel;
4924 frmsg.version = 1;
4925
4926 uint32_t header_crc = (pntohu24(pd + 4) & FLEXRAY_HEADER_CRC_MASK0x01ffc0) >> FLEXRAY_HEADER_CRC_SHFT6;
4927
4928 if ((pd[0] & FLEXRAY_CHANNEL_MASK0x80) == 0) {
4929 frmsg.channelMask = BLF_FLEXRAYRCVMSG_CHANNELMASK_A0x01;
4930 frmsg.headerCrc1 = header_crc;
4931 frmsg.headerCrc2 = 0;
4932 } else {
4933 frmsg.channelMask = BLF_FLEXRAYRCVMSG_CHANNELMASK_B0x02;
4934 frmsg.headerCrc1 = 0;
4935 frmsg.headerCrc2 = header_crc;
4936 }
4937
4938 frmsg.dir = blf_get_direction(rec);
4939 frmsg.clientIndex = 0;
4940 frmsg.clusterNo = 0;
4941 frmsg.frameId = (pntohu16(pd + 2)) & FLEXRAY_ID_MASK0x07ff;
4942 frmsg.payloadLength = payload_length;
4943 frmsg.payloadLengthValid = payload_length;
4944 frmsg.cycle = pd[6] & FLEXRAY_CC_MASK0x3f;
4945 frmsg.tag = 0;
4946 frmsg.data = 0;
4947 frmsg.frameFlags = 0;
4948
4949 /* The NULL Flag 1 -> False */
4950 bool_Bool null_frame = (pd[2] & FLEXRAY_NFI_MASK0x20) != FLEXRAY_NFI_MASK0x20;
4951
4952 if (null_frame) {
4953 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_NULL_FRAME0x00000001;
4954 /* LINKTYPE_FLEXRAY has no payload for Null Frames present */
4955 payload_length = 0;
4956 }
4957
4958 /* TODO: check truncated data */
4959 if (payload_length > 0) {
4960 /* Data Valid*/
4961 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_VALID_DATA0x00000002;
4962 }
4963
4964 if ((pd[2] & FLEXRAY_SFI_MASK0x10) == FLEXRAY_SFI_MASK0x10) {
4965 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_SYNC0x00000004;
4966 }
4967
4968 if ((pd[2] & FLEXRAY_STFI_MASK0x08) == FLEXRAY_STFI_MASK0x08) {
4969 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_STARTUP0x00000008;
4970 }
4971
4972 if ((pd[2] & FLEXRAY_PPI_MASK0x40) == FLEXRAY_PPI_MASK0x40) {
4973 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_PAYLOAD_PREAM0x00000010;
4974 }
4975
4976 if ((pd[2] & FLEXRAY_RES_MASK0x80) == FLEXRAY_RES_MASK0x80) {
4977 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_RES_200x00000020;
4978 }
4979
4980 /* if any error flag is set */
4981 if ((pd[1] & FLEXRAY_ERRORS_DEFINED0x1f) != 0x00) {
4982 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_ERROR0x00000040;
4983 }
4984
4985 /* Not sure how to determine this as we do not know the low level parameters */
4986 //if ( ) {
4987 // /* DYNAMIC SEG =1 (Bit 20)*/
4988 // frmsg.frameFlags |= 0x100000;
4989 //}
4990
4991 frmsg.appParameter = 0;
4992
4993 fix_endianness_blf_flexrayrcvmessage(&frmsg);
4994
4995 if (length < (size_t)payload_length + 2 + FLEXRAY_HEADER_LENGTH5) {
4996 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4997 *err_info = ws_strdup_printf("blf: record length %u for FlexRay Frame (LINKTYPE_FLEXRAY) is truncated", (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: record length %u for FlexRay Frame (LINKTYPE_FLEXRAY) is truncated"
, (uint32_t)length)
;
4998 ws_debug("LINKTYPE_FLEXRAY Frame truncated.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4998, __func__, "LINKTYPE_FLEXRAY Frame truncated."); } } while
(0)
;
4999 return false0;
5000 }
5001
5002 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_FLEXRAY_RCVMESSAGE50, sizeof(blf_flexrayrcvmessage_t) + 254)) {
5003 return false0;
5004 }
5005
5006 if (!wtap_dump_file_write(wdh, &(frmsg), sizeof(blf_flexrayrcvmessage_t), err)) {
5007 return false0;
5008 }
5009
5010 if (payload_length > 0) {
5011 if (!wtap_dump_file_write(wdh, &(pd[7]), payload_length, err)) {
5012 return false0;
5013 }
5014 }
5015
5016 const uint8_t zero_bytes[256] = { 0 };
5017
5018 if (payload_length < 254) {
5019 if (!wtap_dump_file_write(wdh, &zero_bytes[0], 254 - payload_length, err)) {
5020 return false0;
5021 }
5022 }
5023
5024 return true1;
5025 }
5026
5027 /* no padding */
5028
5029 return true1;
5030}
5031
5032static bool_Bool blf_dump_lin(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
5033 /* LIN */
5034 /* https://www.tcpdump.org/linktypes/LINKTYPE_LIN.html */
5035
5036 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5037 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
5038 if (iface_entry == NULL((void*)0)) {
5039 return false0;
5040 }
5041
5042 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
5043 size_t length = ws_buffer_length(&rec->data);
5044
5045 if (length < 8) {
5046 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5047 *err_info = ws_strdup_printf("blf: record length %u for LIN message/symbol/error is lower than minimum of 8", (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: record length %u for LIN message/symbol/error is lower than minimum of 8"
, (uint32_t)length)
;
5048 ws_debug("LIN Data is too short (less than 8 bytes).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5048, __func__, "LIN Data is too short (less than 8 bytes)."
); } } while (0)
;
5049 return false0;
5050 }
5051
5052 uint8_t lin_err = pd[7] & 0x3f;
5053 if (lin_err != 0) {
5054 // TODO: handle LIN errors
5055 return true1;
5056 }
5057
5058 int i;
5059 uint8_t dlc = (pd[4] & LIN_PAYLOAD_LENGTH_MASK0xf0) >> 4;
5060 uint8_t msg_type = (pd[4] & LIN_MSG_TYPE_MASK0x0c) >> 2;
5061
5062 if (msg_type != LIN_MSG_TYPE_FRAME0) {
5063 // TODO: handle LIN events
5064 return true1;
5065 }
5066
5067 /* we need to have at least the data */
5068 if (length < (size_t)dlc + 8) {
5069 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5070 *err_info = ws_strdup_printf("blf: record length %u for LIN message is too low for data. DLC: %u.", (uint32_t)length, dlc)wmem_strdup_printf(((void*)0), "blf: record length %u for LIN message is too low for data. DLC: %u."
, (uint32_t)length, dlc)
;
5071 ws_debug("LIN Data is too short (less than needed).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5071, __func__, "LIN Data is too short (less than needed)."
); } } while (0)
;
5072 return false0;
5073 }
5074
5075 /* we ignore padding as we do not need it anyhow */
5076
5077 blf_linmessage_t linmsg;
5078 linmsg.channel = (uint16_t)iface_entry->channel;
5079 linmsg.id = pd[5];
5080 linmsg.dlc = dlc;
5081 for (i = 0; i < 8; i++) {
5082 if (i < dlc) {
5083 linmsg.data[i] = pd[i + 8];
5084 } else {
5085 linmsg.data[i] = 0;
5086 }
5087 }
5088 linmsg.fsmId = 0;
5089 linmsg.fsmState = 0;
5090 linmsg.headerTime = 0;
5091 linmsg.fullTime = 0;
5092 linmsg.crc = pd[6];
5093 linmsg.dir = blf_get_direction(rec);
5094 linmsg.res1 = 0;
5095
5096 fix_endianness_blf_linmessage(&linmsg);
5097
5098 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_LIN_MESSAGE11, sizeof(blf_linmessage_t) + 4)) {
5099 return false0;
5100 }
5101
5102 if (!wtap_dump_file_write(wdh, &(linmsg), sizeof(blf_linmessage_t), err)) {
5103 return false0;
5104 }
5105
5106 uint8_t rest_of_header[4] = { 0, 0, 0, 0};
5107
5108 if (!wtap_dump_file_write(wdh, &(rest_of_header), 4, err)) {
5109 return false0;
5110 }
5111
5112 /* no padding! */
5113
5114 return true1;
5115}
5116
5117static bool_Bool blf_dump_upper_pdu(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
5118 const blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5119
5120 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
5121 size_t length = ws_buffer_length(&rec->data);
5122
5123 unsigned tag_diss_pos = 0;
5124 size_t tag_diss_len = 0;
5125 unsigned col_proto_pos = 0;
5126 size_t col_proto_len = 0;
5127 unsigned col_info_pos = 0;
5128 size_t col_info_len = 0;
5129
5130 /* parse the tags */
5131 size_t pos = 0;
5132 bool_Bool done = false0;
5133 while (!done) {
5134 if (length - pos < 4) {
5135 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5136 *err_info = ws_strdup_printf("blf: Upper PDU has no or truncated tags (pos: %u, length: %u)", (uint32_t)pos, (uint32_t)length)wmem_strdup_printf(((void*)0), "blf: Upper PDU has no or truncated tags (pos: %u, length: %u)"
, (uint32_t)pos, (uint32_t)length)
;
5137 ws_debug("Upper PDU has truncated tags.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5137, __func__, "Upper PDU has truncated tags."); } } while
(0)
;
5138 return false0;
5139 }
5140
5141 uint16_t tag_type = pntohu16(pd + pos);
5142 uint16_t tag_len = pntohu16(pd + pos + 2);
5143
5144 if ((length - pos) < (size_t)tag_len + 4) {
5145 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5146 *err_info = ws_strdup_printf("blf: Upper PDU has truncated tags (pos: %u, tag_type: %u, tag_len: %u)", (uint32_t)pos, tag_type, tag_len)wmem_strdup_printf(((void*)0), "blf: Upper PDU has truncated tags (pos: %u, tag_type: %u, tag_len: %u)"
, (uint32_t)pos, tag_type, tag_len)
;
5147 ws_debug("Upper PDU has truncated tags.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5147, __func__, "Upper PDU has truncated tags."); } } while
(0)
;
5148 return false0;
5149 }
5150
5151 switch (tag_type) {
5152 case EXP_PDU_TAG_DISSECTOR_NAME12:
5153 tag_diss_pos = (unsigned)pos + 4;
5154 tag_diss_len = tag_len;
5155 break;
5156
5157 case EXP_PDU_TAG_COL_PROT_TEXT33:
5158 col_proto_pos = (unsigned)pos + 4;
5159 col_proto_len = tag_len;
5160 break;
5161
5162 case EXP_PDU_TAG_COL_INFO_TEXT36:
5163 col_info_pos = (unsigned)pos + 4;
5164 col_info_len = tag_len;
5165 break;
5166
5167 case EXP_PDU_TAG_END_OF_OPT0:
5168 done = true1;
5169 break;
5170 }
5171
5172 pos += 4;
5173 pos += tag_len;
5174 }
5175
5176 /* strip zero termination, if existing (a missing tag has length 0) */
5177 while (tag_diss_len > 0 && pd[tag_diss_pos + tag_diss_len - 1] == 0) {
5178 tag_diss_len -= 1;
5179 }
5180
5181 while (col_proto_len > 0 && pd[col_proto_pos + col_proto_len - 1] == 0) {
5182 col_proto_len -= 1;
5183 }
5184
5185 while (col_info_len > 0 && pd[col_info_pos + col_info_len - 1] == 0) {
5186 col_info_len -= 1;
5187 }
5188
5189 if (tag_diss_len == strlen(BLF_APPTEXT_TAG_DISS_DEFAULT"data-text-lines") && 0 == strncmp(BLF_APPTEXT_TAG_DISS_DEFAULT"data-text-lines", (const char*)&pd[tag_diss_pos], tag_diss_len)) {
5190 if (col_proto_len == strlen(BLF_APPTEXT_COL_PROT_TEXT"BLF App text") && 0 == strncmp(BLF_APPTEXT_COL_PROT_TEXT"BLF App text", (const char*)&pd[col_proto_pos], col_proto_len)) {
5191 blf_apptext_t apptext_header;
5192 apptext_header.source = BLF_APPTEXT_METADATA0x00000002;
5193 apptext_header.reservedAppText1 = 0;
5194 apptext_header.reservedAppText2 = 412; /* not sure what to put in but this is commonly used!? */
5195 uint32_t payload_len = (uint32_t)(length - pos);
5196 apptext_header.textLength = payload_len;
5197
5198 /* Metadata */
5199 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, BLF_APPTEXT_COL_INFO_TEXT_... */
5200 if (col_info_len == strlen(BLF_APPTEXT_COL_INFO_TEXT_GENERAL"Metadata: General") && 0 == strncmp(BLF_APPTEXT_COL_INFO_TEXT_GENERAL"Metadata: General", (const char*)&pd[col_info_pos], col_info_len)) {
5201 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_GENERAL */
5202 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_GENERAL0x01 << 24) | (0xffffff & payload_len);
5203 } else if (col_info_len == strlen(BLF_APPTEXT_COL_INFO_TEXT_CHANNELS"Metadata: Channels") && 0 == strncmp(BLF_APPTEXT_COL_INFO_TEXT_CHANNELS"Metadata: Channels", (const char*)&pd[col_info_pos], col_info_len)) {
5204 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_CHANNELS */
5205 if (writer_data->iface_to_channel_names_recovered) {
5206 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_CHANNELS0x02 << 24) | (0xffffff & payload_len);
5207 }
5208 } else if (col_info_len == strlen(BLF_APPTEXT_COL_INFO_TEXT_IDENTITY"Metadata: Identity") && 0 == strncmp(BLF_APPTEXT_COL_INFO_TEXT_IDENTITY"Metadata: Identity", (const char*)&pd[col_info_pos], col_info_len)) {
5209 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_IDENTITY */
5210 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_IDENTITY0x03 << 24) | (0xffffff & payload_len);
5211
5212 //} else if
5213 /* BLF_APPTEXT_COMMENT */
5214 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Comment: %s" */
5215 // TODO
5216 //} else if
5217 /* BLF_APPTEXT_ATTACHMENT */
5218 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Attachment: %s" */
5219 // TODO
5220 //} else if
5221 /* BLF_APPTEXT_TRACELINE */
5222 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Trace line%s: %s" */
5223 // TODO
5224 } else {
5225 return true1; /* just leave */
5226 }
5227
5228 if (payload_len > 2048 && (apptext_header.source != BLF_APPTEXT_METADATA0x00000002)) {
5229 ws_warning("Only Meta Data can be broken into smaller chunks.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 5229, __func__, "Only Meta Data can be broken into smaller chunks."
); } } while (0)
;
5230 }
5231
5232 uint32_t chunk_size;
5233 bool_Bool last_round = false0;
5234 do {
5235 if (payload_len > 2048 && apptext_header.source == BLF_APPTEXT_METADATA0x00000002) {
5236 chunk_size = 2048;
5237 } else {
5238 chunk_size = payload_len;
5239 last_round = true1;
5240 }
5241
5242 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_APP_TEXT65, sizeof(blf_apptext_t) + chunk_size)) {
5243 return false0;
5244 }
5245
5246 if (apptext_header.source == BLF_APPTEXT_METADATA0x00000002) {
5247 apptext_header.reservedAppText1 = (0xff000000 & apptext_header.reservedAppText1) | (0x00ffffff & payload_len);
5248 }
5249
5250 apptext_header.textLength = chunk_size;
5251 fix_endianness_blf_apptext_header(&apptext_header);
5252 if (!wtap_dump_file_write(wdh, &(apptext_header), sizeof(blf_apptext_t), err)) {
5253 return false0;
5254 }
5255 if (!last_round) {
5256 fix_endianness_blf_apptext_header(&apptext_header);
5257 }
5258
5259 if (!wtap_dump_file_write(wdh, &(pd[pos]), chunk_size, err)) {
5260 return false0;
5261 }
5262 pos += chunk_size;
5263
5264 /* Add strange padding to 4 bytes. */
5265 uint8_t padding_needed = (sizeof(blf_apptext_t) + chunk_size) % 4;
5266 if (!blf_write_add_padding(wdh, err, padding_needed)) {
5267 return false0;
5268 }
5269
5270 if (!last_round) {
5271 payload_len -= 2048;
5272 }
5273 } while (!last_round);
5274
5275 return true1;
5276 }
5277 // else if
5278 /* BLF_OBJTYPE_ETHERNET_STATUS */
5279 /* tags: BLF_APPTEXT_TAG_DISS_ETHSTATUS */
5280 // TODO
5281
5282 // else if
5283 /* BLF_OBJTYPE_ETHERNET_PHY_STATE */
5284 /* tags: BLF_APPTEXT_TAG_DISS_ETHPHYSTATUS */
5285 // TODO
5286 }
5287
5288 return true1;
5289}
5290
5291static bool_Bool blf_dump_interface_setup_by_blf_based_idb_desc(wtap_dumper *wdh, int *err _U___attribute__((unused))) {
5292 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5293 bool_Bool iface_descr_found;
5294
5295 /* check all interfaces first to avoid inconsistent state */
5296 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5297 ws_debug("interface: %d (pass 1)", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5297, __func__, "interface: %d (pass 1)", i); } } while (0)
;
5298
5299 /* get interface data */
5300 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5301 if (idb == NULL((void*)0)) {
5302 return false0;
5303 }
5304
5305 char *iface_descr = NULL((void*)0);
5306 iface_descr_found = wtap_block_get_string_option_value(idb, OPT_IDB_DESCRIPTION3, &iface_descr) == WTAP_OPTTYPE_SUCCESS;
5307
5308 if (!iface_descr_found) {
5309 ws_debug("IDB interface description not found! We need to map the interfaces.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5309, __func__, "IDB interface description not found! We need to map the interfaces."
); } } while (0)
;
5310 return false0;
5311 }
5312
5313 if (strncmp(iface_descr, "BLF-", 4) != 0) {
5314 ws_debug("IDB interface description found but not BLF format! We have to map freely the interfaces.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5314, __func__, "IDB interface description found but not BLF format! We have to map freely the interfaces."
); } } while (0)
;
5315 return false0;
5316 }
5317 }
5318
5319 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5320 ws_debug("interface: %d (pass 2)", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5320, __func__, "interface: %d (pass 2)", i); } } while (0)
;
5321
5322 /* get interface data */
5323 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5324 if (idb == NULL((void*)0)) {
5325 return false0;
5326 }
5327
5328 char *iface_descr = NULL((void*)0);
5329 iface_descr_found = wtap_block_get_string_option_value(idb, OPT_IDB_DESCRIPTION3, &iface_descr) == WTAP_OPTTYPE_SUCCESS;
5330
5331 if (!iface_descr_found) {
5332 /* This cannot be reached but it removes a warning. */
5333 ws_debug("IDB interface description not found! We need to map the interfaces.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5333, __func__, "IDB interface description not found! We need to map the interfaces."
); } } while (0)
;
5334 return false0;
5335 }
5336
5337 if (strncmp(iface_descr, "BLF-ETH-", 8) == 0) {
5338 char *endptr;
5339 uint16_t channel = (uint16_t)strtol(&iface_descr[8], &endptr, 16);
5340 uint16_t hwchannel = (uint16_t)strtol(&endptr[1], NULL((void*)0), 16);
5341
5342 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_ETHERNET1, channel, hwchannel)) {
5343 return false0;
5344 }
5345 } else if (strncmp(iface_descr, "BLF-CAN-", 8) == 0) {
5346 uint16_t channel = (uint16_t)strtol(&iface_descr[8], NULL((void*)0), 16);
5347
5348 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_SOCKETCAN125, channel, UINT16_MAX(65535))) {
5349 return false0;
5350 }
5351 } else if (strncmp(iface_descr, "BLF-LIN-", 8) == 0) {
5352 uint16_t channel = (uint16_t)strtol(&iface_descr[8], NULL((void*)0), 16);
5353
5354 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_LIN107, channel, UINT16_MAX(65535))) {
5355 return false0;
5356 }
5357 } else if (strncmp(iface_descr, "BLF-FR-", 7) == 0) {
5358 uint16_t channel = (uint16_t)strtol(&iface_descr[7], NULL((void*)0), 16);
5359
5360 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_FLEXRAY106, channel, UINT16_MAX(65535))) {
5361 return false0;
5362 }
5363 }
5364 }
5365
5366 writer_data->iface_to_channel_names_recovered = true1;
5367 return true1;
5368}
5369
5370static bool_Bool blf_dump_interface_setup(wtap_dumper *wdh, int *err) {
5371 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5372
5373 /* Try 1: BLF details in Interface Description */
5374 if (blf_dump_interface_setup_by_blf_based_idb_desc(wdh, err)) {
5375 return true1;
5376 }
5377
5378 /* Try 2: Generate new IDs by mapping Interface IDs and also add names to BLF */
5379 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5380 ws_debug("i: %d", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5380, __func__, "i: %d", i); } } while (0)
;
5381
5382 /* get interface data */
5383 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5384 if (idb == NULL((void*)0)) {
5385 return false0;
5386 }
5387
5388 const wtapng_if_descr_mandatory_t *mand_data = (wtapng_if_descr_mandatory_t *) idb->mandatory_data;
5389
5390 if (mand_data->wtap_encap == WTAP_ENCAP_ETHERNET1 || mand_data->wtap_encap == WTAP_ENCAP_SLL25 ||
5391 mand_data->wtap_encap == WTAP_ENCAP_LIN107 || mand_data->wtap_encap == WTAP_ENCAP_SOCKETCAN125 ||
5392 mand_data->wtap_encap == WTAP_ENCAP_FLEXRAY106) {
5393
5394 char *iface_name = NULL((void*)0);
5395 bool_Bool iface_name_found = wtap_block_get_string_option_value(idb, OPT_IDB_NAME2, &iface_name) == WTAP_OPTTYPE_SUCCESS;
5396
5397 /* BLF can only support 255 channels */
5398 if (iface_name_found && iface_name != NULL((void*)0) && (i) < 255) {
5399 uint8_t iface_id = (uint8_t)(i + 1);
5400
5401 /* we are not even trying to create APPTEXT CHANNELS as we are missing too much information */
5402
5403 /* mapping up to 255 interface ids to channels directly */
5404 if (!blf_dump_set_interface_mapping(wdh, i, mand_data->wtap_encap, (uint16_t)iface_id, UINT16_MAX(65535))) {
5405 return false0;
5406 }
5407 }
5408 }
5409 }
5410
5411 return true1;
5412}
5413
5414#define NS_PER_S1000000000 1000000000
5415
5416static bool_Bool blf_dump(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info) {
5417 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5418 ws_debug("encap = %d (%s) rec type = %u", rec->rec_header.packet_header.pkt_encap,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5419, __func__, "encap = %d (%s) rec type = %u", rec->rec_header
.packet_header.pkt_encap, wtap_encap_description(rec->rec_header
.packet_header.pkt_encap), rec->rec_type); } } while (0)
5419 wtap_encap_description(rec->rec_header.packet_header.pkt_encap), rec->rec_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5419, __func__, "encap = %d (%s) rec type = %u", rec->rec_header
.packet_header.pkt_encap, wtap_encap_description(rec->rec_header
.packet_header.pkt_encap), rec->rec_type); } } while (0)
;
5420
5421 /* TODO */
5422 switch (rec->rec_type) {
5423 case REC_TYPE_PACKET0:
5424 break;
5425 default:
5426 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
5427 return false0;
5428 }
5429
5430 /* logcontainer full already? we just estimate the headers/overhead to be less than 100 */
5431 blf_dump_check_logcontainer_full(wdh, err, err_info, rec->rec_header.packet_header.len + 100);
5432
5433 uint64_t obj_timestamp = (rec->ts.secs * 1000 * 1000 * 1000 + rec->ts.nsecs);
5434
5435 /* Due to all object timestamps being relative the file header start time, we only want to do this once. */
5436 /* Packets can be skipped due to writing of that specfic event type not being supported or just not yet */
5437 /* implemented, so use the object_count to know if any events has been output to file yet. */
5438 if (writer_data->object_count == 0) {
5439 /* TODO: refine method. Right now assume no event will ever be more than 1 second prior to first packet time. */
5440 /* Suggested improvement 1: For 2-pass or preloaded data use the time of the actual first event. */
5441 /* Suggested improvement 2: For single step conversion, make safety margin configurable. */
5442 if(obj_timestamp > NS_PER_S1000000000) {
5443 writer_data->start_time = obj_timestamp - NS_PER_S1000000000;
5444 } else {
5445 writer_data->start_time = 0;
5446 }
5447 }
5448
5449 if (obj_timestamp < writer_data->start_time) {
5450 *err = WTAP_ERR_BAD_FILE-13;
5451 *err_info = ws_strdup("blf_dump: packet timestamp more than 1 second earlier than first packet encountered, making the file timetamp invalid. Reordering packets chronologically will solve this.")wmem_strdup(((void*)0), "blf_dump: packet timestamp more than 1 second earlier than first packet encountered, making the file timetamp invalid. Reordering packets chronologically will solve this."
)
;
5452 return false0;
5453 }
5454
5455 if (writer_data->end_time < obj_timestamp) {
5456 writer_data->end_time = obj_timestamp;
5457 }
5458
5459 /* reduce by BLF start offset */
5460 obj_timestamp = obj_timestamp - writer_data->start_time;
5461
5462 switch (rec->rec_header.packet_header.pkt_encap) {
5463 case WTAP_ENCAP_ETHERNET1: /* 1 */
5464 return blf_dump_ethernet(wdh, rec, err, err_info, obj_timestamp);
5465 break;
5466
5467 case WTAP_ENCAP_SLL25: /* 25 */
5468 return blf_dump_sll(wdh, rec, err, err_info, obj_timestamp);
5469 break;
5470
5471 case WTAP_ENCAP_FLEXRAY106: /* 106 */
5472 return blf_dump_flexray(wdh, rec, err, err_info, obj_timestamp);
5473 break;
5474
5475 case WTAP_ENCAP_LIN107: /* 107 */
5476 return blf_dump_lin(wdh, rec, err, err_info, obj_timestamp);
5477 break;
5478
5479 case WTAP_ENCAP_SOCKETCAN125: { /* 125 */
5480 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
5481 size_t length = ws_buffer_length(&rec->data);
5482 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, pd, length, false0, false0, false0, false0);
5483 }
5484 break;
5485
5486 case WTAP_ENCAP_WIRESHARK_UPPER_PDU155: /* 155 */
5487 return blf_dump_upper_pdu(wdh, rec, err, err_info, obj_timestamp);
5488 break;
5489
5490 default:
5491 break;
5492 }
5493
5494 return true1;
5495}
5496
5497/* Returns 0 if we could write the specified encapsulation type,
5498 an error indication otherwise. */
5499static int blf_dump_can_write_encap(int wtap_encap) {
5500 ws_debug("encap = %d (%s)", wtap_encap, wtap_encap_description(wtap_encap))do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5500, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
;
5501
5502 /* Per-packet encapsulation is supported. */
5503 if (wtap_encap == WTAP_ENCAP_PER_PACKET-1)
5504 return 0;
5505
5506 switch (wtap_encap) {
5507 /* fall through */
5508 case WTAP_ENCAP_ETHERNET1:
5509 case WTAP_ENCAP_SLL25:
5510 case WTAP_ENCAP_FLEXRAY106:
5511 case WTAP_ENCAP_LIN107:
5512 case WTAP_ENCAP_SOCKETCAN125:
5513 case WTAP_ENCAP_WIRESHARK_UPPER_PDU155:
5514 return 0;
5515 }
5516
5517 return WTAP_ERR_UNWRITABLE_ENCAP-8;
5518}
5519
5520static bool_Bool blf_add_idb(wtap_dumper *wdh, wtap_block_t idb _U___attribute__((unused)), int *err _U___attribute__((unused)), char **err_info _U___attribute__((unused))) {
5521 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5521, __func__, "entering function"); } } while (0)
;
5522 /*
5523 * A new IDB was added to the list of itnerfaces for the file to
5524 * which we're writing; update hte interface mapping.
5525 */
5526 blf_dump_interface_setup(wdh, err); // Expands and populates the interface mapping
5527
5528 return true1;
5529}
5530
5531/* Finish writing to a dump file.
5532 Returns true on success, false on failure. */
5533static bool_Bool blf_dump_finish(wtap_dumper *wdh, int *err, char **err_info) {
5534 if (!blf_dump_close_logcontainer(wdh, err, err_info)) {
5535 blf_dump_free(wdh);
5536 return false0;
5537 }
5538
5539 if (!blf_finalize_file_header(wdh, err)) {
5540 blf_dump_free(wdh);
5541 return false0;
5542 }
5543
5544 blf_dump_free(wdh);
5545 /* File is finished, do not touch anymore ! */
5546
5547 ws_debug("leaving function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5547, __func__, "leaving function"); } } while (0)
;
5548 return true1;
5549}
5550
5551/* Returns true on success, false on failure; sets "*err" to an error code on
5552 failure */
5553static bool_Bool
5554blf_dump_open(wtap_dumper *wdh, int *err, char **err_info) {
5555 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5555, __func__, "entering function"); } } while (0)
;
5556
5557 if (wdh == NULL((void*)0) || wdh->priv != NULL((void*)0)) {
5558 *err = WTAP_ERR_INTERNAL-21;
5559 ws_debug("internal error: blf wdh is NULL or private data already set.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5559, __func__, "internal error: blf wdh is NULL or private data already set."
); } } while (0)
;
5560 return false0;
5561 }
5562
5563 wdh->subtype_add_idb = blf_add_idb;
5564 wdh->subtype_write = blf_dump;
5565 wdh->subtype_finish = blf_dump_finish;
5566
5567 /* set up priv data */
5568 blf_writer_data_t *writer_data = g_new(blf_writer_data_t, 1)((blf_writer_data_t *) g_malloc_n ((1), sizeof (blf_writer_data_t
)))
;
5569 wdh->priv = writer_data;
5570
5571 /* set up and init interface mappings */
5572 writer_data->iface_to_channel_array = g_array_new(TRUE(!(0)), TRUE(!(0)), sizeof(blf_channel_to_iface_entry_t));
5573 blf_dump_expand_interface_mapping(wdh, wdh->interface_data->len);
5574 writer_data->iface_to_channel_names_recovered = false0;
5575
5576 writer_data->fileheader = NULL((void*)0);
5577 writer_data->object_count = 0;
5578 writer_data->start_time = 0;
5579 writer_data->end_time = 0;
5580
5581 writer_data->logcontainer_start = LOG_CONTAINER_NONE(18446744073709551615UL);
5582
5583 /* create the blf header structure and attach to wdh */
5584 if (!blf_init_file_header(wdh, err)) {
5585 blf_dump_free(wdh);
5586 return false0;
5587 }
5588
5589 /* write space in output file for header */
5590 if (!blf_write_file_header_zeros(wdh, err)) {
5591 blf_dump_free(wdh);
5592 return false0;
5593 }
5594
5595 ws_debug("wrote blf file header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5595, __func__, "wrote blf file header"); } } while (0)
;
5596
5597 /* Create first log_container */
5598 if (!blf_dump_start_logcontainer(wdh, err, err_info)) {
5599 blf_dump_free(wdh);
5600 return false0;
5601 }
5602
5603 if (!blf_dump_interface_setup(wdh, err)) {
5604 blf_dump_free(wdh);
5605 return false0;
5606 }
5607
5608 return true1;
5609}
5610
5611static const struct file_type_subtype_info blf_info = {
5612 "Vector Informatik Binary Logging Format (BLF) logfile", "blf", "blf", NULL((void*)0),
5613 true1, BLOCKS_SUPPORTED(blf_blocks_supported)(sizeof (blf_blocks_supported) / sizeof (blf_blocks_supported
)[0]), blf_blocks_supported
,
5614 blf_dump_can_write_encap, blf_dump_open, NULL((void*)0)
5615};
5616
5617void register_blf(void) {
5618
5619 blf_file_type_subtype = wtap_register_file_type_subtype(&blf_info);
5620
5621 /*
5622 * Register name for backwards compatibility with the
5623 * wtap_filetypes table in Lua.
5624 */
5625 wtap_register_backwards_compatibility_lua_name("BLF", blf_file_type_subtype);
5626}
5627
5628/*
5629 * Editor modelines - https://www.wireshark.org/tools/modelines.html
5630 *
5631 * Local variables:
5632 * c-basic-offset: 4
5633 * tab-width: 8
5634 * indent-tabs-mode: nil
5635 * End:
5636 *
5637 * vi: set shiftwidth=4 tabstop=8 expandtab:
5638 * :indentSize=4:tabSize=8:noTabs=true:
5639 */