Bug Summary

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