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-11-100357-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 if (channel == 0) {
4003 ws_warning("Trying to set channel to 0! That will probably lead to an unreadable file! Replacing by 1 to limit problem!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4003, __func__, "Trying to set channel to 0! That will probably lead to an unreadable file! Replacing by 1 to limit problem!"
); } } while (0)
;
4004 channel = 1;
4005 }
4006
4007 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4008
4009 blf_dump_expand_interface_mapping(wdh, interface_id + 1);
4010
4011 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)])
;
4012 tmp->channel = channel;
4013 tmp->hwchannel = hw_channel;
4014 tmp->interface_id = interface_id;
4015 tmp->pkt_encap = pkt_encap;
4016
4017 return true1;
4018}
4019
4020static blf_channel_to_iface_entry_t *
4021blf_dump_get_interface_mapping(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info) {
4022 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4023
4024 uint32_t interface_id = rec->rec_header.packet_header.interface_id;
4025 if (interface_id < writer_data->iface_to_channel_array->len) {
4026 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)])
;
4027 }
4028
4029 *err = WTAP_ERR_INTERNAL-21;
4030 *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)
;
4031 ws_critical("BLF Interface Mapping cannot be found!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_CRITICAL, "wiretap/blf.c"
, 4031, __func__, "BLF Interface Mapping cannot be found!"); }
} while (0)
;
4032
4033 return NULL((void*)0);
4034}
4035
4036static bool_Bool
4037blf_init_file_header(wtap_dumper *wdh, int *err) {
4038 if (wdh == NULL((void*)0) || wdh->priv == NULL((void*)0)) {
4039 *err = WTAP_ERR_INTERNAL-21;
4040 ws_debug("internal error: blf private data not found!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 4040, __func__, "internal error: blf private data not found!"
); } } while (0)
;
4041 return false0;
4042 }
4043
4044 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4045
4046 writer_data->fileheader = g_new0(blf_fileheader_t, 1)((blf_fileheader_t *) g_malloc0_n ((1), sizeof (blf_fileheader_t
)))
;
4047
4048 /* set magic */
4049 int i;
4050 for (i = 0; i < 4; i++) {
4051 writer_data->fileheader->magic[i] = blf_magic[i];
4052 }
4053
4054 /* currently only support 144 byte length*/
4055 writer_data->fileheader->header_length = 144;
4056
4057 writer_data->fileheader->application_major = WIRESHARK_VERSION_MAJOR4;
4058 writer_data->fileheader->application_minor = WIRESHARK_VERSION_MINOR7;
4059 writer_data->fileheader->application_build = WIRESHARK_VERSION_MICRO0;
4060
4061 return true1;
4062}
4063
4064static bool_Bool
4065blf_write_add_padding(wtap_dumper *wdh, int *err, uint8_t count) {
4066 if (count > 0 && count < 4) {
4067 uint8_t padding[3] = { 0 };
4068 if (!wtap_dump_file_write(wdh, &padding, count, err)) {
4069 return false0;
4070 }
4071 }
4072 return true1;
4073}
4074
4075static bool_Bool
4076blf_write_file_header_zeros(wtap_dumper *wdh, int *err) {
4077 /* lets add 144 bytes for the header and padding */
4078 uint8_t padding[144] = { 0 };
4079 if (!wtap_dump_file_write(wdh, &padding, 144, err)) {
4080 return false0;
4081 }
4082
4083 return true1;
4084}
4085
4086static void
4087blf_write_date_to_blf_header(blf_fileheader_t *fileheader, bool_Bool start, uint64_t ns_timestamp) {
4088 struct tm tmp;
4089 const time_t date = (time_t)(ns_timestamp / (1000 * 1000 * 1000));
4090
4091 if (ws_localtime_r(&date, &tmp) != NULL((void*)0)) {
4092 blf_date_t *target = start ? &(fileheader->start_date) : &(fileheader->end_date);
4093 target->year = 1900 + tmp.tm_year;
4094 target->month = tmp.tm_mon + 1;
4095 target->day = tmp.tm_mday;
4096 target->hour = tmp.tm_hour;
4097 target->mins = tmp.tm_min;
4098 target->sec = tmp.tm_sec;
4099
4100 uint64_t tmp_date = blf_get_start_offset_ns((const blf_date_t *)target);
4101
4102 target->ms = (uint16_t)((ns_timestamp - tmp_date) / (1000 * 1000));
4103 }
4104
4105}
4106
4107static bool_Bool
4108blf_finalize_file_header(wtap_dumper *wdh, int *err) {
4109 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4110 blf_fileheader_t *fileheader = writer_data->fileheader;
4111 int64_t bytes_written = wtap_dump_file_tell(wdh, err);
4112
4113 /* update the header and convert all to LE */
4114 fileheader->api_version = (((WIRESHARK_VERSION_MAJOR4 * 100) + WIRESHARK_VERSION_MINOR7) * 100 + WIRESHARK_VERSION_MICRO0) * 100;
4115 fileheader->application_major = WIRESHARK_VERSION_MAJOR4;
4116 fileheader->application_minor = WIRESHARK_VERSION_MINOR7;
4117 fileheader->application_build = WIRESHARK_VERSION_MICRO0;
4118
4119 fileheader->len_compressed = (uint64_t)bytes_written;
4120 fileheader->len_uncompressed = (uint64_t)bytes_written;
4121
4122 fileheader->obj_count = writer_data->object_count;
4123
4124 if (writer_data->start_time_set) {
4125 blf_write_date_to_blf_header(fileheader, true1, writer_data->start_time);
4126 }
4127
4128 blf_write_date_to_blf_header(fileheader, false0, writer_data->end_time);
4129
4130 fix_endianness_blf_fileheader(fileheader);
4131
4132 /* seek to start of file */
4133 int64_t tmp = wtap_dump_file_seek(wdh, 0, SEEK_SET0, err);
4134 if (*err != 0 || tmp != 0) {
4135 return false0;
4136 }
4137
4138 if (!wtap_dump_file_write(wdh, fileheader, fileheader->header_length, err)) {
4139 return false0;
4140 }
4141
4142 return true1;
4143}
4144
4145static bool_Bool blf_dump_write_logcontainer(wtap_dumper *wdh, int *err, char **err_info) {
4146 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4147
4148 if (!wtap_dump_file_write(wdh, &(writer_data->logcontainer_block_header), sizeof(blf_blockheader_t), err)) {
4149 *err = WTAP_ERR_INTERNAL-21;
4150 *err_info = ws_strdup_printf("blf: cannot write Log Container Block Header")wmem_strdup_printf(((void*)0), "blf: cannot write Log Container Block Header"
)
;
4151 ws_warning("Cannot write Log Container Block Header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4151, __func__, "Cannot write Log Container Block Header");
} } while (0)
;
4152 return false0;
4153 }
4154
4155 if (!wtap_dump_file_write(wdh, &(writer_data->logcontainer_header), sizeof(blf_logcontainerheader_t), err)) {
4156 *err = WTAP_ERR_INTERNAL-21;
4157 *err_info = ws_strdup_printf("blf: cannot write Log Container")wmem_strdup_printf(((void*)0), "blf: cannot write Log Container"
)
;
4158 ws_warning("Cannot write Log Container")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4158, __func__, "Cannot write Log Container"); } } while (0
)
;
4159 return false0;
4160 }
4161
4162 return true1;
4163}
4164
4165static bool_Bool blf_dump_close_logcontainer(wtap_dumper *wdh, int *err, char **err_info) {
4166 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4167
4168 int64_t current_position = wtap_dump_file_tell(wdh, err);
4169
4170 int64_t tmp = wtap_dump_file_seek(wdh, writer_data->logcontainer_start, SEEK_SET0, err);
4171 if (*err != 0 || tmp != 0) {
4172 return false0;
4173 }
4174
4175 int64_t logcontainer_length = current_position - writer_data->logcontainer_start;
4176 if (logcontainer_length < 32) {
4177 *err = WTAP_ERR_INTERNAL-21;
4178 }
4179 writer_data->logcontainer_block_header.object_length = GUINT32_TO_LE((uint32_t)logcontainer_length)((guint32) ((uint32_t)logcontainer_length));
4180 writer_data->logcontainer_header.uncompressed_size = GUINT32_TO_LE((uint32_t)(logcontainer_length - 32))((guint32) ((uint32_t)(logcontainer_length - 32)));
4181
4182 if (!blf_dump_write_logcontainer(wdh, err, err_info)) {
4183 return false0;
4184 }
4185
4186 tmp = wtap_dump_file_seek(wdh, current_position, SEEK_SET0, err);
4187 if (*err != 0 || tmp != 0) {
4188 return false0;
4189 }
4190
4191 return true1;
4192}
4193
4194static bool_Bool blf_dump_start_logcontainer(wtap_dumper *wdh, int *err, char **err_info) {
4195 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4196
4197 if (writer_data->logcontainer_start != LOG_CONTAINER_NONE(18446744073709551615UL)) {
4198 if (!blf_dump_close_logcontainer(wdh, err, err_info)) {
4199 return false0;
4200 }
4201 }
4202
4203 /* start new log container */
4204 /* set magic */
4205 int i;
4206 for (i = 0; i < 4; i++) {
4207 writer_data->logcontainer_block_header.magic[i] = blf_obj_magic[i];
4208 }
4209 writer_data->logcontainer_block_header.header_length = 16;
4210 writer_data->logcontainer_block_header.header_type = 1;
4211 writer_data->logcontainer_block_header.object_length = 32;
4212 writer_data->logcontainer_block_header.object_type = BLF_OBJTYPE_LOG_CONTAINER10;
4213 fix_endianness_blf_blockheader(&(writer_data->logcontainer_block_header));
4214
4215 writer_data->logcontainer_header.compression_method = 0;
4216 writer_data->logcontainer_header.res1 = 0;
4217 writer_data->logcontainer_header.res2 = 0;
4218 writer_data->logcontainer_header.uncompressed_size = 0;
4219 writer_data->logcontainer_header.res4 = 0;
4220 fix_endianness_blf_logcontainerheader(&(writer_data->logcontainer_header));
4221
4222 writer_data->logcontainer_start = wtap_dump_file_tell(wdh, err);
4223
4224 return blf_dump_write_logcontainer(wdh, err, err_info);
4225}
4226
4227static bool_Bool blf_dump_check_logcontainer_full(wtap_dumper *wdh, int *err, char **err_info, uint32_t length) {
4228 const blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4229
4230 uint64_t position = (uint64_t)wtap_dump_file_tell(wdh, err);
4231 if (position - writer_data->logcontainer_start + length <= LOG_CONTAINER_BUFFER_SIZE10485760) {
4232 return true1;
4233 }
4234
4235 return blf_dump_start_logcontainer(wdh, err, err_info);
4236}
4237
4238static bool_Bool blf_dump_objheader(wtap_dumper *wdh, int *err, uint64_t obj_timestamp, uint32_t obj_type, uint32_t obj_length) {
4239 blf_logobjectheader_t logheader;
4240 logheader.flags = BLF_TIMESTAMP_RESOLUTION_1NS2;
4241 logheader.client_index = 0;
4242 logheader.object_version = 1;
4243 logheader.object_timestamp = obj_timestamp;
4244 fix_endianness_blf_logobjectheader(&logheader);
4245
4246 blf_blockheader_t blockheader;
4247 /* set magic */
4248 int i;
4249 for (i = 0; i < 4; i++) {
4250 blockheader.magic[i] = blf_obj_magic[i];
4251 }
4252 blockheader.header_length = sizeof(blf_blockheader_t) + sizeof(blf_logobjectheader_t);
4253 blockheader.header_type = 1;
4254 blockheader.object_length = sizeof(blf_blockheader_t) + sizeof(blf_logobjectheader_t) + obj_length;
4255 blockheader.object_type = obj_type;
4256 fix_endianness_blf_blockheader(&blockheader);
4257
4258 if (!wtap_dump_file_write(wdh, &(blockheader), sizeof(blf_blockheader_t), err)) {
4259 return false0;
4260 }
4261
4262 if (!wtap_dump_file_write(wdh, &(logheader), sizeof(blf_logobjectheader_t), err)) {
4263 return false0;
4264 }
4265
4266 return true1;
4267}
4268
4269/* return standard direction format of BLF, RX on error or unknown */
4270static uint8_t blf_get_direction(const wtap_rec *rec) {
4271 uint32_t tmp_direction = 0;
4272 if (WTAP_OPTTYPE_SUCCESS != wtap_block_get_uint32_option_value(rec->block, OPT_PKT_FLAGS2, &tmp_direction)) {
4273 return BLF_DIR_RX0;
4274 }
4275
4276 if (tmp_direction == PACK_FLAGS_DIRECTION_OUTBOUND2) {
4277 return BLF_DIR_TX1;
4278
4279 }
4280
4281 return BLF_DIR_RX0;
4282}
4283
4284static bool_Bool blf_dump_ethernet(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4285 /* LINKTYPE_ETHERNET */
4286 /* https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html */
4287
4288 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4289 const blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4290
4291 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4292 size_t length = ws_buffer_length(&rec->data);
4293
4294 /* 14 bytes is the full Ethernet Header up to EtherType */
4295 if (length < 14) {
4296 *err = WTAP_ERR_INTERNAL-21;
4297 *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)
;
4298 ws_warning("LINKTYPE_ETHERNET Data is too short!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4298, __func__, "LINKTYPE_ETHERNET Data is too short!"); } }
while (0)
;
4299 return false0;
4300 }
4301
4302 uint32_t offset = 12;
4303
4304 blf_ethernetframeheader_t ethheader;
4305 ethheader.src_addr[0] = pd[6];
4306 ethheader.src_addr[1] = pd[7];
4307 ethheader.src_addr[2] = pd[8];
4308 ethheader.src_addr[3] = pd[9];
4309 ethheader.src_addr[4] = pd[10];
4310 ethheader.src_addr[5] = pd[11];
4311
4312 ethheader.channel = iface_entry->channel;
4313
4314 ethheader.dst_addr[0] = pd[0];
4315 ethheader.dst_addr[1] = pd[1];
4316 ethheader.dst_addr[2] = pd[2];
4317 ethheader.dst_addr[3] = pd[3];
4318 ethheader.dst_addr[4] = pd[4];
4319 ethheader.dst_addr[5] = pd[5];
4320
4321 ethheader.direction = blf_get_direction(rec);
4322
4323 uint16_t eth_type = pntohu16(pd + offset);
4324 offset += 2;
4325
4326 if (eth_type == 0x8100 || eth_type == 0x9100 || eth_type == 0x88a8) {
4327 ethheader.tpid = eth_type;
4328 ethheader.tci = pntohu16(pd + offset);
4329 offset += 2;
4330
4331 eth_type = pntohu16(pd + offset);
4332 offset += 2;
4333 } else {
4334 ethheader.tpid = 0;
4335 ethheader.tci = 0;
4336 }
4337
4338 ethheader.ethtype = eth_type;
4339 ethheader.payloadlength = rec->rec_header.packet_header.caplen - offset;
4340 ethheader.res = 0;
4341 fix_endianness_blf_ethernetframeheader(&ethheader);
4342
4343 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_ETHERNET_FRAME71, sizeof(blf_ethernetframeheader_t) + ethheader.payloadlength)) {
4344 return false0;
4345 }
4346
4347 if (!wtap_dump_file_write(wdh, &(ethheader), sizeof(blf_ethernetframeheader_t), err)) {
4348 return false0;
4349 }
4350
4351 if (!wtap_dump_file_write(wdh, &(pd[offset]), ethheader.payloadlength, err)) {
4352 return false0;
4353 }
4354
4355 /* Add strange padding to 4 bytes. */
4356 uint8_t padding_needed = (sizeof(blf_ethernetframeheader_t) + ethheader.payloadlength) % 4;
4357 return blf_write_add_padding(wdh, err, padding_needed);
4358}
4359
4360static 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,
4361 const uint8_t *pd, size_t length, bool_Bool is_rx, bool_Bool is_tx) {
4362 /* LINKTYPE_CAN_SOCKETCAN */
4363 /* https://www.tcpdump.org/linktypes/LINKTYPE_CAN_SOCKETCAN.html */
4364
4365 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4366 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4367
4368 uint8_t socketcan_vcid = pd[1];
4369 uint16_t socketcan_id = pntohu16(pd + 2) & CAN_SFF_MASK0x000007FF;
4370 uint8_t socketcan_flags = pd[4];
4371 uint8_t socketcan_sdut = pd[5];
4372 uint16_t socketcan_payload_length = pletohu16(pd + 6);
4373
4374 if ((socketcan_flags & CANXL_XLF0x80) != CANXL_XLF0x80) {
4375 *err = WTAP_ERR_INTERNAL-21;
4376 *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!"
)
;
4377 ws_error("LINKTYPE_CAN_SOCKETCAN CAN XL flag not set for CAN XL?")ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/blf.c"
, 4377, __func__, "LINKTYPE_CAN_SOCKETCAN CAN XL flag not set for CAN XL?"
)
;
4378 return false0;
4379 }
4380
4381 if (length < (size_t)socketcan_payload_length + 12) {
4382 *err = WTAP_ERR_INTERNAL-21;
4383 *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)
;
4384 ws_error("LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL)!")ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/blf.c"
, 4384, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short (CAN XL)!"
)
;
4385 return false0;
4386 }
4387 uint32_t socketcan_acceptance_field = pletohu32(pd + 8);
4388
4389 /* LINKTYPE_LINUX_SLL would have set is_tx or is_rx */
4390 uint8_t frame_dir = is_tx ? BLF_DIR_TX1 : BLF_DIR_RX0;
4391 if (!is_rx && !is_tx) {
4392 frame_dir = blf_get_direction(rec);
4393 }
4394
4395 blf_canxlchannelframe_t canxl = {0};
4396 canxl.channel = (uint8_t)iface_entry->channel;
4397 canxl.dir = frame_dir;
4398 canxl.frameIdentifier = socketcan_id;
4399 canxl.serviceDataUnitType = socketcan_sdut;
4400 canxl.dlc = socketcan_payload_length - 1;
4401 canxl.dataLength = socketcan_payload_length;
4402 canxl.virtualControllerAreaNetChannelID = socketcan_vcid;
4403 canxl.acceptanceField = socketcan_acceptance_field;
4404
4405 if ((socketcan_flags & CANXL_XLF0x80) == CANXL_XLF0x80) {
4406 /* should be always true but we might refactor */
4407 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_XLF0x400000;
4408 }
4409 if ((socketcan_flags & CANXL_SEC0x01) == CANXL_SEC0x01) {
4410 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_SEC0x1000000;
4411 }
4412 if ((socketcan_flags & CANXL_RRS0x02) == CANXL_RRS0x02) {
4413 canxl.flags |= BLF_CANXLCHANNELFRAME_FLAG_RRS0x800000;
4414 }
4415
4416 fix_endianness_blf_canxlchannelframe(&canxl);
4417
4418 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_XL_CHANNEL_FRAME139, sizeof(blf_canxlchannelframe_t) + socketcan_payload_length)) {
4419 return false0;
4420 }
4421
4422 if (!wtap_dump_file_write(wdh, &(canxl), sizeof(blf_canxlchannelframe_t), err)) {
4423 return false0;
4424 }
4425
4426 if (!wtap_dump_file_write(wdh, &(pd[12]), socketcan_payload_length, err)) {
4427 return false0;
4428 }
4429
4430 return true1;
4431}
4432
4433static const uint8_t canfd_length_to_dlc[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 9, 0, 0, 0,
4434 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
4435 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4436 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4437 15 };
4438
4439static bool_Bool blf_dump_socketcan(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp,
4440 const uint8_t *pd, size_t length, bool_Bool is_can, bool_Bool is_canfd, bool_Bool is_rx, bool_Bool is_tx) {
4441 /* LINKTYPE_CAN_SOCKETCAN */
4442 /* https://www.tcpdump.org/linktypes/LINKTYPE_CAN_SOCKETCAN.html */
4443
4444 if (length < 8) {
4445 *err = WTAP_ERR_INTERNAL-21;
4446 *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)
;
4447 ws_warning("LINKTYPE_CAN_SOCKETCAN header is too short!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4447, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short!"
); } } while (0)
;
4448 return false0;
4449 }
4450
4451 /* check for CAN-XL */
4452 if ((pd[4] & CANXL_XLF0x80) == CANXL_XLF0x80) {
4453 return blf_dump_socketcanxl(wdh, rec, err, err_info, obj_timestamp, pd, length, is_rx, is_tx);
4454 }
4455
4456 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4457 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4458
4459 uint8_t payload_length = pd[4];
4460
4461 if (length < (size_t)payload_length + 8) {
4462 *err = WTAP_ERR_INTERNAL-21;
4463 *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)
;
4464 ws_warning("LINKTYPE_CAN_SOCKETCAN header is too short!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4464, __func__, "LINKTYPE_CAN_SOCKETCAN header is too short!"
); } } while (0)
;
4465 return false0;
4466 }
4467
4468 /* LINKTYPE_LINUX_SLL would have set is_tx or is_rx */
4469 uint8_t frame_dir = is_tx ? BLF_DIR_TX1 : BLF_DIR_RX0;
4470 if (!is_rx && !is_tx) {
4471 frame_dir = blf_get_direction(rec);
4472 }
4473
4474 bool_Bool canfd = is_canfd;
4475
4476 /* LINKTYPE_LINUX_SLL would have set one */
4477 if (!is_can && !is_canfd) {
4478 if ((pd[5] & CANFD_FDF0x04) == CANFD_FDF0x04) {
4479 canfd = true1;
4480 } else {
4481 /* heuristic. if longer than header + 8 bytes data, its CAN-FD*/
4482 canfd = rec->rec_header.packet_header.caplen > 16;
4483 }
4484 }
4485
4486 /* XXX endianess is not defined. Assuming BE as this seems the common choice*/
4487 uint32_t can_id = pntohu32(pd);
4488
4489 /* lets check if can_id makes sense
4490 * 29bit CAN ID mask 0x1fffffff CAN_EFF_MASK
4491 * 11bit CAN ID mask 0x000007ff CAN_SFF_MASK
4492 * 29 only bits 0x1ffff800 CAN_EFF_MASK & !CAN_SFF_MASK
4493 */
4494 if (((can_id & CAN_EFF_FLAG0x80000000) == 0) && ((can_id & (CAN_EFF_MASK0x1FFFFFFF & (!CAN_SFF_MASK0x000007FF))) != 0)) {
4495 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)
;
4496 can_id = pletohu32(pd);
4497 }
4498
4499 bool_Bool err_flag = (can_id & CAN_ERR_FLAG0x20000000) == CAN_ERR_FLAG0x20000000;
4500 bool_Bool rtr_flag = (can_id & CAN_RTR_FLAG0x40000000) == CAN_RTR_FLAG0x40000000;
4501 //bool ext_id_flag = (can_id & CAN_EFF_FLAG) == CAN_EFF_FLAG;
4502 can_id &= (CAN_EFF_MASK0x1FFFFFFF | CAN_EFF_FLAG0x80000000);
4503
4504 if (canfd) {
4505 /* CAN-FD */
4506 bool_Bool brs_flag = (pd[5] & CANFD_BRS0x01) == CANFD_BRS0x01;
4507 bool_Bool esi_flag = (pd[5] & CANFD_ESI0x02) == CANFD_ESI0x02;
4508 bool_Bool fdf_flag = (pd[5] & CANFD_FDF0x04) == CANFD_FDF0x04;
4509
4510 blf_canfdmessage64_t canfdmsg;
4511 canfdmsg.channel = (uint8_t)iface_entry->channel;
4512
4513 canfdmsg.dlc = (payload_length <= 64) ? canfd_length_to_dlc[payload_length] : 0;
4514 canfdmsg.validDataBytes = payload_length;
4515 canfdmsg.txCount = 0;
4516 canfdmsg.id = can_id;
4517 canfdmsg.frameLength_in_ns = 0;
4518 canfdmsg.flags = 0;
4519
4520 /* TODO: fdf_flag is not always set for CAN-FD */
4521 if (fdf_flag) {
4522 canfdmsg.flags = BLF_CANFDMESSAGE64_FLAG_EDL0x001000; // CAN-FD
4523 } else {
4524 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"
, 4524, __func__, "CAN-FD has not CANFD_FDF set. File not correct."
); } } while (0)
;
4525 }
4526 if (brs_flag) {
4527 canfdmsg.flags |= BLF_CANFDMESSAGE64_FLAG_BRS0x002000;
4528 }
4529 if (esi_flag) {
4530 canfdmsg.flags |= BLF_CANFDMESSAGE64_FLAG_ESI0x004000;
4531 }
4532
4533 canfdmsg.btrCfgArb = 0;
4534 canfdmsg.btrCfgData = 0;
4535 canfdmsg.timeOffsetBrsNs = 0;
4536 canfdmsg.timeOffsetCrcDelNs = 0;
4537 canfdmsg.bitCount = 0;
4538 canfdmsg.dir = frame_dir;
4539 canfdmsg.extDataOffset = 0;
4540 canfdmsg.crc = 0;
4541
4542 fix_endianness_blf_canfdmessage64(&canfdmsg);
4543
4544 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_FD_MESSAGE_64101, sizeof(blf_canfdmessage64_t) + payload_length)) {
4545 return false0;
4546 }
4547
4548 if (!wtap_dump_file_write(wdh, &(canfdmsg), sizeof(blf_canfdmessage64_t), err)) {
4549 return false0;
4550 }
4551 } else {
4552 /* CAN */
4553 blf_canmessage_t canmsg;
4554
4555 if (payload_length > 8) {
4556 ws_warning("CAN frames can only have up to 8 bytes of payload! We have %d bytes", payload_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4556, __func__, "CAN frames can only have up to 8 bytes of payload! We have %d bytes"
, payload_length); } } while (0)
;
4557 payload_length = 8;
4558 }
4559
4560 canmsg.dlc = payload_length;
4561 canmsg.channel = iface_entry->channel;
4562
4563 canmsg.flags = 0;
4564 if (frame_dir == BLF_DIR_TX1) {
4565 canmsg.flags |= BLF_CANMESSAGE_FLAG_TX0x01;
4566 }
4567
4568 if (err_flag) {
4569 // TODO: we need to implement CAN ERROR, ignore for now
4570 return true1;
4571 //canmsg.flags |= BLF_CANMESSAGE_FLAG_NERR; - NERR is not error
4572 }
4573
4574 if (rtr_flag) {
4575 canmsg.flags |= BLF_CANMESSAGE_FLAG_RTR0x80;
4576 }
4577
4578 canmsg.id = can_id;
4579
4580 fix_endianness_blf_canmessage(&canmsg);
4581
4582 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_CAN_MESSAGE1, sizeof(blf_canmessage_t) + 8)) {
4583 return false0;
4584 }
4585
4586 if (!wtap_dump_file_write(wdh, &(canmsg), sizeof(blf_canmessage_t), err)) {
4587 return false0;
4588 }
4589 }
4590
4591 if (!wtap_dump_file_write(wdh, &(pd[8]), payload_length, err)) {
4592 return false0;
4593 }
4594
4595 if (!canfd && payload_length < 8) {
4596 uint8_t padding[8] = { 0 };
4597 if (!wtap_dump_file_write(wdh, &padding, 8 - payload_length, err)) {
4598 return false0;
4599 }
4600 }
4601
4602 /* no padding */
4603
4604 return true1;
4605}
4606
4607static bool_Bool blf_dump_sll(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4608 /* Linux Cooked CAN / CAN-FD */
4609 /* https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html */
4610
4611 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4612 size_t length = ws_buffer_length(&rec->data);
4613
4614 if (length < 16) {
4615 *err = WTAP_ERR_INTERNAL-21;
4616 *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)
;
4617 ws_warning("LINKTYPE_LINUX_SLL header is too short!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4617, __func__, "LINKTYPE_LINUX_SLL header is too short!");
} } while (0)
;
4618 return false0;
4619 }
4620
4621 bool_Bool frame_tx = false0;
4622 if (pd[0] == 0 && pd[1] == 4) {
4623 frame_tx = true1;
4624 }
4625
4626 uint16_t protocol_type = pntohu16(pd + 14);
4627
4628 switch (protocol_type) {
4629 case 0x000C: /* CAN */
4630 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, true1, false0, !frame_tx, frame_tx);
4631 break;
4632 case 0x000D: /* CAN-FD */
4633 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, false0, true1, !frame_tx, frame_tx);
4634 break;
4635 case 0x000E: /* CAN-XL */
4636 return blf_dump_socketcanxl(wdh, rec, err, err_info, obj_timestamp, &(pd[16]), length - 16, !frame_tx, frame_tx);
4637 break;
4638 default:
4639 return false0;
4640 }
4641
4642 /* not reachable? */
4643 return true1;
4644}
4645
4646static bool_Bool blf_dump_flexray(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4647 /* FlexRay */
4648 /* https://www.tcpdump.org/linktypes/LINKTYPE_FLEXRAY.html */
4649
4650 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4651 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4652
4653 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4654 size_t length = ws_buffer_length(&rec->data);
4655
4656 if (length < 1) {
4657 *err = WTAP_ERR_INTERNAL-21;
4658 *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)
;
4659 ws_warning("LINKTYPE_FLEXRAY header is too short (< 1 Byte)!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4659, __func__, "LINKTYPE_FLEXRAY header is too short (< 1 Byte)!"
); } } while (0)
;
4660 return false0;
4661 }
4662
4663 /* Check Measurement Header for Type */
4664 if ((pd[0] & FLEXRAY_TYPE_MASK0x7f) == FLEXRAY_SYMBOL0x02) {
4665 /* Symbol */
4666
4667 if (length < 2) {
4668 *err = WTAP_ERR_INTERNAL-21;
4669 *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)
;
4670 ws_warning("LINKTYPE_FLEXRAY Symbol is too short (< 2 Byte)!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4670, __func__, "LINKTYPE_FLEXRAY Symbol is too short (< 2 Byte)!"
); } } while (0)
;
4671 return false0;
4672 }
4673
4674 /* TODO: SYMBOL */
4675
4676 return true1;
4677 }
4678
4679 if ((pd[0] & FLEXRAY_TYPE_MASK0x7f) == FLEXRAY_FRAME0x01) {
4680 /* Frame */
4681
4682 if (length < 2 + FLEXRAY_HEADER_LENGTH5) {
4683 *err = WTAP_ERR_INTERNAL-21;
4684 *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)
;
4685 ws_warning("LINKTYPE_FLEXRAY Frame Header is too short (< 7 Byte)!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4685, __func__, "LINKTYPE_FLEXRAY Frame Header is too short (< 7 Byte)!"
); } } while (0)
;
4686 return false0;
4687 }
4688
4689 uint8_t payload_length = pd[4] & FLEXRAY_LENGTH_MASK0xfe;
4690
4691 /* FLEXRAY FRAME */
4692 blf_flexrayrcvmessage_t frmsg;
4693
4694 frmsg.channel = (uint16_t)iface_entry->channel;
4695 frmsg.version = 1;
4696
4697 uint32_t header_crc = (pntohu24(pd + 4) & FLEXRAY_HEADER_CRC_MASK0x01ffc0) >> FLEXRAY_HEADER_CRC_SHFT6;
4698
4699 if ((pd[0] & FLEXRAY_CHANNEL_MASK0x80) == 0) {
4700 frmsg.channelMask = BLF_FLEXRAYRCVMSG_CHANNELMASK_A0x01;
4701 frmsg.headerCrc1 = header_crc;
4702 frmsg.headerCrc2 = 0;
4703 } else {
4704 frmsg.channelMask = BLF_FLEXRAYRCVMSG_CHANNELMASK_B0x02;
4705 frmsg.headerCrc1 = 0;
4706 frmsg.headerCrc2 = header_crc;
4707 }
4708
4709 frmsg.dir = blf_get_direction(rec);
4710 frmsg.clientIndex = 0;
4711 frmsg.clusterNo = 0;
4712 frmsg.frameId = (pntohu16(pd + 2)) & FLEXRAY_ID_MASK0x07ff;
4713 frmsg.payloadLength = payload_length;
4714 frmsg.payloadLengthValid = payload_length;
4715 frmsg.cycle = pd[6] & FLEXRAY_CC_MASK0x3f;
4716 frmsg.tag = 0;
4717 frmsg.data = 0;
4718 frmsg.frameFlags = 0;
4719
4720 /* The NULL Flag 1 -> False */
4721 bool_Bool null_frame = (pd[2] & FLEXRAY_NFI_MASK0x20) != FLEXRAY_NFI_MASK0x20;
4722
4723 if (null_frame) {
4724 frmsg.frameFlags &= BLF_FLEXRAYRCVMSG_FRAME_FLAG_NULL_FRAME0x00000001;
4725 /* LINKTYPE_FLEXRAY has no payload for Null Frames present */
4726 payload_length = 0;
4727 }
4728
4729 /* TODO: check truncated data */
4730 if (payload_length > 0) {
4731 /* Data Valid*/
4732 frmsg.frameFlags &= BLF_FLEXRAYRCVMSG_FRAME_FLAG_VALID_DATA0x00000002;
4733 }
4734
4735 if ((pd[2] & FLEXRAY_SFI_MASK0x10) == FLEXRAY_SFI_MASK0x10) {
4736 frmsg.frameFlags &= BLF_FLEXRAYRCVMSG_FRAME_FLAG_SYNC0x00000004;
4737 }
4738
4739 if ((pd[2] & FLEXRAY_STFI_MASK0x08) == FLEXRAY_STFI_MASK0x08) {
4740 frmsg.frameFlags &= BLF_FLEXRAYRCVMSG_FRAME_FLAG_STARTUP0x00000008;
4741 }
4742
4743 if ((pd[2] & FLEXRAY_PPI_MASK0x40) == FLEXRAY_PPI_MASK0x40) {
4744 frmsg.frameFlags &= BLF_FLEXRAYRCVMSG_FRAME_FLAG_PAYLOAD_PREAM0x00000010;
4745 }
4746
4747 if ((pd[2] & FLEXRAY_RES_MASK0x80) == FLEXRAY_RES_MASK0x80) {
4748 frmsg.frameFlags &= BLF_FLEXRAYRCVMSG_FRAME_FLAG_RES_200x00000020;
4749 }
4750
4751 /* if any error flag is set */
4752 if ((pd[1] & FLEXRAY_ERRORS_DEFINED0x1f) != 0x00) {
4753 frmsg.frameFlags &= BLF_FLEXRAYRCVMSG_FRAME_FLAG_ERROR0x00000040;
4754 }
4755
4756 /* Not sure how to determine this as we do not know the low level parameters */
4757 //if ( ) {
4758 // /* DYNAMIC SEG =1 (Bit 20)*/
4759 // frmsg.frameFlags &= 0x100000;
4760 //}
4761
4762 frmsg.appParameter = 0;
4763
4764 fix_endianness_blf_flexrayrcvmessage(&frmsg);
4765
4766 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_FLEXRAY_RCVMESSAGE50, sizeof(blf_flexrayrcvmessage_t) + 254)) {
4767 return false0;
4768 }
4769
4770 if (!wtap_dump_file_write(wdh, &(frmsg), sizeof(blf_flexrayrcvmessage_t), err)) {
4771 return false0;
4772 }
4773
4774 if (length < (size_t)payload_length + 2 + FLEXRAY_HEADER_LENGTH5) {
4775 *err = WTAP_ERR_INTERNAL-21;
4776 *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)
;
4777 ws_warning("LINKTYPE_FLEXRAY Frame truncated!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4777, __func__, "LINKTYPE_FLEXRAY Frame truncated!"); } } while
(0)
;
4778 return false0;
4779 }
4780
4781 if (payload_length > 0) {
4782 if (!wtap_dump_file_write(wdh, &(pd[7]), payload_length, err)) {
4783 return false0;
4784 }
4785 }
4786
4787 const uint8_t zero_bytes[256] = { 0 };
4788
4789 if (payload_length < 254) {
4790 if (!wtap_dump_file_write(wdh, &zero_bytes[0], 254 - payload_length, err)) {
4791 return false0;
4792 }
4793 }
4794
4795 return true1;
4796 }
4797
4798 /* no padding */
4799
4800 return true1;
4801}
4802
4803static bool_Bool blf_dump_lin(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4804 /* LIN */
4805 /* https://www.tcpdump.org/linktypes/LINKTYPE_LIN.html */
4806
4807 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4808 blf_channel_to_iface_entry_t *iface_entry = blf_dump_get_interface_mapping(wdh, rec, err, err_info);
4809
4810 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4811 size_t length = ws_buffer_length(&rec->data);
4812
4813 if (length < 8) {
4814 *err = WTAP_ERR_INTERNAL-21;
4815 *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)
;
4816 ws_warning("LIN Data is too short (less than 8 bytes)!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4816, __func__, "LIN Data is too short (less than 8 bytes)!"
); } } while (0)
;
4817 return false0;
4818 }
4819
4820 uint8_t lin_err = pd[7] & 0x3f;
4821 if (lin_err != 0) {
4822 // TODO: handle LIN errors
4823 return true1;
4824 }
4825
4826 int i;
4827 uint8_t dlc = (pd[4] & LIN_PAYLOAD_LENGTH_MASK0xf0) >> 4;
4828 uint8_t msg_type = (pd[4] & LIN_MSG_TYPE_MASK0x0c) >> 2;
4829
4830 if (msg_type != LIN_MSG_TYPE_FRAME0) {
4831 // TODO: handle LIN events
4832 return true1;
4833 }
4834
4835 /* we need to have at least the data */
4836 if (length < (size_t)dlc + 8) {
4837 *err = WTAP_ERR_INTERNAL-21;
4838 *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)
;
4839 ws_error("LIN Data is too short (less than needed)!")ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/blf.c"
, 4839, __func__, "LIN Data is too short (less than needed)!"
)
;
4840 return false0;
4841 }
4842
4843 /* we ignore padding as we do not need it anyhow */
4844
4845 blf_linmessage_t linmsg;
4846 linmsg.channel = (uint16_t)iface_entry->channel;
4847 linmsg.id = pd[5];
4848 linmsg.dlc = dlc;
4849 for (i = 0; i < 8; i++) {
4850 if (i < dlc) {
4851 linmsg.data[i] = pd[i + 8];
4852 } else {
4853 linmsg.data[i] = 0;
4854 }
4855 }
4856 linmsg.fsmId = 0;
4857 linmsg.fsmState = 0;
4858 linmsg.headerTime = 0;
4859 linmsg.fullTime = 0;
4860 linmsg.crc = pd[6];
4861 linmsg.dir = blf_get_direction(rec);
4862 linmsg.res1 = 0;
4863
4864 fix_endianness_blf_linmessage(&linmsg);
4865
4866 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_LIN_MESSAGE11, sizeof(blf_linmessage_t) + 4)) {
4867 return false0;
4868 }
4869
4870 if (!wtap_dump_file_write(wdh, &(linmsg), sizeof(blf_linmessage_t), err)) {
4871 return false0;
4872 }
4873
4874 uint8_t rest_of_header[4] = { 0, 0, 0, 0};
4875
4876 if (!wtap_dump_file_write(wdh, &(rest_of_header), 4, err)) {
4877 return false0;
4878 }
4879
4880 /* no padding! */
4881
4882 return true1;
4883}
4884
4885static bool_Bool blf_dump_upper_pdu(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info, uint64_t obj_timestamp) {
4886 const blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
4887
4888 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
4889 size_t length = ws_buffer_length(&rec->data);
4890
4891 unsigned tag_diss_pos = 0;
4892 size_t tag_diss_len = 0;
4893 unsigned col_proto_pos = 0;
4894 size_t col_proto_len = 0;
4895 unsigned col_info_pos = 0;
4896 size_t col_info_len = 0;
4897
4898 /* parse the tags */
4899 size_t pos = 0;
4900 bool_Bool done = false0;
4901 while (!done) {
4902 if (length - pos < 4) {
4903 *err = WTAP_ERR_INTERNAL-21;
4904 *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)
;
4905 ws_warning("Upper PDU has truncated tags!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4905, __func__, "Upper PDU has truncated tags!"); } } while
(0)
;
4906 return false0;
4907 }
4908
4909 uint16_t tag_type = pntohu16(pd + pos);
4910 uint16_t tag_len = pntohu16(pd + pos + 2);
4911
4912 if ((length - pos) < (size_t)tag_len + 4) {
4913 *err = WTAP_ERR_INTERNAL-21;
4914 *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)
;
4915 ws_warning("Upper PDU has truncated tags!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4915, __func__, "Upper PDU has truncated tags!"); } } while
(0)
;
4916 return false0;
4917 }
4918
4919 switch (tag_type) {
4920 case EXP_PDU_TAG_DISSECTOR_NAME12:
4921 tag_diss_pos = (unsigned)pos + 4;
4922 tag_diss_len = tag_len;
4923 break;
4924
4925 case EXP_PDU_TAG_COL_PROT_TEXT33:
4926 col_proto_pos = (unsigned)pos + 4;
4927 col_proto_len = tag_len;
4928 break;
4929
4930 case EXP_PDU_TAG_COL_INFO_TEXT36:
4931 col_info_pos = (unsigned)pos + 4;
4932 col_info_len = tag_len;
4933 break;
4934
4935 case EXP_PDU_TAG_END_OF_OPT0:
4936 done = true1;
4937 break;
4938 }
4939
4940 pos += 4;
4941 pos += tag_len;
4942 }
4943
4944 /* strip zero termination, if existing */
4945 while (pd[tag_diss_pos + tag_diss_len - 1] == 0) {
4946 tag_diss_len -= 1;
4947 }
4948
4949 while (pd[col_proto_pos + col_proto_len - 1] == 0) {
4950 col_proto_len -= 1;
4951 }
4952
4953 while (pd[col_info_pos + col_info_len - 1] == 0) {
4954 col_info_len -= 1;
4955 }
4956
4957 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)) {
4958 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)) {
4959 blf_apptext_t apptext_header;
4960 apptext_header.source = BLF_APPTEXT_METADATA0x00000002;
4961 apptext_header.reservedAppText1 = 0;
4962 apptext_header.reservedAppText2 = 412; /* not sure what to put in but this is commonly used!? */
4963 uint32_t payload_len = (uint32_t)(length - pos);
4964 apptext_header.textLength = payload_len;
4965
4966 /* Metadata */
4967 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, BLF_APPTEXT_COL_INFO_TEXT_... */
4968 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)) {
4969 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_GENERAL */
4970 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_GENERAL0x01 << 24) | (0xffffff & payload_len);
4971 } 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)) {
4972 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_CHANNELS */
4973 if (writer_data->iface_to_channel_names_recovered) {
4974 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_CHANNELS0x02 << 24) | (0xffffff & payload_len);
4975 }
4976 } 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)) {
4977 /* BLF_APPTEXT_METADATA: BLF_APPTEXT_XML_IDENTITY */
4978 apptext_header.reservedAppText1 = (BLF_APPTEXT_XML_IDENTITY0x03 << 24) | (0xffffff & payload_len);
4979
4980 // else if
4981 /* BLF_APPTEXT_COMMENT */
4982 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Comment: %s" */
4983 // TODO } else {
4984 // else if
4985 /* BLF_APPTEXT_ATTACHMENT */
4986 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Attachment: %s" */
4987 // TODO } else {
4988 // else if
4989 /* BLF_APPTEXT_TRACELINE */
4990 /* tags: BLF_APPTEXT_TAG_DISS_DEFAULT, BLF_APPTEXT_COL_PROT_TEXT, "Trace line%s: %s" */
4991 // TODO
4992 } else {
4993 return true1; /* just leave */
4994 }
4995
4996 if (payload_len > 2048 && (apptext_header.source != BLF_APPTEXT_METADATA0x00000002)) {
4997 ws_warning("Only Meta Data can be broken into smaller chunks!")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/blf.c"
, 4997, __func__, "Only Meta Data can be broken into smaller chunks!"
); } } while (0)
;
4998 }
4999
5000 uint32_t chunk_size = payload_len;
5001 bool_Bool last_round = false0;
5002 do {
5003 if (payload_len > 2048 && apptext_header.source == BLF_APPTEXT_METADATA0x00000002) {
5004 chunk_size = 2048;
5005 } else {
5006 chunk_size = payload_len;
5007 last_round = true1;
5008 }
5009
5010 if (!blf_dump_objheader(wdh, err, obj_timestamp, BLF_OBJTYPE_APP_TEXT65, sizeof(blf_apptext_t) + chunk_size)) {
5011 return false0;
5012 }
5013
5014 if (apptext_header.source == BLF_APPTEXT_METADATA0x00000002) {
5015 apptext_header.reservedAppText1 = (0xff000000 & apptext_header.reservedAppText1) | (0x00ffffff & payload_len);
5016 }
5017
5018 apptext_header.textLength = chunk_size;
5019 fix_endianness_blf_apptext_header(&apptext_header);
5020 if (!wtap_dump_file_write(wdh, &(apptext_header), sizeof(blf_apptext_t), err)) {
5021 return false0;
5022 }
5023 if (!last_round) {
5024 fix_endianness_blf_apptext_header(&apptext_header);
5025 }
5026
5027 if (!wtap_dump_file_write(wdh, &(pd[pos]), chunk_size, err)) {
5028 return false0;
5029 }
5030 pos += chunk_size;
5031
5032 /* Add strange padding to 4 bytes. */
5033 uint8_t padding_needed = (sizeof(blf_apptext_t) + chunk_size) % 4;
5034 if (!blf_write_add_padding(wdh, err, padding_needed)) {
5035 return false0;
5036 }
5037
5038 if (!last_round) {
5039 payload_len -= 2048;
5040 }
5041 } while (!last_round);
5042
5043 return true1;
5044 }
5045 // else if
5046 /* BLF_OBJTYPE_ETHERNET_STATUS */
5047 /* tags: BLF_APPTEXT_TAG_DISS_ETHSTATUS */
5048 // TODO
5049
5050 // else if
5051 /* BLF_OBJTYPE_ETHERNET_PHY_STATE */
5052 /* tags: BLF_APPTEXT_TAG_DISS_ETHPHYSTATUS */
5053 // TODO
5054 }
5055
5056 return true1;
5057}
5058
5059static bool_Bool blf_dump_interface_setup_by_blf_based_idb_desc(wtap_dumper *wdh, int *err _U___attribute__((unused))) {
5060 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5061 bool_Bool iface_descr_found;
5062
5063 /* check all interfaces first to avoid inconstistent state */
5064 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5065 ws_debug("interface: %d (pass 1)", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5065, __func__, "interface: %d (pass 1)", i); } } while (0)
;
5066
5067 /* get interface data */
5068 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5069 if (idb == NULL((void*)0)) {
5070 return false0;
5071 }
5072
5073 char *iface_descr = NULL((void*)0);
5074 iface_descr_found = wtap_block_get_string_option_value(idb, OPT_IDB_DESCRIPTION3, &iface_descr) == WTAP_OPTTYPE_SUCCESS;
5075
5076 if (!iface_descr_found) {
5077 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"
, 5077, __func__, "IDB interface description not found! We need to map the interfaces."
); } } while (0)
;
5078 return false0;
5079 }
5080
5081 if (strncmp(iface_descr, "BLF-", 4) != 0) {
5082 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"
, 5082, __func__, "IDB interface description found but not BLF format! We have to map freely the interfaces."
); } } while (0)
;
5083 return false0;
5084 }
5085 }
5086
5087 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5088 ws_debug("interface: %d (pass 2)", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5088, __func__, "interface: %d (pass 2)", i); } } while (0)
;
5089
5090 /* get interface data */
5091 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5092 if (idb == NULL((void*)0)) {
5093 return false0;
5094 }
5095
5096 char *iface_descr = NULL((void*)0);
5097 iface_descr_found = wtap_block_get_string_option_value(idb, OPT_IDB_DESCRIPTION3, &iface_descr);
5098
5099 if (!iface_descr_found) {
5100 /* This cannot be reached but it removes a warning. */
5101 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"
, 5101, __func__, "IDB interface description not found! We need to map the interfaces."
); } } while (0)
;
5102 return false0;
5103 }
5104
5105 if (strncmp(iface_descr, "BLF-ETH-", 8) == 0) {
5106 char *endptr;
5107 uint16_t channel = (uint16_t)strtol(&iface_descr[8], &endptr, 16);
5108 uint16_t hwchannel = (uint16_t)strtol(&endptr[1], NULL((void*)0), 16);
5109
5110 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_ETHERNET1, channel, hwchannel)) {
5111 return false0;
5112 }
5113 } else if (strncmp(iface_descr, "BLF-CAN-", 8) == 0) {
5114 uint16_t channel = (uint16_t)strtol(&iface_descr[8], NULL((void*)0), 16);
5115
5116 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_SOCKETCAN125, channel, UINT16_MAX(65535))) {
5117 return false0;
5118 }
5119 } else if (strncmp(iface_descr, "BLF-LIN-", 8) == 0) {
5120 uint16_t channel = (uint16_t)strtol(&iface_descr[8], NULL((void*)0), 16);
5121
5122 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_LIN107, channel, UINT16_MAX(65535))) {
5123 return false0;
5124 }
5125 } else if (strncmp(iface_descr, "BLF-FR-", 7) == 0) {
5126 uint16_t channel = (uint16_t)strtol(&iface_descr[7], NULL((void*)0), 16);
5127
5128 if (!blf_dump_set_interface_mapping(wdh, i, WTAP_ENCAP_FLEXRAY106, channel, UINT16_MAX(65535))) {
5129 return false0;
5130 }
5131 }
5132 }
5133
5134 writer_data->iface_to_channel_names_recovered = true1;
5135 return true1;
5136}
5137
5138static bool_Bool blf_dump_interface_setup(wtap_dumper *wdh, int *err) {
5139 //blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5140
5141 /* Try 1: BLF details in Interface Description */
5142 if (blf_dump_interface_setup_by_blf_based_idb_desc(wdh, err)) {
5143 return true1;
5144 }
5145
5146 /* Try 2: Generate new IDs by mapping Interface IDs and also add names to BLF */
5147 for (unsigned i = 0; i < wdh->interface_data->len; i++) {
5148 ws_debug("i: %d", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5148, __func__, "i: %d", i); } } while (0)
;
5149
5150 /* get interface data */
5151 wtap_block_t idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
5152 if (idb == NULL((void*)0)) {
5153 return false0;
5154 }
5155
5156 const wtapng_if_descr_mandatory_t *mand_data = (wtapng_if_descr_mandatory_t *) idb->mandatory_data;
5157
5158 if (mand_data->wtap_encap == WTAP_ENCAP_ETHERNET1 || mand_data->wtap_encap == WTAP_ENCAP_SLL25 ||
5159 mand_data->wtap_encap == WTAP_ENCAP_LIN107 || mand_data->wtap_encap == WTAP_ENCAP_SOCKETCAN125) {
5160
5161 char *iface_name = NULL((void*)0);
5162 bool_Bool iface_name_found = wtap_block_get_string_option_value(idb, OPT_IDB_NAME2, &iface_name) == WTAP_OPTTYPE_SUCCESS;
5163
5164 /* BLF can only support 255 channels */
5165 if (iface_name_found && iface_name != NULL((void*)0) && (i) < 255) {
5166 uint8_t iface_id = (uint8_t)(i + 1);
5167
5168 /* we are not even trying to create APPTEXT CHANNELS as we are missing too much information */
5169
5170 /* mapping up to 255 interface ids to channels directly */
5171 if (!blf_dump_set_interface_mapping(wdh, i, mand_data->wtap_encap, (uint16_t)iface_id, UINT16_MAX(65535))) {
5172 return false0;
5173 }
5174 }
5175 }
5176 }
5177
5178 return true1;
5179}
5180
5181static bool_Bool blf_dump(wtap_dumper *wdh, const wtap_rec *rec, int *err, char **err_info) {
5182 blf_writer_data_t *writer_data = (blf_writer_data_t *)wdh->priv;
5183 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"
, 5184, __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)
5184 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"
, 5184, __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)
;
5185
5186 /* TODO */
5187 switch (rec->rec_type) {
5188 case REC_TYPE_PACKET0:
5189 break;
5190 default:
5191 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
5192 return false0;
5193 }
5194
5195 /* logcontainer full already? we just estimate the headers/overhead to be less than 100 */
5196 blf_dump_check_logcontainer_full(wdh, err, err_info, rec->rec_header.packet_header.len + 100);
5197
5198 if (!writer_data->start_time_set) {
5199 /* TODO: consider to set trace start time to first packet time stamp - is this the lowest timestamp? how to know? */
5200 writer_data->start_time = 0;
5201 writer_data->start_time_set = true1;
5202 }
5203
5204 uint64_t obj_timestamp = (rec->ts.secs * 1000 * 1000 * 1000 + rec->ts.nsecs);
5205
5206 if (writer_data->end_time < obj_timestamp) {
5207 writer_data->end_time = obj_timestamp;
5208 }
5209
5210 /* reduce by BLF start offset */
5211 obj_timestamp = obj_timestamp - writer_data->start_time;
5212 writer_data->object_count += 1;
5213
5214 switch (rec->rec_header.packet_header.pkt_encap) {
5215 case WTAP_ENCAP_ETHERNET1: /* 1 */
5216 return blf_dump_ethernet(wdh, rec, err, err_info, obj_timestamp);
5217 break;
5218
5219 case WTAP_ENCAP_SLL25: /* 25 */
5220 return blf_dump_sll(wdh, rec, err, err_info, obj_timestamp);
5221 break;
5222
5223 case WTAP_ENCAP_FLEXRAY106: /* 106 */
5224 return blf_dump_flexray(wdh, rec, err, err_info, obj_timestamp);
5225 break;
5226
5227 case WTAP_ENCAP_LIN107: /* 107 */
5228 return blf_dump_lin(wdh, rec, err, err_info, obj_timestamp);
5229 break;
5230
5231 case WTAP_ENCAP_SOCKETCAN125: { /* 125 */
5232 const uint8_t *pd = ws_buffer_start_ptr(&rec->data);
5233 size_t length = ws_buffer_length(&rec->data);
5234 return blf_dump_socketcan(wdh, rec, err, err_info, obj_timestamp, pd, length, false0, false0, false0, false0);
5235 }
5236 break;
5237
5238 case WTAP_ENCAP_WIRESHARK_UPPER_PDU155: /* 155 */
5239 return blf_dump_upper_pdu(wdh, rec, err, err_info, obj_timestamp);
5240 break;
5241
5242 default:
5243 /* we did not write, so correct count */
5244 writer_data->object_count -= 1;
5245 }
5246
5247 return true1;
5248}
5249
5250/* Returns 0 if we could write the specified encapsulation type,
5251 an error indication otherwise. */
5252static int blf_dump_can_write_encap(int wtap_encap) {
5253 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"
, 5253, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
;
5254
5255 /* Per-packet encapsulation is supported. */
5256 if (wtap_encap == WTAP_ENCAP_PER_PACKET-1)
5257 return 0;
5258
5259 switch (wtap_encap) {
5260 /* fall through */
5261 case WTAP_ENCAP_ETHERNET1:
5262 case WTAP_ENCAP_SLL25:
5263 case WTAP_ENCAP_FLEXRAY106:
5264 case WTAP_ENCAP_LIN107:
5265 case WTAP_ENCAP_SOCKETCAN125:
5266 case WTAP_ENCAP_WIRESHARK_UPPER_PDU155:
5267 return 0;
5268 }
5269
5270 return WTAP_ERR_UNWRITABLE_ENCAP-8;
5271}
5272
5273static 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))) {
5274 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5274, __func__, "entering function"); } } while (0)
;
5275 /* TODO: is there any reason to keep this? */
5276
5277 return true1;
5278}
5279
5280/* Finish writing to a dump file.
5281 Returns true on success, false on failure. */
5282static bool_Bool blf_dump_finish(wtap_dumper *wdh, int *err, char **err_info) {
5283 if (!blf_dump_close_logcontainer(wdh, err, err_info)) {
5284 return false0;
5285 }
5286
5287 if (!blf_finalize_file_header(wdh, err)) {
5288 return false0;
5289 }
5290
5291 /* File is finished, do not touch anymore ! */
5292
5293 ws_debug("leaving function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5293, __func__, "leaving function"); } } while (0)
;
5294 return true1;
5295}
5296
5297/* Returns true on success, false on failure; sets "*err" to an error code on
5298 failure */
5299static bool_Bool
5300blf_dump_open(wtap_dumper *wdh, int *err, char **err_info) {
5301 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5301, __func__, "entering function"); } } while (0)
;
1
Taking true branch
5302
5303 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
5304 *err = WTAP_ERR_INTERNAL-21;
5305 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"
, 5305, __func__, "internal error: blf wdh is NULL or private data already set!"
); } } while (0)
;
5306 return false0;
5307 }
5308
5309 wdh->subtype_add_idb = blf_add_idb;
5310 wdh->subtype_write = blf_dump;
5311 wdh->subtype_finish = blf_dump_finish;
5312
5313 /* set up priv data */
5314 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
)))
;
5315 wdh->priv = writer_data;
5316
5317 /* set up and init interface mappings */
5318 writer_data->iface_to_channel_array = g_array_new(true1, true1, sizeof(blf_channel_to_iface_entry_t));
5319 blf_dump_expand_interface_mapping(wdh, wdh->interface_data->len);
5
Calling 'blf_dump_expand_interface_mapping'
5320 writer_data->iface_to_channel_names_recovered = false0;
5321
5322 writer_data->fileheader = NULL((void*)0);
5323 writer_data->object_count = 0;
5324 writer_data->start_time = 0;
5325 writer_data->start_time_set = false0;
5326 writer_data->end_time = 0;
5327
5328 writer_data->logcontainer_start = LOG_CONTAINER_NONE(18446744073709551615UL);
5329
5330 /* create the blf header structure and attach to wdh */
5331 if (!blf_init_file_header(wdh, err)) {
5332 return false0;
5333 }
5334
5335 /* write space in output file for header */
5336 if (!blf_write_file_header_zeros(wdh, err)) {
5337 return false0;
5338 }
5339
5340 ws_debug("wrote blf file header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/blf.c"
, 5340, __func__, "wrote blf file header"); } } while (0)
;
5341
5342 /* Create first log_container */
5343 if (!blf_dump_start_logcontainer(wdh, err, err_info)) {
5344 return false0;
5345 }
5346
5347 if (!blf_dump_interface_setup(wdh, err)) {
5348 return false0;
5349 }
5350
5351 return true1;
5352}
5353
5354static const struct file_type_subtype_info blf_info = {
5355 "Vector Informatik Binary Logging Format (BLF) logfile", "blf", "blf", NULL((void*)0),
5356 false0, BLOCKS_SUPPORTED(blf_blocks_supported)(sizeof (blf_blocks_supported) / sizeof (blf_blocks_supported
)[0]), blf_blocks_supported
,
5357 blf_dump_can_write_encap, blf_dump_open, NULL((void*)0)
5358};
5359
5360void register_blf(void)
5361{
5362 blf_file_type_subtype = wtap_register_file_type_subtype(&blf_info);
5363
5364 /*
5365 * Register name for backwards compatibility with the
5366 * wtap_filetypes table in Lua.
5367 */
5368 wtap_register_backwards_compatibility_lua_name("BLF", blf_file_type_subtype);
5369}
5370
5371/*
5372 * Editor modelines - https://www.wireshark.org/tools/modelines.html
5373 *
5374 * Local variables:
5375 * c-basic-offset: 4
5376 * tab-width: 8
5377 * indent-tabs-mode: nil
5378 * End:
5379 *
5380 * vi: set shiftwidth=4 tabstop=8 expandtab:
5381 * :indentSize=4:tabSize=8:noTabs=true:
5382 */