Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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