Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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