Bug Summary

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