Bug Summary

File:wiretap/blf.c
Warning:line 5003, column 22
Value stored to 'chunk_size' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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