Bug Summary

File:wiretap/pcapng.c
Warning:line 3175, column 9
Value stored to 'handler' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pcapng.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-19/lib/clang/19 -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-19/lib/clang/19/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 -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-07-14-100251-3848-1 -x c /builds/wireshark/wireshark/wiretap/pcapng.c
1/* pcapng.c
2 *
3 * Wiretap Library
4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
5 *
6 * File format support for pcapng file format
7 * Copyright (c) 2007 by Ulf Lamping <ulf.lamping@web.de>
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12/* File format specification:
13 * https://github.com/pcapng/pcapng
14 * Related Wiki page:
15 * https://gitlab.com/wireshark/wireshark/-/wikis/Development/PcapNg
16 */
17
18#include "config.h"
19#define WS_LOG_DOMAIN"Wiretap" LOG_DOMAIN_WIRETAP"Wiretap"
20#include "pcapng.h"
21
22#include "wtap_opttypes.h"
23
24#include <stdlib.h>
25#include <string.h>
26#include <errno(*__errno_location ()).h>
27
28#include <jtckdint.h>
29
30#include <wsutil/application_flavor.h>
31#include <wsutil/wslog.h>
32#include <wsutil/strtoi.h>
33#include <wsutil/glib-compat.h>
34#include <wsutil/ws_assert.h>
35#include <wsutil/ws_roundup.h>
36#include <wsutil/ws_padding_to.h>
37#include <wsutil/unicode-utils.h>
38
39#include "wtap-int.h"
40#include "file_wrappers.h"
41#include "required_file_handlers.h"
42#include "pcap-common.h"
43#include "pcap-encap.h"
44#include "pcapng_module.h"
45#include "secrets-types.h"
46
47#define NS_PER_S1000000000U 1000000000U
48
49static bool_Bool
50pcapng_read(wtap *wth, wtap_rec *rec, int *err,
51 char **err_info, int64_t *data_offset);
52static bool_Bool
53pcapng_seek_read(wtap *wth, int64_t seek_off,
54 wtap_rec *rec, int *err, char **err_info);
55static void
56pcapng_close(wtap *wth);
57
58static bool_Bool
59pcapng_encap_is_ft_specific(int encap);
60
61static bool_Bool
62pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data,
63 int *err, char **err_info);
64
65/*
66 * Minimum block size = size of block header + size of block trailer.
67 */
68#define MIN_BLOCK_SIZE((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t))
)
((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t)))
69
70/*
71 * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
72 */
73#define MIN_SHB_SIZE((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t) + sizeof
(uint32_t))) + sizeof(pcapng_section_header_block_t)))
((uint32_t)(MIN_BLOCK_SIZE((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t))
)
+ sizeof(pcapng_section_header_block_t)))
74
75/* pcapng: packet block file encoding (obsolete) */
76typedef struct pcapng_packet_block_s {
77 uint16_t interface_id;
78 uint16_t drops_count;
79 uint32_t timestamp_high;
80 uint32_t timestamp_low;
81 uint32_t captured_len;
82 uint32_t packet_len;
83 /* ... Packet Data ... */
84 /* ... Padding ... */
85 /* ... Options ... */
86} pcapng_packet_block_t;
87
88/* pcapng: enhanced packet block file encoding */
89typedef struct pcapng_enhanced_packet_block_s {
90 uint32_t interface_id;
91 uint32_t timestamp_high;
92 uint32_t timestamp_low;
93 uint32_t captured_len;
94 uint32_t packet_len;
95 /* ... Packet Data ... */
96 /* ... Padding ... */
97 /* ... Options ... */
98} pcapng_enhanced_packet_block_t;
99
100/*
101 * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
102 */
103#define MIN_EPB_SIZE((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t) + sizeof
(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t)))
((uint32_t)(MIN_BLOCK_SIZE((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t))
)
+ sizeof(pcapng_enhanced_packet_block_t)))
104
105/* pcapng: simple packet block file encoding */
106typedef struct pcapng_simple_packet_block_s {
107 uint32_t packet_len;
108 /* ... Packet Data ... */
109 /* ... Padding ... */
110} pcapng_simple_packet_block_t;
111
112/* pcapng: name resolution block file encoding */
113typedef struct pcapng_name_resolution_block_s {
114 uint16_t record_type;
115 uint16_t record_len;
116 /* ... Record ... */
117} pcapng_name_resolution_block_t;
118
119/* pcapng: custom block file encoding */
120typedef struct pcapng_custom_block_s {
121 uint32_t pen;
122 /* Custom data and options */
123} pcapng_custom_block_t;
124
125/*
126 * We require __REALTIME_TIMESTAMP in the Journal Export Format reader in
127 * order to set each packet timestamp. Require it here as well, although
128 * it's not strictly necessary.
129 */
130#define SDJ__REALTIME_TIMESTAMP"__REALTIME_TIMESTAMP=" "__REALTIME_TIMESTAMP="
131#define MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE23 23 // "__REALTIME_TIMESTAMP=0\n"
132
133/* pcapng: common option header file encoding for every option type */
134typedef struct pcapng_option_header_s {
135 uint16_t option_code;
136 uint16_t option_length;
137 /* ... x bytes Option Body ... */
138 /* ... Padding ... */
139} pcapng_option_header_t;
140
141struct pcapng_option {
142 uint16_t type;
143 uint16_t value_length;
144};
145
146/* MSBit of option code means "local type" */
147#define OPT_LOCAL_FLAG0x8000 0x8000
148
149/* OPT_EPB_VERDICT sub-types */
150#define OPT_VERDICT_TYPE_HW0 0
151#define OPT_VERDICT_TYPE_TC1 1
152#define OPT_VERDICT_TYPE_XDP2 2
153
154/* OPT_EPB_HASH sub-types */
155#define OPT_HASH_2COMP0 0
156#define OPT_HASH_XOR1 1
157#define OPT_HASH_CRC322 2
158#define OPT_HASH_MD53 3
159#define OPT_HASH_SHA14 4
160#define OPT_HASH_TOEPLITZ5 5
161
162/*
163 * In order to keep from trying to allocate large chunks of memory,
164 * which could either fail or, even if it succeeds, chew up so much
165 * address space or memory+backing store as not to leave room for
166 * anything else, we impose upper limits on the size of blocks we're
167 * willing to handle.
168 *
169 * We pick a limit of an EPB with a maximum-sized D-Bus packet and 128 KiB
170 * worth of options; we use the maximum D-Bus packet size as that's larger
171 * than the maximum packet size for other link-layer types, and the maximum
172 * packet size for other link-layer types is currently small enough that
173 * the resulting block size would be less than the previous 16 MiB limit.
174 */
175#define MAX_BLOCK_SIZE(((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t) + sizeof
(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t))) + (128U
*1024U*1024U) + 131072)
(MIN_EPB_SIZE((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t) + sizeof
(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t)))
+ WTAP_MAX_PACKET_SIZE_DBUS(128U*1024U*1024U) + 131072)
176
177/* Note: many of the defined structures for block data are defined in wtap.h */
178
179/* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
180typedef struct wtapng_packet_s {
181 /* mandatory */
182 uint32_t ts_high; /* seconds since 1.1.1970 */
183 uint32_t ts_low; /* fraction of seconds, depends on if_tsresol */
184 uint32_t cap_len; /* data length in the file */
185 uint32_t packet_len; /* data length on the wire */
186 uint32_t interface_id; /* identifier of the interface. */
187 uint16_t drops_count; /* drops count, only valid for packet block */
188 /* 0xffff if information no available */
189 /* pack_hash */
190 /* XXX - put the packet data / pseudo_header here as well? */
191} wtapng_packet_t;
192
193/* Simple Packet data */
194typedef struct wtapng_simple_packet_s {
195 /* mandatory */
196 uint32_t cap_len; /* data length in the file */
197 uint32_t packet_len; /* data length on the wire */
198 /* XXX - put the packet data / pseudo_header here as well? */
199} wtapng_simple_packet_t;
200
201/* Interface data in private struct */
202typedef struct interface_info_s {
203 int wtap_encap;
204 uint32_t snap_len;
205 uint64_t time_units_per_second;
206 int tsprecision;
207 int64_t tsoffset;
208 int fcslen;
209 uint8_t tsresol_binary;
210} interface_info_t;
211
212typedef struct {
213 unsigned current_section_number; /**< Section number of the current section being read sequentially */
214 GArray *sections; /**< Sections found in the capture file. */
215} pcapng_t;
216
217/*
218 * Table for plugins to handle particular block types.
219 *
220 * A handler has a type, whether its internally handled and "read"
221 * and "write" routines.
222 *
223 * A "read" routine returns a block as a libwiretap record, filling
224 * in the wtap_rec structure with the appropriate record type and
225 * other information, and filling in the structure's Buffer with
226 * data for which there's no place in the wtap_rec structure.
227 *
228 * A "write" routine takes a libwiretap record and out a block.
229 */
230static GHashTable *block_handlers;
231
232void
233register_pcapng_block_type_information(pcapng_block_type_information_t* handler)
234{
235 if (handler == NULL((void*)0)) {
236 ws_warning("Attempt to register NULL plugin block type handler")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/pcapng.c"
, 236, __func__, "Attempt to register NULL plugin block type handler"
); } } while (0)
;
237 return;
238 }
239
240 /* Don't allow duplication of block types */
241 if (g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(handler->type)((gpointer) (gulong) (handler->type))) != NULL((void*)0)) {
242 ws_warning("Attempt to register plugin for an existing block type 0x%08x not allowed",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/pcapng.c"
, 243, __func__, "Attempt to register plugin for an existing block type 0x%08x not allowed"
, handler->type); } } while (0)
243 handler->type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_WARNING, "wiretap/pcapng.c"
, 243, __func__, "Attempt to register plugin for an existing block type 0x%08x not allowed"
, handler->type); } } while (0)
;
244 return;
245 }
246
247 g_hash_table_insert(block_handlers, GUINT_TO_POINTER(handler->type)((gpointer) (gulong) (handler->type)),
248 handler);
249}
250
251/*
252 * Tables for plugins to handle particular options for particular block
253 * types.
254 *
255 * An option has three handler routines:
256 *
257 * An option parser, used when reading an option from a file:
258 *
259 * The option parser is passed an indication of whether this section
260 * of the file is byte-swapped, the length of the option, the data of
261 * the option, a pointer to an error code, and a pointer to a pointer
262 * variable for an error string.
263 *
264 * It checks whether the length and option are valid, and, if they
265 * aren't, returns false, setting the error code to the appropriate
266 * error (normally WTAP_ERR_BAD_FILE) and the error string to an
267 * appropriate string indicating the problem.
268 *
269 * Otherwise, if this section of the file is byte-swapped, it byte-swaps
270 * multi-byte numerical values, so that it's in the host byte order.
271 *
272 * An option sizer, used when writing an option to a file:
273 *
274 * The option sizer is passed the option identifier for the option
275 * and a wtap_optval_t * that points to the data for the option.
276 *
277 * It calculates how many bytes the option's data requires, not
278 * including any padding bytes, and returns that value.
279 *
280 * An option writer, used when writing an option to a file:
281 *
282 * The option writer is passed a wtap_dumper * to which the
283 * option data should be written, the option identifier for
284 * the option, a wtap_optval_t * that points to the data for
285 * the option, and an int * into which an error code should
286 * be stored if an error occurs when writing the option.
287 *
288 * It returns a bool value of true if the attempt to
289 * write the option succeeds and false if the attempt to
290 * write the option gets an error.
291 */
292
293typedef struct {
294 option_parser parser;
295 option_sizer sizer;
296 option_writer writer;
297} option_handler;
298
299static GHashTable *custom_enterprise_handlers;
300
301/* Return whether this block type is handled interally, or
302 * if it is returned to the caller in pcapng_read().
303 * This is used by pcapng_open() to decide if it can process
304 * the block.
305 * Note that for block types that are registered from plugins,
306 * we don't know the true answer without actually reading the block,
307 * or even if there is a fixed answer for all blocks of that type,
308 * so we err on the side of not processing.
309 */
310static bool_Bool
311get_block_type_internal(unsigned block_type)
312{
313 pcapng_block_type_information_t *handler;
314
315 handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(block_type)((gpointer) (gulong) (block_type)));
316
317 if (handler != NULL((void*)0))
318 return handler->internal;
319 else
320 return true1;
321}
322
323GHashTable *
324pcapng_create_option_handler_table(void)
325{
326 return g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL((void*)0), g_free);
327}
328
329static GHashTable *
330get_option_handlers(unsigned block_type)
331{
332 pcapng_block_type_information_t *block_handler;
333
334 block_handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(block_type)((gpointer) (gulong) (block_type)));
335 if (block_handler == NULL((void*)0)) {
336 /* No such block type. */
337 return NULL((void*)0);
338 }
339
340 if (block_handler->option_handlers == NULL((void*)0)) {
341 /*
342 * This block type doesn't support options other than
343 * those supported by all blocks.
344 */
345 return NULL((void*)0);
346 }
347
348 return block_handler->option_handlers;
349}
350
351void
352register_pcapng_option_handler(unsigned block_type, unsigned option_code,
353 option_parser parser,
354 option_sizer sizer,
355 option_writer writer)
356{
357 GHashTable *option_handlers;
358 option_handler *handler;
359
360 /*
361 * Get the table of option handlers for this block type.
362 */
363 option_handlers = get_option_handlers(block_type);
364
365 /*
366 * If there isn't one, the block only supports the standard options
367 * (if it supports options at all; the SPB doesn't).
368 */
369 if (option_handlers == NULL((void*)0))
370 return;
371
372 /*
373 * Is this combination already registered?
374 */
375 handler = (option_handler *)g_hash_table_lookup(option_handlers,
376 GUINT_TO_POINTER(option_code)((gpointer) (gulong) (option_code)));
377 if (handler != NULL((void*)0)) {
378 if (handler->parser == parser &&
379 handler->sizer == sizer &&
380 handler->writer == writer) {
381 /*
382 * Yes. This might be a case where multiple block types
383 * share the same table, and some code registers the same
384 * option for all of those blocks, which is OK. Just
385 * ignore it.
386 */
387 return;
388 }
389
390 /*
391 * No. XXX - report this.
392 */
393 return;
394 }
395
396 /*
397 * No - register it.
398 */
399 handler = g_new(option_handler, 1)((option_handler *) g_malloc_n ((1), sizeof (option_handler))
)
;
400 handler->parser = parser;
401 handler->sizer = sizer;
402 handler->writer = writer;
403 g_hash_table_insert(option_handlers,
404 GUINT_TO_POINTER(option_code)((gpointer) (gulong) (option_code)), handler);
405}
406
407void
408pcapng_add_cb_section_info_data(section_info_t *section_info,
409 uint32_t pen, void *data)
410{
411 g_hash_table_insert(section_info->custom_block_data,
412 GUINT_TO_POINTER(pen)((gpointer) (gulong) (pen)), data);
413}
414
415void *
416pcapng_get_cb_section_info_data(section_info_t *section_info, uint32_t pen,
417 const section_info_funcs_t *funcs)
418{
419 void *data;
420
421 if (section_info->custom_block_data == NULL((void*)0)) {
422 /*
423 * Create the table of custom block data for this section_info_t.
424 *
425 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
426 * so we use "g_direct_hash()" and "g_direct_equal()".
427 */
428 section_info->custom_block_data = g_hash_table_new_full(g_direct_hash,
429 g_direct_equal,
430 NULL((void*)0),
431 funcs->free);
432
433 /*
434 * The newly-created hash table is empty, so no point in looking
435 * for an element in it.
436 */
437 data = NULL((void*)0);
438 } else {
439 /*
440 * We have the hash table; look for the entry.
441 */
442 data = g_hash_table_lookup(section_info->custom_block_data,
443 GUINT_TO_POINTER(pen)((gpointer) (gulong) (pen)));
444 }
445 if (data == NULL((void*)0)) {
446 /*
447 * No entry found - create a new one, and add it to the
448 * hash table.
449 */
450 data = funcs->new();
451 g_hash_table_insert(section_info->custom_block_data,
452 GUINT_TO_POINTER(pen)((gpointer) (gulong) (pen)), data);
453 }
454 return data;
455}
456
457void *
458pcapng_get_lb_section_info_data(section_info_t *section_info,
459 uint32_t block_type,
460 const section_info_funcs_t *funcs)
461{
462 void *data;
463
464 if (section_info->local_block_data == NULL((void*)0)) {
465 /*
466 * Create the table of local block data for this section_info_t.
467 *
468 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
469 * so we use "g_direct_hash()" and "g_direct_equal()".
470 */
471 section_info->local_block_data = g_hash_table_new_full(g_direct_hash,
472 g_direct_equal,
473 NULL((void*)0),
474 funcs->free);
475
476 /*
477 * The newly-created hash table is empty, so no point in looking
478 * for an element in it.
479 */
480 data = NULL((void*)0);
481 } else {
482 /*
483 * We have the hash table; look for the entry.
484 */
485 data = g_hash_table_lookup(section_info->local_block_data,
486 GUINT_TO_POINTER(block_type)((gpointer) (gulong) (block_type)));
487 }
488 if (data == NULL((void*)0)) {
489 /*
490 * No entry found - create a new one, and add it to the
491 * hash table.
492 */
493 data = funcs->new();
494 g_hash_table_insert(section_info->local_block_data,
495 GUINT_TO_POINTER(block_type)((gpointer) (gulong) (block_type)), data);
496 }
497 return data;
498}
499
500void
501pcapng_process_uint8_option(wtapng_block_t *wblock,
502 uint16_t option_code, uint16_t option_length,
503 const uint8_t *option_content)
504{
505 if (option_length == 1) {
506 /*
507 * If this option can appear only once in a block, this call
508 * will fail on the second and later occurrences of the option;
509 * we silently ignore the failure.
510 */
511 wtap_block_add_uint8_option(wblock->block, option_code, option_content[0]);
512 }
513}
514
515void
516pcapng_process_uint32_option(wtapng_block_t *wblock,
517 section_info_t *section_info,
518 pcapng_opt_byte_order_e byte_order,
519 uint16_t option_code, uint16_t option_length,
520 const uint8_t *option_content)
521{
522 uint32_t uint32;
523
524 if (option_length == 4) {
525 /* Don't cast a uint8_t * into a uint32_t *--the
526 * uint8_t * may not point to something that's
527 * aligned correctly.
528 *
529 * XXX - options are aligned on 32-bit boundaries, so, while
530 * it may be true that 64-bit options aren't guaranteed to be
531 * aligned on 64-bit bounaries, it shouldn't be true that 32-bit
532 * options aren't guaranteed to be aligned on 32-bit boundaries.
533 */
534 memcpy(&uint32, option_content, sizeof(uint32_t));
535 switch (byte_order) {
536
537 case OPT_SECTION_BYTE_ORDER:
538 if (section_info->byte_swapped) {
539 uint32 = GUINT32_SWAP_LE_BE(uint32)(((guint32) ( (((guint32) (uint32) & (guint32) 0x000000ffU
) << 24) | (((guint32) (uint32) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (uint32) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (uint32) & (guint32) 0xff000000U
) >> 24))))
;
540 }
541 break;
542
543 case OPT_BIG_ENDIAN:
544 uint32 = GUINT32_FROM_BE(uint32)(((((guint32) ( (((guint32) (uint32) & (guint32) 0x000000ffU
) << 24) | (((guint32) (uint32) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (uint32) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (uint32) & (guint32) 0xff000000U
) >> 24))))))
;
545 break;
546
547 case OPT_LITTLE_ENDIAN:
548 uint32 = GUINT32_FROM_LE(uint32)(((guint32) (uint32)));
549 break;
550
551 default:
552 /*
553 * This should not happen - this is called by pcapng_process_options(),
554 * which returns an error for an invalid byte_order argument, and
555 * otherwise passes the known-to-be-valid byte_order argument to
556 * us.
557 *
558 * Just ignore the option.
559 */
560 return;
561 }
562
563 /*
564 * If this option can appear only once in a block, this call
565 * will fail on the second and later occurrences of the option;
566 * we silently ignore the failure.
567 */
568 wtap_block_add_uint32_option(wblock->block, option_code, uint32);
569 }
570}
571
572void
573pcapng_process_timestamp_option(wtapng_block_t *wblock,
574 section_info_t *section_info,
575 pcapng_opt_byte_order_e byte_order,
576 uint16_t option_code, uint16_t option_length,
577 const uint8_t *option_content)
578{
579 if (option_length == 8) {
580 uint32_t high, low;
581 uint64_t timestamp;
582
583 /* Don't cast a uint8_t * into a uint32_t *--the
584 * uint8_t * may not point to something that's
585 * aligned correctly.
586 */
587 memcpy(&high, option_content, sizeof(uint32_t));
588 memcpy(&low, option_content + sizeof(uint32_t), sizeof(uint32_t));
589 switch (byte_order) {
590
591 case OPT_SECTION_BYTE_ORDER:
592 if (section_info->byte_swapped) {
593 high = GUINT32_SWAP_LE_BE(high)(((guint32) ( (((guint32) (high) & (guint32) 0x000000ffU)
<< 24) | (((guint32) (high) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (high) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (high) & (guint32) 0xff000000U
) >> 24))))
;
594 low = GUINT32_SWAP_LE_BE(low)(((guint32) ( (((guint32) (low) & (guint32) 0x000000ffU) <<
24) | (((guint32) (low) & (guint32) 0x0000ff00U) <<
8) | (((guint32) (low) & (guint32) 0x00ff0000U) >>
8) | (((guint32) (low) & (guint32) 0xff000000U) >>
24))))
;
595 }
596 break;
597
598 case OPT_BIG_ENDIAN:
599 high = GUINT32_FROM_BE(high)(((((guint32) ( (((guint32) (high) & (guint32) 0x000000ffU
) << 24) | (((guint32) (high) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (high) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (high) & (guint32) 0xff000000U
) >> 24))))))
;
600 low = GUINT32_FROM_BE(low)(((((guint32) ( (((guint32) (low) & (guint32) 0x000000ffU
) << 24) | (((guint32) (low) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (low) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (low) & (guint32) 0xff000000U
) >> 24))))))
;
601 break;
602
603 case OPT_LITTLE_ENDIAN:
604 high = GUINT32_FROM_LE(high)(((guint32) (high)));
605 low = GUINT32_FROM_LE(low)(((guint32) (low)));
606 break;
607
608 default:
609 /*
610 * This should not happen - this is called by pcapng_process_options(),
611 * which returns an error for an invalid byte_order argument, and
612 * otherwise passes the known-to-be-valid byte_order argument to
613 * us.
614 *
615 * Just ignore the option.
616 */
617 return;
618 }
619 timestamp = (uint64_t)high;
620 timestamp <<= 32;
621 timestamp += (uint64_t)low;
622 /*
623 * If this option can appear only once in a block, this call
624 * will fail on the second and later occurrences of the option;
625 * we silently ignore the failure.
626 */
627 wtap_block_add_uint64_option(wblock->block, option_code, timestamp);
628 }
629}
630
631void
632pcapng_process_uint64_option(wtapng_block_t *wblock,
633 section_info_t *section_info,
634 pcapng_opt_byte_order_e byte_order,
635 uint16_t option_code, uint16_t option_length,
636 const uint8_t *option_content)
637{
638 uint64_t uint64;
639
640 if (option_length == 8) {
641 /* Don't cast a uint8_t * into a uint64_t *--the
642 * uint8_t * may not point to something that's
643 * aligned correctly.
644 */
645 memcpy(&uint64, option_content, sizeof(uint64_t));
646 switch (byte_order) {
647
648 case OPT_SECTION_BYTE_ORDER:
649 if (section_info->byte_swapped) {
650 uint64 = GUINT64_SWAP_LE_BE(uint64)(((guint64) ( (((guint64) (uint64) & (guint64) (0x00000000000000ffUL
)) << 56) | (((guint64) (uint64) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (uint64) & (guint64) (0x0000000000ff0000UL
)) << 24) | (((guint64) (uint64) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (uint64) & (guint64) (0x000000ff00000000UL
)) >> 8) | (((guint64) (uint64) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (uint64) & (guint64) (0x00ff000000000000UL
)) >> 40) | (((guint64) (uint64) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
651 }
652 break;
653
654 case OPT_BIG_ENDIAN:
655 uint64 = GUINT64_FROM_BE(uint64)(((((guint64) ( (((guint64) (uint64) & (guint64) (0x00000000000000ffUL
)) << 56) | (((guint64) (uint64) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (uint64) & (guint64) (0x0000000000ff0000UL
)) << 24) | (((guint64) (uint64) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (uint64) & (guint64) (0x000000ff00000000UL
)) >> 8) | (((guint64) (uint64) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (uint64) & (guint64) (0x00ff000000000000UL
)) >> 40) | (((guint64) (uint64) & (guint64) (0xff00000000000000UL
)) >> 56))))))
;
656 break;
657
658 case OPT_LITTLE_ENDIAN:
659 uint64 = GUINT64_FROM_LE(uint64)(((guint64) (uint64)));
660 break;
661
662 default:
663 /*
664 * This should not happen - this is called by pcapng_process_options(),
665 * which returns an error for an invalid byte_order argument, and
666 * otherwise passes the known-to-be-valid byte_order argument to
667 * us.
668 *
669 * Just ignore the option.
670 */
671 return;
672 }
673
674 /*
675 * If this option can appear only once in a block, this call
676 * will fail on the second and later occurrences of the option;
677 * we silently ignore the failure.
678 */
679 wtap_block_add_uint64_option(wblock->block, option_code, uint64);
680 }
681}
682
683void
684pcapng_process_int64_option(wtapng_block_t *wblock,
685 section_info_t *section_info,
686 pcapng_opt_byte_order_e byte_order,
687 uint16_t option_code, uint16_t option_length,
688 const uint8_t *option_content)
689{
690 int64_t int64;
691
692 if (option_length == 8) {
693 /* Don't cast a int8_t * into a int64_t *--the
694 * uint8_t * may not point to something that's
695 * aligned correctly.
696 */
697 memcpy(&int64, option_content, sizeof(int64_t));
698 switch (byte_order) {
699
700 case OPT_SECTION_BYTE_ORDER:
701 if (section_info->byte_swapped) {
702 int64 = GUINT64_SWAP_LE_BE(int64)(((guint64) ( (((guint64) (int64) & (guint64) (0x00000000000000ffUL
)) << 56) | (((guint64) (int64) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (int64) & (guint64) (0x0000000000ff0000UL
)) << 24) | (((guint64) (int64) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (int64) & (guint64) (0x000000ff00000000UL
)) >> 8) | (((guint64) (int64) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (int64) & (guint64) (0x00ff000000000000UL
)) >> 40) | (((guint64) (int64) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
703 }
704 break;
705
706 case OPT_BIG_ENDIAN:
707 int64 = GUINT64_FROM_BE(int64)(((((guint64) ( (((guint64) (int64) & (guint64) (0x00000000000000ffUL
)) << 56) | (((guint64) (int64) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (int64) & (guint64) (0x0000000000ff0000UL
)) << 24) | (((guint64) (int64) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (int64) & (guint64) (0x000000ff00000000UL
)) >> 8) | (((guint64) (int64) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (int64) & (guint64) (0x00ff000000000000UL
)) >> 40) | (((guint64) (int64) & (guint64) (0xff00000000000000UL
)) >> 56))))))
;
708 break;
709
710 case OPT_LITTLE_ENDIAN:
711 int64 = GUINT64_FROM_LE(int64)(((guint64) (int64)));
712 break;
713
714 default:
715 /*
716 * This should not happen - this is called by pcapng_process_options(),
717 * which returns an error for an invalid byte_order argument, and
718 * otherwise passes the known-to-be-valid byte_order argument to
719 * us.
720 *
721 * Just ignore the option.
722 */
723 return;
724 }
725
726 /*
727 * If this option can appear only once in a block, this call
728 * will fail on the second and later occurrences of the option;
729 * we silently ignore the failure.
730 */
731 wtap_block_add_int64_option(wblock->block, option_code, int64);
732 }
733}
734
735void
736pcapng_process_string_option(wtapng_block_t *wblock, uint16_t option_code,
737 uint16_t option_length, const uint8_t *option_content)
738{
739 const char *opt = (const char *)option_content;
740 size_t optlen = option_length;
741 char *str;
742
743 /* Validate UTF-8 encoding. */
744 str = ws_utf8_make_valid(NULL((void*)0), opt, optlen);
745
746 wtap_block_add_string_option_owned(wblock->block, option_code, str);
747}
748
749void
750pcapng_process_bytes_option(wtapng_block_t *wblock, uint16_t option_code,
751 uint16_t option_length, const uint8_t *option_content)
752{
753 wtap_block_add_bytes_option(wblock->block, option_code, (const char *)option_content, option_length);
754}
755
756static bool_Bool
757pcapng_process_custom_option_common(section_info_t *section_info,
758 uint16_t option_length,
759 const uint8_t *option_content,
760 pcapng_opt_byte_order_e byte_order,
761 uint32_t *pen,
762 int *err, char **err_info)
763{
764 if (option_length < 4) {
765 *err = WTAP_ERR_BAD_FILE-13;
766 *err_info = ws_strdup_printf("pcapng: option length (%d) too small for custom option",wmem_strdup_printf(((void*)0), "pcapng: option length (%d) too small for custom option"
, option_length)
767 option_length)wmem_strdup_printf(((void*)0), "pcapng: option length (%d) too small for custom option"
, option_length)
;
768 return false0;
769 }
770 memcpy(pen, option_content, sizeof(uint32_t));
771 switch (byte_order) {
772
773 case OPT_SECTION_BYTE_ORDER:
774 if (section_info->byte_swapped) {
775 *pen = GUINT32_SWAP_LE_BE(*pen)(((guint32) ( (((guint32) (*pen) & (guint32) 0x000000ffU)
<< 24) | (((guint32) (*pen) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (*pen) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (*pen) & (guint32) 0xff000000U
) >> 24))))
;
776 }
777 break;
778
779 case OPT_BIG_ENDIAN:
780 *pen = GUINT32_FROM_BE(*pen)(((((guint32) ( (((guint32) (*pen) & (guint32) 0x000000ffU
) << 24) | (((guint32) (*pen) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (*pen) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (*pen) & (guint32) 0xff000000U
) >> 24))))))
;
781 break;
782
783 case OPT_LITTLE_ENDIAN:
784 *pen = GUINT32_FROM_LE(*pen)(((guint32) (*pen)));
785 break;
786
787 default:
788 /*
789 * This should not happen - this is called by pcapng_process_options(),
790 * which returns an error for an invalid byte_order argument, and
791 * otherwise passes the known-to-be-valid byte_order argument to
792 * us.
793 */
794 *err = WTAP_ERR_INTERNAL-21;
795 *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_process_custom_option()",wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_process_custom_option()"
, byte_order)
796 byte_order)wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_process_custom_option()"
, byte_order)
;
797 return false0;
798 }
799 return true1;
800}
801
802static bool_Bool
803pcapng_process_custom_string_option(wtapng_block_t *wblock,
804 section_info_t *section_info,
805 uint16_t option_code,
806 uint16_t option_length,
807 const uint8_t *option_content,
808 pcapng_opt_byte_order_e byte_order,
809 int *err, char **err_info)
810{
811 uint32_t pen;
812 bool_Bool ret;
813
814 if (!pcapng_process_custom_option_common(section_info, option_length,
815 option_content, byte_order,
816 &pen, err, err_info)) {
817 return false0;
818 }
819 ret = wtap_block_add_custom_string_option(wblock->block, option_code, pen, option_content + 4, option_length - 4) == WTAP_OPTTYPE_SUCCESS;
820 ws_debug("returning %d", ret)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 820, __func__, "returning %d", ret); } } while (0)
;
821 return ret;
822}
823
824static bool_Bool
825pcapng_process_custom_binary_option(wtapng_block_t *wblock,
826 section_info_t *section_info,
827 uint16_t option_code,
828 uint16_t option_length,
829 const uint8_t *option_content,
830 pcapng_opt_byte_order_e byte_order,
831 int *err, char **err_info)
832{
833 uint32_t pen;
834 pcapng_custom_block_enterprise_handler_t* pen_handler;
835 bool_Bool ret;
836
837 if (!pcapng_process_custom_option_common(section_info, option_length,
838 option_content, byte_order,
839 &pen, err, err_info)) {
840 return false0;
841 }
842
843 pen_handler = (pcapng_custom_block_enterprise_handler_t*)g_hash_table_lookup(custom_enterprise_handlers, GUINT_TO_POINTER(pen)((gpointer) (gulong) (pen)));
844
845 if (pen_handler != NULL((void*)0))
846 {
847 ret = pen_handler->processor(wblock, section_info, option_code, option_content + 4, option_length - 4);
848 }
849 else
850 {
851 ret = wtap_block_add_custom_binary_option_from_data(wblock->block, option_code, pen, option_content + 4, option_length - 4) == WTAP_OPTTYPE_SUCCESS;
852 ws_debug("Custom option type %u (0x%04x) with unknown pen %u with custom data of length %u", option_code, option_code, pen, option_length - 4)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 852, __func__, "Custom option type %u (0x%04x) with unknown pen %u with custom data of length %u"
, option_code, option_code, pen, option_length - 4); } } while
(0)
;
853 }
854
855 ws_debug("returning %d", ret)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 855, __func__, "returning %d", ret); } } while (0)
;
856 return ret;
857}
858
859#ifdef HAVE_PLUGINS1
860static bool_Bool
861pcapng_process_unhandled_option(wtapng_block_t *wblock,
862 section_info_t *section_info,
863 uint16_t option_code, uint16_t option_length,
864 const uint8_t *option_content,
865 int *err, char **err_info)
866{
867 GHashTable *option_handlers;
868 option_handler *handler;
869
870 /*
871 * Get the table of option handlers for this block type.
872 */
873 option_handlers = get_option_handlers(wblock->type);
874
875 /*
876 * Do we have a handler for this packet block option code?
877 */
878 if (option_handlers != NULL((void*)0) &&
879 (handler = (option_handler *)g_hash_table_lookup(option_handlers,
880 GUINT_TO_POINTER((unsigned)option_code)((gpointer) (gulong) ((unsigned)option_code)))) != NULL((void*)0)) {
881 /* Yes - call the handler. */
882 if (!handler->parser(wblock->block, section_info->byte_swapped,
883 option_length, option_content, err, err_info))
884 /* XXX - free anything? */
885 return false0;
886 }
887 return true1;
888}
889#else
890static bool_Bool
891pcapng_process_unhandled_option(wtapng_block_t *wblock _U___attribute__((unused)),
892 section_info_t *section_info _U___attribute__((unused)),
893 uint16_t option_code _U___attribute__((unused)), uint16_t option_length _U___attribute__((unused)),
894 const uint8_t *option_content _U___attribute__((unused)),
895 int *err _U___attribute__((unused)), char **err_info _U___attribute__((unused)))
896{
897 return true1;
898}
899#endif
900
901bool_Bool
902pcapng_process_options(FILE_T fh, wtapng_block_t *wblock,
903 section_info_t *section_info,
904 unsigned opt_cont_buf_len,
905 bool_Bool (*process_option)(wtapng_block_t *,
906 section_info_t *,
907 uint16_t, uint16_t,
908 const uint8_t *,
909 int *, char **),
910 pcapng_opt_byte_order_e byte_order,
911 int *err, char **err_info)
912{
913 uint8_t *option_content; /* Allocate as large as the options block */
914 unsigned opt_bytes_remaining;
915 const uint8_t *option_ptr;
916 const pcapng_option_header_t *oh;
917 uint16_t option_code, option_length;
918 unsigned rounded_option_length;
919
920 ws_debug("Options %u bytes", opt_cont_buf_len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 920, __func__, "Options %u bytes", opt_cont_buf_len); } } while
(0)
;
921 if (opt_cont_buf_len == 0) {
922 /* No options, so nothing to do */
923 return true1;
924 }
925
926 /* Allocate enough memory to hold all options */
927 option_content = (uint8_t *)g_try_malloc(opt_cont_buf_len);
928 if (option_content == NULL((void*)0)) {
929 *err = ENOMEM12; /* we assume we're out of memory */
930 return false0;
931 }
932
933 /* Read all the options into the buffer */
934 if (!wtap_read_bytes(fh, option_content, opt_cont_buf_len, err, err_info)) {
935 ws_debug("failed to read options")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 935, __func__, "failed to read options"); } } while (0)
;
936 g_free(option_content);
937 return false0;
938 }
939
940 /*
941 * Now process them.
942 * option_ptr starts out aligned on at least a 4-byte boundary, as
943 * that's what g_try_malloc() gives us, and each option is padded
944 * to a length that's a multiple of 4 bytes, so it remains aligned.
945 */
946 option_ptr = &option_content[0];
947 opt_bytes_remaining = opt_cont_buf_len;
948 while (opt_bytes_remaining != 0) {
949 /* Get option header. */
950 oh = (const pcapng_option_header_t *)(const void *)option_ptr;
951 /* Sanity check: don't run past the end of the options. */
952 if (sizeof (*oh) > opt_bytes_remaining) {
953 *err = WTAP_ERR_BAD_FILE-13;
954 *err_info = ws_strdup_printf("pcapng: Not enough data for option header")wmem_strdup_printf(((void*)0), "pcapng: Not enough data for option header"
)
;
955 g_free(option_content);
956 return false0;
957 }
958 option_code = oh->option_code;
959 option_length = oh->option_length;
960 switch (byte_order) {
961
962 case OPT_SECTION_BYTE_ORDER:
963 if (section_info->byte_swapped) {
964 option_code = GUINT16_SWAP_LE_BE(option_code)(((guint16) ( (guint16) ((guint16) (option_code) >> 8) |
(guint16) ((guint16) (option_code) << 8))))
;
965 option_length = GUINT16_SWAP_LE_BE(option_length)(((guint16) ( (guint16) ((guint16) (option_length) >> 8
) | (guint16) ((guint16) (option_length) << 8))))
;
966 }
967 break;
968
969 case OPT_BIG_ENDIAN:
970 option_code = GUINT16_FROM_BE(option_code)(((((guint16) ( (guint16) ((guint16) (option_code) >> 8
) | (guint16) ((guint16) (option_code) << 8))))))
;
971 option_length = GUINT16_FROM_BE(option_length)(((((guint16) ( (guint16) ((guint16) (option_length) >>
8) | (guint16) ((guint16) (option_length) << 8))))))
;
972 break;
973
974 case OPT_LITTLE_ENDIAN:
975 option_code = GUINT16_FROM_LE(option_code)(((guint16) (option_code)));
976 option_length = GUINT16_FROM_LE(option_length)(((guint16) (option_length)));
977 break;
978
979 default:
980 /* Don't do that. */
981 *err = WTAP_ERR_INTERNAL-21;
982 *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_process_options()",wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_process_options()"
, byte_order)
983 byte_order)wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_process_options()"
, byte_order)
;
984 return false0;
985 }
986 option_ptr += sizeof (*oh); /* 4 bytes, so it remains aligned */
987 opt_bytes_remaining -= sizeof (*oh);
988
989 /* Round up option length to a multiple of 4. */
990 rounded_option_length = WS_ROUNDUP_4(option_length)(((option_length) + ((unsigned)(4U-1U))) & (~((unsigned)(
4U-1U))))
;
991
992 /* Sanity check: don't run past the end of the options. */
993 if (rounded_option_length > opt_bytes_remaining) {
994 *err = WTAP_ERR_BAD_FILE-13;
995 *err_info = ws_strdup_printf("pcapng: Not enough data to handle option of length %u",wmem_strdup_printf(((void*)0), "pcapng: Not enough data to handle option of length %u"
, option_length)
996 option_length)wmem_strdup_printf(((void*)0), "pcapng: Not enough data to handle option of length %u"
, option_length)
;
997 g_free(option_content);
998 return false0;
999 }
1000
1001 switch (option_code) {
1002 case(OPT_EOFOPT0): /* opt_endofopt */
1003 if (opt_bytes_remaining != 0) {
1004 ws_debug("%u bytes after opt_endofopt", opt_bytes_remaining)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1004, __func__, "%u bytes after opt_endofopt", opt_bytes_remaining
); } } while (0)
;
1005 }
1006 /* padding should be ok here, just get out of this */
1007 opt_bytes_remaining = rounded_option_length;
1008 break;
1009 case(OPT_COMMENT1):
1010 pcapng_process_string_option(wblock, option_code, option_length,
1011 option_ptr);
1012 break;
1013 case(OPT_CUSTOM_STR_COPY2988):
1014 case(OPT_CUSTOM_STR_NO_COPY19372):
1015 if (!pcapng_process_custom_string_option(wblock, section_info,
1016 option_code,
1017 option_length,
1018 option_ptr,
1019 byte_order,
1020 err, err_info)) {
1021 g_free(option_content);
1022 return false0;
1023 }
1024 break;
1025 case(OPT_CUSTOM_BIN_COPY2989):
1026 case(OPT_CUSTOM_BIN_NO_COPY19373):
1027 if (!pcapng_process_custom_binary_option(wblock, section_info,
1028 option_code,
1029 option_length,
1030 option_ptr,
1031 byte_order,
1032 err, err_info)) {
1033 g_free(option_content);
1034 return false0;
1035 }
1036 break;
1037 default:
1038 if (process_option == NULL((void*)0) ||
1039 !(*process_option)(wblock, section_info, option_code,
1040 option_length, option_ptr,
1041 err, err_info)) {
1042 g_free(option_content);
1043 return false0;
1044 }
1045 break;
1046 }
1047 option_ptr += rounded_option_length; /* multiple of 4 bytes, so it remains aligned */
1048 opt_bytes_remaining -= rounded_option_length;
1049 }
1050 g_free(option_content);
1051 return true1;
1052}
1053
1054typedef enum {
1055 PCAPNG_BLOCK_OK,
1056 PCAPNG_BLOCK_NOT_SHB,
1057 PCAPNG_BLOCK_ERROR
1058} block_return_val;
1059
1060static bool_Bool
1061pcapng_process_section_header_block_option(wtapng_block_t *wblock,
1062 section_info_t *section_info,
1063 uint16_t option_code,
1064 uint16_t option_length,
1065 const uint8_t *option_content,
1066 int *err, char **err_info)
1067{
1068 /*
1069 * Handle option content.
1070 *
1071 * ***DO NOT*** add any items to this table that are not
1072 * standardized option codes in either section 3.5 "Options"
1073 * of the current pcapng spec, at
1074 *
1075 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1076 *
1077 * or in the list of options in section 4.1 "Section Header Block"
1078 * of the current pcapng spec, at
1079 *
1080 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
1081 *
1082 * All option codes in this switch statement here must be listed
1083 * in one of those places as standardized option types.
1084 */
1085 switch (option_code) {
1086 case(OPT_SHB_HARDWARE2):
1087 pcapng_process_string_option(wblock, option_code, option_length,
1088 option_content);
1089 break;
1090 case(OPT_SHB_OS3):
1091 pcapng_process_string_option(wblock, option_code, option_length,
1092 option_content);
1093 break;
1094 case(OPT_SHB_USERAPPL4):
1095 pcapng_process_string_option(wblock, option_code, option_length,
1096 option_content);
1097 break;
1098 default:
1099 if (!pcapng_process_unhandled_option(wblock, section_info,
1100 option_code, option_length,
1101 option_content,
1102 err, err_info))
1103 return false0;
1104 break;
1105 }
1106 return true1;
1107}
1108
1109static block_return_val
1110pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
1111 section_info_t *section_info,
1112 wtapng_block_t *wblock,
1113 int *err, char **err_info)
1114{
1115 bool_Bool byte_swapped;
1116 uint16_t version_major;
1117 uint16_t version_minor;
1118 unsigned opt_cont_buf_len;
1119 pcapng_section_header_block_t shb;
1120 wtapng_section_mandatory_t* section_data;
1121
1122 /* read fixed-length part of the block */
1123 if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
1124 /*
1125 * Even if this is just a short read, report it as an error.
1126 * It *is* a read error except when we're doing an open, in
1127 * which case it's a "this isn't a pcapng file" indication.
1128 * The open code will call us directly, and treat a short
1129 * read error as such an indication.
1130 */
1131 return PCAPNG_BLOCK_ERROR;
1132 }
1133
1134 /* is the magic number one we expect? */
1135 switch (shb.magic) {
1136 case(0x1A2B3C4D):
1137 /* this seems pcapng with correct byte order */
1138 byte_swapped = false0;
1139 version_major = shb.version_major;
1140 version_minor = shb.version_minor;
1141
1142 ws_debug("SHB (our byte order) V%u.%u, len %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1143, __func__, "SHB (our byte order) V%u.%u, len %u", version_major
, version_minor, bh->block_total_length); } } while (0)
1143 version_major, version_minor, bh->block_total_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1143, __func__, "SHB (our byte order) V%u.%u, len %u", version_major
, version_minor, bh->block_total_length); } } while (0)
;
1144 break;
1145 case(0x4D3C2B1A):
1146 /* this seems pcapng with swapped byte order */
1147 byte_swapped = true1;
1148 version_major = GUINT16_SWAP_LE_BE(shb.version_major)(((guint16) ( (guint16) ((guint16) (shb.version_major) >>
8) | (guint16) ((guint16) (shb.version_major) << 8))))
;
1149 version_minor = GUINT16_SWAP_LE_BE(shb.version_minor)(((guint16) ( (guint16) ((guint16) (shb.version_minor) >>
8) | (guint16) ((guint16) (shb.version_minor) << 8))))
;
1150
1151 /* tweak the block length to meet current swapping that we know now */
1152 bh->block_total_length = GUINT32_SWAP_LE_BE(bh->block_total_length)(((guint32) ( (((guint32) (bh->block_total_length) & (
guint32) 0x000000ffU) << 24) | (((guint32) (bh->block_total_length
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (bh->
block_total_length) & (guint32) 0x00ff0000U) >> 8) |
(((guint32) (bh->block_total_length) & (guint32) 0xff000000U
) >> 24))))
;
1153
1154 ws_debug("SHB (byte-swapped) V%u.%u, len %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1155, __func__, "SHB (byte-swapped) V%u.%u, len %u", version_major
, version_minor, bh->block_total_length); } } while (0)
1155 version_major, version_minor, bh->block_total_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1155, __func__, "SHB (byte-swapped) V%u.%u, len %u", version_major
, version_minor, bh->block_total_length); } } while (0)
;
1156 break;
1157 default:
1158 /* Not a "pcapng" magic number we know about. */
1159 *err = WTAP_ERR_BAD_FILE-13;
1160 *err_info = ws_strdup_printf("pcapng: unknown byte-order magic number 0x%08x", shb.magic)wmem_strdup_printf(((void*)0), "pcapng: unknown byte-order magic number 0x%08x"
, shb.magic)
;
1161
1162 /*
1163 * See above comment about PCAPNG_BLOCK_NOT_SHB.
1164 */
1165 return PCAPNG_BLOCK_NOT_SHB;
1166 }
1167
1168 /*
1169 * Add padding bytes to the block total length.
1170 *
1171 * See the comment in pcapng_read_block() for a long discussion
1172 * of this.
1173 */
1174 bh->block_total_length = WS_ROUNDUP_4(bh->block_total_length)(((bh->block_total_length) + ((unsigned)(4U-1U))) & (~
((unsigned)(4U-1U))))
;
1175
1176 /*
1177 * Is this block long enough to be an SHB?
1178 */
1179 if (bh->block_total_length < MIN_SHB_SIZE((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t) + sizeof
(uint32_t))) + sizeof(pcapng_section_header_block_t)))
) {
1180 /*
1181 * No.
1182 */
1183 *err = WTAP_ERR_BAD_FILE-13;
1184 *err_info = ws_strdup_printf("pcapng: total block length %u of an SHB is less than the minimum SHB size %u",wmem_strdup_printf(((void*)0), "pcapng: total block length %u of an SHB is less than the minimum SHB size %u"
, bh->block_total_length, ((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t
) + sizeof(uint32_t))) + sizeof(pcapng_section_header_block_t
))))
1185 bh->block_total_length, MIN_SHB_SIZE)wmem_strdup_printf(((void*)0), "pcapng: total block length %u of an SHB is less than the minimum SHB size %u"
, bh->block_total_length, ((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t
) + sizeof(uint32_t))) + sizeof(pcapng_section_header_block_t
))))
;
1186 return PCAPNG_BLOCK_ERROR;
1187 }
1188
1189 /* OK, at this point we assume it's a pcapng file.
1190
1191 Don't try to allocate memory for a huge number of options, as
1192 that might fail and, even if it succeeds, it might not leave
1193 any address space or memory+backing store for anything else.
1194
1195 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1196 We check for this *after* checking the SHB for its byte
1197 order magic number, so that non-pcapng files are less
1198 likely to be treated as bad pcapng files. */
1199 if (bh->block_total_length > MAX_BLOCK_SIZE(((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t) + sizeof
(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t))) + (128U
*1024U*1024U) + 131072)
) {
1200 *err = WTAP_ERR_BAD_FILE-13;
1201 *err_info = ws_strdup_printf("pcapng: total block length %u is too large (> %u)",wmem_strdup_printf(((void*)0), "pcapng: total block length %u is too large (> %u)"
, bh->block_total_length, (((uint32_t)(((uint32_t)(sizeof(
pcapng_block_header_t) + sizeof(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t
))) + (128U*1024U*1024U) + 131072))
1202 bh->block_total_length, MAX_BLOCK_SIZE)wmem_strdup_printf(((void*)0), "pcapng: total block length %u is too large (> %u)"
, bh->block_total_length, (((uint32_t)(((uint32_t)(sizeof(
pcapng_block_header_t) + sizeof(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t
))) + (128U*1024U*1024U) + 131072))
;
1203 return PCAPNG_BLOCK_ERROR;
1204 }
1205
1206 /* Currently only SHB versions 1.0 and 1.2 are supported;
1207 version 1.2 is treated as being the same as version 1.0.
1208 See the current version of the pcapng specification.
1209
1210 Version 1.2 is written by some programs that write additional
1211 block types (which can be read by any code that handles them,
1212 regarless of whether the minor version if 0 or 2, so that's
1213 not a reason to change the minor version number).
1214
1215 XXX - the pcapng specification says that readers should
1216 just ignore sections with an unsupported version number;
1217 presumably they can also report an error if they skip
1218 all the way to the end of the file without finding
1219 any versions that they support. */
1220 if (!(version_major == 1 &&
1221 (version_minor == 0 || version_minor == 2))) {
1222 *err = WTAP_ERR_UNSUPPORTED-4;
1223 *err_info = ws_strdup_printf("pcapng: unknown SHB version %u.%u",wmem_strdup_printf(((void*)0), "pcapng: unknown SHB version %u.%u"
, version_major, version_minor)
1224 version_major, version_minor)wmem_strdup_printf(((void*)0), "pcapng: unknown SHB version %u.%u"
, version_major, version_minor)
;
1225 return PCAPNG_BLOCK_ERROR;
1226 }
1227
1228 memset(section_info, 0, sizeof(section_info_t));
1229 section_info->byte_swapped = byte_swapped;
1230 section_info->version_major = version_major;
1231 section_info->version_minor = version_minor;
1232
1233 /*
1234 * Set wblock->block to a newly-allocated section header block.
1235 */
1236 wblock->block = wtap_block_create(WTAP_BLOCK_SECTION);
1237
1238 /*
1239 * Set the mandatory values for the block.
1240 */
1241 section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1242 /* 64bit section_length (currently unused) */
1243 if (section_info->byte_swapped) {
1244 section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length)(((guint64) ( (((guint64) (shb.section_length) & (guint64
) (0x00000000000000ffUL)) << 56) | (((guint64) (shb.section_length
) & (guint64) (0x000000000000ff00UL)) << 40) | (((guint64
) (shb.section_length) & (guint64) (0x0000000000ff0000UL)
) << 24) | (((guint64) (shb.section_length) & (guint64
) (0x00000000ff000000UL)) << 8) | (((guint64) (shb.section_length
) & (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (shb.section_length) & (guint64) (0x0000ff0000000000UL)
) >> 24) | (((guint64) (shb.section_length) & (guint64
) (0x00ff000000000000UL)) >> 40) | (((guint64) (shb.section_length
) & (guint64) (0xff00000000000000UL)) >> 56))))
;
1245 } else {
1246 section_data->section_length = shb.section_length;
1247 }
1248
1249 /* Options */
1250 opt_cont_buf_len = bh->block_total_length - MIN_SHB_SIZE((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t) + sizeof
(uint32_t))) + sizeof(pcapng_section_header_block_t)))
;
1251 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
1252 pcapng_process_section_header_block_option,
1253 OPT_SECTION_BYTE_ORDER, err, err_info))
1254 return PCAPNG_BLOCK_ERROR;
1255
1256 /*
1257 * We don't return these to the caller in pcapng_read().
1258 */
1259 wblock->internal = true1;
1260
1261 return PCAPNG_BLOCK_OK;
1262}
1263
1264static bool_Bool
1265pcapng_process_if_descr_block_option(wtapng_block_t *wblock,
1266 section_info_t *section_info,
1267 uint16_t option_code,
1268 uint16_t option_length,
1269 const uint8_t *option_content,
1270 int *err, char **err_info)
1271{
1272 if_filter_opt_t if_filter;
1273
1274 /*
1275 * Handle option content.
1276 *
1277 * ***DO NOT*** add any items to this table that are not
1278 * standardized option codes in either section 3.5 "Options"
1279 * of the current pcapng spec, at
1280 *
1281 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1282 *
1283 * or in the list of options in section 4.1 "Section Header Block"
1284 * of the current pcapng spec, at
1285 *
1286 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
1287 *
1288 * All option codes in this switch statement here must be listed
1289 * in one of those places as standardized option types.
1290 */
1291 switch (option_code) {
1292 case(OPT_IDB_NAME2): /* if_name */
1293 pcapng_process_string_option(wblock, option_code, option_length,
1294 option_content);
1295 break;
1296 case(OPT_IDB_DESCRIPTION3): /* if_description */
1297 pcapng_process_string_option(wblock, option_code, option_length,
1298 option_content);
1299 break;
1300 case(OPT_IDB_IP4ADDR4):
1301 /*
1302 * Interface network address and netmask. This option can be
1303 * repeated multiple times within the same Interface
1304 * Description Block when multiple IPv4 addresses are assigned
1305 * to the interface. 192 168 1 1 255 255 255 0
1306 */
1307 break;
1308 case(OPT_IDB_IP6ADDR5):
1309 /*
1310 * Interface network address and prefix length (stored in the
1311 * last byte). This option can be repeated multiple times
1312 * within the same Interface Description Block when multiple
1313 * IPv6 addresses are assigned to the interface.
1314 * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
1315 * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
1316 * 40"
1317 */
1318 break;
1319 case(OPT_IDB_MACADDR6):
1320 /*
1321 * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
1322 */
1323 break;
1324 case(OPT_IDB_EUIADDR7):
1325 /*
1326 * Interface Hardware EUI address (64 bits), if available.
1327 * 02 34 56 FF FE 78 9A BC
1328 */
1329 break;
1330 case(OPT_IDB_SPEED8): /* if_speed */
1331 pcapng_process_uint64_option(wblock, section_info,
1332 OPT_SECTION_BYTE_ORDER,
1333 option_code, option_length,
1334 option_content);
1335 break;
1336 case(OPT_IDB_TSRESOL9): /* if_tsresol */
1337 pcapng_process_uint8_option(wblock, option_code, option_length,
1338 option_content);
1339 break;
1340 case(OPT_IDB_TZONE10): /* if_tzone */
1341 /*
1342 * Time zone for GMT support. This option has never been
1343 * specified in greater detail and, unless it were to identify
1344 * something such as an IANA time zone database timezone,
1345 * would be insufficient for converting between UTC and local
1346 * time. Therefore, it SHOULD NOT be used; instead, the
1347 * if_iana_tzname option SHOULD be used if time zone
1348 * information is to be specified.
1349 *
1350 * Given that, we don't do anything with it.
1351 */
1352 break;
1353 case(OPT_IDB_FILTER11): /* if_filter */
1354 if (option_length < 1) {
1355 *err = WTAP_ERR_BAD_FILE-13;
1356 *err_info = ws_strdup_printf("pcapng: packet block verdict option length %u is < 1",wmem_strdup_printf(((void*)0), "pcapng: packet block verdict option length %u is < 1"
, option_length)
1357 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block verdict option length %u is < 1"
, option_length)
;
1358 /* XXX - free anything? */
1359 return false0;
1360 }
1361 /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
1362 * or BPF bytecode.
1363 */
1364 if (option_content[0] == 0) {
1365 if_filter.type = if_filter_pcap;
1366 if_filter.data.filter_str = g_strndup((char *)option_content+1, option_length-1);
1367 ws_debug("filter_str %s option_length %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1368, __func__, "filter_str %s option_length %u", if_filter
.data.filter_str, option_length); } } while (0)
1368 if_filter.data.filter_str, option_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1368, __func__, "filter_str %s option_length %u", if_filter
.data.filter_str, option_length); } } while (0)
;
1369 /* Fails with multiple options; we silently ignore the failure */
1370 wtap_block_add_if_filter_option(wblock->block, option_code, &if_filter);
1371 g_free(if_filter.data.filter_str);
1372 } else if (option_content[0] == 1) {
1373 /*
1374 * XXX - byte-swap the code and k fields
1375 * of each instruction as needed!
1376 *
1377 * XXX - what if option_length-1 is not a
1378 * multiple of the size of a BPF instruction?
1379 */
1380 unsigned num_insns;
1381 const uint8_t *insn_in;
1382
1383 if_filter.type = if_filter_bpf;
1384 num_insns = (option_length-1)/8;
1385 insn_in = option_content+1;
1386 if_filter.data.bpf_prog.bpf_prog_len = num_insns;
1387 if_filter.data.bpf_prog.bpf_prog = g_new(wtap_bpf_insn_t, num_insns)((wtap_bpf_insn_t *) g_malloc_n ((num_insns), sizeof (wtap_bpf_insn_t
)))
;
1388 for (unsigned i = 0; i < num_insns; i++) {
1389 wtap_bpf_insn_t *insn = &if_filter.data.bpf_prog.bpf_prog[i];
1390
1391 memcpy(&insn->code, insn_in, 2);
1392 if (section_info->byte_swapped)
1393 insn->code = GUINT16_SWAP_LE_BE(insn->code)(((guint16) ( (guint16) ((guint16) (insn->code) >> 8
) | (guint16) ((guint16) (insn->code) << 8))))
;
1394 insn_in += 2;
1395 memcpy(&insn->jt, insn_in, 1);
1396 insn_in += 1;
1397 memcpy(&insn->jf, insn_in, 1);
1398 insn_in += 1;
1399 memcpy(&insn->k, insn_in, 4);
1400 if (section_info->byte_swapped)
1401 insn->k = GUINT32_SWAP_LE_BE(insn->k)(((guint32) ( (((guint32) (insn->k) & (guint32) 0x000000ffU
) << 24) | (((guint32) (insn->k) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (insn->k) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (insn->k) & (guint32) 0xff000000U
) >> 24))))
;
1402 insn_in += 4;
1403 }
1404 /* Fails with multiple options; we silently ignore the failure */
1405 wtap_block_add_if_filter_option(wblock->block, option_code, &if_filter);
1406 g_free(if_filter.data.bpf_prog.bpf_prog);
1407 }
1408 break;
1409 case(OPT_IDB_OS12): /* if_os */
1410 /*
1411 * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
1412 * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
1413 * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
1414 */
1415 pcapng_process_string_option(wblock, option_code, option_length,
1416 option_content);
1417 break;
1418 case(OPT_IDB_FCSLEN13): /* if_fcslen */
1419 pcapng_process_uint8_option(wblock, option_code, option_length,
1420 option_content);
1421 break;
1422 case(OPT_IDB_TSOFFSET14):
1423 /*
1424 * A 64-bit integer value that specifies an offset (in
1425 * seconds) that must be added to the timestamp of each packet
1426 * to obtain the absolute timestamp of a packet. If this optio
1427 * is not present, an offset of 0 is assumed (i.e., timestamps
1428 * in blocks are absolute timestamps.)
1429 */
1430 pcapng_process_int64_option(wblock, section_info,
1431 OPT_SECTION_BYTE_ORDER,
1432 option_code, option_length,
1433 option_content);
1434 break;
1435 case(OPT_IDB_HARDWARE15): /* if_hardware */
1436 pcapng_process_string_option(wblock, option_code, option_length,
1437 option_content);
1438 break;
1439 case(OPT_IDB_TXSPEED16): /* if_txspeed */
1440 pcapng_process_uint64_option(wblock, section_info,
1441 OPT_SECTION_BYTE_ORDER,
1442 option_code, option_length,
1443 option_content);
1444 break;
1445 case(OPT_IDB_RXSPEED17): /* if_rxspeed */
1446 pcapng_process_uint64_option(wblock, section_info,
1447 OPT_SECTION_BYTE_ORDER,
1448 option_code, option_length,
1449 option_content);
1450 break;
1451 case(OPT_IDB_IANA_TZNAME18): /* if_iana_tzname */
1452 pcapng_process_string_option(wblock, option_code, option_length,
1453 option_content);
1454 break;
1455 default:
1456 if (!pcapng_process_unhandled_option(wblock, section_info,
1457 option_code, option_length,
1458 option_content,
1459 err, err_info))
1460 return false0;
1461 break;
1462 }
1463 return true1;
1464}
1465
1466/* "Interface Description Block" */
1467static bool_Bool
1468pcapng_read_if_descr_block(wtap *wth, FILE_T fh, uint32_t block_type _U___attribute__((unused)),
1469 uint32_t block_content_length,
1470 section_info_t *section_info,
1471 wtapng_block_t *wblock, int *err, char **err_info)
1472{
1473 /* Default time stamp resolution is 10^6 */
1474 uint64_t time_units_per_second = 1000000;
1475 int tsprecision = 6;
1476 unsigned opt_cont_buf_len;
1477 pcapng_interface_description_block_t idb;
1478 wtapng_if_descr_mandatory_t* if_descr_mand;
1479 unsigned link_type;
1480 uint8_t if_tsresol;
1481
1482 /*
1483 * Is this block long enough to be an IDB?
1484 */
1485 if (block_content_length < sizeof idb) {
1486 /*
1487 * No.
1488 */
1489 *err = WTAP_ERR_BAD_FILE-13;
1490 *err_info = ws_strdup_printf("pcapng: block content length %u of an IDB is less than the minimum IDB content size %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an IDB is less than the minimum IDB content size %zu"
, block_content_length, sizeof idb)
1491 block_content_length, sizeof idb)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an IDB is less than the minimum IDB content size %zu"
, block_content_length, sizeof idb)
;
1492 return false0;
1493 }
1494
1495 /* read block content */
1496 if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
1497 ws_debug("failed to read IDB")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1497, __func__, "failed to read IDB"); } } while (0)
;
1498 return false0;
1499 }
1500
1501 /*
1502 * Set wblock->block to a newly-allocated interface ID and information
1503 * block.
1504 */
1505 wblock->block = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
1506
1507 /*
1508 * Set the mandatory values for the block.
1509 */
1510 if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1511 if (section_info->byte_swapped) {
1512 link_type = GUINT16_SWAP_LE_BE(idb.linktype)(((guint16) ( (guint16) ((guint16) (idb.linktype) >> 8)
| (guint16) ((guint16) (idb.linktype) << 8))))
;
1513 if_descr_mand->snap_len = GUINT32_SWAP_LE_BE(idb.snaplen)(((guint32) ( (((guint32) (idb.snaplen) & (guint32) 0x000000ffU
) << 24) | (((guint32) (idb.snaplen) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (idb.snaplen) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (idb.snaplen) & (guint32) 0xff000000U
) >> 24))))
;
1514 } else {
1515 link_type = idb.linktype;
1516 if_descr_mand->snap_len = idb.snaplen;
1517 }
1518
1519 if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(link_type);
1520
1521 ws_debug("IDB link_type %u (%s), snap %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1524, __func__, "IDB link_type %u (%s), snap %u", link_type
, wtap_encap_description(if_descr_mand->wtap_encap), if_descr_mand
->snap_len); } } while (0)
1522 link_type,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1524, __func__, "IDB link_type %u (%s), snap %u", link_type
, wtap_encap_description(if_descr_mand->wtap_encap), if_descr_mand
->snap_len); } } while (0)
1523 wtap_encap_description(if_descr_mand->wtap_encap),do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1524, __func__, "IDB link_type %u (%s), snap %u", link_type
, wtap_encap_description(if_descr_mand->wtap_encap), if_descr_mand
->snap_len); } } while (0)
1524 if_descr_mand->snap_len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1524, __func__, "IDB link_type %u (%s), snap %u", link_type
, wtap_encap_description(if_descr_mand->wtap_encap), if_descr_mand
->snap_len); } } while (0)
;
1525
1526 if (if_descr_mand->snap_len > wtap_max_snaplen_for_encap(if_descr_mand->wtap_encap)) {
1527 /*
1528 * We do not use this value, maybe we should check the
1529 * snap_len of the packets against it. For now, only warn.
1530 */
1531 ws_debug("snapshot length %u unrealistic.",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1532, __func__, "snapshot length %u unrealistic.", if_descr_mand
->snap_len); } } while (0)
1532 if_descr_mand->snap_len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1532, __func__, "snapshot length %u unrealistic.", if_descr_mand
->snap_len); } } while (0)
;
1533 /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;*/
1534 }
1535
1536 /* Options */
1537 opt_cont_buf_len = block_content_length - sizeof idb;
1538 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
1539 pcapng_process_if_descr_block_option,
1540 OPT_SECTION_BYTE_ORDER, err, err_info))
1541 return false0;
1542
1543 /*
1544 * Did we get a time stamp precision option?
1545 */
1546 if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_TSRESOL9,
1547 &if_tsresol) == WTAP_OPTTYPE_SUCCESS) {
1548 /*
1549 * Yes. Set time_units_per_second appropriately.
1550 */
1551 uint8_t exponent;
1552
1553 exponent = (uint8_t)(if_tsresol & 0x7f);
1554 if (if_tsresol & 0x80) {
1555 /*
1556 * 2^63 fits in a 64-bit unsigned number; 2^64 does not.
1557 *
1558 * ((2^64-1)/(2^63) is about 1.99, so, in practice, that
1559 * fine a time stamp resolution works only if you start
1560 * capturing at the Unix/POSIX epoch and capture for about
1561 * 1.9 seconds, so the maximum useful power-of-2 exponent
1562 * in a pcapng file is less than 63.)
1563 */
1564 if (exponent > 63) {
1565 /*
1566 * Time units per second won't fit in a 64-bit integer,
1567 * so Wireshark's current code can't read the file.
1568 */
1569 *err = WTAP_ERR_UNSUPPORTED-4;
1570 *err_info = ws_strdup_printf("pcapng: IDB power-of-2 time stamp resolution %u > 63",wmem_strdup_printf(((void*)0), "pcapng: IDB power-of-2 time stamp resolution %u > 63"
, exponent)
1571 exponent)wmem_strdup_printf(((void*)0), "pcapng: IDB power-of-2 time stamp resolution %u > 63"
, exponent)
;
1572 return false0;
1573 }
1574
1575 /* 2^exponent */
1576 time_units_per_second = UINT64_C(1)1UL << exponent;
1577
1578 /*
1579 * Set the display precision to a value large enough to
1580 * show the fractional time units we get, so that we
1581 * don't display more digits than are justified.
1582 *
1583 * (That's also used as the base-10 if_tsresol value we use
1584 * if we write this file as a pcapng file. Yes, that means
1585 * that we won't write out the exact value we read in.
1586 *
1587 * Dealing with base-2 time stamps is a bit of a mess,
1588 * thanks to humans counting with their fingers rather
1589 * than their hands, and it applies to more files than
1590 * pcapng files, e.g. ERF files.)
1591 */
1592 if (time_units_per_second >= NS_PER_S1000000000U)
1593 tsprecision = WTAP_TSPREC_NSEC9;
1594 else if (time_units_per_second >= 100000000)
1595 tsprecision = WTAP_TSPREC_10_NSEC8;
1596 else if (time_units_per_second >= 10000000)
1597 tsprecision = WTAP_TSPREC_100_NSEC7;
1598 else if (time_units_per_second >= 1000000)
1599 tsprecision = WTAP_TSPREC_USEC6;
1600 else if (time_units_per_second >= 100000)
1601 tsprecision = WTAP_TSPREC_10_USEC5;
1602 else if (time_units_per_second >= 10000)
1603 tsprecision = WTAP_TSPREC_100_USEC4;
1604 else if (time_units_per_second >= 1000)
1605 tsprecision = WTAP_TSPREC_MSEC3;
1606 else if (time_units_per_second >= 100)
1607 tsprecision = WTAP_TSPREC_10_MSEC2;
1608 else if (time_units_per_second >= 10)
1609 tsprecision = WTAP_TSPREC_100_MSEC1;
1610 else
1611 tsprecision = WTAP_TSPREC_SEC0;
1612 } else {
1613 /*
1614 * 10^19 fits in a 64-bit unsigned number; 10^20 does not.
1615 *
1616 * ((2^64-1)/(10^19) is about 1.84, so, in practice, that
1617 * fine a time stamp resolution works only if you start
1618 * capturing at the Unix/POSIX epoch and capture for about
1619 * 1.8 seconds, so the maximum useful power-of-10 exponent
1620 * in a pcapng file is less than 19.)
1621 */
1622 uint64_t result;
1623
1624 if (exponent > 19) {
1625 /*
1626 * Time units per second won't fit in a 64-bit integer,
1627 * so Wireshark's current code can't read the file.
1628 */
1629 *err = WTAP_ERR_UNSUPPORTED-4;
1630 *err_info = ws_strdup_printf("pcapng: IDB power-of-10 time stamp resolution %u > 19",wmem_strdup_printf(((void*)0), "pcapng: IDB power-of-10 time stamp resolution %u > 19"
, exponent)
1631 exponent)wmem_strdup_printf(((void*)0), "pcapng: IDB power-of-10 time stamp resolution %u > 19"
, exponent)
;
1632 return false0;
1633 }
1634
1635 /* 10^exponent */
1636 result = 1;
1637 for (unsigned i = 0; i < exponent; i++) {
1638 result *= 10U;
1639 }
1640 time_units_per_second = result;
1641
1642 /*
1643 * Set the display precision to min(exponent, WS_TSPREC_MAX),
1644 * so that we don't display more digits than are justified.
1645 * (That's also used as the base-10 if_tsresol value we use
1646 * if we write this file as a pcapng file.)
1647 */
1648 if (exponent <= WS_TSPREC_MAX9) {
1649 tsprecision = exponent;
1650 } else {
1651 tsprecision = WS_TSPREC_MAX9;
1652 }
1653 }
1654 if (time_units_per_second > (((uint64_t)1) << 32)) {
1655 ws_debug("time conversion might be inaccurate")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1655, __func__, "time conversion might be inaccurate"); } }
while (0)
;
1656 }
1657 }
1658
1659 /*
1660 * Set the time units per second for this interface.
1661 */
1662 if_descr_mand->time_units_per_second = time_units_per_second;
1663
1664 /*
1665 * Set the number of digits of precision to display (and the
1666 * number to use for this interface if saving to a pcapng
1667 * file).
1668 */
1669 if_descr_mand->tsprecision = tsprecision;
1670
1671 /*
1672 * If the per-file encapsulation isn't known, set it to this
1673 * interface's encapsulation.
1674 *
1675 * If it *is* known, and it isn't this interface's encapsulation,
1676 * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
1677 * have a single encapsulation for all interfaces in the file,
1678 * so it probably doesn't have a single encapsulation for all
1679 * packets in the file.
1680 */
1681 if (wth->file_encap == WTAP_ENCAP_NONE-2) {
1682 wth->file_encap = if_descr_mand->wtap_encap;
1683 } else {
1684 if (wth->file_encap != if_descr_mand->wtap_encap) {
1685 wth->file_encap = WTAP_ENCAP_PER_PACKET-1;
1686 }
1687 }
1688
1689 /*
1690 * The same applies to the per-file time stamp resolution.
1691 */
1692 if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN-2) {
1693 wth->file_tsprec = if_descr_mand->tsprecision;
1694 } else {
1695 if (wth->file_tsprec != if_descr_mand->tsprecision) {
1696 wth->file_tsprec = WTAP_TSPREC_PER_PACKET-1;
1697 }
1698 }
1699
1700 /*
1701 * We don't return these to the caller in pcapng_read().
1702 */
1703 wblock->internal = true1;
1704
1705 return true1;
1706}
1707
1708static bool_Bool
1709pcapng_read_decryption_secrets_block(wtap *wth _U___attribute__((unused)), FILE_T fh,
1710 uint32_t block_read _U___attribute__((unused)),
1711 uint32_t block_content_length,
1712 section_info_t *section_info,
1713 wtapng_block_t *wblock,
1714 int *err, char **err_info)
1715{
1716 unsigned to_read;
1717 pcapng_decryption_secrets_block_t dsb;
1718 wtapng_dsb_mandatory_t *dsb_mand;
1719
1720 /*
1721 * Is this block long enough to be an DSB?
1722 */
1723 if (block_content_length < sizeof dsb) {
1724 /*
1725 * No.
1726 */
1727 *err = WTAP_ERR_BAD_FILE-13;
1728 *err_info = ws_strdup_printf("pcapng: block content length %u of an DSB is less than the minimum DSB content size %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an DSB is less than the minimum DSB content size %zu"
, block_content_length, sizeof dsb)
1729 block_content_length, sizeof dsb)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an DSB is less than the minimum DSB content size %zu"
, block_content_length, sizeof dsb)
;
1730 return false0;
1731 }
1732
1733 /* read block content */
1734 if (!wtap_read_bytes(fh, &dsb, sizeof dsb, err, err_info)) {
1735 ws_debug("failed to read DSB fixed portion")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1735, __func__, "failed to read DSB fixed portion"); } } while
(0)
;
1736 return false0;
1737 }
1738
1739 /*
1740 * Set wblock->block to a newly-allocated decryption secrets block.
1741 */
1742 wblock->block = wtap_block_create(WTAP_BLOCK_DECRYPTION_SECRETS);
1743
1744 /*
1745 * Set the mandatory values for the block.
1746 */
1747 dsb_mand = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
1748 if (section_info->byte_swapped) {
1749 dsb_mand->secrets_type = GUINT32_SWAP_LE_BE(dsb.secrets_type)(((guint32) ( (((guint32) (dsb.secrets_type) & (guint32) 0x000000ffU
) << 24) | (((guint32) (dsb.secrets_type) & (guint32
) 0x0000ff00U) << 8) | (((guint32) (dsb.secrets_type) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (dsb.secrets_type
) & (guint32) 0xff000000U) >> 24))))
;
1750 dsb_mand->secrets_len = GUINT32_SWAP_LE_BE(dsb.secrets_len)(((guint32) ( (((guint32) (dsb.secrets_len) & (guint32) 0x000000ffU
) << 24) | (((guint32) (dsb.secrets_len) & (guint32
) 0x0000ff00U) << 8) | (((guint32) (dsb.secrets_len) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (dsb.secrets_len
) & (guint32) 0xff000000U) >> 24))))
;
1751 } else {
1752 dsb_mand->secrets_type = dsb.secrets_type;
1753 dsb_mand->secrets_len = dsb.secrets_len;
1754 }
1755
1756 /*
1757 * Is this block long enough to contain the secrets?
1758 */
1759 if (block_content_length < sizeof dsb + dsb_mand->secrets_len) {
1760 /*
1761 * No.
1762 */
1763 *err = WTAP_ERR_BAD_FILE-13;
1764 *err_info = ws_strdup_printf("pcapng: block content length %u of an DSB is less the size needed for the secrets in the DSB %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an DSB is less the size needed for the secrets in the DSB %zu"
, block_content_length, sizeof dsb + dsb_mand->secrets_len
)
1765 block_content_length,wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an DSB is less the size needed for the secrets in the DSB %zu"
, block_content_length, sizeof dsb + dsb_mand->secrets_len
)
1766 sizeof dsb + dsb_mand->secrets_len)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an DSB is less the size needed for the secrets in the DSB %zu"
, block_content_length, sizeof dsb + dsb_mand->secrets_len
)
;
1767 return false0;
1768 }
1769
1770 /*
1771 * Sanity check: assume the secrets will never need to be larger
1772 * than 1 GiB.
1773 */
1774 if (dsb_mand->secrets_len > 1024 * 1024 * 1024) {
1775 *err = WTAP_ERR_BAD_FILE-13;
1776 *err_info = ws_strdup_printf("pcapng: secrets block is too large: %u", dsb_mand->secrets_len)wmem_strdup_printf(((void*)0), "pcapng: secrets block is too large: %u"
, dsb_mand->secrets_len)
;
1777 return false0;
1778 }
1779
1780 dsb_mand->secrets_data = (uint8_t *)g_malloc0(dsb_mand->secrets_len);
1781 if (!wtap_read_bytes(fh, dsb_mand->secrets_data, dsb_mand->secrets_len, err, err_info)) {
1782 ws_debug("failed to read DSB secrets")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1782, __func__, "failed to read DSB secrets"); } } while (0
)
;
1783 return false0;
1784 }
1785
1786 /* Skip past padding and discard options (not supported yet). */
1787 to_read = block_content_length - sizeof dsb - dsb_mand->secrets_len;
1788 if (!wtap_read_bytes(fh, NULL((void*)0), to_read, err, err_info)) {
1789 ws_debug("failed to read DSB options")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1789, __func__, "failed to read DSB options"); } } while (0
)
;
1790 return false0;
1791 }
1792
1793 /*
1794 * We don't return these to the caller in pcapng_read().
1795 */
1796 wblock->internal = true1;
1797
1798 return true1;
1799}
1800
1801static bool_Bool
1802pcapng_process_packet_block_option(wtapng_block_t *wblock,
1803 section_info_t *section_info,
1804 uint16_t option_code,
1805 uint16_t option_length,
1806 const uint8_t *option_content,
1807 int *err, char **err_info)
1808{
1809 uint64_t tmp64;
1810 packet_verdict_opt_t packet_verdict;
1811 packet_hash_opt_t packet_hash;
1812
1813 /*
1814 * Handle option content.
1815 *
1816 * ***DO NOT*** add any items to this table that are not
1817 * standardized option codes in either section 3.5 "Options"
1818 * of the current pcapng spec, at
1819 *
1820 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1821 *
1822 * or in the list of options in section 4.3 "Enhanced Packet Block"
1823 * of the current pcapng spec, at
1824 *
1825 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-enhanced-packet-block
1826 *
1827 * All option codes in this switch statement here must be listed
1828 * in one of those places as standardized option types.
1829 */
1830 switch (option_code) {
1831 case(OPT_PKT_FLAGS2):
1832 if (option_length != 4) {
1833 *err = WTAP_ERR_BAD_FILE-13;
1834 *err_info = ws_strdup_printf("pcapng: packet block flags option length %u is not 4",wmem_strdup_printf(((void*)0), "pcapng: packet block flags option length %u is not 4"
, option_length)
1835 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block flags option length %u is not 4"
, option_length)
;
1836 /* XXX - free anything? */
1837 return false0;
1838 }
1839 pcapng_process_uint32_option(wblock, section_info,
1840 OPT_SECTION_BYTE_ORDER,
1841 option_code, option_length,
1842 option_content);
1843 break;
1844 case(OPT_PKT_HASH3):
1845 if (option_length < 1) {
1846 *err = WTAP_ERR_BAD_FILE-13;
1847 *err_info = ws_strdup_printf("pcapng: packet block hash option length %u is < 1",wmem_strdup_printf(((void*)0), "pcapng: packet block hash option length %u is < 1"
, option_length)
1848 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block hash option length %u is < 1"
, option_length)
;
1849 /* XXX - free anything? */
1850 return false0;
1851 }
1852 packet_hash.type = option_content[0];
1853 packet_hash.hash_bytes =
1854 g_byte_array_new_take((uint8_t *)g_memdup2(&option_content[1],
1855 option_length - 1),
1856 option_length - 1);
1857 wtap_block_add_packet_hash_option(wblock->block, option_code, &packet_hash);
1858 wtap_packet_hash_free(&packet_hash);
1859 ws_debug("hash type %u, data len %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1860, __func__, "hash type %u, data len %u", option_content
[0], option_length - 1); } } while (0)
1860 option_content[0], option_length - 1)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1860, __func__, "hash type %u, data len %u", option_content
[0], option_length - 1); } } while (0)
;
1861 break;
1862 case(OPT_PKT_DROPCOUNT4):
1863 if (option_length != 8) {
1864 *err = WTAP_ERR_BAD_FILE-13;
1865 *err_info = ws_strdup_printf("pcapng: packet block drop count option length %u is not 8",wmem_strdup_printf(((void*)0), "pcapng: packet block drop count option length %u is not 8"
, option_length)
1866 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block drop count option length %u is not 8"
, option_length)
;
1867 /* XXX - free anything? */
1868 return false0;
1869 }
1870 pcapng_process_uint64_option(wblock, section_info,
1871 OPT_SECTION_BYTE_ORDER,
1872 option_code, option_length,
1873 option_content);
1874 break;
1875 case(OPT_PKT_PACKETID5):
1876 if (option_length != 8) {
1877 *err = WTAP_ERR_BAD_FILE-13;
1878 *err_info = ws_strdup_printf("pcapng: packet block packet id option length %u is not 8",wmem_strdup_printf(((void*)0), "pcapng: packet block packet id option length %u is not 8"
, option_length)
1879 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block packet id option length %u is not 8"
, option_length)
;
1880 /* XXX - free anything? */
1881 return false0;
1882 }
1883 pcapng_process_uint64_option(wblock, section_info,
1884 OPT_SECTION_BYTE_ORDER,
1885 option_code, option_length,
1886 option_content);
1887 break;
1888 case(OPT_PKT_QUEUE6):
1889 if (option_length != 4) {
1890 *err = WTAP_ERR_BAD_FILE-13;
1891 *err_info = ws_strdup_printf("pcapng: packet block queue option length %u is not 4",wmem_strdup_printf(((void*)0), "pcapng: packet block queue option length %u is not 4"
, option_length)
1892 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block queue option length %u is not 4"
, option_length)
;
1893 /* XXX - free anything? */
1894 return false0;
1895 }
1896 pcapng_process_uint32_option(wblock, section_info,
1897 OPT_SECTION_BYTE_ORDER,
1898 option_code, option_length,
1899 option_content);
1900 break;
1901 case(OPT_PKT_VERDICT7):
1902 if (option_length < 1) {
1903 *err = WTAP_ERR_BAD_FILE-13;
1904 *err_info = ws_strdup_printf("pcapng: packet block verdict option length %u is < 1",wmem_strdup_printf(((void*)0), "pcapng: packet block verdict option length %u is < 1"
, option_length)
1905 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block verdict option length %u is < 1"
, option_length)
;
1906 /* XXX - free anything? */
1907 return false0;
1908 }
1909 switch (option_content[0]) {
1910
1911 case(OPT_VERDICT_TYPE_HW0):
1912 packet_verdict.type = packet_verdict_hardware;
1913 packet_verdict.data.verdict_bytes =
1914 g_byte_array_new_take((uint8_t *)g_memdup2(&option_content[1],
1915 option_length - 1),
1916 option_length - 1);
1917 break;
1918
1919 case(OPT_VERDICT_TYPE_TC1):
1920 if (option_length != 9) {
1921 *err = WTAP_ERR_BAD_FILE-13;
1922 *err_info = ws_strdup_printf("pcapng: packet block TC verdict option length %u is != 9",wmem_strdup_printf(((void*)0), "pcapng: packet block TC verdict option length %u is != 9"
, option_length)
1923 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block TC verdict option length %u is != 9"
, option_length)
;
1924 /* XXX - free anything? */
1925 return false0;
1926 }
1927 /* Don't cast a uint8_t * into a uint64_t *--the
1928 * uint8_t * may not point to something that's
1929 * aligned correctly.
1930 */
1931 memcpy(&tmp64, &option_content[1], sizeof(uint64_t));
1932 if (section_info->byte_swapped)
1933 tmp64 = GUINT64_SWAP_LE_BE(tmp64)(((guint64) ( (((guint64) (tmp64) & (guint64) (0x00000000000000ffUL
)) << 56) | (((guint64) (tmp64) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (tmp64) & (guint64) (0x0000000000ff0000UL
)) << 24) | (((guint64) (tmp64) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (tmp64) & (guint64) (0x000000ff00000000UL
)) >> 8) | (((guint64) (tmp64) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (tmp64) & (guint64) (0x00ff000000000000UL
)) >> 40) | (((guint64) (tmp64) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
1934 packet_verdict.type = packet_verdict_linux_ebpf_tc;
1935 packet_verdict.data.verdict_linux_ebpf_tc = tmp64;
1936 break;
1937
1938 case(OPT_VERDICT_TYPE_XDP2):
1939 if (option_length != 9) {
1940 *err = WTAP_ERR_BAD_FILE-13;
1941 *err_info = ws_strdup_printf("pcapng: packet block XDP verdict option length %u is != 9",wmem_strdup_printf(((void*)0), "pcapng: packet block XDP verdict option length %u is != 9"
, option_length)
1942 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block XDP verdict option length %u is != 9"
, option_length)
;
1943 /* XXX - free anything? */
1944 return false0;
1945 }
1946 /* Don't cast a uint8_t * into a uint64_t *--the
1947 * uint8_t * may not point to something that's
1948 * aligned correctly.
1949 */
1950 memcpy(&tmp64, &option_content[1], sizeof(uint64_t));
1951 if (section_info->byte_swapped)
1952 tmp64 = GUINT64_SWAP_LE_BE(tmp64)(((guint64) ( (((guint64) (tmp64) & (guint64) (0x00000000000000ffUL
)) << 56) | (((guint64) (tmp64) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (tmp64) & (guint64) (0x0000000000ff0000UL
)) << 24) | (((guint64) (tmp64) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (tmp64) & (guint64) (0x000000ff00000000UL
)) >> 8) | (((guint64) (tmp64) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (tmp64) & (guint64) (0x00ff000000000000UL
)) >> 40) | (((guint64) (tmp64) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
1953 packet_verdict.type = packet_verdict_linux_ebpf_xdp;
1954 packet_verdict.data.verdict_linux_ebpf_xdp = tmp64;
1955 break;
1956
1957 default:
1958 /* Silently ignore unknown verdict types */
1959 return true1;
1960 }
1961 wtap_block_add_packet_verdict_option(wblock->block, option_code, &packet_verdict);
1962 wtap_packet_verdict_free(&packet_verdict);
1963 ws_debug("verdict type %u, data len %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1964, __func__, "verdict type %u, data len %u", option_content
[0], option_length - 1); } } while (0)
1964 option_content[0], option_length - 1)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 1964, __func__, "verdict type %u, data len %u", option_content
[0], option_length - 1); } } while (0)
;
1965 break;
1966 case(OPT_PKT_PROCIDTHRDID8):
1967 if (option_length != 8) {
1968 *err = WTAP_ERR_BAD_FILE-13;
1969 *err_info = ws_strdup_printf("pcapng: packet block process id thread id option length %u is not 8",wmem_strdup_printf(((void*)0), "pcapng: packet block process id thread id option length %u is not 8"
, option_length)
1970 option_length)wmem_strdup_printf(((void*)0), "pcapng: packet block process id thread id option length %u is not 8"
, option_length)
;
1971 /* XXX - free anything? */
1972 return false0;
1973 }
1974 // XXX - It's two concatenated 32 bit unsigned integers
1975 pcapng_process_uint64_option(wblock, section_info,
1976 OPT_SECTION_BYTE_ORDER,
1977 option_code, option_length,
1978 option_content);
1979 break;
1980 default:
1981 if (!pcapng_process_unhandled_option(wblock, section_info,
1982 option_code, option_length,
1983 option_content,
1984 err, err_info))
1985 return false0;
1986 break;
1987 }
1988 return true1;
1989}
1990
1991static bool_Bool
1992pcapng_read_packet_block(wtap *wth _U___attribute__((unused)), FILE_T fh, uint32_t block_type,
1993 uint32_t block_content_length,
1994 section_info_t *section_info,
1995 wtapng_block_t *wblock,
1996 int *err, char **err_info)
1997{
1998 unsigned block_read;
1999 unsigned opt_cont_buf_len;
2000 pcapng_enhanced_packet_block_t epb;
2001 pcapng_packet_block_t pb;
2002 wtapng_packet_t packet;
2003 uint32_t padding;
2004 uint32_t flags;
2005 uint64_t tmp64;
2006 interface_info_t iface_info;
2007 uint64_t ts;
2008 int pseudo_header_len;
2009 int fcslen;
2010 bool_Bool enhanced = (block_type == BLOCK_TYPE_EPB0x00000006);
2011
2012 wblock->block = wtap_block_create(WTAP_BLOCK_PACKET);
2013
2014 if (enhanced) {
2015 /*
2016 * Is this block long enough to be an EPB?
2017 */
2018 if (block_content_length < sizeof epb) {
2019 /*
2020 * No.
2021 */
2022 *err = WTAP_ERR_BAD_FILE-13;
2023 *err_info = ws_strdup_printf("pcapng: block content length %u of an EPB is less than the minimum EPB content size %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an EPB is less than the minimum EPB content size %zu"
, block_content_length, sizeof epb)
2024 block_content_length, sizeof epb)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an EPB is less than the minimum EPB content size %zu"
, block_content_length, sizeof epb)
;
2025 return false0;
2026 }
2027
2028 /* "Enhanced Packet Block" read fixed part */
2029 if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
2030 ws_debug("failed to read EPB fixed portion")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2030, __func__, "failed to read EPB fixed portion"); } } while
(0)
;
2031 return false0;
2032 }
2033 block_read = (unsigned)sizeof epb;
2034
2035 if (section_info->byte_swapped) {
2036 packet.interface_id = GUINT32_SWAP_LE_BE(epb.interface_id)(((guint32) ( (((guint32) (epb.interface_id) & (guint32) 0x000000ffU
) << 24) | (((guint32) (epb.interface_id) & (guint32
) 0x0000ff00U) << 8) | (((guint32) (epb.interface_id) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (epb.interface_id
) & (guint32) 0xff000000U) >> 24))))
;
2037 packet.drops_count = 0xFFFF; /* invalid */
2038 packet.ts_high = GUINT32_SWAP_LE_BE(epb.timestamp_high)(((guint32) ( (((guint32) (epb.timestamp_high) & (guint32
) 0x000000ffU) << 24) | (((guint32) (epb.timestamp_high
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (epb
.timestamp_high) & (guint32) 0x00ff0000U) >> 8) | (
((guint32) (epb.timestamp_high) & (guint32) 0xff000000U) >>
24))))
;
2039 packet.ts_low = GUINT32_SWAP_LE_BE(epb.timestamp_low)(((guint32) ( (((guint32) (epb.timestamp_low) & (guint32)
0x000000ffU) << 24) | (((guint32) (epb.timestamp_low) &
(guint32) 0x0000ff00U) << 8) | (((guint32) (epb.timestamp_low
) & (guint32) 0x00ff0000U) >> 8) | (((guint32) (epb
.timestamp_low) & (guint32) 0xff000000U) >> 24))))
;
2040 packet.cap_len = GUINT32_SWAP_LE_BE(epb.captured_len)(((guint32) ( (((guint32) (epb.captured_len) & (guint32) 0x000000ffU
) << 24) | (((guint32) (epb.captured_len) & (guint32
) 0x0000ff00U) << 8) | (((guint32) (epb.captured_len) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (epb.captured_len
) & (guint32) 0xff000000U) >> 24))))
;
2041 packet.packet_len = GUINT32_SWAP_LE_BE(epb.packet_len)(((guint32) ( (((guint32) (epb.packet_len) & (guint32) 0x000000ffU
) << 24) | (((guint32) (epb.packet_len) & (guint32)
0x0000ff00U) << 8) | (((guint32) (epb.packet_len) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (epb.packet_len
) & (guint32) 0xff000000U) >> 24))))
;
2042 } else {
2043 packet.interface_id = epb.interface_id;
2044 packet.drops_count = 0xFFFF; /* invalid */
2045 packet.ts_high = epb.timestamp_high;
2046 packet.ts_low = epb.timestamp_low;
2047 packet.cap_len = epb.captured_len;
2048 packet.packet_len = epb.packet_len;
2049 }
2050 ws_debug("EPB on interface_id %d, cap_len %d, packet_len %d",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2051, __func__, "EPB on interface_id %d, cap_len %d, packet_len %d"
, packet.interface_id, packet.cap_len, packet.packet_len); } }
while (0)
2051 packet.interface_id, packet.cap_len, packet.packet_len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2051, __func__, "EPB on interface_id %d, cap_len %d, packet_len %d"
, packet.interface_id, packet.cap_len, packet.packet_len); } }
while (0)
;
2052 } else {
2053 /*
2054 * Is this block long enough to be a PB?
2055 */
2056 if (block_content_length < sizeof pb) {
2057 /*
2058 * No.
2059 */
2060 *err = WTAP_ERR_BAD_FILE-13;
2061 *err_info = ws_strdup_printf("pcapng: block content length %u of a PB is less than the minimum PB content size %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of a PB is less than the minimum PB content size %zu"
, block_content_length, sizeof pb)
2062 block_content_length, sizeof pb)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of a PB is less than the minimum PB content size %zu"
, block_content_length, sizeof pb)
;
2063 return false0;
2064 }
2065
2066 /* "Packet Block" read fixed part */
2067 if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
2068 ws_debug("failed to read packet data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2068, __func__, "failed to read packet data"); } } while (0
)
;
2069 return false0;
2070 }
2071 block_read = (unsigned)sizeof pb;
2072
2073 if (section_info->byte_swapped) {
2074 packet.interface_id = GUINT16_SWAP_LE_BE(pb.interface_id)(((guint16) ( (guint16) ((guint16) (pb.interface_id) >>
8) | (guint16) ((guint16) (pb.interface_id) << 8))))
;
2075 packet.drops_count = GUINT16_SWAP_LE_BE(pb.drops_count)(((guint16) ( (guint16) ((guint16) (pb.drops_count) >> 8
) | (guint16) ((guint16) (pb.drops_count) << 8))))
;
2076 packet.ts_high = GUINT32_SWAP_LE_BE(pb.timestamp_high)(((guint32) ( (((guint32) (pb.timestamp_high) & (guint32)
0x000000ffU) << 24) | (((guint32) (pb.timestamp_high) &
(guint32) 0x0000ff00U) << 8) | (((guint32) (pb.timestamp_high
) & (guint32) 0x00ff0000U) >> 8) | (((guint32) (pb.
timestamp_high) & (guint32) 0xff000000U) >> 24))))
;
2077 packet.ts_low = GUINT32_SWAP_LE_BE(pb.timestamp_low)(((guint32) ( (((guint32) (pb.timestamp_low) & (guint32) 0x000000ffU
) << 24) | (((guint32) (pb.timestamp_low) & (guint32
) 0x0000ff00U) << 8) | (((guint32) (pb.timestamp_low) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (pb.timestamp_low
) & (guint32) 0xff000000U) >> 24))))
;
2078 packet.cap_len = GUINT32_SWAP_LE_BE(pb.captured_len)(((guint32) ( (((guint32) (pb.captured_len) & (guint32) 0x000000ffU
) << 24) | (((guint32) (pb.captured_len) & (guint32
) 0x0000ff00U) << 8) | (((guint32) (pb.captured_len) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (pb.captured_len
) & (guint32) 0xff000000U) >> 24))))
;
2079 packet.packet_len = GUINT32_SWAP_LE_BE(pb.packet_len)(((guint32) ( (((guint32) (pb.packet_len) & (guint32) 0x000000ffU
) << 24) | (((guint32) (pb.packet_len) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (pb.packet_len) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (pb.packet_len) & (guint32) 0xff000000U
) >> 24))))
;
2080 } else {
2081 packet.interface_id = pb.interface_id;
2082 packet.drops_count = pb.drops_count;
2083 packet.ts_high = pb.timestamp_high;
2084 packet.ts_low = pb.timestamp_low;
2085 packet.cap_len = pb.captured_len;
2086 packet.packet_len = pb.packet_len;
2087 }
2088 ws_debug("PB on interface_id %d, cap_len %d, packet_len %d",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2089, __func__, "PB on interface_id %d, cap_len %d, packet_len %d"
, packet.interface_id, packet.cap_len, packet.packet_len); } }
while (0)
2089 packet.interface_id, packet.cap_len, packet.packet_len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2089, __func__, "PB on interface_id %d, cap_len %d, packet_len %d"
, packet.interface_id, packet.cap_len, packet.packet_len); } }
while (0)
;
2090 }
2091 ws_debug("packet data: packet_len %u captured_len %u interface_id %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2094, __func__, "packet data: packet_len %u captured_len %u interface_id %u"
, packet.packet_len, packet.cap_len, packet.interface_id); } }
while (0)
2092 packet.packet_len,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2094, __func__, "packet data: packet_len %u captured_len %u interface_id %u"
, packet.packet_len, packet.cap_len, packet.interface_id); } }
while (0)
2093 packet.cap_len,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2094, __func__, "packet data: packet_len %u captured_len %u interface_id %u"
, packet.packet_len, packet.cap_len, packet.interface_id); } }
while (0)
2094 packet.interface_id)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2094, __func__, "packet data: packet_len %u captured_len %u interface_id %u"
, packet.packet_len, packet.cap_len, packet.interface_id); } }
while (0)
;
2095
2096 if (packet.interface_id >= section_info->interfaces->len) {
2097 *err = WTAP_ERR_BAD_FILE-13;
2098 *err_info = ws_strdup_printf("pcapng: interface index %u is not less than section interface count %u",wmem_strdup_printf(((void*)0), "pcapng: interface index %u is not less than section interface count %u"
, packet.interface_id, section_info->interfaces->len)
2099 packet.interface_id,wmem_strdup_printf(((void*)0), "pcapng: interface index %u is not less than section interface count %u"
, packet.interface_id, section_info->interfaces->len)
2100 section_info->interfaces->len)wmem_strdup_printf(((void*)0), "pcapng: interface index %u is not less than section interface count %u"
, packet.interface_id, section_info->interfaces->len)
;
2101 return false0;
2102 }
2103 iface_info = g_array_index(section_info->interfaces, interface_info_t,(((interface_info_t*) (void *) (section_info->interfaces)->
data) [(packet.interface_id)])
2104 packet.interface_id)(((interface_info_t*) (void *) (section_info->interfaces)->
data) [(packet.interface_id)])
;
2105
2106 if (packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
2107 *err = WTAP_ERR_BAD_FILE-13;
2108 *err_info = ws_strdup_printf("pcapng: cap_len %u is larger than maximum supported length %u",wmem_strdup_printf(((void*)0), "pcapng: cap_len %u is larger than maximum supported length %u"
, packet.cap_len, wtap_max_snaplen_for_encap(iface_info.wtap_encap
))
2109 packet.cap_len,wmem_strdup_printf(((void*)0), "pcapng: cap_len %u is larger than maximum supported length %u"
, packet.cap_len, wtap_max_snaplen_for_encap(iface_info.wtap_encap
))
2110 wtap_max_snaplen_for_encap(iface_info.wtap_encap))wmem_strdup_printf(((void*)0), "pcapng: cap_len %u is larger than maximum supported length %u"
, packet.cap_len, wtap_max_snaplen_for_encap(iface_info.wtap_encap
))
;
2111 return false0;
2112 }
2113
2114 /*
2115 * How much padding is there at the end of the packet data?
2116 */
2117 padding = WS_PADDING_TO_4(packet.cap_len)((4U - ((packet.cap_len) % 4U)) % 4U);
2118
2119 /*
2120 * Is this block long enough to hold the packet data?
2121 */
2122 if (enhanced) {
2123 if (block_content_length < sizeof epb + packet.cap_len + padding) {
2124 /*
2125 * No.
2126 */
2127 *err = WTAP_ERR_BAD_FILE-13;
2128 *err_info = ws_strdup_printf("pcapng: block content length %u of an EPB is too small for %u bytes of packet data",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an EPB is too small for %u bytes of packet data"
, block_content_length, packet.cap_len)
2129 block_content_length, packet.cap_len)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an EPB is too small for %u bytes of packet data"
, block_content_length, packet.cap_len)
;
2130 return false0;
2131 }
2132 } else {
2133 if (block_content_length < sizeof pb + packet.cap_len + padding) {
2134 /*
2135 * No.
2136 */
2137 *err = WTAP_ERR_BAD_FILE-13;
2138 *err_info = ws_strdup_printf("pcapng: total block length %u of a PB is too small for %u bytes of packet data",wmem_strdup_printf(((void*)0), "pcapng: total block length %u of a PB is too small for %u bytes of packet data"
, block_content_length, packet.cap_len)
2139 block_content_length, packet.cap_len)wmem_strdup_printf(((void*)0), "pcapng: total block length %u of a PB is too small for %u bytes of packet data"
, block_content_length, packet.cap_len)
;
2140 return false0;
2141 }
2142 }
2143
2144 ws_debug("Need to read pseudo header of size %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2145, __func__, "Need to read pseudo header of size %u", pcap_get_phdr_size
(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header
.pseudo_header)); } } while (0)
2145 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header))do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2145, __func__, "Need to read pseudo header of size %u", pcap_get_phdr_size
(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header
.pseudo_header)); } } while (0)
;
2146
2147 wtap_setup_packet_rec(wblock->rec, iface_info.wtap_encap);
2148 wblock->rec->presence_flags = WTAP_HAS_TS0x00000001|WTAP_HAS_CAP_LEN0x00000002|WTAP_HAS_INTERFACE_ID0x00000004;
2149
2150 ws_debug("encapsulation = %d (%s), pseudo header size = %u.",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2153, __func__, "encapsulation = %d (%s), pseudo header size = %u."
, iface_info.wtap_encap, wtap_encap_description(iface_info.wtap_encap
), pcap_get_phdr_size(iface_info.wtap_encap, &wblock->
rec->rec_header.packet_header.pseudo_header)); } } while (
0)
2151 iface_info.wtap_encap,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2153, __func__, "encapsulation = %d (%s), pseudo header size = %u."
, iface_info.wtap_encap, wtap_encap_description(iface_info.wtap_encap
), pcap_get_phdr_size(iface_info.wtap_encap, &wblock->
rec->rec_header.packet_header.pseudo_header)); } } while (
0)
2152 wtap_encap_description(iface_info.wtap_encap),do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2153, __func__, "encapsulation = %d (%s), pseudo header size = %u."
, iface_info.wtap_encap, wtap_encap_description(iface_info.wtap_encap
), pcap_get_phdr_size(iface_info.wtap_encap, &wblock->
rec->rec_header.packet_header.pseudo_header)); } } while (
0)
2153 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header))do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2153, __func__, "encapsulation = %d (%s), pseudo header size = %u."
, iface_info.wtap_encap, wtap_encap_description(iface_info.wtap_encap
), pcap_get_phdr_size(iface_info.wtap_encap, &wblock->
rec->rec_header.packet_header.pseudo_header)); } } while (
0)
;
2154 wblock->rec->rec_header.packet_header.interface_id = packet.interface_id;
2155 wblock->rec->tsprec = iface_info.tsprecision;
2156
2157 memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2158 pseudo_header_len = pcap_process_pseudo_header(fh,
2159 false0, /* not a Nokia pcap - not a pcap at all */
2160 iface_info.wtap_encap,
2161 packet.cap_len,
2162 wblock->rec,
2163 err,
2164 err_info);
2165 if (pseudo_header_len < 0) {
2166 return false0;
2167 }
2168 block_read += pseudo_header_len;
2169 wblock->rec->rec_header.packet_header.caplen = packet.cap_len - pseudo_header_len;
2170 wblock->rec->rec_header.packet_header.len = packet.packet_len - pseudo_header_len;
2171
2172 /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
2173 ts = (((uint64_t)packet.ts_high) << 32) | ((uint64_t)packet.ts_low);
2174
2175 /* Convert it to seconds and nanoseconds. */
2176 wblock->rec->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
2177 /* This can overflow if iface_info.time_units_per_seconds > (2^64 - 1) / 10^9;
2178 * log10((2^64 - 1) / 10^9) ~ 10.266 and log2((2^64 - 1) / 10^9) ~ 32.103,
2179 * so that's if the power of 10 exponent is greater than 10 or the power of 2
2180 * exponent is greater than 32.
2181 *
2182 * We could test for and use 128 bit integers and platforms and compilers
2183 * that have it (C23, and gcc, clang, and ICC on most 64-bit platforms).
2184 * For C23, if we include <limits.h> and BITINT_MAXWIDTH is defined to be
2185 * at least 128 (or even just 96) we could use unsigned _BitInt(128).
2186 * If __SIZEOF_INT128__ is defined we can use unsigned __int128. Some
2187 * testing (including with godbolt.org) suggests it's faster to check
2188 * overflow and handle our two special cases.
2189 */
2190 uint64_t ts_frac = ts % iface_info.time_units_per_second;
2191 uint64_t ts_ns;
2192 if (ckd_mul(&ts_ns, ts_frac, NS_PER_S)__builtin_mul_overflow((ts_frac), (1000000000U), (&ts_ns)
)
) {
2193 /* We have 10^N where N > 10 or 2^N where N > 32. */
2194 if (!iface_info.tsresol_binary) {
2195 /* 10^N where N > 10, so this divides evenly. */
2196 ws_assert(iface_info.time_units_per_second > NS_PER_S)do { if ((1) && !(iface_info.time_units_per_second >
1000000000U)) ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/pcapng.c"
, 2196, __func__, "assertion failed: %s", "iface_info.time_units_per_second > 1000000000U"
); } while (0)
;
2197 wblock->rec->ts.nsecs = (int)(ts_frac / (iface_info.time_units_per_second / NS_PER_S1000000000U));
2198 } else {
2199 /* Multiplying a 64 bit integer by a 32 bit integer, then dividing
2200 * by 2^N, where N > 32. */
2201 uint64_t ts_frac_low = (ts_frac & 0xFFFFFFFF) * NS_PER_S1000000000U;
2202 uint64_t ts_frac_high = (ts_frac >> 32) * NS_PER_S1000000000U;
2203 // Add the carry.
2204 ts_frac_high += ts_frac_low >> 32;
2205 //ts_frac_low &= 0xFFFFFFFF;
2206 ws_assert(iface_info.tsresol_binary > 32)do { if ((1) && !(iface_info.tsresol_binary > 32))
ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/pcapng.c"
, 2206, __func__, "assertion failed: %s", "iface_info.tsresol_binary > 32"
); } while (0)
;
2207 uint8_t high_shift = iface_info.tsresol_binary - 32;
2208 wblock->rec->ts.nsecs = (int)(ts_frac_high >> high_shift);
2209 }
2210 } else {
2211 wblock->rec->ts.nsecs = (int)(ts_ns / iface_info.time_units_per_second);
2212 }
2213
2214 /* Add the time stamp offset. */
2215 wblock->rec->ts.secs = (time_t)(wblock->rec->ts.secs + iface_info.tsoffset);
2216
2217 /* "(Enhanced) Packet Block" read capture data */
2218 if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
2219 packet.cap_len - pseudo_header_len, err, err_info))
2220 return false0;
2221 block_read += packet.cap_len - pseudo_header_len;
2222
2223 /* jump over potential padding bytes at end of the packet data */
2224 if (padding != 0) {
2225 if (!wtap_read_bytes(fh, NULL((void*)0), padding, err, err_info))
2226 return false0;
2227 block_read += padding;
2228 }
2229
2230 /* FCS length default */
2231 fcslen = iface_info.fcslen;
2232
2233 /* Options */
2234 opt_cont_buf_len = block_content_length - block_read;
2235 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2236 pcapng_process_packet_block_option,
2237 OPT_SECTION_BYTE_ORDER, err, err_info))
2238 return false0;
2239
2240 /*
2241 * Did we get a packet flags option?
2242 */
2243 if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(wblock->block, OPT_PKT_FLAGS2, &flags)) {
2244 if (PACK_FLAGS_FCS_LENGTH(flags)(((flags) & 0x000001E0) >> 5) != 0) {
2245 /*
2246 * The FCS length is present, but in units of octets, not
2247 * bits; convert it to bits.
2248 */
2249 fcslen = PACK_FLAGS_FCS_LENGTH(flags)(((flags) & 0x000001E0) >> 5)*8;
2250 }
2251 }
2252 /*
2253 * How about a drop_count option? If not, set it from other sources
2254 */
2255 if (WTAP_OPTTYPE_SUCCESS != wtap_block_get_uint64_option_value(wblock->block, OPT_PKT_DROPCOUNT4, &tmp64) && packet.drops_count != 0xFFFF) {
2256 wtap_block_add_uint64_option(wblock->block, OPT_PKT_DROPCOUNT4, (uint64_t)packet.drops_count);
2257 }
2258
2259 pcap_read_post_process(false0, iface_info.wtap_encap, wblock->rec,
2260 section_info->byte_swapped, fcslen);
2261
2262 /*
2263 * We return these to the caller in pcapng_read().
2264 */
2265 wblock->internal = false0;
2266
2267 /*
2268 * We want dissectors (particularly packet_frame) to be able to
2269 * access packet comments and whatnot that are in the block. wblock->block
2270 * will be unref'd by pcapng_seek_read(), so move the block to where
2271 * dissectors can find it.
2272 */
2273 wblock->rec->block = wblock->block;
2274 wblock->block = NULL((void*)0);
2275
2276 return true1;
2277}
2278
2279
2280static bool_Bool
2281pcapng_read_simple_packet_block(wtap *wth _U___attribute__((unused)), FILE_T fh,
2282 uint32_t block_type _U___attribute__((unused)),
2283 uint32_t block_content_length,
2284 section_info_t *section_info,
2285 wtapng_block_t *wblock,
2286 int *err, char **err_info)
2287{
2288 pcapng_simple_packet_block_t spb;
2289 wtapng_simple_packet_t simple_packet;
2290 uint32_t padding;
2291 interface_info_t iface_info;
2292 int pseudo_header_len;
2293
2294 /*
2295 * Is this block long enough to be an SPB?
2296 */
2297 if (block_content_length < sizeof spb) {
2298 /*
2299 * No.
2300 */
2301 *err = WTAP_ERR_BAD_FILE-13;
2302 *err_info = ws_strdup_printf("pcapng: block content length %u of an SPB is less than the minimum SPB content size %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an SPB is less than the minimum SPB content size %zu"
, block_content_length, sizeof spb)
2303 block_content_length, sizeof spb)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an SPB is less than the minimum SPB content size %zu"
, block_content_length, sizeof spb)
;
2304 return false0;
2305 }
2306
2307 /* "Simple Packet Block" read fixed part */
2308 if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
2309 ws_debug("failed to read SPB fixed portion")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2309, __func__, "failed to read SPB fixed portion"); } } while
(0)
;
2310 return false0;
2311 }
2312
2313 if (section_info->byte_swapped) {
2314 simple_packet.packet_len = GUINT32_SWAP_LE_BE(spb.packet_len)(((guint32) ( (((guint32) (spb.packet_len) & (guint32) 0x000000ffU
) << 24) | (((guint32) (spb.packet_len) & (guint32)
0x0000ff00U) << 8) | (((guint32) (spb.packet_len) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (spb.packet_len
) & (guint32) 0xff000000U) >> 24))))
;
2315 } else {
2316 simple_packet.packet_len = spb.packet_len;
2317 }
2318
2319 if (0 >= section_info->interfaces->len) {
2320 *err = WTAP_ERR_BAD_FILE-13;
2321 *err_info = g_strdup("pcapng: SPB appeared before any IDBs in the section")g_strdup_inline ("pcapng: SPB appeared before any IDBs in the section"
)
;
2322 return false0;
2323 }
2324 iface_info = g_array_index(section_info->interfaces, interface_info_t, 0)(((interface_info_t*) (void *) (section_info->interfaces)->
data) [(0)])
;
2325
2326 /*
2327 * The captured length is not a field in the SPB; it can be
2328 * calculated as the minimum of the snapshot length from the
2329 * IDB and the packet length, as per the pcapng spec. An IDB
2330 * snapshot length of 0 means no limit.
2331 */
2332 simple_packet.cap_len = simple_packet.packet_len;
2333 if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
2334 simple_packet.cap_len = iface_info.snap_len;
2335 ws_debug("packet data: packet_len %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2336, __func__, "packet data: packet_len %u", simple_packet
.packet_len); } } while (0)
2336 simple_packet.packet_len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2336, __func__, "packet data: packet_len %u", simple_packet
.packet_len); } } while (0)
;
2337
2338 if (simple_packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
2339 *err = WTAP_ERR_BAD_FILE-13;
2340 *err_info = ws_strdup_printf("pcapng: cap_len %u is larger than maximum supported length %u",wmem_strdup_printf(((void*)0), "pcapng: cap_len %u is larger than maximum supported length %u"
, simple_packet.cap_len, wtap_max_snaplen_for_encap(iface_info
.wtap_encap))
2341 simple_packet.cap_len,wmem_strdup_printf(((void*)0), "pcapng: cap_len %u is larger than maximum supported length %u"
, simple_packet.cap_len, wtap_max_snaplen_for_encap(iface_info
.wtap_encap))
2342 wtap_max_snaplen_for_encap(iface_info.wtap_encap))wmem_strdup_printf(((void*)0), "pcapng: cap_len %u is larger than maximum supported length %u"
, simple_packet.cap_len, wtap_max_snaplen_for_encap(iface_info
.wtap_encap))
;
2343 return false0;
2344 }
2345
2346 /*
2347 * How much padding is there at the end of the packet data?
2348 */
2349 padding = WS_PADDING_TO_4(simple_packet.cap_len)((4U - ((simple_packet.cap_len) % 4U)) % 4U);
2350
2351 /*
2352 * Is this block long enough to hold the packet data?
2353 */
2354 if (block_content_length < sizeof spb + simple_packet.cap_len + padding) {
2355 /*
2356 * No. That means that the problem is with the packet
2357 * length; the snapshot length can be bigger than the amount
2358 * of packet data in the block, as it's a *maximum* length,
2359 * not a *minimum* length.
2360 */
2361 *err = WTAP_ERR_BAD_FILE-13;
2362 *err_info = ws_strdup_printf("pcapng: block content length %u of an SPB is too small for %u bytes of packet data",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an SPB is too small for %u bytes of packet data"
, block_content_length, simple_packet.cap_len)
2363 block_content_length, simple_packet.cap_len)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an SPB is too small for %u bytes of packet data"
, block_content_length, simple_packet.cap_len)
;
2364 return false0;
2365 }
2366
2367 ws_debug("Need to read pseudo header of size %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2368, __func__, "Need to read pseudo header of size %u", pcap_get_phdr_size
(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header
.pseudo_header)); } } while (0)
2368 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header))do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2368, __func__, "Need to read pseudo header of size %u", pcap_get_phdr_size
(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header
.pseudo_header)); } } while (0)
;
2369
2370 /* No time stamp in a simple packet block; no options, either */
2371 wtap_setup_packet_rec(wblock->rec, iface_info.wtap_encap);
2372 wblock->rec->presence_flags = WTAP_HAS_CAP_LEN0x00000002|WTAP_HAS_INTERFACE_ID0x00000004;
2373 wblock->rec->rec_header.packet_header.interface_id = 0;
2374 wblock->rec->tsprec = iface_info.tsprecision;
2375 wblock->rec->ts.secs = 0;
2376 wblock->rec->ts.nsecs = 0;
2377 wblock->rec->rec_header.packet_header.interface_id = 0;
2378
2379 memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2380 pseudo_header_len = pcap_process_pseudo_header(fh,
2381 false0, /* not a Nokia pcap - not a pcap at all */
2382 iface_info.wtap_encap,
2383 simple_packet.cap_len,
2384 wblock->rec,
2385 err,
2386 err_info);
2387 if (pseudo_header_len < 0) {
2388 return false0;
2389 }
2390 wblock->rec->rec_header.packet_header.caplen = simple_packet.cap_len - pseudo_header_len;
2391 wblock->rec->rec_header.packet_header.len = simple_packet.packet_len - pseudo_header_len;
2392
2393 /* "Simple Packet Block" read capture data */
2394 if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
2395 simple_packet.cap_len - pseudo_header_len, err, err_info))
2396 return false0;
2397
2398 /* jump over potential padding bytes at end of the packet data */
2399 if (padding != 0) {
2400 if (!wtap_read_bytes(fh, NULL((void*)0), padding, err, err_info))
2401 return false0;
2402 }
2403
2404 pcap_read_post_process(false0, iface_info.wtap_encap, wblock->rec,
2405 section_info->byte_swapped, iface_info.fcslen);
2406
2407 /*
2408 * We return these to the caller in pcapng_read().
2409 */
2410 wblock->internal = false0;
2411
2412 /*
2413 * We want dissectors (particularly packet_frame) to be able to
2414 * access packet comments and whatnot that are in the block
2415 * (not that there will be any, as an SPB has no options). wblock->block
2416 * will be unref'd by pcapng_seek_read(), so move the block to where
2417 * dissectors can find it.
2418 */
2419 wblock->rec->block = wblock->block;
2420 wblock->block = NULL((void*)0);
2421
2422 return true1;
2423}
2424
2425#define NRES_ENDOFRECORD0 0
2426#define NRES_IP4RECORD1 1
2427#define NRES_IP6RECORD2 2
2428/* IPv6 + MAXDNSNAMELEN */
2429#define INITIAL_NRB_REC_SIZE(16 + 256) (16 + MAXDNSNAMELEN256)
2430
2431/*
2432 * Find the end of the NUL-terminated name the beginning of which is pointed
2433 * to by p; record_len is the number of bytes remaining in the record.
2434 *
2435 * Return the length of the name, including the terminating NUL.
2436 *
2437 * If we don't find a terminating NUL, return -1 and set *err and
2438 * *err_info appropriately.
2439 */
2440static int
2441name_resolution_block_find_name_end(const char *p, unsigned record_len, int *err,
2442 char **err_info)
2443{
2444 int namelen;
2445
2446 namelen = 0;
2447 for (;;) {
2448 if (record_len == 0) {
2449 /*
2450 * We ran out of bytes in the record without
2451 * finding a NUL.
2452 */
2453 *err = WTAP_ERR_BAD_FILE-13;
2454 *err_info = g_strdup("pcapng: NRB record has non-null-terminated host name")g_strdup_inline ("pcapng: NRB record has non-null-terminated host name"
)
;
2455 return -1;
2456 }
2457 if (*p == '\0')
2458 break; /* that's the terminating NUL */
2459 p++;
2460 record_len--;
2461 namelen++; /* count this byte */
2462 }
2463
2464 /* Include the NUL in the name length. */
2465 return namelen + 1;
2466}
2467
2468static bool_Bool
2469pcapng_process_name_resolution_block_option(wtapng_block_t *wblock,
2470 section_info_t *section_info,
2471 uint16_t option_code,
2472 uint16_t option_length,
2473 const uint8_t *option_content,
2474 int *err, char **err_info)
2475{
2476 /*
2477 * Handle option content.
2478 *
2479 * ***DO NOT*** add any items to this table that are not
2480 * standardized option codes in either section 3.5 "Options"
2481 * of the current pcapng spec, at
2482 *
2483 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
2484 *
2485 * or in the list of options in section 4.1 "Section Header Block"
2486 * of the current pcapng spec, at
2487 *
2488 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
2489 *
2490 * All option codes in this switch statement here must be listed
2491 * in one of those places as standardized option types.
2492 */
2493 switch (option_code) {
2494 /* TODO:
2495 * ns_dnsname 2
2496 * ns_dnsIP4addr 3
2497 * ns_dnsIP6addr 4
2498 */
2499 default:
2500 if (!pcapng_process_unhandled_option(wblock, section_info,
2501 option_code, option_length,
2502 option_content,
2503 err, err_info))
2504 return false0;
2505 break;
2506 }
2507 return true1;
2508}
2509
2510static bool_Bool
2511pcapng_read_name_resolution_block(wtap *wth _U___attribute__((unused)), FILE_T fh,
2512 uint32_t block_type _U___attribute__((unused)),
2513 uint32_t block_content_length,
2514 section_info_t *section_info,
2515 wtapng_block_t *wblock,
2516 int *err, char **err_info)
2517{
2518 unsigned to_read;
2519 pcapng_name_resolution_block_t nrb;
2520 Buffer nrb_rec;
2521 uint32_t v4_addr;
2522 unsigned record_len, opt_cont_buf_len;
2523 const char *namep;
2524 int namelen;
2525 wtapng_nrb_mandatory_t *nrb_mand;
2526
2527 /*
2528 * Is this block long enough to be an NRB?
2529 * There must be at least an "end of records" record.
2530 */
2531 if (block_content_length < sizeof nrb) {
2532 /*
2533 * No.
2534 */
2535 *err = WTAP_ERR_BAD_FILE-13;
2536 *err_info = ws_strdup_printf("pcapng: block content length %u of an NRB is less than the minimum NRB content size %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an NRB is less than the minimum NRB content size %zu"
, block_content_length, sizeof nrb)
2537 block_content_length, sizeof nrb)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an NRB is less than the minimum NRB content size %zu"
, block_content_length, sizeof nrb)
;
2538 return false0;
2539 }
2540
2541 to_read = block_content_length;
2542
2543 ws_debug("total content %u bytes", block_content_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2543, __func__, "total content %u bytes", block_content_length
); } } while (0)
;
2544
2545 /* Ensure we have a name resolution block */
2546 if (wblock->block == NULL((void*)0)) {
2547 wblock->block = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
2548 }
2549
2550 /*
2551 * Set the mandatory values for the block.
2552 */
2553 nrb_mand = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
2554
2555 /*
2556 * Start out with a buffer big enough for an IPv6 address and one
2557 * 64-byte name; we'll make the buffer bigger if necessary.
2558 */
2559 ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE(16 + 256));
2560 while (to_read != 0) {
2561 unsigned padding;
2562
2563 /*
2564 * There must be at least one record's worth of data
2565 * here.
2566 */
2567 if (to_read < sizeof nrb) {
2568 ws_buffer_free(&nrb_rec);
2569 *err = WTAP_ERR_BAD_FILE-13;
2570 *err_info = ws_strdup_printf("pcapng: %u bytes left in the block < NRB record header size %zu",wmem_strdup_printf(((void*)0), "pcapng: %u bytes left in the block < NRB record header size %zu"
, to_read, sizeof nrb)
2571 to_read, sizeof nrb)wmem_strdup_printf(((void*)0), "pcapng: %u bytes left in the block < NRB record header size %zu"
, to_read, sizeof nrb)
;
2572 return false0;
2573 }
2574 if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
2575 ws_buffer_free(&nrb_rec);
2576 ws_debug("failed to read record header")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2576, __func__, "failed to read record header"); } } while (
0)
;
2577 return false0;
2578 }
2579 to_read -= (unsigned)sizeof nrb;
2580
2581 if (section_info->byte_swapped) {
2582 nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type)(((guint16) ( (guint16) ((guint16) (nrb.record_type) >>
8) | (guint16) ((guint16) (nrb.record_type) << 8))))
;
2583 nrb.record_len = GUINT16_SWAP_LE_BE(nrb.record_len)(((guint16) ( (guint16) ((guint16) (nrb.record_len) >> 8
) | (guint16) ((guint16) (nrb.record_len) << 8))))
;
2584 }
2585
2586 padding = WS_PADDING_TO_4(nrb.record_len)((4U - ((nrb.record_len) % 4U)) % 4U); /* padding at end of record */
2587 if (to_read < nrb.record_len + padding) {
2588 ws_buffer_free(&nrb_rec);
2589 *err = WTAP_ERR_BAD_FILE-13;
2590 *err_info = ws_strdup_printf("pcapng: %u bytes left in the block < NRB record length + padding %u",wmem_strdup_printf(((void*)0), "pcapng: %u bytes left in the block < NRB record length + padding %u"
, to_read, nrb.record_len + padding)
2591 to_read, nrb.record_len + padding)wmem_strdup_printf(((void*)0), "pcapng: %u bytes left in the block < NRB record length + padding %u"
, to_read, nrb.record_len + padding)
;
2592 return false0;
2593 }
2594 switch (nrb.record_type) {
2595 case NRES_ENDOFRECORD0:
2596 /* There shouldn't be any more data - but there MAY be options */
2597 goto read_options;
2598 break;
2599 case NRES_IP4RECORD1:
2600 /*
2601 * The smallest possible record must have
2602 * a 4-byte IPv4 address, hence a minimum
2603 * of 4 bytes.
2604 *
2605 * (The pcapng spec really indicates
2606 * that it must be at least 5 bytes,
2607 * as there must be at least one name,
2608 * and it really must be at least 6
2609 * bytes, as the name mustn't be null,
2610 * but there's no need to fail if there
2611 * aren't any names at all, and we
2612 * should report a null name as such.)
2613 */
2614 if (nrb.record_len < 4) {
2615 ws_buffer_free(&nrb_rec);
2616 *err = WTAP_ERR_BAD_FILE-13;
2617 *err_info = ws_strdup_printf("pcapng: NRB IPv4 record length %u < minimum length 4",wmem_strdup_printf(((void*)0), "pcapng: NRB IPv4 record length %u < minimum length 4"
, nrb.record_len)
2618 nrb.record_len)wmem_strdup_printf(((void*)0), "pcapng: NRB IPv4 record length %u < minimum length 4"
, nrb.record_len)
;
2619 return false0;
2620 }
2621 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
2622 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
2623 nrb.record_len, err, err_info)) {
2624 ws_buffer_free(&nrb_rec);
2625 ws_debug("failed to read IPv4 record data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2625, __func__, "failed to read IPv4 record data"); } } while
(0)
;
2626 return false0;
2627 }
2628 to_read -= nrb.record_len;
2629
2630 /*
2631 * Scan through all the names in
2632 * the record and add them.
2633 */
2634 memcpy(&v4_addr,
2635 ws_buffer_start_ptr(&nrb_rec), 4);
2636 /* IPv4 address is in big-endian order in the file always, which is how we store
2637 it internally as well, so don't byte-swap it */
2638 for (namep = (const char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
2639 record_len != 0;
2640 namep += namelen, record_len -= namelen) {
2641 /*
2642 * Scan forward for a null byte.
2643 *
2644 * This will never return a value > record_len.
2645 */
2646 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
2647 if (namelen == -1) {
2648 ws_buffer_free(&nrb_rec);
2649 return false0; /* fail */
2650 }
2651 hashipv4_t *tp = g_new0(hashipv4_t, 1)((hashipv4_t *) g_malloc0_n ((1), sizeof (hashipv4_t)));
2652 tp->addr = v4_addr;
2653 (void) g_strlcpy(tp->name, namep, MAXDNSNAMELEN256);
2654 nrb_mand->ipv4_addr_list = g_list_prepend(nrb_mand->ipv4_addr_list, tp);
2655 }
2656 break;
2657 case NRES_IP6RECORD2:
2658 /*
2659 * The smallest possible record must have
2660 * a 16-byte IPv6 address, hence a minimum
2661 * of 16 bytes.
2662 *
2663 * (The pcapng spec really indicates
2664 * that it must be at least 17 bytes,
2665 * as there must be at least one name,
2666 * and it really must be at least 18
2667 * bytes, as the name mustn't be null,
2668 * but there's no need to fail if there
2669 * aren't any names at all, and we
2670 * should report a null name as such.)
2671 */
2672 if (nrb.record_len < 16) {
2673 ws_buffer_free(&nrb_rec);
2674 *err = WTAP_ERR_BAD_FILE-13;
2675 *err_info = ws_strdup_printf("pcapng: NRB record length for IPv6 record %u < minimum length 16",wmem_strdup_printf(((void*)0), "pcapng: NRB record length for IPv6 record %u < minimum length 16"
, nrb.record_len)
2676 nrb.record_len)wmem_strdup_printf(((void*)0), "pcapng: NRB record length for IPv6 record %u < minimum length 16"
, nrb.record_len)
;
2677 return false0;
2678 }
2679 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
2680 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
2681 nrb.record_len, err, err_info)) {
2682 ws_buffer_free(&nrb_rec);
2683 return false0;
2684 }
2685 to_read -= nrb.record_len;
2686
2687 for (namep = (const char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
2688 record_len != 0;
2689 namep += namelen, record_len -= namelen) {
2690 /*
2691 * Scan forward for a null byte.
2692 *
2693 * This will never return a value > record_len.
2694 */
2695 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
2696 if (namelen == -1) {
2697 ws_buffer_free(&nrb_rec);
2698 return false0; /* fail */
2699 }
2700 hashipv6_t *tp = g_new0(hashipv6_t, 1)((hashipv6_t *) g_malloc0_n ((1), sizeof (hashipv6_t)));
2701 memcpy(tp->addr, ws_buffer_start_ptr(&nrb_rec), sizeof tp->addr);
2702 (void) g_strlcpy(tp->name, namep, MAXDNSNAMELEN256);
2703 nrb_mand->ipv6_addr_list = g_list_prepend(nrb_mand->ipv6_addr_list, tp);
2704 }
2705 break;
2706 default:
2707 ws_debug("unknown record type 0x%x", nrb.record_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2707, __func__, "unknown record type 0x%x", nrb.record_type
); } } while (0)
;
2708 if (!wtap_read_bytes(fh, NULL((void*)0), nrb.record_len, err, err_info)) {
2709 ws_buffer_free(&nrb_rec);
2710 return false0;
2711 }
2712 to_read -= nrb.record_len;
2713 break;
2714 }
2715
2716 /* Skip padding */
2717 if (!wtap_read_bytes(fh, NULL((void*)0), padding, err, err_info)) {
2718 ws_buffer_free(&nrb_rec);
2719 return false0;
2720 }
2721 to_read -= padding;
2722 }
2723
2724read_options:
2725 /* Options */
2726 opt_cont_buf_len = to_read;
2727 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2728 pcapng_process_name_resolution_block_option,
2729 OPT_SECTION_BYTE_ORDER, err, err_info))
2730 return false0;
2731
2732 ws_buffer_free(&nrb_rec);
2733
2734 /*
2735 * We don't return these to the caller in pcapng_read().
2736 */
2737 wblock->internal = true1;
2738
2739 return true1;
2740}
2741
2742static bool_Bool
2743pcapng_process_interface_statistics_block_option(wtapng_block_t *wblock,
2744 section_info_t *section_info,
2745 uint16_t option_code,
2746 uint16_t option_length,
2747 const uint8_t *option_content,
2748 int *err, char **err_info)
2749{
2750 /*
2751 * Handle option content.
2752 *
2753 * ***DO NOT*** add any items to this table that are not
2754 * standardized option codes in either section 3.5 "Options"
2755 * of the current pcapng spec, at
2756 *
2757 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
2758 *
2759 * or in the list of options in section 4.1 "Section Header Block"
2760 * of the current pcapng spec, at
2761 *
2762 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
2763 *
2764 * All option codes in this switch statement here must be listed
2765 * in one of those places as standardized option types.
2766 */
2767 switch (option_code) {
2768 case(OPT_ISB_STARTTIME2): /* isb_starttime */
2769 pcapng_process_timestamp_option(wblock, section_info,
2770 OPT_SECTION_BYTE_ORDER,
2771 option_code, option_length,
2772 option_content);
2773 break;
2774 case(OPT_ISB_ENDTIME3): /* isb_endtime */
2775 pcapng_process_timestamp_option(wblock, section_info,
2776 OPT_SECTION_BYTE_ORDER,
2777 option_code, option_length,
2778 option_content);
2779 break;
2780 case(OPT_ISB_IFRECV4): /* isb_ifrecv */
2781 pcapng_process_uint64_option(wblock, section_info,
2782 OPT_SECTION_BYTE_ORDER,
2783 option_code, option_length,
2784 option_content);
2785 break;
2786 case(OPT_ISB_IFDROP5): /* isb_ifdrop */
2787 pcapng_process_uint64_option(wblock, section_info,
2788 OPT_SECTION_BYTE_ORDER,
2789 option_code, option_length,
2790 option_content);
2791 break;
2792 case(OPT_ISB_FILTERACCEPT6): /* isb_filteraccept 6 */
2793 pcapng_process_uint64_option(wblock, section_info,
2794 OPT_SECTION_BYTE_ORDER,
2795 option_code, option_length,
2796 option_content);
2797 break;
2798 case(OPT_ISB_OSDROP7): /* isb_osdrop 7 */
2799 pcapng_process_uint64_option(wblock, section_info,
2800 OPT_SECTION_BYTE_ORDER,
2801 option_code, option_length,
2802 option_content);
2803 break;
2804 case(OPT_ISB_USRDELIV8): /* isb_usrdeliv 8 */
2805 pcapng_process_uint64_option(wblock, section_info,
2806 OPT_SECTION_BYTE_ORDER,
2807 option_code, option_length,
2808 option_content);
2809 break;
2810 default:
2811 if (!pcapng_process_unhandled_option(wblock, section_info,
2812 option_code, option_length,
2813 option_content,
2814 err, err_info))
2815 return false0;
2816 break;
2817 }
2818 return true1;
2819}
2820
2821static bool_Bool
2822pcapng_read_interface_statistics_block(wtap *wth _U___attribute__((unused)), FILE_T fh,
2823 uint32_t block_type _U___attribute__((unused)),
2824 uint32_t block_content_length,
2825 section_info_t *section_info,
2826 wtapng_block_t *wblock,
2827 int *err, char **err_info)
2828{
2829 unsigned opt_cont_buf_len;
2830 pcapng_interface_statistics_block_t isb;
2831 wtapng_if_stats_mandatory_t* if_stats_mand;
2832
2833 /*
2834 * Is this block long enough to be an ISB?
2835 */
2836 if (block_content_length < sizeof isb) {
2837 /*
2838 * No.
2839 */
2840 *err = WTAP_ERR_BAD_FILE-13;
2841 *err_info = ws_strdup_printf("pcapng: block content length %u of an ISB is less than the minimum ISB content size %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an ISB is less than the minimum ISB content size %zu"
, block_content_length, sizeof isb)
2842 block_content_length, sizeof isb)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of an ISB is less than the minimum ISB content size %zu"
, block_content_length, sizeof isb)
;
2843 return false0;
2844 }
2845
2846 /* "Interface Statistics Block" read fixed part */
2847 if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
2848 ws_debug("failed to read packet data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2848, __func__, "failed to read packet data"); } } while (0
)
;
2849 return false0;
2850 }
2851
2852 /*
2853 * Set wblock->block to a newly-allocated interface statistics block.
2854 */
2855 wblock->block = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
2856
2857 /*
2858 * Set the mandatory values for the block.
2859 */
2860 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
2861 if (section_info->byte_swapped) {
2862 if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id)(((guint32) ( (((guint32) (isb.interface_id) & (guint32) 0x000000ffU
) << 24) | (((guint32) (isb.interface_id) & (guint32
) 0x0000ff00U) << 8) | (((guint32) (isb.interface_id) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (isb.interface_id
) & (guint32) 0xff000000U) >> 24))))
;
2863 if_stats_mand->ts_high = GUINT32_SWAP_LE_BE(isb.timestamp_high)(((guint32) ( (((guint32) (isb.timestamp_high) & (guint32
) 0x000000ffU) << 24) | (((guint32) (isb.timestamp_high
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (isb
.timestamp_high) & (guint32) 0x00ff0000U) >> 8) | (
((guint32) (isb.timestamp_high) & (guint32) 0xff000000U) >>
24))))
;
2864 if_stats_mand->ts_low = GUINT32_SWAP_LE_BE(isb.timestamp_low)(((guint32) ( (((guint32) (isb.timestamp_low) & (guint32)
0x000000ffU) << 24) | (((guint32) (isb.timestamp_low) &
(guint32) 0x0000ff00U) << 8) | (((guint32) (isb.timestamp_low
) & (guint32) 0x00ff0000U) >> 8) | (((guint32) (isb
.timestamp_low) & (guint32) 0xff000000U) >> 24))))
;
2865 } else {
2866 if_stats_mand->interface_id = isb.interface_id;
2867 if_stats_mand->ts_high = isb.timestamp_high;
2868 if_stats_mand->ts_low = isb.timestamp_low;
2869 }
2870 ws_debug("interface_id %u", if_stats_mand->interface_id)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2870, __func__, "interface_id %u", if_stats_mand->interface_id
); } } while (0)
;
2871
2872 /* Options */
2873 opt_cont_buf_len = block_content_length - sizeof isb;
2874 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2875 pcapng_process_interface_statistics_block_option,
2876 OPT_SECTION_BYTE_ORDER, err, err_info))
2877 return false0;
2878
2879 /*
2880 * We don't return these to the caller in pcapng_read().
2881 */
2882 wblock->internal = true1;
2883
2884 return true1;
2885}
2886
2887void
2888register_pcapng_custom_block_enterprise_handler(unsigned enterprise_number, pcapng_custom_block_enterprise_handler_t* handler)
2889{
2890 g_hash_table_insert(custom_enterprise_handlers, GUINT_TO_POINTER(enterprise_number)((gpointer) (gulong) (enterprise_number)), handler);
2891}
2892
2893static bool_Bool
2894pcapng_read_custom_block(wtap *wth _U___attribute__((unused)), FILE_T fh, uint32_t block_type,
2895 uint32_t block_content_length,
2896 section_info_t *section_info, wtapng_block_t *wblock,
2897 int *err, char **err_info)
2898{
2899 pcapng_custom_block_t cb;
2900 uint32_t pen;
2901 pcapng_custom_block_enterprise_handler_t* pen_handler;
2902
2903 /* Is this block long enough to be an CB? */
2904 if (block_content_length < sizeof cb) {
2905 /*
2906 * No.
2907 */
2908 *err = WTAP_ERR_BAD_FILE-13;
2909 *err_info = ws_strdup_printf("pcapng: block content length %u of a CB is less than the minimum CB content size %zu",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of a CB is less than the minimum CB content size %zu"
, block_content_length, sizeof cb)
2910 block_content_length, sizeof cb)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of a CB is less than the minimum CB content size %zu"
, block_content_length, sizeof cb)
;
2911 return false0;
2912 }
2913
2914 wblock->block = wtap_block_create(WTAP_BLOCK_CUSTOM);
2915
2916 /* Custom block read fixed part */
2917 if (!wtap_read_bytes(fh, &cb, sizeof cb, err, err_info)) {
2918 ws_debug("failed to read pen")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2918, __func__, "failed to read pen"); } } while (0)
;
2919 return false0;
2920 }
2921 if (section_info->byte_swapped) {
2922 pen = GUINT32_SWAP_LE_BE(cb.pen)(((guint32) ( (((guint32) (cb.pen) & (guint32) 0x000000ffU
) << 24) | (((guint32) (cb.pen) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (cb.pen) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (cb.pen) & (guint32) 0xff000000U
) >> 24))))
;
2923 } else {
2924 pen = cb.pen;
2925 }
2926 uint32_t block_payload_length = block_content_length - sizeof cb;
2927 ws_debug("pen %u, custom data and option length %u", pen, block_payload_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2927, __func__, "pen %u, custom data and option length %u",
pen, block_payload_length); } } while (0)
;
2928
2929 wtap_setup_custom_block_rec(wblock->rec, pen, block_payload_length,
2930 (block_type == BLOCK_TYPE_CB_COPY0x00000BAD));
2931
2932 pen_handler = (pcapng_custom_block_enterprise_handler_t*)g_hash_table_lookup(custom_enterprise_handlers, GUINT_TO_POINTER(pen)((gpointer) (gulong) (pen)));
2933
2934 if (pen_handler != NULL((void*)0))
2935 {
2936 if (!pen_handler->parser(fh, section_info, wblock, err, err_info))
2937 return false0;
2938 }
2939 else
2940 {
2941 ws_debug("unknown pen %u", pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2941, __func__, "unknown pen %u", pen); } } while (0)
;
2942 if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
2943 block_payload_length, err, err_info))
2944 return false0;
2945 }
2946
2947 wblock->rec->block = wblock->block;
2948 wblock->block = NULL((void*)0);
2949 /*
2950 * We return these to the caller in pcapng_read().
2951 */
2952 wblock->internal = false0;
2953
2954 return true1;
2955}
2956
2957static bool_Bool
2958pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh,
2959 uint32_t block_type _U___attribute__((unused)),
2960 uint32_t block_content_length,
2961 section_info_t *section_info _U___attribute__((unused)),
2962 wtapng_block_t *wblock,
2963 int *err, char **err_info)
2964{
2965 uint32_t entry_length;
2966 uint64_t rt_ts;
2967 bool_Bool have_ts = false0;
2968
2969 if (block_content_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE23) {
2970 *err = WTAP_ERR_BAD_FILE-13;
2971 *err_info = ws_strdup_printf("pcapng: block content length %u of a systemd journal export is less than the minimum systemd journal export content size %u",wmem_strdup_printf(((void*)0), "pcapng: block content length %u of a systemd journal export is less than the minimum systemd journal export content size %u"
, block_content_length, 23)
2972 block_content_length,wmem_strdup_printf(((void*)0), "pcapng: block content length %u of a systemd journal export is less than the minimum systemd journal export content size %u"
, block_content_length, 23)
2973 MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE)wmem_strdup_printf(((void*)0), "pcapng: block content length %u of a systemd journal export is less than the minimum systemd journal export content size %u"
, block_content_length, 23)
;
2974 return false0;
2975 }
2976
2977 entry_length = block_content_length;
2978
2979 /* Includes padding bytes. */
2980 if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
2981 entry_length, err, err_info)) {
2982 return false0;
2983 }
2984
2985 /*
2986 * We don't have memmem available everywhere, so we get to add space for
2987 * a trailing \0 for strstr below.
2988 */
2989 ws_buffer_assure_space(&wblock->rec->data, entry_length+1);
2990
2991 char *buf_ptr = (char *) ws_buffer_start_ptr(&wblock->rec->data);
2992 while (entry_length > 0 && buf_ptr[entry_length-1] == '\0') {
2993 entry_length--;
2994 }
2995
2996 if (entry_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE23) {
2997 *err = WTAP_ERR_BAD_FILE-13;
2998 *err_info = ws_strdup_printf("pcapng: entry length %u is too small (< %u)",wmem_strdup_printf(((void*)0), "pcapng: entry length %u is too small (< %u)"
, entry_length, 23)
2999 entry_length, MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE)wmem_strdup_printf(((void*)0), "pcapng: entry length %u is too small (< %u)"
, entry_length, 23)
;
3000 return false0;
3001 }
3002
3003 ws_debug("entry_length %u", entry_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3003, __func__, "entry_length %u", entry_length); } } while
(0)
;
3004
3005 size_t rt_ts_len = strlen(SDJ__REALTIME_TIMESTAMP"__REALTIME_TIMESTAMP=");
3006
3007 buf_ptr[entry_length] = '\0';
3008 char *ts_pos = strstr(buf_ptr, SDJ__REALTIME_TIMESTAMP"__REALTIME_TIMESTAMP=");
3009
3010 if (!ts_pos) {
3011 ws_debug("no timestamp")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3011, __func__, "no timestamp"); } } while (0)
;
3012 } else if (ts_pos+rt_ts_len >= (char *) buf_ptr+entry_length) {
3013 ws_debug("timestamp past end of buffer")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3013, __func__, "timestamp past end of buffer"); } } while (
0)
;
3014 } else {
3015 const char *ts_end;
3016 have_ts = ws_strtou64(ts_pos+rt_ts_len, &ts_end, &rt_ts);
3017
3018 if (!have_ts) {
3019 ws_debug("invalid timestamp")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3019, __func__, "invalid timestamp"); } } while (0)
;
3020 }
3021 }
3022
3023 wtap_setup_systemd_journal_export_rec(wblock->rec);
3024 wblock->rec->rec_header.systemd_journal_export_header.record_len = entry_length;
3025 wblock->rec->presence_flags = WTAP_HAS_CAP_LEN0x00000002;
3026 if (have_ts) {
3027 wblock->rec->presence_flags |= WTAP_HAS_TS0x00000001;
3028 wblock->rec->tsprec = WTAP_TSPREC_USEC6;
3029 wblock->rec->ts.secs = (time_t) (rt_ts / 1000000);
3030 wblock->rec->ts.nsecs = (rt_ts % 1000000) * 1000;
3031 }
3032
3033 /*
3034 * We return these to the caller in pcapng_read().
3035 */
3036 wblock->internal = false0;
3037
3038 if (wth->file_encap == WTAP_ENCAP_NONE-2) {
3039 /*
3040 * Nothing (most notably an IDB) has set a file encap at this point.
3041 * Do so here.
3042 * XXX Should we set WTAP_ENCAP_SYSTEMD_JOURNAL if appropriate?
3043 */
3044 wth->file_encap = WTAP_ENCAP_PER_PACKET-1;
3045 }
3046
3047 return true1;
3048}
3049
3050static bool_Bool
3051pcapng_read_unknown_block(FILE_T fh, guint32 block_content_length,
3052 section_info_t *section_info _U___attribute__((unused)), wtapng_block_t *wblock,
3053 int *err, char **err_info)
3054{
3055 /* Skip the block content. */
3056 if (!wtap_read_bytes(fh, NULL((void*)0), block_content_length, err, err_info)) {
3057 return false0;
3058 }
3059
3060 /*
3061 * We're skipping this, so we won't return these to the caller
3062 * in pcapng_read().
3063 */
3064 wblock->internal = true1;
3065
3066 return true1;
3067}
3068
3069static bool_Bool
3070pcapng_read_and_check_block_trailer(FILE_T fh, pcapng_block_header_t *bh,
3071 section_info_t *section_info,
3072 int *err, char **err_info)
3073{
3074 uint32_t block_total_length;
3075
3076 /* sanity check: first and second block lengths must match */
3077 if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
3078 err, err_info)) {
3079 ws_debug("couldn't read second block length")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3079, __func__, "couldn't read second block length"); } } while
(0)
;
3080 return false0;
3081 }
3082
3083 if (section_info->byte_swapped)
3084 block_total_length = GUINT32_SWAP_LE_BE(block_total_length)(((guint32) ( (((guint32) (block_total_length) & (guint32
) 0x000000ffU) << 24) | (((guint32) (block_total_length
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (block_total_length
) & (guint32) 0x00ff0000U) >> 8) | (((guint32) (block_total_length
) & (guint32) 0xff000000U) >> 24))))
;
3085
3086 /*
3087 * According to the pcapng spec, this should equal the block total
3088 * length value at the beginning of the block, which MUST (in the
3089 * IANA sense) be a multiple of 4.
3090 *
3091 * We round the value at the beginning of the block to a multiple
3092 * of 4, so do so with this value as well. This *does* mean that
3093 * the two values, if they're not both multiples of 4, can differ
3094 * and this code won't detect that, but we're already not detecting
3095 * non-multiple-of-4 total lengths.
3096 */
3097 block_total_length = WS_ROUNDUP_4(block_total_length)(((block_total_length) + ((unsigned)(4U-1U))) & (~((unsigned
)(4U-1U))))
;
3098
3099 if (block_total_length != bh->block_total_length) {
3100 *err = WTAP_ERR_BAD_FILE-13;
3101 *err_info = ws_strdup_printf("pcapng: total block lengths (first %u and second %u) don't match",wmem_strdup_printf(((void*)0), "pcapng: total block lengths (first %u and second %u) don't match"
, bh->block_total_length, block_total_length)
3102 bh->block_total_length, block_total_length)wmem_strdup_printf(((void*)0), "pcapng: total block lengths (first %u and second %u) don't match"
, bh->block_total_length, block_total_length)
;
3103 return false0;
3104 }
3105 return true1;
3106}
3107
3108static bool_Bool
3109pcapng_read_block(wtap *wth, FILE_T fh,
3110 section_info_t *section_info,
3111 section_info_t *new_section_info,
3112 wtapng_block_t *wblock,
3113 int *err, char **err_info)
3114{
3115 pcapng_block_type_information_t *handler;
3116 block_return_val ret;
3117 pcapng_block_header_t bh;
3118 uint32_t block_content_length;
3119
3120 wblock->block = NULL((void*)0);
3121
3122 /* Try to read the (next) block header */
3123 if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
3124 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3124, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
3125 return false0;
3126 }
3127
3128 /*
3129 * SHBs have to be treated differently from other blocks, because
3130 * the byte order of the fields in the block can only be determined
3131 * by looking at the byte-order magic number inside the block, not
3132 * by using the byte order of the section to which it belongs, as
3133 * it is the block that *defines* the byte order of the section to
3134 * which it belongs.
3135 */
3136 if (bh.block_type == BLOCK_TYPE_SHB0x0A0D0D0A) {
3137 /*
3138 * BLOCK_TYPE_SHB has the same value regardless of byte order,
3139 * so we don't need to byte-swap it.
3140 *
3141 * We *might* need to byte-swap the total length, but we
3142 * can't determine whether we do until we look inside the
3143 * block and find the byte-order magic number, so we rely
3144 * on pcapng_read_section_header_block() to do that and
3145 * to swap the total length (as it needs to get the total
3146 * length in the right byte order in order to read the
3147 * entire block).
3148 */
3149 wblock->type = bh.block_type;
3150
3151 ws_debug("block_type BLOCK_TYPE_SHB (0x%08x)", bh.block_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3151, __func__, "block_type BLOCK_TYPE_SHB (0x%08x)", bh.block_type
); } } while (0)
;
3152
3153 /*
3154 * Fill in the section_info_t passed to us for use when
3155 * there's a new SHB; don't overwrite the existing SHB,
3156 * if there is one.
3157 */
3158 ret = pcapng_read_section_header_block(fh, &bh, new_section_info,
3159 wblock, err, err_info);
3160 if (ret != PCAPNG_BLOCK_OK) {
3161 return false0;
3162 }
3163
3164 /*
3165 * This is the current section; use its byte order, not that
3166 * of the section pointed to by section_info (which could be
3167 * null).
3168 */
3169 section_info = new_section_info;
3170
3171 /*
3172 * Get information for this block type, for use when setting the
3173 * internal flag.
3174 */
3175 handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(bh.block_type)((gpointer) (gulong) (bh.block_type)));
Value stored to 'handler' is never read
3176 } else {
3177 /*
3178 * Not an SHB.
3179 */
3180 if (section_info->byte_swapped) {
3181 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type)(((guint32) ( (((guint32) (bh.block_type) & (guint32) 0x000000ffU
) << 24) | (((guint32) (bh.block_type) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (bh.block_type) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (bh.block_type) & (guint32) 0xff000000U
) >> 24))))
;
3182 bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length)(((guint32) ( (((guint32) (bh.block_total_length) & (guint32
) 0x000000ffU) << 24) | (((guint32) (bh.block_total_length
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (bh.
block_total_length) & (guint32) 0x00ff0000U) >> 8) |
(((guint32) (bh.block_total_length) & (guint32) 0xff000000U
) >> 24))))
;
3183 }
3184
3185 if (bh.block_total_length < MIN_BLOCK_SIZE((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t))
)
) {
3186 *err = WTAP_ERR_BAD_FILE-13;
3187 *err_info = ws_strdup_printf("pcapng: total block length %u of block is less than the minimum block size %u",wmem_strdup_printf(((void*)0), "pcapng: total block length %u of block is less than the minimum block size %u"
, bh.block_total_length, ((uint32_t)(sizeof(pcapng_block_header_t
) + sizeof(uint32_t))))
3188 bh.block_total_length, MIN_BLOCK_SIZE)wmem_strdup_printf(((void*)0), "pcapng: total block length %u of block is less than the minimum block size %u"
, bh.block_total_length, ((uint32_t)(sizeof(pcapng_block_header_t
) + sizeof(uint32_t))))
;
3189 return false0;
3190 }
3191
3192 /*
3193 * Add padding bytes to the block total length.
3194 * (The "block total length" fields of some example files
3195 * don't contain the packet data padding bytes!)
3196 *
3197 * For all block types currently defined in the pcapng
3198 * specification, the portion of the block that precedes
3199 * the options is, if necessary, padded to be a multiple
3200 * of 4 octets, the header of an option is 4 octets long,
3201 * and the value of an option is also padded to be a
3202 * multiple of 4 octets, so the total length of a block
3203 * is always a multiple of 4 octets.
3204 *
3205 * If you have defined a block where that is not true, you
3206 * have violated the pcapng specification - where it says
3207 * that "[The value of the Block Total Length] MUST be a
3208 * multiple of 4.", with MUST as described in BCP 14 (RFC 2119/
3209 * RFC 8174).
3210 *
3211 * Therefore, if adjusting the block total length causes the
3212 * code to read your block type not to work, that's your
3213 * problem. It's bad enough that some blocks were written
3214 * out with the block total length not including the padding.
3215 * (Please note that libpcap is less forgiving that we are;
3216 * it reports an error if the block total length isn't a
3217 * multiple of 4.)
3218 */
3219 bh.block_total_length = WS_ROUNDUP_4(bh.block_total_length)(((bh.block_total_length) + ((unsigned)(4U-1U))) & (~((unsigned
)(4U-1U))))
;
3220
3221 wblock->type = bh.block_type;
3222
3223 ws_noisy("block_type 0x%08x", bh.block_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3223, __func__, "block_type 0x%08x", bh.block_type); } } while
(0)
;
3224
3225 /* Don't try to allocate memory for a huge number of options, as
3226 that might fail and, even if it succeeds, it might not leave
3227 any address space or memory+backing store for anything else.
3228
3229 We do that by imposing a maximum block size of MAX_BLOCK_SIZE. */
3230 if (bh.block_total_length > MAX_BLOCK_SIZE(((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t) + sizeof
(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t))) + (128U
*1024U*1024U) + 131072)
) {
3231 *err = WTAP_ERR_BAD_FILE-13;
3232 *err_info = ws_strdup_printf("pcapng: total block length %u is too large (> %u)",wmem_strdup_printf(((void*)0), "pcapng: total block length %u is too large (> %u)"
, bh.block_total_length, (((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t
) + sizeof(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t
))) + (128U*1024U*1024U) + 131072))
3233 bh.block_total_length, MAX_BLOCK_SIZE)wmem_strdup_printf(((void*)0), "pcapng: total block length %u is too large (> %u)"
, bh.block_total_length, (((uint32_t)(((uint32_t)(sizeof(pcapng_block_header_t
) + sizeof(uint32_t))) + sizeof(pcapng_enhanced_packet_block_t
))) + (128U*1024U*1024U) + 131072))
;
3234 return false0;
3235 }
3236
3237 /*
3238 * Length of the contents of the block.
3239 */
3240 block_content_length = bh.block_total_length - MIN_BLOCK_SIZE((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t))
)
;
3241
3242 /*
3243 * Do we have a handler for this block type?
3244 */
3245 handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(bh.block_type)((gpointer) (gulong) (bh.block_type)));
3246 if (handler != NULL((void*)0)) {
3247 /* Yes - call it to read this block type. */
3248 if (!handler->reader(wth, fh, bh.block_type,
3249 block_content_length, section_info,
3250 wblock, err, err_info))
3251 return false0;
3252 } else {
3253 ws_debug("Unknown block_type: 0x%08x (block ignored), block total length %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3254, __func__, "Unknown block_type: 0x%08x (block ignored), block total length %u"
, bh.block_type, bh.block_total_length); } } while (0)
3254 bh.block_type, bh.block_total_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3254, __func__, "Unknown block_type: 0x%08x (block ignored), block total length %u"
, bh.block_type, bh.block_total_length); } } while (0)
;
3255 if (!pcapng_read_unknown_block(fh, block_content_length,
3256 section_info, wblock,
3257 err, err_info))
3258 return false0;
3259 }
3260 }
3261
3262 /*
3263 * Read and check the block trailer.
3264 */
3265 if (!pcapng_read_and_check_block_trailer(fh, &bh, section_info, err, err_info)) {
3266 /* Not readable or not valid. */
3267 return false0;
3268 }
3269
3270 return true1;
3271}
3272
3273static void
3274pcapng_process_shb(wtap *wth, pcapng_t *pcapng, section_info_t new_section, wtapng_block_t *wblock, const int64_t *data_offset)
3275{
3276 /*
3277 * Add this SHB to the table of SHBs.
3278 */
3279 g_array_append_val(wth->shb_hdrs, wblock->block)g_array_append_vals (wth->shb_hdrs, &(wblock->block
), 1)
;
3280 g_array_append_val(wth->shb_iface_to_global, wth->interface_data->len)g_array_append_vals (wth->shb_iface_to_global, &(wth->
interface_data->len), 1)
;
3281
3282 /*
3283 * Update the current section number, and add
3284 * the updated section_info_t to the array of
3285 * section_info_t's for this file.
3286 */
3287 pcapng->current_section_number++;
3288 new_section.interfaces = g_array_new(false0, false0, sizeof(interface_info_t));
3289 new_section.shb_off = *data_offset;
3290 g_array_append_val(pcapng->sections, new_section)g_array_append_vals (pcapng->sections, &(new_section),
1)
;
3291}
3292
3293/* Process an IDB that we've just read. The contents of wblock are copied as needed. */
3294static bool_Bool
3295pcapng_process_idb(wtap *wth, section_info_t *section_info,
3296 wtapng_block_t *wblock)
3297{
3298 wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
3299 interface_info_t iface_info;
3300 wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data),
3301 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3302 uint8_t if_fcslen;
3303
3304 wtap_block_copy(int_data, wblock->block);
3305
3306 /* XXX if_tsoffset; opt 14 A 64 bits integer value that specifies an offset (in seconds)...*/
3307 /* Interface statistics */
3308 if_descr_mand->num_stat_entries = 0;
3309 if_descr_mand->interface_statistics = NULL((void*)0);
3310
3311 wtap_add_idb(wth, int_data);
3312
3313 iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
3314 iface_info.snap_len = wblock_if_descr_mand->snap_len;
3315 iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
3316 iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
3317
3318 /*
3319 * Did we get an FCS length option?
3320 */
3321 if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_FCSLEN13,
3322 &if_fcslen) == WTAP_OPTTYPE_SUCCESS) {
3323 /*
3324 * Yes.
3325 */
3326 iface_info.fcslen = if_fcslen;
3327 } else {
3328 /*
3329 * No. Mark the FCS length as unknown.
3330 */
3331 iface_info.fcslen = -1;
3332 }
3333
3334 /*
3335 * Did we get a time stamp offset option?
3336 */
3337 if (wtap_block_get_int64_option_value(wblock->block, OPT_IDB_TSOFFSET14,
3338 &iface_info.tsoffset) == WTAP_OPTTYPE_SUCCESS) {
3339 /*
3340 * Yes.
3341 *
3342 * Remove the option, as the time stamps we provide will be
3343 * absolute time stamps, with the offset added in, so it will
3344 * appear as if there were no such option.
3345 */
3346 wtap_block_remove_option(wblock->block, OPT_IDB_TSOFFSET14);
3347 } else {
3348 /*
3349 * No. Default to 0, meahing that time stamps in the file are
3350 * absolute time stamps.
3351 */
3352 iface_info.tsoffset = 0;
3353 }
3354
3355 /*
3356 * Did we get a time stamp precision option?
3357 */
3358 iface_info.tsresol_binary = 0;
3359 uint8_t if_tsresol;
3360 if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_TSRESOL9,
3361 &if_tsresol) == WTAP_OPTTYPE_SUCCESS) {
3362 /* Is the timestamp resolution a power of two? */
3363 if (if_tsresol & 0x80) {
3364 /* Note that 0x80 and 0x80 mean the same thing, as 2^-0 == 10^-0 */
3365 iface_info.tsresol_binary = if_tsresol & 0x7F;
3366 }
3367 }
3368 g_array_append_val(section_info->interfaces, iface_info)g_array_append_vals (section_info->interfaces, &(iface_info
), 1)
;
3369
3370 wtap_block_unref(wblock->block);
3371
3372 return true1;
3373}
3374
3375/* Process an NRB that we have just read. */
3376static bool_Bool
3377pcapng_process_nrb(wtap *wth, section_info_t *section_info _U___attribute__((unused)),
3378 wtapng_block_t *wblock)
3379{
3380 wtapng_process_nrb(wth, wblock->block);
3381
3382 if (wth->nrbs == NULL((void*)0)) {
3383 wth->nrbs = g_array_new(false0, false0, sizeof(wtap_block_t));
3384 }
3385 /* Store NRB such that it can be saved by the dumper. */
3386 g_array_append_val(wth->nrbs, wblock->block)g_array_append_vals (wth->nrbs, &(wblock->block), 1
)
;
3387 /* Do not free wblock->block, it is consumed above */
3388
3389 return true1;
3390}
3391
3392/* Process a DSB that we have just read. */
3393static bool_Bool
3394pcapng_process_dsb(wtap *wth, section_info_t *section_info _U___attribute__((unused)),
3395 wtapng_block_t *wblock)
3396{
3397 wtapng_process_dsb(wth, wblock->block);
3398
3399 /* Store DSB such that it can be saved by the dumper. */
3400 g_array_append_val(wth->dsbs, wblock->block)g_array_append_vals (wth->dsbs, &(wblock->block), 1
)
;
3401
3402 /* Do not free wblock->block, it is consumed above */
3403
3404 return true1;
3405}
3406
3407/* Process a ISB that we have just read. */
3408static bool_Bool
3409pcapng_process_isb(wtap *wth, section_info_t *section_info _U___attribute__((unused)),
3410 wtapng_block_t *wblock)
3411{
3412 wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
3413 wtap_block_t if_stats;
3414 wtap_block_t wtapng_if_descr;
3415 wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
3416
3417 /*
3418 * Another interface statistics report
3419 *
3420 * XXX - given that they're reports, we should be
3421 * supplying them in read calls, and displaying them
3422 * in the "packet" list, so you can see what the
3423 * statistics were *at the time when the report was
3424 * made*.
3425 *
3426 * The statistics from the *last* ISB could be displayed
3427 * in the summary, but if there are packets after the
3428 * last ISB, that could be misleading.
3429 *
3430 * If we only display them if that ISB has an isb_endtime
3431 * option, which *should* only appear when capturing ended
3432 * on that interface (so there should be no more packet
3433 * blocks or ISBs for that interface after that point,
3434 * that would be the best way of showing "summary"
3435 * statistics.
3436 */
3437 ws_debug("block type BLOCK_TYPE_ISB")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3437, __func__, "block type BLOCK_TYPE_ISB"); } } while (0)
;
3438 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3439 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
3440 ws_debug("BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3441, __func__, "BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces"
, if_stats_mand_block->interface_id); } } while (0)
3441 if_stats_mand_block->interface_id)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3441, __func__, "BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces"
, if_stats_mand_block->interface_id); } } while (0)
;
3442 } else {
3443 /* Get the interface description */
3444 wtapng_if_descr = g_array_index(wth->interface_data, wtap_block_t, if_stats_mand_block->interface_id)(((wtap_block_t*) (void *) (wth->interface_data)->data)
[(if_stats_mand_block->interface_id)])
;
3445 wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
3446 if (wtapng_if_descr_mand->num_stat_entries == 0) {
3447 /* First ISB found, no previous entry */
3448 ws_debug("block type BLOCK_TYPE_ISB. First ISB found, no previous entry")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3448, __func__, "block type BLOCK_TYPE_ISB. First ISB found, no previous entry"
); } } while (0)
;
3449 wtapng_if_descr_mand->interface_statistics = g_array_new(false0, false0, sizeof(wtap_block_t));
3450 }
3451
3452 if_stats = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
3453 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
3454 if_stats_mand->interface_id = if_stats_mand_block->interface_id;
3455 if_stats_mand->ts_high = if_stats_mand_block->ts_high;
3456 if_stats_mand->ts_low = if_stats_mand_block->ts_low;
3457
3458 wtap_block_copy(if_stats, wblock->block);
3459 g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats)g_array_append_vals (wtapng_if_descr_mand->interface_statistics
, &(if_stats), 1)
;
3460 wtapng_if_descr_mand->num_stat_entries++;
3461 }
3462 wtap_block_unref(wblock->block);
3463 return true1;
3464}
3465
3466static void
3467pcapng_process_internal_block(wtap *wth, pcapng_t *pcapng, section_info_t *section, section_info_t new_section, wtapng_block_t *wblock, const int64_t *data_offset)
3468{
3469 if (wblock->type == BLOCK_TYPE_SHB0x0A0D0D0A) {
3470 pcapng_process_shb(wth, pcapng, new_section, wblock, data_offset);
3471 } else {
3472 pcapng_block_type_information_t* handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(wblock->type)((gpointer) (gulong) (wblock->type)));
3473
3474 if (handler != NULL((void*)0)) {
3475 /* XXX - Is it okay to not have a processor? */
3476 if (handler->processor != NULL((void*)0)) {
3477 handler->processor(wth, section, wblock);
3478 }
3479 } else {
3480 /* XXX - improve handling of "unknown" blocks */
3481 ws_debug("Unknown block type 0x%08x", wblock->type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3481, __func__, "Unknown block type 0x%08x", wblock->type
); } } while (0)
;
3482 }
3483 }
3484}
3485
3486/* classic wtap: open capture file */
3487wtap_open_return_val
3488pcapng_open(wtap *wth, int *err, char **err_info)
3489{
3490 wtapng_block_t wblock;
3491 pcapng_t *pcapng;
3492 pcapng_block_header_t bh;
3493 int64_t saved_offset;
3494 section_info_t first_section, new_section, *current_section;
3495
3496 ws_debug("opening file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3496, __func__, "opening file"); } } while (0)
;
3497 /*
3498 * Read first block.
3499 *
3500 * First, try to read the block header.
3501 */
3502 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3503 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3503, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
3504 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12) {
3505 /*
3506 * Short read or EOF.
3507 *
3508 * We're reading this as part of an open, so
3509 * the file is too short to be a pcapng file.
3510 */
3511 *err = 0;
3512 g_free(*err_info);
3513 *err_info = NULL((void*)0);
3514 return WTAP_OPEN_NOT_MINE;
3515 }
3516 return WTAP_OPEN_ERROR;
3517 }
3518
3519 /*
3520 * If this is a pcapng file, the first block must be a
3521 * Section Header Block.
3522 */
3523 if (bh.block_type != BLOCK_TYPE_SHB0x0A0D0D0A) {
3524 /*
3525 * Not an SHB, so this isn't a pcapng file.
3526 *
3527 * XXX - check for damage from transferring a file
3528 * between Windows and UN*X as text rather than
3529 * binary data?
3530 */
3531 ws_debug("first block type 0x%08x not SHB", bh.block_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3531, __func__, "first block type 0x%08x not SHB", bh.block_type
); } } while (0)
;
3532 return WTAP_OPEN_NOT_MINE;
3533 }
3534
3535 ws_debug("got an SHB")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3535, __func__, "got an SHB"); } } while (0)
;
3536
3537 /*
3538 * Now try to read the block body, filling in the section_info_t
3539 * for the first section.
3540 */
3541 wblock.type = bh.block_type;
3542 wblock.block = NULL((void*)0);
3543 /* we don't expect any packet blocks yet */
3544 wblock.rec = NULL((void*)0);
3545
3546 switch (pcapng_read_section_header_block(wth->fh, &bh, &first_section,
3547 &wblock, err, err_info)) {
3548 case PCAPNG_BLOCK_OK:
3549 /* No problem */
3550 break;
3551
3552 case PCAPNG_BLOCK_NOT_SHB:
3553 /* This doesn't look like an SHB, so this isn't a pcapng file. */
3554 wtap_block_unref(wblock.block);
3555 *err = 0;
3556 g_free(*err_info);
3557 *err_info = NULL((void*)0);
3558 return WTAP_OPEN_NOT_MINE;
3559
3560 case PCAPNG_BLOCK_ERROR:
3561 wtap_block_unref(wblock.block);
3562 if (*err == WTAP_ERR_SHORT_READ-12) {
3563 /*
3564 * Short read.
3565 *
3566 * We're reading this as part of an open, so
3567 * the file is too short to be a pcapng file.
3568 */
3569 *err = 0;
3570 g_free(*err_info);
3571 *err_info = NULL((void*)0);
3572 return WTAP_OPEN_NOT_MINE;
3573 }
3574 /* An I/O error. */
3575 return WTAP_OPEN_ERROR;
3576 }
3577
3578 /*
3579 * Read and check the block trailer.
3580 */
3581 if (!pcapng_read_and_check_block_trailer(wth->fh, &bh, &first_section, err, err_info)) {
3582 /* Not readable or not valid. */
3583 wtap_block_unref(wblock.block);
3584 return WTAP_OPEN_ERROR;
3585 }
3586
3587 /*
3588 * At this point, we've decided this is a pcapng file, not
3589 * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
3590 * past this point.
3591 *
3592 * Copy the SHB that we just read to the first entry in the table of
3593 * SHBs for this file.
3594 */
3595 wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (wth->shb_hdrs)->data) [(0)]
)
, wblock.block);
3596 wtap_block_unref(wblock.block);
3597 wblock.block = NULL((void*)0);
3598
3599 wth->file_encap = WTAP_ENCAP_NONE-2;
3600 wth->snapshot_length = 0;
3601 wth->file_tsprec = WTAP_TSPREC_UNKNOWN-2;
3602 pcapng = g_new(pcapng_t, 1)((pcapng_t *) g_malloc_n ((1), sizeof (pcapng_t)));
3603 wth->priv = (void *)pcapng;
3604 /*
3605 * We're currently processing the first section; as this is written
3606 * in C, that's section 0. :-)
3607 */
3608 pcapng->current_section_number = 0;
3609
3610 /*
3611 * Create the array of interfaces for the first section.
3612 */
3613 first_section.interfaces = g_array_new(false0, false0, sizeof(interface_info_t));
3614
3615 /*
3616 * The first section is at the very beginning of the file.
3617 */
3618 first_section.shb_off = 0;
3619
3620 /*
3621 * Allocate the sections table with space reserved for the first
3622 * section, and add that section.
3623 */
3624 pcapng->sections = g_array_sized_new(false0, false0, sizeof(section_info_t), 1);
3625 g_array_append_val(pcapng->sections, first_section)g_array_append_vals (pcapng->sections, &(first_section
), 1)
;
3626
3627 wth->subtype_read = pcapng_read;
3628 wth->subtype_seek_read = pcapng_seek_read;
3629 wth->subtype_close = pcapng_close;
3630 wth->file_type_subtype = pcapng_file_type_subtype;
3631
3632 /* Always initialize the lists of Decryption Secret Blocks, Name
3633 * Resolution Blocks, and Sysdig meta event blocks such that a
3634 * wtap_dumper can refer to them right after opening the capture
3635 * file. */
3636 wth->dsbs = g_array_new(false0, false0, sizeof(wtap_block_t));
3637 wth->nrbs = g_array_new(false0, false0, sizeof(wtap_block_t));
3638 wth->meta_events = g_array_new(false0, false0, sizeof(wtap_block_t));
3639
3640 /* Most other capture types (such as pcap) support a single link-layer
3641 * type, indicated in the header, and don't support WTAP_ENCAP_PER_PACKET.
3642 * Most programs that write such capture files want to know the link-layer
3643 * type when initially opening the destination file, and (unlike Wireshark)
3644 * don't want to read the entire source file to find all the link-layer
3645 * types before writing (particularly if reading from a pipe or FIFO.)
3646 *
3647 * In support of this, read all the internally-processed, non packet
3648 * blocks that appear before the first packet block (EPB or SPB).
3649 *
3650 * Note that such programs will still have issues when trying to read
3651 * a pcapng that has a new link-layer type in an IDB in the middle of
3652 * the file, as they will discover in the middle that no, they can't
3653 * successfully write the output file as desired.
3654 *
3655 * If this is a live capture, and we're reading the initially written
3656 * header, we'll loop until we reach EOF. (If compressed, it might
3657 * also set WTAP_ERR_SHORT_READ from the stream / frame end not being
3658 * present until the file is closed.) So we'll need to clear that at
3659 * some point before reading packets.
3660 */
3661 while (!file_eof(wth->fh)) {
3662 /* peek at next block */
3663 /* Try to read the (next) block header */
3664 saved_offset = file_tell(wth->fh);
3665 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3666 if (*err == 0) {
3667 /* EOF */
3668 ws_debug("No more blocks available...")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3668, __func__, "No more blocks available..."); } } while (
0)
;
3669 break;
3670 }
3671 ws_debug("Check for more initial blocks, wtap_read_bytes_or_eof() failed, err = %d.",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3672, __func__, "Check for more initial blocks, wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
3672 *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3672, __func__, "Check for more initial blocks, wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
3673 return WTAP_OPEN_ERROR;
3674 }
3675
3676 /* go back to where we were */
3677 file_seek(wth->fh, saved_offset, SEEK_SET0, err);
3678
3679 /*
3680 * Get a pointer to the current section's section_info_t.
3681 */
3682 current_section = &g_array_index(pcapng->sections, section_info_t,(((section_info_t*) (void *) (pcapng->sections)->data) [
(pcapng->current_section_number)])
3683 pcapng->current_section_number)(((section_info_t*) (void *) (pcapng->sections)->data) [
(pcapng->current_section_number)])
;
3684
3685 if (current_section->byte_swapped) {
3686 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type)(((guint32) ( (((guint32) (bh.block_type) & (guint32) 0x000000ffU
) << 24) | (((guint32) (bh.block_type) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (bh.block_type) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (bh.block_type) & (guint32) 0xff000000U
) >> 24))))
;
3687 }
3688
3689 ws_debug("Check for more initial internal blocks, block_type 0x%08x",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3690, __func__, "Check for more initial internal blocks, block_type 0x%08x"
, bh.block_type); } } while (0)
3690 bh.block_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3690, __func__, "Check for more initial internal blocks, block_type 0x%08x"
, bh.block_type); } } while (0)
;
3691
3692 if (!get_block_type_internal(bh.block_type)) {
3693 break; /* Next block has to be returned in pcap_read */
3694 }
3695 /* Note that some custom block types, unlike packet blocks,
3696 * don't need to be preceded by an IDB and so theoretically
3697 * we could skip past them here. However, then there's no good
3698 * way to both later return those blocks in pcap_read() and
3699 * ensure that we don't read and process the IDBs (and other
3700 * internal block types) a second time.
3701 *
3702 * pcapng_read_systemd_journal_export_block() sets the file level
3703 * link-layer type if it's still UNKNOWN. We could do the same here
3704 * for it and possibly other types based on block type, even without
3705 * reading them.
3706 */
3707 if (!pcapng_read_block(wth, wth->fh, current_section,
3708 &new_section, &wblock, err, err_info)) {
3709 wtap_block_unref(wblock.block);
3710 if (*err == 0) {
3711 ws_debug("No more initial blocks available...")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3711, __func__, "No more initial blocks available..."); } }
while (0)
;
3712 break;
3713 } else {
3714 ws_debug("couldn't read block")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3714, __func__, "couldn't read block"); } } while (0)
;
3715 return WTAP_OPEN_ERROR;
3716 }
3717 }
3718 pcapng_process_internal_block(wth, pcapng, current_section, new_section, &wblock, &saved_offset);
3719 ws_debug("Read IDB number_of_interfaces %u, wtap_encap %i",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3720, __func__, "Read IDB number_of_interfaces %u, wtap_encap %i"
, wth->interface_data->len, wth->file_encap); } } while
(0)
3720 wth->interface_data->len, wth->file_encap)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3720, __func__, "Read IDB number_of_interfaces %u, wtap_encap %i"
, wth->interface_data->len, wth->file_encap); } } while
(0)
;
3721 }
3722 return WTAP_OPEN_MINE;
3723}
3724
3725/* classic wtap: read packet */
3726static bool_Bool
3727pcapng_read(wtap *wth, wtap_rec *rec, int *err, char **err_info,
3728 int64_t *data_offset)
3729{
3730 pcapng_t *pcapng = (pcapng_t *)wth->priv;
3731 section_info_t *current_section, new_section;
3732 wtapng_block_t wblock;
3733
3734 wblock.rec = rec;
3735
3736 /* read next block */
3737 while (1) {
3738 *data_offset = file_tell(wth->fh);
3739 ws_noisy("data_offset is %" PRId64, *data_offset)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3739, __func__, "data_offset is %" "l" "d", *data_offset); }
} while (0)
;
3740
3741 /*
3742 * Get the section_info_t for the current section.
3743 */
3744 current_section = &g_array_index(pcapng->sections, section_info_t,(((section_info_t*) (void *) (pcapng->sections)->data) [
(pcapng->current_section_number)])
3745 pcapng->current_section_number)(((section_info_t*) (void *) (pcapng->sections)->data) [
(pcapng->current_section_number)])
;
3746
3747 /*
3748 * Read the next block.
3749 */
3750 if (!pcapng_read_block(wth, wth->fh, current_section,
3751 &new_section, &wblock, err, err_info)) {
3752 ws_noisy("data_offset is finally %" PRId64, *data_offset)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3752, __func__, "data_offset is finally %" "l" "d", *data_offset
); } } while (0)
;
3753 ws_debug("couldn't read packet block")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3753, __func__, "couldn't read packet block"); } } while (0
)
;
3754 wtap_block_unref(wblock.block);
3755 return false0;
3756 }
3757
3758 if (!wblock.internal) {
3759 /*
3760 * This is a block type we return to the caller to process.
3761 */
3762 ws_noisy("rec_type %u", wblock.rec->rec_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3762, __func__, "rec_type %u", wblock.rec->rec_type); } }
while (0)
;
3763 break;
3764 }
3765
3766 /*
3767 * This is a block type we process internally, rather than
3768 * returning it for the caller to process.
3769 */
3770 pcapng_process_internal_block(wth, pcapng, current_section, new_section, &wblock, data_offset);
3771 }
3772
3773 /*ws_debug("Read length: %u Packet length: %u", bytes_read, rec->rec_header.packet_header.caplen);*/
3774 ws_noisy("data_offset is finally %" PRId64, *data_offset)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3774, __func__, "data_offset is finally %" "l" "d", *data_offset
); } } while (0)
;
3775
3776 /* Provide the section number */
3777 rec->presence_flags |= WTAP_HAS_SECTION_NUMBER0x00000008;
3778 rec->section_number = pcapng->current_section_number;
3779
3780 return true1;
3781}
3782
3783/* classic wtap: seek to file position and read packet */
3784static bool_Bool
3785pcapng_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec,
3786 int *err, char **err_info)
3787{
3788 pcapng_t *pcapng = (pcapng_t *)wth->priv;
3789 section_info_t *section_info, new_section;
3790 wtapng_block_t wblock;
3791
3792
3793 /* seek to the right file position */
3794 if (file_seek(wth->random_fh, seek_off, SEEK_SET0, err) < 0) {
3795 return false0; /* Seek error */
3796 }
3797 ws_noisy("reading at offset %" PRIu64, seek_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3797, __func__, "reading at offset %" "l" "u", seek_off); }
} while (0)
;
3798
3799 /*
3800 * Find the section_info_t for the section in which this block
3801 * appears.
3802 *
3803 * First, make sure we have at least one section; if we don't, that's
3804 * an internal error.
3805 */
3806 ws_assert(pcapng->sections->len >= 1)do { if ((1) && !(pcapng->sections->len >= 1
)) ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/pcapng.c"
, 3806, __func__, "assertion failed: %s", "pcapng->sections->len >= 1"
); } while (0)
;
3807
3808 /*
3809 * Now scan backwards through the array to find the first section
3810 * that begins at or before the offset of the block we're reading.
3811 *
3812 * Yes, that's O(n) in the number of blocks, but we're unlikely to
3813 * have many sections and pretty unlikely to have more than one.
3814 */
3815 unsigned section_number = pcapng->sections->len - 1;
3816 for (;;) {
3817 section_info = &g_array_index(pcapng->sections, section_info_t,(((section_info_t*) (void *) (pcapng->sections)->data) [
(section_number)])
3818 section_number)(((section_info_t*) (void *) (pcapng->sections)->data) [
(section_number)])
;
3819 if (section_info->shb_off <= seek_off)
3820 break;
3821
3822 /*
3823 * If that's section 0, something's wrong; that section should
3824 * have an offset of 0.
3825 */
3826 ws_assert(section_number != 0)do { if ((1) && !(section_number != 0)) ws_log_fatal_full
("Wiretap", LOG_LEVEL_ERROR, "wiretap/pcapng.c", 3826, __func__
, "assertion failed: %s", "section_number != 0"); } while (0)
;
3827 section_number--;
3828 }
3829
3830 wblock.rec = rec;
3831
3832 /* read the block */
3833 if (!pcapng_read_block(wth, wth->random_fh, section_info,
3834 &new_section, &wblock, err, err_info)) {
3835 ws_debug("couldn't read packet block (err=%d).", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3835, __func__, "couldn't read packet block (err=%d).", *err
); } } while (0)
;
3836 wtap_block_unref(wblock.block);
3837 return false0;
3838 }
3839
3840 /* block must not be one we process internally rather than supplying */
3841 if (wblock.internal) {
3842 ws_debug("block type 0x%08x is not one we return",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3843, __func__, "block type 0x%08x is not one we return", wblock
.type); } } while (0)
3843 wblock.type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3843, __func__, "block type 0x%08x is not one we return", wblock
.type); } } while (0)
;
3844 wtap_block_unref(wblock.block);
3845 return false0;
3846 }
3847
3848 wtap_block_unref(wblock.block);
3849
3850 /* Provide the section number */
3851 rec->presence_flags |= WTAP_HAS_SECTION_NUMBER0x00000008;
3852 rec->section_number = section_number;
3853
3854 return true1;
3855}
3856
3857/* classic wtap: close capture file */
3858static void
3859pcapng_close(wtap *wth)
3860{
3861 pcapng_t *pcapng = (pcapng_t *)wth->priv;
3862
3863 ws_debug("closing file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3863, __func__, "closing file"); } } while (0)
;
3864
3865 /*
3866 * Free up the interfaces tables for all the sections.
3867 */
3868 for (unsigned i = 0; i < pcapng->sections->len; i++) {
3869 section_info_t *section_info = &g_array_index(pcapng->sections,(((section_info_t*) (void *) (pcapng->sections)->data) [
(i)])
3870 section_info_t, i)(((section_info_t*) (void *) (pcapng->sections)->data) [
(i)])
;
3871 g_array_free(section_info->interfaces, true1);
3872 if (section_info->custom_block_data != NULL((void*)0))
3873 g_hash_table_destroy(section_info->custom_block_data);
3874 if (section_info->local_block_data != NULL((void*)0))
3875 g_hash_table_destroy(section_info->local_block_data);
3876 }
3877 g_array_free(pcapng->sections, true1);
3878}
3879
3880/*
3881 * As it says at the top of the file, an option sizer "calculates how many
3882 * bytes the option's data requires, not including any padding bytes."
3883 * Callers are responsible for rounding up to multiples of 4 bytes.
3884 * compute_block_options_size() does that for each option in the block;
3885 * option writers that call an option sizer (which helps ensure that the
3886 * sizes are internally consistent) should do the same.
3887 */
3888
3889static uint32_t pcapng_compute_string_option_size(wtap_optval_t *optval)
3890{
3891 uint32_t size = 0;
3892
3893 size = (uint32_t)strlen(optval->stringval) & 0xffff;
3894
3895 return size;
3896}
3897
3898#if 0
3899static uint32_t pcapng_compute_bytes_option_size(wtap_optval_t *optval)
3900{
3901 uint32_t size = 0;
3902
3903 size = (uint32_t)g_bytes_get_size(optval->byteval) & 0xffff;
3904
3905 return size;
3906}
3907#endif
3908
3909static uint32_t pcapng_compute_if_filter_option_size(wtap_optval_t *optval)
3910{
3911 if_filter_opt_t* filter = &optval->if_filterval;
3912 uint32_t size;
3913
3914 if (filter->type == if_filter_pcap) {
3915 size = (uint32_t)(strlen(filter->data.filter_str) + 1) & 0xffff;
3916 } else if (filter->type == if_filter_bpf) {
3917 size = (uint32_t)((filter->data.bpf_prog.bpf_prog_len * 8) + 1) & 0xffff;
3918 } else {
3919 /* Unknown type; don't write it */
3920 size = 0;
3921 }
3922 return size;
3923}
3924
3925static uint32_t pcapng_compute_custom_string_option_size(wtap_optval_t *optval)
3926{
3927 uint32_t size = 0;
3928
3929 size = (uint32_t)strlen(optval->custom_stringval.string) & 0xffff;
3930
3931 return size;
3932}
3933
3934static uint32_t pcapng_compute_custom_binary_option_size(wtap_optval_t *optval)
3935{
3936 size_t size;
3937
3938 /* PEN */
3939 size = sizeof(uint32_t) + optval->custom_binaryval.data.custom_data_len;
3940
3941 if (size > 65535) {
3942 size = 65535;
3943 }
3944
3945 return (uint32_t)size;
3946}
3947
3948static uint32_t pcapng_compute_packet_hash_option_size(wtap_optval_t *optval)
3949{
3950 packet_hash_opt_t* hash = &optval->packet_hash;
3951 uint32_t size;
3952
3953 switch (hash->type) {
3954 case OPT_HASH_CRC322:
3955 size = 4;
3956 break;
3957 case OPT_HASH_MD53:
3958 size = 16;
3959 break;
3960 case OPT_HASH_SHA14:
3961 size = 20;
3962 break;
3963 case OPT_HASH_TOEPLITZ5:
3964 size = 4;
3965 break;
3966 default:
3967 /* 2COMP and XOR size not defined in standard (yet) */
3968 size = hash->hash_bytes->len;
3969 break;
3970 }
3971 /* XXX - What if the size of the hash bytes doesn't match the
3972 * expected size? We can:
3973 * 1) Return 0, and omit it when writing
3974 * 2) Return hash_bytes->len, and write it out exactly as we have it
3975 * 3) Return the correct size here, and when writing err or possibly
3976 * truncate.
3977 */
3978 /* Account for the size of the algorithm type field. */
3979 size += 1;
3980
3981 return size;
3982}
3983
3984static uint32_t pcapng_compute_packet_verdict_option_size(wtap_optval_t *optval)
3985{
3986 packet_verdict_opt_t* verdict = &optval->packet_verdictval;
3987 uint32_t size;
3988
3989 switch (verdict->type) {
3990
3991 case packet_verdict_hardware:
3992 size = verdict->data.verdict_bytes->len;
3993 break;
3994
3995 case packet_verdict_linux_ebpf_tc:
3996 size = 8;
3997 break;
3998
3999 case packet_verdict_linux_ebpf_xdp:
4000 size = 8;
4001 break;
4002
4003 default:
4004 size = 0;
4005 break;
4006 }
4007 /* Account for the type octet */
4008 if (size) {
4009 size += 1;
4010 }
4011
4012 return size;
4013}
4014
4015static bool_Bool
4016compute_block_option_size(wtap_block_t block _U___attribute__((unused)), unsigned option_id, wtap_opttype_e option_type, wtap_optval_t *optval, void *user_data)
4017{
4018 compute_options_size_t* options_size = (compute_options_size_t*)user_data;
4019 uint32_t size = 0;
4020
4021 /*
4022 * Process the option IDs that are the same for all block types here;
4023 * call the block-type-specific compute_size function for others.
4024 */
4025 switch(option_id)
4026 {
4027 case OPT_COMMENT1:
4028 size = pcapng_compute_string_option_size(optval);
4029 break;
4030 case OPT_CUSTOM_STR_COPY2988:
4031 size = pcapng_compute_custom_string_option_size(optval);
4032 break;
4033 case OPT_CUSTOM_BIN_COPY2989:
4034 size = pcapng_compute_custom_binary_option_size(optval);
4035 break;
4036 case OPT_CUSTOM_STR_NO_COPY19372:
4037 case OPT_CUSTOM_BIN_NO_COPY19373:
4038 /*
4039 * Do not count these, as they're not supposed to be copied to
4040 * new files.
4041 *
4042 * XXX - what if we're writing out a file that's *not* based on
4043 * another file, so that we're *not* copying it from that file?
4044 */
4045 break;
4046 default:
4047 /* Block-type dependent; call the callback. */
4048 if (options_size->compute_option_size) {
4049 size = (*options_size->compute_option_size)(block, option_id, option_type, optval);
4050 }
4051 break;
4052 }
4053
4054 /*
4055 * Are we writing this option?
4056 */
4057 /*
4058 * XXX: The option length field is 16 bits. If size > 65535 (how?
4059 * was the block was obtained from some format other than pcapng?),
4060 * are we going to silently omit the option (in which case we shouldn't
4061 * add the size here), or err out when writing it (in which case
4062 * it's probably fine to add the size or not?) Adding it here and
4063 * then omitting it when writing, as some of the routines do, means
4064 * creating a corrupt file.
4065 */
4066 if (size != 0) {
4067 /*
4068 * Yes. The length of this option is 4 bytes for the option
4069 * header, plus the size of the option data, rounded up
4070 * to a multiple of 4 bytes (32 bits).
4071 */
4072 options_size->size += WS_ROUNDUP_4(4 + size)(((4 + size) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U
))))
;
4073 }
4074 return true1; /* we always succeed */
4075}
4076
4077uint32_t
4078pcapng_compute_options_size(wtap_block_t block, compute_option_size_func compute_option_size)
4079{
4080 compute_options_size_t compute_options_size;
4081
4082 /*
4083 * Compute the total size of all the options in the block.
4084 * This always succeeds, so we don't check the return value.
4085 */
4086 compute_options_size.size = 0;
4087 compute_options_size.compute_option_size = compute_option_size;
4088 wtap_block_foreach_option(block, compute_block_option_size, &compute_options_size);
4089
4090 /* Are we writing any options? */
4091 if (compute_options_size.size != 0) {
4092 /* Yes, add the size of the End-of-options tag. */
4093 compute_options_size.size += 4;
4094 }
4095 return compute_options_size.size;
4096}
4097
4098static uint32_t compute_shb_option_size(wtap_block_t block _U___attribute__((unused)), unsigned option_id, wtap_opttype_e option_type _U___attribute__((unused)), wtap_optval_t* optval)
4099{
4100 uint32_t size;
4101
4102 switch(option_id)
4103 {
4104 case OPT_SHB_HARDWARE2:
4105 case OPT_SHB_OS3:
4106 case OPT_SHB_USERAPPL4:
4107 size = pcapng_compute_string_option_size(optval);
4108 break;
4109 default:
4110 /* Unknown options - size by datatype? */
4111 size = 0;
4112 break;
4113 }
4114 return size;
4115}
4116
4117typedef struct write_options_t
4118{
4119 wtap_dumper *wdh;
4120 pcapng_opt_byte_order_e byte_order;
4121 write_option_func write_option;
4122 int *err;
4123 char **err_info;
4124}
4125write_options_t;
4126
4127static bool_Bool pcapng_write_option_eofopt(wtap_dumper *wdh, int *err)
4128{
4129 struct pcapng_option_header option_hdr;
4130
4131 /*
4132 * Write end of options.
4133 *
4134 * OPT_EOFOPT is zero, so we don't need to know the byte order to
4135 * be used, as both fields in the option header are zero and thus
4136 * unchanged if byte-swapped.
4137 */
4138 option_hdr.type = OPT_EOFOPT0;
4139 option_hdr.value_length = 0;
4140 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4141 return false0;
4142 return true1;
4143}
4144
4145static bool_Bool pcapng_write_uint8_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4146{
4147 struct pcapng_option_header option_hdr;
4148
4149 option_hdr.type = (uint16_t)option_id;
4150 option_hdr.value_length = (uint16_t)1;
4151 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4152 return false0;
4153
4154 if (!wtap_dump_file_write(wdh, &optval->uint8val, 1, err))
4155 return false0;
4156
4157 if (!pcapng_write_padding(wdh, 3, err))
4158 return false0;
4159
4160 return true1;
4161}
4162
4163static bool_Bool pcapng_write_uint32_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4164{
4165 struct pcapng_option_header option_hdr;
4166
4167 option_hdr.type = (uint16_t)option_id;
4168 option_hdr.value_length = (uint16_t)4;
4169 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4170 return false0;
4171
4172 if (!wtap_dump_file_write(wdh, &optval->uint32val, 4, err))
4173 return false0;
4174
4175 return true1;
4176}
4177
4178static bool_Bool pcapng_write_uint64_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4179{
4180 struct pcapng_option_header option_hdr;
4181
4182 option_hdr.type = (uint16_t)option_id;
4183 option_hdr.value_length = (uint16_t)8;
4184 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4185 return false0;
4186
4187 if (!wtap_dump_file_write(wdh, &optval->uint64val, 8, err))
4188 return false0;
4189
4190 return true1;
4191}
4192
4193static bool_Bool pcapng_write_timestamp_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4194{
4195 struct pcapng_option_header option_hdr;
4196 uint32_t high, low;
4197
4198 option_hdr.type = (uint16_t)option_id;
4199 option_hdr.value_length = (uint16_t)8;
4200 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4201 return false0;
4202
4203 high = (uint32_t)(optval->uint64val >> 32);
4204 low = (uint32_t)(optval->uint64val >> 0);
4205 if (!wtap_dump_file_write(wdh, &high, 4, err))
4206 return false0;
4207 if (!wtap_dump_file_write(wdh, &low, 4, err))
4208 return false0;
4209
4210 return true1;
4211}
4212
4213static bool_Bool pcapng_write_string_option(wtap_dumper *wdh,
4214 pcapng_opt_byte_order_e byte_order,
4215 unsigned option_id,
4216 wtap_optval_t *optval,
4217 int *err, char **err_info)
4218{
4219 struct pcapng_option_header option_hdr;
4220 size_t size = strlen(optval->stringval);
4221
4222 if (size == 0)
4223 return true1;
4224 if (size > 65535) {
4225 /*
4226 * Too big to fit in the option.
4227 * Don't write anything.
4228 *
4229 * XXX - truncate it? Report an error?
4230 */
4231 return true1;
4232 }
4233
4234 /* write option header */
4235 /* String options don't consider pad bytes part of the length */
4236 option_hdr.type = (uint16_t)option_id;
4237 option_hdr.value_length = (uint16_t)size;
4238 switch (byte_order) {
4239
4240 case OPT_SECTION_BYTE_ORDER:
4241 /* This is host byte order when writing, so nothing to do. */
4242 break;
4243
4244 case OPT_BIG_ENDIAN:
4245 option_hdr.type = GUINT16_TO_BE(option_hdr.type)((((guint16) ( (guint16) ((guint16) (option_hdr.type) >>
8) | (guint16) ((guint16) (option_hdr.type) << 8)))))
;
4246 option_hdr.value_length = GUINT16_TO_BE(option_hdr.value_length)((((guint16) ( (guint16) ((guint16) (option_hdr.value_length)
>> 8) | (guint16) ((guint16) (option_hdr.value_length)
<< 8)))))
;
4247 break;
4248
4249 case OPT_LITTLE_ENDIAN:
4250 option_hdr.type = GUINT16_TO_LE(option_hdr.type)((guint16) (option_hdr.type));
4251 option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length)((guint16) (option_hdr.value_length));
4252 break;
4253
4254 default:
4255 /*
4256 * This indicates somebody passed an invalid option to
4257 * pcapng_write_options().
4258 *
4259 * Report this as an internal error.
4260 */
4261 *err = WTAP_ERR_INTERNAL-21;
4262 *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_write_options()",wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
4263 byte_order)wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
;
4264 return true1;
4265 }
4266 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4267 return false0;
4268
4269 if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4270 return false0;
4271
4272 /* write padding (if any) */
4273 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4274}
4275
4276#if 0
4277static bool_Bool pcapng_write_bytes_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4278{
4279 struct pcapng_option_header option_hdr;
4280 size_t size = g_bytes_get_size(optval->byteval);
4281
4282 if (size == 0)
4283 return true1;
4284 if (size > 65535) {
4285 /*
4286 * Too big to fit in the option.
4287 * Don't write anything.
4288 *
4289 * XXX - truncate it? Report an error?
4290 */
4291 return true1;
4292 }
4293
4294 /* Bytes options don't consider pad bytes part of the length */
4295 option_hdr.type = (uint16_t)option_id;
4296 option_hdr.value_length = (uint16_t)size;
4297 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4298 return false0;
4299
4300 if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4301 return false0;
4302
4303 /* write padding (if any) */
4304 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4305}
4306
4307static bool_Bool pcapng_write_ipv4_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4308{
4309 struct pcapng_option_header option_hdr;
4310
4311 option_hdr.type = (uint16_t)option_id;
4312 option_hdr.value_length = (uint16_t)4;
4313 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4314 return false0;
4315
4316 if (!wtap_dump_file_write(wdh, &optval->ipv4val, 1, err))
4317 return false0;
4318
4319 return true1;
4320}
4321
4322static bool_Bool pcapng_write_ipv6_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4323{
4324 struct pcapng_option_header option_hdr;
4325
4326 option_hdr.type = (uint16_t)option_id;
4327 option_hdr.value_length = (uint16_t)IPv6_ADDR_SIZE;
4328 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4329 return false0;
4330
4331 if (!wtap_dump_file_write(wdh, &optval->ipv6val.bytes, IPv6_ADDR_SIZE, err))
4332 return false0;
4333
4334 return true1;
4335}
4336#endif
4337
4338static bool_Bool pcapng_write_if_filter_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4339{
4340 if_filter_opt_t* filter = &optval->if_filterval;
4341 uint32_t size;
4342 uint8_t filter_type;
4343 size_t filter_data_len;
4344 struct pcapng_option_header option_hdr;
4345
4346 switch (filter->type) {
4347
4348 case if_filter_pcap:
4349 filter_type = 0; /* pcap filter string */
4350 filter_data_len = strlen(filter->data.filter_str);
4351 if (filter_data_len > 65534) {
4352 /*
4353 * Too big to fit in the option.
4354 * Don't write anything.
4355 *
4356 * XXX - truncate it? Report an error?
4357 */
4358 return true1;
4359 }
4360 break;
4361
4362 case if_filter_bpf:
4363 filter_type = 1; /* BPF filter program */
4364 filter_data_len = filter->data.bpf_prog.bpf_prog_len*8;
4365 if (filter_data_len > 65528) {
4366 /*
4367 * Too big to fit in the option. (The filter length
4368 * must be a multiple of 8, as that's the length
4369 * of a BPF instruction.) Don't write anything.
4370 *
4371 * XXX - truncate it? Report an error?
4372 */
4373 return true1;
4374 }
4375 break;
4376
4377 default:
4378 /* Unknown filter type; don't write anything. */
4379 return true1;
4380 }
4381 size = (uint32_t)(filter_data_len + 1);
4382
4383 option_hdr.type = option_id;
4384 option_hdr.value_length = size;
4385 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4386 return false0;
4387
4388 /* Write the filter type */
4389 if (!wtap_dump_file_write(wdh, &filter_type, 1, err))
4390 return false0;
4391
4392 switch (filter->type) {
4393
4394 case if_filter_pcap:
4395 /* Write the filter string */
4396 if (!wtap_dump_file_write(wdh, filter->data.filter_str, filter_data_len, err))
4397 return false0;
4398 break;
4399
4400 case if_filter_bpf:
4401 if (!wtap_dump_file_write(wdh, filter->data.bpf_prog.bpf_prog, filter_data_len, err))
4402 return false0;
4403 break;
4404
4405 default:
4406 ws_assert_not_reached()ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/pcapng.c"
, 4406, __func__, "assertion \"not reached\" failed")
;
4407 return true1;
4408 }
4409
4410 /* write padding (if any) */
4411 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4412}
4413
4414static bool_Bool pcapng_write_custom_string_option(wtap_dumper *wdh,
4415 pcapng_opt_byte_order_e byte_order,
4416 unsigned option_id,
4417 wtap_optval_t *optval,
4418 int *err, char **err_info)
4419{
4420 struct pcapng_option_header option_hdr;
4421 size_t stringlen;
4422 size_t size;
4423 uint32_t pen;
4424
4425 if (option_id == OPT_CUSTOM_STR_NO_COPY19372)
4426 return true1;
4427 ws_debug("PEN %u", optval->custom_stringval.pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 4427, __func__, "PEN %u", optval->custom_stringval.pen);
} } while (0)
;
4428 stringlen = strlen(optval->custom_stringval.string);
4429 size = sizeof(uint32_t) + stringlen;
4430 if (size > 65535) {
4431 /*
4432 * Too big to fit in the option.
4433 * Don't write anything.
4434 *
4435 * XXX - truncate it? Report an error?
4436 */
4437 return true1;
4438 }
4439
4440 /* write option header and PEN */
4441 /* String options don't consider pad bytes part of the length */
4442 option_hdr.type = (uint16_t)option_id;
4443 option_hdr.value_length = (uint16_t)size;
4444 pen = optval->custom_stringval.pen;
4445 switch (byte_order) {
4446
4447 case OPT_SECTION_BYTE_ORDER:
4448 /* This is host byte order when writing, so nothing to do. */
4449 break;
4450
4451 case OPT_BIG_ENDIAN:
4452 option_hdr.type = GUINT16_TO_BE(option_hdr.type)((((guint16) ( (guint16) ((guint16) (option_hdr.type) >>
8) | (guint16) ((guint16) (option_hdr.type) << 8)))))
;
4453 option_hdr.value_length = GUINT16_TO_BE(option_hdr.value_length)((((guint16) ( (guint16) ((guint16) (option_hdr.value_length)
>> 8) | (guint16) ((guint16) (option_hdr.value_length)
<< 8)))))
;
4454 pen = GUINT32_TO_BE(pen)((((guint32) ( (((guint32) (pen) & (guint32) 0x000000ffU)
<< 24) | (((guint32) (pen) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (pen) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (pen) & (guint32) 0xff000000U
) >> 24)))))
;
4455 break;
4456
4457 case OPT_LITTLE_ENDIAN:
4458 option_hdr.type = GUINT16_TO_LE(option_hdr.type)((guint16) (option_hdr.type));
4459 option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length)((guint16) (option_hdr.value_length));
4460 pen = GUINT32_TO_LE(pen)((guint32) (pen));
4461 break;
4462
4463 default:
4464 /*
4465 * This indicates somebody passed an invalid option to
4466 * pcapng_write_options().
4467 *
4468 * Report this as an internal error.
4469 */
4470 *err = WTAP_ERR_INTERNAL-21;
4471 *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_write_options()",wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
4472 byte_order)wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
;
4473 return true1;
4474 }
4475 if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
4476 return false0;
4477 if (!wtap_dump_file_write(wdh, &pen, sizeof(uint32_t), err))
4478 return false0;
4479
4480 /* write custom data */
4481 if (!wtap_dump_file_write(wdh, optval->custom_stringval.string, stringlen, err)) {
4482 return false0;
4483 }
4484 ws_debug("Wrote custom option: type %u, length %u", option_hdr.type, option_hdr.value_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 4484, __func__, "Wrote custom option: type %u, length %u", option_hdr
.type, option_hdr.value_length); } } while (0)
;
4485
4486 /* write padding (if any) */
4487 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4488}
4489
4490static bool_Bool pcapng_write_custom_binary_option(wtap_dumper *wdh,
4491 pcapng_opt_byte_order_e byte_order,
4492 unsigned option_id,
4493 wtap_optval_t *optval,
4494 int *err, char **err_info)
4495{
4496 struct pcapng_option_header option_hdr;
4497 size_t size;
4498 uint32_t pen;
4499
4500 if (option_id == OPT_CUSTOM_BIN_NO_COPY19373)
4501 return true1;
4502 ws_debug("PEN %u", optval->custom_binaryval.pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 4502, __func__, "PEN %u", optval->custom_binaryval.pen);
} } while (0)
;
4503 size = sizeof(uint32_t) + optval->custom_binaryval.data.custom_data_len;
4504 if (size > 65535) {
4505 /*
4506 * Too big to fit in the option.
4507 * Don't write anything.
4508 *
4509 * XXX - truncate it? Report an error?
4510 */
4511 return true1;
4512 }
4513
4514 /* write option header and PEN */
4515 option_hdr.type = (uint16_t)option_id;
4516 option_hdr.value_length = (uint16_t)size;
4517 pen = optval->custom_binaryval.pen;
4518 switch (byte_order) {
4519
4520 case OPT_SECTION_BYTE_ORDER:
4521 /* This is host byte order when writing, so nothing to do. */
4522 break;
4523
4524 case OPT_BIG_ENDIAN:
4525 option_hdr.type = GUINT16_TO_BE(option_hdr.type)((((guint16) ( (guint16) ((guint16) (option_hdr.type) >>
8) | (guint16) ((guint16) (option_hdr.type) << 8)))))
;
4526 option_hdr.value_length = GUINT16_TO_BE(option_hdr.value_length)((((guint16) ( (guint16) ((guint16) (option_hdr.value_length)
>> 8) | (guint16) ((guint16) (option_hdr.value_length)
<< 8)))))
;
4527 pen = GUINT32_TO_BE(pen)((((guint32) ( (((guint32) (pen) & (guint32) 0x000000ffU)
<< 24) | (((guint32) (pen) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (pen) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (pen) & (guint32) 0xff000000U
) >> 24)))))
;
4528 break;
4529
4530 case OPT_LITTLE_ENDIAN:
4531 option_hdr.type = GUINT16_TO_LE(option_hdr.type)((guint16) (option_hdr.type));
4532 option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length)((guint16) (option_hdr.value_length));
4533 pen = GUINT32_TO_LE(pen)((guint32) (pen));
4534 break;
4535
4536 default:
4537 /*
4538 * This indicates somebody passed an invalid option to
4539 * pcapng_write_options().
4540 *
4541 * Report this as an internal error.
4542 */
4543 *err = WTAP_ERR_INTERNAL-21;
4544 *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_write_options()",wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
4545 byte_order)wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
;
4546 return true1;
4547 }
4548 if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
4549 return false0;
4550 if (!wtap_dump_file_write(wdh, &pen, sizeof(uint32_t), err))
4551 return false0;
4552
4553 /* write custom data */
4554 if (!wtap_dump_file_write(wdh, optval->custom_binaryval.data.custom_data, optval->custom_binaryval.data.custom_data_len, err)) {
4555 return false0;
4556 }
4557 ws_debug("Wrote custom option: type %u, length %u", option_hdr.type, option_hdr.value_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 4557, __func__, "Wrote custom option: type %u, length %u", option_hdr
.type, option_hdr.value_length); } } while (0)
;
4558
4559 /* write padding (if any) */
4560 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4561}
4562
4563static bool_Bool pcapng_write_packet_verdict_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4564{
4565 packet_verdict_opt_t* verdict = &optval->packet_verdictval;
4566 struct pcapng_option_header option_hdr;
4567 uint8_t type;
4568 size_t size;
4569
4570 size = pcapng_compute_packet_verdict_option_size(optval);
4571
4572 switch (verdict->type) {
4573
4574 case packet_verdict_hardware:
4575 if (size > 65535) {
4576 /*
4577 * Too big to fit in the option.
4578 * Don't write anything.
4579 *
4580 * XXX - truncate it? Report an error?
4581 */
4582 return true1;
4583 }
4584 option_hdr.type = option_id;
4585 option_hdr.value_length = (uint16_t)size;
4586 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4587 return false0;
4588
4589 type = packet_verdict_hardware;
4590 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4591 return false0;
4592
4593 if (!wtap_dump_file_write(wdh, verdict->data.verdict_bytes->data,
4594 verdict->data.verdict_bytes->len, err))
4595 return false0;
4596 break;
4597
4598 case packet_verdict_linux_ebpf_tc:
4599 option_hdr.type = option_id;
4600 option_hdr.value_length = (uint16_t)size;
4601 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4602 return false0;
4603
4604 type = packet_verdict_linux_ebpf_tc;
4605 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4606 return false0;
4607
4608 if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_tc,
4609 sizeof(uint64_t), err))
4610 return false0;
4611 break;
4612
4613 case packet_verdict_linux_ebpf_xdp:
4614 option_hdr.type = option_id;
4615 option_hdr.value_length = (uint16_t)size;
4616 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4617 return false0;
4618
4619 type = packet_verdict_linux_ebpf_xdp;
4620 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4621 return false0;
4622
4623 if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_xdp,
4624 sizeof(uint64_t), err))
4625 return false0;
4626 break;
4627
4628 default:
4629 /* Unknown - don't write it out. */
4630 return true1;
4631 }
4632
4633 /* write padding (if any) */
4634 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4635}
4636
4637static bool_Bool pcapng_write_packet_hash_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4638{
4639 packet_hash_opt_t* hash = &optval->packet_hash;
4640 struct pcapng_option_header option_hdr;
4641 uint8_t type;
4642 size_t size;
4643
4644 size = pcapng_compute_packet_hash_option_size(optval);
4645
4646 if (size > 65535) {
4647 /*
4648 * Too big to fit in the option.
4649 * Don't write anything.
4650 *
4651 * XXX - truncate it? Report an error?
4652 */
4653 return true1;
4654 }
4655
4656 if (size > hash->hash_bytes->len + 1) {
4657 /*
4658 * We don't have enough bytes to write.
4659 * pcapng_compute_packet_hash_option_size() should return 0 if
4660 * we want to silently omit the option instead, or should return
4661 * the length if we want to blindly copy it.
4662 * XXX - Is this the best error type?
4663 */
4664 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4665 return false0;
4666 }
4667
4668 type = hash->type;
4669
4670 option_hdr.type = option_id;
4671 /* Include type byte */
4672 option_hdr.value_length = (uint16_t)size;
4673 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4674 return false0;
4675
4676 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4677 return false0;
4678
4679 if (!wtap_dump_file_write(wdh, hash->hash_bytes->data, size - 1,
4680 err))
4681 return false0;
4682
4683 /* write padding (if any) */
4684 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4685}
4686
4687static bool_Bool write_block_option(wtap_block_t block,
4688 unsigned option_id,
4689 wtap_opttype_e option_type _U___attribute__((unused)),
4690 wtap_optval_t *optval, void* user_data)
4691{
4692 write_options_t* options = (write_options_t*)user_data;
4693
4694 /*
4695 * Process the option IDs that are the same for all block types here;
4696 * call the block-type-specific write function for others.
4697 */
4698 switch(option_id)
4699 {
4700 case OPT_COMMENT1:
4701 if (!pcapng_write_string_option(options->wdh, options->byte_order,
4702 option_id, optval,
4703 options->err, options->err_info))
4704 return false0;
4705 break;
4706 case OPT_CUSTOM_STR_COPY2988:
4707 if (!pcapng_write_custom_string_option(options->wdh,
4708 options->byte_order,
4709 option_id, optval,
4710 options->err, options->err_info))
4711 return false0;
4712 break;
4713 case OPT_CUSTOM_BIN_COPY2989:
4714 if (!pcapng_write_custom_binary_option(options->wdh,
4715 options->byte_order,
4716 option_id, optval,
4717 options->err,
4718 options->err_info))
4719 return false0;
4720 break;
4721 case OPT_CUSTOM_STR_NO_COPY19372:
4722 case OPT_CUSTOM_BIN_NO_COPY19373:
4723 /*
4724 * Do not write these, as they're not supposed to be copied to
4725 * new files.
4726 *
4727 * XXX - what if we're writing out a file that's *not* based on
4728 * another file, so that we're *not* copying it from that file?
4729 */
4730 break;
4731 default:
4732 /* Block-type dependent; call the callback, if we have one. */
4733 if (options->write_option != NULL((void*)0) &&
4734 !(*options->write_option)(options->wdh, block, option_id,
4735 option_type, optval,
4736 options->err, options->err_info))
4737 return false0;
4738 break;
4739 }
4740 return true1;
4741}
4742
4743bool_Bool
4744pcapng_write_options(wtap_dumper *wdh, pcapng_opt_byte_order_e byte_order,
4745 wtap_block_t block, write_option_func write_option,
4746 int *err, char **err_info)
4747{
4748 write_options_t options;
4749
4750 options.wdh = wdh;
4751 options.byte_order = byte_order;
4752 options.write_option = write_option;
4753 options.err = err;
4754 options.err_info = err_info;
4755 if (!wtap_block_foreach_option(block, write_block_option, &options))
4756 return false0;
4757
4758 /* Write end of options */
4759 return pcapng_write_option_eofopt(wdh, err);
4760}
4761
4762static bool_Bool write_wtap_shb_option(wtap_dumper *wdh, wtap_block_t block _U___attribute__((unused)),
4763 unsigned option_id,
4764 wtap_opttype_e option_type _U___attribute__((unused)),
4765 wtap_optval_t *optval,
4766 int *err, char **err_info)
4767{
4768 switch(option_id)
4769 {
4770 case OPT_SHB_HARDWARE2:
4771 case OPT_SHB_OS3:
4772 case OPT_SHB_USERAPPL4:
4773 if (!pcapng_write_string_option(wdh, OPT_SECTION_BYTE_ORDER,
4774 option_id, optval, err, err_info))
4775 return false0;
4776 break;
4777 default:
4778 /* Unknown options - write by datatype? */
4779 break;
4780 }
4781 return true1; /* success */
4782}
4783
4784/* Write a section header block.
4785 * If we don't have a section block header already, create a default
4786 * one with no options.
4787 */
4788static bool_Bool
4789pcapng_write_section_header_block(wtap_dumper *wdh, int *err, char **err_info)
4790{
4791 uint32_t block_content_length;
4792 pcapng_section_header_block_t shb;
4793 uint32_t options_size;
4794 wtap_block_t wdh_shb = NULL((void*)0);
4795
4796 if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
4797 wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (wdh->shb_hdrs)->data) [(0)]
)
;
4798 }
4799
4800 block_content_length = (uint32_t)sizeof(shb);
4801 options_size = 0;
4802 if (wdh_shb) {
4803 ws_debug("Have shb_hdr")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 4803, __func__, "Have shb_hdr"); } } while (0)
;
4804
4805 /* Compute size of all the options */
4806 options_size = pcapng_compute_options_size(wdh_shb, compute_shb_option_size);
4807
4808 block_content_length += options_size;
4809 }
4810
4811 /* write block header */
4812 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SHB0x0A0D0D0A, block_content_length,
4813 err))
4814 return false0;
4815
4816 /* write block fixed content */
4817 shb.magic = 0x1A2B3C4D;
4818 shb.version_major = 1;
4819 shb.version_minor = 0;
4820 if (wdh_shb) {
4821 wtapng_section_mandatory_t* section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wdh_shb);
4822 shb.section_length = section_data->section_length;
4823 } else {
4824 shb.section_length = -1;
4825 }
4826
4827 if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
4828 return false0;
4829
4830 if (wdh_shb) {
4831 /* Write options, if we have any */
4832 if (options_size != 0) {
4833 if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
4834 wdh_shb, write_wtap_shb_option,
4835 err, err_info))
4836 return false0;
4837 }
4838 }
4839
4840 /* write block footer */
4841 return pcapng_write_block_footer(wdh, block_content_length, err);
4842}
4843
4844/* options defined in Section 2.5 (Options)
4845 * Name Code Length Description
4846 * opt_comment 1 variable A UTF-8 string containing a comment that is associated to the current block.
4847 *
4848 * Enhanced Packet Block options
4849 * epb_flags 2 4 A flags word containing link-layer information. A complete specification of
4850 * the allowed flags can be found in Appendix A (Packet Block Flags Word).
4851 * epb_hash 3 variable This option contains a hash of the packet. The first byte specifies the hashing algorithm,
4852 * while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
4853 * and hence from the value in the first bit. The hashing algorithm can be: 2s complement
4854 * (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
4855 * MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
4856 * The hash covers only the packet, not the header added by the capture driver:
4857 * this gives the possibility to calculate it inside the network card.
4858 * The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
4859 * data acquisition system and the capture library.
4860 * epb_dropcount 4 8 A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
4861 * between this packet and the preceding one.
4862 * epb_packetid 5 8 The epb_packetid option is a 64-bit unsigned integer that
4863 * uniquely identifies the packet. If the same packet is seen
4864 * by multiple interfaces and there is a way for the capture
4865 * application to correlate them, the same epb_packetid value
4866 * must be used. An example could be a router that captures
4867 * packets on all its interfaces in both directions. When a
4868 * packet hits interface A on ingress, an EPB entry gets
4869 * created, TTL gets decremented, and right before it egresses
4870 * on interface B another EPB entry gets created in the trace
4871 * file. In this case, two packets are in the capture file,
4872 * which are not identical but the epb_packetid can be used to
4873 * correlate them.
4874 * epb_queue 6 4 The epb_queue option is a 32-bit unsigned integer that
4875 * identifies on which queue of the interface the specific
4876 * packet was received.
4877 * epb_verdict 7 variable The epb_verdict option stores a verdict of the packet. The
4878 * verdict indicates what would be done with the packet after
4879 * processing it. For example, a firewall could drop the
4880 * packet. This verdict can be set by various components, i.e.
4881 * Hardware, Linux's eBPF TC or XDP framework, etc. etc. The
4882 * first octet specifies the verdict type, while the following
4883 * octets contain the actual verdict data, whose size depends on
4884 * the verdict type, and hence from the value in the first
4885 * octet. The verdict type can be: Hardware (type octet = 0,
4886 * size = variable), Linux_eBPF_TC (type octet = 1, size = 8
4887 * (64-bit unsigned integer), value = TC_ACT_* as defined in the
4888 * Linux pck_cls.h include), Linux_eBPF_XDP (type octet = 2,
4889 * size = 8 (64-bit unsigned integer), value = xdp_action as
4890 * defined in the Linux pbf.h include).
4891 * opt_endofopt 0 0 It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
4892 */
4893static uint32_t
4894compute_epb_option_size(wtap_block_t block _U___attribute__((unused)), unsigned option_id, wtap_opttype_e option_type _U___attribute__((unused)), wtap_optval_t* optval)
4895{
4896 uint32_t size;
4897
4898 switch(option_id)
4899 {
4900 case OPT_PKT_FLAGS2:
4901 size = 4;
4902 break;
4903 case OPT_PKT_HASH3:
4904 size = pcapng_compute_packet_hash_option_size(optval);
4905 break;
4906 case OPT_PKT_DROPCOUNT4:
4907 size = 8;
4908 break;
4909 case OPT_PKT_PACKETID5:
4910 size = 8;
4911 break;
4912 case OPT_PKT_QUEUE6:
4913 size = 4;
4914 break;
4915 case OPT_PKT_VERDICT7:
4916 size = pcapng_compute_packet_verdict_option_size(optval);
4917 break;
4918 case OPT_PKT_PROCIDTHRDID8:
4919 size = 8;
4920 break;
4921 default:
4922 /* Unknown options - size by datatype? */
4923 size = 0;
4924 break;
4925 }
4926 return size;
4927}
4928
4929static bool_Bool write_wtap_epb_option(wtap_dumper *wdh, wtap_block_t block _U___attribute__((unused)),
4930 unsigned option_id,
4931 wtap_opttype_e option_type _U___attribute__((unused)),
4932 wtap_optval_t *optval,
4933 int *err, char **err_info _U___attribute__((unused)))
4934{
4935 switch(option_id)
4936 {
4937 case OPT_PKT_FLAGS2:
4938 if (!pcapng_write_uint32_option(wdh, OPT_PKT_FLAGS2, optval, err))
4939 return false0;
4940 break;
4941 case OPT_PKT_HASH3:
4942 if (!pcapng_write_packet_hash_option(wdh, OPT_PKT_HASH3, optval, err))
4943 return false0;
4944 break;
4945 case OPT_PKT_DROPCOUNT4:
4946 if (!pcapng_write_uint64_option(wdh, OPT_PKT_DROPCOUNT4, optval, err))
4947 return false0;
4948 break;
4949 case OPT_PKT_PACKETID5:
4950 if (!pcapng_write_uint64_option(wdh, OPT_PKT_PACKETID5, optval, err))
4951 return false0;
4952 break;
4953 case OPT_PKT_QUEUE6:
4954 if (!pcapng_write_uint32_option(wdh, OPT_PKT_QUEUE6, optval, err))
4955 return false0;
4956 break;
4957 case OPT_PKT_VERDICT7:
4958 if (!pcapng_write_packet_verdict_option(wdh, OPT_PKT_VERDICT7, optval, err))
4959 return false0;
4960 break;
4961 case OPT_PKT_PROCIDTHRDID8:
4962 if (!pcapng_write_uint64_option(wdh, OPT_PKT_PROCIDTHRDID8, optval, err))
4963 return false0;
4964 break;
4965 default:
4966 /* Unknown options - write by datatype? */
4967 break;
4968 }
4969 return true1; /* success */
4970}
4971
4972static bool_Bool
4973pcapng_write_simple_packet_block(wtap_dumper* wdh, const wtap_rec* rec,
4974 int* err, char** err_info _U___attribute__((unused)))
4975{
4976 const union wtap_pseudo_header* pseudo_header = &rec->rec_header.packet_header.pseudo_header;
4977 uint32_t block_content_length;
4978 pcapng_simple_packet_block_t spb;
4979 uint32_t pad_len;
4980 uint32_t phdr_len;
4981
4982 /* Don't write anything we're not willing to read. */
4983 if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->file_encap)) {
4984 *err = WTAP_ERR_PACKET_TOO_LARGE-22;
4985 return false0;
4986 }
4987
4988 phdr_len = pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
4989 pad_len = WS_PADDING_TO_4(phdr_len + rec->rec_header.packet_header.caplen)((4U - ((phdr_len + rec->rec_header.packet_header.caplen) %
4U)) % 4U)
;
4990
4991 /* write (simple) packet block header */
4992 block_content_length = (uint32_t)sizeof(spb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len;
4993 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SPB0x00000003, block_content_length,
4994 err))
4995 return false0;
4996
4997 /* write block fixed content */
4998 spb.packet_len = rec->rec_header.packet_header.len + phdr_len;
4999
5000 if (!wtap_dump_file_write(wdh, &spb, sizeof spb, err))
5001 return false0;
5002
5003 /* write pseudo header */
5004 if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
5005 return false0;
5006 }
5007
5008 /* write packet data */
5009 if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.packet_header.caplen, err))
5010 return false0;
5011
5012 /* write padding (if any) */
5013 if (!pcapng_write_padding(wdh, pad_len, err))
5014 return false0;
5015
5016 /* write block footer */
5017 return pcapng_write_block_footer(wdh, block_content_length, err);
5018}
5019
5020static bool_Bool
5021pcapng_write_enhanced_packet_block(wtap_dumper *wdh, const wtap_rec *rec,
5022 int *err, char **err_info)
5023{
5024 const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
5025 uint32_t block_content_length;
5026 pcapng_enhanced_packet_block_t epb;
5027 uint32_t options_size = 0;
5028 uint64_t ts;
5029 uint32_t pad_len;
5030 uint32_t phdr_len;
5031 wtap_block_t int_data;
5032 wtapng_if_descr_mandatory_t *int_data_mand;
5033
5034 /* Don't write anything we're not willing to read. */
5035 if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->file_encap)) {
5036 *err = WTAP_ERR_PACKET_TOO_LARGE-22;
5037 return false0;
5038 }
5039
5040 phdr_len = pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
5041 pad_len = WS_PADDING_TO_4(phdr_len + rec->rec_header.packet_header.caplen)((4U - ((phdr_len + rec->rec_header.packet_header.caplen) %
4U)) % 4U)
;
5042
5043 if (rec->block != NULL((void*)0)) {
5044 /* Compute size of all the options */
5045 options_size = pcapng_compute_options_size(rec->block, compute_epb_option_size);
5046 }
5047
5048 /*
5049 * Check the interface ID. Do this before writing the header,
5050 * in case we need to add a new IDB.
5051 */
5052 if (rec->presence_flags & WTAP_HAS_INTERFACE_ID0x00000004) {
5053 epb.interface_id = rec->rec_header.packet_header.interface_id;
5054 if (rec->presence_flags & WTAP_HAS_SECTION_NUMBER0x00000008 && wdh->shb_iface_to_global) {
5055 /*
5056 * In the extremely unlikely event this overflows we give the
5057 * wrong interface ID.
5058 */
5059 epb.interface_id += g_array_index(wdh->shb_iface_to_global, unsigned, rec->section_number)(((unsigned*) (void *) (wdh->shb_iface_to_global)->data
) [(rec->section_number)])
;
5060 }
5061 } else {
5062 /*
5063 * The source isn't sending us IDBs. See if we already have a
5064 * matching interface, and use it if so.
5065 */
5066 for (epb.interface_id = 0; epb.interface_id < wdh->interface_data->len; ++epb.interface_id) {
5067 int_data = g_array_index(wdh->interface_data, wtap_block_t,(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(epb.interface_id)])
5068 epb.interface_id)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(epb.interface_id)])
;
5069 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5070 if (int_data_mand->wtap_encap == rec->rec_header.packet_header.pkt_encap) {
5071 if (int_data_mand->tsprecision == rec->tsprec || (!(rec->presence_flags & WTAP_HAS_TS0x00000001))) {
5072 break;
5073 }
5074 }
5075 }
5076 if (epb.interface_id == wdh->interface_data->len) {
5077 /*
5078 * We don't have a matching IDB. Generate a new one
5079 * and write it to the file.
5080 */
5081 int_data = wtap_rec_generate_idb(rec);
5082 g_array_append_val(wdh->interface_data, int_data)g_array_append_vals (wdh->interface_data, &(int_data),
1)
;
5083 if (!pcapng_write_if_descr_block(wdh, int_data, err, err_info)) {
5084 return false0;
5085 }
5086 }
5087 }
5088 if (epb.interface_id >= wdh->interface_data->len) {
5089 /*
5090 * Our caller is doing something bad.
5091 */
5092 *err = WTAP_ERR_INTERNAL-21;
5093 *err_info = ws_strdup_printf("pcapng: epb.interface_id (%u) >= wdh->interface_data->len (%u)",wmem_strdup_printf(((void*)0), "pcapng: epb.interface_id (%u) >= wdh->interface_data->len (%u)"
, epb.interface_id, wdh->interface_data->len)
5094 epb.interface_id, wdh->interface_data->len)wmem_strdup_printf(((void*)0), "pcapng: epb.interface_id (%u) >= wdh->interface_data->len (%u)"
, epb.interface_id, wdh->interface_data->len)
;
5095 return false0;
5096 }
5097 int_data = g_array_index(wdh->interface_data, wtap_block_t,(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(epb.interface_id)])
5098 epb.interface_id)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(epb.interface_id)])
;
5099 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5100 if (int_data_mand->wtap_encap != rec->rec_header.packet_header.pkt_encap) {
5101 /*
5102 * Our caller is doing something bad.
5103 */
5104 *err = WTAP_ERR_INTERNAL-21;
5105 *err_info = ws_strdup_printf("pcapng: interface %u encap %d != packet encap %d",wmem_strdup_printf(((void*)0), "pcapng: interface %u encap %d != packet encap %d"
, epb.interface_id, int_data_mand->wtap_encap, rec->rec_header
.packet_header.pkt_encap)
5106 epb.interface_id,wmem_strdup_printf(((void*)0), "pcapng: interface %u encap %d != packet encap %d"
, epb.interface_id, int_data_mand->wtap_encap, rec->rec_header
.packet_header.pkt_encap)
5107 int_data_mand->wtap_encap,wmem_strdup_printf(((void*)0), "pcapng: interface %u encap %d != packet encap %d"
, epb.interface_id, int_data_mand->wtap_encap, rec->rec_header
.packet_header.pkt_encap)
5108 rec->rec_header.packet_header.pkt_encap)wmem_strdup_printf(((void*)0), "pcapng: interface %u encap %d != packet encap %d"
, epb.interface_id, int_data_mand->wtap_encap, rec->rec_header
.packet_header.pkt_encap)
;
5109 return false0;
5110 }
5111
5112 /* write (enhanced) packet block header */
5113 block_content_length = (uint32_t)sizeof(epb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len + options_size;
5114 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_EPB0x00000006, block_content_length,
5115 err))
5116 return false0;
5117
5118 /* write block fixed content */
5119 /* Calculate the time stamp as a 64-bit integer. */
5120 ts = ((uint64_t)rec->ts.secs) * int_data_mand->time_units_per_second +
5121 (((uint64_t)rec->ts.nsecs) * int_data_mand->time_units_per_second) / NS_PER_S1000000000U;
5122 /*
5123 * Split the 64-bit timestamp into two 32-bit pieces, using
5124 * the time stamp resolution for the interface.
5125 */
5126 epb.timestamp_high = (uint32_t)(ts >> 32);
5127 epb.timestamp_low = (uint32_t)ts;
5128 epb.captured_len = rec->rec_header.packet_header.caplen + phdr_len;
5129 epb.packet_len = rec->rec_header.packet_header.len + phdr_len;
5130
5131 if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
5132 return false0;
5133
5134 /* write pseudo header */
5135 if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
5136 return false0;
5137 }
5138
5139 /* write packet data */
5140 if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.packet_header.caplen, err))
5141 return false0;
5142
5143 /* write padding (if any) */
5144 if (!pcapng_write_padding(wdh, pad_len, err))
5145 return false0;
5146
5147 /* Write options, if we have any */
5148 if (options_size != 0) {
5149 if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
5150 rec->block, write_wtap_epb_option,
5151 err, err_info))
5152 return false0;
5153 }
5154
5155 /* write block footer */
5156 return pcapng_write_block_footer(wdh, block_content_length, err);
5157}
5158
5159static bool_Bool
5160pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
5161 int *err, char **err_info _U___attribute__((unused)))
5162{
5163 uint32_t block_content_length;
5164 uint32_t pad_len;
5165
5166 /* Don't write anything we're not willing to read. */
5167 if (rec->rec_header.systemd_journal_export_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD262144U) {
5168 *err = WTAP_ERR_PACKET_TOO_LARGE-22;
5169 return false0;
5170 }
5171
5172 pad_len = WS_PADDING_TO_4(rec->rec_header.systemd_journal_export_header.record_len)((4U - ((rec->rec_header.systemd_journal_export_header.record_len
) % 4U)) % 4U)
;
5173
5174 /* write systemd journal export block header */
5175 block_content_length = rec->rec_header.systemd_journal_export_header.record_len + pad_len;
5176 ws_debug("writing %u bytes, %u padded",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5178, __func__, "writing %u bytes, %u padded", rec->rec_header
.systemd_journal_export_header.record_len, block_content_length
); } } while (0)
5177 rec->rec_header.systemd_journal_export_header.record_len,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5178, __func__, "writing %u bytes, %u padded", rec->rec_header
.systemd_journal_export_header.record_len, block_content_length
); } } while (0)
5178 block_content_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5178, __func__, "writing %u bytes, %u padded", rec->rec_header
.systemd_journal_export_header.record_len, block_content_length
); } } while (0)
;
5179 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT0x00000009,
5180 block_content_length, err))
5181 return false0;
5182
5183 /* write entry data */
5184 if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.systemd_journal_export_header.record_len, err))
5185 return false0;
5186
5187 /* write padding (if any) */
5188 if (!pcapng_write_padding(wdh, pad_len, err))
5189 return false0;
5190
5191 /* write block footer */
5192 return pcapng_write_block_footer(wdh, block_content_length, err);
5193}
5194
5195static bool_Bool
5196pcapng_write_custom_block_copy(wtap_dumper *wdh, const wtap_rec *rec,
5197 int *err, char **err_info _U___attribute__((unused)))
5198{
5199 pcapng_custom_block_enterprise_handler_t *pen_handler;
5200 uint32_t block_content_length;
5201 pcapng_custom_block_t cb;
5202 uint32_t pad_len;
5203
5204 /* Don't write anything we are not supposed to. */
5205 if (!rec->rec_header.custom_block_header.copy_allowed) {
5206 return true1;
5207 }
5208
5209 pen_handler = (pcapng_custom_block_enterprise_handler_t*)g_hash_table_lookup(custom_enterprise_handlers, GUINT_TO_POINTER(rec->rec_header.custom_block_header.pen)((gpointer) (gulong) (rec->rec_header.custom_block_header.
pen))
);
5210 if (pen_handler != NULL((void*)0))
5211 {
5212 if (!pen_handler->writer(wdh, rec, err, err_info))
5213 return false0;
5214 }
5215 else
5216 {
5217 /* Don't write anything we're not willing to read. */
5218 if (rec->rec_header.custom_block_header.length > WTAP_MAX_PACKET_SIZE_STANDARD262144U) {
5219 *err = WTAP_ERR_PACKET_TOO_LARGE-22;
5220 return false0;
5221 }
5222
5223 pad_len = WS_PADDING_TO_4(rec->rec_header.custom_block_header.length)((4U - ((rec->rec_header.custom_block_header.length) % 4U)
) % 4U)
;
5224
5225 /* write block header */
5226 block_content_length = (uint32_t)sizeof(cb) + rec->rec_header.custom_block_header.length + pad_len;
5227 ws_debug("writing %u bytes, %u padded, PEN %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5229, __func__, "writing %u bytes, %u padded, PEN %u", (uint32_t
)sizeof(cb) + rec->rec_header.custom_block_header.length, block_content_length
, rec->rec_header.custom_block_header.pen); } } while (0)
5228 (uint32_t)sizeof(cb) + rec->rec_header.custom_block_header.length,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5229, __func__, "writing %u bytes, %u padded, PEN %u", (uint32_t
)sizeof(cb) + rec->rec_header.custom_block_header.length, block_content_length
, rec->rec_header.custom_block_header.pen); } } while (0)
5229 block_content_length, rec->rec_header.custom_block_header.pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5229, __func__, "writing %u bytes, %u padded, PEN %u", (uint32_t
)sizeof(cb) + rec->rec_header.custom_block_header.length, block_content_length
, rec->rec_header.custom_block_header.pen); } } while (0)
;
5230 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_CB_COPY0x00000BAD,
5231 block_content_length, err))
5232 return false0;
5233
5234 /* write custom block header */
5235 cb.pen = rec->rec_header.custom_block_header.pen;
5236 if (!wtap_dump_file_write(wdh, &cb, sizeof cb, err)) {
5237 return false0;
5238 }
5239 ws_debug("wrote PEN = %u", cb.pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5239, __func__, "wrote PEN = %u", cb.pen); } } while (0)
;
5240
5241 /* write custom data */
5242 if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.custom_block_header.length, err)) {
5243 return false0;
5244 }
5245
5246 /* write padding (if any) */
5247 if (!pcapng_write_padding(wdh, pad_len, err))
5248 return false0;
5249
5250 /* write block footer */
5251 return pcapng_write_block_footer(wdh, block_content_length, err);
5252 }
5253 return true1;
5254}
5255
5256static bool_Bool
5257pcapng_write_custom_block_no_copy(wtap_dumper *wdh _U___attribute__((unused)), const wtap_rec *rec _U___attribute__((unused)),
5258 int *err _U___attribute__((unused)), char **err_info _U___attribute__((unused)))
5259{
5260 /* Don't write anything we are not supposed to. */
5261 return true1;
5262}
5263
5264static bool_Bool
5265pcapng_write_decryption_secrets_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
5266{
5267 uint32_t block_content_length;
5268 pcapng_decryption_secrets_block_t dsb;
5269 wtapng_dsb_mandatory_t *mand_data = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
5270 uint32_t pad_len;
5271
5272 pad_len = WS_PADDING_TO_4(mand_data->secrets_len)((4U - ((mand_data->secrets_len) % 4U)) % 4U);
5273
5274 /* write block header */
5275 block_content_length = (uint32_t)sizeof(dsb) + mand_data->secrets_len + pad_len;
5276 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_DSB0x0000000A, block_content_length,
5277 err))
5278 return false0;
5279
5280 /* write block fixed content */
5281 dsb.secrets_type = mand_data->secrets_type;
5282 dsb.secrets_len = mand_data->secrets_len;
5283 if (!wtap_dump_file_write(wdh, &dsb, sizeof dsb, err))
5284 return false0;
5285
5286 if (!wtap_dump_file_write(wdh, mand_data->secrets_data, mand_data->secrets_len, err))
5287 return false0;
5288
5289 /* write padding (if any) */
5290 if (!pcapng_write_padding(wdh, pad_len, err))
5291 return false0;
5292
5293 /* write block footer */
5294 return pcapng_write_block_footer(wdh, block_content_length, err);
5295}
5296
5297static bool_Bool
5298pcapng_write_meta_event_block(wtap_dumper *wdh, wtap_block_t mev_data, int *err)
5299{
5300 uint32_t block_content_length;
5301 wtapng_meta_event_mandatory_t *mand_data = (wtapng_meta_event_mandatory_t *)wtap_block_get_mandatory_data(mev_data);
5302 uint32_t pad_len;
5303
5304 pad_len = WS_PADDING_TO_4(mand_data->mev_data_len)((4U - ((mand_data->mev_data_len) % 4U)) % 4U);
5305
5306 /* write block header */
5307 block_content_length = mand_data->mev_data_len + pad_len;
5308 if (!pcapng_write_block_header(wdh, mand_data->mev_block_type,
5309 block_content_length, err))
5310 return false0;
5311 ws_debug("Sysdig mev len %u", block_content_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5311, __func__, "Sysdig mev len %u", block_content_length);
} } while (0)
;
5312
5313 /* write block fixed content */
5314 if (!wtap_dump_file_write(wdh, mand_data->mev_data, mand_data->mev_data_len, err))
5315 return false0;
5316
5317 /* write padding (if any) */
5318 if (!pcapng_write_padding(wdh, pad_len, err))
5319 return false0;
5320
5321 /* write block footer */
5322 return pcapng_write_block_footer(wdh, block_content_length, err);
5323}
5324
5325/*
5326 * libpcap's maximum pcapng block size is currently 16MB.
5327 *
5328 * The maximum pcapng block size in macOS's private pcapng reading code
5329 * is 1MB. (Yes, this means that a program using the standard pcap
5330 * code to read pcapng files can handle bigger blocks than can programs
5331 * using the private code, such as Apple's tcpdump, can handle.)
5332 *
5333 * The pcapng reading code here can handle NRBs of arbitrary size (less
5334 * than 4GB, obviously), as they read each NRB record independently,
5335 * rather than reading the entire block into memory.
5336 *
5337 * So, for now, we set the maximum NRB block size we write as 1 MB.
5338 *
5339 * (Yes, for the benefit of the fussy, "MB" is really "MiB".)
5340 */
5341
5342#define NRES_BLOCK_MAX_SIZE(1024*1024) (1024*1024)
5343
5344static uint32_t
5345compute_nrb_option_size(wtap_block_t block _U___attribute__((unused)), unsigned option_id, wtap_opttype_e option_type _U___attribute__((unused)), wtap_optval_t* optval)
5346{
5347 uint32_t size;
5348
5349 switch(option_id)
5350 {
5351 case OPT_NS_DNSNAME2:
5352 size = pcapng_compute_string_option_size(optval);
5353 break;
5354 case OPT_NS_DNSIP4ADDR3:
5355 size = 4;
5356 break;
5357 case OPT_NS_DNSIP6ADDR4:
5358 size = 16;
5359 break;
5360 default:
5361 /* Unknown options - size by datatype? */
5362 size = 0;
5363 break;
5364 }
5365 return size;
5366}
5367
5368static bool_Bool
5369put_nrb_option(wtap_block_t block _U___attribute__((unused)), unsigned option_id, wtap_opttype_e option_type _U___attribute__((unused)), wtap_optval_t* optval, void* user_data)
5370{
5371 uint8_t **opt_ptrp = (uint8_t **)user_data;
5372 size_t stringlen;
5373 size_t size = 0;
5374 struct pcapng_option_header option_hdr;
5375 uint32_t pad;
5376
5377 switch(option_id)
5378 {
5379 case OPT_COMMENT1:
5380 case OPT_NS_DNSNAME2:
5381 size = strlen(optval->stringval);
5382 if (size > 65535) {
5383 /*
5384 * Too big to fit in the option.
5385 * Don't write anything.
5386 *
5387 * XXX - truncate it? Report an error?
5388 */
5389 return true1;
5390 }
5391
5392 /* Put option header */
5393 /* String options don't consider pad bytes part of the length */
5394 option_hdr.type = (uint16_t)option_id;
5395 option_hdr.value_length = (uint16_t)size;
5396 memcpy(*opt_ptrp, &option_hdr, 4);
5397 *opt_ptrp += 4;
5398
5399 memcpy(*opt_ptrp, optval->stringval, size);
5400 *opt_ptrp += size;
5401
5402 /* put padding (if any) */
5403 pad = WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U);
5404 if (pad != 0) {
5405 memset(*opt_ptrp, 0, pad);
5406 *opt_ptrp += pad;
5407 }
5408 break;
5409 case OPT_CUSTOM_STR_COPY2988:
5410 /* String options don't consider pad bytes part of the length */
5411 stringlen = strlen(optval->custom_stringval.string);
5412 size = sizeof(uint32_t) + stringlen;
5413 if (size > 65535) {
5414 /*
5415 * Too big to fit in the option.
5416 * Don't write anything.
5417 *
5418 * XXX - truncate it? Report an error?
5419 */
5420 return true1;
5421 }
5422
5423 /* Put option header and PEN */
5424 /* String options don't consider pad bytes part of the length */
5425 option_hdr.type = (uint16_t)option_id;
5426 option_hdr.value_length = (uint16_t)size;
5427 memcpy(*opt_ptrp, &option_hdr, 4);
5428 *opt_ptrp += 4;
5429
5430 memcpy(*opt_ptrp, &optval->custom_stringval.pen, sizeof(uint32_t));
5431 *opt_ptrp += sizeof(uint32_t);
5432 memcpy(*opt_ptrp, optval->custom_stringval.string, size);
5433 *opt_ptrp += size;
5434
5435 /* put padding (if any) */
5436 pad = WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U);
5437 if (pad != 0) {
5438 memset(*opt_ptrp, 0, pad);
5439 *opt_ptrp += pad;
5440 }
5441 break;
5442 case OPT_CUSTOM_BIN_COPY2989:
5443 /* Custom options don't consider pad bytes part of the length */
5444 size = (uint32_t)(optval->custom_binaryval.data.custom_data_len + sizeof(uint32_t)) & 0xffff;
5445 option_hdr.type = (uint16_t)option_id;
5446 option_hdr.value_length = (uint16_t)size;
5447 memcpy(*opt_ptrp, &option_hdr, 4);
5448 *opt_ptrp += 4;
5449
5450 memcpy(*opt_ptrp, &optval->custom_binaryval.pen, sizeof(uint32_t));
5451 *opt_ptrp += sizeof(uint32_t);
5452
5453 memcpy(*opt_ptrp, optval->custom_binaryval.data.custom_data, optval->custom_binaryval.data.custom_data_len);
5454 *opt_ptrp += optval->custom_binaryval.data.custom_data_len;
5455
5456 /* put padding (if any) */
5457 pad = WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U);
5458 if (pad != 0) {
5459 memset(*opt_ptrp, 0, pad);
5460 *opt_ptrp += pad;
5461 }
5462 break;
5463 case OPT_NS_DNSIP4ADDR3:
5464 option_hdr.type = (uint16_t)option_id;
5465 option_hdr.value_length = 4;
5466 memcpy(*opt_ptrp, &option_hdr, 4);
5467 *opt_ptrp += 4;
5468
5469 memcpy(*opt_ptrp, &optval->ipv4val, 4);
5470 *opt_ptrp += 4;
5471 break;
5472 case OPT_NS_DNSIP6ADDR4:
5473 option_hdr.type = (uint16_t)option_id;
5474 option_hdr.value_length = 16;
5475 memcpy(*opt_ptrp, &option_hdr, 4);
5476 *opt_ptrp += 4;
5477
5478 memcpy(*opt_ptrp, &optval->ipv6val, 16);
5479 *opt_ptrp += 16;
5480 break;
5481 default:
5482 /* Unknown options - size by datatype? */
5483 break;
5484 }
5485 return true1; /* we always succeed */
5486}
5487
5488static void
5489put_nrb_options(wtap_dumper *wdh _U___attribute__((unused)), wtap_block_t nrb, uint8_t *opt_ptr)
5490{
5491 struct pcapng_option option_hdr;
5492
5493 wtap_block_foreach_option(nrb, put_nrb_option, &opt_ptr);
5494
5495 /* Put end of options */
5496 option_hdr.type = OPT_EOFOPT0;
5497 option_hdr.value_length = 0;
5498 memcpy(opt_ptr, &option_hdr, 4);
5499}
5500
5501static bool_Bool
5502pcapng_write_name_resolution_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
5503{
5504 pcapng_block_header_t bh;
5505 pcapng_name_resolution_block_t nrb;
5506 wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
5507 uint32_t options_size;
5508 size_t max_rec_data_size;
5509 uint8_t *block_data;
5510 uint32_t block_off;
5511 size_t hostnamelen;
5512 uint16_t namelen;
5513 uint32_t tot_rec_len;
5514 hashipv4_t *ipv4_hash_list_entry;
5515 hashipv6_t *ipv6_hash_list_entry;
5516 int i;
5517
5518 if (!mand_data) {
5519 /*
5520 * No name/address pairs to write.
5521 * XXX - what if we have options?
5522 */
5523 return true1;
5524 }
5525
5526 /* Calculate the space needed for options. */
5527 options_size = pcapng_compute_options_size(sdata, compute_nrb_option_size);
5528
5529 /*
5530 * Make sure we can fit at least one maximum-sized record, plus
5531 * an end-of-records record, plus the options, into a maximum-sized
5532 * block.
5533 *
5534 * That requires that there be enough space for the block header
5535 * (8 bytes), a maximum-sized record (2 bytes of record type, 2
5536 * bytes of record value length, 65535 bytes of record value,
5537 * and 1 byte of padding), an end-of-records record (4 bytes),
5538 * the options (options_size bytes), and the block trailer (4
5539 * bytes).
5540 */
5541 if (8 + 2 + 2 + 65535 + 1 + 4 + options_size + 4 > NRES_BLOCK_MAX_SIZE(1024*1024)) {
5542 /*
5543 * XXX - we can't even fit the options in the largest NRB size
5544 * we're willing to write and still have room enough for a
5545 * maximum-sized record. Just discard the information for now.
5546 */
5547 return true1;
5548 }
5549
5550 /*
5551 * Allocate a buffer for the largest block we'll write.
5552 */
5553 block_data = (uint8_t *)g_malloc(NRES_BLOCK_MAX_SIZE(1024*1024));
5554
5555 /*
5556 * Calculate the maximum amount of record data we'll be able to
5557 * fit into such a block, after taking into account the block header
5558 * (8 bytes), the end-of-records record (4 bytes), the options
5559 * (options_size bytes), and the block trailer (4 bytes).
5560 */
5561 max_rec_data_size = NRES_BLOCK_MAX_SIZE(1024*1024) - (8 + 4 + options_size + 4);
5562
5563 block_off = 8; /* block type + block total length */
5564 bh.block_type = BLOCK_TYPE_NRB0x00000004;
5565 bh.block_total_length = 12; /* block header + block trailer */
5566
5567 /*
5568 * Write out the IPv4 resolved addresses, if any.
5569 */
5570 if (mand_data->ipv4_addr_list){
5571 i = 0;
5572 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5573 while(ipv4_hash_list_entry != NULL((void*)0)){
5574
5575 nrb.record_type = NRES_IP4RECORD1;
5576 hostnamelen = strlen(ipv4_hash_list_entry->name);
5577 if (hostnamelen > (UINT16_MAX(65535) - 4) - 1) {
5578 /*
5579 * This won't fit in the largest possible NRB record;
5580 * discard it.
5581 */
5582 i++;
5583 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5584 continue;
5585 }
5586 namelen = (uint16_t)(hostnamelen + 1);
5587 nrb.record_len = 4 + namelen; /* 4 bytes IPv4 address length */
5588 /* 2 bytes record type, 2 bytes length field */
5589 tot_rec_len = 4 + nrb.record_len + WS_PADDING_TO_4(nrb.record_len)((4U - ((nrb.record_len) % 4U)) % 4U);
5590
5591 if (block_off + tot_rec_len > max_rec_data_size) {
5592 /*
5593 * This record would overflow our maximum size for Name
5594 * Resolution Blocks; write out all the records we created
5595 * before it, and start a new NRB.
5596 */
5597
5598 /* Append the end-of-records record */
5599 memset(block_data + block_off, 0, 4);
5600 block_off += 4;
5601 bh.block_total_length += 4;
5602
5603 /*
5604 * Put the options into the block.
5605 */
5606 put_nrb_options(wdh, sdata, block_data + block_off);
5607 block_off += options_size;
5608 bh.block_total_length += options_size;
5609
5610 /* Copy the block header. */
5611 memcpy(block_data, &bh, sizeof(bh));
5612
5613 /* Copy the block trailer. */
5614 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5615
5616 ws_debug("Write bh.block_total_length bytes %d, block_off %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5617, __func__, "Write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
5617 bh.block_total_length, block_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5617, __func__, "Write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
;
5618
5619 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5620 g_free(block_data);
5621 return false0;
5622 }
5623
5624 /*Start a new NRB */
5625 block_off = 8; /* block type + block total length */
5626 bh.block_type = BLOCK_TYPE_NRB0x00000004;
5627 bh.block_total_length = 12; /* block header + block trailer */
5628 }
5629
5630 bh.block_total_length += tot_rec_len;
5631 memcpy(block_data + block_off, &nrb, sizeof(nrb));
5632 block_off += 4;
5633 memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4);
5634 block_off += 4;
5635 memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen);
5636 block_off += namelen;
5637 memset(block_data + block_off, 0, WS_PADDING_TO_4(namelen)((4U - ((namelen) % 4U)) % 4U));
5638 block_off += WS_PADDING_TO_4(namelen)((4U - ((namelen) % 4U)) % 4U);
5639 ws_debug("added IPv4 record for %s", ipv4_hash_list_entry->name)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5639, __func__, "added IPv4 record for %s", ipv4_hash_list_entry
->name); } } while (0)
;
5640
5641 i++;
5642 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5643 }
5644 }
5645
5646 if (mand_data->ipv6_addr_list){
5647 i = 0;
5648 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5649 while(ipv6_hash_list_entry != NULL((void*)0)){
5650
5651 nrb.record_type = NRES_IP6RECORD2;
5652 hostnamelen = strlen(ipv6_hash_list_entry->name);
5653 if (hostnamelen > (UINT16_MAX(65535) - 16) - 1) {
5654 /*
5655 * This won't fit in the largest possible NRB record;
5656 * discard it.
5657 */
5658 i++;
5659 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5660 continue;
5661 }
5662 namelen = (uint16_t)(hostnamelen + 1);
5663 nrb.record_len = 16 + namelen; /* 16 bytes IPv6 address length */
5664 /* 2 bytes record type, 2 bytes length field */
5665 tot_rec_len = 4 + nrb.record_len + WS_PADDING_TO_4(nrb.record_len)((4U - ((nrb.record_len) % 4U)) % 4U);
5666
5667 if (block_off + tot_rec_len > max_rec_data_size) {
5668 /*
5669 * This record would overflow our maximum size for Name
5670 * Resolution Blocks; write out all the records we created
5671 * before it, and start a new NRB.
5672 */
5673
5674 /* Append the end-of-records record */
5675 memset(block_data + block_off, 0, 4);
5676 block_off += 4;
5677 bh.block_total_length += 4;
5678
5679 /*
5680 * Put the options into the block.
5681 */
5682 put_nrb_options(wdh, sdata, block_data + block_off);
5683 block_off += options_size;
5684 bh.block_total_length += options_size;
5685
5686 /* Copy the block header. */
5687 memcpy(block_data, &bh, sizeof(bh));
5688
5689 /* Copy the block trailer. */
5690 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5691
5692 ws_debug("write bh.block_total_length bytes %d, block_off %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5693, __func__, "write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
5693 bh.block_total_length, block_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5693, __func__, "write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
;
5694
5695 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5696 g_free(block_data);
5697 return false0;
5698 }
5699
5700 /*Start a new NRB */
5701 block_off = 8; /* block type + block total length */
5702 bh.block_type = BLOCK_TYPE_NRB0x00000004;
5703 bh.block_total_length = 12; /* block header + block trailer */
5704 }
5705
5706 bh.block_total_length += tot_rec_len;
5707 memcpy(block_data + block_off, &nrb, sizeof(nrb));
5708 block_off += 4;
5709 memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16);
5710 block_off += 16;
5711 memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen);
5712 block_off += namelen;
5713 memset(block_data + block_off, 0, WS_PADDING_TO_4(namelen)((4U - ((namelen) % 4U)) % 4U));
5714 block_off += WS_PADDING_TO_4(namelen)((4U - ((namelen) % 4U)) % 4U);
5715 ws_debug("added IPv6 record for %s", ipv6_hash_list_entry->name)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5715, __func__, "added IPv6 record for %s", ipv6_hash_list_entry
->name); } } while (0)
;
5716
5717 i++;
5718 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5719 }
5720 }
5721
5722 /* Append the end-of-records record */
5723 memset(block_data + block_off, 0, 4);
5724 block_off += 4;
5725 bh.block_total_length += 4;
5726
5727 /*
5728 * Put the options into the block.
5729 */
5730 put_nrb_options(wdh, sdata, block_data + block_off);
5731 block_off += options_size;
5732 bh.block_total_length += options_size;
5733
5734 /* Copy the block header. */
5735 memcpy(block_data, &bh, sizeof(bh));
5736
5737 /* Copy the block trailer. */
5738 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5739
5740 ws_debug("Write bh.block_total_length bytes %d, block_off %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5741, __func__, "Write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
5741 bh.block_total_length, block_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5741, __func__, "Write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
;
5742
5743 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5744 g_free(block_data);
5745 return false0;
5746 }
5747
5748 g_free(block_data);
5749
5750 return true1;
5751}
5752
5753static uint32_t compute_isb_option_size(wtap_block_t block _U___attribute__((unused)), unsigned option_id, wtap_opttype_e option_type _U___attribute__((unused)), wtap_optval_t *optval _U___attribute__((unused)))
5754{
5755 uint32_t size;
5756
5757 switch(option_id)
5758 {
5759 case OPT_ISB_STARTTIME2:
5760 case OPT_ISB_ENDTIME3:
5761 size = 8;
5762 break;
5763 case OPT_ISB_IFRECV4:
5764 case OPT_ISB_IFDROP5:
5765 case OPT_ISB_FILTERACCEPT6:
5766 case OPT_ISB_OSDROP7:
5767 case OPT_ISB_USRDELIV8:
5768 size = 8;
5769 break;
5770 default:
5771 /* Unknown options - size by datatype? */
5772 size = 0;
5773 break;
5774 }
5775 return size;
5776}
5777
5778static bool_Bool write_wtap_isb_option(wtap_dumper *wdh, wtap_block_t block _U___attribute__((unused)),
5779 unsigned option_id,
5780 wtap_opttype_e option_type _U___attribute__((unused)),
5781 wtap_optval_t *optval,
5782 int *err, char **err_info _U___attribute__((unused)))
5783{
5784 switch(option_id)
5785 {
5786 case OPT_ISB_STARTTIME2:
5787 case OPT_ISB_ENDTIME3:
5788 if (!pcapng_write_timestamp_option(wdh, option_id, optval, err))
5789 return false0;
5790 break;
5791 case OPT_ISB_IFRECV4:
5792 case OPT_ISB_IFDROP5:
5793 case OPT_ISB_FILTERACCEPT6:
5794 case OPT_ISB_OSDROP7:
5795 case OPT_ISB_USRDELIV8:
5796 if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5797 return false0;
5798 break;
5799 default:
5800 /* Unknown options - write by datatype? */
5801 break;
5802 }
5803 return true1; /* success */
5804}
5805
5806static bool_Bool
5807pcapng_write_interface_statistics_block(wtap_dumper *wdh,
5808 wtap_block_t if_stats,
5809 int *err, char **err_info)
5810{
5811 uint32_t block_content_length;
5812 pcapng_interface_statistics_block_t isb;
5813 uint32_t options_size;
5814 wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
5815
5816 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5816, __func__, "entering function"); } } while (0)
;
5817
5818 /* Compute size of all the options */
5819 options_size = pcapng_compute_options_size(if_stats, compute_isb_option_size);
5820
5821 /* write block header */
5822 block_content_length = (uint32_t)sizeof(isb) + options_size;
5823 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_ISB0x00000005, block_content_length,
5824 err))
5825 return false0;
5826
5827 /* write block fixed content */
5828 isb.interface_id = mand_data->interface_id;
5829 isb.timestamp_high = mand_data->ts_high;
5830 isb.timestamp_low = mand_data->ts_low;
5831
5832 if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
5833 return false0;
5834
5835 /* Write options */
5836 if (options_size != 0) {
5837 if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
5838 if_stats, write_wtap_isb_option,
5839 err, err_info))
5840 return false0;
5841 }
5842
5843 /* write block footer */
5844 return pcapng_write_block_footer(wdh, block_content_length, err);
5845}
5846
5847static uint32_t compute_idb_option_size(wtap_block_t block _U___attribute__((unused)), unsigned option_id, wtap_opttype_e option_type _U___attribute__((unused)), wtap_optval_t *optval)
5848{
5849 uint32_t size;
5850
5851 switch(option_id)
5852 {
5853 case OPT_IDB_NAME2:
5854 case OPT_IDB_DESCRIPTION3:
5855 case OPT_IDB_OS12:
5856 case OPT_IDB_HARDWARE15:
5857 size = pcapng_compute_string_option_size(optval);
5858 break;
5859 case OPT_IDB_SPEED8:
5860 size = 8;
5861 break;
5862 case OPT_IDB_TSRESOL9:
5863 size = 1;
5864 break;
5865 case OPT_IDB_FILTER11:
5866 size = pcapng_compute_if_filter_option_size(optval);
5867 break;
5868 case OPT_IDB_FCSLEN13:
5869 size = 1;
5870 break;
5871 case OPT_IDB_TSOFFSET14:
5872 /*
5873 * The time stamps handed to us when writing a file are
5874 * absolute time staps, so the time stamp offset is
5875 * zero.
5876 *
5877 * We do not adjust them when writing, so we should not
5878 * write if_tsoffset options; that is interpreted as
5879 * the offset is zero, i.e. the time stamps in the file
5880 * are absolute.
5881 */
5882 size = 0;
5883 break;
5884 default:
5885 /* Unknown options - size by datatype? */
5886 size = 0;
5887 break;
5888 }
5889 return size;
5890}
5891
5892static bool_Bool write_wtap_idb_option(wtap_dumper *wdh, wtap_block_t block _U___attribute__((unused)),
5893 unsigned option_id,
5894 wtap_opttype_e option_type _U___attribute__((unused)),
5895 wtap_optval_t *optval,
5896 int *err, char **err_info)
5897{
5898 switch(option_id)
5899 {
5900 case OPT_IDB_NAME2:
5901 case OPT_IDB_DESCRIPTION3:
5902 case OPT_IDB_OS12:
5903 case OPT_IDB_HARDWARE15:
5904 if (!pcapng_write_string_option(wdh, OPT_SECTION_BYTE_ORDER,
5905 option_id, optval, err, err_info))
5906 return false0;
5907 break;
5908 case OPT_IDB_SPEED8:
5909 if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5910 return false0;
5911 break;
5912 case OPT_IDB_TSRESOL9:
5913 if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
5914 return false0;
5915 break;
5916 case OPT_IDB_FILTER11:
5917 if (!pcapng_write_if_filter_option(wdh, option_id, optval, err))
5918 return false0;
5919 break;
5920 case OPT_IDB_FCSLEN13:
5921 if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
5922 return false0;
5923 break;
5924 case OPT_IDB_TSOFFSET14:
5925 /*
5926 * As noted above, we discard these.
5927 */
5928 break;
5929 default:
5930 /* Unknown options - size by datatype? */
5931 break;
5932 }
5933 return true1;
5934}
5935
5936static bool_Bool
5937pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data,
5938 int *err, char **err_info)
5939{
5940 uint32_t block_content_length;
5941 pcapng_interface_description_block_t idb;
5942 uint32_t options_size;
5943 wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5944 int link_type;
5945
5946 ws_debug("encap = %d (%s), snaplen = %d",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5949, __func__, "encap = %d (%s), snaplen = %d", mand_data->
wtap_encap, wtap_encap_description(mand_data->wtap_encap),
mand_data->snap_len); } } while (0)
5947 mand_data->wtap_encap,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5949, __func__, "encap = %d (%s), snaplen = %d", mand_data->
wtap_encap, wtap_encap_description(mand_data->wtap_encap),
mand_data->snap_len); } } while (0)
5948 wtap_encap_description(mand_data->wtap_encap),do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5949, __func__, "encap = %d (%s), snaplen = %d", mand_data->
wtap_encap, wtap_encap_description(mand_data->wtap_encap),
mand_data->snap_len); } } while (0)
5949 mand_data->snap_len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5949, __func__, "encap = %d (%s), snaplen = %d", mand_data->
wtap_encap, wtap_encap_description(mand_data->wtap_encap),
mand_data->snap_len); } } while (0)
;
5950
5951 link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap);
5952 if (link_type == -1) {
5953 if (!pcapng_encap_is_ft_specific(mand_data->wtap_encap)) {
5954 *err = WTAP_ERR_UNWRITABLE_ENCAP-8;
5955 return false0;
5956 }
5957 }
5958
5959 /* Compute size of all the options */
5960 options_size = pcapng_compute_options_size(int_data, compute_idb_option_size);
5961
5962 /* write block header */
5963 block_content_length = (uint32_t)sizeof(idb) + options_size;
5964 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_IDB0x00000001, block_content_length,
5965 err))
5966 return false0;
5967
5968 /* write block fixed content */
5969 idb.linktype = link_type;
5970 idb.reserved = 0;
5971 idb.snaplen = mand_data->snap_len;
5972
5973 if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
5974 return false0;
5975
5976 if (options_size != 0) {
5977 /* Write options */
5978 if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
5979 int_data, write_wtap_idb_option,
5980 err, err_info))
5981 return false0;
5982 }
5983
5984 /* write block footer */
5985 return pcapng_write_block_footer(wdh, block_content_length, err);
5986}
5987
5988static bool_Bool pcapng_add_idb(wtap_dumper *wdh, wtap_block_t idb,
5989 int *err, char **err_info)
5990{
5991 wtap_block_t idb_copy;
5992
5993 /*
5994 * Add a copy of this IDB to our array of IDBs.
5995 */
5996 idb_copy = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
5997 wtap_block_copy(idb_copy, idb);
5998 g_array_append_val(wdh->interface_data, idb_copy)g_array_append_vals (wdh->interface_data, &(idb_copy),
1)
;
5999
6000 /*
6001 * And write it to the output file.
6002 */
6003 return pcapng_write_if_descr_block(wdh, idb_copy, err, err_info);
6004}
6005
6006static bool_Bool pcapng_write_internal_blocks(wtap_dumper *wdh, int *err)
6007{
6008
6009 /* Write (optional) Decryption Secrets Blocks that were collected while
6010 * reading packet blocks. */
6011 if (wdh->dsbs_growing) {
6012 for (unsigned i = wdh->dsbs_growing_written; i < wdh->dsbs_growing->len; i++) {
6013 ws_debug("writing DSB %u", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6013, __func__, "writing DSB %u", i); } } while (0)
;
6014 wtap_block_t dsb = g_array_index(wdh->dsbs_growing, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->dsbs_growing)->data) [
(i)])
;
6015 if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6016 return false0;
6017 }
6018 ++wdh->dsbs_growing_written;
6019 }
6020 }
6021
6022 /* Write (optional) Sysdig Meta Event Blocks that were collected while
6023 * reading packet blocks. */
6024 if (wdh->mevs_growing) {
6025 for (unsigned i = wdh->mevs_growing_written; i < wdh->mevs_growing->len; i++) {
6026 ws_debug("writing Sysdig mev %u", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6026, __func__, "writing Sysdig mev %u", i); } } while (0)
;
6027 wtap_block_t mev = g_array_index(wdh->mevs_growing, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->mevs_growing)->data) [
(i)])
;
6028 if (!pcapng_write_meta_event_block(wdh, mev, err)) {
6029 return false0;
6030 }
6031 ++wdh->mevs_growing_written;
6032 }
6033 }
6034
6035 /* Write any hostname resolution info from wtap_dump_set_addrinfo_list() */
6036 if (!wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
6037 /*
6038 * XXX: get_addrinfo_list() returns a list of all known and used
6039 * resolved addresses, regardless of origin: existing NRBs, externally
6040 * resolved, DNS packet data, a hosts file, and manual host resolution
6041 * through the GUI. It does not include the source for each.
6042 *
6043 * If it did, we could instead create multiple NRBs, one for each
6044 * server (as the options can only be included once per block.)
6045 * Instead, we copy the options from the first already existing NRB
6046 * (if there is one), since some of the name resolutions may be
6047 * from that block.
6048 */
6049 wtap_block_t nrb;
6050 if (wdh->nrbs_growing && wdh->nrbs_growing->len) {
6051 nrb = wtap_block_make_copy(g_array_index(wdh->nrbs_growing, wtap_block_t, 0)(((wtap_block_t*) (void *) (wdh->nrbs_growing)->data) [
(0)])
);
6052 } else {
6053 nrb = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
6054 }
6055 wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(nrb);
6056 mand_data->ipv4_addr_list = wdh->addrinfo_lists->ipv4_addr_list;
6057 mand_data->ipv6_addr_list = wdh->addrinfo_lists->ipv6_addr_list;
6058
6059 if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
6060 return false0;
6061 }
6062 mand_data->ipv4_addr_list = NULL((void*)0);
6063 mand_data->ipv6_addr_list = NULL((void*)0);
6064 wtap_block_unref(nrb);
6065 g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
6066 wdh->addrinfo_lists->ipv4_addr_list = NULL((void*)0);
6067 g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
6068 wdh->addrinfo_lists->ipv6_addr_list = NULL((void*)0);
6069 /* Since the addrinfo lists include information from existing NRBs,
6070 * avoid writing them to avoid duplication.
6071 *
6072 * XXX: Perhaps we don't want to include information from the NRBs
6073 * in get_addrinfo_list at all, so that we could write existing
6074 * NRBs as-is.
6075 *
6076 * This is still not well oriented for one-pass programs, where we
6077 * don't have addrinfo_lists until we've already written the
6078 * NRBs. We should not write both in such a situation. See bug 15502.
6079 */
6080 wtap_dump_discard_name_resolution(wdh);
6081 }
6082
6083 /* Write (optional) Name Resolution Blocks that were collected while
6084 * reading packet blocks. */
6085 if (wdh->nrbs_growing) {
6086 for (unsigned i = wdh->nrbs_growing_written; i < wdh->nrbs_growing->len; i++) {
6087 wtap_block_t nrb = g_array_index(wdh->nrbs_growing, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->nrbs_growing)->data) [
(i)])
;
6088 if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
6089 return false0;
6090 }
6091 ++wdh->nrbs_growing_written;
6092 }
6093 }
6094
6095 return true1;
6096}
6097
6098static bool_Bool pcapng_dump(wtap_dumper *wdh, const wtap_rec *rec,
6099 int *err, char **err_info)
6100{
6101 uint32_t block_type;
6102 pcapng_block_type_information_t* handler;
6103
6104 if (!pcapng_write_internal_blocks(wdh, err)) {
6105 return false0;
6106 }
6107
6108 ws_debug("encap = %d (%s) rec type = %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6111, __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)
6109 rec->rec_header.packet_header.pkt_encap,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6111, __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)
6110 wtap_encap_description(rec->rec_header.packet_header.pkt_encap),do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6111, __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)
6111 rec->rec_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6111, __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)
;
6112
6113 switch (rec->rec_type) {
6114
6115 case REC_TYPE_PACKET0:
6116 /* Write Simple Packet Block if appropriate, Enhanced Packet Block otherwise. */
6117 if (!(rec->presence_flags & WTAP_HAS_TS0x00000001) &&
6118 (!(rec->presence_flags & WTAP_HAS_INTERFACE_ID0x00000004) || rec->rec_header.packet_header.interface_id == 0) &&
6119 (!(rec->presence_flags & WTAP_HAS_CAP_LEN0x00000002) || rec->rec_header.packet_header.len == rec->rec_header.packet_header.caplen) &&
6120 (rec->block == NULL((void*)0) || pcapng_compute_options_size(rec->block, compute_epb_option_size) == 0)) {
6121 block_type = BLOCK_TYPE_SPB0x00000003;
6122 }
6123 else {
6124 block_type = BLOCK_TYPE_EPB0x00000006;
6125 }
6126 break;
6127
6128 case REC_TYPE_FT_SPECIFIC_EVENT1:
6129 case REC_TYPE_FT_SPECIFIC_REPORT2:
6130 /*
6131 * Is this an event or report for our file type?
6132 */
6133 if (rec->rec_header.ft_specific_header.file_type_subtype != pcapng_file_type_subtype) {
6134 /*
6135 * No. We can't write that.
6136 */
6137 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
6138 *err_info = g_strdup_printf("%s records for \"%s\" files aren't supported for this file type",
6139 rec->rec_type_name,
6140 wtap_file_type_subtype_name(rec->rec_header.ft_specific_header.file_type_subtype));
6141 return false0;
6142 }
6143
6144 block_type = rec->rec_header.ft_specific_header.record_type;
6145 break;
6146
6147 case REC_TYPE_SYSCALL3:
6148 block_type = rec->rec_header.syscall_header.record_type;
6149 break;
6150
6151 case REC_TYPE_SYSTEMD_JOURNAL_EXPORT4:
6152 block_type = BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT0x00000009;
6153 break;
6154
6155 case REC_TYPE_CUSTOM_BLOCK5:
6156 {
6157 /* Don't write anything we are not supposed to. */
6158 if (!rec->rec_header.custom_block_header.copy_allowed) {
6159 return true1;
6160 }
6161 block_type = BLOCK_TYPE_CB_COPY0x00000BAD;
6162 break;
6163 }
6164
6165 default:
6166 /* We don't support writing this record type. */
6167 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
6168 *err_info = wtap_unwritable_rec_type_err_string(rec);
6169 return false0;
6170 }
6171
6172 /*
6173 * Do we have a handler for this block type?
6174 */
6175 handler = (pcapng_block_type_information_t*)g_hash_table_lookup(block_handlers,
6176 GUINT_TO_POINTER(block_type)((gpointer) (gulong) (block_type)));
6177 if (handler == NULL((void*)0)) {
6178 /* No. We can't write that. */
6179 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
6180 *err_info = g_strdup_printf("Pcapng blocks of type 0x%8x aren't supported",
6181 rec->rec_header.ft_specific_header.record_type);
6182 return false0;
6183 }
6184
6185 /* Yes. Call it to write out this record. */
6186 return handler->writer(wdh, rec, err, err_info);
6187}
6188
6189/*
6190 * Write block header.
6191 */
6192bool_Bool
6193pcapng_write_block_header(wtap_dumper *wdh, uint32_t block_type,
6194 uint32_t block_content_length, int *err)
6195{
6196 pcapng_block_header_t bh;
6197
6198 bh.block_type = block_type;
6199 /*
6200 * Total block length is the length of the header plus the length
6201 * of the block content (which is padded to a multiple of 4 bytes)
6202 * plus the length of the trailer.
6203 */
6204 bh.block_total_length = (uint32_t)sizeof(pcapng_block_header_t) + block_content_length + 4;
6205 ws_debug("Total len %u", bh.block_total_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6205, __func__, "Total len %u", bh.block_total_length); } }
while (0)
;
6206 return wtap_dump_file_write(wdh, &bh, sizeof bh, err);
6207}
6208
6209/*
6210 * Write block footer.
6211 */
6212bool_Bool
6213pcapng_write_block_footer(wtap_dumper *wdh, uint32_t block_content_length,
6214 int *err)
6215{
6216 uint32_t bf;
6217
6218 bf = (uint32_t)sizeof(pcapng_block_header_t) + block_content_length + 4;
6219 return wtap_dump_file_write(wdh, &bf, sizeof bf, err);
6220}
6221
6222/* Finish writing to a dump file.
6223 Returns true on success, false on failure. */
6224static bool_Bool pcapng_dump_finish(wtap_dumper *wdh, int *err, char **err_info)
6225{
6226 unsigned i, j;
6227
6228 /* Flush any hostname resolution or decryption secrets info we may have */
6229 if (!pcapng_write_internal_blocks(wdh, err)) {
6230 return false0;
6231 }
6232
6233 for (i = 0; i < wdh->interface_data->len; i++) {
6234
6235 /* Get the interface description */
6236 wtap_block_t int_data;
6237 wtapng_if_descr_mandatory_t *int_data_mand;
6238
6239 int_data = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
6240 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
6241
6242 for (j = 0; j < int_data_mand->num_stat_entries; j++) {
6243 wtap_block_t if_stats;
6244
6245 if_stats = g_array_index(int_data_mand->interface_statistics, wtap_block_t, j)(((wtap_block_t*) (void *) (int_data_mand->interface_statistics
)->data) [(j)])
;
6246 ws_debug("write ISB for interface %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6247, __func__, "write ISB for interface %u", ((wtapng_if_stats_mandatory_t
*)wtap_block_get_mandatory_data(if_stats))->interface_id);
} } while (0)
6247 ((wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats))->interface_id)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6247, __func__, "write ISB for interface %u", ((wtapng_if_stats_mandatory_t
*)wtap_block_get_mandatory_data(if_stats))->interface_id);
} } while (0)
;
6248 if (!pcapng_write_interface_statistics_block(wdh, if_stats,
6249 err, err_info)) {
6250 return false0;
6251 }
6252 }
6253 }
6254
6255 ws_debug("leaving function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6255, __func__, "leaving function"); } } while (0)
;
6256 return true1;
6257}
6258
6259/* Returns true on success, false on failure; sets "*err" to an error code on
6260 failure */
6261static bool_Bool
6262pcapng_dump_open(wtap_dumper *wdh, int *err, char **err_info)
6263{
6264 unsigned i;
6265
6266 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6266, __func__, "entering function"); } } while (0)
;
6267 /* This is a pcapng file */
6268 wdh->subtype_add_idb = pcapng_add_idb;
6269 wdh->subtype_write = pcapng_dump;
6270 wdh->subtype_finish = pcapng_dump_finish;
6271
6272 /* write the section header block */
6273 if (!pcapng_write_section_header_block(wdh, err, err_info)) {
6274 return false0;
6275 }
6276 ws_debug("wrote section header block.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6276, __func__, "wrote section header block."); } } while (
0)
;
6277
6278 /* Write the Interface description blocks */
6279 ws_debug("Number of IDBs to write (number of interfaces) %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6280, __func__, "Number of IDBs to write (number of interfaces) %u"
, wdh->interface_data->len); } } while (0)
6280 wdh->interface_data->len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6280, __func__, "Number of IDBs to write (number of interfaces) %u"
, wdh->interface_data->len); } } while (0)
;
6281
6282 for (i = 0; i < wdh->interface_data->len; i++) {
6283
6284 /* Get the interface description */
6285 wtap_block_t idb;
6286
6287 idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
6288
6289 if (!pcapng_write_if_descr_block(wdh, idb, err, err_info)) {
6290 return false0;
6291 }
6292
6293 }
6294
6295 /* Write (optional) fixed Decryption Secrets Blocks. */
6296 if (wdh->dsbs_initial) {
6297 for (i = 0; i < wdh->dsbs_initial->len; i++) {
6298 wtap_block_t dsb = g_array_index(wdh->dsbs_initial, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->dsbs_initial)->data) [
(i)])
;
6299 if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6300 return false0;
6301 }
6302 }
6303 }
6304
6305 return true1;
6306}
6307
6308/* Returns 0 if we could write the specified encapsulation type,
6309 an error indication otherwise. */
6310static int pcapng_dump_can_write_encap(int wtap_encap)
6311{
6312 ws_debug("encap = %d (%s)",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6314, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
6313 wtap_encap,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6314, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
6314 wtap_encap_description(wtap_encap))do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6314, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
;
6315
6316 /* Per-packet encapsulation is supported. */
6317 if (wtap_encap == WTAP_ENCAP_PER_PACKET-1)
6318 return 0;
6319
6320 /* No encapsulation type (yet) is supported. */
6321 if (wtap_encap == WTAP_ENCAP_NONE-2)
6322 return 0;
6323
6324 /* Is it a filetype-specific encapsulation that we support? */
6325 if (pcapng_encap_is_ft_specific(wtap_encap)) {
6326 return 0;
6327 }
6328
6329 /* Make sure we can figure out this DLT type */
6330 if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
6331 return WTAP_ERR_UNWRITABLE_ENCAP-8;
6332
6333 return 0;
6334}
6335
6336/*
6337 * Returns true if the specified encapsulation type is filetype-specific
6338 * and one that we support.
6339 */
6340bool_Bool pcapng_encap_is_ft_specific(int encap)
6341{
6342 switch (encap) {
6343 case WTAP_ENCAP_SYSTEMD_JOURNAL203:
6344 return true1;
6345 }
6346 return false0;
6347}
6348
6349/*
6350 * pcapng supports several block types, and supports more than one
6351 * of them.
6352 *
6353 * It also supports comments for many block types, as well as other
6354 * option types.
6355 */
6356
6357/* Options for section blocks. */
6358static const struct supported_option_type section_block_options_supported[] = {
6359 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6360 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6361 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6362 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6363 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED },
6364 { OPT_SHB_HARDWARE2, ONE_OPTION_SUPPORTED },
6365 { OPT_SHB_USERAPPL4, ONE_OPTION_SUPPORTED }
6366};
6367
6368/* Options for interface blocks. */
6369static const struct supported_option_type interface_block_options_supported[] = {
6370 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6371 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6372 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6373 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6374 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED },
6375 { OPT_IDB_NAME2, ONE_OPTION_SUPPORTED },
6376 { OPT_IDB_DESCRIPTION3, ONE_OPTION_SUPPORTED },
6377 { OPT_IDB_IP4ADDR4, MULTIPLE_OPTIONS_SUPPORTED },
6378 { OPT_IDB_IP6ADDR5, MULTIPLE_OPTIONS_SUPPORTED },
6379 { OPT_IDB_MACADDR6, ONE_OPTION_SUPPORTED },
6380 { OPT_IDB_EUIADDR7, ONE_OPTION_SUPPORTED },
6381 { OPT_IDB_SPEED8, ONE_OPTION_SUPPORTED },
6382 { OPT_IDB_TSRESOL9, ONE_OPTION_SUPPORTED },
6383 { OPT_IDB_TZONE10, ONE_OPTION_SUPPORTED },
6384 { OPT_IDB_FILTER11, ONE_OPTION_SUPPORTED },
6385 { OPT_IDB_OS12, ONE_OPTION_SUPPORTED },
6386 { OPT_IDB_FCSLEN13, ONE_OPTION_SUPPORTED },
6387 { OPT_IDB_TSOFFSET14, ONE_OPTION_SUPPORTED },
6388 { OPT_IDB_HARDWARE15, ONE_OPTION_SUPPORTED },
6389 { OPT_IDB_TXSPEED16, ONE_OPTION_SUPPORTED },
6390 { OPT_IDB_RXSPEED17, ONE_OPTION_SUPPORTED },
6391 { OPT_IDB_IANA_TZNAME18, ONE_OPTION_SUPPORTED }
6392};
6393
6394/* Options for name resolution blocks. */
6395static const struct supported_option_type name_resolution_block_options_supported[] = {
6396 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6397 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6398 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6399 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6400 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED },
6401 { OPT_NS_DNSNAME2, ONE_OPTION_SUPPORTED },
6402 { OPT_NS_DNSIP4ADDR3, ONE_OPTION_SUPPORTED },
6403 { OPT_NS_DNSIP6ADDR4, ONE_OPTION_SUPPORTED }
6404};
6405
6406/* Options for interface statistics blocks. */
6407static const struct supported_option_type interface_statistics_block_options_supported[] = {
6408 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6409 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6410 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6411 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6412 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED },
6413 { OPT_ISB_STARTTIME2, ONE_OPTION_SUPPORTED },
6414 { OPT_ISB_ENDTIME3, ONE_OPTION_SUPPORTED },
6415 { OPT_ISB_IFRECV4, ONE_OPTION_SUPPORTED },
6416 { OPT_ISB_IFDROP5, ONE_OPTION_SUPPORTED },
6417 { OPT_ISB_FILTERACCEPT6, ONE_OPTION_SUPPORTED },
6418 { OPT_ISB_OSDROP7, ONE_OPTION_SUPPORTED },
6419 { OPT_ISB_USRDELIV8, ONE_OPTION_SUPPORTED }
6420};
6421
6422/* Options for decryption secrets blocks. */
6423static const struct supported_option_type decryption_secrets_block_options_supported[] = {
6424 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6425 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6426 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6427 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6428 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6429};
6430
6431/* Options for meta event blocks. */
6432static const struct supported_option_type meta_events_block_options_supported[] = {
6433 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6434 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6435 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6436 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6437 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6438};
6439
6440/* Options for packet blocks. */
6441static const struct supported_option_type packet_block_options_supported[] = {
6442 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6443 { OPT_PKT_FLAGS2, ONE_OPTION_SUPPORTED },
6444 { OPT_PKT_HASH3, MULTIPLE_OPTIONS_SUPPORTED },
6445 { OPT_PKT_DROPCOUNT4, ONE_OPTION_SUPPORTED },
6446 { OPT_PKT_PACKETID5, ONE_OPTION_SUPPORTED },
6447 { OPT_PKT_QUEUE6, ONE_OPTION_SUPPORTED },
6448 { OPT_PKT_VERDICT7, MULTIPLE_OPTIONS_SUPPORTED },
6449 { OPT_PKT_PROCIDTHRDID8, ONE_OPTION_SUPPORTED },
6450 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6451 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6452 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6453 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6454};
6455
6456/* Options for file-type-specific reports. */
6457static const struct supported_option_type ft_specific_report_block_options_supported[] = {
6458 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6459 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6460 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6461 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6462 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6463};
6464
6465/* Options for file-type-specific event. */
6466static const struct supported_option_type ft_specific_event_block_options_supported[] = {
6467 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6468 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6469 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6470 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6471 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6472};
6473
6474/* Options for systemd journal entry. */
6475static const struct supported_option_type systemd_journal_export_block_options_supported[] = {
6476 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6477 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6478 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6479 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6480 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6481};
6482
6483static const struct supported_block_type pcapng_blocks_supported[] = {
6484 /* Multiple sections. */
6485 { WTAP_BLOCK_SECTION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(section_block_options_supported)(sizeof (section_block_options_supported) / sizeof (section_block_options_supported
)[0]), section_block_options_supported
},
6486
6487 /* Multiple interfaces. */
6488 { 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
},
6489
6490 /* Multiple blocks of name resolution information */
6491 { WTAP_BLOCK_NAME_RESOLUTION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(name_resolution_block_options_supported)(sizeof (name_resolution_block_options_supported) / sizeof (name_resolution_block_options_supported
)[0]), name_resolution_block_options_supported
},
6492
6493 /* Multiple blocks of interface statistics. */
6494 { WTAP_BLOCK_IF_STATISTICS, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_statistics_block_options_supported)(sizeof (interface_statistics_block_options_supported) / sizeof
(interface_statistics_block_options_supported)[0]), interface_statistics_block_options_supported
},
6495
6496 /* Multiple blocks of decryption secrets. */
6497 { WTAP_BLOCK_DECRYPTION_SECRETS, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(decryption_secrets_block_options_supported)(sizeof (decryption_secrets_block_options_supported) / sizeof
(decryption_secrets_block_options_supported)[0]), decryption_secrets_block_options_supported
},
6498
6499 /* Multiple blocks of meta evens.. */
6500 { WTAP_BLOCK_META_EVENT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(meta_events_block_options_supported)(sizeof (meta_events_block_options_supported) / sizeof (meta_events_block_options_supported
)[0]), meta_events_block_options_supported
},
6501
6502 /* And, obviously, multiple packets. */
6503 { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(packet_block_options_supported)(sizeof (packet_block_options_supported) / sizeof (packet_block_options_supported
)[0]), packet_block_options_supported
},
6504
6505 /* Multiple file-type specific reports (including local ones). */
6506 { WTAP_BLOCK_FT_SPECIFIC_REPORT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_report_block_options_supported)(sizeof (ft_specific_report_block_options_supported) / sizeof
(ft_specific_report_block_options_supported)[0]), ft_specific_report_block_options_supported
},
6507
6508 /* Multiple file-type specific events (including local ones). */
6509 { WTAP_BLOCK_FT_SPECIFIC_EVENT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_event_block_options_supported)(sizeof (ft_specific_event_block_options_supported) / sizeof (
ft_specific_event_block_options_supported)[0]), ft_specific_event_block_options_supported
},
6510
6511 /* Multiple systemd journal export records. */
6512 { WTAP_BLOCK_SYSTEMD_JOURNAL_EXPORT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(systemd_journal_export_block_options_supported)(sizeof (systemd_journal_export_block_options_supported) / sizeof
(systemd_journal_export_block_options_supported)[0]), systemd_journal_export_block_options_supported
},
6513
6514 /* Multiple custom blocks. */
6515 { WTAP_BLOCK_CUSTOM, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED0, ((void*)0) },
6516};
6517
6518static const struct file_type_subtype_info wireshark_pcapng_info = {
6519 "Wireshark/... - pcapng", "pcapng", "pcapng", "ntar",
6520 false0, BLOCKS_SUPPORTED(pcapng_blocks_supported)(sizeof (pcapng_blocks_supported) / sizeof (pcapng_blocks_supported
)[0]), pcapng_blocks_supported
,
6521 pcapng_dump_can_write_encap, pcapng_dump_open, NULL((void*)0)
6522};
6523
6524static const struct file_type_subtype_info stratoshark_pcapng_info = {
6525 "Stratoshark/... - scap", "scap", "scap", "scap",
6526 false0, BLOCKS_SUPPORTED(pcapng_blocks_supported)(sizeof (pcapng_blocks_supported) / sizeof (pcapng_blocks_supported
)[0]), pcapng_blocks_supported
,
6527 pcapng_dump_can_write_encap, pcapng_dump_open, NULL((void*)0)
6528};
6529
6530void register_pcapng(void)
6531{
6532 if (application_flavor_is_wireshark()) {
6533 pcapng_file_type_subtype = wtap_register_file_type_subtype(&wireshark_pcapng_info);
6534 } else {
6535 pcapng_file_type_subtype = wtap_register_file_type_subtype(&stratoshark_pcapng_info);
6536 }
6537
6538 wtap_register_backwards_compatibility_lua_name("PCAPNG",
6539 pcapng_file_type_subtype);
6540
6541 /* Setup the tables that will be used to handle custom block options */
6542
6543 /*
6544 * Create the table of option handlers for this block type.
6545 *
6546 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
6547 * so we use "g_direct_hash()" and "g_direct_equal()".
6548 */
6549 block_handlers = g_hash_table_new_full(g_direct_hash,
6550 g_direct_equal,
6551 NULL((void*)0), g_free);
6552
6553 custom_enterprise_handlers = g_hash_table_new_full(g_direct_hash,
6554 g_direct_equal,
6555 NULL((void*)0), g_free);
6556
6557 /* SHBs require special handling, so they don't have handlers here. */
6558 static pcapng_block_type_information_t SHB = { BLOCK_TYPE_SHB0x0A0D0D0A, NULL((void*)0), NULL((void*)0), NULL((void*)0), true1, NULL((void*)0) };
6559 SHB.option_handlers = pcapng_create_option_handler_table();
6560 register_pcapng_block_type_information(&SHB);
6561
6562 static pcapng_block_type_information_t IDB = { BLOCK_TYPE_IDB0x00000001, pcapng_read_if_descr_block, pcapng_process_idb, NULL((void*)0), true1, NULL((void*)0) };
6563 IDB.option_handlers = pcapng_create_option_handler_table();
6564 register_pcapng_block_type_information(&IDB);
6565
6566 static pcapng_block_type_information_t EPB = { BLOCK_TYPE_EPB0x00000006, pcapng_read_packet_block, NULL((void*)0), pcapng_write_enhanced_packet_block, false0, NULL((void*)0) };
6567 EPB.option_handlers = pcapng_create_option_handler_table();
6568 register_pcapng_block_type_information(&EPB);
6569
6570 static pcapng_block_type_information_t PB = { BLOCK_TYPE_PB0x00000002, pcapng_read_packet_block, NULL((void*)0), NULL((void*)0), false0, NULL((void*)0) };
6571 /* PBs and EPBs have the same options. */
6572 PB.option_handlers = EPB.option_handlers;
6573 register_pcapng_block_type_information(&PB);
6574
6575 static pcapng_block_type_information_t SPB = { BLOCK_TYPE_SPB0x00000003, pcapng_read_simple_packet_block, NULL((void*)0), pcapng_write_simple_packet_block, false0, NULL((void*)0) };
6576 /* SPBs don't support options */
6577 register_pcapng_block_type_information(&SPB);
6578
6579 static pcapng_block_type_information_t NRB = { BLOCK_TYPE_NRB0x00000004, pcapng_read_name_resolution_block, pcapng_process_nrb, NULL((void*)0), true1, NULL((void*)0) };
6580 NRB.option_handlers = pcapng_create_option_handler_table();
6581 register_pcapng_block_type_information(&NRB);
6582
6583 static pcapng_block_type_information_t ISB = { BLOCK_TYPE_ISB0x00000005, pcapng_read_interface_statistics_block, pcapng_process_isb, NULL((void*)0), true1, NULL((void*)0) };
6584 ISB.option_handlers = pcapng_create_option_handler_table();
6585 register_pcapng_block_type_information(&ISB);
6586
6587 static pcapng_block_type_information_t DSB = { BLOCK_TYPE_DSB0x0000000A, pcapng_read_decryption_secrets_block, pcapng_process_dsb, NULL((void*)0), true1, NULL((void*)0) };
6588 DSB.option_handlers = pcapng_create_option_handler_table();
6589 register_pcapng_block_type_information(&DSB);
6590
6591 static pcapng_block_type_information_t CB_COPY = { BLOCK_TYPE_CB_COPY0x00000BAD, pcapng_read_custom_block, NULL((void*)0), pcapng_write_custom_block_copy, false0, NULL((void*)0) };
6592 CB_COPY.option_handlers = pcapng_create_option_handler_table();
6593 register_pcapng_block_type_information(&CB_COPY);
6594
6595 static pcapng_block_type_information_t CB_NO_COPY = { BLOCK_TYPE_CB_NO_COPY0x40000BAD, pcapng_read_custom_block, NULL((void*)0), pcapng_write_custom_block_no_copy, false0, NULL((void*)0) };
6596 /* Copy and no-copy and CBs have the same options. */
6597 CB_NO_COPY.option_handlers = CB_COPY.option_handlers;
6598 register_pcapng_block_type_information(&CB_NO_COPY);
6599
6600 static pcapng_block_type_information_t SYSTEMD_JOURNAL_EXPORT = { BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT0x00000009, pcapng_read_systemd_journal_export_block, NULL((void*)0), pcapng_write_systemd_journal_export_block, false0, NULL((void*)0) };
6601 SYSTEMD_JOURNAL_EXPORT.option_handlers = pcapng_create_option_handler_table();
6602 register_pcapng_block_type_information(&SYSTEMD_JOURNAL_EXPORT);
6603}
6604
6605/*
6606 * Editor modelines - https://www.wireshark.org/tools/modelines.html
6607 *
6608 * Local variables:
6609 * c-basic-offset: 4
6610 * tab-width: 8
6611 * indent-tabs-mode: nil
6612 * End:
6613 *
6614 * vi: set shiftwidth=4 tabstop=8 expandtab:
6615 * :indentSize=4:tabSize=8:noTabs=true:
6616 */