Bug Summary

File:builds/wireshark/wireshark/wiretap/blf.c
Warning:line 2275, 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-04-100346-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 uint16_t payload_length = ethheader.payloadlength;
1588 if (payload_length > object_length - (data_start - block_start) - sizeof(blf_ethernetframeheader_t)) {
1589 ws_debug("shortening payload_length because not enough bytes for frame")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1589, __func__, "shortening payload_length because not enough bytes for frame"
); } } while (0)
;
1590 payload_length = (uint16_t)(object_length - (data_start - block_start) - sizeof(blf_ethernetframeheader_t));
1591 }
1592
1593 /*
1594 * BLF breaks up and reorders the Ethernet header and VLAN tag fields.
1595 * This is a really bad design and makes this format one of the worst.
1596 * If you want a fast format that keeps your data intact, avoid this format!
1597 * So, lets hope we can reconstruct the original packet successfully.
1598 */
1599
1600 tmpbuf[0] = ethheader.dst_addr[0];
1601 tmpbuf[1] = ethheader.dst_addr[1];
1602 tmpbuf[2] = ethheader.dst_addr[2];
1603 tmpbuf[3] = ethheader.dst_addr[3];
1604 tmpbuf[4] = ethheader.dst_addr[4];
1605 tmpbuf[5] = ethheader.dst_addr[5];
1606
1607 tmpbuf[6] = ethheader.src_addr[0];
1608 tmpbuf[7] = ethheader.src_addr[1];
1609 tmpbuf[8] = ethheader.src_addr[2];
1610 tmpbuf[9] = ethheader.src_addr[3];
1611 tmpbuf[10] = ethheader.src_addr[4];
1612 tmpbuf[11] = ethheader.src_addr[5];
1613
1614 if (ethheader.tpid != 0) { /* A valid VLAN tag can have a TCI of 0. */
1615 phtonu16(tmpbuf + 12, ethheader.tpid);
1616 phtonu16(tmpbuf + 14, ethheader.tci);
1617 phtonu16(tmpbuf + 16, ethheader.ethtype);
1618 ws_buffer_assure_space(&params->rec->data, (size_t)18 + payload_length);
1619 ws_buffer_append(&params->rec->data, tmpbuf, (size_t)18);
1620 caplen = ((uint32_t)18 + payload_length);
1621 len = ((uint32_t)18 + payload_length);
1622 } else {
1623 phtonu16(tmpbuf + 12, ethheader.ethtype);
1624 ws_buffer_assure_space(&params->rec->data, (size_t)14 + payload_length);
1625 ws_buffer_append(&params->rec->data, tmpbuf, (size_t)14);
1626 caplen = ((uint32_t)14 + payload_length);
1627 len = ((uint32_t)14 + payload_length);
1628 }
1629
1630 if (!blf_read_bytes(params, data_start + sizeof(blf_ethernetframeheader_t), ws_buffer_end_ptr(&params->rec->data), payload_length, err, err_info)) {
1631 ws_debug("copying ethernet frame failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1631, __func__, "copying ethernet frame failed"); } } while
(0)
;
1632 return false0;
1633 }
1634 ws_buffer_increase_length(&params->rec->data, payload_length);
1635
1636 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, UINT16_MAX(65535), caplen, len);
1637 blf_add_direction_option(params, ethheader.direction);
1638
1639 return true1;
1640}
1641
1642static bool_Bool
1643blf_read_ethernetframe_ext(blf_params_t *params, int *err, char **err_info, int64_t block_start,int64_t data_start,
1644 int64_t object_length, uint32_t flags, uint64_t object_timestamp, bool_Bool error) {
1645 blf_ethernetframeheader_ex_t ethheader;
1646
1647 if (object_length < (data_start - block_start) + (int) sizeof(blf_ethernetframeheader_ex_t)) {
1648 *err = WTAP_ERR_BAD_FILE-13;
1649 *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")
;
1650 ws_debug("not enough bytes for ethernet frame header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1650, __func__, "not enough bytes for ethernet frame header in object"
); } } while (0)
;
1651 return false0;
1652 }
1653
1654 if (!blf_read_bytes(params, data_start, &ethheader, sizeof(blf_ethernetframeheader_ex_t), err, err_info)) {
1655 ws_debug("not enough bytes for ethernet frame header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1655, __func__, "not enough bytes for ethernet frame header in file"
); } } while (0)
;
1656 return false0;
1657 }
1658 fix_endianness_blf_ethernetframeheader_ex(&ethheader);
1659
1660 if (object_length - (data_start - block_start) - sizeof(blf_ethernetframeheader_ex_t) < ethheader.frame_length) {
1661 *err = WTAP_ERR_BAD_FILE-13;
1662 *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")
;
1663 ws_debug("frame too short")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1663, __func__, "frame too short"); } } while (0)
;
1664 return false0;
1665 }
1666
1667 ws_buffer_assure_space(&params->rec->data, ethheader.frame_length);
1668
1669 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)) {
1670 ws_debug("copying ethernet frame failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1670, __func__, "copying ethernet frame failed"); } } while
(0)
;
1671 return false0;
1672 }
1673 ws_buffer_increase_length(&params->rec->data, ethheader.frame_length);
1674
1675 if (ethheader.flags & BLF_ETHERNET_EX_HARDWARECHANNEL0x0002) {
1676 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, ethheader.hw_channel, ethheader.frame_length, ethheader.frame_length);
1677 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_QUEUE6, ethheader.hw_channel);
1678 } else {
1679 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, UINT16_MAX(65535), ethheader.frame_length, ethheader.frame_length);
1680 }
1681
1682 blf_add_direction_option(params, ethheader.direction);
1683
1684 return true1;
1685}
1686
1687static bool_Bool
1688blf_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) {
1689 blf_ethernet_rxerror_t ethheader;
1690
1691 if (object_length < (data_start - block_start) + (int)sizeof(blf_ethernet_rxerror_t)) {
1692 *err = WTAP_ERR_BAD_FILE-13;
1693 *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"
)
;
1694 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"
, 1694, __func__, "not enough bytes for ethernet rx error header in object"
); } } while (0)
;
1695 return false0;
1696 }
1697
1698 if (!blf_read_bytes(params, data_start, &ethheader, sizeof(blf_ethernet_rxerror_t), err, err_info)) {
1699 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"
, 1699, __func__, "not enough bytes for ethernet rx error header in file"
); } } while (0)
;
1700 return false0;
1701 }
1702 fix_endianness_blf_ethernet_rxerror(&ethheader);
1703
1704 if (object_length - (data_start - block_start) < ethheader.frame_length) {
1705 *err = WTAP_ERR_BAD_FILE-13;
1706 *err_info = ws_strdup("blf: ETHERNET_RXERROR: frame too short")wmem_strdup(((void*)0), "blf: ETHERNET_RXERROR: frame too short"
)
;
1707 ws_debug("frame too short")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1707, __func__, "frame too short"); } } while (0)
;
1708 return false0;
1709 }
1710
1711 ws_buffer_assure_space(&params->rec->data, ethheader.frame_length);
1712
1713 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)) {
1714 ws_debug("copying ethernet rx error failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1714, __func__, "copying ethernet rx error failed"); } } while
(0)
;
1715 return false0;
1716 }
1717 ws_buffer_increase_length(&params->rec->data, ethheader.frame_length);
1718
1719 if (ethheader.hw_channel != 0) { /* In this object type, a value of 0 is considered invalid. */
1720 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, ethheader.hw_channel, ethheader.frame_length, ethheader.frame_length);
1721 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_QUEUE6, ethheader.hw_channel);
1722 } else {
1723 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_ETHERNET1, ethheader.channel, UINT16_MAX(65535), ethheader.frame_length, ethheader.frame_length);
1724 }
1725 blf_add_direction_option(params, ethheader.direction);
1726
1727 return true1;
1728}
1729
1730/*
1731 * XXX - provide radio information to our caller in the pseudo-header.
1732 */
1733static bool_Bool
1734blf_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) {
1735 blf_wlanframeheader_t wlanheader;
1736
1737 if (object_length < (data_start - block_start) + (int)sizeof(blf_wlanframeheader_t)) {
1738 *err = WTAP_ERR_BAD_FILE-13;
1739 *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"
)
;
1740 ws_debug("not enough bytes for wlan frame header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1740, __func__, "not enough bytes for wlan frame header in object"
); } } while (0)
;
1741 return false0;
1742 }
1743
1744 if (!blf_read_bytes(params, data_start, &wlanheader, sizeof(blf_wlanframeheader_t), err, err_info)) {
1745 ws_debug("not enough bytes for wlan frame header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1745, __func__, "not enough bytes for wlan frame header in file"
); } } while (0)
;
1746 return false0;
1747 }
1748 fix_endianness_blf_wlanframeheader(&wlanheader);
1749
1750 if (object_length - (data_start - block_start) - sizeof(blf_wlanframeheader_t) < wlanheader.frame_length) {
1751 *err = WTAP_ERR_BAD_FILE-13;
1752 *err_info = ws_strdup("blf: WLAN_FRAME: frame too short")wmem_strdup(((void*)0), "blf: WLAN_FRAME: frame too short");
1753 ws_debug("frame too short")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1753, __func__, "frame too short"); } } while (0)
;
1754 return false0;
1755 }
1756
1757 ws_buffer_assure_space(&params->rec->data, wlanheader.frame_length);
1758
1759 if (!blf_read_bytes(params, data_start + sizeof(blf_wlanframeheader_t), ws_buffer_end_ptr(&params->rec->data), wlanheader.frame_length, err, err_info)) {
1760 ws_debug("copying wlan frame failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1760, __func__, "copying wlan frame failed"); } } while (0)
;
1761 return false0;
1762 }
1763 ws_buffer_increase_length(&params->rec->data, wlanheader.frame_length);
1764
1765 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_IEEE_802_1120, wlanheader.channel, UINT16_MAX(65535), wlanheader.frame_length, wlanheader.frame_length);
1766 blf_add_direction_option(params, wlanheader.direction);
1767
1768 return true1;
1769}
1770
1771static const uint8_t can_dlc_to_length[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8 };
1772static const uint8_t canfd_dlc_to_length[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64 };
1773
1774static bool_Bool
1775blf_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,
1776 uint32_t flags, uint64_t object_timestamp, uint16_t channel, uint8_t canfd_flags) {
1777 uint8_t tmpbuf[8];
1778 unsigned caplen, len;
1779
1780 phtonu32(tmpbuf, canid);
1781 tmpbuf[4] = payload_length;
1782 tmpbuf[5] = canfd_flags;
1783 tmpbuf[6] = 0;
1784 tmpbuf[7] = 0;
1785
1786 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length_valid);
1787 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
1788 caplen = sizeof(tmpbuf) + payload_length_valid;
1789 len = sizeof(tmpbuf) + payload_length;
1790
1791 if (payload_length_valid > 0 && !blf_read_bytes(params, start_position, ws_buffer_end_ptr(&params->rec->data), payload_length_valid, err, err_info)) {
1792 ws_debug("copying can payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1792, __func__, "copying can payload failed"); } } while (0
)
;
1793 return false0;
1794 }
1795 ws_buffer_increase_length(&params->rec->data, payload_length_valid);
1796
1797 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, channel, UINT16_MAX(65535), caplen, len);
1798
1799 return true1;
1800}
1801
1802static bool_Bool
1803blf_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) {
1804 blf_canmessage_t canheader;
1805 blf_canmessage2_trailer_t can2trailer;
1806
1807 uint32_t canid;
1808 uint8_t payload_length;
1809
1810 /* The canheader is followed by 8 bytes, which need to be present! */
1811 if (object_length < (data_start - block_start) + (int) sizeof(canheader) + 8) {
1812 *err = WTAP_ERR_BAD_FILE-13;
1813 *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")
1814 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")
;
1815 ws_debug("not enough bytes for can header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1815, __func__, "not enough bytes for can header in object"
); } } while (0)
;
1816 return false0;
1817 }
1818
1819 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
1820 ws_debug("not enough bytes for can header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1820, __func__, "not enough bytes for can header in file");
} } while (0)
;
1821 return false0;
1822 }
1823 fix_endianness_blf_canmessage(&canheader);
1824
1825 canheader.dlc &= 0x0f;
1826
1827 payload_length = canheader.dlc;
1828 if (payload_length > 8) {
1829 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"
, 1829, __func__, "regular CAN tries more than 8 bytes? Cutting to 8."
); } } while (0)
;
1830 payload_length = 8;
1831 }
1832
1833 canid = canheader.id;
1834
1835 if ((canheader.flags & BLF_CANMESSAGE_FLAG_RTR0x80) == BLF_CANMESSAGE_FLAG_RTR0x80) {
1836 canid |= CAN_RTR_FLAG0x40000000;
1837 payload_length = 0;
1838 }
1839
1840 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)) {
1841 return false0;
1842 }
1843
1844 /* actually, we do not really need the data, right now.... */
1845 if (can_message2) {
1846 if (object_length < (data_start - block_start) + (int) sizeof(canheader) + 8 + (int) sizeof(can2trailer)) {
1847 *err = WTAP_ERR_BAD_FILE-13;
1848 *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"
)
;
1849 ws_debug("not enough bytes for can message 2 trailer")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1849, __func__, "not enough bytes for can message 2 trailer"
); } } while (0)
;
1850 return false0;
1851 }
1852 if (!blf_read_bytes(params, data_start + sizeof(canheader) + 8, &can2trailer, sizeof(can2trailer), err, err_info)) {
1853 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"
, 1853, __func__, "not enough bytes for can message 2 trailer in file"
); } } while (0)
;
1854 return false0;
1855 }
1856 fix_endianness_blf_canmessage2_trailer(&can2trailer);
1857 }
1858
1859 blf_add_direction_option(params, (canheader.flags & BLF_CANMESSAGE_FLAG_TX0x01) == BLF_CANMESSAGE_FLAG_TX0x01 ? BLF_DIR_TX1: BLF_DIR_RX0);
1860
1861 return true1;
1862}
1863
1864static bool_Bool
1865blf_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) {
1866 blf_canfdmessage_t canheader;
1867
1868 bool_Bool canfd;
1869 uint32_t canid;
1870 uint8_t payload_length;
1871 uint8_t payload_length_valid;
1872 uint8_t canfd_flags;
1873
1874 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
1875 *err = WTAP_ERR_BAD_FILE-13;
1876 *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"
)
;
1877 ws_debug("not enough bytes for canfd header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1877, __func__, "not enough bytes for canfd header in object"
); } } while (0)
;
1878 return false0;
1879 }
1880
1881 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
1882 ws_debug("not enough bytes for canfd header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1882, __func__, "not enough bytes for canfd header in file"
); } } while (0)
;
1883 return false0;
1884 }
1885 fix_endianness_blf_canfdmessage(&canheader);
1886
1887 canheader.dlc &= 0x0f;
1888
1889 canfd = (canheader.canfdflags & BLF_CANFDMESSAGE_CANFDFLAG_EDL0x01) == BLF_CANFDMESSAGE_CANFDFLAG_EDL0x01;
1890 if (canfd) {
1891 payload_length = canfd_dlc_to_length[canheader.dlc];
1892 canfd_flags = (canheader.canfdflags & BLF_CANFDMESSAGE_CANFDFLAG_EDL0x01) << 2 | (canheader.canfdflags & BLF_CANFDMESSAGE_CANFDFLAG_ESI0x04) >> 1 | (canheader.canfdflags & BLF_CANFDMESSAGE_CANFDFLAG_BRS0x02) >> 1;
1893 } else {
1894 if (canheader.dlc > 8) {
1895 ws_debug("regular CAN tries more than 8 bytes?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1895, __func__, "regular CAN tries more than 8 bytes?"); } }
while (0)
;
1896 }
1897 payload_length = can_dlc_to_length[canheader.dlc];
1898 canfd_flags = 0;
1899 }
1900
1901 if (payload_length > canheader.validDataBytes) {
1902 ws_debug("shortening canfd payload because valid data bytes shorter.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1902, __func__, "shortening canfd payload because valid data bytes shorter."
); } } while (0)
;
1903 payload_length = canheader.validDataBytes;
1904 }
1905
1906 canid = canheader.id;
1907
1908 if (!canfd && (canheader.flags & BLF_CANMESSAGE_FLAG_RTR0x80) == BLF_CANMESSAGE_FLAG_RTR0x80) {
1909 canid |= CAN_RTR_FLAG0x40000000;
1910 payload_length = 0; /* Should already be zero from validDataBytes */
1911 }
1912
1913 payload_length_valid = payload_length;
1914
1915 if (payload_length_valid > object_length - (data_start - block_start) - sizeof(canheader)) {
1916 ws_debug("shortening can payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1916, __func__, "shortening can payload because buffer is too short."
); } } while (0)
;
1917 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - sizeof(canheader));
1918 }
1919
1920 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)) {
1921 return false0;
1922 }
1923
1924 blf_add_direction_option(params, (canheader.flags & BLF_CANMESSAGE_FLAG_TX0x01) == BLF_CANMESSAGE_FLAG_TX0x01 ? BLF_DIR_TX1 : BLF_DIR_RX0);
1925
1926 return true1;
1927}
1928
1929static bool_Bool
1930blf_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) {
1931 blf_canfdmessage64_t canheader;
1932
1933 bool_Bool canfd;
1934 uint32_t canid;
1935 uint8_t payload_length;
1936 uint8_t payload_length_valid;
1937 uint8_t canfd_flags;
1938
1939 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
1940 *err = WTAP_ERR_BAD_FILE-13;
1941 *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"
)
;
1942 ws_debug("not enough bytes for canfd header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1942, __func__, "not enough bytes for canfd header in object"
); } } while (0)
;
1943 return false0;
1944 }
1945
1946 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
1947 ws_debug("not enough bytes for canfd header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1947, __func__, "not enough bytes for canfd header in file"
); } } while (0)
;
1948 return false0;
1949 }
1950 fix_endianness_blf_canfdmessage64(&canheader);
1951
1952 canheader.dlc &= 0x0f;
1953
1954 canfd = (canheader.flags & BLF_CANFDMESSAGE64_FLAG_EDL0x001000) == BLF_CANFDMESSAGE64_FLAG_EDL0x001000;
1955 if (canfd) {
1956 payload_length = canfd_dlc_to_length[canheader.dlc];
1957 canfd_flags = (canheader.flags & BLF_CANFDMESSAGE64_FLAG_EDL0x001000) >> 10 | (canheader.flags & BLF_CANFDMESSAGE64_FLAG_ESI0x004000) >> 13 | (canheader.flags & BLF_CANFDMESSAGE64_FLAG_BRS0x002000) >> 13;
1958 } else {
1959 if (canheader.dlc > 8) {
1960 ws_debug("regular CAN tries more than 8 bytes?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1960, __func__, "regular CAN tries more than 8 bytes?"); } }
while (0)
;
1961 }
1962 payload_length = can_dlc_to_length[canheader.dlc];
1963 canfd_flags = 0;
1964 }
1965
1966 if (payload_length > canheader.validDataBytes) {
1967 ws_debug("shortening canfd payload because valid data bytes shorter.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1967, __func__, "shortening canfd payload because valid data bytes shorter."
); } } while (0)
;
1968 payload_length = canheader.validDataBytes;
1969 }
1970
1971 canid = canheader.id;
1972
1973 if (!canfd && (canheader.flags & BLF_CANFDMESSAGE64_FLAG_REMOTE_FRAME0x000010) == BLF_CANFDMESSAGE64_FLAG_REMOTE_FRAME0x000010) {
1974 canid |= CAN_RTR_FLAG0x40000000;
1975 payload_length = 0; /* Should already be zero from validDataBytes */
1976 }
1977
1978 payload_length_valid = payload_length;
1979
1980 if (payload_length_valid > object_length - (data_start - block_start) - sizeof(canheader)) {
1981 ws_debug("shortening can payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 1981, __func__, "shortening can payload because buffer is too short."
); } } while (0)
;
1982 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - sizeof(canheader));
1983 }
1984
1985 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)) {
1986 return false0;
1987 }
1988
1989 blf_add_direction_option(params, canheader.dir);
1990
1991 return true1;
1992}
1993
1994static bool_Bool
1995blf_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) {
1996 blf_canerror_t canheader;
1997 uint32_t canid;
1998 uint8_t payload_length;
1999 uint8_t tmpbuf[16] = {0};
2000
2001 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
2002 *err = WTAP_ERR_BAD_FILE-13;
2003 *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"
)
;
2004 ws_debug("not enough bytes for canerror header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2004, __func__, "not enough bytes for canerror header in object"
); } } while (0)
;
2005 return false0;
2006 }
2007
2008 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
2009 ws_debug("not enough bytes for canerror header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2009, __func__, "not enough bytes for canerror header in file"
); } } while (0)
;
2010 return false0;
2011 }
2012 fix_endianness_blf_canerror(&canheader);
2013
2014 // Set CAN_ERR_FLAG in unused bits of Can ID to indicate error in socketcan
2015 canid = CAN_ERR_FLAG0x20000000;
2016
2017 // Fixed packet data length for socketcan error messages
2018 payload_length = CAN_ERR_DLC8;
2019
2020 if (overload) {
2021 tmpbuf[10] = CAN_ERR_PROT_OVERLOAD0x20;
2022 canid |= CAN_ERR_PROT0x00000008U;
2023 }
2024
2025 phtonu32(tmpbuf, canid);
2026 tmpbuf[4] = payload_length;
2027
2028 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2029
2030 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, canheader.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2031 return true1;
2032}
2033
2034static bool_Bool
2035blf_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) {
2036 blf_canerrorext_t canheader;
2037
2038 bool_Bool err_ack = false0;
2039 bool_Bool err_prot = false0;
2040 bool_Bool direction_tx;
2041 uint32_t canid;
2042 uint8_t payload_length;
2043 uint8_t tmpbuf[16] = {0};
2044
2045 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
2046 *err = WTAP_ERR_BAD_FILE-13;
2047 *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"
)
;
2048 ws_debug("not enough bytes for canerrorext header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2048, __func__, "not enough bytes for canerrorext header in object"
); } } while (0)
;
2049 return false0;
2050 }
2051
2052 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
2053 ws_debug("not enough bytes for canerrorext header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2053, __func__, "not enough bytes for canerrorext header in file"
); } } while (0)
;
2054 return false0;
2055 }
2056 fix_endianness_blf_canerrorext(&canheader);
2057
2058 if (canheader.flags & BLF_CANERROREXT_FLAG_CANCORE0x02) {
2059 // Map Vector Can Core error codes to compareable socketcan errors
2060 switch ((canheader.errorCodeExt >> 6) & 0x3f) {
2061 case BLF_CANERROREXT_ECC_MEANING_BIT_ERROR0x0:
2062 err_prot = true1;
2063 tmpbuf[10] = CAN_ERR_PROT_BIT0x01;
2064 break;
2065 case BLF_CANERROREXT_ECC_MEANING_FORM_ERROR0x1:
2066 err_prot = true1;
2067 tmpbuf[10] = CAN_ERR_PROT_FORM0x02;
2068 break;
2069 case BLF_CANERROREXT_ECC_MEANING_STUFF_ERROR0x2:
2070 err_prot = true1;
2071 tmpbuf[10] = CAN_ERR_PROT_STUFF0x04;
2072 break;
2073 case BLF_CANERROREXT_ECC_MEANING_CRC_ERROR0x4:
2074 err_prot = true1;
2075 tmpbuf[11] = CAN_ERR_PROT_LOC_CRC_SEQ0x08;
2076 break;
2077 case BLF_CANERROREXT_ECC_MEANING_NACK_ERROR0x7:
2078 err_ack = true1;
2079 tmpbuf[11] = CAN_ERR_PROT_LOC_ACK0x19;
2080 break;
2081 case BLF_CANERROREXT_ECC_MEANING_OVERLOAD0x8:
2082 err_prot = true1;
2083 tmpbuf[10] = CAN_ERR_PROT_OVERLOAD0x20;
2084 break;
2085 default:
2086 err_prot = true1;
2087 tmpbuf[10] = CAN_ERR_PROT_UNSPEC0x00;
2088 break;
2089 }
2090 err_ack = err_ack || (canheader.errorCodeExt & BLF_CANERROREXT_EXTECC_NOT_ACK0x2000) == 0x0;
2091 if (err_ack) {
2092 // Don't set protocol error on ack errors
2093 err_prot = false0;
2094 }
2095 }
2096
2097 // CanID contains error class in socketcan
2098 canid = CAN_ERR_FLAG0x20000000;
2099 canid |= err_prot ? CAN_ERR_PROT0x00000008U : 0;
2100 canid |= err_ack ? CAN_ERR_ACK0x00000020U : 0;
2101
2102 // Fixed packet data length for socketcan error messages
2103 payload_length = CAN_ERR_DLC8;
2104 canheader.dlc = payload_length;
2105
2106 phtonu32(tmpbuf, canid);
2107 tmpbuf[4] = payload_length;
2108
2109 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2110
2111 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, canheader.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2112 if (canheader.flags & BLF_CANERROREXT_FLAG_CANCORE0x02) {
2113 direction_tx = (canheader.errorCodeExt & BLF_CANERROREXT_EXTECC_TX0x1000) == BLF_CANERROREXT_EXTECC_TX0x1000;
2114 blf_add_direction_option(params, direction_tx ? BLF_DIR_TX1: BLF_DIR_RX0);
2115 }
2116 return true1;
2117}
2118
2119static bool_Bool
2120blf_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) {
2121 blf_canfderror64_t canheader;
2122
2123 bool_Bool err_ack = false0;
2124 bool_Bool err_prot = false0;
2125 bool_Bool direction_tx;
2126 uint32_t canid;
2127 uint8_t payload_length;
2128 uint8_t tmpbuf[16] = {0};
2129
2130 if (object_length < (data_start - block_start) + (int) sizeof(canheader)) {
2131 *err = WTAP_ERR_BAD_FILE-13;
2132 *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"
)
;
2133 ws_debug("not enough bytes for canfderror header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2133, __func__, "not enough bytes for canfderror header in object"
); } } while (0)
;
2134 return false0;
2135 }
2136
2137 if (!blf_read_bytes(params, data_start, &canheader, sizeof(canheader), err, err_info)) {
2138 ws_debug("not enough bytes for canfderror header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2138, __func__, "not enough bytes for canfderror header in file"
); } } while (0)
;
2139 return false0;
2140 }
2141 fix_endianness_blf_canfderror64(&canheader);
2142
2143 if (canheader.flags & BLF_CANERROREXT_FLAG_CANCORE0x02) {
2144 // Map Vector Can Core error codes to compareable socketcan errors
2145 switch ((canheader.errorCodeExt >> 6) & 0x3f) {
2146 case BLF_CANERROREXT_ECC_MEANING_BIT_ERROR0x0:
2147 err_prot = true1;
2148 tmpbuf[10] = CAN_ERR_PROT_BIT0x01;
2149 break;
2150 case BLF_CANERROREXT_ECC_MEANING_FORM_ERROR0x1:
2151 err_prot = true1;
2152 tmpbuf[10] = CAN_ERR_PROT_FORM0x02;
2153 break;
2154 case BLF_CANERROREXT_ECC_MEANING_STUFF_ERROR0x2:
2155 err_prot = true1;
2156 tmpbuf[10] = CAN_ERR_PROT_STUFF0x04;
2157 break;
2158 case BLF_CANERROREXT_ECC_MEANING_CRC_ERROR0x4:
2159 err_prot = true1;
2160 tmpbuf[11] = CAN_ERR_PROT_LOC_CRC_SEQ0x08;
2161 break;
2162 case BLF_CANERROREXT_ECC_MEANING_NACK_ERROR0x7:
2163 err_ack = true1;
2164 tmpbuf[11] = CAN_ERR_PROT_LOC_ACK0x19;
2165 break;
2166 case BLF_CANERROREXT_ECC_MEANING_OVERLOAD0x8:
2167 err_prot = true1;
2168 tmpbuf[10] = CAN_ERR_PROT_OVERLOAD0x20;
2169 break;
2170 default:
2171 err_prot = true1;
2172 tmpbuf[10] = CAN_ERR_PROT_UNSPEC0x00;
2173 break;
2174 }
2175 err_ack = err_ack || (canheader.errorCodeExt & BLF_CANERROREXT_EXTECC_NOT_ACK0x2000) == 0x0;
2176 if (err_ack) {
2177 // Don't set protocol error on ack errors
2178 err_prot = false0;
2179 }
2180 }
2181
2182 // CanID contains error class in socketcan
2183 canid = CAN_ERR_FLAG0x20000000;
2184 canid |= err_prot ? CAN_ERR_PROT0x00000008U : 0;
2185 canid |= err_ack ? CAN_ERR_ACK0x00000020U : 0;
2186
2187 // Fixed packet data length for socketcan error messages
2188 payload_length = CAN_ERR_DLC8;
2189 canheader.dlc = payload_length;
2190
2191 phtonu32(tmpbuf, canid);
2192 tmpbuf[4] = payload_length;
2193 // Don't set FDF, ESI and BRS flags, since error messages are always encapsulated in Classic CAN frames
2194
2195 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2196
2197 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, canheader.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2198 if (canheader.flags & BLF_CANERROREXT_FLAG_CANCORE0x02) {
2199 direction_tx = (canheader.errorCodeExt & BLF_CANERROREXT_EXTECC_TX0x1000) == BLF_CANERROREXT_EXTECC_TX0x1000;
2200 blf_add_direction_option(params, direction_tx ? BLF_DIR_TX1: BLF_DIR_RX0);
2201 }
2202 return true1;
2203}
2204
2205static bool_Bool
2206blf_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) {
2207 blf_canxlchannelframe_t canxlheader;
2208
2209 if (object_length < (data_start - block_start) + (int)sizeof(canxlheader)) {
2210 *err = WTAP_ERR_BAD_FILE-13;
2211 *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"
)
;
2212 ws_debug("not enough bytes for canxlchannelframe header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2212, __func__, "not enough bytes for canxlchannelframe header in object"
); } } while (0)
;
2213 return false0;
2214 }
2215
2216 if (!blf_read_bytes(params, data_start, &canxlheader, sizeof(canxlheader), err, err_info)) {
2217 ws_debug("not enough bytes for canxlchannelframe header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2217, __func__, "not enough bytes for canxlchannelframe header in file"
); } } while (0)
;
2218 return false0;
2219 }
2220 fix_endianness_blf_canxlchannelframe(&canxlheader);
2221
2222 uint16_t payload_length = canxlheader.dataLength;
2223 bool_Bool is_canxl = canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000;
2224
2225 if (is_canxl) {
2226 uint16_t canid = canxlheader.frameIdentifier & CAN_SFF_MASK0x000007FF;
2227
2228 uint8_t canxl_flags = 0;
2229 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000) == BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000) {
2230 canxl_flags |= CANXL_XLF0x80;
2231 }
2232
2233 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_SEC0x1000000) == BLF_CANXLCHANNELFRAME_FLAG_SEC0x1000000) {
2234 canxl_flags |= CANXL_SEC0x01;
2235 }
2236
2237 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_RRS0x800000) == BLF_CANXLCHANNELFRAME_FLAG_RRS0x800000) {
2238 canxl_flags |= CANXL_RRS0x02;
2239 }
2240
2241 uint8_t tmpbuf[12] = { 0 };
2242 tmpbuf[1] = canxlheader.virtualControllerAreaNetChannelID;
2243 phtonu16(tmpbuf + 2, canid);
2244 tmpbuf[4] = canxl_flags;
2245 tmpbuf[5] = canxlheader.serviceDataUnitType;
2246 phtoleu16(tmpbuf + 6, payload_length);
2247 phtoleu32(tmpbuf + 8, canxlheader.acceptanceField);
2248
2249 if (object_length < (data_start - block_start) + (int)sizeof(canxlheader) + payload_length) {
2250 *err = WTAP_ERR_BAD_FILE-13;
2251 *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"
)
;
2252 ws_debug("not enough bytes for canxl payload in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2252, __func__, "not enough bytes for canxl payload in object"
); } } while (0)
;
2253 return false0;
2254 }
2255
2256 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length);
2257 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2258
2259 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)) {
2260 ws_debug("copying canxl payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2260, __func__, "copying canxl payload failed"); } } while (
0)
;
2261 return false0;
2262 }
2263 ws_buffer_increase_length(&params->rec->data, payload_length);
2264
2265 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_SOCKETCAN125, canxlheader.channel, UINT16_MAX(65535), sizeof(tmpbuf) + payload_length, sizeof(tmpbuf) + payload_length);
2266 } else {
2267 // Support for CAN or CAN-FD in CAN-XL Channel Frame format is experimental as of 2025!
2268 // If you have samples traces, please create a ticket and attach them to it: https://gitlab.com/wireshark/wireshark/-/issues
2269
2270 bool_Bool canfd = canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_FDF0x1000;
2271 uint8_t canfd_flags = 0;
2272
2273 if (object_length < (data_start - block_start) + (int)sizeof(canxlheader) + payload_length) {
2274 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"
, 2274, __func__, "shortening canxl for can/canfd payload because buffer is too short."
); } } while (0)
;
2275 object_length = (data_start - block_start) + (int)sizeof(canxlheader) + payload_length;
Value stored to 'object_length' is never read
2276 }
2277
2278 if (canfd) {
2279 if (payload_length > 64) {
2280 ws_debug("CANFD should not have payload_length > 64. Shortening!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2280, __func__, "CANFD should not have payload_length > 64. Shortening!"
); } } while (0)
;
2281 payload_length = 64;
2282 }
2283
2284 if (canxlheader.dlc > 0x0f) {
2285 ws_debug("CANFD should not have DLC > 0x0f.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2285, __func__, "CANFD should not have DLC > 0x0f."); } }
while (0)
;
2286 } else if (payload_length > canfd_dlc_to_length[canxlheader.dlc]) {
2287 ws_debug("CANFD payload_length and DLC not compatible!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2287, __func__, "CANFD payload_length and DLC not compatible!"
); } } while (0)
;
2288 }
2289
2290
2291 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_BRS0x2000) == BLF_CANXLCHANNELFRAME_FLAG_BRS0x2000) {
2292 canfd_flags |= CANFD_BRS0x01;
2293 }
2294 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_ESI0x4000) == BLF_CANXLCHANNELFRAME_FLAG_ESI0x4000) {
2295 canfd_flags |= CANFD_ESI0x02;
2296 }
2297 if ((canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_FDF0x1000) == BLF_CANXLCHANNELFRAME_FLAG_FDF0x1000) {
2298 canfd_flags |= CANFD_FDF0x04;
2299 }
2300 } else {
2301 if (payload_length > 8) {
2302 ws_debug("Regular CAN should not have payload_length > 8. Shortening!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2302, __func__, "Regular CAN should not have payload_length > 8. Shortening!"
); } } while (0)
;
2303 payload_length = 8;
2304 }
2305
2306 if (canxlheader.dlc > 8) {
2307 ws_debug("Regular CAN should not have DLC > 8.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2307, __func__, "Regular CAN should not have DLC > 8.");
} } while (0)
;
2308 } else if (payload_length != canxlheader.dlc) {
2309 ws_debug("CAN payload_length and DLC not compatible!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2309, __func__, "CAN payload_length and DLC not compatible!"
); } } while (0)
;
2310 }
2311
2312 canfd_flags = 0;
2313 }
2314
2315 uint32_t canid = canxlheader.frameIdentifier;
2316
2317 /* Unclear how to reconstruct the EFF Flag. Let's make sure, we set it if the ID is more than 11 bits */
2318 if ((canid & CAN_EFF_MASK0x1FFFFFFF) > CAN_SFF_MASK0x000007FF) {
2319 canid |= CAN_EFF_FLAG0x80000000;
2320 }
2321
2322 if (!canfd && (canxlheader.flags & BLF_CANXLCHANNELFRAME_FLAG_REMOTE_FRAME0x10) == BLF_CANXLCHANNELFRAME_FLAG_REMOTE_FRAME0x10) {
2323 canid |= CAN_RTR_FLAG0x40000000;
2324 payload_length = 0;
2325 }
2326
2327 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)) {
2328 return false0;
2329 }
2330 }
2331
2332 blf_add_direction_option(params, canxlheader.dir ? BLF_DIR_TX1 : BLF_DIR_RX0);
2333
2334 return true1;
2335}
2336
2337static bool_Bool
2338blf_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) {
2339 blf_flexraydata_t frheader;
2340
2341 uint8_t payload_length;
2342 uint8_t payload_length_valid;
2343 uint8_t tmpbuf[7];
2344 unsigned caplen, len;
2345
2346 if (object_length < (data_start - block_start) + (int) sizeof(frheader)) {
2347 *err = WTAP_ERR_BAD_FILE-13;
2348 *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"
)
;
2349 ws_debug("not enough bytes for flexrayheader in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2349, __func__, "not enough bytes for flexrayheader in object"
); } } while (0)
;
2350 return false0;
2351 }
2352
2353 if (!blf_read_bytes(params, data_start, &frheader, sizeof(frheader), err, err_info)) {
2354 ws_debug("not enough bytes for flexrayheader header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2354, __func__, "not enough bytes for flexrayheader header in file"
); } } while (0)
;
2355 return false0;
2356 }
2357 fix_endianness_blf_flexraydata(&frheader);
2358
2359 payload_length = frheader.len;
2360 payload_length_valid = payload_length;
2361
2362 if ((frheader.len & 0x01) == 0x01) {
2363 ws_debug("reading odd length in FlexRay!?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2363, __func__, "reading odd length in FlexRay!?"); } } while
(0)
;
2364 }
2365
2366 if (payload_length_valid > object_length - (data_start - block_start) - sizeof(frheader)) {
2367 ws_debug("shortening FlexRay payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2367, __func__, "shortening FlexRay payload because buffer is too short."
); } } while (0)
;
2368 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - sizeof(frheader));
2369 }
2370
2371 if (frheader.channel != 0 && frheader.channel != 1) {
2372 ws_debug("FlexRay supports only two channels.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2372, __func__, "FlexRay supports only two channels."); } }
while (0)
;
2373 }
2374
2375 /* Measurement Header */
2376 if (frheader.channel == 0) {
2377 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01;
2378 } else {
2379 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01 | BLF_FLEXRAYDATA_CHANNEL_B0x80;
2380 }
2381
2382 /* Error Flags */
2383 tmpbuf[1] = 0;
2384
2385 /* Frame Header */
2386 tmpbuf[2] = 0x20 | ((0x0700 & frheader.messageId) >> 8);
2387 tmpbuf[3] = 0x00ff & frheader.messageId;
2388 tmpbuf[4] = (0xfe & frheader.len) | ((frheader.crc & 0x0400) >> 10);
2389 tmpbuf[5] = (0x03fc & frheader.crc) >> 2;
2390 tmpbuf[6] = ((0x0003 & frheader.crc) << 6) | (0x3f & frheader.mux);
2391
2392 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length_valid);
2393 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2394 caplen = sizeof(tmpbuf) + payload_length_valid;
2395 len = sizeof(tmpbuf) + payload_length;
2396
2397 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)) {
2398 ws_debug("copying flexray payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2398, __func__, "copying flexray payload failed"); } } while
(0)
;
2399 return false0;
2400 }
2401 ws_buffer_increase_length(&params->rec->data, payload_length_valid);
2402
2403 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_FLEXRAY106, frheader.channel, UINT16_MAX(65535), caplen, len);
2404 blf_add_direction_option(params, frheader.dir);
2405
2406 return true1;
2407}
2408
2409static bool_Bool
2410blf_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) {
2411 blf_flexraymessage_t frheader;
2412
2413 uint8_t payload_length;
2414 uint8_t payload_length_valid;
2415 uint8_t tmpbuf[7];
2416 unsigned caplen, len;
2417
2418 if (object_length < (data_start - block_start) + (int) sizeof(frheader)) {
2419 *err = WTAP_ERR_BAD_FILE-13;
2420 *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"
)
;
2421 ws_debug("not enough bytes for flexrayheader in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2421, __func__, "not enough bytes for flexrayheader in object"
); } } while (0)
;
2422 return false0;
2423 }
2424
2425 if (!blf_read_bytes(params, data_start, &frheader, sizeof(frheader), err, err_info)) {
2426 ws_debug("not enough bytes for flexrayheader header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2426, __func__, "not enough bytes for flexrayheader header in file"
); } } while (0)
;
2427 return false0;
2428 }
2429 fix_endianness_blf_flexraymessage(&frheader);
2430
2431 payload_length = frheader.length;
2432 payload_length_valid = payload_length;
2433
2434 if ((frheader.length & 0x01) == 0x01) {
2435 ws_debug("reading odd length in FlexRay!?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2435, __func__, "reading odd length in FlexRay!?"); } } while
(0)
;
2436 }
2437
2438 if (payload_length_valid > object_length - (data_start - block_start) - sizeof(frheader)) {
2439 ws_debug("shortening FlexRay payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2439, __func__, "shortening FlexRay payload because buffer is too short."
); } } while (0)
;
2440 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - sizeof(frheader));
2441 }
2442
2443 if (frheader.channel != 0 && frheader.channel != 1) {
2444 ws_debug("FlexRay supports only two channels.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2444, __func__, "FlexRay supports only two channels."); } }
while (0)
;
2445 }
2446
2447 /* Measurement Header */
2448 if (frheader.channel == 0) {
2449 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01;
2450 } else {
2451 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01 | BLF_FLEXRAYDATA_CHANNEL_B0x80;
2452 }
2453
2454 /* Error Flags */
2455 tmpbuf[1] = 0;
2456
2457 /* Frame Header */
2458 tmpbuf[2] = ((0x0700 & frheader.frameId) >> 8);
2459 if ((frheader.frameState & BLF_FLEXRAYMESSAGE_STATE_PPI0x01) == BLF_FLEXRAYMESSAGE_STATE_PPI0x01) {
2460 tmpbuf[2] |= BLF_DLT_FLEXRAY_PPI0x40;
2461 }
2462
2463 if ((frheader.frameState & BLF_FLEXRAYMESSAGE_STATE_SFI0x02) == BLF_FLEXRAYMESSAGE_STATE_SFI0x02) {
2464 tmpbuf[2] |= BLF_DLT_FLEXRAY_SFI0x10;
2465 }
2466
2467 if ((frheader.frameState & BLF_FLEXRAYMESSAGE_STATE_NFI0x08) != BLF_FLEXRAYMESSAGE_STATE_NFI0x08) {
2468 /* NFI needs to be inversed !? */
2469 tmpbuf[2] |= BLF_DLT_FLEXRAY_NFI0x20;
2470 }
2471
2472 if ((frheader.frameState & BLF_FLEXRAYMESSAGE_STATE_STFI0x10) == BLF_FLEXRAYMESSAGE_STATE_STFI0x10) {
2473 tmpbuf[2] |= BLF_DLT_FLEXRAY_STFI0x08;
2474 }
2475
2476 tmpbuf[3] = 0x00ff & frheader.frameId;
2477 tmpbuf[4] = (0xfe & frheader.length) | ((frheader.headerCrc & 0x0400) >> 10);
2478 tmpbuf[5] = (0x03fc & frheader.headerCrc) >> 2;
2479 tmpbuf[6] = ((0x0003 & frheader.headerCrc) << 6) | (0x3f & frheader.cycle);
2480
2481 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length_valid);
2482 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2483 caplen = sizeof(tmpbuf) + payload_length_valid;
2484 len = sizeof(tmpbuf) + payload_length;
2485
2486 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)) {
2487 ws_debug("copying flexray payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2487, __func__, "copying flexray payload failed"); } } while
(0)
;
2488 return false0;
2489 }
2490 ws_buffer_increase_length(&params->rec->data, payload_length_valid);
2491
2492 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_FLEXRAY106, frheader.channel, UINT16_MAX(65535), caplen, len);
2493 blf_add_direction_option(params, frheader.dir);
2494
2495 return true1;
2496}
2497
2498static bool_Bool
2499blf_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) {
2500 blf_flexrayrcvmessage_t frheader;
2501
2502 uint16_t payload_length;
2503 uint16_t payload_length_valid;
2504 uint8_t tmpbuf[7];
2505 int frheadersize = sizeof(frheader);
2506 unsigned caplen, len;
2507
2508 if (ext) {
2509 frheadersize += 40;
2510 }
2511
2512 if ((int64_t)object_length < (data_start - block_start) + frheadersize) {
2513 *err = WTAP_ERR_BAD_FILE-13;
2514 *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")
2515 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")
;
2516 ws_debug("not enough bytes for flexrayheader in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2516, __func__, "not enough bytes for flexrayheader in object"
); } } while (0)
;
2517 return false0;
2518 }
2519
2520 if (!blf_read_bytes(params, data_start, &frheader, sizeof(frheader), err, err_info)) {
2521 ws_debug("not enough bytes for flexrayheader header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2521, __func__, "not enough bytes for flexrayheader header in file"
); } } while (0)
;
2522 return false0;
2523 }
2524 fix_endianness_blf_flexrayrcvmessage(&frheader);
2525
2526 if (!ext) {
2527 frheader.dir &= 0xff;
2528 frheader.cycle &= 0xff;
2529 }
2530
2531 payload_length = frheader.payloadLength;
2532 payload_length_valid = frheader.payloadLengthValid;
2533
2534 if ((frheader.payloadLength & 0x01) == 0x01) {
2535 ws_debug("reading odd length in FlexRay!?")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2535, __func__, "reading odd length in FlexRay!?"); } } while
(0)
;
2536 }
2537
2538 if (payload_length_valid > object_length - (data_start - block_start) - frheadersize) {
2539 ws_debug("shortening FlexRay payload because buffer is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2539, __func__, "shortening FlexRay payload because buffer is too short."
); } } while (0)
;
2540 payload_length_valid = (uint8_t)(object_length - (data_start - block_start) - frheadersize);
2541 }
2542
2543 /* Measurement Header */
2544 /* TODO: It seems that this format support both channels at the same time!? */
2545 if (frheader.channelMask == BLF_FLEXRAYRCVMSG_CHANNELMASK_A0x01) {
2546 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01;
2547 } else {
2548 tmpbuf[0] = BLF_FLEXRAYDATA_FRAME0x01 | BLF_FLEXRAYDATA_CHANNEL_B0x80;
2549 }
2550
2551 /* Error Flags */
2552 tmpbuf[1] = 0;
2553
2554 /* Frame Header */
2555 tmpbuf[2] = ((0x0700 & frheader.frameId) >> 8);
2556 if ((frheader.frameFlags & BLF_FLEXRAYRCVMSG_FRAME_FLAG_PAYLOAD_PREAM0x00000010) == BLF_FLEXRAYRCVMSG_FRAME_FLAG_PAYLOAD_PREAM0x00000010) {
2557 tmpbuf[2] |= BLF_DLT_FLEXRAY_PPI0x40;
2558 }
2559
2560 if ((frheader.frameFlags & BLF_FLEXRAYRCVMSG_FRAME_FLAG_SYNC0x00000004) == BLF_FLEXRAYRCVMSG_FRAME_FLAG_SYNC0x00000004) {
2561 tmpbuf[2] |= BLF_DLT_FLEXRAY_SFI0x10;
2562 }
2563
2564 if ((frheader.frameFlags & BLF_FLEXRAYRCVMSG_FRAME_FLAG_NULL_FRAME0x00000001) != BLF_FLEXRAYRCVMSG_FRAME_FLAG_NULL_FRAME0x00000001) {
2565 /* NFI needs to be inversed !? */
2566 tmpbuf[2] |= BLF_DLT_FLEXRAY_NFI0x20;
2567 }
2568
2569 if ((frheader.frameFlags & BLF_FLEXRAYRCVMSG_FRAME_FLAG_STARTUP0x00000008) == BLF_FLEXRAYRCVMSG_FRAME_FLAG_STARTUP0x00000008) {
2570 tmpbuf[2] |= BLF_DLT_FLEXRAY_STFI0x08;
2571 }
2572
2573 tmpbuf[3] = 0x00ff & frheader.frameId;
2574 tmpbuf[4] = (0xfe & frheader.payloadLength) | ((frheader.headerCrc1 & 0x0400) >> 10);
2575 tmpbuf[5] = (0x03fc & frheader.headerCrc1) >> 2;
2576 tmpbuf[6] = ((0x0003 & frheader.headerCrc1) << 6) | (0x3f & frheader.cycle);
2577
2578 ws_buffer_assure_space(&params->rec->data, sizeof(tmpbuf) + payload_length_valid);
2579 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2580 caplen = sizeof(tmpbuf) + payload_length_valid;
2581 len = sizeof(tmpbuf) + payload_length;
2582
2583 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)) {
2584 ws_debug("copying flexray payload failed")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2584, __func__, "copying flexray payload failed"); } } while
(0)
;
2585 return false0;
2586 }
2587 ws_buffer_increase_length(&params->rec->data, payload_length_valid);
2588
2589 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_FLEXRAY106, frheader.channelMask, UINT16_MAX(65535), caplen, len);
2590 blf_add_direction_option(params, frheader.dir);
2591
2592 return true1;
2593}
2594
2595static bool_Bool
2596blf_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) {
2597 blf_linmessage_t linmessage;
2598
2599 uint8_t payload_length;
2600 unsigned len;
2601
2602 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2603 *err = WTAP_ERR_BAD_FILE-13;
2604 *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")
;
2605 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"
, 2605, __func__, "not enough bytes for %s in object", crc_error
? "lincrcerror" : "linmessage"); } } while (0)
;
2606 return false0;
2607 }
2608
2609 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2610 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"
, 2610, __func__, "not enough bytes for %s in file", crc_error
? "lincrcerror" : "linmessage"); } } while (0)
;
2611 return false0;
2612 }
2613 fix_endianness_blf_linmessage(&linmessage);
2614
2615 linmessage.dlc &= 0x0f;
2616 linmessage.id &= 0x3f;
2617
2618 payload_length = MIN(linmessage.dlc, 8)(((linmessage.dlc) < (8)) ? (linmessage.dlc) : (8));
2619
2620 uint8_t tmpbuf[8];
2621 tmpbuf[0] = 1; /* message format rev = 1 */
2622 tmpbuf[1] = 0; /* reserved */
2623 tmpbuf[2] = 0; /* reserved */
2624 tmpbuf[3] = 0; /* reserved */
2625 tmpbuf[4] = linmessage.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2626 tmpbuf[5] = linmessage.id; /* parity (2bit) | id (6bit) */
2627 tmpbuf[6] = (uint8_t)(linmessage.crc & 0xff); /* checksum */
2628 tmpbuf[7] = 0; /* errors */
2629
2630 if (crc_error) {
2631 tmpbuf[7] |= 0x08;
2632 }
2633
2634 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2635 ws_buffer_append(&params->rec->data, linmessage.data, payload_length);
2636 len = sizeof(tmpbuf) + payload_length;
2637
2638 /* make sure that the payload is 4 or 8 bytes long */
2639 const uint8_t padding[4] = { 0, 0, 0, 0 };
2640 if (payload_length < 4) {
2641 ws_buffer_append(&params->rec->data, padding, 4 - payload_length);
2642 len += 4 - payload_length;
2643 } else if (payload_length > 4 && payload_length < 8) {
2644 ws_buffer_append(&params->rec->data, padding, 8 - payload_length);
2645 len += 8 - payload_length;
2646 }
2647
2648 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.channel, UINT16_MAX(65535), len, len);
2649 blf_add_direction_option(params, linmessage.dir);
2650
2651 return true1;
2652}
2653
2654static bool_Bool
2655blf_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) {
2656 blf_linrcverror_t linmessage;
2657
2658 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2659 *err = WTAP_ERR_BAD_FILE-13;
2660 *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"
)
;
2661 ws_debug("not enough bytes for linrcverror in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2661, __func__, "not enough bytes for linrcverror in object"
); } } while (0)
;
2662 return false0;
2663 }
2664
2665 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2666 ws_debug("not enough bytes for linrcverror in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2666, __func__, "not enough bytes for linrcverror in file")
; } } while (0)
;
2667 return false0;
2668 }
2669 linmessage.channel = GUINT16_FROM_LE(linmessage.channel)(((guint16) (linmessage.channel)));
2670
2671 linmessage.dlc &= 0x0f;
2672 linmessage.id &= 0x3f;
2673
2674 uint8_t tmpbuf[12];
2675 tmpbuf[0] = 1; /* message format rev = 1 */
2676 tmpbuf[1] = 0; /* reserved */
2677 tmpbuf[2] = 0; /* reserved */
2678 tmpbuf[3] = 0; /* reserved */
2679 tmpbuf[4] = linmessage.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2680 tmpbuf[5] = linmessage.id; /* parity (2bit) | id (6bit) */
2681 tmpbuf[6] = 0; /* checksum */
2682 /* XXX - This object can represent many different error types.
2683 * For now we always treat it as framing error,
2684 * but in the future we should expand it. */
2685 tmpbuf[7] = LIN_ERROR_FRAMING_ERROR0x02; /* errors */
2686 tmpbuf[8] = 0;
2687 tmpbuf[9] = 0;
2688 tmpbuf[10] = 0;
2689 tmpbuf[11] = 0;
2690
2691 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2692 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2693
2694 return true1;
2695}
2696
2697static bool_Bool
2698blf_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) {
2699 blf_linsenderror_t linmessage;
2700
2701 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2702 *err = WTAP_ERR_BAD_FILE-13;
2703 *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"
)
;
2704 ws_debug("not enough bytes for linsenderror in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2704, __func__, "not enough bytes for linsenderror in object"
); } } while (0)
;
2705 return false0;
2706 }
2707
2708 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2709 ws_debug("not enough bytes for linsenderror in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2709, __func__, "not enough bytes for linsenderror in file"
); } } while (0)
;
2710 return false0;
2711 }
2712 linmessage.channel = GUINT16_FROM_LE(linmessage.channel)(((guint16) (linmessage.channel)));
2713
2714 linmessage.dlc &= 0x0f;
2715 linmessage.id &= 0x3f;
2716
2717 uint8_t tmpbuf[12];
2718 tmpbuf[0] = 1; /* message format rev = 1 */
2719 tmpbuf[1] = 0; /* reserved */
2720 tmpbuf[2] = 0; /* reserved */
2721 tmpbuf[3] = 0; /* reserved */
2722 tmpbuf[4] = linmessage.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2723 tmpbuf[5] = linmessage.id; /* parity (2bit) | id (6bit) */
2724 tmpbuf[6] = 0; /* checksum */
2725 tmpbuf[7] = LIN_ERROR_NO_SLAVE_RESPONSE0x01; /* errors */
2726 tmpbuf[8] = 0;
2727 tmpbuf[9] = 0;
2728 tmpbuf[10] = 0;
2729 tmpbuf[11] = 0;
2730
2731 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2732 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2733
2734 return true1;
2735}
2736
2737static bool_Bool
2738blf_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) {
2739 blf_linwakeupevent_t linevent;
2740
2741 if (object_length < (data_start - block_start) + (int)sizeof(linevent)) {
2742 *err = WTAP_ERR_BAD_FILE-13;
2743 *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"
)
;
2744 ws_debug("not enough bytes for linwakeup in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2744, __func__, "not enough bytes for linwakeup in object")
; } } while (0)
;
2745 return false0;
2746 }
2747
2748 if (!blf_read_bytes(params, data_start, &linevent, sizeof(linevent), err, err_info)) {
2749 ws_debug("not enough bytes for linwakeup in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2749, __func__, "not enough bytes for linwakeup in file"); }
} while (0)
;
2750 return false0;
2751 }
2752 linevent.channel = GUINT16_FROM_LE(linevent.channel)(((guint16) (linevent.channel)));
2753
2754 uint8_t tmpbuf[12]; /* LIN events have a fixed length of 12 bytes */
2755 tmpbuf[0] = 1; /* message format rev = 1 */
2756 tmpbuf[1] = 0; /* reserved */
2757 tmpbuf[2] = 0; /* reserved */
2758 tmpbuf[3] = 0; /* reserved */
2759 tmpbuf[4] = 3 << 2; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2760 tmpbuf[5] = 0; /* parity (2bit) | id (6bit) */
2761 tmpbuf[6] = 0; /* checksum */
2762 tmpbuf[7] = 0; /* errors */
2763
2764 /* Wake-up event */
2765 tmpbuf[8] = 0xB0;
2766 tmpbuf[9] = 0xB0;
2767 tmpbuf[10] = 0x00;
2768 tmpbuf[11] = 0x04;
2769
2770 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2771
2772 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linevent.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
2773
2774 return true1;
2775}
2776
2777static bool_Bool
2778blf_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) {
2779 blf_linmessage2_t linmessage;
2780
2781 uint8_t payload_length;
2782 unsigned len;
2783
2784 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2785 *err = WTAP_ERR_BAD_FILE-13;
2786 *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"
)
;
2787 ws_debug("not enough bytes for linmessage2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2787, __func__, "not enough bytes for linmessage2 in object"
); } } while (0)
;
2788 return false0;
2789 }
2790
2791 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2792 ws_debug("not enough bytes for linmessage2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2792, __func__, "not enough bytes for linmessage2 in file")
; } } while (0)
;
2793 return false0;
2794 }
2795 fix_endianness_blf_linmessage2(&linmessage);
2796
2797 linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc &= 0x0f;
2798 linmessage.linDataByteTimestampEvent.linMessageDescriptor.id &= 0x3f;
2799
2800 payload_length = MIN(linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc, 8)(((linmessage.linDataByteTimestampEvent.linMessageDescriptor.
dlc) < (8)) ? (linmessage.linDataByteTimestampEvent.linMessageDescriptor
.dlc) : (8))
;
2801
2802 uint8_t tmpbuf[8];
2803 tmpbuf[0] = 1; /* message format rev = 1 */
2804 tmpbuf[1] = 0; /* reserved */
2805 tmpbuf[2] = 0; /* reserved */
2806 tmpbuf[3] = 0; /* reserved */
2807 tmpbuf[4] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2808 if (object_version >= 1) { /* The 'checksumModel' field is valid only if objectVersion >= 1 */
2809 switch (linmessage.linDataByteTimestampEvent.linMessageDescriptor.checksumModel) {
2810 case 0:
2811 tmpbuf[4] |= 1; /* Classic */
2812 break;
2813 case 1:
2814 tmpbuf[4] |= 2; /* Enhanced */
2815 break;
2816 default:
2817 break;
2818 }
2819 }
2820 tmpbuf[5] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.id; /* parity (2bit) | id (6bit) */
2821 tmpbuf[6] = (uint8_t)(linmessage.crc & 0xff); /* checksum */
2822 tmpbuf[7] = 0; /* errors */
2823
2824 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2825 ws_buffer_append(&params->rec->data, linmessage.data, payload_length);
2826 len = sizeof(tmpbuf) + payload_length;
2827
2828 /* make sure that the payload is 4 or 8 bytes long */
2829 const uint8_t padding[4] = { 0, 0, 0, 0 };
2830 if (payload_length < 4) {
2831 ws_buffer_append(&params->rec->data, padding, 4 - payload_length);
2832 len += 4 - payload_length;
2833 } else if (payload_length > 4 && payload_length < 8) {
2834 ws_buffer_append(&params->rec->data, padding, 8 - payload_length);
2835 len += 8 - payload_length;
2836 }
2837
2838 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.linDataByteTimestampEvent.linMessageDescriptor.linSynchFieldEvent.linBusEvent.channel, UINT16_MAX(65535), len, len);
2839 blf_add_direction_option(params, linmessage.dir);
2840
2841 return true1;
2842}
2843
2844static bool_Bool
2845blf_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) {
2846 blf_lincrcerror2_t linmessage;
2847
2848 uint8_t payload_length;
2849 unsigned len;
2850
2851 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2852 *err = WTAP_ERR_BAD_FILE-13;
2853 *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"
)
;
2854 ws_debug("not enough bytes for lincrcerror2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2854, __func__, "not enough bytes for lincrcerror2 in object"
); } } while (0)
;
2855 return false0;
2856 }
2857
2858 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2859 ws_debug("not enough bytes for lincrcerror2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2859, __func__, "not enough bytes for lincrcerror2 in file"
); } } while (0)
;
2860 return false0;
2861 }
2862 fix_endianness_blf_lincrcerror2(&linmessage);
2863
2864 linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc &= 0x0f;
2865 linmessage.linDataByteTimestampEvent.linMessageDescriptor.id &= 0x3f;
2866
2867 payload_length = MIN(linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc, 8)(((linmessage.linDataByteTimestampEvent.linMessageDescriptor.
dlc) < (8)) ? (linmessage.linDataByteTimestampEvent.linMessageDescriptor
.dlc) : (8))
;
2868
2869 uint8_t tmpbuf[12];
2870 tmpbuf[0] = 1; /* message format rev = 1 */
2871 tmpbuf[1] = 0; /* reserved */
2872 tmpbuf[2] = 0; /* reserved */
2873 tmpbuf[3] = 0; /* reserved */
2874 tmpbuf[4] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2875 if (object_version >= 1) { /* The 'checksumModel' field is valid only if objectVersion >= 1 */
2876 switch (linmessage.linDataByteTimestampEvent.linMessageDescriptor.checksumModel) {
2877 case 0:
2878 tmpbuf[4] |= 1; /* Classic */
2879 break;
2880 case 1:
2881 tmpbuf[4] |= 2; /* Enhanced */
2882 break;
2883 default:
2884 break;
2885 }
2886 }
2887 tmpbuf[5] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.id; /* parity (2bit) | id (6bit) */
2888 tmpbuf[6] = (uint8_t)(linmessage.crc & 0xff); /* checksum */
2889 tmpbuf[7] = LIN_ERROR_CHECKSUM_ERROR0x08; /* errors */
2890 tmpbuf[8] = 0;
2891 tmpbuf[9] = 0;
2892 tmpbuf[10] = 0;
2893 tmpbuf[11] = 0;
2894
2895 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2896 ws_buffer_append(&params->rec->data, linmessage.data, payload_length);
2897 len = sizeof(tmpbuf) + payload_length;
2898
2899 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.linDataByteTimestampEvent.linMessageDescriptor.linSynchFieldEvent.linBusEvent.channel, UINT16_MAX(65535), len, len);
2900 blf_add_direction_option(params, linmessage.dir);
2901
2902 return true1;
2903}
2904
2905static bool_Bool
2906blf_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) {
2907 blf_linrcverror2_t linmessage;
2908
2909 uint8_t payload_length;
2910 unsigned len;
2911
2912 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2913 *err = WTAP_ERR_BAD_FILE-13;
2914 *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"
)
;
2915 ws_debug("not enough bytes for linrcverror2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2915, __func__, "not enough bytes for linrcverror2 in object"
); } } while (0)
;
2916 return false0;
2917 }
2918
2919 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2920 ws_debug("not enough bytes for linrcverror2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2920, __func__, "not enough bytes for linrcverror2 in file"
); } } while (0)
;
2921 return false0;
2922 }
2923 fix_endianness_blf_linrcverror2(&linmessage);
2924
2925 linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc &= 0x0f;
2926 linmessage.linDataByteTimestampEvent.linMessageDescriptor.id &= 0x3f;
2927
2928 if (linmessage.hasDataBytes) {
2929 payload_length = MIN(linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc, 8)(((linmessage.linDataByteTimestampEvent.linMessageDescriptor.
dlc) < (8)) ? (linmessage.linDataByteTimestampEvent.linMessageDescriptor
.dlc) : (8))
;
2930 } else {
2931 payload_length = 0;
2932 }
2933
2934 uint8_t tmpbuf[12];
2935 tmpbuf[0] = 1; /* message format rev = 1 */
2936 tmpbuf[1] = 0; /* reserved */
2937 tmpbuf[2] = 0; /* reserved */
2938 tmpbuf[3] = 0; /* reserved */
2939 tmpbuf[4] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
2940 if (object_version >= 1) { /* The 'checksumModel' field is valid only if objectVersion >= 1 */
2941 switch (linmessage.linDataByteTimestampEvent.linMessageDescriptor.checksumModel) {
2942 case 0:
2943 tmpbuf[4] |= 1; /* Classic */
2944 break;
2945 case 1:
2946 tmpbuf[4] |= 2; /* Enhanced */
2947 break;
2948 default:
2949 break;
2950 }
2951 }
2952 tmpbuf[5] = linmessage.linDataByteTimestampEvent.linMessageDescriptor.id; /* parity (2bit) | id (6bit) */
2953 tmpbuf[6] = 0; /* checksum */
2954 /* XXX - This object can represent many different error types.
2955 * For now we always treat it as framing error,
2956 * but in the future we should expand it. */
2957 tmpbuf[7] = LIN_ERROR_FRAMING_ERROR0x02; /* errors */
2958 tmpbuf[8] = 0;
2959 tmpbuf[9] = 0;
2960 tmpbuf[10] = 0;
2961 tmpbuf[11] = 0;
2962
2963 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
2964 if (payload_length > 0) {
2965 ws_buffer_append(&params->rec->data, linmessage.data, payload_length);
2966 }
2967 len = sizeof(tmpbuf) + payload_length;
2968
2969 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.linDataByteTimestampEvent.linMessageDescriptor.linSynchFieldEvent.linBusEvent.channel, UINT16_MAX(65535), len, len);
2970
2971 return true1;
2972}
2973
2974static bool_Bool
2975blf_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) {
2976 blf_linsenderror2_t linmessage;
2977
2978 if (object_length < (data_start - block_start) + (int)sizeof(linmessage)) {
2979 *err = WTAP_ERR_BAD_FILE-13;
2980 *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"
)
;
2981 ws_debug("not enough bytes for linsenderror2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2981, __func__, "not enough bytes for linsenderror2 in object"
); } } while (0)
;
2982 return false0;
2983 }
2984
2985 if (!blf_read_bytes(params, data_start, &linmessage, sizeof(linmessage), err, err_info)) {
2986 ws_debug("not enough bytes for linsenderror2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 2986, __func__, "not enough bytes for linsenderror2 in file"
); } } while (0)
;
2987 return false0;
2988 }
2989 fix_endianness_blf_linsenderror2(&linmessage);
2990
2991 linmessage.linMessageDescriptor.dlc &= 0x0f;
2992 linmessage.linMessageDescriptor.id &= 0x3f;
2993
2994 uint8_t tmpbuf[12];
2995 tmpbuf[0] = 1; /* message format rev = 1 */
2996 tmpbuf[1] = 0; /* reserved */
2997 tmpbuf[2] = 0; /* reserved */
2998 tmpbuf[3] = 0; /* reserved */
2999 tmpbuf[4] = linmessage.linMessageDescriptor.dlc << 4; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
3000 if (object_version >= 1) { /* The 'checksumModel' field is valid only if objectVersion >= 1 */
3001 switch (linmessage.linMessageDescriptor.checksumModel) {
3002 case 0:
3003 tmpbuf[4] |= 1; /* Classic */
3004 break;
3005 case 1:
3006 tmpbuf[4] |= 2; /* Enhanced */
3007 break;
3008 default:
3009 break;
3010 }
3011 }
3012 tmpbuf[5] = linmessage.linMessageDescriptor.id; /* parity (2bit) | id (6bit) */
3013 tmpbuf[6] = 0; /* checksum */
3014 tmpbuf[7] = LIN_ERROR_NO_SLAVE_RESPONSE0x01; /* errors */
3015 tmpbuf[8] = 0;
3016 tmpbuf[9] = 0;
3017 tmpbuf[10] = 0;
3018 tmpbuf[11] = 0;
3019
3020 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
3021
3022 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linmessage.linMessageDescriptor.linSynchFieldEvent.linBusEvent.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
3023
3024 return true1;
3025}
3026
3027static bool_Bool
3028blf_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) {
3029 blf_linwakeupevent2_t linevent;
3030
3031 if (object_length < (data_start - block_start) + (int)sizeof(linevent)) {
3032 *err = WTAP_ERR_BAD_FILE-13;
3033 *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"
)
;
3034 ws_debug("not enough bytes for linwakeup2 in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3034, __func__, "not enough bytes for linwakeup2 in object"
); } } while (0)
;
3035 return false0;
3036 }
3037
3038 if (!blf_read_bytes(params, data_start, &linevent, sizeof(linevent), err, err_info)) {
3039 ws_debug("not enough bytes for linwakeup2 in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3039, __func__, "not enough bytes for linwakeup2 in file");
} } while (0)
;
3040 return false0;
3041 }
3042 fix_endianness_blf_linwakeupevent2(&linevent);
3043
3044 uint8_t tmpbuf[12]; /* LIN events have a fixed length of 12 bytes */
3045 tmpbuf[0] = 1; /* message format rev = 1 */
3046 tmpbuf[1] = 0; /* reserved */
3047 tmpbuf[2] = 0; /* reserved */
3048 tmpbuf[3] = 0; /* reserved */
3049 tmpbuf[4] = 3 << 2; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
3050 tmpbuf[5] = 0; /* parity (2bit) | id (6bit) */
3051 tmpbuf[6] = 0; /* checksum */
3052 tmpbuf[7] = 0; /* errors */
3053
3054 /* Wake-up event */
3055 tmpbuf[8] = 0xB0;
3056 tmpbuf[9] = 0xB0;
3057 tmpbuf[10] = 0x00;
3058 tmpbuf[11] = 0x04;
3059
3060 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
3061
3062 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linevent.linBusEvent.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
3063
3064 return true1;
3065}
3066
3067static bool_Bool
3068blf_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) {
3069 blf_linsleepmodeevent_t linevent;
3070
3071 if (object_length < (data_start - block_start) + (int)sizeof(linevent)) {
3072 *err = WTAP_ERR_BAD_FILE-13;
3073 *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"
)
;
3074 ws_debug("not enough bytes for linsleep in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3074, __func__, "not enough bytes for linsleep in object");
} } while (0)
;
3075 return false0;
3076 }
3077
3078 if (!blf_read_bytes(params, data_start, &linevent, sizeof(linevent), err, err_info)) {
3079 ws_debug("not enough bytes for linsleep in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3079, __func__, "not enough bytes for linsleep in file"); }
} while (0)
;
3080 return false0;
3081 }
3082 linevent.channel = GUINT16_FROM_LE(linevent.channel)(((guint16) (linevent.channel)));
3083
3084 uint8_t tmpbuf[12]; /* LIN events have a fixed length of 12 bytes */
3085 tmpbuf[0] = 1; /* message format rev = 1 */
3086 tmpbuf[1] = 0; /* reserved */
3087 tmpbuf[2] = 0; /* reserved */
3088 tmpbuf[3] = 0; /* reserved */
3089 tmpbuf[4] = 3 << 2; /* dlc (4bit) | type (2bit) | checksum type (2bit) */
3090 tmpbuf[5] = 0; /* parity (2bit) | id (6bit) */
3091 tmpbuf[6] = 0; /* checksum */
3092 tmpbuf[7] = 0; /* errors */
3093
3094 switch (linevent.reason) {
3095 case BLF_LIN_SLEEP_REASON_GO_TO_SLEEP_FRAME1:
3096 /* Go-to-Sleep event by Go-to-Sleep frame */
3097 tmpbuf[8] = 0xB0;
3098 tmpbuf[9] = 0xB0;
3099 tmpbuf[10] = 0x00;
3100 tmpbuf[11] = 0x01;
3101 break;
3102 case BLF_LIN_SLEEP_REASON_BUS_IDLE_TIMEOUT2:
3103 case BLF_LIN_SLEEP_REASON_SILENT_SLEEPMODE_CMD3:
3104 /* Go-to-Sleep event by Inactivity for more than 4s */
3105 tmpbuf[8] = 0xB0;
3106 tmpbuf[9] = 0xB0;
3107 tmpbuf[10] = 0x00;
3108 tmpbuf[11] = 0x02;
3109 break;
3110 case BLF_LIN_WU_REASON_EXTERNAL_WAKEUP_SIG9:
3111 case BLF_LIN_WU_REASON_INTERNAL_WAKEUP_SIG10:
3112 case BLF_LIN_WU_REASON_BUS_TRAFFIC11: /* There's no "wake-up by bus traffic" event in the LIN packet. */
3113 /* Wake-up event by Wake-up signal */
3114 tmpbuf[8] = 0xB0;
3115 tmpbuf[9] = 0xB0;
3116 tmpbuf[10] = 0x00;
3117 tmpbuf[11] = 0x04;
3118 break;
3119 case BLF_LIN_WU_SLEEP_REASON_START_STATE0:
3120 case BLF_LIN_NO_SLEEP_REASON_BUS_TRAFFIC18:
3121 /* If we're just reporting on the initial state,
3122 * or the interface doesn't want to go to sleep,
3123 * report the current state as "event". */
3124 if (linevent.flags & 0x2) {
3125 /* Wake-up event by Wake-up signal */
3126 tmpbuf[8] = 0xB0;
3127 tmpbuf[9] = 0xB0;
3128 tmpbuf[10] = 0x00;
3129 tmpbuf[11] = 0x04;
3130 } else {
3131 /* Go-to-Sleep event by Inactivity for more than 4s */
3132 tmpbuf[8] = 0xB0;
3133 tmpbuf[9] = 0xB0;
3134 tmpbuf[10] = 0x00;
3135 tmpbuf[11] = 0x02;
3136 }
3137 break;
3138 default:
3139 tmpbuf[8] = 0x00;
3140 tmpbuf[9] = 0x00;
3141 tmpbuf[10] = 0x00;
3142 tmpbuf[11] = 0x00;
3143 break;
3144 }
3145
3146 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
3147
3148 blf_init_rec(params, flags, object_timestamp, WTAP_ENCAP_LIN107, linevent.channel, UINT16_MAX(65535), sizeof(tmpbuf), sizeof(tmpbuf));
3149
3150 return true1;
3151}
3152
3153static bool_Bool
3154blf_parse_xml_port(const xmlChar* str, char** name, uint16_t* hwchannel, bool_Bool* simulated) {
3155 static const char name_magic[] = "name=";
3156 static const char hwchannel_magic[] = "hwchannel=";
3157 static const char simulated_magic[] = "simulated=";
3158
3159 if (str == NULL((void*)0)) return false0;
3160
3161 char** tokens = g_strsplit_set((const char*)str, ";", -1);
3162 if (tokens == NULL((void*)0)) {
3163 ws_debug("cannot split XML port data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3163, __func__, "cannot split XML port data"); } } while (0
)
;
3164 return false0;
3165 }
3166
3167 for (int i = 0; tokens[i] != NULL((void*)0); i++) {
3168 const char* token = tokens[i];
3169 if (name && strncmp(token, name_magic, strlen(name_magic)) == 0) {
3170 if (*name == NULL((void*)0)) { /* Avoid memory leak in case of repeated names */
3171 *name = ws_strdup(token + strlen(name_magic))wmem_strdup(((void*)0), token + strlen(name_magic));
3172 }
3173 } else if (hwchannel && strncmp(token, hwchannel_magic, strlen(hwchannel_magic)) == 0) {
3174 if (!ws_strtou16(token + strlen(hwchannel_magic), NULL((void*)0), hwchannel)) {
3175 *hwchannel = UINT16_MAX(65535);
3176 }
3177 } else if (simulated && strncmp(token, simulated_magic, strlen(simulated_magic)) == 0) {
3178 if (strlen(token) > strlen(simulated_magic) && token[strlen(simulated_magic)] != '0') {
3179 *simulated = true1; /* TODO: Find a way to use this information */
3180 }
3181 }
3182 }
3183
3184 g_strfreev(tokens);
3185
3186 return true1;
3187}
3188
3189static int
3190blf_get_xml_pkt_encap(const xmlChar* str) {
3191 if (str == NULL((void*)0)) return 0;
3192
3193 if (xmlStrcmp(str, (const xmlChar*)"CAN") == 0) {
3194 return WTAP_ENCAP_SOCKETCAN125;
3195 }
3196 if (xmlStrcmp(str, (const xmlChar*)"FlexRay") == 0) {
3197 return WTAP_ENCAP_FLEXRAY106;
3198 }
3199 if (xmlStrcmp(str, (const xmlChar*)"LIN") == 0) {
3200 return WTAP_ENCAP_LIN107;
3201 }
3202 if (xmlStrcmp(str, (const xmlChar*)"Ethernet") == 0) {
3203 return WTAP_ENCAP_ETHERNET1;
3204 }
3205 if (xmlStrcmp(str, (const xmlChar*)"WLAN") == 0) { /* Not confirmed with a real capture */
3206 return WTAP_ENCAP_IEEE_802_1120;
3207 }
3208
3209 return WTAP_ENCAP_UNKNOWN0;
3210}
3211
3212
3213/** Extracts the channel and port names from a channels XML.
3214 *
3215 * A sample channels XML looks like this:
3216 *
3217 * <?xml version="1.0" encoding="UTF-8"?>
3218 * <channels version="1">
3219 * <channel number="1" type="CAN" network="CAN01">
3220 * <databases>
3221 * <database file="DB.arxml" path="C:\...\" cluster="CAN01" />
3222 * <database file="DB.dbc" path="C:\...\" cluster="General" />
3223 * </databases>
3224 * </channel>
3225 * <channel number="1" type="LIN" network="LIN01">
3226 * <databases>
3227 * <database file="DB.dbc" path="C:\...\" cluster="General" />
3228 * <database file="DB.ldf" path="C:\...\" cluster="LIN01" />
3229 * </databases>
3230 * </channel>
3231 * <channel number="1" type="Ethernet" network="ETH01">
3232 * <databases>
3233 * <database file="DB.dbc" path="C:\...\" cluster="General" />
3234 * </databases>
3235 * <channel_properties>
3236 * <elist name="ports">
3237 * <eli name="port">name=Port1;hwchannel=11;simulated=1</eli>
3238 * <eli name="port">name=Port2;hwchannel=12;simulated=0</eli>
3239 * </elist>
3240 * </channel_properties>
3241 * </channel>
3242 * </channels>
3243 */
3244static bool_Bool
3245blf_set_xml_channels(blf_params_t* params, const char* text, size_t len) {
3246 xmlDocPtr doc;
3247 xmlNodePtr root_element = NULL((void*)0);
3248 xmlNodePtr channels = NULL((void*)0);
3249
3250 if (text == NULL((void*)0)) return false0;
3251
3252 /* Now it can be parsed into a proper structure */
3253 doc = xmlParseMemory(text, (int)len);
3254 if (doc == NULL((void*)0)) {
3255 ws_debug("invalid xml found")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3255, __func__, "invalid xml found"); } } while (0)
;
3256 return false0;
3257 }
3258
3259 root_element = xmlDocGetRootElement(doc);
3260 if (root_element == NULL((void*)0)) {
3261 ws_debug("empty xml doc")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3261, __func__, "empty xml doc"); } } while (0)
;
3262 xmlFreeDoc(doc);
3263 return false0;
3264 }
3265
3266 if (xmlStrcmp(root_element->name, (const xmlChar*)"channels") == 0) {
3267 channels = root_element;
3268 } else {
3269 for (xmlNodePtr cur = root_element->children; cur != NULL((void*)0); cur = cur->next) {
3270 if (cur->type == XML_ELEMENT_NODE && xmlStrcmp(cur->name, (const xmlChar*)"channels") == 0) {
3271 channels = cur;
3272 break;
3273 }
3274 }
3275 }
3276
3277 if (channels == NULL((void*)0)) {
3278 ws_debug("No channels found")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3278, __func__, "No channels found"); } } while (0)
;
3279 xmlFreeDoc(doc);
3280 return false0;
3281 }
3282
3283 for (xmlNodePtr current_channel_node = channels->children; current_channel_node != NULL((void*)0); current_channel_node = current_channel_node->next) {
3284 if ((current_channel_node->type == XML_ELEMENT_NODE) && (xmlStrcmp(current_channel_node->name, (const xmlChar*)"channel") == 0)) {
3285 /* Reset the found attributes */
3286 int pkt_encap = WTAP_ENCAP_UNKNOWN0;
3287 uint16_t channel = UINT16_MAX(65535);
3288 char* channel_name = NULL((void*)0);
3289
3290 for (xmlAttrPtr attr = current_channel_node->properties; attr; attr = attr->next) {
3291 if (xmlStrcmp(attr->name, (const xmlChar*)"number") == 0) {
3292 xmlChar* str_channel = xmlNodeListGetString(current_channel_node->doc, attr->children, 1);
3293 if (str_channel != NULL((void*)0)) {
3294 ws_strtou16((const char*)str_channel, NULL((void*)0), &channel);
3295 xmlFree(str_channel);
3296 }
3297 } else if (xmlStrcmp(attr->name, (const xmlChar*)"type") == 0) {
3298 xmlChar* str_type = xmlNodeListGetString(current_channel_node->doc, attr->children, 1);
3299 if (str_type != NULL((void*)0)) {
3300 pkt_encap = blf_get_xml_pkt_encap(str_type);
3301 xmlFree(str_type);
3302 }
3303 } else if (xmlStrcmp(attr->name, (const xmlChar*)"network") == 0) {
3304 xmlChar* str_network = xmlNodeListGetString(current_channel_node->doc, attr->children, 1);
3305 if (str_network != NULL((void*)0)) {
3306 if (channel_name == NULL((void*)0)) {
3307 channel_name = ws_strdup((const char*)str_network)wmem_strdup(((void*)0), (const char*)str_network);
3308 }
3309 xmlFree(str_network);
3310 }
3311 }
3312 }
3313
3314 if (pkt_encap != WTAP_ENCAP_UNKNOWN0 && channel != UINT16_MAX(65535) && channel_name != NULL((void*)0)) {
3315 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"
, 3315, __func__, "Found channel in XML: PKT_ENCAP: %d, ID: %u, name: %s"
, pkt_encap, channel, channel_name); } } while (0)
;
3316 blf_prepare_interface_name(params, pkt_encap, channel, UINT16_MAX(65535), channel_name, true1);
3317
3318 /* Look for ports under the channel properties */
3319 for (xmlNodePtr channel_property = current_channel_node->children; channel_property != NULL((void*)0); channel_property = channel_property->next) {
3320 if ((channel_property->type == XML_ELEMENT_NODE) && (xmlStrcmp(channel_property->name, (const xmlChar*)"channel_properties") == 0)) {
3321 for (xmlNodePtr prop_child = channel_property->children; prop_child != NULL((void*)0); prop_child = prop_child->next) {
3322 if (prop_child->type == XML_ELEMENT_NODE && xmlStrcmp(prop_child->name, (const xmlChar*)"elist") == 0) {
3323 xmlNodePtr elist_node = prop_child;
3324 xmlChar* str_name = xmlGetProp(elist_node, (const xmlChar*)"name");
3325 if (xmlStrcmp(str_name, (const xmlChar*)"ports") == 0) {
3326 for (xmlNodePtr eli_node = elist_node->children; eli_node != NULL((void*)0); eli_node = eli_node->next) {
3327 if (eli_node->type == XML_ELEMENT_NODE && xmlStrcmp(eli_node->name, (const xmlChar*)"eli") == 0) {
3328 xmlChar* eli_name_attr = xmlGetProp(eli_node, (const xmlChar*)"name");
3329 if (xmlStrcmp(eli_name_attr, (const xmlChar*)"port") == 0) {
3330 char* port_name = NULL((void*)0);
3331 uint16_t hwchannel = UINT16_MAX(65535);
3332 bool_Bool simulated = false0;
3333 char* iface_name = NULL((void*)0);
3334 xmlChar* eli_content = xmlNodeGetContent(eli_node);
3335
3336 bool_Bool res = blf_parse_xml_port(eli_content, &port_name, &hwchannel, &simulated);
3337 if (res && port_name != NULL((void*)0) && hwchannel != UINT16_MAX(65535)) {
3338 iface_name = ws_strdup_printf("%s::%s", channel_name, port_name)wmem_strdup_printf(((void*)0), "%s::%s", channel_name, port_name
)
;
3339 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"
, 3339, __func__, "Found channel in XML: PKT_ENCAP: %d, ID: %u, HW ID: %u, name: %s"
, pkt_encap, channel, hwchannel, iface_name); } } while (0)
;
3340 blf_prepare_interface_name(params, pkt_encap, channel, hwchannel, iface_name, true1);
3341 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)
;
3342 } else {
3343 ws_debug("port with missing or malformed info found in xml")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3343, __func__, "port with missing or malformed info found in xml"
); } } while (0)
;
3344 }
3345 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)
;
3346 xmlFree(eli_content);
3347 }
3348 xmlFree(eli_name_attr);
3349 }
3350 }
3351 }
3352 xmlFree(str_name);
3353 }
3354 }
3355 }
3356 }
3357 }
3358 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)
;
3359 }
3360 }
3361
3362 xmlFreeDoc(doc);
3363 return true1;
3364}
3365
3366static int
3367blf_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) {
3368 blf_apptext_t apptextheader;
3369
3370 if (object_length < (data_start - block_start) + (int)sizeof(apptextheader)) {
3371 *err = WTAP_ERR_BAD_FILE-13;
3372 *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"
)
;
3373 ws_debug("not enough bytes for apptext header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3373, __func__, "not enough bytes for apptext header in object"
); } } while (0)
;
3374 return BLF_APPTEXT_FAILED0x000000FF;
3375 }
3376
3377 if (!blf_read_bytes(params, data_start, &apptextheader, sizeof(apptextheader), err, err_info)) {
3378 ws_debug("not enough bytes for apptext header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3378, __func__, "not enough bytes for apptext header in file"
); } } while (0)
;
3379 return BLF_APPTEXT_FAILED0x000000FF;
3380 }
3381 fix_endianness_blf_apptext_header(&apptextheader);
3382
3383 if (metadata_info->valid && apptextheader.source != BLF_APPTEXT_METADATA0x00000002) {
3384 /* If we're in the middle of a sequence of metadata objects,
3385 * but we get an AppText object from another source,
3386 * skip the previously incomplete object and start fresh.
3387 */
3388 metadata_info->valid = false0;
3389 }
3390
3391 /* Add an extra byte for a terminating '\0' */
3392 char* text = g_try_malloc((size_t)apptextheader.textLength + 1);
3393 if (text == NULL((void*)0)) {
3394 ws_debug("cannot allocate memory")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3394, __func__, "cannot allocate memory"); } } while (0)
;
3395 return BLF_APPTEXT_FAILED0x000000FF;
3396 }
3397
3398 if (!blf_read_bytes(params, data_start + sizeof(apptextheader), text, apptextheader.textLength, err, err_info)) {
3399 ws_debug("not enough bytes for apptext text in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3399, __func__, "not enough bytes for apptext text in file"
); } } while (0)
;
3400 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3401 return BLF_APPTEXT_FAILED0x000000FF;
3402 }
3403 text[apptextheader.textLength] = '\0'; /* Here's the '\0' */
3404
3405 switch (apptextheader.source) {
3406 case BLF_APPTEXT_CHANNEL0x00000001:
3407 {
3408
3409 /* returns a NULL terminated array of NULL terminates strings */
3410 char** tokens = g_strsplit_set(text, ";", -1);
3411
3412 if (tokens == NULL((void*)0) || tokens[0] == NULL((void*)0) || tokens[1] == NULL((void*)0)) {
3413 if (tokens != NULL((void*)0)) {
3414 g_strfreev(tokens);
3415 }
3416 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3417 return BLF_APPTEXT_CHANNEL0x00000001;
3418 }
3419
3420 uint16_t channel = (apptextheader.reservedAppText1 >> 8) & 0xff;
3421 int pkt_encap;
3422
3423 switch ((apptextheader.reservedAppText1 >> 16) & 0xff) {
3424 case BLF_BUSTYPE_CAN1:
3425 pkt_encap = WTAP_ENCAP_SOCKETCAN125;
3426 break;
3427
3428 case BLF_BUSTYPE_FLEXRAY7:
3429 pkt_encap = WTAP_ENCAP_FLEXRAY106;
3430 break;
3431
3432 case BLF_BUSTYPE_LIN5:
3433 pkt_encap = WTAP_ENCAP_LIN107;
3434 break;
3435
3436 case BLF_BUSTYPE_ETHERNET11:
3437 pkt_encap = WTAP_ENCAP_ETHERNET1;
3438 break;
3439
3440 case BLF_BUSTYPE_WLAN13:
3441 pkt_encap = WTAP_ENCAP_IEEE_802_1120;
3442 break;
3443
3444 default:
3445 pkt_encap = WTAP_ENCAP_UNKNOWN0;
3446 break;
3447 }
3448
3449 if (pkt_encap != WTAP_ENCAP_UNKNOWN0) {
3450 /* we use lookup to create interface, if not existing yet */
3451 blf_prepare_interface_name(params, pkt_encap, channel, UINT16_MAX(65535), tokens[1], false0);
3452 }
3453
3454 g_strfreev(tokens);
3455 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3456 return BLF_APPTEXT_CHANNEL0x00000001;
3457 }
3458 case BLF_APPTEXT_METADATA0x00000002:
3459 if (metadata_info->valid) {
3460 /* Set the buffer pointer to the end of the previous object */
3461 params->rec->data.first_free = metadata_info->metadata_cont;
3462 } else {
3463 /* First object of a sequence of one or more */
3464 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_DISSECTOR_NAME12, BLF_APPTEXT_TAG_DISS_DEFAULT"data-text-lines");
3465 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_PROT_TEXT33, BLF_APPTEXT_COL_PROT_TEXT"BLF App text");
3466 switch (((apptextheader.reservedAppText1 >> 24) & 0xff)) {
3467 case BLF_APPTEXT_XML_GENERAL0x01:
3468 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, BLF_APPTEXT_COL_INFO_TEXT_GENERAL"Metadata: General");
3469 break;
3470
3471 case BLF_APPTEXT_XML_CHANNELS0x02:
3472 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, BLF_APPTEXT_COL_INFO_TEXT_CHANNELS"Metadata: Channels");
3473 break;
3474
3475 case BLF_APPTEXT_XML_IDENTITY0x03:
3476 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, BLF_APPTEXT_COL_INFO_TEXT_IDENTITY"Metadata: Identity");
3477 break;
3478
3479 default:
3480 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, BLF_APPTEXT_COL_INFO_TEXT"Metadata");
3481 }
3482 wtap_buffer_append_epdu_end(&params->rec->data);
3483 metadata_info->payload_start = params->rec->data.first_free;
3484 }
3485
3486 ws_buffer_append(&params->rec->data, (const uint8_t*)text, apptextheader.textLength);
3487 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3488
3489 if ((apptextheader.reservedAppText1 & 0x00ffffff) > apptextheader.textLength) {
3490 /* Continues in the next object */
3491 return BLF_APPTEXT_CONT0x000000FE;
3492 }
3493
3494 if (((apptextheader.reservedAppText1 >> 24) & 0xff) == BLF_APPTEXT_XML_CHANNELS0x02) {
3495 blf_set_xml_channels(params, (const char*)(params->rec->data.data + metadata_info->payload_start), params->rec->data.first_free - metadata_info->payload_start);
3496 }
3497
3498 /* 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. */
3499 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));
3500 return BLF_APPTEXT_METADATA0x00000002;
3501 case BLF_APPTEXT_COMMENT0x00000000:
3502 case BLF_APPTEXT_ATTACHMENT0x00000003:
3503 case BLF_APPTEXT_TRACELINE0x00000004:
3504 {
3505 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_DISSECTOR_NAME12, BLF_APPTEXT_TAG_DISS_DEFAULT"data-text-lines");
3506 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_PROT_TEXT33, BLF_APPTEXT_COL_PROT_TEXT"BLF App text");
3507
3508 char* info_line = NULL((void*)0);
3509 switch (apptextheader.source) {
3510 case BLF_APPTEXT_COMMENT0x00000000:
3511 info_line = ws_strdup_printf("Comment: %s", text)wmem_strdup_printf(((void*)0), "Comment: %s", text);
3512 break;
3513 case BLF_APPTEXT_ATTACHMENT0x00000003:
3514 info_line = ws_strdup_printf("Attachment: %s", text)wmem_strdup_printf(((void*)0), "Attachment: %s", text);
3515 break;
3516 case BLF_APPTEXT_TRACELINE0x00000004:
3517 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)
;
3518 break;
3519 default:
3520 ws_assert_not_reached()ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/blf.c"
, 3520, __func__, "assertion \"not reached\" failed")
;
3521 }
3522
3523 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_COL_INFO_TEXT36, info_line);
3524 wtap_buffer_append_epdu_end(&params->rec->data);
3525
3526 size_t text_length = strlen(text); /* The string can contain '\0' before textLength bytes */
3527 ws_buffer_append(&params->rec->data, (const uint8_t*)text, text_length); /* The dissector doesn't need NULL-terminated strings */
3528
3529 /* We'll write this as a WS UPPER PDU packet with a text blob */
3530 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));
3531 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3532 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)
;
3533 return apptextheader.source;
3534 }
3535 default:
3536 g_free(text)(__builtin_object_size ((text), 0) != ((size_t) - 1)) ? g_free_sized
(text, __builtin_object_size ((text), 0)) : (g_free) (text)
;
3537 return BLF_APPTEXT_CHANNEL0x00000001; /* Cheat - no block to write */;
3538 }
3539 return BLF_APPTEXT_CHANNEL0x00000001; /* Cheat - no block to write */
3540}
3541
3542static bool_Bool
3543blf_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) {
3544 blf_ethernet_status_t ethernet_status_header;
3545 uint8_t tmpbuf[24];
3546 uint64_t linkUpDuration;
3547
3548 if (object_length < (data_start - block_start) + (int)sizeof(ethernet_status_header) + (int)(object_version >= 1 ? 8 : 0)) {
3549 *err = WTAP_ERR_BAD_FILE-13;
3550 *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"
)
;
3551 ws_debug("not enough bytes for ethernet status header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3551, __func__, "not enough bytes for ethernet status header in object"
); } } while (0)
;
3552 return false0;
3553 }
3554
3555 if (!blf_read_bytes(params, data_start, &ethernet_status_header, sizeof(ethernet_status_header), 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
3560 if (object_version >= 1) {
3561 if (!blf_read_bytes(params, data_start + sizeof(ethernet_status_header), &linkUpDuration, 8, err, err_info)) {
3562 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"
, 3562, __func__, "not enough bytes for ethernet_status_header header in file"
); } } while (0)
;
3563 return false0;
3564 }
3565 linkUpDuration = GUINT64_FROM_LE(linkUpDuration)(((guint64) (linkUpDuration)));
3566 }
3567
3568 fix_endianness_blf_ethernet_status_header(&ethernet_status_header);
3569
3570 phtonu16(tmpbuf, ethernet_status_header.channel);
3571 phtonu16(tmpbuf + 2, ethernet_status_header.flags);
3572 tmpbuf[4] = (ethernet_status_header.linkStatus);
3573 tmpbuf[5] = (ethernet_status_header.ethernetPhy);
3574 tmpbuf[6] = (ethernet_status_header.duplex);
3575 tmpbuf[7] = (ethernet_status_header.mdi);
3576 tmpbuf[8] = (ethernet_status_header.connector);
3577 tmpbuf[9] = (ethernet_status_header.clockMode);
3578 tmpbuf[10] = (ethernet_status_header.pairs);
3579 tmpbuf[11] = (ethernet_status_header.hardwareChannel);
3580 phtonu32(tmpbuf + 12, ethernet_status_header.bitrate);
3581
3582 if (object_version >= 1) {
3583 phtonu64(tmpbuf + 16, linkUpDuration);
3584 }
3585
3586 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_DISSECTOR_NAME12, BLF_APPTEXT_TAG_DISS_ETHSTATUS"blf-ethernetstatus-obj");
3587 wtap_buffer_append_epdu_end(&params->rec->data);
3588
3589 ws_buffer_append(&params->rec->data, tmpbuf, (size_t)(object_version >= 1 ? 24 : 16));
3590
3591 /* We'll write this as a WS UPPER PDU packet with a data blob */
3592 /* This will create an interface with the "name" of the matching
3593 * WTAP_ENCAP_ETHERNET interface with the same channel and hardware
3594 * channel prefixed with "STATUS" and with a different interface ID,
3595 * because IDBs in pcapng can only have one linktype.
3596 * The other option would be to write everything as UPPER_PDU, including
3597 * the Ethernet data (with one of the "eth_" dissectors.)
3598 */
3599 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)
;
3600 blf_lookup_interface(params, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, ethernet_status_header.channel, ethernet_status_header.hardwareChannel, iface_name);
3601 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)
;
3602 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));
3603
3604 if ((ethernet_status_header.flags & BLF_ETH_STATUS_HARDWARECHANNEL0x0100) == BLF_ETH_STATUS_HARDWARECHANNEL0x0100) {
3605 /* If HW channel valid */
3606 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_QUEUE6, ethernet_status_header.hardwareChannel);
3607 }
3608
3609 return true1;
3610}
3611
3612static bool_Bool
3613blf_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) {
3614 blf_ethernet_phystate_t ethernet_phystate_header;
3615 uint8_t tmpbuf[8];
3616
3617 if (object_length < (data_start - block_start) + (int)sizeof(ethernet_phystate_header)) {
3618 *err = WTAP_ERR_BAD_FILE-13;
3619 *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"
)
;
3620 ws_debug("not enough bytes for ethernet phystate header in object")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3620, __func__, "not enough bytes for ethernet phystate header in object"
); } } while (0)
;
3621 return false0;
3622 }
3623
3624 if (!blf_read_bytes(params, data_start, &ethernet_phystate_header, sizeof(ethernet_phystate_header), err, err_info)) {
3625 ws_debug("not enough bytes for ethernet phystate header in file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3625, __func__, "not enough bytes for ethernet phystate header in file"
); } } while (0)
;
3626 return false0;
3627 }
3628
3629 fix_endianness_blf_ethernet_phystate_header(&ethernet_phystate_header);
3630
3631 phtonu16(tmpbuf, ethernet_phystate_header.channel);
3632 phtonu16(tmpbuf + 2, ethernet_phystate_header.flags);
3633 tmpbuf[4] = (ethernet_phystate_header.phyState);
3634 tmpbuf[5] = (ethernet_phystate_header.phyEvent);
3635 tmpbuf[6] = (ethernet_phystate_header.hardwareChannel);
3636 tmpbuf[7] = (ethernet_phystate_header.res1);
3637
3638 wtap_buffer_append_epdu_string(&params->rec->data, EXP_PDU_TAG_DISSECTOR_NAME12, BLF_APPTEXT_TAG_DISS_ETHPHYSTATUS"blf-ethernetphystate-obj");
3639 wtap_buffer_append_epdu_end(&params->rec->data);
3640
3641 ws_buffer_append(&params->rec->data, tmpbuf, sizeof(tmpbuf));
3642
3643 /* We'll write this as a WS UPPER PDU packet with a data blob */
3644 /* This will create an interface with the "name" of the matching
3645 * WTAP_ENCAP_ETHERNET interface with the same channel and hardware
3646 * channel prefixed with "STATUS" and with a different interface ID,
3647 * because IDBs in pcapng can only have one linktype.
3648 * The other option would be to write everything as UPPER_PDU, including
3649 * the Ethernet data (with one of the "eth_" dissectors.)
3650 */
3651 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)
;
3652 blf_lookup_interface(params, WTAP_ENCAP_WIRESHARK_UPPER_PDU155, ethernet_phystate_header.channel, ethernet_phystate_header.hardwareChannel, iface_name);
3653 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)
;
3654 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));
3655
3656 if ((ethernet_phystate_header.flags & BLF_PHY_STATE_HARDWARECHANNEL0x0004) == BLF_PHY_STATE_HARDWARECHANNEL0x0004) {
3657 /* If HW channel valid */
3658 wtap_block_add_uint32_option(params->rec->block, OPT_PKT_QUEUE6, ethernet_phystate_header.hardwareChannel);
3659 }
3660
3661 return true1;
3662}
3663
3664static bool_Bool
3665blf_read_block(blf_params_t *params, int64_t start_pos, int *err, char **err_info) {
3666 blf_blockheader_t header;
3667 blf_logobjectheader_t logheader;
3668 blf_logobjectheader2_t logheader2;
3669 blf_logobjectheader3_t logheader3;
3670 uint32_t flags;
3671 uint64_t object_timestamp;
3672 uint16_t object_version;
3673 blf_metadata_info_t metadata_info = { 0, 0, false0 };
3674 int64_t last_metadata_start = 0;
3675
3676 while (1) {
3677 /* Find Object */
3678
3679 /* Resetting buffer */
3680 params->rec->data.first_free = params->rec->data.start;
3681
3682 while (1) {
3683 if (!blf_read_bytes_or_eof(params, start_pos, &header, sizeof header, err, err_info)) {
3684 ws_debug("not enough bytes for block header or unsupported file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3684, __func__, "not enough bytes for block header or unsupported file"
); } } while (0)
;
3685 if (*err == WTAP_ERR_SHORT_READ-12) {
3686 /* we have found the end that is not a short read therefore. */
3687 *err = 0;
3688 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)
;
3689 *err_info = NULL((void*)0);
3690 }
3691 return false0;
3692 }
3693
3694 fix_endianness_blf_blockheader(&header);
3695
3696 if (memcmp(header.magic, blf_obj_magic, sizeof(blf_obj_magic))) {
3697 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"
, 3697, __func__, "object magic is not LOBJ (pos: 0x%" "l" "x"
")", start_pos); } } while (0)
;
3698 } else {
3699 break;
3700 }
3701
3702 /* we are moving back and try again but 1 byte later */
3703 /* TODO: better understand how this paddings works... */
3704 start_pos++;
3705 }
3706 params->blf_data->start_of_last_obj = start_pos;
3707
3708 if (!params->random) {
3709 /* Make sure that we start after this object next time,
3710 * but only if it's a linear read. We can have random reads
3711 * during the linear read, so we have to make sure we don't
3712 * lose track of our position.
3713 */
3714 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)
)
;
3715 }
3716
3717 switch (header.header_type) {
3718 case BLF_HEADER_TYPE_DEFAULT1:
3719 if (!blf_read_log_object_header(params, err, err_info, start_pos + sizeof(blf_blockheader_t), start_pos + header.header_length, &logheader)) {
3720 return false0;
3721 }
3722 flags = logheader.flags;
3723 object_timestamp = logheader.object_timestamp;
3724 object_version = logheader.object_version;
3725 break;
3726
3727 case BLF_HEADER_TYPE_22:
3728 if (!blf_read_log_object_header2(params, err, err_info, start_pos + sizeof(blf_blockheader_t), start_pos + header.header_length, &logheader2)) {
3729 return false0;
3730 }
3731 flags = logheader2.flags;
3732 object_timestamp = logheader2.object_timestamp;
3733 object_version = logheader2.object_version;
3734 break;
3735
3736 case BLF_HEADER_TYPE_33:
3737 if (!blf_read_log_object_header3(params, err, err_info, start_pos + sizeof(blf_blockheader_t), start_pos + header.header_length, &logheader3)) {
3738 return false0;
3739 }
3740 flags = logheader3.flags;
3741 object_timestamp = logheader3.object_timestamp;
3742 object_version = logheader3.object_version;
3743 break;
3744
3745 default:
3746 *err = WTAP_ERR_UNSUPPORTED-4;
3747 *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)
;
3748 ws_debug("unknown header type")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3748, __func__, "unknown header type"); } } while (0)
;
3749 return false0;
3750 }
3751
3752 if (metadata_info.valid && header.object_type != BLF_OBJTYPE_APP_TEXT65) {
3753 /* If we're in the middle of a sequence of AppText metadata objects,
3754 * but we get an AppText object from another source,
3755 * skip the previous incomplete packet and start fresh.
3756 */
3757 metadata_info.valid = false0;
3758 }
3759
3760 switch (header.object_type) {
3761 case BLF_OBJTYPE_LOG_CONTAINER10:
3762 *err = WTAP_ERR_UNSUPPORTED-4;
3763 *err_info = ws_strdup("blf: log container in log container not supported")wmem_strdup(((void*)0), "blf: log container in log container not supported"
)
;
3764 ws_debug("log container in log container not supported")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3764, __func__, "log container in log container not supported"
); } } while (0)
;
3765 return false0;
3766
3767 case BLF_OBJTYPE_ETHERNET_FRAME71:
3768 return blf_read_ethernetframe(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3769
3770 case BLF_OBJTYPE_ETHERNET_FRAME_EX120:
3771 return blf_read_ethernetframe_ext(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3772
3773 case BLF_OBJTYPE_ETHERNET_RX_ERROR102:
3774 return blf_read_ethernet_rxerror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3775
3776 case BLF_OBJTYPE_ETHERNET_ERROR_EX122:
3777 return blf_read_ethernetframe_ext(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3778
3779 case BLF_OBJTYPE_WLAN_FRAME93:
3780 return blf_read_wlanframe(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3781
3782 case BLF_OBJTYPE_CAN_MESSAGE1:
3783 return blf_read_canmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3784
3785 case BLF_OBJTYPE_CAN_ERROR2:
3786 return blf_read_canerror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3787
3788 case BLF_OBJTYPE_CAN_OVERLOAD3:
3789 return blf_read_canerror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3790
3791 case BLF_OBJTYPE_CAN_MESSAGE286:
3792 return blf_read_canmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3793
3794 case BLF_OBJTYPE_CAN_ERROR_EXT73:
3795 return blf_read_canerrorext(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3796
3797 case BLF_OBJTYPE_CAN_FD_MESSAGE100:
3798 return blf_read_canfdmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3799
3800 case BLF_OBJTYPE_CAN_FD_MESSAGE_64101:
3801 return blf_read_canfdmessage64(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3802
3803 case BLF_OBJTYPE_CAN_FD_ERROR_64104:
3804 return blf_read_canfderror64(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3805
3806 case BLF_OBJTYPE_CAN_XL_CHANNEL_FRAME139:
3807 return blf_read_canxlchannelframe(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3808
3809 case BLF_OBJTYPE_FLEXRAY_DATA29:
3810 return blf_read_flexraydata(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3811
3812 case BLF_OBJTYPE_FLEXRAY_MESSAGE41:
3813 return blf_read_flexraymessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3814
3815 case BLF_OBJTYPE_FLEXRAY_RCVMESSAGE50:
3816 return blf_read_flexrayrcvmessageex(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3817
3818 case BLF_OBJTYPE_FLEXRAY_RCVMESSAGE_EX66:
3819 return blf_read_flexrayrcvmessageex(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3820
3821 case BLF_OBJTYPE_LIN_MESSAGE11:
3822 return blf_read_linmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, false0);
3823
3824 case BLF_OBJTYPE_LIN_CRC_ERROR12:
3825 return blf_read_linmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, true1);
3826
3827 case BLF_OBJTYPE_LIN_RCV_ERROR14:
3828 return blf_read_linrcverror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3829
3830 case BLF_OBJTYPE_LIN_SND_ERROR15:
3831 return blf_read_linsenderror(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3832
3833 case BLF_OBJTYPE_LIN_WAKEUP21:
3834 return blf_read_linwakeupevent(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3835
3836 case BLF_OBJTYPE_LIN_MESSAGE257:
3837 return blf_read_linmessage2(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_CRC_ERROR260:
3840 return blf_read_lincrcerror2(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_RCV_ERROR261:
3843 return blf_read_linrcverror2(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, object_version);
3844
3845 case BLF_OBJTYPE_LIN_SND_ERROR258:
3846 return blf_read_linsenderror2(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, object_version);
3847
3848 case BLF_OBJTYPE_LIN_WAKEUP262:
3849 return blf_read_linwakeupevent2(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3850
3851 case BLF_OBJTYPE_LIN_SLEEP20:
3852 return blf_read_linsleepmodeevent(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3853
3854 case BLF_OBJTYPE_APP_TEXT65:
3855 {
3856 int result = blf_read_apptextmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, &metadata_info);
3857 if (result == BLF_APPTEXT_CONT0x000000FE) {
3858 if (!metadata_info.valid) {
3859 /* First object of a sequence, save its start position */
3860 last_metadata_start = start_pos;
3861 metadata_info.valid = true1;
3862 }
3863 /* Save a pointer to the end of the buffer */
3864 metadata_info.metadata_cont = params->rec->data.first_free;
3865 } else {
3866 if (result == BLF_APPTEXT_METADATA0x00000002 && metadata_info.valid) {
3867 /* Last object of a sequence, restore the start position of the first object */
3868 params->blf_data->start_of_last_obj = last_metadata_start;
3869 }
3870 /* Reset everything and start fresh */
3871 metadata_info.valid = false0;
3872 }
3873 switch (result) {
3874 case BLF_APPTEXT_FAILED0x000000FF:
3875 return false0;
3876 case BLF_APPTEXT_COMMENT0x00000000:
3877 case BLF_APPTEXT_METADATA0x00000002:
3878 case BLF_APPTEXT_ATTACHMENT0x00000003:
3879 case BLF_APPTEXT_TRACELINE0x00000004:
3880 return true1;
3881 case BLF_APPTEXT_CHANNEL0x00000001:
3882 case BLF_APPTEXT_CONT0x000000FE:
3883 default:
3884 /* we do not return since there is no packet to show here */
3885 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)
)
;
3886 break;
3887 }
3888 }
3889 break;
3890
3891 case BLF_OBJTYPE_ETHERNET_STATUS103:
3892 return blf_read_ethernet_status(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp, object_version);
3893
3894 case BLF_OBJTYPE_ETHERNET_PHY_STATE133:
3895 return blf_read_ethernet_phystate(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, flags, object_timestamp);
3896
3897 case BLF_OBJTYPE_ENV_INTEGER6:
3898 case BLF_OBJTYPE_ENV_DOUBLE7:
3899 case BLF_OBJTYPE_ENV_STRING8:
3900 case BLF_OBJTYPE_ENV_DATA9:
3901 case BLF_OBJTYPE_SYS_VARIABLE72:
3902 case BLF_OBJTYPE_RESERVED5115: /* Despite the name, this is actually used. Maybe it's worth investigating the content. */
3903 case BLF_OBJTYPE_TEST_STRUCTURE118:
3904 ws_debug("skipping unsupported object type 0x%04x", header.object_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3904, __func__, "skipping unsupported object type 0x%04x", header
.object_type); } } while (0)
;
3905 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)
)
;
3906 break;
3907 default:
3908 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)
;
3909 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)
)
;
3910 break;
3911 }
3912 }
3913 return true1;
3914}
3915
3916static bool_Bool blf_read(wtap *wth, wtap_rec *rec, int *err, char **err_info, int64_t *data_offset) {
3917 blf_params_t blf_tmp;
3918
3919 blf_tmp.wth = wth;
3920 blf_tmp.fh = wth->fh;
3921 blf_tmp.random = false0;
3922 blf_tmp.pipe = wth->ispipe;
3923 blf_tmp.rec = rec;
3924 blf_tmp.blf_data = (blf_t *)wth->priv;
3925
3926 if (!blf_read_block(&blf_tmp, blf_tmp.blf_data->current_real_seek_pos, err, err_info)) {
3927 return false0;
3928 }
3929 *data_offset = blf_tmp.blf_data->start_of_last_obj;
3930
3931 return true1;
3932}
3933
3934static bool_Bool blf_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec, int *err, char **err_info) {
3935 blf_params_t blf_tmp;
3936
3937 blf_tmp.wth = wth;
3938 blf_tmp.fh = wth->random_fh;
3939 blf_tmp.random = true1;
3940 blf_tmp.pipe = wth->ispipe;
3941 blf_tmp.rec = rec;
3942 blf_tmp.blf_data = (blf_t *)wth->priv;
3943
3944 if (!blf_read_block(&blf_tmp, seek_off, err, err_info)) {
3945 ws_debug("couldn't read packet block (err=%d).", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3945, __func__, "couldn't read packet block (err=%d).", *err
); } } while (0)
;
3946 return false0;
3947 }
3948
3949 return true1;
3950}
3951
3952static void blf_free(blf_t *blf) {
3953 if (blf != NULL((void*)0)) {
3954 if (blf->log_containers != NULL((void*)0)) {
3955 for (unsigned i = 0; i < blf->log_containers->len; i++) {
3956 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)])
;
3957 if (log_container->real_data != NULL((void*)0)) {
3958 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)
;
3959 }
3960 }
3961 g_array_free(blf->log_containers, true1);
3962 blf->log_containers = NULL((void*)0);
3963 }
3964 if (blf->channel_to_iface_ht != NULL((void*)0)) {
3965 g_hash_table_destroy(blf->channel_to_iface_ht);
3966 blf->channel_to_iface_ht = NULL((void*)0);
3967 }
3968 if (blf->channel_to_name_ht != NULL((void*)0)) {
3969 g_hash_table_destroy(blf->channel_to_name_ht);
3970 blf->channel_to_name_ht = NULL((void*)0);
3971 }
3972 }
3973}
3974
3975static void blf_close(wtap *wth) {
3976 blf_free((blf_t *)wth->priv);
3977
3978 /* TODO: do we need to reverse the wtap_add_idb? how? */
3979}
3980
3981wtap_open_return_val
3982blf_open(wtap *wth, int *err, char **err_info) {
3983 blf_fileheader_t header;
3984 blf_t *blf;
3985
3986 ws_debug("opening file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3986, __func__, "opening file"); } } while (0)
;
3987
3988 if (!wtap_read_bytes_or_eof(wth->fh, &header, sizeof(blf_fileheader_t), err, err_info)) {
3989
3990 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 3990, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
3991 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12) {
3992 /*
3993 * Short read or EOF.
3994 *
3995 * We're reading this as part of an open, so
3996 * the file is too short to be a blf file.
3997 */
3998 *err = 0;
3999 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)
;
4000 *err_info = NULL((void*)0);
4001 return WTAP_OPEN_NOT_MINE;
4002 }
4003 return WTAP_OPEN_ERROR;
4004 }
4005
4006 fix_endianness_blf_fileheader(&header);
4007
4008 if (memcmp(header.magic, blf_magic, sizeof(blf_magic))) {
4009 return WTAP_OPEN_NOT_MINE;
4010 }
4011
4012 /* This seems to be an BLF! */
4013 /* Check for a valid header length */
4014 if (header.header_length < sizeof(blf_fileheader_t)) {
4015 *err = WTAP_ERR_BAD_FILE-13;
4016 *err_info = ws_strdup("blf: file header length too short")wmem_strdup(((void*)0), "blf: file header length too short");
4017 return WTAP_OPEN_ERROR;
4018 }
4019
4020 /* skip past the header, which may include padding/reserved space */
4021 if (!wtap_read_bytes(wth->fh, NULL((void*)0), header.header_length - sizeof(blf_fileheader_t), err, err_info)) {
4022 return WTAP_OPEN_ERROR;
4023 }
4024
4025 /* Prepare our private context. */
4026 blf = g_new(blf_t, 1)((blf_t *) g_malloc_n ((1), sizeof (blf_t)));
4027 blf->log_containers = g_array_new(FALSE(0), FALSE(0), sizeof(blf_log_container_t));
4028 blf->current_real_seek_pos = 0;
4029 blf->start_offset_ns = blf_data_to_ns(&header.start_date);
4030 blf->end_offset_ns = blf_data_to_ns(&header.end_date);
4031
4032 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);
4033 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);
4034 blf->next_interface_id = 0;
4035
4036 wth->priv = (void *)blf;
4037 wth->file_encap = WTAP_ENCAP_NONE-2;
4038 wth->snapshot_length = 0;
4039 wth->file_tsprec = WTAP_TSPREC_UNKNOWN-2;
4040 wth->file_start_ts.secs = blf->start_offset_ns / (1000 * 1000 * 1000);
4041 wth->file_start_ts.nsecs = blf->start_offset_ns % (1000 * 1000 * 1000);
4042 wth->file_end_ts.secs = blf->end_offset_ns / (1000 * 1000 * 1000);
4043 wth->file_end_ts.nsecs = blf->end_offset_ns % (1000 * 1000 * 1000);
4044 wth->subtype_read = blf_read;
4045 wth->subtype_seek_read = blf_seek_read;
4046 wth->subtype_close = blf_close;
4047 wth->file_type_subtype = blf_file_type_subtype;
4048
4049 wtap_block_t block = wtap_block_create(WTAP_BLOCK_SECTION);
4050 wtapng_section_mandatory_t *shb_mand = (wtapng_section_mandatory_t *)wtap_block_get_mandatory_data(block);
4051 shb_mand->section_length = UINT64_MAX(18446744073709551615UL);
4052
4053 wtap_block_add_string_option_format(block, OPT_SHB_USERAPPL4, "%s %d.%d.%d", try_val_to_str(header.application, blf_application_names),
4054 header.application_major, header.application_minor, header.application_build);
4055 wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (wth->shb_hdrs)->data) [(0)]
)
, block);
4056 wtap_block_unref(block);
4057
4058 return WTAP_OPEN_MINE;
4059}
4060
4061/* Options for interface blocks. */
4062static const struct supported_option_type interface_block_options_supported[] = {
4063 /* No comments, just an interface name. */
4064 { OPT_IDB_NAME2, ONE_OPTION_SUPPORTED }
4065};
4066
4067static const struct supported_block_type blf_blocks_supported[] = {
4068 { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED0, ((void*)0) },
4069 { 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
},
4070};
4071
4072
4073/***********************/
4074/* BLF Writing Support */
4075/***********************/
4076
4077/* 10MB = 10485760 */
4078#define LOG_CONTAINER_BUFFER_SIZE10485760 10485760
4079
4080#define LOG_CONTAINER_NONE(18446744073709551615UL) UINT64_MAX(18446744073709551615UL)
4081
4082typedef struct _blf_writer_data {
4083 GArray *iface_to_channel_array;
4084 bool_Bool iface_to_channel_names_recovered;
4085
4086 blf_fileheader_t *fileheader;
4087 uint32_t object_count;
4088 uint64_t start_time;
4089 uint64_t end_time;
4090
4091 uint64_t logcontainer_start;
4092 blf_blockheader_t logcontainer_block_header;
4093 blf_logcontainerheader_t logcontainer_header;
4094
4095 /* Last object header, file position and content tracked
4096 in case padding is needed at end of log container*/
4097 uint64_t logobject_start;
4098 blf_blockheader_t logobject_block_header;
4099} blf_writer_data_t;
4100
4101static void
4102blf_dump_free(wtap_dumper *wdh)
4103{
4104 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4105
4106 g_array_unref(writer_data->iface_to_channel_array);
4107 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)
;
4108}
4109
4110static void
4111blf_dump_init_channel_to_iface_entry(blf_channel_to_iface_entry_t* tmp, unsigned int if_id) {
4112 tmp->channel = 0;
4113 tmp->hwchannel = UINT16_MAX(65535);
4114 tmp->interface_id = if_id;
4115 tmp->pkt_encap = WTAP_ENCAP_NONE-2;
4116}
4117
4118static void
4119blf_dump_expand_interface_mapping(wtap_dumper *wdh, unsigned new_size) {
4120 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4121
4122 unsigned old_size = writer_data->iface_to_channel_array->len;
4123
4124 if (old_size < new_size) {
4125 /* we need to expand array */
4126 g_array_set_size(writer_data->iface_to_channel_array, new_size);
4127
4128 for (unsigned int i = old_size; i < writer_data->iface_to_channel_array->len; i++) {
4129 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)])
;
4130 blf_dump_init_channel_to_iface_entry(tmp, i);
4131 }
4132 }
4133}
4134
4135static bool_Bool
4136blf_dump_set_interface_mapping(wtap_dumper *wdh, uint32_t interface_id, int pkt_encap, uint16_t channel, uint16_t hw_channel) {
4137 if (channel == 0) {
4138 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"
, 4138, __func__, "Trying to set channel to 0. That will probably lead to an unreadable file. Replacing by 1 to limit problem."
); } } while (0)
;
4139 channel = 1;
4140 }
4141
4142 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4143
4144 /*
4145 * XXX - will this ever happen add new mappings?
4146 *
4147 * We expand the interface mapping to include all known interfaces
4148 * at the time we open the dump file for writing and every time
4149 * we get notified of a new IDB.
4150 *
4151 * Does that miss any cases?
4152 */
4153 blf_dump_expand_interface_mapping(wdh, interface_id + 1);
4154
4155 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)])
;
4156 tmp->channel = channel;
4157 tmp->hwchannel = hw_channel;
4158 tmp->interface_id = interface_id;
4159 tmp->pkt_encap = pkt_encap;
4160
4161 return true1;
4162}
4163
4164static blf_channel_to_iface_entry_t *
4165blf_dump_get_interface_mapping(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info) {
4166 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4167
4168 uint32_t interface_id = rec->rec_header.packet_header.interface_id;
4169 if (interface_id < writer_data->iface_to_channel_array->len) {
4170 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)])
;
4171 }
4172
4173 *err = WTAP_ERR_INTERNAL-21;
4174 *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)
;
4175 ws_critical("BLF Interface Mapping cannot be found.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_CRITICAL, "wiretap/blf.c"
, 4175, __func__, "BLF Interface Mapping cannot be found."); }
} while (0)
;
4176
4177 return NULL((void*)0);
4178}
4179
4180static bool_Bool
4181blf_init_file_header(wtap_dumper *wdh, int *err) {
4182 if (wdh == NULL((void*)0) || wdh->priv == NULL((void*)0)) {
4183 *err = WTAP_ERR_INTERNAL-21;
4184 ws_debug("internal error: blf private data not found.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4184, __func__, "internal error: blf private data not found."
); } } while (0)
;
4185 return false0;
4186 }
4187
4188 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4189
4190 /* currently only support 144 byte length*/
4191 writer_data->fileheader = (blf_fileheader_t*)g_malloc0(144);
4192
4193 /* set magic */
4194 int i;
4195 for (i = 0; i < 4; i++) {
4196 writer_data->fileheader->magic[i] = blf_magic[i];
4197 }
4198
4199 /* currently only support 144 byte length*/
4200 writer_data->fileheader->header_length = 144;
4201
4202 writer_data->fileheader->application_major = WIRESHARK_VERSION_MAJOR5;
4203 writer_data->fileheader->application_minor = WIRESHARK_VERSION_MINOR1;
4204 writer_data->fileheader->application_build = WIRESHARK_VERSION_MICRO0;
4205
4206 return true1;
4207}
4208
4209static bool_Bool
4210blf_write_add_padding(wtap_dumper *wdh, int *err, uint8_t count) {
4211 if (count > 0 && count < 4) {
4212 uint8_t padding[3] = { 0 };
4213 if (!wtap_dump_file_write(wdh, &padding, count, err)) {
4214 return false0;
4215 }
4216 }
4217 return true1;
4218}
4219
4220static bool_Bool
4221blf_write_file_header_zeros(wtap_dumper *wdh, int *err) {
4222 /* lets add 144 bytes for the header and padding */
4223 uint8_t padding[144] = { 0 };
4224 if (!wtap_dump_file_write(wdh, &padding, 144, err)) {
4225 return false0;
4226 }
4227
4228 return true1;
4229}
4230
4231static void
4232blf_write_date_to_blf_header(blf_fileheader_t *fileheader, bool_Bool start, uint64_t ns_timestamp) {
4233 struct tm tmp;
4234 const time_t date = (time_t)(ns_timestamp / (1000 * 1000 * 1000));
4235
4236 if (ws_localtime_r(&date, &tmp) != NULL((void*)0)) {
4237 blf_date_t *target = start ? &(fileheader->start_date) : &(fileheader->end_date);
4238 target->year = 1900 + tmp.tm_year;
4239 target->month = tmp.tm_mon + 1;
4240 target->day = tmp.tm_mday;
4241 target->hour = tmp.tm_hour;
4242 target->mins = tmp.tm_min;
4243 target->sec = tmp.tm_sec;
4244
4245 uint64_t tmp_date = blf_data_to_ns((const blf_date_t *)target);
4246
4247 target->ms = (uint16_t)((ns_timestamp - tmp_date) / (1000 * 1000));
4248 }
4249
4250}
4251
4252static bool_Bool
4253blf_finalize_file_header(wtap_dumper *wdh, int *err) {
4254 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4255 blf_fileheader_t *fileheader = writer_data->fileheader;
4256 int64_t bytes_written = wtap_dump_file_tell(wdh, err);
4257 if (bytes_written == -1 || *err != 0) {
4258 return false0;
4259 }
4260
4261 /* update the header and convert all to LE */
4262 fileheader->api_version = (((WIRESHARK_VERSION_MAJOR5 * 100) + WIRESHARK_VERSION_MINOR1) * 100 + WIRESHARK_VERSION_MICRO0) * 100;
4263 fileheader->application_major = WIRESHARK_VERSION_MAJOR5;
4264 fileheader->application_minor = WIRESHARK_VERSION_MINOR1;
4265 fileheader->application_build = WIRESHARK_VERSION_MICRO0;
4266
4267 fileheader->len_compressed = (uint64_t)bytes_written;
4268 fileheader->len_uncompressed = (uint64_t)bytes_written;
4269
4270 fileheader->obj_count = writer_data->object_count;
4271
4272 blf_write_date_to_blf_header(fileheader, true1, writer_data->start_time);
4273 blf_write_date_to_blf_header(fileheader, false0, writer_data->end_time);
4274
4275 fix_endianness_blf_fileheader(fileheader);
4276
4277 /* seek to start of file */
4278 int64_t tmp = wtap_dump_file_seek(wdh, 0, SEEK_SET0, err);
4279 if (*err != 0 || tmp != 0) {
4280 return false0;
4281 }
4282
4283 if (!wtap_dump_file_write(wdh, fileheader, fileheader->header_length, err)) {
4284 return false0;
4285 }
4286
4287 return true1;
4288}
4289
4290static bool_Bool blf_dump_write_logcontainer(wtap_dumper *wdh, int *err, char **err_info _U___attribute__((unused))) {
4291 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4292
4293 if (!wtap_dump_file_write(wdh, &(writer_data->logcontainer_block_header), sizeof(blf_blockheader_t), err)) {
4294 ws_debug("Cannot write Log Container Block Header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4294, __func__, "Cannot write Log Container Block Header");
} } while (0)
;
4295 return false0;
4296 }
4297
4298 if (!wtap_dump_file_write(wdh, &(writer_data->logcontainer_header), sizeof(blf_logcontainerheader_t), err)) {
4299 ws_debug("Cannot write Log Container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4299, __func__, "Cannot write Log Container"); } } while (0
)
;
4300 return false0;
4301 }
4302
4303 return true1;
4304}
4305
4306static bool_Bool blf_dump_pad_last_object(wtap_dumper *wdh, int *err, uint8_t padding_count) {
4307 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4308
4309 int64_t current_position = wtap_dump_file_tell(wdh, err);
4310 if (current_position == -1 || *err != 0) {
4311 return false0;
4312 }
4313
4314 if(!blf_write_add_padding(wdh, err, padding_count)) {
4315 return false0;
4316 }
4317 current_position += padding_count;
4318 writer_data->logobject_block_header.object_length += padding_count;
4319
4320 /* Copy out blockheader before fixing endianness */
4321 blf_blockheader_t blockheader = writer_data->logobject_block_header;
4322 fix_endianness_blf_blockheader(&blockheader);
4323
4324 int64_t tmp = wtap_dump_file_seek(wdh, writer_data->logobject_start, SEEK_SET0, err);
4325 if (*err != 0 || tmp != 0) {
4326 return false0;
4327 }
4328
4329 if (!wtap_dump_file_write(wdh, &(blockheader), sizeof(blf_blockheader_t), err)) {
4330 return false0;
4331 }
4332
4333 tmp = wtap_dump_file_seek(wdh, current_position, SEEK_SET0, err);
4334 if (*err != 0 || tmp != 0) {
4335 return false0;
4336 }
4337
4338 return true1;
4339}
4340
4341static bool_Bool blf_dump_close_logcontainer(wtap_dumper *wdh, int *err, char **err_info) {
4342 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4343
4344 int64_t current_position = wtap_dump_file_tell(wdh, err);
4345 if (current_position == -1 || *err != 0) {
4346 return false0;
4347 }
4348 int64_t logcontainer_length = current_position - writer_data->logcontainer_start;
4349 if (logcontainer_length < 32) {
4350 *err = WTAP_ERR_INTERNAL-21;
4351 }
4352
4353 /* Add padding to last object, to ensure logcontainer ends at 4 byte alignment.
4354 Improves compatibility with other tools. */
4355 uint8_t padding_needed = logcontainer_length % 4;
4356 if (padding_needed != 0) {
4357 padding_needed = 4 - padding_needed;
4358 if (!blf_dump_pad_last_object(wdh, err, padding_needed)) {
4359 return false0;
4360 }
4361 logcontainer_length += padding_needed;
4362 current_position += padding_needed;
4363 }
4364
4365 int64_t tmp = wtap_dump_file_seek(wdh, writer_data->logcontainer_start, SEEK_SET0, err);
4366 if (*err != 0 || tmp != 0) {
4367 return false0;
4368 }
4369
4370 writer_data->logcontainer_block_header.object_length = GUINT32_TO_LE((uint32_t)logcontainer_length)((guint32) ((uint32_t)logcontainer_length));
4371 writer_data->logcontainer_header.uncompressed_size = GUINT32_TO_LE((uint32_t)(logcontainer_length - 32))((guint32) ((uint32_t)(logcontainer_length - 32)));
4372
4373 if (!blf_dump_write_logcontainer(wdh, err, err_info)) {
4374 return false0;
4375 }
4376
4377 tmp = wtap_dump_file_seek(wdh, current_position, SEEK_SET0, err);
4378 if (*err != 0 || tmp != 0) {
4379 return false0;
4380 }
4381
4382 return true1;
4383}
4384
4385static bool_Bool blf_dump_start_logcontainer(wtap_dumper *wdh, int *err, char **err_info) {
4386 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4387
4388 if (writer_data->logcontainer_start != LOG_CONTAINER_NONE(18446744073709551615UL)) {
4389 if (!blf_dump_close_logcontainer(wdh, err, err_info)) {
4390 return false0;
4391 }
4392 }
4393
4394 /* start new log container */
4395 /* set magic */
4396 int i;
4397 for (i = 0; i < 4; i++) {
4398 writer_data->logcontainer_block_header.magic[i] = blf_obj_magic[i];
4399 }
4400 writer_data->logcontainer_block_header.header_length = 16;
4401 writer_data->logcontainer_block_header.header_type = 1;
4402 writer_data->logcontainer_block_header.object_length = 32;
4403 writer_data->logcontainer_block_header.object_type = BLF_OBJTYPE_LOG_CONTAINER10;
4404 fix_endianness_blf_blockheader(&(writer_data->logcontainer_block_header));
4405
4406 writer_data->logcontainer_header.compression_method = 0;
4407 writer_data->logcontainer_header.res1 = 0;
4408 writer_data->logcontainer_header.res2 = 0;
4409 writer_data->logcontainer_header.uncompressed_size = 0;
4410 writer_data->logcontainer_header.res4 = 0;
4411 fix_endianness_blf_logcontainerheader(&(writer_data->logcontainer_header));
4412
4413 writer_data->logcontainer_start = wtap_dump_file_tell(wdh, err);
4414 if (*err != 0) {
4415 return false0;
4416 }
4417
4418 return blf_dump_write_logcontainer(wdh, err, err_info);
4419}
4420
4421static bool_Bool blf_dump_check_logcontainer_full(wtap_dumper *wdh, int *err, char **err_info, uint32_t length) {
4422 const blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4423
4424 uint64_t position = (uint64_t)wtap_dump_file_tell(wdh, err);
4425 if (*err != 0) {
4426 return false0;
4427 }
4428 if (position - writer_data->logcontainer_start + length <= LOG_CONTAINER_BUFFER_SIZE10485760) {
4429 return true1;
4430 }
4431
4432 return blf_dump_start_logcontainer(wdh, err, err_info);
4433}
4434
4435static bool_Bool blf_dump_objheader(wtap_dumper *wdh, int *err, uint64_t obj_timestamp, uint32_t obj_type, uint32_t obj_length) {
4436 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4437 blf_logobjectheader_t logheader;
4438 logheader.flags = BLF_TIMESTAMP_RESOLUTION_1NS2;
4439 logheader.client_index = 0;
4440 logheader.object_version = 1;
4441 logheader.object_timestamp = obj_timestamp;
4442 fix_endianness_blf_logobjectheader(&logheader);
4443
4444 blf_blockheader_t blockheader;
4445 /* set magic */
4446 int i;
4447 for (i = 0; i < 4; i++) {
4448 blockheader.magic[i] = blf_obj_magic[i];
4449 }
4450 blockheader.header_length = sizeof(blf_blockheader_t) + sizeof(blf_logobjectheader_t);
4451 blockheader.header_type = 1;
4452 blockheader.object_length = sizeof(blf_blockheader_t) + sizeof(blf_logobjectheader_t) + obj_length;
4453 blockheader.object_type = obj_type;
4454
4455 /* Track blockheader of object, in case padding is needed at end of log container */
4456 writer_data->logobject_start = wtap_dump_file_tell(wdh, err);
4457 writer_data->logobject_block_header = blockheader;
4458
4459 fix_endianness_blf_blockheader(&blockheader);
4460
4461 if (!wtap_dump_file_write(wdh, &(blockheader), sizeof(blf_blockheader_t), err)) {
4462 return false0;
4463 }
4464
4465 if (!wtap_dump_file_write(wdh, &(logheader), sizeof(blf_logobjectheader_t), err)) {
4466 return false0;
4467 }
4468
4469 /* Successful writing done, time to update count */
4470 writer_data->object_count += 1;
4471
4472 return true1;
4473}
4474
4475/* return standard direction format of BLF, RX on error or unknown */
4476static uint8_t blf_get_direction(const wtap_rec *rec) {
4477 uint32_t tmp_direction = 0;
4478 if (WTAP_OPTTYPE_SUCCESS != wtap_block_get_uint32_option_value(rec->block, OPT_PKT_FLAGS2, &tmp_direction)) {
4479 return BLF_DIR_RX0;
4480 }
4481
4482 if (tmp_direction == PACK_FLAGS_DIRECTION_OUTBOUND2) {
4483 return BLF_DIR_TX1;
4484
4485 }
4486
4487 return BLF_DIR_RX0;
4488}
4489
4490static bool_Bool blf_dump_ethernet(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4491 /* LINKTYPE_ETHERNET */
4492 /* https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html */
4493
4494 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4495 const blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4496 if (iface_entry == NULL((void*)0)) {
4497 return false0;
4498 }
4499
4500 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4501 size_t length = ws_buffer_length(&rec->data);
4502
4503 /* 14 bytes is the full Ethernet Header up to EtherType */
4504 if (length < 14) {
4505 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4506 *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)
;
4507 return false0;
4508 }
4509
4510 uint32_t offset = 12;
4511
4512 blf_ethernetframeheader_t ethheader;
4513 ethheader.src_addr[0] = pd[6];
4514 ethheader.src_addr[1] = pd[7];
4515 ethheader.src_addr[2] = pd[8];
4516 ethheader.src_addr[3] = pd[9];
4517 ethheader.src_addr[4] = pd[10];
4518 ethheader.src_addr[5] = pd[11];
4519
4520 ethheader.channel = iface_entry->channel;
4521
4522 ethheader.dst_addr[0] = pd[0];
4523 ethheader.dst_addr[1] = pd[1];
4524 ethheader.dst_addr[2] = pd[2];
4525 ethheader.dst_addr[3] = pd[3];
4526 ethheader.dst_addr[4] = pd[4];
4527 ethheader.dst_addr[5] = pd[5];
4528
4529 ethheader.direction = blf_get_direction(rec);
4530
4531 uint16_t eth_type = pntohu16(pd + offset);
4532 offset += 2;
4533
4534 if (eth_type == 0x8100 || eth_type == 0x9100 || eth_type == 0x88a8) {
4535 if (length < 18) {
4536 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4537 *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)
;
4538 return false0;
4539 }
4540 ethheader.tpid = eth_type;
4541 ethheader.tci = pntohu16(pd + offset);
4542 offset += 2;
4543
4544 eth_type = pntohu16(pd + offset);
4545 offset += 2;
4546 } else {
4547 ethheader.tpid = 0;
4548 ethheader.tci = 0;
4549 }
4550
4551 ethheader.ethtype = eth_type;
4552 if (ckd_sub(&ethheader.payloadlength, length, offset)__builtin_sub_overflow((length), (offset), (&ethheader.payloadlength
))
) {
4553 /* Congratulations! You may have spotted a IPv6 Jumbogram (RFC 2675)!
4554 * You're another lucky winner of a Wiretap No-Prize! */
4555 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4556 *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)
;
4557 return false0;
4558 }
4559 ethheader.res = 0;
4560 fix_endianness_blf_ethernetframeheader(&ethheader);
4561
4562 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_ETHERNET_FRAME71, sizeof(blf_ethernetframeheader_t) + ethheader.payloadlength)) {
4563 return false0;
4564 }
4565
4566 if (!wtap_dump_file_write(wdh, &(ethheader), sizeof(blf_ethernetframeheader_t), err)) {
4567 return false0;
4568 }
4569
4570 if (!wtap_dump_file_write(wdh, &(pd[offset]), ethheader.payloadlength, err)) {
4571 return false0;
4572 }
4573
4574 /* Add strange padding to 4 bytes. */
4575 uint8_t padding_needed = (sizeof(blf_ethernetframeheader_t) + ethheader.payloadlength) % 4;
4576 return blf_write_add_padding(wdh, err, padding_needed);
4577}
4578
4579static bool_Bool blf_dump_socketcanxl(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp,
4580 const uint8_t *pd, size_t length, bool_Bool is_rx, bool_Bool is_tx) {
4581 /* LINKTYPE_CAN_SOCKETCAN */
4582 /* https://www.tcpdump.org/linktypes/LINKTYPE_CAN_SOCKETCAN.html */
4583
4584 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4585 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4586 if (iface_entry == NULL((void*)0)) {
4587 return false0;
4588 }
4589
4590 if (length < 12) {
4591 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4592 *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)
;
4593 ws_debug("LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4593, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL)."
); } } while (0)
;
4594 return false0;
4595 }
4596
4597 uint8_t socketcan_vcid = pd[1];
4598 uint16_t socketcan_id = pntohu16(pd + 2) & CAN_SFF_MASK0x000007FF;
4599 uint8_t socketcan_flags = pd[4];
4600 uint8_t socketcan_sdut = pd[5];
4601 uint16_t socketcan_payload_length = pletohu16(pd + 6);
4602
4603 if ((socketcan_flags & CANXL_XLF0x80) != CANXL_XLF0x80) {
4604 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4605 *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."
)
;
4606 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"
, 4606, __func__, "LINKTYPE_CAN_SOCKETCAN CAN XL flag not set for CAN XL?"
); } } while (0)
;
4607 return false0;
4608 }
4609
4610 if (length < (size_t)socketcan_payload_length + 12) {
4611 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4612 *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)
;
4613 ws_debug("LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4613, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL)."
); } } while (0)
;
4614 return false0;
4615 }
4616 uint32_t socketcan_acceptance_field = pletohu32(pd + 8);
4617
4618 /* LINKTYPE_LINUX_SLL would have set is_tx or is_rx */
4619 uint8_t frame_dir = is_tx ? BLF_DIR_TX1 : BLF_DIR_RX0;
4620 if (!is_rx && !is_tx) {
4621 frame_dir = blf_get_direction(rec);
4622 }
4623
4624 blf_canxlchannelframe_t canxl = {0};
4625 canxl.channel = (uint8_t)iface_entry->channel;
4626 canxl.dir = frame_dir;
4627 canxl.frameIdentifier = socketcan_id;
4628 canxl.serviceDataUnitType = socketcan_sdut;
4629 canxl.dlc = socketcan_payload_length - 1;
4630 canxl.dataLength = socketcan_payload_length;
4631 canxl.virtualControllerAreaNetChannelID = socketcan_vcid;
4632 canxl.acceptanceField = socketcan_acceptance_field;
4633
4634 if ((socketcan_flags & CANXL_XLF0x80) == CANXL_XLF0x80) {
4635 /* should be always true but we might refactor */
4636 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000;
4637 }
4638 if ((socketcan_flags & CANXL_SEC0x01) == CANXL_SEC0x01) {
4639 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_SEC0x1000000;
4640 }
4641 if ((socketcan_flags & CANXL_RRS0x02) == CANXL_RRS0x02) {
4642 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_RRS0x800000;
4643 }
4644
4645 fix_endianness_blf_canxlchannelframe(&canxl);
4646
4647 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_XL_CHANNEL_FRAME139, sizeof(blf_canxlchannelframe_t) + socketcan_payload_length)) {
4648 return false0;
4649 }
4650
4651 if (!wtap_dump_file_write(wdh, &(canxl), sizeof(blf_canxlchannelframe_t), err)) {
4652 return false0;
4653 }
4654
4655 if (!wtap_dump_file_write(wdh, &(pd[12]), socketcan_payload_length, err)) {
4656 return false0;
4657 }
4658
4659 return true1;
4660}
4661
4662static const uint8_t canfd_length_to_dlc[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 9, 0, 0, 0,
4663 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
4664 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4665 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4666 15 };
4667
4668static bool_Bool blf_dump_socketcan(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp,
4669 const uint8_t *pd, size_t length, bool_Bool is_can, bool_Bool is_canfd, bool_Bool is_rx, bool_Bool is_tx) {
4670 /* LINKTYPE_CAN_SOCKETCAN */
4671 /* https://www.tcpdump.org/linktypes/LINKTYPE_CAN_SOCKETCAN.html */
4672
4673 if (length < 8) {
4674 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4675 *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)
;
4676 ws_debug("LINKTYPE_CAN_SOCKETCAN header is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4676, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short."
); } } while (0)
;
4677 return false0;
4678 }
4679
4680 /* check for CAN-XL */
4681 if ((pd[4] & CANXL_XLF0x80) == CANXL_XLF0x80) {
4682 return blf_dump_socketcanxl(wdh, rec, err, err_info, obj_timestamp, pd, length, is_rx, is_tx);
4683 }
4684
4685 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4686 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4687 if (iface_entry == NULL((void*)0)) {
4688 return false0;
4689 }
4690
4691 uint8_t payload_length = pd[4];
4692
4693 if (length < (size_t)payload_length + 8) {
4694 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4695 *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)
;
4696 ws_debug("LINKTYPE_CAN_SOCKETCAN header is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4696, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short."
); } } while (0)
;
4697 return false0;
4698 }
4699
4700 /* LINKTYPE_LINUX_SLL would have set is_tx or is_rx */
4701 uint8_t frame_dir = is_tx ? BLF_DIR_TX1 : BLF_DIR_RX0;
4702 if (!is_rx && !is_tx) {
4703 frame_dir = blf_get_direction(rec);
4704 }
4705
4706 bool_Bool canfd = is_canfd;
4707
4708 /* LINKTYPE_LINUX_SLL would have set one */
4709 if (!is_can && !is_canfd) {
4710 if ((pd[5] & CANFD_FDF0x04) == CANFD_FDF0x04) {
4711 canfd = true1;
4712 } else {
4713 /* heuristic. if longer than header + 8 bytes data, its CAN-FD*/
4714 canfd = rec->rec_header.packet_header.caplen > 16;
4715 }
4716 }
4717
4718 /* XXX endianness is not defined. Assuming BE as this seems the common choice*/
4719 uint32_t can_id = pntohu32(pd);
4720
4721 /* lets check if can_id makes sense
4722 * 29bit CAN ID mask 0x1fffffff CAN_EFF_MASK
4723 * 11bit CAN ID mask 0x000007ff CAN_SFF_MASK
4724 * 29 only bits 0x1ffff800 CAN_EFF_MASK & !CAN_SFF_MASK
4725 */
4726 if (((can_id & CAN_EFF_FLAG0x80000000) == 0) && ((can_id & (CAN_EFF_MASK0x1FFFFFFF & (!CAN_SFF_MASK0x000007FF))) != 0)) {
4727 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)
;
4728 can_id = pletohu32(pd);
4729 }
4730
4731 bool_Bool err_flag = (can_id & CAN_ERR_FLAG0x20000000) == CAN_ERR_FLAG0x20000000;
4732 bool_Bool rtr_flag = (can_id & CAN_RTR_FLAG0x40000000) == CAN_RTR_FLAG0x40000000;
4733 //bool ext_id_flag = (can_id & CAN_EFF_FLAG) == CAN_EFF_FLAG;
4734 can_id &= (CAN_EFF_MASK0x1FFFFFFF | CAN_EFF_FLAG0x80000000);
4735
4736 if (canfd) {
4737 /* CAN-FD */
4738 bool_Bool brs_flag = (pd[5] & CANFD_BRS0x01) == CANFD_BRS0x01;
4739 bool_Bool esi_flag = (pd[5] & CANFD_ESI0x02) == CANFD_ESI0x02;
4740 bool_Bool fdf_flag = (pd[5] & CANFD_FDF0x04) == CANFD_FDF0x04;
4741
4742 blf_canfdmessage64_t canfdmsg;
4743 canfdmsg.channel = (uint8_t)iface_entry->channel;
4744
4745 canfdmsg.dlc = (payload_length <= 64) ? canfd_length_to_dlc[payload_length] : 0;
4746 canfdmsg.validDataBytes = payload_length;
4747 canfdmsg.txCount = 0;
4748 canfdmsg.id = can_id;
4749 canfdmsg.frameLength_in_ns = 0;
4750 canfdmsg.flags = 0;
4751
4752 /* TODO: fdf_flag is not always set for CAN-FD */
4753 if (fdf_flag) {
4754 canfdmsg.flags = BLF_CANFDMESSAGE64_FLAG_EDL0x001000; // CAN-FD
4755 } else {
4756 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"
, 4756, __func__, "CAN-FD has not CANFD_FDF set. File not correct."
); } } while (0)
;
4757 }
4758 if (brs_flag) {
4759 canfdmsg.flags |= BLF_CANFDMESSAGE64_FLAG_BRS0x002000;
4760 }
4761 if (esi_flag) {
4762 canfdmsg.flags |= BLF_CANFDMESSAGE64_FLAG_ESI0x004000;
4763 }
4764
4765 canfdmsg.btrCfgArb = 0;
4766 canfdmsg.btrCfgData = 0;
4767 canfdmsg.timeOffsetBrsNs = 0;
4768 canfdmsg.timeOffsetCrcDelNs = 0;
4769 canfdmsg.bitCount = 0;
4770 canfdmsg.dir = frame_dir;
4771 canfdmsg.extDataOffset = 0;
4772 canfdmsg.crc = 0;
4773
4774 fix_endianness_blf_canfdmessage64(&canfdmsg);
4775
4776 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_FD_MESSAGE_64101, sizeof(blf_canfdmessage64_t) + payload_length)) {
4777 return false0;
4778 }
4779
4780 if (!wtap_dump_file_write(wdh, &(canfdmsg), sizeof(blf_canfdmessage64_t), err)) {
4781 return false0;
4782 }
4783 } else {
4784 /* CAN */
4785 blf_canmessage_t canmsg;
4786
4787 if (payload_length > 8) {
4788 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"
, 4788, __func__, "CAN frames can only have up to 8 bytes of payload! We have %d bytes"
, payload_length); } } while (0)
;
4789 payload_length = 8;
4790 }
4791
4792 canmsg.dlc = payload_length;
4793 canmsg.channel = iface_entry->channel;
4794
4795 canmsg.flags = 0;
4796 if (frame_dir == BLF_DIR_TX1) {
4797 canmsg.flags |= BLF_CANMESSAGE_FLAG_TX0x01;
4798 }
4799
4800 if (err_flag) {
4801 // TODO: we need to implement CAN ERROR, ignore for now
4802 return true1;
4803 //canmsg.flags |= BLF_CANMESSAGE_FLAG_NERR; - NERR is not error
4804 }
4805
4806 if (rtr_flag) {
4807 canmsg.flags |= BLF_CANMESSAGE_FLAG_RTR0x80;
4808 }
4809
4810 canmsg.id = can_id;
4811
4812 fix_endianness_blf_canmessage(&canmsg);
4813
4814 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_MESSAGE1, sizeof(blf_canmessage_t) + 8)) {
4815 return false0;
4816 }
4817
4818 if (!wtap_dump_file_write(wdh, &(canmsg), sizeof(blf_canmessage_t), err)) {
4819 return false0;
4820 }
4821 }
4822
4823 if (!wtap_dump_file_write(wdh, &(pd[8]), payload_length, err)) {
4824 return false0;
4825 }
4826
4827 if (!canfd && payload_length < 8) {
4828 uint8_t padding[8] = { 0 };
4829 if (!wtap_dump_file_write(wdh, &padding, 8 - payload_length, err)) {
4830 return false0;
4831 }
4832 }
4833
4834 /* no padding */
4835
4836 return true1;
4837}
4838
4839static bool_Bool blf_dump_sll(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4840 /* Linux Cooked CAN / CAN-FD */
4841 /* https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html */
4842
4843 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4844 size_t length = ws_buffer_length(&rec->data);
4845
4846 if (length < 16) {
4847 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4848 *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)
;
4849 ws_debug("LINKTYPE_LINUX_SLL header is too short.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4849, __func__, "LINKTYPE_LINUX_SLL header is too short.");
} } while (0)
;
4850 return false0;
4851 }
4852
4853 bool_Bool frame_tx = false0;
4854 if (pd[0] == 0 && pd[1] == 4) {
4855 frame_tx = true1;
4856 }
4857
4858 uint16_t protocol_type = pntohu16(pd + 14);
4859
4860 switch (protocol_type) {
4861 case 0x000C: /* CAN */
4862 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, true1, false0, !frame_tx, frame_tx);
4863 break;
4864 case 0x000D: /* CAN-FD */
4865 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, false0, true1, !frame_tx, frame_tx);
4866 break;
4867 case 0x000E: /* CAN-XL */
4868 return blf_dump_socketcanxl(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, !frame_tx, frame_tx);
4869 break;
4870 default:
4871 return false0;
4872 }
4873
4874 /* not reachable? */
4875 return true1;
4876}
4877
4878static bool_Bool blf_dump_flexray(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4879 /* FlexRay */
4880 /* https://www.tcpdump.org/linktypes/LINKTYPE_FLEXRAY.html */
4881
4882 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4883 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4884 if (iface_entry == NULL((void*)0)) {
4885 return false0;
4886 }
4887
4888 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4889 size_t length = ws_buffer_length(&rec->data);
4890
4891 if (length < 1) {
4892 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4893 *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)
;
4894 ws_debug("LINKTYPE_FLEXRAY header is too short (< 1 Byte).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4894, __func__, "LINKTYPE_FLEXRAY header is too short (< 1 Byte)."
); } } while (0)
;
4895 return false0;
4896 }
4897
4898 /* Check Measurement Header for Type */
4899 if ((pd[0] & FLEXRAY_TYPE_MASK0x7f) == FLEXRAY_SYMBOL0x02) {
4900 /* Symbol */
4901
4902 if (length < 2) {
4903 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4904 *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)
;
4905 ws_debug("LINKTYPE_FLEXRAY Symbol is too short (< 2 Byte).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4905, __func__, "LINKTYPE_FLEXRAY Symbol is too short (< 2 Byte)."
); } } while (0)
;
4906 return false0;
4907 }
4908
4909 /* TODO: SYMBOL */
4910
4911 return true1;
4912 }
4913
4914 if ((pd[0] & FLEXRAY_TYPE_MASK0x7f) == FLEXRAY_FRAME0x01) {
4915 /* Frame */
4916
4917 if (length < 2 + FLEXRAY_HEADER_LENGTH5) {
4918 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4919 *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)
;
4920 ws_debug("LINKTYPE_FLEXRAY Frame Header is too short (< 7 Byte).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4920, __func__, "LINKTYPE_FLEXRAY Frame Header is too short (< 7 Byte)."
); } } while (0)
;
4921 return false0;
4922 }
4923
4924 uint8_t payload_length = pd[4] & FLEXRAY_LENGTH_MASK0xfe;
4925
4926 /* FLEXRAY FRAME */
4927 blf_flexrayrcvmessage_t frmsg;
4928
4929 frmsg.channel = (uint16_t)iface_entry->channel;
4930 frmsg.version = 1;
4931
4932 uint32_t header_crc = (pntohu24(pd + 4) & FLEXRAY_HEADER_CRC_MASK0x01ffc0) >> FLEXRAY_HEADER_CRC_SHFT6;
4933
4934 if ((pd[0] & FLEXRAY_CHANNEL_MASK0x80) == 0) {
4935 frmsg.channelMask = BLF_FLEXRAYRCVMSG_CHANNELMASK_A0x01;
4936 frmsg.headerCrc1 = header_crc;
4937 frmsg.headerCrc2 = 0;
4938 } else {
4939 frmsg.channelMask = BLF_FLEXRAYRCVMSG_CHANNELMASK_B0x02;
4940 frmsg.headerCrc1 = 0;
4941 frmsg.headerCrc2 = header_crc;
4942 }
4943
4944 frmsg.dir = blf_get_direction(rec);
4945 frmsg.clientIndex = 0;
4946 frmsg.clusterNo = 0;
4947 frmsg.frameId = (pntohu16(pd + 2)) & FLEXRAY_ID_MASK0x07ff;
4948 frmsg.payloadLength = payload_length;
4949 frmsg.payloadLengthValid = payload_length;
4950 frmsg.cycle = pd[6] & FLEXRAY_CC_MASK0x3f;
4951 frmsg.tag = 0;
4952 frmsg.data = 0;
4953 frmsg.frameFlags = 0;
4954
4955 /* The NULL Flag 1 -> False */
4956 bool_Bool null_frame = (pd[2] & FLEXRAY_NFI_MASK0x20) != FLEXRAY_NFI_MASK0x20;
4957
4958 if (null_frame) {
4959 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_NULL_FRAME0x00000001;
4960 /* LINKTYPE_FLEXRAY has no payload for Null Frames present */
4961 payload_length = 0;
4962 }
4963
4964 /* TODO: check truncated data */
4965 if (payload_length > 0) {
4966 /* Data Valid*/
4967 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_VALID_DATA0x00000002;
4968 }
4969
4970 if ((pd[2] & FLEXRAY_SFI_MASK0x10) == FLEXRAY_SFI_MASK0x10) {
4971 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_SYNC0x00000004;
4972 }
4973
4974 if ((pd[2] & FLEXRAY_STFI_MASK0x08) == FLEXRAY_STFI_MASK0x08) {
4975 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_STARTUP0x00000008;
4976 }
4977
4978 if ((pd[2] & FLEXRAY_PPI_MASK0x40) == FLEXRAY_PPI_MASK0x40) {
4979 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_PAYLOAD_PREAM0x00000010;
4980 }
4981
4982 if ((pd[2] & FLEXRAY_RES_MASK0x80) == FLEXRAY_RES_MASK0x80) {
4983 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_RES_200x00000020;
4984 }
4985
4986 /* if any error flag is set */
4987 if ((pd[1] & FLEXRAY_ERRORS_DEFINED0x1f) != 0x00) {
4988 frmsg.frameFlags |= BLF_FLEXRAYRCVMSG_FRAME_FLAG_ERROR0x00000040;
4989 }
4990
4991 /* Not sure how to determine this as we do not know the low level parameters */
4992 //if ( ) {
4993 // /* DYNAMIC SEG =1 (Bit 20)*/
4994 // frmsg.frameFlags |= 0x100000;
4995 //}
4996
4997 frmsg.appParameter = 0;
4998
4999 fix_endianness_blf_flexrayrcvmessage(&frmsg);
5000
5001 if (length < (size_t)payload_length + 2 + FLEXRAY_HEADER_LENGTH5) {
5002 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5003 *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)
;
5004 ws_debug("LINKTYPE_FLEXRAY Frame truncated.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5004, __func__, "LINKTYPE_FLEXRAY Frame truncated."); } } while
(0)
;
5005 return false0;
5006 }
5007
5008 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_FLEXRAY_RCVMESSAGE50, sizeof(blf_flexrayrcvmessage_t) + 254)) {
5009 return false0;
5010 }
5011
5012 if (!wtap_dump_file_write(wdh, &(frmsg), sizeof(blf_flexrayrcvmessage_t), err)) {
5013 return false0;
5014 }
5015
5016 if (payload_length > 0) {
5017 if (!wtap_dump_file_write(wdh, &(pd[7]), payload_length, err)) {
5018 return false0;
5019 }
5020 }
5021
5022 const uint8_t zero_bytes[256] = { 0 };
5023
5024 if (payload_length < 254) {
5025 if (!wtap_dump_file_write(wdh, &zero_bytes[0], 254 - payload_length, err)) {
5026 return false0;
5027 }
5028 }
5029
5030 return true1;
5031 }
5032
5033 /* no padding */
5034
5035 return true1;
5036}
5037
5038static bool_Bool blf_dump_lin(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
5039 /* LIN */
5040 /* https://www.tcpdump.org/linktypes/LINKTYPE_LIN.html */
5041
5042 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5043 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
5044 if (iface_entry == NULL((void*)0)) {
5045 return false0;
5046 }
5047
5048 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
5049 size_t length = ws_buffer_length(&rec->data);
5050
5051 if (length < 8) {
5052 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5053 *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)
;
5054 ws_debug("LIN Data is too short (less than 8 bytes).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5054, __func__, "LIN Data is too short (less than 8 bytes)."
); } } while (0)
;
5055 return false0;
5056 }
5057
5058 uint8_t lin_err = pd[7] & 0x3f;
5059 if (lin_err != 0) {
5060 // TODO: handle LIN errors
5061 return true1;
5062 }
5063
5064 int i;
5065 uint8_t dlc = (pd[4] & LIN_PAYLOAD_LENGTH_MASK0xf0) >> 4;
5066 uint8_t msg_type = (pd[4] & LIN_MSG_TYPE_MASK0x0c) >> 2;
5067
5068 if (msg_type != LIN_MSG_TYPE_FRAME0) {
5069 // TODO: handle LIN events
5070 return true1;
5071 }
5072
5073 /* we need to have at least the data */
5074 if (length < (size_t)dlc + 8) {
5075 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5076 *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)
;
5077 ws_debug("LIN Data is too short (less than needed).")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5077, __func__, "LIN Data is too short (less than needed)."
); } } while (0)
;
5078 return false0;
5079 }
5080
5081 /* we ignore padding as we do not need it anyhow */
5082
5083 blf_linmessage_t linmsg;
5084 linmsg.channel = (uint16_t)iface_entry->channel;
5085 linmsg.id = pd[5];
5086 linmsg.dlc = dlc;
5087 for (i = 0; i < 8; i++) {
5088 if (i < dlc) {
5089 linmsg.data[i] = pd[i + 8];
5090 } else {
5091 linmsg.data[i] = 0;
5092 }
5093 }
5094 linmsg.fsmId = 0;
5095 linmsg.fsmState = 0;
5096 linmsg.headerTime = 0;
5097 linmsg.fullTime = 0;
5098 linmsg.crc = pd[6];
5099 linmsg.dir = blf_get_direction(rec);
5100 linmsg.res1 = 0;
5101
5102 fix_endianness_blf_linmessage(&linmsg);
5103
5104 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_LIN_MESSAGE11, sizeof(blf_linmessage_t) + 4)) {
5105 return false0;
5106 }
5107
5108 if (!wtap_dump_file_write(wdh, &(linmsg), sizeof(blf_linmessage_t), err)) {
5109 return false0;
5110 }
5111
5112 uint8_t rest_of_header[4] = { 0, 0, 0, 0};
5113
5114 if (!wtap_dump_file_write(wdh, &(rest_of_header), 4, err)) {
5115 return false0;
5116 }
5117
5118 /* no padding! */
5119
5120 return true1;
5121}
5122
5123static bool_Bool blf_dump_upper_pdu(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
5124 const blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5125
5126 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
5127 size_t length = ws_buffer_length(&rec->data);
5128
5129 unsigned tag_diss_pos = 0;
5130 size_t tag_diss_len = 0;
5131 unsigned col_proto_pos = 0;
5132 size_t col_proto_len = 0;
5133 unsigned col_info_pos = 0;
5134 size_t col_info_len = 0;
5135
5136 /* parse the tags */
5137 size_t pos = 0;
5138 bool_Bool done = false0;
5139 while (!done) {
5140 if (length - pos < 4) {
5141 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5142 *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)
;
5143 ws_debug("Upper PDU has truncated tags.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5143, __func__, "Upper PDU has truncated tags."); } } while
(0)
;
5144 return false0;
5145 }
5146
5147 uint16_t tag_type = pntohu16(pd + pos);
5148 uint16_t tag_len = pntohu16(pd + pos + 2);
5149
5150 if ((length - pos) < (size_t)tag_len + 4) {
5151 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
5152 *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)
;
5153 ws_debug("Upper PDU has truncated tags.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5153, __func__, "Upper PDU has truncated tags."); } } while
(0)
;
5154 return false0;
5155 }
5156
5157 switch (tag_type) {
5158 case EXP_PDU_TAG_DISSECTOR_NAME12:
5159 tag_diss_pos = (unsigned)pos + 4;
5160 tag_diss_len = tag_len;
5161 break;
5162
5163 case EXP_PDU_TAG_COL_PROT_TEXT33:
5164 col_proto_pos = (unsigned)pos + 4;
5165 col_proto_len = tag_len;
5166 break;
5167
5168 case EXP_PDU_TAG_COL_INFO_TEXT36:
5169 col_info_pos = (unsigned)pos + 4;
5170 col_info_len = tag_len;
5171 break;
5172
5173 case EXP_PDU_TAG_END_OF_OPT0:
5174 done = true1;
5175 break;
5176 }
5177
5178 pos += 4;
5179 pos += tag_len;
5180 }
5181
5182 /* strip zero termination, if existing (a missing tag has length 0) */
5183 while (tag_diss_len > 0 && pd[tag_diss_pos + tag_diss_len - 1] == 0) {
5184 tag_diss_len -= 1;
5185 }
5186
5187 while (col_proto_len > 0 && pd[col_proto_pos + col_proto_len - 1] == 0) {
5188 col_proto_len -= 1;
5189 }
5190
5191 while (col_info_len > 0 && pd[col_info_pos + col_info_len - 1] == 0) {
5192 col_info_len -= 1;
5193 }
5194
5195 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)) {
5196 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)) {
5197 blf_apptext_t apptext_header;
5198 apptext_header.source = BLF_APPTEXT_METADATA0x00000002;
5199 apptext_header.reservedAppText1 = 0;
5200 apptext_header.reservedAppText2 = 412; /* not sure what to put in but this is commonly used!? */
5201 uint32_t payload_len = (uint32_t)(length - pos);
5202 apptext_header.textLength = payload_len;
5203
5204 /* Metadata */
5205 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, BLF_APPTEXT_COL_INFO_TEXT_... */
5206 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)) {
5207 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_GENERAL */
5208 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_GENERAL0x01 << 24) | (0xffffff & payload_len);
5209 } 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)) {
5210 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_CHANNELS */
5211 if (writer_data->iface_to_channel_names_recovered) {
5212 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_CHANNELS0x02 << 24) | (0xffffff & payload_len);
5213 }
5214 } 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)) {
5215 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_IDENTITY */
5216 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_IDENTITY0x03 << 24) | (0xffffff & payload_len);
5217
5218 //} else if
5219 /* BLF_APPTEXT_COMMENT */
5220 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Comment: %s" */
5221 // TODO
5222 //} else if
5223 /* BLF_APPTEXT_ATTACHMENT */
5224 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Attachment: %s" */
5225 // TODO
5226 //} else if
5227 /* BLF_APPTEXT_TRACELINE */
5228 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Trace line%s: %s" */
5229 // TODO
5230 } else {
5231 return true1; /* just leave */
5232 }
5233
5234 if (payload_len > 2048 && (apptext_header.source != BLF_APPTEXT_METADATA0x00000002)) {
5235 ws_warning("Only Meta Data can be broken into smaller chunks.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 5235, __func__, "Only Meta Data can be broken into smaller chunks."
); } } while (0)
;
5236 }
5237
5238 uint32_t chunk_size;
5239 bool_Bool last_round = false0;
5240 do {
5241 if (payload_len > 2048 && apptext_header.source == BLF_APPTEXT_METADATA0x00000002) {
5242 chunk_size = 2048;
5243 } else {
5244 chunk_size = payload_len;
5245 last_round = true1;
5246 }
5247
5248 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_APP_TEXT65, sizeof(blf_apptext_t) + chunk_size)) {
5249 return false0;
5250 }
5251
5252 if (apptext_header.source == BLF_APPTEXT_METADATA0x00000002) {
5253 apptext_header.reservedAppText1 = (0xff000000 & apptext_header.reservedAppText1) | (0x00ffffff & payload_len);
5254 }
5255
5256 apptext_header.textLength = chunk_size;
5257 fix_endianness_blf_apptext_header(&apptext_header);
5258 if (!wtap_dump_file_write(wdh, &(apptext_header), sizeof(blf_apptext_t), err)) {
5259 return false0;
5260 }
5261 if (!last_round) {
5262 fix_endianness_blf_apptext_header(&apptext_header);
5263 }
5264
5265 if (!wtap_dump_file_write(wdh, &(pd[pos]), chunk_size, err)) {
5266 return false0;
5267 }
5268 pos += chunk_size;
5269
5270 /* Add strange padding to 4 bytes. */
5271 uint8_t padding_needed = (sizeof(blf_apptext_t) + chunk_size) % 4;
5272 if (!blf_write_add_padding(wdh, err, padding_needed)) {
5273 return false0;
5274 }
5275
5276 if (!last_round) {
5277 payload_len -= 2048;
5278 }
5279 } while (!last_round);
5280
5281 return true1;
5282 }
5283 // else if
5284 /* BLF_OBJTYPE_ETHERNET_STATUS */
5285 /* tags: BLF_APPTEXT_TAG_DISS_ETHSTATUS */
5286 // TODO
5287
5288 // else if
5289 /* BLF_OBJTYPE_ETHERNET_PHY_STATE */
5290 /* tags: BLF_APPTEXT_TAG_DISS_ETHPHYSTATUS */
5291 // TODO
5292 }
5293
5294 return true1;
5295}
5296
5297static bool_Bool blf_dump_interface_setup_by_blf_based_idb_desc(wtap_dumper *wdh, int *err _U___attribute__((unused))) {
5298 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5299 bool_Bool iface_descr_found;
5300
5301 /* check all interfaces first to avoid inconsistent state */
5302 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5303 ws_debug("interface: %d (pass 1)", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5303, __func__, "interface: %d (pass 1)", i); } } while (0)
;
5304
5305 /* get interface data */
5306 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5307 if (idb == NULL((void*)0)) {
5308 return false0;
5309 }
5310
5311 char *iface_descr = NULL((void*)0);
5312 iface_descr_found = wtap_block_get_string_option_value(idb, OPT_IDB_DESCRIPTION3, &iface_descr) == WTAP_OPTTYPE_SUCCESS;
5313
5314 if (!iface_descr_found) {
5315 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"
, 5315, __func__, "IDB interface description not found! We need to map the interfaces."
); } } while (0)
;
5316 return false0;
5317 }
5318
5319 if (strncmp(iface_descr, "BLF-", 4) != 0) {
5320 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"
, 5320, __func__, "IDB interface description found but not BLF format! We have to map freely the interfaces."
); } } while (0)
;
5321 return false0;
5322 }
5323 }
5324
5325 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5326 ws_debug("interface: %d (pass 2)", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5326, __func__, "interface: %d (pass 2)", i); } } while (0)
;
5327
5328 /* get interface data */
5329 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5330 if (idb == NULL((void*)0)) {
5331 return false0;
5332 }
5333
5334 char *iface_descr = NULL((void*)0);
5335 iface_descr_found = wtap_block_get_string_option_value(idb, OPT_IDB_DESCRIPTION3, &iface_descr) == WTAP_OPTTYPE_SUCCESS;
5336
5337 if (!iface_descr_found) {
5338 /* This cannot be reached but it removes a warning. */
5339 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"
, 5339, __func__, "IDB interface description not found! We need to map the interfaces."
); } } while (0)
;
5340 return false0;
5341 }
5342
5343 if (strncmp(iface_descr, "BLF-ETH-", 8) == 0) {
5344 char *endptr;
5345 uint16_t channel = (uint16_t)strtol(&iface_descr[8], &endptr, 16);
5346 uint16_t hwchannel = (uint16_t)strtol(&endptr[1], NULL((void*)0), 16);
5347
5348 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_ETHERNET1, channel, hwchannel)) {
5349 return false0;
5350 }
5351 } else if (strncmp(iface_descr, "BLF-CAN-", 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_SOCKETCAN125, channel, UINT16_MAX(65535))) {
5355 return false0;
5356 }
5357 } else if (strncmp(iface_descr, "BLF-LIN-", 8) == 0) {
5358 uint16_t channel = (uint16_t)strtol(&iface_descr[8], NULL((void*)0), 16);
5359
5360 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_LIN107, channel, UINT16_MAX(65535))) {
5361 return false0;
5362 }
5363 } else if (strncmp(iface_descr, "BLF-FR-", 7) == 0) {
5364 uint16_t channel = (uint16_t)strtol(&iface_descr[7], NULL((void*)0), 16);
5365
5366 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_FLEXRAY106, channel, UINT16_MAX(65535))) {
5367 return false0;
5368 }
5369 }
5370 }
5371
5372 writer_data->iface_to_channel_names_recovered = true1;
5373 return true1;
5374}
5375
5376static bool_Bool blf_dump_interface_setup(wtap_dumper *wdh, int *err) {
5377 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5378
5379 /* Try 1: BLF details in Interface Description */
5380 if (blf_dump_interface_setup_by_blf_based_idb_desc(wdh, err)) {
5381 return true1;
5382 }
5383
5384 /* Try 2: Generate new IDs by mapping Interface IDs and also add names to BLF */
5385 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5386 ws_debug("i: %d", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5386, __func__, "i: %d", i); } } while (0)
;
5387
5388 /* get interface data */
5389 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5390 if (idb == NULL((void*)0)) {
5391 return false0;
5392 }
5393
5394 const wtapng_if_descr_mandatory_t *mand_data = (wtapng_if_descr_mandatory_t *) idb->mandatory_data;
5395
5396 if (mand_data->wtap_encap == WTAP_ENCAP_ETHERNET1 || mand_data->wtap_encap == WTAP_ENCAP_SLL25 ||
5397 mand_data->wtap_encap == WTAP_ENCAP_LIN107 || mand_data->wtap_encap == WTAP_ENCAP_SOCKETCAN125 ||
5398 mand_data->wtap_encap == WTAP_ENCAP_FLEXRAY106) {
5399
5400 char *iface_name = NULL((void*)0);
5401 bool_Bool iface_name_found = wtap_block_get_string_option_value(idb, OPT_IDB_NAME2, &iface_name) == WTAP_OPTTYPE_SUCCESS;
5402
5403 /* BLF can only support 255 channels */
5404 if (iface_name_found && iface_name != NULL((void*)0) && (i) < 255) {
5405 uint8_t iface_id = (uint8_t)(i + 1);
5406
5407 /* we are not even trying to create APPTEXT CHANNELS as we are missing too much information */
5408
5409 /* mapping up to 255 interface ids to channels directly */
5410 if (!blf_dump_set_interface_mapping(wdh, i, mand_data->wtap_encap, (uint16_t)iface_id, UINT16_MAX(65535))) {
5411 return false0;
5412 }
5413 }
5414 }
5415 }
5416
5417 return true1;
5418}
5419
5420#define NS_PER_S1000000000 1000000000
5421
5422static bool_Bool blf_dump(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info) {
5423 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5424 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"
, 5425, __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)
5425 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"
, 5425, __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)
;
5426
5427 /* TODO */
5428 switch (rec->rec_type) {
5429 case REC_TYPE_PACKET0:
5430 break;
5431 default:
5432 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
5433 return false0;
5434 }
5435
5436 /* logcontainer full already? we just estimate the headers/overhead to be less than 100 */
5437 blf_dump_check_logcontainer_full(wdh, err, err_info, rec->rec_header.packet_header.len + 100);
5438
5439 uint64_t obj_timestamp = (rec->ts.secs * 1000 * 1000 * 1000 + rec->ts.nsecs);
5440
5441 /* Due to all object timestamps being relative the file header start time, we only want to do this once. */
5442 /* Packets can be skipped due to writing of that specfic event type not being supported or just not yet */
5443 /* implemented, so use the object_count to know if any events has been output to file yet. */
5444 if (writer_data->object_count == 0) {
5445 /* TODO: refine method. Right now assume no event will ever be more than 1 second prior to first packet time. */
5446 /* Suggested improvement 1: For 2-pass or preloaded data use the time of the actual first event. */
5447 /* Suggested improvement 2: For single step conversion, make safety margin configurable. */
5448 if(obj_timestamp > NS_PER_S1000000000) {
5449 writer_data->start_time = obj_timestamp - NS_PER_S1000000000;
5450 } else {
5451 writer_data->start_time = 0;
5452 }
5453 }
5454
5455 if (obj_timestamp < writer_data->start_time) {
5456 *err = WTAP_ERR_BAD_FILE-13;
5457 *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."
)
;
5458 return false0;
5459 }
5460
5461 if (writer_data->end_time < obj_timestamp) {
5462 writer_data->end_time = obj_timestamp;
5463 }
5464
5465 /* reduce by BLF start offset */
5466 obj_timestamp = obj_timestamp - writer_data->start_time;
5467
5468 switch (rec->rec_header.packet_header.pkt_encap) {
5469 case WTAP_ENCAP_ETHERNET1: /* 1 */
5470 return blf_dump_ethernet(wdh, rec, err, err_info, obj_timestamp);
5471 break;
5472
5473 case WTAP_ENCAP_SLL25: /* 25 */
5474 return blf_dump_sll(wdh, rec, err, err_info, obj_timestamp);
5475 break;
5476
5477 case WTAP_ENCAP_FLEXRAY106: /* 106 */
5478 return blf_dump_flexray(wdh, rec, err, err_info, obj_timestamp);
5479 break;
5480
5481 case WTAP_ENCAP_LIN107: /* 107 */
5482 return blf_dump_lin(wdh, rec, err, err_info, obj_timestamp);
5483 break;
5484
5485 case WTAP_ENCAP_SOCKETCAN125: { /* 125 */
5486 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
5487 size_t length = ws_buffer_length(&rec->data);
5488 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, pd, length, false0, false0, false0, false0);
5489 }
5490 break;
5491
5492 case WTAP_ENCAP_WIRESHARK_UPPER_PDU155: /* 155 */
5493 return blf_dump_upper_pdu(wdh, rec, err, err_info, obj_timestamp);
5494 break;
5495
5496 default:
5497 break;
5498 }
5499
5500 return true1;
5501}
5502
5503/* Returns 0 if we could write the specified encapsulation type,
5504 an error indication otherwise. */
5505static int blf_dump_can_write_encap(int wtap_encap) {
5506 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"
, 5506, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
;
5507
5508 /* Per-packet encapsulation is supported. */
5509 if (wtap_encap == WTAP_ENCAP_PER_PACKET-1)
5510 return 0;
5511
5512 switch (wtap_encap) {
5513 /* fall through */
5514 case WTAP_ENCAP_ETHERNET1:
5515 case WTAP_ENCAP_SLL25:
5516 case WTAP_ENCAP_FLEXRAY106:
5517 case WTAP_ENCAP_LIN107:
5518 case WTAP_ENCAP_SOCKETCAN125:
5519 case WTAP_ENCAP_WIRESHARK_UPPER_PDU155:
5520 return 0;
5521 }
5522
5523 return WTAP_ERR_UNWRITABLE_ENCAP-8;
5524}
5525
5526static 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))) {
5527 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5527, __func__, "entering function"); } } while (0)
;
5528 /*
5529 * A new IDB was added to the list of itnerfaces for the file to
5530 * which we're writing; update hte interface mapping.
5531 */
5532 blf_dump_interface_setup(wdh, err); // Expands and populates the interface mapping
5533
5534 return true1;
5535}
5536
5537/* Finish writing to a dump file.
5538 Returns true on success, false on failure. */
5539static bool_Bool blf_dump_finish(wtap_dumper *wdh, int *err, char **err_info) {
5540 if (!blf_dump_close_logcontainer(wdh, err, err_info)) {
5541 blf_dump_free(wdh);
5542 return false0;
5543 }
5544
5545 if (!blf_finalize_file_header(wdh, err)) {
5546 blf_dump_free(wdh);
5547 return false0;
5548 }
5549
5550 blf_dump_free(wdh);
5551 /* File is finished, do not touch anymore ! */
5552
5553 ws_debug("leaving function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5553, __func__, "leaving function"); } } while (0)
;
5554 return true1;
5555}
5556
5557/* Returns true on success, false on failure; sets "*err" to an error code on
5558 failure */
5559static bool_Bool
5560blf_dump_open(wtap_dumper *wdh, int *err, char **err_info) {
5561 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5561, __func__, "entering function"); } } while (0)
;
5562
5563 if (wdh == NULL((void*)0) || wdh->priv != NULL((void*)0)) {
5564 *err = WTAP_ERR_INTERNAL-21;
5565 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"
, 5565, __func__, "internal error: blf wdh is NULL or private data already set."
); } } while (0)
;
5566 return false0;
5567 }
5568
5569 wdh->subtype_add_idb = blf_add_idb;
5570 wdh->subtype_write = blf_dump;
5571 wdh->subtype_finish = blf_dump_finish;
5572
5573 /* set up priv data */
5574 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
)))
;
5575 wdh->priv = writer_data;
5576
5577 /* set up and init interface mappings */
5578 writer_data->iface_to_channel_array = g_array_new(TRUE(!(0)), TRUE(!(0)), sizeof(blf_channel_to_iface_entry_t));
5579 blf_dump_expand_interface_mapping(wdh, wdh->interface_data->len);
5580 writer_data->iface_to_channel_names_recovered = false0;
5581
5582 writer_data->fileheader = NULL((void*)0);
5583 writer_data->object_count = 0;
5584 writer_data->start_time = 0;
5585 writer_data->end_time = 0;
5586
5587 writer_data->logcontainer_start = LOG_CONTAINER_NONE(18446744073709551615UL);
5588
5589 /* create the blf header structure and attach to wdh */
5590 if (!blf_init_file_header(wdh, err)) {
5591 blf_dump_free(wdh);
5592 return false0;
5593 }
5594
5595 /* write space in output file for header */
5596 if (!blf_write_file_header_zeros(wdh, err)) {
5597 blf_dump_free(wdh);
5598 return false0;
5599 }
5600
5601 ws_debug("wrote blf file header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5601, __func__, "wrote blf file header"); } } while (0)
;
5602
5603 /* Create first log_container */
5604 if (!blf_dump_start_logcontainer(wdh, err, err_info)) {
5605 blf_dump_free(wdh);
5606 return false0;
5607 }
5608
5609 if (!blf_dump_interface_setup(wdh, err)) {
5610 blf_dump_free(wdh);
5611 return false0;
5612 }
5613
5614 return true1;
5615}
5616
5617static const struct file_type_subtype_info blf_info = {
5618 "Vector Informatik Binary Logging Format (BLF) logfile", "blf", "blf", NULL((void*)0),
5619 true1, BLOCKS_SUPPORTED(blf_blocks_supported)(sizeof (blf_blocks_supported) / sizeof (blf_blocks_supported
)[0]), blf_blocks_supported
,
5620 blf_dump_can_write_encap, blf_dump_open, NULL((void*)0)
5621};
5622
5623void register_blf(void) {
5624
5625 blf_file_type_subtype = wtap_register_file_type_subtype(&blf_info);
5626
5627 /*
5628 * Register name for backwards compatibility with the
5629 * wtap_filetypes table in Lua.
5630 */
5631 wtap_register_backwards_compatibility_lua_name("BLF", blf_file_type_subtype);
5632}
5633
5634/*
5635 * Editor modelines - https://www.wireshark.org/tools/modelines.html
5636 *
5637 * Local variables:
5638 * c-basic-offset: 4
5639 * tab-width: 8
5640 * indent-tabs-mode: nil
5641 * End:
5642 *
5643 * vi: set shiftwidth=4 tabstop=8 expandtab:
5644 * :indentSize=4:tabSize=8:noTabs=true:
5645 */