Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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