Bug Summary

File:wiretap/blf.c
Warning:line 3824, column 14
Potential leak of memory pointed to by 'newdata'

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