Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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