Bug Summary

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