Bug Summary

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