Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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