Bug Summary

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