Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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