Bug Summary

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