Bug Summary

File:wiretap/pcapng.c
Warning:line 3182, 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-08-31-100407-3933-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 if (*err == WTAP_ERR_REC_MALFORMED-28) {
2938 /* Allow the packet to be kept */
2939 wblock->rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NULL15;
2940 }
2941 else {
2942 return false0;
2943 }
2944 }
2945 }
2946 else
2947 {
2948 ws_debug("unknown pen %u", pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 2948, __func__, "unknown pen %u", pen); } } while (0)
;
2949 if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
2950 block_payload_length, err, err_info))
2951 return false0;
2952 }
2953
2954 wblock->rec->block = wblock->block;
2955 wblock->block = NULL((void*)0);
2956 /*
2957 * We return these to the caller in pcapng_read().
2958 */
2959 wblock->internal = false0;
2960
2961 return true1;
2962}
2963
2964static bool_Bool
2965pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh,
2966 uint32_t block_type _U___attribute__((unused)),
2967 uint32_t block_content_length,
2968 section_info_t *section_info _U___attribute__((unused)),
2969 wtapng_block_t *wblock,
2970 int *err, char **err_info)
2971{
2972 uint32_t entry_length;
2973 uint64_t rt_ts;
2974 bool_Bool have_ts = false0;
2975
2976 if (block_content_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE23) {
2977 *err = WTAP_ERR_BAD_FILE-13;
2978 *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)
2979 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)
2980 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)
;
2981 return false0;
2982 }
2983
2984 entry_length = block_content_length;
2985
2986 /* Includes padding bytes. */
2987 if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
2988 entry_length, err, err_info)) {
2989 return false0;
2990 }
2991
2992 /*
2993 * We don't have memmem available everywhere, so we get to add space for
2994 * a trailing \0 for strstr below.
2995 */
2996 ws_buffer_assure_space(&wblock->rec->data, entry_length+1);
2997
2998 char *buf_ptr = (char *) ws_buffer_start_ptr(&wblock->rec->data);
2999 while (entry_length > 0 && buf_ptr[entry_length-1] == '\0') {
3000 entry_length--;
3001 }
3002
3003 if (entry_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE23) {
3004 *err = WTAP_ERR_BAD_FILE-13;
3005 *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)
3006 entry_length, MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE)wmem_strdup_printf(((void*)0), "pcapng: entry length %u is too small (< %u)"
, entry_length, 23)
;
3007 return false0;
3008 }
3009
3010 ws_debug("entry_length %u", entry_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3010, __func__, "entry_length %u", entry_length); } } while
(0)
;
3011
3012 size_t rt_ts_len = strlen(SDJ__REALTIME_TIMESTAMP"__REALTIME_TIMESTAMP=");
3013
3014 buf_ptr[entry_length] = '\0';
3015 char *ts_pos = strstr(buf_ptr, SDJ__REALTIME_TIMESTAMP"__REALTIME_TIMESTAMP=");
3016
3017 if (!ts_pos) {
3018 ws_debug("no timestamp")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3018, __func__, "no timestamp"); } } while (0)
;
3019 } else if (ts_pos+rt_ts_len >= (char *) buf_ptr+entry_length) {
3020 ws_debug("timestamp past end of buffer")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3020, __func__, "timestamp past end of buffer"); } } while (
0)
;
3021 } else {
3022 const char *ts_end;
3023 have_ts = ws_strtou64(ts_pos+rt_ts_len, &ts_end, &rt_ts);
3024
3025 if (!have_ts) {
3026 ws_debug("invalid timestamp")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3026, __func__, "invalid timestamp"); } } while (0)
;
3027 }
3028 }
3029
3030 wtap_setup_systemd_journal_export_rec(wblock->rec);
3031 wblock->rec->rec_header.systemd_journal_export_header.record_len = entry_length;
3032 wblock->rec->presence_flags = WTAP_HAS_CAP_LEN0x00000002;
3033 if (have_ts) {
3034 wblock->rec->presence_flags |= WTAP_HAS_TS0x00000001;
3035 wblock->rec->tsprec = WTAP_TSPREC_USEC6;
3036 wblock->rec->ts.secs = (time_t) (rt_ts / 1000000);
3037 wblock->rec->ts.nsecs = (rt_ts % 1000000) * 1000;
3038 }
3039
3040 /*
3041 * We return these to the caller in pcapng_read().
3042 */
3043 wblock->internal = false0;
3044
3045 if (wth->file_encap == WTAP_ENCAP_NONE-2) {
3046 /*
3047 * Nothing (most notably an IDB) has set a file encap at this point.
3048 * Do so here.
3049 * XXX Should we set WTAP_ENCAP_SYSTEMD_JOURNAL if appropriate?
3050 */
3051 wth->file_encap = WTAP_ENCAP_PER_PACKET-1;
3052 }
3053
3054 return true1;
3055}
3056
3057static bool_Bool
3058pcapng_read_unknown_block(FILE_T fh, guint32 block_content_length,
3059 section_info_t *section_info _U___attribute__((unused)), wtapng_block_t *wblock,
3060 int *err, char **err_info)
3061{
3062 /* Skip the block content. */
3063 if (!wtap_read_bytes(fh, NULL((void*)0), block_content_length, err, err_info)) {
3064 return false0;
3065 }
3066
3067 /*
3068 * We're skipping this, so we won't return these to the caller
3069 * in pcapng_read().
3070 */
3071 wblock->internal = true1;
3072
3073 return true1;
3074}
3075
3076static bool_Bool
3077pcapng_read_and_check_block_trailer(FILE_T fh, pcapng_block_header_t *bh,
3078 section_info_t *section_info,
3079 int *err, char **err_info)
3080{
3081 uint32_t block_total_length;
3082
3083 /* sanity check: first and second block lengths must match */
3084 if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
3085 err, err_info)) {
3086 ws_debug("couldn't read second block length")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3086, __func__, "couldn't read second block length"); } } while
(0)
;
3087 return false0;
3088 }
3089
3090 if (section_info->byte_swapped)
3091 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))))
;
3092
3093 /*
3094 * According to the pcapng spec, this should equal the block total
3095 * length value at the beginning of the block, which MUST (in the
3096 * IANA sense) be a multiple of 4.
3097 *
3098 * We round the value at the beginning of the block to a multiple
3099 * of 4, so do so with this value as well. This *does* mean that
3100 * the two values, if they're not both multiples of 4, can differ
3101 * and this code won't detect that, but we're already not detecting
3102 * non-multiple-of-4 total lengths.
3103 */
3104 block_total_length = WS_ROUNDUP_4(block_total_length)(((block_total_length) + ((unsigned)(4U-1U))) & (~((unsigned
)(4U-1U))))
;
3105
3106 if (block_total_length != bh->block_total_length) {
3107 *err = WTAP_ERR_BAD_FILE-13;
3108 *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)
3109 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)
;
3110 return false0;
3111 }
3112 return true1;
3113}
3114
3115static bool_Bool
3116pcapng_read_block(wtap *wth, FILE_T fh,
3117 section_info_t *section_info,
3118 section_info_t *new_section_info,
3119 wtapng_block_t *wblock,
3120 int *err, char **err_info)
3121{
3122 pcapng_block_type_information_t *handler;
3123 block_return_val ret;
3124 pcapng_block_header_t bh;
3125 uint32_t block_content_length;
3126
3127 wblock->block = NULL((void*)0);
3128
3129 /* Try to read the (next) block header */
3130 if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
3131 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3131, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
3132 return false0;
3133 }
3134
3135 /*
3136 * SHBs have to be treated differently from other blocks, because
3137 * the byte order of the fields in the block can only be determined
3138 * by looking at the byte-order magic number inside the block, not
3139 * by using the byte order of the section to which it belongs, as
3140 * it is the block that *defines* the byte order of the section to
3141 * which it belongs.
3142 */
3143 if (bh.block_type == BLOCK_TYPE_SHB0x0A0D0D0A) {
3144 /*
3145 * BLOCK_TYPE_SHB has the same value regardless of byte order,
3146 * so we don't need to byte-swap it.
3147 *
3148 * We *might* need to byte-swap the total length, but we
3149 * can't determine whether we do until we look inside the
3150 * block and find the byte-order magic number, so we rely
3151 * on pcapng_read_section_header_block() to do that and
3152 * to swap the total length (as it needs to get the total
3153 * length in the right byte order in order to read the
3154 * entire block).
3155 */
3156 wblock->type = bh.block_type;
3157
3158 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"
, 3158, __func__, "block_type BLOCK_TYPE_SHB (0x%08x)", bh.block_type
); } } while (0)
;
3159
3160 /*
3161 * Fill in the section_info_t passed to us for use when
3162 * there's a new SHB; don't overwrite the existing SHB,
3163 * if there is one.
3164 */
3165 ret = pcapng_read_section_header_block(fh, &bh, new_section_info,
3166 wblock, err, err_info);
3167 if (ret != PCAPNG_BLOCK_OK) {
3168 return false0;
3169 }
3170
3171 /*
3172 * This is the current section; use its byte order, not that
3173 * of the section pointed to by section_info (which could be
3174 * null).
3175 */
3176 section_info = new_section_info;
3177
3178 /*
3179 * Get information for this block type, for use when setting the
3180 * internal flag.
3181 */
3182 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
3183 } else {
3184 /*
3185 * Not an SHB.
3186 */
3187 if (section_info->byte_swapped) {
3188 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))))
;
3189 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))))
;
3190 }
3191
3192 if (bh.block_total_length < MIN_BLOCK_SIZE((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t))
)
) {
3193 *err = WTAP_ERR_BAD_FILE-13;
3194 *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))))
3195 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))))
;
3196 return false0;
3197 }
3198
3199 /*
3200 * Add padding bytes to the block total length.
3201 * (The "block total length" fields of some example files
3202 * don't contain the packet data padding bytes!)
3203 *
3204 * For all block types currently defined in the pcapng
3205 * specification, the portion of the block that precedes
3206 * the options is, if necessary, padded to be a multiple
3207 * of 4 octets, the header of an option is 4 octets long,
3208 * and the value of an option is also padded to be a
3209 * multiple of 4 octets, so the total length of a block
3210 * is always a multiple of 4 octets.
3211 *
3212 * If you have defined a block where that is not true, you
3213 * have violated the pcapng specification - where it says
3214 * that "[The value of the Block Total Length] MUST be a
3215 * multiple of 4.", with MUST as described in BCP 14 (RFC 2119/
3216 * RFC 8174).
3217 *
3218 * Therefore, if adjusting the block total length causes the
3219 * code to read your block type not to work, that's your
3220 * problem. It's bad enough that some blocks were written
3221 * out with the block total length not including the padding.
3222 * (Please note that libpcap is less forgiving that we are;
3223 * it reports an error if the block total length isn't a
3224 * multiple of 4.)
3225 */
3226 bh.block_total_length = WS_ROUNDUP_4(bh.block_total_length)(((bh.block_total_length) + ((unsigned)(4U-1U))) & (~((unsigned
)(4U-1U))))
;
3227
3228 wblock->type = bh.block_type;
3229
3230 ws_noisy("block_type 0x%08x", bh.block_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3230, __func__, "block_type 0x%08x", bh.block_type); } } while
(0)
;
3231
3232 /* Don't try to allocate memory for a huge number of options, as
3233 that might fail and, even if it succeeds, it might not leave
3234 any address space or memory+backing store for anything else.
3235
3236 We do that by imposing a maximum block size of MAX_BLOCK_SIZE. */
3237 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)
) {
3238 *err = WTAP_ERR_BAD_FILE-13;
3239 *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))
3240 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))
;
3241 return false0;
3242 }
3243
3244 /*
3245 * Length of the contents of the block.
3246 */
3247 block_content_length = bh.block_total_length - MIN_BLOCK_SIZE((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t))
)
;
3248
3249 /*
3250 * Do we have a handler for this block type?
3251 */
3252 handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(bh.block_type)((gpointer) (gulong) (bh.block_type)));
3253 if (handler != NULL((void*)0)) {
3254 /* Yes - call it to read this block type. */
3255 if (!handler->reader(wth, fh, bh.block_type,
3256 block_content_length, section_info,
3257 wblock, err, err_info))
3258 return false0;
3259 } else {
3260 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"
, 3261, __func__, "Unknown block_type: 0x%08x (block ignored), block total length %u"
, bh.block_type, bh.block_total_length); } } while (0)
3261 bh.block_type, bh.block_total_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3261, __func__, "Unknown block_type: 0x%08x (block ignored), block total length %u"
, bh.block_type, bh.block_total_length); } } while (0)
;
3262 if (!pcapng_read_unknown_block(fh, block_content_length,
3263 section_info, wblock,
3264 err, err_info))
3265 return false0;
3266 }
3267 }
3268
3269 /*
3270 * Read and check the block trailer.
3271 */
3272 if (!pcapng_read_and_check_block_trailer(fh, &bh, section_info, err, err_info)) {
3273 /* Not readable or not valid. */
3274 return false0;
3275 }
3276
3277 return true1;
3278}
3279
3280static void
3281pcapng_process_shb(wtap *wth, pcapng_t *pcapng, section_info_t new_section, wtapng_block_t *wblock, const int64_t *data_offset)
3282{
3283 /*
3284 * Add this SHB to the table of SHBs.
3285 */
3286 g_array_append_val(wth->shb_hdrs, wblock->block)g_array_append_vals (wth->shb_hdrs, &(wblock->block
), 1)
;
3287 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)
;
3288
3289 /*
3290 * Update the current section number, and add
3291 * the updated section_info_t to the array of
3292 * section_info_t's for this file.
3293 */
3294 pcapng->current_section_number++;
3295 new_section.interfaces = g_array_new(false0, false0, sizeof(interface_info_t));
3296 new_section.shb_off = *data_offset;
3297 g_array_append_val(pcapng->sections, new_section)g_array_append_vals (pcapng->sections, &(new_section),
1)
;
3298}
3299
3300/* Process an IDB that we've just read. The contents of wblock are copied as needed. */
3301static bool_Bool
3302pcapng_process_idb(wtap *wth, section_info_t *section_info,
3303 wtapng_block_t *wblock)
3304{
3305 wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
3306 interface_info_t iface_info;
3307 wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data),
3308 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3309 uint8_t if_fcslen;
3310
3311 wtap_block_copy(int_data, wblock->block);
3312
3313 /* Interface statistics */
3314 if_descr_mand->num_stat_entries = 0;
3315 if_descr_mand->interface_statistics = NULL((void*)0);
3316
3317 wtap_add_idb(wth, int_data);
3318
3319 iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
3320 iface_info.snap_len = wblock_if_descr_mand->snap_len;
3321 iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
3322 iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
3323
3324 /*
3325 * Did we get an FCS length option?
3326 */
3327 if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_FCSLEN13,
3328 &if_fcslen) == WTAP_OPTTYPE_SUCCESS) {
3329 /*
3330 * Yes.
3331 */
3332 iface_info.fcslen = if_fcslen;
3333 } else {
3334 /*
3335 * No. Mark the FCS length as unknown.
3336 */
3337 iface_info.fcslen = -1;
3338 }
3339
3340 /*
3341 * Did we get a time stamp offset option?
3342 */
3343 if (wtap_block_get_int64_option_value(wblock->block, OPT_IDB_TSOFFSET14,
3344 &iface_info.tsoffset) != WTAP_OPTTYPE_SUCCESS) {
3345 /*
3346 * No. Default to 0, meaning that time stamps in the file are
3347 * absolute time stamps.
3348 */
3349 iface_info.tsoffset = 0;
3350 }
3351
3352 /*
3353 * Did we get a time stamp precision option?
3354 */
3355 iface_info.tsresol_binary = 0;
3356 uint8_t if_tsresol;
3357 if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_TSRESOL9,
3358 &if_tsresol) == WTAP_OPTTYPE_SUCCESS) {
3359 /* Is the timestamp resolution a power of two? */
3360 if (if_tsresol & 0x80) {
3361 /* Note that 0x80 and 0x80 mean the same thing, as 2^-0 == 10^-0 */
3362 iface_info.tsresol_binary = if_tsresol & 0x7F;
3363 }
3364 }
3365 g_array_append_val(section_info->interfaces, iface_info)g_array_append_vals (section_info->interfaces, &(iface_info
), 1)
;
3366
3367 wtap_block_unref(wblock->block);
3368
3369 return true1;
3370}
3371
3372/* Process an NRB that we have just read. */
3373static bool_Bool
3374pcapng_process_nrb(wtap *wth, section_info_t *section_info _U___attribute__((unused)),
3375 wtapng_block_t *wblock)
3376{
3377 wtapng_process_nrb(wth, wblock->block);
3378
3379 if (wth->nrbs == NULL((void*)0)) {
3380 wth->nrbs = g_array_new(false0, false0, sizeof(wtap_block_t));
3381 }
3382 /* Store NRB such that it can be saved by the dumper. */
3383 g_array_append_val(wth->nrbs, wblock->block)g_array_append_vals (wth->nrbs, &(wblock->block), 1
)
;
3384 /* Do not free wblock->block, it is consumed above */
3385
3386 return true1;
3387}
3388
3389/* Process a DSB that we have just read. */
3390static bool_Bool
3391pcapng_process_dsb(wtap *wth, section_info_t *section_info _U___attribute__((unused)),
3392 wtapng_block_t *wblock)
3393{
3394 wtapng_process_dsb(wth, wblock->block);
3395
3396 /* Store DSB such that it can be saved by the dumper. */
3397 g_array_append_val(wth->dsbs, wblock->block)g_array_append_vals (wth->dsbs, &(wblock->block), 1
)
;
3398
3399 /* Do not free wblock->block, it is consumed above */
3400
3401 return true1;
3402}
3403
3404/* Process a ISB that we have just read. */
3405static bool_Bool
3406pcapng_process_isb(wtap *wth, section_info_t *section_info _U___attribute__((unused)),
3407 wtapng_block_t *wblock)
3408{
3409 wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
3410 wtap_block_t if_stats;
3411 wtap_block_t wtapng_if_descr;
3412 wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
3413
3414 /*
3415 * Another interface statistics report
3416 *
3417 * XXX - given that they're reports, we should be
3418 * supplying them in read calls, and displaying them
3419 * in the "packet" list, so you can see what the
3420 * statistics were *at the time when the report was
3421 * made*.
3422 *
3423 * The statistics from the *last* ISB could be displayed
3424 * in the summary, but if there are packets after the
3425 * last ISB, that could be misleading.
3426 *
3427 * If we only display them if that ISB has an isb_endtime
3428 * option, which *should* only appear when capturing ended
3429 * on that interface (so there should be no more packet
3430 * blocks or ISBs for that interface after that point,
3431 * that would be the best way of showing "summary"
3432 * statistics.
3433 */
3434 ws_debug("block type BLOCK_TYPE_ISB")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3434, __func__, "block type BLOCK_TYPE_ISB"); } } while (0)
;
3435 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3436 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
3437 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"
, 3438, __func__, "BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces"
, if_stats_mand_block->interface_id); } } while (0)
3438 if_stats_mand_block->interface_id)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3438, __func__, "BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces"
, if_stats_mand_block->interface_id); } } while (0)
;
3439 } else {
3440 /* Get the interface description */
3441 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)])
;
3442 wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
3443 if (wtapng_if_descr_mand->num_stat_entries == 0) {
3444 /* First ISB found, no previous entry */
3445 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"
, 3445, __func__, "block type BLOCK_TYPE_ISB. First ISB found, no previous entry"
); } } while (0)
;
3446 wtapng_if_descr_mand->interface_statistics = g_array_new(false0, false0, sizeof(wtap_block_t));
3447 }
3448
3449 if_stats = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
3450 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
3451 if_stats_mand->interface_id = if_stats_mand_block->interface_id;
3452 if_stats_mand->ts_high = if_stats_mand_block->ts_high;
3453 if_stats_mand->ts_low = if_stats_mand_block->ts_low;
3454
3455 wtap_block_copy(if_stats, wblock->block);
3456 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)
;
3457 wtapng_if_descr_mand->num_stat_entries++;
3458 }
3459 wtap_block_unref(wblock->block);
3460 return true1;
3461}
3462
3463static void
3464pcapng_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)
3465{
3466 if (wblock->type == BLOCK_TYPE_SHB0x0A0D0D0A) {
3467 pcapng_process_shb(wth, pcapng, new_section, wblock, data_offset);
3468 } else {
3469 pcapng_block_type_information_t* handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(wblock->type)((gpointer) (gulong) (wblock->type)));
3470
3471 if (handler != NULL((void*)0)) {
3472 /* XXX - Is it okay to not have a processor? */
3473 if (handler->processor != NULL((void*)0)) {
3474 handler->processor(wth, section, wblock);
3475 }
3476 } else {
3477 /* XXX - improve handling of "unknown" blocks */
3478 ws_debug("Unknown block type 0x%08x", wblock->type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3478, __func__, "Unknown block type 0x%08x", wblock->type
); } } while (0)
;
3479 }
3480 }
3481}
3482
3483/* classic wtap: open capture file */
3484wtap_open_return_val
3485pcapng_open(wtap *wth, int *err, char **err_info)
3486{
3487 wtapng_block_t wblock;
3488 pcapng_t *pcapng;
3489 pcapng_block_header_t bh;
3490 int64_t saved_offset;
3491 section_info_t first_section, new_section, *current_section;
3492
3493 ws_debug("opening file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3493, __func__, "opening file"); } } while (0)
;
3494 /*
3495 * Read first block.
3496 *
3497 * First, try to read the block header.
3498 */
3499 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3500 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3500, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
3501 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12) {
3502 /*
3503 * Short read or EOF.
3504 *
3505 * We're reading this as part of an open, so
3506 * the file is too short to be a pcapng file.
3507 */
3508 *err = 0;
3509 g_free(*err_info);
3510 *err_info = NULL((void*)0);
3511 return WTAP_OPEN_NOT_MINE;
3512 }
3513 return WTAP_OPEN_ERROR;
3514 }
3515
3516 /*
3517 * If this is a pcapng file, the first block must be a
3518 * Section Header Block.
3519 */
3520 if (bh.block_type != BLOCK_TYPE_SHB0x0A0D0D0A) {
3521 /*
3522 * Not an SHB, so this isn't a pcapng file.
3523 *
3524 * XXX - check for damage from transferring a file
3525 * between Windows and UN*X as text rather than
3526 * binary data?
3527 */
3528 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"
, 3528, __func__, "first block type 0x%08x not SHB", bh.block_type
); } } while (0)
;
3529 return WTAP_OPEN_NOT_MINE;
3530 }
3531
3532 ws_debug("got an SHB")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3532, __func__, "got an SHB"); } } while (0)
;
3533
3534 /*
3535 * Now try to read the block body, filling in the section_info_t
3536 * for the first section.
3537 */
3538 wblock.type = bh.block_type;
3539 wblock.block = NULL((void*)0);
3540 /* we don't expect any packet blocks yet */
3541 wblock.rec = NULL((void*)0);
3542
3543 switch (pcapng_read_section_header_block(wth->fh, &bh, &first_section,
3544 &wblock, err, err_info)) {
3545 case PCAPNG_BLOCK_OK:
3546 /* No problem */
3547 break;
3548
3549 case PCAPNG_BLOCK_NOT_SHB:
3550 /* This doesn't look like an SHB, so this isn't a pcapng file. */
3551 wtap_block_unref(wblock.block);
3552 *err = 0;
3553 g_free(*err_info);
3554 *err_info = NULL((void*)0);
3555 return WTAP_OPEN_NOT_MINE;
3556
3557 case PCAPNG_BLOCK_ERROR:
3558 wtap_block_unref(wblock.block);
3559 if (*err == WTAP_ERR_SHORT_READ-12) {
3560 /*
3561 * Short read.
3562 *
3563 * We're reading this as part of an open, so
3564 * the file is too short to be a pcapng file.
3565 */
3566 *err = 0;
3567 g_free(*err_info);
3568 *err_info = NULL((void*)0);
3569 return WTAP_OPEN_NOT_MINE;
3570 }
3571 /* An I/O error. */
3572 return WTAP_OPEN_ERROR;
3573 }
3574
3575 /*
3576 * Read and check the block trailer.
3577 */
3578 if (!pcapng_read_and_check_block_trailer(wth->fh, &bh, &first_section, err, err_info)) {
3579 /* Not readable or not valid. */
3580 wtap_block_unref(wblock.block);
3581 return WTAP_OPEN_ERROR;
3582 }
3583
3584 /*
3585 * At this point, we've decided this is a pcapng file, not
3586 * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
3587 * past this point.
3588 *
3589 * Copy the SHB that we just read to the first entry in the table of
3590 * SHBs for this file.
3591 */
3592 wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (wth->shb_hdrs)->data) [(0)]
)
, wblock.block);
3593 wtap_block_unref(wblock.block);
3594 wblock.block = NULL((void*)0);
3595
3596 wth->file_encap = WTAP_ENCAP_NONE-2;
3597 wth->snapshot_length = 0;
3598 wth->file_tsprec = WTAP_TSPREC_UNKNOWN-2;
3599 pcapng = g_new(pcapng_t, 1)((pcapng_t *) g_malloc_n ((1), sizeof (pcapng_t)));
3600 wth->priv = (void *)pcapng;
3601 /*
3602 * We're currently processing the first section; as this is written
3603 * in C, that's section 0. :-)
3604 */
3605 pcapng->current_section_number = 0;
3606
3607 /*
3608 * Create the array of interfaces for the first section.
3609 */
3610 first_section.interfaces = g_array_new(false0, false0, sizeof(interface_info_t));
3611
3612 /*
3613 * The first section is at the very beginning of the file.
3614 */
3615 first_section.shb_off = 0;
3616
3617 /*
3618 * Allocate the sections table with space reserved for the first
3619 * section, and add that section.
3620 */
3621 pcapng->sections = g_array_sized_new(false0, false0, sizeof(section_info_t), 1);
3622 g_array_append_val(pcapng->sections, first_section)g_array_append_vals (pcapng->sections, &(first_section
), 1)
;
3623
3624 wth->subtype_read = pcapng_read;
3625 wth->subtype_seek_read = pcapng_seek_read;
3626 wth->subtype_close = pcapng_close;
3627 wth->file_type_subtype = pcapng_file_type_subtype;
3628
3629 /* Always initialize the lists of Decryption Secret Blocks, Name
3630 * Resolution Blocks, and Sysdig meta event blocks such that a
3631 * wtap_dumper can refer to them right after opening the capture
3632 * file. */
3633 wth->dsbs = g_array_new(false0, false0, sizeof(wtap_block_t));
3634 wth->nrbs = g_array_new(false0, false0, sizeof(wtap_block_t));
3635 wth->meta_events = g_array_new(false0, false0, sizeof(wtap_block_t));
3636
3637 /* Most other capture types (such as pcap) support a single link-layer
3638 * type, indicated in the header, and don't support WTAP_ENCAP_PER_PACKET.
3639 * Most programs that write such capture files want to know the link-layer
3640 * type when initially opening the destination file, and (unlike Wireshark)
3641 * don't want to read the entire source file to find all the link-layer
3642 * types before writing (particularly if reading from a pipe or FIFO.)
3643 *
3644 * In support of this, read all the internally-processed, non packet
3645 * blocks that appear before the first packet block (EPB or SPB).
3646 *
3647 * Note that such programs will still have issues when trying to read
3648 * a pcapng that has a new link-layer type in an IDB in the middle of
3649 * the file, as they will discover in the middle that no, they can't
3650 * successfully write the output file as desired.
3651 *
3652 * If this is a live capture, and we're reading the initially written
3653 * header, we'll loop until we reach EOF. (If compressed, it might
3654 * also set WTAP_ERR_SHORT_READ from the stream / frame end not being
3655 * present until the file is closed.) So we'll need to clear that at
3656 * some point before reading packets.
3657 */
3658 while (!file_eof(wth->fh)) {
3659 /* peek at next block */
3660 /* Try to read the (next) block header */
3661 saved_offset = file_tell(wth->fh);
3662 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3663 if (*err == 0) {
3664 /* EOF */
3665 ws_debug("No more blocks available...")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3665, __func__, "No more blocks available..."); } } while (
0)
;
3666 break;
3667 }
3668 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"
, 3669, __func__, "Check for more initial blocks, wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
3669 *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3669, __func__, "Check for more initial blocks, wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
3670 return WTAP_OPEN_ERROR;
3671 }
3672
3673 /* go back to where we were */
3674 file_seek(wth->fh, saved_offset, SEEK_SET0, err);
3675
3676 /*
3677 * Get a pointer to the current section's section_info_t.
3678 */
3679 current_section = &g_array_index(pcapng->sections, section_info_t,(((section_info_t*) (void *) (pcapng->sections)->data) [
(pcapng->current_section_number)])
3680 pcapng->current_section_number)(((section_info_t*) (void *) (pcapng->sections)->data) [
(pcapng->current_section_number)])
;
3681
3682 if (current_section->byte_swapped) {
3683 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))))
;
3684 }
3685
3686 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"
, 3687, __func__, "Check for more initial internal blocks, block_type 0x%08x"
, bh.block_type); } } while (0)
3687 bh.block_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3687, __func__, "Check for more initial internal blocks, block_type 0x%08x"
, bh.block_type); } } while (0)
;
3688
3689 if (!get_block_type_internal(bh.block_type)) {
3690 break; /* Next block has to be returned in pcap_read */
3691 }
3692 /* Note that some custom block types, unlike packet blocks,
3693 * don't need to be preceded by an IDB and so theoretically
3694 * we could skip past them here. However, then there's no good
3695 * way to both later return those blocks in pcap_read() and
3696 * ensure that we don't read and process the IDBs (and other
3697 * internal block types) a second time.
3698 *
3699 * pcapng_read_systemd_journal_export_block() sets the file level
3700 * link-layer type if it's still UNKNOWN. We could do the same here
3701 * for it and possibly other types based on block type, even without
3702 * reading them.
3703 */
3704 if (!pcapng_read_block(wth, wth->fh, current_section,
3705 &new_section, &wblock, err, err_info)) {
3706 wtap_block_unref(wblock.block);
3707 if (*err == 0) {
3708 ws_debug("No more initial blocks available...")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3708, __func__, "No more initial blocks available..."); } }
while (0)
;
3709 break;
3710 } else {
3711 ws_debug("couldn't read block")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3711, __func__, "couldn't read block"); } } while (0)
;
3712 return WTAP_OPEN_ERROR;
3713 }
3714 }
3715 pcapng_process_internal_block(wth, pcapng, current_section, new_section, &wblock, &saved_offset);
3716 ws_debug("Read IDB number_of_interfaces %u, wtap_encap %i",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3717, __func__, "Read IDB number_of_interfaces %u, wtap_encap %i"
, wth->interface_data->len, wth->file_encap); } } while
(0)
3717 wth->interface_data->len, wth->file_encap)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3717, __func__, "Read IDB number_of_interfaces %u, wtap_encap %i"
, wth->interface_data->len, wth->file_encap); } } while
(0)
;
3718 }
3719 return WTAP_OPEN_MINE;
3720}
3721
3722/* classic wtap: read packet */
3723static bool_Bool
3724pcapng_read(wtap *wth, wtap_rec *rec, int *err, char **err_info,
3725 int64_t *data_offset)
3726{
3727 pcapng_t *pcapng = (pcapng_t *)wth->priv;
3728 section_info_t *current_section, new_section;
3729 wtapng_block_t wblock;
3730
3731 wblock.rec = rec;
3732
3733 /* read next block */
3734 while (1) {
3735 *data_offset = file_tell(wth->fh);
3736 ws_noisy("data_offset is %" PRId64, *data_offset)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3736, __func__, "data_offset is %" "l" "d", *data_offset); }
} while (0)
;
3737
3738 /*
3739 * Get the section_info_t for the current section.
3740 */
3741 current_section = &g_array_index(pcapng->sections, section_info_t,(((section_info_t*) (void *) (pcapng->sections)->data) [
(pcapng->current_section_number)])
3742 pcapng->current_section_number)(((section_info_t*) (void *) (pcapng->sections)->data) [
(pcapng->current_section_number)])
;
3743
3744 /*
3745 * Read the next block.
3746 */
3747 if (!pcapng_read_block(wth, wth->fh, current_section,
3748 &new_section, &wblock, err, err_info)) {
3749 ws_noisy("data_offset is finally %" PRId64, *data_offset)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3749, __func__, "data_offset is finally %" "l" "d", *data_offset
); } } while (0)
;
3750 ws_debug("couldn't read packet block")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3750, __func__, "couldn't read packet block"); } } while (0
)
;
3751 wtap_block_unref(wblock.block);
3752 return false0;
3753 }
3754
3755 if (!wblock.internal) {
3756 /*
3757 * This is a block type we return to the caller to process.
3758 */
3759 ws_noisy("rec_type %u", wblock.rec->rec_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3759, __func__, "rec_type %u", wblock.rec->rec_type); } }
while (0)
;
3760 break;
3761 }
3762
3763 /*
3764 * This is a block type we process internally, rather than
3765 * returning it for the caller to process.
3766 */
3767 pcapng_process_internal_block(wth, pcapng, current_section, new_section, &wblock, data_offset);
3768 }
3769
3770 /*ws_debug("Read length: %u Packet length: %u", bytes_read, rec->rec_header.packet_header.caplen);*/
3771 ws_noisy("data_offset is finally %" PRId64, *data_offset)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3771, __func__, "data_offset is finally %" "l" "d", *data_offset
); } } while (0)
;
3772
3773 /* Provide the section number */
3774 rec->presence_flags |= WTAP_HAS_SECTION_NUMBER0x00000008;
3775 rec->section_number = pcapng->current_section_number;
3776
3777 return true1;
3778}
3779
3780/* classic wtap: seek to file position and read packet */
3781static bool_Bool
3782pcapng_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec,
3783 int *err, char **err_info)
3784{
3785 pcapng_t *pcapng = (pcapng_t *)wth->priv;
3786 section_info_t *section_info, new_section;
3787 wtapng_block_t wblock;
3788
3789
3790 /* seek to the right file position */
3791 if (file_seek(wth->random_fh, seek_off, SEEK_SET0, err) < 0) {
3792 return false0; /* Seek error */
3793 }
3794 ws_noisy("reading at offset %" PRIu64, seek_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/pcapng.c"
, 3794, __func__, "reading at offset %" "l" "u", seek_off); }
} while (0)
;
3795
3796 /*
3797 * Find the section_info_t for the section in which this block
3798 * appears.
3799 *
3800 * First, make sure we have at least one section; if we don't, that's
3801 * an internal error.
3802 */
3803 ws_assert(pcapng->sections->len >= 1)do { if ((1) && !(pcapng->sections->len >= 1
)) ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/pcapng.c"
, 3803, __func__, "assertion failed: %s", "pcapng->sections->len >= 1"
); } while (0)
;
3804
3805 /*
3806 * Now scan backwards through the array to find the first section
3807 * that begins at or before the offset of the block we're reading.
3808 *
3809 * Yes, that's O(n) in the number of blocks, but we're unlikely to
3810 * have many sections and pretty unlikely to have more than one.
3811 */
3812 unsigned section_number = pcapng->sections->len - 1;
3813 for (;;) {
3814 section_info = &g_array_index(pcapng->sections, section_info_t,(((section_info_t*) (void *) (pcapng->sections)->data) [
(section_number)])
3815 section_number)(((section_info_t*) (void *) (pcapng->sections)->data) [
(section_number)])
;
3816 if (section_info->shb_off <= seek_off)
3817 break;
3818
3819 /*
3820 * If that's section 0, something's wrong; that section should
3821 * have an offset of 0.
3822 */
3823 ws_assert(section_number != 0)do { if ((1) && !(section_number != 0)) ws_log_fatal_full
("Wiretap", LOG_LEVEL_ERROR, "wiretap/pcapng.c", 3823, __func__
, "assertion failed: %s", "section_number != 0"); } while (0)
;
3824 section_number--;
3825 }
3826
3827 wblock.rec = rec;
3828
3829 /* read the block */
3830 if (!pcapng_read_block(wth, wth->random_fh, section_info,
3831 &new_section, &wblock, err, err_info)) {
3832 ws_debug("couldn't read packet block (err=%d).", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3832, __func__, "couldn't read packet block (err=%d).", *err
); } } while (0)
;
3833 wtap_block_unref(wblock.block);
3834 return false0;
3835 }
3836
3837 /* block must not be one we process internally rather than supplying */
3838 if (wblock.internal) {
3839 ws_debug("block type 0x%08x is not one we return",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3840, __func__, "block type 0x%08x is not one we return", wblock
.type); } } while (0)
3840 wblock.type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3840, __func__, "block type 0x%08x is not one we return", wblock
.type); } } while (0)
;
3841 wtap_block_unref(wblock.block);
3842 return false0;
3843 }
3844
3845 wtap_block_unref(wblock.block);
3846
3847 /* Provide the section number */
3848 rec->presence_flags |= WTAP_HAS_SECTION_NUMBER0x00000008;
3849 rec->section_number = section_number;
3850
3851 return true1;
3852}
3853
3854/* classic wtap: close capture file */
3855static void
3856pcapng_close(wtap *wth)
3857{
3858 pcapng_t *pcapng = (pcapng_t *)wth->priv;
3859
3860 ws_debug("closing file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 3860, __func__, "closing file"); } } while (0)
;
3861
3862 /*
3863 * Free up the interfaces tables for all the sections.
3864 */
3865 for (unsigned i = 0; i < pcapng->sections->len; i++) {
3866 section_info_t *section_info = &g_array_index(pcapng->sections,(((section_info_t*) (void *) (pcapng->sections)->data) [
(i)])
3867 section_info_t, i)(((section_info_t*) (void *) (pcapng->sections)->data) [
(i)])
;
3868 g_array_free(section_info->interfaces, true1);
3869 if (section_info->custom_block_data != NULL((void*)0))
3870 g_hash_table_destroy(section_info->custom_block_data);
3871 if (section_info->local_block_data != NULL((void*)0))
3872 g_hash_table_destroy(section_info->local_block_data);
3873 }
3874 g_array_free(pcapng->sections, true1);
3875}
3876
3877/*
3878 * As it says at the top of the file, an option sizer "calculates how many
3879 * bytes the option's data requires, not including any padding bytes."
3880 * Callers are responsible for rounding up to multiples of 4 bytes.
3881 * compute_block_options_size() does that for each option in the block;
3882 * option writers that call an option sizer (which helps ensure that the
3883 * sizes are internally consistent) should do the same.
3884 */
3885
3886static uint32_t pcapng_compute_string_option_size(wtap_optval_t *optval)
3887{
3888 uint32_t size = 0;
3889
3890 size = (uint32_t)strlen(optval->stringval);
3891
3892 if (size > 65535) {
3893 /*
3894 * Too big to fit in the option.
3895 * Don't write anything.
3896 *
3897 * XXX - truncate it? Report an error?
3898 */
3899 size = 0;
3900 }
3901
3902 return size;
3903}
3904
3905#if 0
3906static uint32_t pcapng_compute_bytes_option_size(wtap_optval_t *optval)
3907{
3908 uint32_t size = 0;
3909
3910 size = (uint32_t)g_bytes_get_size(optval->byteval) & 0xffff;
3911
3912 return size;
3913}
3914#endif
3915
3916static uint32_t pcapng_compute_if_filter_option_size(wtap_optval_t *optval)
3917{
3918 if_filter_opt_t* filter = &optval->if_filterval;
3919 uint32_t size;
3920
3921 if (filter->type == if_filter_pcap) {
3922 size = (uint32_t)(strlen(filter->data.filter_str) + 1) & 0xffff;
3923 } else if (filter->type == if_filter_bpf) {
3924 size = (uint32_t)((filter->data.bpf_prog.bpf_prog_len * 8) + 1) & 0xffff;
3925 } else {
3926 /* Unknown type; don't write it */
3927 size = 0;
3928 }
3929 return size;
3930}
3931
3932static uint32_t pcapng_compute_custom_string_option_size(wtap_optval_t *optval)
3933{
3934 uint32_t size = 0;
3935
3936 size = (uint32_t)strlen(optval->custom_stringval.string) & 0xffff;
3937
3938 return size;
3939}
3940
3941static uint32_t pcapng_compute_custom_binary_option_size(wtap_optval_t *optval)
3942{
3943 size_t size;
3944
3945 /* PEN */
3946 size = sizeof(uint32_t) + optval->custom_binaryval.data.custom_data_len;
3947
3948 if (size > 65535) {
3949 size = 65535;
3950 }
3951
3952 return (uint32_t)size;
3953}
3954
3955static uint32_t pcapng_compute_packet_hash_option_size(wtap_optval_t *optval)
3956{
3957 packet_hash_opt_t* hash = &optval->packet_hash;
3958 uint32_t size;
3959
3960 switch (hash->type) {
3961 case OPT_HASH_CRC322:
3962 size = 4;
3963 break;
3964 case OPT_HASH_MD53:
3965 size = 16;
3966 break;
3967 case OPT_HASH_SHA14:
3968 size = 20;
3969 break;
3970 case OPT_HASH_TOEPLITZ5:
3971 size = 4;
3972 break;
3973 default:
3974 /* 2COMP and XOR size not defined in standard (yet) */
3975 size = hash->hash_bytes->len;
3976 break;
3977 }
3978 /* XXX - What if the size of the hash bytes doesn't match the
3979 * expected size? We can:
3980 * 1) Return 0, and omit it when writing
3981 * 2) Return hash_bytes->len, and write it out exactly as we have it
3982 * 3) Return the correct size here, and when writing err or possibly
3983 * truncate.
3984 */
3985 /* Account for the size of the algorithm type field. */
3986 size += 1;
3987
3988 return size;
3989}
3990
3991static uint32_t pcapng_compute_packet_verdict_option_size(wtap_optval_t *optval)
3992{
3993 packet_verdict_opt_t* verdict = &optval->packet_verdictval;
3994 uint32_t size;
3995
3996 switch (verdict->type) {
3997
3998 case packet_verdict_hardware:
3999 size = verdict->data.verdict_bytes->len;
4000 break;
4001
4002 case packet_verdict_linux_ebpf_tc:
4003 size = 8;
4004 break;
4005
4006 case packet_verdict_linux_ebpf_xdp:
4007 size = 8;
4008 break;
4009
4010 default:
4011 size = 0;
4012 break;
4013 }
4014 /* Account for the type octet */
4015 if (size) {
4016 size += 1;
4017 }
4018
4019 return size;
4020}
4021
4022static bool_Bool
4023compute_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)
4024{
4025 compute_options_size_t* options_size = (compute_options_size_t*)user_data;
4026 uint32_t size = 0;
4027
4028 /*
4029 * Process the option IDs that are the same for all block types here;
4030 * call the block-type-specific compute_size function for others.
4031 */
4032 switch(option_id)
4033 {
4034 case OPT_COMMENT1:
4035 size = pcapng_compute_string_option_size(optval);
4036 break;
4037 case OPT_CUSTOM_STR_COPY2988:
4038 size = pcapng_compute_custom_string_option_size(optval);
4039 break;
4040 case OPT_CUSTOM_BIN_COPY2989:
4041 size = pcapng_compute_custom_binary_option_size(optval);
4042 break;
4043 case OPT_CUSTOM_STR_NO_COPY19372:
4044 case OPT_CUSTOM_BIN_NO_COPY19373:
4045 /*
4046 * Do not count these, as they're not supposed to be copied to
4047 * new files.
4048 *
4049 * XXX - what if we're writing out a file that's *not* based on
4050 * another file, so that we're *not* copying it from that file?
4051 */
4052 break;
4053 default:
4054 /* Block-type dependent; call the callback. */
4055 if (options_size->compute_option_size) {
4056 size = (*options_size->compute_option_size)(block, option_id, option_type, optval);
4057 }
4058 break;
4059 }
4060
4061 /*
4062 * Are we writing this option?
4063 */
4064 /*
4065 * XXX: The option length field is 16 bits. If size > 65535 (how?
4066 * was the block was obtained from some format other than pcapng?),
4067 * are we going to silently omit the option (in which case we shouldn't
4068 * add the size here), or err out when writing it (in which case
4069 * it's probably fine to add the size or not?) Adding it here and
4070 * then omitting it when writing, as some of the routines do, means
4071 * creating a corrupt file.
4072 */
4073 if (size != 0) {
4074 /*
4075 * Yes. The length of this option is 4 bytes for the option
4076 * header, plus the size of the option data, rounded up
4077 * to a multiple of 4 bytes (32 bits).
4078 */
4079 options_size->size += WS_ROUNDUP_4(4 + size)(((4 + size) + ((unsigned)(4U-1U))) & (~((unsigned)(4U-1U
))))
;
4080 }
4081 return true1; /* we always succeed */
4082}
4083
4084uint32_t
4085pcapng_compute_options_size(wtap_block_t block, compute_option_size_func compute_option_size)
4086{
4087 compute_options_size_t compute_options_size;
4088
4089 /*
4090 * Compute the total size of all the options in the block.
4091 * This always succeeds, so we don't check the return value.
4092 */
4093 compute_options_size.size = 0;
4094 compute_options_size.compute_option_size = compute_option_size;
4095 wtap_block_foreach_option(block, compute_block_option_size, &compute_options_size);
4096
4097 /* Are we writing any options? */
4098 if (compute_options_size.size != 0) {
4099 /* Yes, add the size of the End-of-options tag. */
4100 compute_options_size.size += 4;
4101 }
4102 return compute_options_size.size;
4103}
4104
4105static 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)
4106{
4107 uint32_t size;
4108
4109 switch(option_id)
4110 {
4111 case OPT_SHB_HARDWARE2:
4112 case OPT_SHB_OS3:
4113 case OPT_SHB_USERAPPL4:
4114 size = pcapng_compute_string_option_size(optval);
4115 break;
4116 default:
4117 /* Unknown options - size by datatype? */
4118 size = 0;
4119 break;
4120 }
4121 return size;
4122}
4123
4124typedef struct write_options_t
4125{
4126 wtap_dumper *wdh;
4127 pcapng_opt_byte_order_e byte_order;
4128 write_option_func write_option;
4129 int *err;
4130 char **err_info;
4131}
4132write_options_t;
4133
4134static bool_Bool pcapng_write_option_eofopt(wtap_dumper *wdh, int *err)
4135{
4136 struct pcapng_option_header option_hdr;
4137
4138 /*
4139 * Write end of options.
4140 *
4141 * OPT_EOFOPT is zero, so we don't need to know the byte order to
4142 * be used, as both fields in the option header are zero and thus
4143 * unchanged if byte-swapped.
4144 */
4145 option_hdr.type = OPT_EOFOPT0;
4146 option_hdr.value_length = 0;
4147 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4148 return false0;
4149 return true1;
4150}
4151
4152static bool_Bool pcapng_write_uint8_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4153{
4154 struct pcapng_option_header option_hdr;
4155
4156 option_hdr.type = (uint16_t)option_id;
4157 option_hdr.value_length = (uint16_t)1;
4158 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4159 return false0;
4160
4161 if (!wtap_dump_file_write(wdh, &optval->uint8val, 1, err))
4162 return false0;
4163
4164 if (!pcapng_write_padding(wdh, 3, err))
4165 return false0;
4166
4167 return true1;
4168}
4169
4170static bool_Bool pcapng_write_uint32_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4171{
4172 struct pcapng_option_header option_hdr;
4173
4174 option_hdr.type = (uint16_t)option_id;
4175 option_hdr.value_length = (uint16_t)4;
4176 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4177 return false0;
4178
4179 if (!wtap_dump_file_write(wdh, &optval->uint32val, 4, err))
4180 return false0;
4181
4182 return true1;
4183}
4184
4185static bool_Bool pcapng_write_uint64_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4186{
4187 struct pcapng_option_header option_hdr;
4188
4189 option_hdr.type = (uint16_t)option_id;
4190 option_hdr.value_length = (uint16_t)8;
4191 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4192 return false0;
4193
4194 if (!wtap_dump_file_write(wdh, &optval->uint64val, 8, err))
4195 return false0;
4196
4197 return true1;
4198}
4199
4200static bool_Bool pcapng_write_timestamp_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4201{
4202 struct pcapng_option_header option_hdr;
4203 uint32_t high, low;
4204
4205 option_hdr.type = (uint16_t)option_id;
4206 option_hdr.value_length = (uint16_t)8;
4207 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4208 return false0;
4209
4210 high = (uint32_t)(optval->uint64val >> 32);
4211 low = (uint32_t)(optval->uint64val >> 0);
4212 if (!wtap_dump_file_write(wdh, &high, 4, err))
4213 return false0;
4214 if (!wtap_dump_file_write(wdh, &low, 4, err))
4215 return false0;
4216
4217 return true1;
4218}
4219
4220static bool_Bool pcapng_write_string_option(wtap_dumper *wdh,
4221 pcapng_opt_byte_order_e byte_order,
4222 unsigned option_id,
4223 wtap_optval_t *optval,
4224 int *err, char **err_info)
4225{
4226 struct pcapng_option_header option_hdr;
4227 size_t size = strlen(optval->stringval);
4228
4229 if (size == 0)
4230 return true1;
4231 if (size > 65535) {
4232 /*
4233 * Too big to fit in the option.
4234 * Don't write anything.
4235 *
4236 * XXX - truncate it? Report an error?
4237 */
4238 return true1;
4239 }
4240
4241 /* write option header */
4242 /* String options don't consider pad bytes part of the length */
4243 option_hdr.type = (uint16_t)option_id;
4244 option_hdr.value_length = (uint16_t)size;
4245 switch (byte_order) {
4246
4247 case OPT_SECTION_BYTE_ORDER:
4248 /* This is host byte order when writing, so nothing to do. */
4249 break;
4250
4251 case OPT_BIG_ENDIAN:
4252 option_hdr.type = GUINT16_TO_BE(option_hdr.type)((((guint16) ( (guint16) ((guint16) (option_hdr.type) >>
8) | (guint16) ((guint16) (option_hdr.type) << 8)))))
;
4253 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)))))
;
4254 break;
4255
4256 case OPT_LITTLE_ENDIAN:
4257 option_hdr.type = GUINT16_TO_LE(option_hdr.type)((guint16) (option_hdr.type));
4258 option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length)((guint16) (option_hdr.value_length));
4259 break;
4260
4261 default:
4262 /*
4263 * This indicates somebody passed an invalid option to
4264 * pcapng_write_options().
4265 *
4266 * Report this as an internal error.
4267 */
4268 *err = WTAP_ERR_INTERNAL-21;
4269 *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)
4270 byte_order)wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
;
4271 return true1;
4272 }
4273 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4274 return false0;
4275
4276 if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4277 return false0;
4278
4279 /* write padding (if any) */
4280 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4281}
4282
4283#if 0
4284static bool_Bool pcapng_write_bytes_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4285{
4286 struct pcapng_option_header option_hdr;
4287 size_t size = g_bytes_get_size(optval->byteval);
4288
4289 if (size == 0)
4290 return true1;
4291 if (size > 65535) {
4292 /*
4293 * Too big to fit in the option.
4294 * Don't write anything.
4295 *
4296 * XXX - truncate it? Report an error?
4297 */
4298 return true1;
4299 }
4300
4301 /* Bytes options don't consider pad bytes part of the length */
4302 option_hdr.type = (uint16_t)option_id;
4303 option_hdr.value_length = (uint16_t)size;
4304 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4305 return false0;
4306
4307 if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4308 return false0;
4309
4310 /* write padding (if any) */
4311 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4312}
4313
4314static bool_Bool pcapng_write_ipv4_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4315{
4316 struct pcapng_option_header option_hdr;
4317
4318 option_hdr.type = (uint16_t)option_id;
4319 option_hdr.value_length = (uint16_t)4;
4320 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4321 return false0;
4322
4323 if (!wtap_dump_file_write(wdh, &optval->ipv4val, 1, err))
4324 return false0;
4325
4326 return true1;
4327}
4328
4329static bool_Bool pcapng_write_ipv6_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4330{
4331 struct pcapng_option_header option_hdr;
4332
4333 option_hdr.type = (uint16_t)option_id;
4334 option_hdr.value_length = (uint16_t)IPv6_ADDR_SIZE;
4335 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4336 return false0;
4337
4338 if (!wtap_dump_file_write(wdh, &optval->ipv6val.bytes, IPv6_ADDR_SIZE, err))
4339 return false0;
4340
4341 return true1;
4342}
4343#endif
4344
4345static bool_Bool pcapng_write_if_filter_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4346{
4347 if_filter_opt_t* filter = &optval->if_filterval;
4348 uint32_t size;
4349 uint8_t filter_type;
4350 size_t filter_data_len;
4351 struct pcapng_option_header option_hdr;
4352
4353 switch (filter->type) {
4354
4355 case if_filter_pcap:
4356 filter_type = 0; /* pcap filter string */
4357 filter_data_len = strlen(filter->data.filter_str);
4358 if (filter_data_len > 65534) {
4359 /*
4360 * Too big to fit in the option.
4361 * Don't write anything.
4362 *
4363 * XXX - truncate it? Report an error?
4364 */
4365 return true1;
4366 }
4367 break;
4368
4369 case if_filter_bpf:
4370 filter_type = 1; /* BPF filter program */
4371 filter_data_len = filter->data.bpf_prog.bpf_prog_len*8;
4372 if (filter_data_len > 65528) {
4373 /*
4374 * Too big to fit in the option. (The filter length
4375 * must be a multiple of 8, as that's the length
4376 * of a BPF instruction.) Don't write anything.
4377 *
4378 * XXX - truncate it? Report an error?
4379 */
4380 return true1;
4381 }
4382 break;
4383
4384 default:
4385 /* Unknown filter type; don't write anything. */
4386 return true1;
4387 }
4388 size = (uint32_t)(filter_data_len + 1);
4389
4390 option_hdr.type = option_id;
4391 option_hdr.value_length = size;
4392 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4393 return false0;
4394
4395 /* Write the filter type */
4396 if (!wtap_dump_file_write(wdh, &filter_type, 1, err))
4397 return false0;
4398
4399 switch (filter->type) {
4400
4401 case if_filter_pcap:
4402 /* Write the filter string */
4403 if (!wtap_dump_file_write(wdh, filter->data.filter_str, filter_data_len, err))
4404 return false0;
4405 break;
4406
4407 case if_filter_bpf:
4408 if (!wtap_dump_file_write(wdh, filter->data.bpf_prog.bpf_prog, filter_data_len, err))
4409 return false0;
4410 break;
4411
4412 default:
4413 ws_assert_not_reached()ws_log_fatal_full("Wiretap", LOG_LEVEL_ERROR, "wiretap/pcapng.c"
, 4413, __func__, "assertion \"not reached\" failed")
;
4414 return true1;
4415 }
4416
4417 /* write padding (if any) */
4418 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4419}
4420
4421static bool_Bool pcapng_write_custom_string_option(wtap_dumper *wdh,
4422 pcapng_opt_byte_order_e byte_order,
4423 unsigned option_id,
4424 wtap_optval_t *optval,
4425 int *err, char **err_info)
4426{
4427 struct pcapng_option_header option_hdr;
4428 size_t stringlen;
4429 size_t size;
4430 uint32_t pen;
4431
4432 if (option_id == OPT_CUSTOM_STR_NO_COPY19372)
4433 return true1;
4434 ws_debug("PEN %u", optval->custom_stringval.pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 4434, __func__, "PEN %u", optval->custom_stringval.pen);
} } while (0)
;
4435 stringlen = strlen(optval->custom_stringval.string);
4436 size = sizeof(uint32_t) + stringlen;
4437 if (size > 65535) {
4438 /*
4439 * Too big to fit in the option.
4440 * Don't write anything.
4441 *
4442 * XXX - truncate it? Report an error?
4443 */
4444 return true1;
4445 }
4446
4447 /* write option header and PEN */
4448 /* String options don't consider pad bytes part of the length */
4449 option_hdr.type = (uint16_t)option_id;
4450 option_hdr.value_length = (uint16_t)size;
4451 pen = optval->custom_stringval.pen;
4452 switch (byte_order) {
4453
4454 case OPT_SECTION_BYTE_ORDER:
4455 /* This is host byte order when writing, so nothing to do. */
4456 break;
4457
4458 case OPT_BIG_ENDIAN:
4459 option_hdr.type = GUINT16_TO_BE(option_hdr.type)((((guint16) ( (guint16) ((guint16) (option_hdr.type) >>
8) | (guint16) ((guint16) (option_hdr.type) << 8)))))
;
4460 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)))))
;
4461 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)))))
;
4462 break;
4463
4464 case OPT_LITTLE_ENDIAN:
4465 option_hdr.type = GUINT16_TO_LE(option_hdr.type)((guint16) (option_hdr.type));
4466 option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length)((guint16) (option_hdr.value_length));
4467 pen = GUINT32_TO_LE(pen)((guint32) (pen));
4468 break;
4469
4470 default:
4471 /*
4472 * This indicates somebody passed an invalid option to
4473 * pcapng_write_options().
4474 *
4475 * Report this as an internal error.
4476 */
4477 *err = WTAP_ERR_INTERNAL-21;
4478 *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)
4479 byte_order)wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
;
4480 return true1;
4481 }
4482 if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
4483 return false0;
4484 if (!wtap_dump_file_write(wdh, &pen, sizeof(uint32_t), err))
4485 return false0;
4486
4487 /* write custom data */
4488 if (!wtap_dump_file_write(wdh, optval->custom_stringval.string, stringlen, err)) {
4489 return false0;
4490 }
4491 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"
, 4491, __func__, "Wrote custom option: type %u, length %u", option_hdr
.type, option_hdr.value_length); } } while (0)
;
4492
4493 /* write padding (if any) */
4494 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4495}
4496
4497static bool_Bool pcapng_write_custom_binary_option(wtap_dumper *wdh,
4498 pcapng_opt_byte_order_e byte_order,
4499 unsigned option_id,
4500 wtap_optval_t *optval,
4501 int *err, char **err_info)
4502{
4503 struct pcapng_option_header option_hdr;
4504 size_t size;
4505 uint32_t pen;
4506
4507 if (option_id == OPT_CUSTOM_BIN_NO_COPY19373)
4508 return true1;
4509 ws_debug("PEN %u", optval->custom_binaryval.pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 4509, __func__, "PEN %u", optval->custom_binaryval.pen);
} } while (0)
;
4510 size = sizeof(uint32_t) + optval->custom_binaryval.data.custom_data_len;
4511 if (size > 65535) {
4512 /*
4513 * Too big to fit in the option.
4514 * Don't write anything.
4515 *
4516 * XXX - truncate it? Report an error?
4517 */
4518 return true1;
4519 }
4520
4521 /* write option header and PEN */
4522 option_hdr.type = (uint16_t)option_id;
4523 option_hdr.value_length = (uint16_t)size;
4524 pen = optval->custom_binaryval.pen;
4525 switch (byte_order) {
4526
4527 case OPT_SECTION_BYTE_ORDER:
4528 /* This is host byte order when writing, so nothing to do. */
4529 break;
4530
4531 case OPT_BIG_ENDIAN:
4532 option_hdr.type = GUINT16_TO_BE(option_hdr.type)((((guint16) ( (guint16) ((guint16) (option_hdr.type) >>
8) | (guint16) ((guint16) (option_hdr.type) << 8)))))
;
4533 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)))))
;
4534 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)))))
;
4535 break;
4536
4537 case OPT_LITTLE_ENDIAN:
4538 option_hdr.type = GUINT16_TO_LE(option_hdr.type)((guint16) (option_hdr.type));
4539 option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length)((guint16) (option_hdr.value_length));
4540 pen = GUINT32_TO_LE(pen)((guint32) (pen));
4541 break;
4542
4543 default:
4544 /*
4545 * This indicates somebody passed an invalid option to
4546 * pcapng_write_options().
4547 *
4548 * Report this as an internal error.
4549 */
4550 *err = WTAP_ERR_INTERNAL-21;
4551 *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)
4552 byte_order)wmem_strdup_printf(((void*)0), "pcapng: invalid byte order %d passed to pcapng_write_options()"
, byte_order)
;
4553 return true1;
4554 }
4555 if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
4556 return false0;
4557 if (!wtap_dump_file_write(wdh, &pen, sizeof(uint32_t), err))
4558 return false0;
4559
4560 /* write custom data */
4561 if (!wtap_dump_file_write(wdh, optval->custom_binaryval.data.custom_data, optval->custom_binaryval.data.custom_data_len, err)) {
4562 return false0;
4563 }
4564 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"
, 4564, __func__, "Wrote custom option: type %u, length %u", option_hdr
.type, option_hdr.value_length); } } while (0)
;
4565
4566 /* write padding (if any) */
4567 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4568}
4569
4570static bool_Bool pcapng_write_packet_verdict_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4571{
4572 packet_verdict_opt_t* verdict = &optval->packet_verdictval;
4573 struct pcapng_option_header option_hdr;
4574 uint8_t type;
4575 size_t size;
4576
4577 size = pcapng_compute_packet_verdict_option_size(optval);
4578
4579 switch (verdict->type) {
4580
4581 case packet_verdict_hardware:
4582 if (size > 65535) {
4583 /*
4584 * Too big to fit in the option.
4585 * Don't write anything.
4586 *
4587 * XXX - truncate it? Report an error?
4588 */
4589 return true1;
4590 }
4591 option_hdr.type = option_id;
4592 option_hdr.value_length = (uint16_t)size;
4593 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4594 return false0;
4595
4596 type = packet_verdict_hardware;
4597 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4598 return false0;
4599
4600 if (!wtap_dump_file_write(wdh, verdict->data.verdict_bytes->data,
4601 verdict->data.verdict_bytes->len, err))
4602 return false0;
4603 break;
4604
4605 case packet_verdict_linux_ebpf_tc:
4606 option_hdr.type = option_id;
4607 option_hdr.value_length = (uint16_t)size;
4608 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4609 return false0;
4610
4611 type = packet_verdict_linux_ebpf_tc;
4612 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4613 return false0;
4614
4615 if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_tc,
4616 sizeof(uint64_t), err))
4617 return false0;
4618 break;
4619
4620 case packet_verdict_linux_ebpf_xdp:
4621 option_hdr.type = option_id;
4622 option_hdr.value_length = (uint16_t)size;
4623 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4624 return false0;
4625
4626 type = packet_verdict_linux_ebpf_xdp;
4627 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4628 return false0;
4629
4630 if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_xdp,
4631 sizeof(uint64_t), err))
4632 return false0;
4633 break;
4634
4635 default:
4636 /* Unknown - don't write it out. */
4637 return true1;
4638 }
4639
4640 /* write padding (if any) */
4641 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4642}
4643
4644static bool_Bool pcapng_write_packet_hash_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4645{
4646 packet_hash_opt_t* hash = &optval->packet_hash;
4647 struct pcapng_option_header option_hdr;
4648 uint8_t type;
4649 size_t size;
4650
4651 size = pcapng_compute_packet_hash_option_size(optval);
4652
4653 if (size > 65535) {
4654 /*
4655 * Too big to fit in the option.
4656 * Don't write anything.
4657 *
4658 * XXX - truncate it? Report an error?
4659 */
4660 return true1;
4661 }
4662
4663 if (size > hash->hash_bytes->len + 1) {
4664 /*
4665 * We don't have enough bytes to write.
4666 * pcapng_compute_packet_hash_option_size() should return 0 if
4667 * we want to silently omit the option instead, or should return
4668 * the length if we want to blindly copy it.
4669 * XXX - Is this the best error type?
4670 */
4671 *err = WTAP_ERR_UNWRITABLE_REC_DATA-25;
4672 return false0;
4673 }
4674
4675 type = hash->type;
4676
4677 option_hdr.type = option_id;
4678 /* Include type byte */
4679 option_hdr.value_length = (uint16_t)size;
4680 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4681 return false0;
4682
4683 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4684 return false0;
4685
4686 if (!wtap_dump_file_write(wdh, hash->hash_bytes->data, size - 1,
4687 err))
4688 return false0;
4689
4690 /* write padding (if any) */
4691 return pcapng_write_padding(wdh, WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U), err);
4692}
4693
4694static bool_Bool write_block_option(wtap_block_t block,
4695 unsigned option_id,
4696 wtap_opttype_e option_type _U___attribute__((unused)),
4697 wtap_optval_t *optval, void* user_data)
4698{
4699 write_options_t* options = (write_options_t*)user_data;
4700
4701 /*
4702 * Process the option IDs that are the same for all block types here;
4703 * call the block-type-specific write function for others.
4704 */
4705 switch(option_id)
4706 {
4707 case OPT_COMMENT1:
4708 if (!pcapng_write_string_option(options->wdh, options->byte_order,
4709 option_id, optval,
4710 options->err, options->err_info))
4711 return false0;
4712 break;
4713 case OPT_CUSTOM_STR_COPY2988:
4714 if (!pcapng_write_custom_string_option(options->wdh,
4715 options->byte_order,
4716 option_id, optval,
4717 options->err, options->err_info))
4718 return false0;
4719 break;
4720 case OPT_CUSTOM_BIN_COPY2989:
4721 if (!pcapng_write_custom_binary_option(options->wdh,
4722 options->byte_order,
4723 option_id, optval,
4724 options->err,
4725 options->err_info))
4726 return false0;
4727 break;
4728 case OPT_CUSTOM_STR_NO_COPY19372:
4729 case OPT_CUSTOM_BIN_NO_COPY19373:
4730 /*
4731 * Do not write these, as they're not supposed to be copied to
4732 * new files.
4733 *
4734 * XXX - what if we're writing out a file that's *not* based on
4735 * another file, so that we're *not* copying it from that file?
4736 */
4737 break;
4738 default:
4739 /* Block-type dependent; call the callback, if we have one. */
4740 if (options->write_option != NULL((void*)0) &&
4741 !(*options->write_option)(options->wdh, block, option_id,
4742 option_type, optval,
4743 options->err, options->err_info))
4744 return false0;
4745 break;
4746 }
4747 return true1;
4748}
4749
4750bool_Bool
4751pcapng_write_options(wtap_dumper *wdh, pcapng_opt_byte_order_e byte_order,
4752 wtap_block_t block, write_option_func write_option,
4753 int *err, char **err_info)
4754{
4755 write_options_t options;
4756
4757 options.wdh = wdh;
4758 options.byte_order = byte_order;
4759 options.write_option = write_option;
4760 options.err = err;
4761 options.err_info = err_info;
4762 if (!wtap_block_foreach_option(block, write_block_option, &options))
4763 return false0;
4764
4765 /* Write end of options */
4766 return pcapng_write_option_eofopt(wdh, err);
4767}
4768
4769static bool_Bool write_wtap_shb_option(wtap_dumper *wdh, wtap_block_t block _U___attribute__((unused)),
4770 unsigned option_id,
4771 wtap_opttype_e option_type _U___attribute__((unused)),
4772 wtap_optval_t *optval,
4773 int *err, char **err_info)
4774{
4775 switch(option_id)
4776 {
4777 case OPT_SHB_HARDWARE2:
4778 case OPT_SHB_OS3:
4779 case OPT_SHB_USERAPPL4:
4780 if (!pcapng_write_string_option(wdh, OPT_SECTION_BYTE_ORDER,
4781 option_id, optval, err, err_info))
4782 return false0;
4783 break;
4784 default:
4785 /* Unknown options - write by datatype? */
4786 break;
4787 }
4788 return true1; /* success */
4789}
4790
4791/* Write a section header block.
4792 * If we don't have a section block header already, create a default
4793 * one with no options.
4794 */
4795static bool_Bool
4796pcapng_write_section_header_block(wtap_dumper *wdh, int *err, char **err_info)
4797{
4798 uint32_t block_content_length;
4799 pcapng_section_header_block_t shb;
4800 uint32_t options_size;
4801 wtap_block_t wdh_shb = NULL((void*)0);
4802
4803 if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
4804 wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (wdh->shb_hdrs)->data) [(0)]
)
;
4805 }
4806
4807 block_content_length = (uint32_t)sizeof(shb);
4808 options_size = 0;
4809 if (wdh_shb) {
4810 ws_debug("Have shb_hdr")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 4810, __func__, "Have shb_hdr"); } } while (0)
;
4811
4812 /* Compute size of all the options */
4813 options_size = pcapng_compute_options_size(wdh_shb, compute_shb_option_size);
4814
4815 block_content_length += options_size;
4816 }
4817
4818 /* write block header */
4819 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SHB0x0A0D0D0A, block_content_length,
4820 err))
4821 return false0;
4822
4823 /* write block fixed content */
4824 shb.magic = 0x1A2B3C4D;
4825 shb.version_major = 1;
4826 shb.version_minor = 0;
4827 if (wdh_shb) {
4828 wtapng_section_mandatory_t* section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wdh_shb);
4829 shb.section_length = section_data->section_length;
4830 } else {
4831 shb.section_length = -1;
4832 }
4833
4834 if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
4835 return false0;
4836
4837 if (wdh_shb) {
4838 /* Write options, if we have any */
4839 if (options_size != 0) {
4840 if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
4841 wdh_shb, write_wtap_shb_option,
4842 err, err_info))
4843 return false0;
4844 }
4845 }
4846
4847 /* write block footer */
4848 return pcapng_write_block_footer(wdh, block_content_length, err);
4849}
4850
4851/* options defined in Section 2.5 (Options)
4852 * Name Code Length Description
4853 * opt_comment 1 variable A UTF-8 string containing a comment that is associated to the current block.
4854 *
4855 * Enhanced Packet Block options
4856 * epb_flags 2 4 A flags word containing link-layer information. A complete specification of
4857 * the allowed flags can be found in Appendix A (Packet Block Flags Word).
4858 * epb_hash 3 variable This option contains a hash of the packet. The first byte specifies the hashing algorithm,
4859 * while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
4860 * and hence from the value in the first bit. The hashing algorithm can be: 2s complement
4861 * (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
4862 * MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
4863 * The hash covers only the packet, not the header added by the capture driver:
4864 * this gives the possibility to calculate it inside the network card.
4865 * The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
4866 * data acquisition system and the capture library.
4867 * epb_dropcount 4 8 A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
4868 * between this packet and the preceding one.
4869 * epb_packetid 5 8 The epb_packetid option is a 64-bit unsigned integer that
4870 * uniquely identifies the packet. If the same packet is seen
4871 * by multiple interfaces and there is a way for the capture
4872 * application to correlate them, the same epb_packetid value
4873 * must be used. An example could be a router that captures
4874 * packets on all its interfaces in both directions. When a
4875 * packet hits interface A on ingress, an EPB entry gets
4876 * created, TTL gets decremented, and right before it egresses
4877 * on interface B another EPB entry gets created in the trace
4878 * file. In this case, two packets are in the capture file,
4879 * which are not identical but the epb_packetid can be used to
4880 * correlate them.
4881 * epb_queue 6 4 The epb_queue option is a 32-bit unsigned integer that
4882 * identifies on which queue of the interface the specific
4883 * packet was received.
4884 * epb_verdict 7 variable The epb_verdict option stores a verdict of the packet. The
4885 * verdict indicates what would be done with the packet after
4886 * processing it. For example, a firewall could drop the
4887 * packet. This verdict can be set by various components, i.e.
4888 * Hardware, Linux's eBPF TC or XDP framework, etc. etc. The
4889 * first octet specifies the verdict type, while the following
4890 * octets contain the actual verdict data, whose size depends on
4891 * the verdict type, and hence from the value in the first
4892 * octet. The verdict type can be: Hardware (type octet = 0,
4893 * size = variable), Linux_eBPF_TC (type octet = 1, size = 8
4894 * (64-bit unsigned integer), value = TC_ACT_* as defined in the
4895 * Linux pck_cls.h include), Linux_eBPF_XDP (type octet = 2,
4896 * size = 8 (64-bit unsigned integer), value = xdp_action as
4897 * defined in the Linux pbf.h include).
4898 * opt_endofopt 0 0 It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
4899 */
4900static uint32_t
4901compute_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)
4902{
4903 uint32_t size;
4904
4905 switch(option_id)
4906 {
4907 case OPT_PKT_FLAGS2:
4908 size = 4;
4909 break;
4910 case OPT_PKT_HASH3:
4911 size = pcapng_compute_packet_hash_option_size(optval);
4912 break;
4913 case OPT_PKT_DROPCOUNT4:
4914 size = 8;
4915 break;
4916 case OPT_PKT_PACKETID5:
4917 size = 8;
4918 break;
4919 case OPT_PKT_QUEUE6:
4920 size = 4;
4921 break;
4922 case OPT_PKT_VERDICT7:
4923 size = pcapng_compute_packet_verdict_option_size(optval);
4924 break;
4925 case OPT_PKT_PROCIDTHRDID8:
4926 size = 8;
4927 break;
4928 default:
4929 /* Unknown options - size by datatype? */
4930 size = 0;
4931 break;
4932 }
4933 return size;
4934}
4935
4936static bool_Bool write_wtap_epb_option(wtap_dumper *wdh, wtap_block_t block _U___attribute__((unused)),
4937 unsigned option_id,
4938 wtap_opttype_e option_type _U___attribute__((unused)),
4939 wtap_optval_t *optval,
4940 int *err, char **err_info _U___attribute__((unused)))
4941{
4942 switch(option_id)
4943 {
4944 case OPT_PKT_FLAGS2:
4945 if (!pcapng_write_uint32_option(wdh, OPT_PKT_FLAGS2, optval, err))
4946 return false0;
4947 break;
4948 case OPT_PKT_HASH3:
4949 if (!pcapng_write_packet_hash_option(wdh, OPT_PKT_HASH3, optval, err))
4950 return false0;
4951 break;
4952 case OPT_PKT_DROPCOUNT4:
4953 if (!pcapng_write_uint64_option(wdh, OPT_PKT_DROPCOUNT4, optval, err))
4954 return false0;
4955 break;
4956 case OPT_PKT_PACKETID5:
4957 if (!pcapng_write_uint64_option(wdh, OPT_PKT_PACKETID5, optval, err))
4958 return false0;
4959 break;
4960 case OPT_PKT_QUEUE6:
4961 if (!pcapng_write_uint32_option(wdh, OPT_PKT_QUEUE6, optval, err))
4962 return false0;
4963 break;
4964 case OPT_PKT_VERDICT7:
4965 if (!pcapng_write_packet_verdict_option(wdh, OPT_PKT_VERDICT7, optval, err))
4966 return false0;
4967 break;
4968 case OPT_PKT_PROCIDTHRDID8:
4969 if (!pcapng_write_uint64_option(wdh, OPT_PKT_PROCIDTHRDID8, optval, err))
4970 return false0;
4971 break;
4972 default:
4973 /* Unknown options - write by datatype? */
4974 break;
4975 }
4976 return true1; /* success */
4977}
4978
4979static bool_Bool
4980pcapng_write_simple_packet_block(wtap_dumper* wdh, const wtap_rec* rec,
4981 int* err, char** err_info _U___attribute__((unused)))
4982{
4983 const union wtap_pseudo_header* pseudo_header = &rec->rec_header.packet_header.pseudo_header;
4984 uint32_t block_content_length;
4985 pcapng_simple_packet_block_t spb;
4986 uint32_t pad_len;
4987 uint32_t phdr_len;
4988
4989 /* Don't write anything we're not willing to read. */
4990 if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->file_encap)) {
4991 *err = WTAP_ERR_PACKET_TOO_LARGE-22;
4992 return false0;
4993 }
4994
4995 phdr_len = pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
4996 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)
;
4997
4998 /* write (simple) packet block header */
4999 block_content_length = (uint32_t)sizeof(spb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len;
5000 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SPB0x00000003, block_content_length,
5001 err))
5002 return false0;
5003
5004 /* write block fixed content */
5005 spb.packet_len = rec->rec_header.packet_header.len + phdr_len;
5006
5007 if (!wtap_dump_file_write(wdh, &spb, sizeof spb, err))
5008 return false0;
5009
5010 /* write pseudo header */
5011 if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
5012 return false0;
5013 }
5014
5015 /* write packet data */
5016 if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.packet_header.caplen, err))
5017 return false0;
5018
5019 /* write padding (if any) */
5020 if (!pcapng_write_padding(wdh, pad_len, err))
5021 return false0;
5022
5023 /* write block footer */
5024 return pcapng_write_block_footer(wdh, block_content_length, err);
5025}
5026
5027static bool_Bool
5028pcapng_write_enhanced_packet_block(wtap_dumper *wdh, const wtap_rec *rec,
5029 int *err, char **err_info)
5030{
5031 const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
5032 uint32_t block_content_length;
5033 pcapng_enhanced_packet_block_t epb;
5034 uint32_t options_size = 0;
5035 uint64_t ts;
5036 uint32_t pad_len;
5037 uint32_t phdr_len;
5038 wtap_block_t int_data;
5039 wtapng_if_descr_mandatory_t *int_data_mand;
5040
5041 /* Don't write anything we're not willing to read. */
5042 if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->file_encap)) {
5043 *err = WTAP_ERR_PACKET_TOO_LARGE-22;
5044 return false0;
5045 }
5046
5047 phdr_len = pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
5048 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)
;
5049
5050 if (rec->block != NULL((void*)0)) {
5051 /* Compute size of all the options */
5052 options_size = pcapng_compute_options_size(rec->block, compute_epb_option_size);
5053 }
5054
5055 /*
5056 * Check the interface ID. Do this before writing the header,
5057 * in case we need to add a new IDB.
5058 */
5059 if (rec->presence_flags & WTAP_HAS_INTERFACE_ID0x00000004) {
5060 epb.interface_id = rec->rec_header.packet_header.interface_id;
5061 if (rec->presence_flags & WTAP_HAS_SECTION_NUMBER0x00000008 && wdh->shb_iface_to_global) {
5062 /*
5063 * In the extremely unlikely event this overflows we give the
5064 * wrong interface ID.
5065 */
5066 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)])
;
5067 }
5068 } else {
5069 /*
5070 * The source isn't sending us IDBs. See if we already have a
5071 * matching interface, and use it if so.
5072 */
5073 for (epb.interface_id = 0; epb.interface_id < wdh->interface_data->len; ++epb.interface_id) {
5074 int_data = g_array_index(wdh->interface_data, wtap_block_t,(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(epb.interface_id)])
5075 epb.interface_id)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(epb.interface_id)])
;
5076 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5077 if (int_data_mand->wtap_encap == rec->rec_header.packet_header.pkt_encap) {
5078 if (int_data_mand->tsprecision == rec->tsprec || (!(rec->presence_flags & WTAP_HAS_TS0x00000001))) {
5079 break;
5080 }
5081 }
5082 }
5083 if (epb.interface_id == wdh->interface_data->len) {
5084 /*
5085 * We don't have a matching IDB. Generate a new one
5086 * and write it to the file.
5087 */
5088 int_data = wtap_rec_generate_idb(rec);
5089 g_array_append_val(wdh->interface_data, int_data)g_array_append_vals (wdh->interface_data, &(int_data),
1)
;
5090 if (!pcapng_write_if_descr_block(wdh, int_data, err, err_info)) {
5091 return false0;
5092 }
5093 }
5094 }
5095 if (epb.interface_id >= wdh->interface_data->len) {
5096 /*
5097 * Our caller is doing something bad.
5098 */
5099 *err = WTAP_ERR_INTERNAL-21;
5100 *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)
5101 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)
;
5102 return false0;
5103 }
5104 int_data = g_array_index(wdh->interface_data, wtap_block_t,(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(epb.interface_id)])
5105 epb.interface_id)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(epb.interface_id)])
;
5106 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5107 if (int_data_mand->wtap_encap != rec->rec_header.packet_header.pkt_encap) {
5108 /*
5109 * Our caller is doing something bad.
5110 */
5111 *err = WTAP_ERR_INTERNAL-21;
5112 *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)
5113 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)
5114 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)
5115 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)
;
5116 return false0;
5117 }
5118
5119 /* write (enhanced) packet block header */
5120 block_content_length = (uint32_t)sizeof(epb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len + options_size;
5121 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_EPB0x00000006, block_content_length,
5122 err))
5123 return false0;
5124
5125 /* write block fixed content */
5126 /* Calculate the time stamp as a 64-bit integer. */
5127 /* TODO - This can't overflow currently because we don't allow greater
5128 * than nanosecond resolution, but if and when we do, we need to check for
5129 * overflow. Normally it shouldn't, but what if there was a time shift?
5130 */
5131 ts = ((uint64_t)rec->ts.secs) * int_data_mand->time_units_per_second +
5132 (((uint64_t)rec->ts.nsecs) * int_data_mand->time_units_per_second) / NS_PER_S1000000000U;
5133 /*
5134 * Split the 64-bit timestamp into two 32-bit pieces, using
5135 * the time stamp resolution for the interface.
5136 */
5137 epb.timestamp_high = (uint32_t)(ts >> 32);
5138 epb.timestamp_low = (uint32_t)ts;
5139 epb.captured_len = rec->rec_header.packet_header.caplen + phdr_len;
5140 epb.packet_len = rec->rec_header.packet_header.len + phdr_len;
5141
5142 if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
5143 return false0;
5144
5145 /* write pseudo header */
5146 if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
5147 return false0;
5148 }
5149
5150 /* write packet data */
5151 if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.packet_header.caplen, err))
5152 return false0;
5153
5154 /* write padding (if any) */
5155 if (!pcapng_write_padding(wdh, pad_len, err))
5156 return false0;
5157
5158 /* Write options, if we have any */
5159 if (options_size != 0) {
5160 if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
5161 rec->block, write_wtap_epb_option,
5162 err, err_info))
5163 return false0;
5164 }
5165
5166 /* write block footer */
5167 return pcapng_write_block_footer(wdh, block_content_length, err);
5168}
5169
5170static bool_Bool
5171pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
5172 int *err, char **err_info _U___attribute__((unused)))
5173{
5174 uint32_t block_content_length;
5175 uint32_t pad_len;
5176
5177 /* Don't write anything we're not willing to read. */
5178 if (rec->rec_header.systemd_journal_export_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD262144U) {
5179 *err = WTAP_ERR_PACKET_TOO_LARGE-22;
5180 return false0;
5181 }
5182
5183 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)
;
5184
5185 /* write systemd journal export block header */
5186 block_content_length = rec->rec_header.systemd_journal_export_header.record_len + pad_len;
5187 ws_debug("writing %u bytes, %u padded",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5189, __func__, "writing %u bytes, %u padded", rec->rec_header
.systemd_journal_export_header.record_len, block_content_length
); } } while (0)
5188 rec->rec_header.systemd_journal_export_header.record_len,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5189, __func__, "writing %u bytes, %u padded", rec->rec_header
.systemd_journal_export_header.record_len, block_content_length
); } } while (0)
5189 block_content_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5189, __func__, "writing %u bytes, %u padded", rec->rec_header
.systemd_journal_export_header.record_len, block_content_length
); } } while (0)
;
5190 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT0x00000009,
5191 block_content_length, err))
5192 return false0;
5193
5194 /* write entry data */
5195 if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.systemd_journal_export_header.record_len, err))
5196 return false0;
5197
5198 /* write padding (if any) */
5199 if (!pcapng_write_padding(wdh, pad_len, err))
5200 return false0;
5201
5202 /* write block footer */
5203 return pcapng_write_block_footer(wdh, block_content_length, err);
5204}
5205
5206static bool_Bool
5207pcapng_write_custom_block_copy(wtap_dumper *wdh, const wtap_rec *rec,
5208 int *err, char **err_info _U___attribute__((unused)))
5209{
5210 pcapng_custom_block_enterprise_handler_t *pen_handler;
5211 uint32_t block_content_length;
5212 pcapng_custom_block_t cb;
5213 uint32_t pad_len;
5214
5215 /* Don't write anything we are not supposed to. */
5216 if (!rec->rec_header.custom_block_header.copy_allowed) {
5217 return true1;
5218 }
5219
5220 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))
);
5221 if (pen_handler != NULL((void*)0))
5222 {
5223 if (!pen_handler->writer(wdh, rec, err, err_info))
5224 return false0;
5225 }
5226 else
5227 {
5228 /* Don't write anything we're not willing to read. */
5229 if (rec->rec_header.custom_block_header.length > WTAP_MAX_PACKET_SIZE_STANDARD262144U) {
5230 *err = WTAP_ERR_PACKET_TOO_LARGE-22;
5231 return false0;
5232 }
5233
5234 pad_len = WS_PADDING_TO_4(rec->rec_header.custom_block_header.length)((4U - ((rec->rec_header.custom_block_header.length) % 4U)
) % 4U)
;
5235
5236 /* write block header */
5237 block_content_length = (uint32_t)sizeof(cb) + rec->rec_header.custom_block_header.length + pad_len;
5238 ws_debug("writing %u bytes, %u padded, PEN %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5240, __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)
5239 (uint32_t)sizeof(cb) + rec->rec_header.custom_block_header.length,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5240, __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)
5240 block_content_length, rec->rec_header.custom_block_header.pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5240, __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)
;
5241 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_CB_COPY0x00000BAD,
5242 block_content_length, err))
5243 return false0;
5244
5245 /* write custom block header */
5246 cb.pen = rec->rec_header.custom_block_header.pen;
5247 if (!wtap_dump_file_write(wdh, &cb, sizeof cb, err)) {
5248 return false0;
5249 }
5250 ws_debug("wrote PEN = %u", cb.pen)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5250, __func__, "wrote PEN = %u", cb.pen); } } while (0)
;
5251
5252 /* write custom data */
5253 if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.custom_block_header.length, err)) {
5254 return false0;
5255 }
5256
5257 /* write padding (if any) */
5258 if (!pcapng_write_padding(wdh, pad_len, err))
5259 return false0;
5260
5261 /* write block footer */
5262 return pcapng_write_block_footer(wdh, block_content_length, err);
5263 }
5264 return true1;
5265}
5266
5267static bool_Bool
5268pcapng_write_custom_block_no_copy(wtap_dumper *wdh _U___attribute__((unused)), const wtap_rec *rec _U___attribute__((unused)),
5269 int *err _U___attribute__((unused)), char **err_info _U___attribute__((unused)))
5270{
5271 /* Don't write anything we are not supposed to. */
5272 return true1;
5273}
5274
5275static bool_Bool
5276pcapng_write_decryption_secrets_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
5277{
5278 uint32_t block_content_length;
5279 pcapng_decryption_secrets_block_t dsb;
5280 wtapng_dsb_mandatory_t *mand_data = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
5281 uint32_t pad_len;
5282
5283 pad_len = WS_PADDING_TO_4(mand_data->secrets_len)((4U - ((mand_data->secrets_len) % 4U)) % 4U);
5284
5285 /* write block header */
5286 block_content_length = (uint32_t)sizeof(dsb) + mand_data->secrets_len + pad_len;
5287 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_DSB0x0000000A, block_content_length,
5288 err))
5289 return false0;
5290
5291 /* write block fixed content */
5292 dsb.secrets_type = mand_data->secrets_type;
5293 dsb.secrets_len = mand_data->secrets_len;
5294 if (!wtap_dump_file_write(wdh, &dsb, sizeof dsb, err))
5295 return false0;
5296
5297 if (!wtap_dump_file_write(wdh, mand_data->secrets_data, mand_data->secrets_len, err))
5298 return false0;
5299
5300 /* write padding (if any) */
5301 if (!pcapng_write_padding(wdh, pad_len, err))
5302 return false0;
5303
5304 /* write block footer */
5305 return pcapng_write_block_footer(wdh, block_content_length, err);
5306}
5307
5308static bool_Bool
5309pcapng_write_meta_event_block(wtap_dumper *wdh, wtap_block_t mev_data, int *err)
5310{
5311 uint32_t block_content_length;
5312 wtapng_meta_event_mandatory_t *mand_data = (wtapng_meta_event_mandatory_t *)wtap_block_get_mandatory_data(mev_data);
5313 uint32_t pad_len;
5314
5315 pad_len = WS_PADDING_TO_4(mand_data->mev_data_len)((4U - ((mand_data->mev_data_len) % 4U)) % 4U);
5316
5317 /* write block header */
5318 block_content_length = mand_data->mev_data_len + pad_len;
5319 if (!pcapng_write_block_header(wdh, mand_data->mev_block_type,
5320 block_content_length, err))
5321 return false0;
5322 ws_debug("Sysdig mev len %u", block_content_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5322, __func__, "Sysdig mev len %u", block_content_length);
} } while (0)
;
5323
5324 /* write block fixed content */
5325 if (!wtap_dump_file_write(wdh, mand_data->mev_data, mand_data->mev_data_len, err))
5326 return false0;
5327
5328 /* write padding (if any) */
5329 if (!pcapng_write_padding(wdh, pad_len, err))
5330 return false0;
5331
5332 /* write block footer */
5333 return pcapng_write_block_footer(wdh, block_content_length, err);
5334}
5335
5336/*
5337 * libpcap's maximum pcapng block size is currently 16MB.
5338 *
5339 * The maximum pcapng block size in macOS's private pcapng reading code
5340 * is 1MB. (Yes, this means that a program using the standard pcap
5341 * code to read pcapng files can handle bigger blocks than can programs
5342 * using the private code, such as Apple's tcpdump, can handle.)
5343 *
5344 * The pcapng reading code here can handle NRBs of arbitrary size (less
5345 * than 4GB, obviously), as they read each NRB record independently,
5346 * rather than reading the entire block into memory.
5347 *
5348 * So, for now, we set the maximum NRB block size we write as 1 MB.
5349 *
5350 * (Yes, for the benefit of the fussy, "MB" is really "MiB".)
5351 */
5352
5353#define NRES_BLOCK_MAX_SIZE(1024*1024) (1024*1024)
5354
5355static uint32_t
5356compute_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)
5357{
5358 uint32_t size;
5359
5360 switch(option_id)
5361 {
5362 case OPT_NS_DNSNAME2:
5363 size = pcapng_compute_string_option_size(optval);
5364 break;
5365 case OPT_NS_DNSIP4ADDR3:
5366 size = 4;
5367 break;
5368 case OPT_NS_DNSIP6ADDR4:
5369 size = 16;
5370 break;
5371 default:
5372 /* Unknown options - size by datatype? */
5373 size = 0;
5374 break;
5375 }
5376 return size;
5377}
5378
5379static bool_Bool
5380put_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)
5381{
5382 uint8_t **opt_ptrp = (uint8_t **)user_data;
5383 size_t stringlen;
5384 size_t size = 0;
5385 struct pcapng_option_header option_hdr;
5386 uint32_t pad;
5387
5388 switch(option_id)
5389 {
5390 case OPT_COMMENT1:
5391 case OPT_NS_DNSNAME2:
5392 size = strlen(optval->stringval);
5393 if (size > 65535) {
5394 /*
5395 * Too big to fit in the option.
5396 * Don't write anything.
5397 *
5398 * XXX - truncate it? Report an error?
5399 */
5400 return true1;
5401 }
5402
5403 /* Put option header */
5404 /* String options don't consider pad bytes part of the length */
5405 option_hdr.type = (uint16_t)option_id;
5406 option_hdr.value_length = (uint16_t)size;
5407 memcpy(*opt_ptrp, &option_hdr, 4);
5408 *opt_ptrp += 4;
5409
5410 memcpy(*opt_ptrp, optval->stringval, size);
5411 *opt_ptrp += size;
5412
5413 /* put padding (if any) */
5414 pad = WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U);
5415 if (pad != 0) {
5416 memset(*opt_ptrp, 0, pad);
5417 *opt_ptrp += pad;
5418 }
5419 break;
5420 case OPT_CUSTOM_STR_COPY2988:
5421 /* String options don't consider pad bytes part of the length */
5422 stringlen = strlen(optval->custom_stringval.string);
5423 size = sizeof(uint32_t) + stringlen;
5424 if (size > 65535) {
5425 /*
5426 * Too big to fit in the option.
5427 * Don't write anything.
5428 *
5429 * XXX - truncate it? Report an error?
5430 */
5431 return true1;
5432 }
5433
5434 /* Put option header and PEN */
5435 /* String options don't consider pad bytes part of the length */
5436 option_hdr.type = (uint16_t)option_id;
5437 option_hdr.value_length = (uint16_t)size;
5438 memcpy(*opt_ptrp, &option_hdr, 4);
5439 *opt_ptrp += 4;
5440
5441 memcpy(*opt_ptrp, &optval->custom_stringval.pen, sizeof(uint32_t));
5442 *opt_ptrp += sizeof(uint32_t);
5443 memcpy(*opt_ptrp, optval->custom_stringval.string, size);
5444 *opt_ptrp += size;
5445
5446 /* put padding (if any) */
5447 pad = WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U);
5448 if (pad != 0) {
5449 memset(*opt_ptrp, 0, pad);
5450 *opt_ptrp += pad;
5451 }
5452 break;
5453 case OPT_CUSTOM_BIN_COPY2989:
5454 /* Custom options don't consider pad bytes part of the length */
5455 size = (uint32_t)(optval->custom_binaryval.data.custom_data_len + sizeof(uint32_t)) & 0xffff;
5456 option_hdr.type = (uint16_t)option_id;
5457 option_hdr.value_length = (uint16_t)size;
5458 memcpy(*opt_ptrp, &option_hdr, 4);
5459 *opt_ptrp += 4;
5460
5461 memcpy(*opt_ptrp, &optval->custom_binaryval.pen, sizeof(uint32_t));
5462 *opt_ptrp += sizeof(uint32_t);
5463
5464 memcpy(*opt_ptrp, optval->custom_binaryval.data.custom_data, optval->custom_binaryval.data.custom_data_len);
5465 *opt_ptrp += optval->custom_binaryval.data.custom_data_len;
5466
5467 /* put padding (if any) */
5468 pad = WS_PADDING_TO_4(size)((4U - ((size) % 4U)) % 4U);
5469 if (pad != 0) {
5470 memset(*opt_ptrp, 0, pad);
5471 *opt_ptrp += pad;
5472 }
5473 break;
5474 case OPT_NS_DNSIP4ADDR3:
5475 option_hdr.type = (uint16_t)option_id;
5476 option_hdr.value_length = 4;
5477 memcpy(*opt_ptrp, &option_hdr, 4);
5478 *opt_ptrp += 4;
5479
5480 memcpy(*opt_ptrp, &optval->ipv4val, 4);
5481 *opt_ptrp += 4;
5482 break;
5483 case OPT_NS_DNSIP6ADDR4:
5484 option_hdr.type = (uint16_t)option_id;
5485 option_hdr.value_length = 16;
5486 memcpy(*opt_ptrp, &option_hdr, 4);
5487 *opt_ptrp += 4;
5488
5489 memcpy(*opt_ptrp, &optval->ipv6val, 16);
5490 *opt_ptrp += 16;
5491 break;
5492 default:
5493 /* Unknown options - size by datatype? */
5494 break;
5495 }
5496 return true1; /* we always succeed */
5497}
5498
5499static void
5500put_nrb_options(wtap_dumper *wdh _U___attribute__((unused)), wtap_block_t nrb, uint8_t *opt_ptr)
5501{
5502 struct pcapng_option option_hdr;
5503
5504 wtap_block_foreach_option(nrb, put_nrb_option, &opt_ptr);
5505
5506 /* Put end of options */
5507 option_hdr.type = OPT_EOFOPT0;
5508 option_hdr.value_length = 0;
5509 memcpy(opt_ptr, &option_hdr, 4);
5510}
5511
5512static bool_Bool
5513pcapng_write_name_resolution_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
5514{
5515 pcapng_block_header_t bh;
5516 pcapng_name_resolution_block_t nrb;
5517 wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
5518 uint32_t options_size;
5519 size_t max_rec_data_size;
5520 uint8_t *block_data;
5521 uint32_t block_off;
5522 size_t hostnamelen;
5523 uint16_t namelen;
5524 uint32_t tot_rec_len;
5525 hashipv4_t *ipv4_hash_list_entry;
5526 hashipv6_t *ipv6_hash_list_entry;
5527 int i;
5528
5529 if (!mand_data) {
5530 /*
5531 * No name/address pairs to write.
5532 * XXX - what if we have options?
5533 */
5534 return true1;
5535 }
5536
5537 /* Calculate the space needed for options. */
5538 options_size = pcapng_compute_options_size(sdata, compute_nrb_option_size);
5539
5540 /*
5541 * Make sure we can fit at least one maximum-sized record, plus
5542 * an end-of-records record, plus the options, into a maximum-sized
5543 * block.
5544 *
5545 * That requires that there be enough space for the block header
5546 * (8 bytes), a maximum-sized record (2 bytes of record type, 2
5547 * bytes of record value length, 65535 bytes of record value,
5548 * and 1 byte of padding), an end-of-records record (4 bytes),
5549 * the options (options_size bytes), and the block trailer (4
5550 * bytes).
5551 */
5552 if (8 + 2 + 2 + 65535 + 1 + 4 + options_size + 4 > NRES_BLOCK_MAX_SIZE(1024*1024)) {
5553 /*
5554 * XXX - we can't even fit the options in the largest NRB size
5555 * we're willing to write and still have room enough for a
5556 * maximum-sized record. Just discard the information for now.
5557 */
5558 return true1;
5559 }
5560
5561 /*
5562 * Allocate a buffer for the largest block we'll write.
5563 */
5564 block_data = (uint8_t *)g_malloc(NRES_BLOCK_MAX_SIZE(1024*1024));
5565
5566 /*
5567 * Calculate the maximum amount of record data we'll be able to
5568 * fit into such a block, after taking into account the block header
5569 * (8 bytes), the end-of-records record (4 bytes), the options
5570 * (options_size bytes), and the block trailer (4 bytes).
5571 */
5572 max_rec_data_size = NRES_BLOCK_MAX_SIZE(1024*1024) - (8 + 4 + options_size + 4);
5573
5574 block_off = 8; /* block type + block total length */
5575 bh.block_type = BLOCK_TYPE_NRB0x00000004;
5576 bh.block_total_length = 12; /* block header + block trailer */
5577
5578 /*
5579 * Write out the IPv4 resolved addresses, if any.
5580 */
5581 if (mand_data->ipv4_addr_list){
5582 i = 0;
5583 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5584 while(ipv4_hash_list_entry != NULL((void*)0)){
5585
5586 nrb.record_type = NRES_IP4RECORD1;
5587 hostnamelen = strlen(ipv4_hash_list_entry->name);
5588 if (hostnamelen > (UINT16_MAX(65535) - 4) - 1) {
5589 /*
5590 * This won't fit in the largest possible NRB record;
5591 * discard it.
5592 */
5593 i++;
5594 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5595 continue;
5596 }
5597 namelen = (uint16_t)(hostnamelen + 1);
5598 nrb.record_len = 4 + namelen; /* 4 bytes IPv4 address length */
5599 /* 2 bytes record type, 2 bytes length field */
5600 tot_rec_len = 4 + nrb.record_len + WS_PADDING_TO_4(nrb.record_len)((4U - ((nrb.record_len) % 4U)) % 4U);
5601
5602 if (block_off + tot_rec_len > max_rec_data_size) {
5603 /*
5604 * This record would overflow our maximum size for Name
5605 * Resolution Blocks; write out all the records we created
5606 * before it, and start a new NRB.
5607 */
5608
5609 /* Append the end-of-records record */
5610 memset(block_data + block_off, 0, 4);
5611 block_off += 4;
5612 bh.block_total_length += 4;
5613
5614 /*
5615 * Put the options into the block.
5616 */
5617 put_nrb_options(wdh, sdata, block_data + block_off);
5618 block_off += options_size;
5619 bh.block_total_length += options_size;
5620
5621 /* Copy the block header. */
5622 memcpy(block_data, &bh, sizeof(bh));
5623
5624 /* Copy the block trailer. */
5625 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5626
5627 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"
, 5628, __func__, "Write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
5628 bh.block_total_length, block_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5628, __func__, "Write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
;
5629
5630 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5631 g_free(block_data);
5632 return false0;
5633 }
5634
5635 /*Start a new NRB */
5636 block_off = 8; /* block type + block total length */
5637 bh.block_type = BLOCK_TYPE_NRB0x00000004;
5638 bh.block_total_length = 12; /* block header + block trailer */
5639 }
5640
5641 bh.block_total_length += tot_rec_len;
5642 memcpy(block_data + block_off, &nrb, sizeof(nrb));
5643 block_off += 4;
5644 memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4);
5645 block_off += 4;
5646 memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen);
5647 block_off += namelen;
5648 memset(block_data + block_off, 0, WS_PADDING_TO_4(namelen)((4U - ((namelen) % 4U)) % 4U));
5649 block_off += WS_PADDING_TO_4(namelen)((4U - ((namelen) % 4U)) % 4U);
5650 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"
, 5650, __func__, "added IPv4 record for %s", ipv4_hash_list_entry
->name); } } while (0)
;
5651
5652 i++;
5653 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5654 }
5655 }
5656
5657 if (mand_data->ipv6_addr_list){
5658 i = 0;
5659 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5660 while(ipv6_hash_list_entry != NULL((void*)0)){
5661
5662 nrb.record_type = NRES_IP6RECORD2;
5663 hostnamelen = strlen(ipv6_hash_list_entry->name);
5664 if (hostnamelen > (UINT16_MAX(65535) - 16) - 1) {
5665 /*
5666 * This won't fit in the largest possible NRB record;
5667 * discard it.
5668 */
5669 i++;
5670 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5671 continue;
5672 }
5673 namelen = (uint16_t)(hostnamelen + 1);
5674 nrb.record_len = 16 + namelen; /* 16 bytes IPv6 address length */
5675 /* 2 bytes record type, 2 bytes length field */
5676 tot_rec_len = 4 + nrb.record_len + WS_PADDING_TO_4(nrb.record_len)((4U - ((nrb.record_len) % 4U)) % 4U);
5677
5678 if (block_off + tot_rec_len > max_rec_data_size) {
5679 /*
5680 * This record would overflow our maximum size for Name
5681 * Resolution Blocks; write out all the records we created
5682 * before it, and start a new NRB.
5683 */
5684
5685 /* Append the end-of-records record */
5686 memset(block_data + block_off, 0, 4);
5687 block_off += 4;
5688 bh.block_total_length += 4;
5689
5690 /*
5691 * Put the options into the block.
5692 */
5693 put_nrb_options(wdh, sdata, block_data + block_off);
5694 block_off += options_size;
5695 bh.block_total_length += options_size;
5696
5697 /* Copy the block header. */
5698 memcpy(block_data, &bh, sizeof(bh));
5699
5700 /* Copy the block trailer. */
5701 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5702
5703 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"
, 5704, __func__, "write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
5704 bh.block_total_length, block_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5704, __func__, "write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
;
5705
5706 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5707 g_free(block_data);
5708 return false0;
5709 }
5710
5711 /*Start a new NRB */
5712 block_off = 8; /* block type + block total length */
5713 bh.block_type = BLOCK_TYPE_NRB0x00000004;
5714 bh.block_total_length = 12; /* block header + block trailer */
5715 }
5716
5717 bh.block_total_length += tot_rec_len;
5718 memcpy(block_data + block_off, &nrb, sizeof(nrb));
5719 block_off += 4;
5720 memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16);
5721 block_off += 16;
5722 memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen);
5723 block_off += namelen;
5724 memset(block_data + block_off, 0, WS_PADDING_TO_4(namelen)((4U - ((namelen) % 4U)) % 4U));
5725 block_off += WS_PADDING_TO_4(namelen)((4U - ((namelen) % 4U)) % 4U);
5726 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"
, 5726, __func__, "added IPv6 record for %s", ipv6_hash_list_entry
->name); } } while (0)
;
5727
5728 i++;
5729 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5730 }
5731 }
5732
5733 /* Append the end-of-records record */
5734 memset(block_data + block_off, 0, 4);
5735 block_off += 4;
5736 bh.block_total_length += 4;
5737
5738 /*
5739 * Put the options into the block.
5740 */
5741 put_nrb_options(wdh, sdata, block_data + block_off);
5742 block_off += options_size;
5743 bh.block_total_length += options_size;
5744
5745 /* Copy the block header. */
5746 memcpy(block_data, &bh, sizeof(bh));
5747
5748 /* Copy the block trailer. */
5749 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5750
5751 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"
, 5752, __func__, "Write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
5752 bh.block_total_length, block_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5752, __func__, "Write bh.block_total_length bytes %d, block_off %u"
, bh.block_total_length, block_off); } } while (0)
;
5753
5754 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5755 g_free(block_data);
5756 return false0;
5757 }
5758
5759 g_free(block_data);
5760
5761 return true1;
5762}
5763
5764static 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)))
5765{
5766 uint32_t size;
5767
5768 switch(option_id)
5769 {
5770 case OPT_ISB_STARTTIME2:
5771 case OPT_ISB_ENDTIME3:
5772 size = 8;
5773 break;
5774 case OPT_ISB_IFRECV4:
5775 case OPT_ISB_IFDROP5:
5776 case OPT_ISB_FILTERACCEPT6:
5777 case OPT_ISB_OSDROP7:
5778 case OPT_ISB_USRDELIV8:
5779 size = 8;
5780 break;
5781 default:
5782 /* Unknown options - size by datatype? */
5783 size = 0;
5784 break;
5785 }
5786 return size;
5787}
5788
5789static bool_Bool write_wtap_isb_option(wtap_dumper *wdh, wtap_block_t block _U___attribute__((unused)),
5790 unsigned option_id,
5791 wtap_opttype_e option_type _U___attribute__((unused)),
5792 wtap_optval_t *optval,
5793 int *err, char **err_info _U___attribute__((unused)))
5794{
5795 switch(option_id)
5796 {
5797 case OPT_ISB_STARTTIME2:
5798 case OPT_ISB_ENDTIME3:
5799 if (!pcapng_write_timestamp_option(wdh, option_id, optval, err))
5800 return false0;
5801 break;
5802 case OPT_ISB_IFRECV4:
5803 case OPT_ISB_IFDROP5:
5804 case OPT_ISB_FILTERACCEPT6:
5805 case OPT_ISB_OSDROP7:
5806 case OPT_ISB_USRDELIV8:
5807 if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5808 return false0;
5809 break;
5810 default:
5811 /* Unknown options - write by datatype? */
5812 break;
5813 }
5814 return true1; /* success */
5815}
5816
5817static bool_Bool
5818pcapng_write_interface_statistics_block(wtap_dumper *wdh,
5819 wtap_block_t if_stats,
5820 int *err, char **err_info)
5821{
5822 uint32_t block_content_length;
5823 pcapng_interface_statistics_block_t isb;
5824 uint32_t options_size;
5825 wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
5826
5827 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5827, __func__, "entering function"); } } while (0)
;
5828
5829 /* Compute size of all the options */
5830 options_size = pcapng_compute_options_size(if_stats, compute_isb_option_size);
5831
5832 /* write block header */
5833 block_content_length = (uint32_t)sizeof(isb) + options_size;
5834 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_ISB0x00000005, block_content_length,
5835 err))
5836 return false0;
5837
5838 /* write block fixed content */
5839 isb.interface_id = mand_data->interface_id;
5840 isb.timestamp_high = mand_data->ts_high;
5841 isb.timestamp_low = mand_data->ts_low;
5842
5843 if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
5844 return false0;
5845
5846 /* Write options */
5847 if (options_size != 0) {
5848 if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
5849 if_stats, write_wtap_isb_option,
5850 err, err_info))
5851 return false0;
5852 }
5853
5854 /* write block footer */
5855 return pcapng_write_block_footer(wdh, block_content_length, err);
5856}
5857
5858static 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)
5859{
5860 uint32_t size;
5861
5862 switch(option_id)
5863 {
5864 case OPT_IDB_NAME2:
5865 case OPT_IDB_DESCRIPTION3:
5866 case OPT_IDB_OS12:
5867 case OPT_IDB_HARDWARE15:
5868 size = pcapng_compute_string_option_size(optval);
5869 break;
5870 case OPT_IDB_SPEED8:
5871 size = 8;
5872 break;
5873 case OPT_IDB_TSRESOL9:
5874 size = 1;
5875 break;
5876 case OPT_IDB_FILTER11:
5877 size = pcapng_compute_if_filter_option_size(optval);
5878 break;
5879 case OPT_IDB_FCSLEN13:
5880 size = 1;
5881 break;
5882 case OPT_IDB_TSOFFSET14:
5883 size = 8;
5884 break;
5885 default:
5886 /* Unknown options - size by datatype? */
5887 size = 0;
5888 break;
5889 }
5890 return size;
5891}
5892
5893static bool_Bool write_wtap_idb_option(wtap_dumper *wdh, wtap_block_t block _U___attribute__((unused)),
5894 unsigned option_id,
5895 wtap_opttype_e option_type _U___attribute__((unused)),
5896 wtap_optval_t *optval,
5897 int *err, char **err_info)
5898{
5899 switch(option_id)
5900 {
5901 case OPT_IDB_NAME2:
5902 case OPT_IDB_DESCRIPTION3:
5903 case OPT_IDB_OS12:
5904 case OPT_IDB_HARDWARE15:
5905 if (!pcapng_write_string_option(wdh, OPT_SECTION_BYTE_ORDER,
5906 option_id, optval, err, err_info))
5907 return false0;
5908 break;
5909 case OPT_IDB_SPEED8:
5910 if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5911 return false0;
5912 break;
5913 case OPT_IDB_TSRESOL9:
5914 if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
5915 return false0;
5916 break;
5917 case OPT_IDB_FILTER11:
5918 if (!pcapng_write_if_filter_option(wdh, option_id, optval, err))
5919 return false0;
5920 break;
5921 case OPT_IDB_FCSLEN13:
5922 if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
5923 return false0;
5924 break;
5925 case OPT_IDB_TSOFFSET14:
5926 if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5927 return false0;
5928 break;
5929 break;
5930 default:
5931 /* Unknown options - size by datatype? */
5932 break;
5933 }
5934 return true1;
5935}
5936
5937static bool_Bool
5938pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data,
5939 int *err, char **err_info)
5940{
5941 uint32_t block_content_length;
5942 pcapng_interface_description_block_t idb;
5943 uint32_t options_size;
5944 wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5945 int link_type;
5946
5947 ws_debug("encap = %d (%s), snaplen = %d",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5950, __func__, "encap = %d (%s), snaplen = %d", mand_data->
wtap_encap, wtap_encap_description(mand_data->wtap_encap),
mand_data->snap_len); } } while (0)
5948 mand_data->wtap_encap,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5950, __func__, "encap = %d (%s), snaplen = %d", mand_data->
wtap_encap, wtap_encap_description(mand_data->wtap_encap),
mand_data->snap_len); } } while (0)
5949 wtap_encap_description(mand_data->wtap_encap),do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5950, __func__, "encap = %d (%s), snaplen = %d", mand_data->
wtap_encap, wtap_encap_description(mand_data->wtap_encap),
mand_data->snap_len); } } while (0)
5950 mand_data->snap_len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 5950, __func__, "encap = %d (%s), snaplen = %d", mand_data->
wtap_encap, wtap_encap_description(mand_data->wtap_encap),
mand_data->snap_len); } } while (0)
;
5951
5952 link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap);
5953 if (link_type == -1) {
5954 if (!pcapng_encap_is_ft_specific(mand_data->wtap_encap)) {
5955 *err = WTAP_ERR_UNWRITABLE_ENCAP-8;
5956 return false0;
5957 }
5958 }
5959
5960 /* Compute size of all the options */
5961 options_size = pcapng_compute_options_size(int_data, compute_idb_option_size);
5962
5963 /* write block header */
5964 block_content_length = (uint32_t)sizeof(idb) + options_size;
5965 if (!pcapng_write_block_header(wdh, BLOCK_TYPE_IDB0x00000001, block_content_length,
5966 err))
5967 return false0;
5968
5969 /* write block fixed content */
5970 idb.linktype = link_type;
5971 idb.reserved = 0;
5972 idb.snaplen = mand_data->snap_len;
5973
5974 if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
5975 return false0;
5976
5977 if (options_size != 0) {
5978 /* Write options */
5979 if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
5980 int_data, write_wtap_idb_option,
5981 err, err_info))
5982 return false0;
5983 }
5984
5985 /* write block footer */
5986 return pcapng_write_block_footer(wdh, block_content_length, err);
5987}
5988
5989static bool_Bool pcapng_add_idb(wtap_dumper *wdh, wtap_block_t idb,
5990 int *err, char **err_info)
5991{
5992 /*
5993 * Write it to the output file.
5994 */
5995 return pcapng_write_if_descr_block(wdh, idb, err, err_info);
5996}
5997
5998static bool_Bool pcapng_write_internal_blocks(wtap_dumper *wdh, int *err)
5999{
6000
6001 /* Write (optional) Decryption Secrets Blocks that were collected while
6002 * reading packet blocks. */
6003 if (wdh->dsbs_growing) {
6004 for (unsigned i = wdh->dsbs_growing_written; i < wdh->dsbs_growing->len; i++) {
6005 ws_debug("writing DSB %u", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6005, __func__, "writing DSB %u", i); } } while (0)
;
6006 wtap_block_t dsb = g_array_index(wdh->dsbs_growing, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->dsbs_growing)->data) [
(i)])
;
6007 if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6008 return false0;
6009 }
6010 ++wdh->dsbs_growing_written;
6011 }
6012 }
6013
6014 /* Write (optional) Sysdig Meta Event Blocks that were collected while
6015 * reading packet blocks. */
6016 if (wdh->mevs_growing) {
6017 for (unsigned i = wdh->mevs_growing_written; i < wdh->mevs_growing->len; i++) {
6018 ws_debug("writing Sysdig mev %u", i)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6018, __func__, "writing Sysdig mev %u", i); } } while (0)
;
6019 wtap_block_t mev = g_array_index(wdh->mevs_growing, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->mevs_growing)->data) [
(i)])
;
6020 if (!pcapng_write_meta_event_block(wdh, mev, err)) {
6021 return false0;
6022 }
6023 ++wdh->mevs_growing_written;
6024 }
6025 }
6026
6027 /* Write any hostname resolution info from wtap_dump_set_addrinfo_list() */
6028 if (!wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
6029 /*
6030 * XXX: get_addrinfo_list() returns a list of all known and used
6031 * resolved addresses, regardless of origin: existing NRBs, externally
6032 * resolved, DNS packet data, a hosts file, and manual host resolution
6033 * through the GUI. It does not include the source for each.
6034 *
6035 * If it did, we could instead create multiple NRBs, one for each
6036 * server (as the options can only be included once per block.)
6037 * Instead, we copy the options from the first already existing NRB
6038 * (if there is one), since some of the name resolutions may be
6039 * from that block.
6040 */
6041 wtap_block_t nrb;
6042 if (wdh->nrbs_growing && wdh->nrbs_growing->len) {
6043 nrb = wtap_block_make_copy(g_array_index(wdh->nrbs_growing, wtap_block_t, 0)(((wtap_block_t*) (void *) (wdh->nrbs_growing)->data) [
(0)])
);
6044 } else {
6045 nrb = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
6046 }
6047 wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(nrb);
6048 mand_data->ipv4_addr_list = wdh->addrinfo_lists->ipv4_addr_list;
6049 mand_data->ipv6_addr_list = wdh->addrinfo_lists->ipv6_addr_list;
6050
6051 if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
6052 return false0;
6053 }
6054 mand_data->ipv4_addr_list = NULL((void*)0);
6055 mand_data->ipv6_addr_list = NULL((void*)0);
6056 wtap_block_unref(nrb);
6057 g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
6058 wdh->addrinfo_lists->ipv4_addr_list = NULL((void*)0);
6059 g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
6060 wdh->addrinfo_lists->ipv6_addr_list = NULL((void*)0);
6061 /* Since the addrinfo lists include information from existing NRBs,
6062 * avoid writing them to avoid duplication.
6063 *
6064 * XXX: Perhaps we don't want to include information from the NRBs
6065 * in get_addrinfo_list at all, so that we could write existing
6066 * NRBs as-is.
6067 *
6068 * This is still not well oriented for one-pass programs, where we
6069 * don't have addrinfo_lists until we've already written the
6070 * NRBs. We should not write both in such a situation. See bug 15502.
6071 */
6072 wtap_dump_discard_name_resolution(wdh);
6073 }
6074
6075 /* Write (optional) Name Resolution Blocks that were collected while
6076 * reading packet blocks. */
6077 if (wdh->nrbs_growing) {
6078 for (unsigned i = wdh->nrbs_growing_written; i < wdh->nrbs_growing->len; i++) {
6079 wtap_block_t nrb = g_array_index(wdh->nrbs_growing, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->nrbs_growing)->data) [
(i)])
;
6080 if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
6081 return false0;
6082 }
6083 ++wdh->nrbs_growing_written;
6084 }
6085 }
6086
6087 return true1;
6088}
6089
6090static bool_Bool pcapng_dump(wtap_dumper *wdh, const wtap_rec *rec,
6091 int *err, char **err_info)
6092{
6093 uint32_t block_type;
6094 pcapng_block_type_information_t* handler;
6095
6096 if (!pcapng_write_internal_blocks(wdh, err)) {
6097 return false0;
6098 }
6099
6100 ws_debug("encap = %d (%s) rec type = %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6103, __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)
6101 rec->rec_header.packet_header.pkt_encap,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6103, __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)
6102 wtap_encap_description(rec->rec_header.packet_header.pkt_encap),do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6103, __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)
6103 rec->rec_type)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6103, __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)
;
6104
6105 switch (rec->rec_type) {
6106
6107 case REC_TYPE_PACKET0:
6108 /* Write Simple Packet Block if appropriate, Enhanced Packet Block otherwise. */
6109 if (!(rec->presence_flags & WTAP_HAS_TS0x00000001) &&
6110 (!(rec->presence_flags & WTAP_HAS_INTERFACE_ID0x00000004) || rec->rec_header.packet_header.interface_id == 0) &&
6111 (!(rec->presence_flags & WTAP_HAS_CAP_LEN0x00000002) || rec->rec_header.packet_header.len == rec->rec_header.packet_header.caplen) &&
6112 (rec->block == NULL((void*)0) || pcapng_compute_options_size(rec->block, compute_epb_option_size) == 0)) {
6113 block_type = BLOCK_TYPE_SPB0x00000003;
6114 }
6115 else {
6116 block_type = BLOCK_TYPE_EPB0x00000006;
6117 }
6118 break;
6119
6120 case REC_TYPE_FT_SPECIFIC_EVENT1:
6121 case REC_TYPE_FT_SPECIFIC_REPORT2:
6122 /*
6123 * Is this an event or report for our file type?
6124 */
6125 if (rec->rec_header.ft_specific_header.file_type_subtype != pcapng_file_type_subtype) {
6126 /*
6127 * No. We can't write that.
6128 */
6129 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
6130 *err_info = g_strdup_printf("%s records for \"%s\" files aren't supported for this file type",
6131 rec->rec_type_name,
6132 wtap_file_type_subtype_name(rec->rec_header.ft_specific_header.file_type_subtype));
6133 return false0;
6134 }
6135
6136 block_type = rec->rec_header.ft_specific_header.record_type;
6137 break;
6138
6139 case REC_TYPE_SYSCALL3:
6140 block_type = rec->rec_header.syscall_header.record_type;
6141 break;
6142
6143 case REC_TYPE_SYSTEMD_JOURNAL_EXPORT4:
6144 block_type = BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT0x00000009;
6145 break;
6146
6147 case REC_TYPE_CUSTOM_BLOCK5:
6148 {
6149 /* Don't write anything we are not supposed to. */
6150 if (!rec->rec_header.custom_block_header.copy_allowed) {
6151 return true1;
6152 }
6153 block_type = BLOCK_TYPE_CB_COPY0x00000BAD;
6154 break;
6155 }
6156
6157 default:
6158 /* We don't support writing this record type. */
6159 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
6160 *err_info = wtap_unwritable_rec_type_err_string(rec);
6161 return false0;
6162 }
6163
6164 /*
6165 * Do we have a handler for this block type?
6166 */
6167 handler = (pcapng_block_type_information_t*)g_hash_table_lookup(block_handlers,
6168 GUINT_TO_POINTER(block_type)((gpointer) (gulong) (block_type)));
6169 if (handler == NULL((void*)0)) {
6170 /* No. We can't write that. */
6171 *err = WTAP_ERR_UNWRITABLE_REC_TYPE-24;
6172 *err_info = g_strdup_printf("Pcapng blocks of type 0x%8x aren't supported",
6173 rec->rec_header.ft_specific_header.record_type);
6174 return false0;
6175 }
6176
6177 /* Yes. Call it to write out this record. */
6178 return handler->writer(wdh, rec, err, err_info);
6179}
6180
6181/*
6182 * Write block header.
6183 */
6184bool_Bool
6185pcapng_write_block_header(wtap_dumper *wdh, uint32_t block_type,
6186 uint32_t block_content_length, int *err)
6187{
6188 pcapng_block_header_t bh;
6189
6190 bh.block_type = block_type;
6191 /*
6192 * Total block length is the length of the header plus the length
6193 * of the block content (which is padded to a multiple of 4 bytes)
6194 * plus the length of the trailer.
6195 */
6196 bh.block_total_length = (uint32_t)sizeof(pcapng_block_header_t) + block_content_length + 4;
6197 ws_debug("Total len %u", bh.block_total_length)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6197, __func__, "Total len %u", bh.block_total_length); } }
while (0)
;
6198 return wtap_dump_file_write(wdh, &bh, sizeof bh, err);
6199}
6200
6201/*
6202 * Write block footer.
6203 */
6204bool_Bool
6205pcapng_write_block_footer(wtap_dumper *wdh, uint32_t block_content_length,
6206 int *err)
6207{
6208 uint32_t bf;
6209
6210 bf = (uint32_t)sizeof(pcapng_block_header_t) + block_content_length + 4;
6211 return wtap_dump_file_write(wdh, &bf, sizeof bf, err);
6212}
6213
6214/* Finish writing to a dump file.
6215 Returns true on success, false on failure. */
6216static bool_Bool pcapng_dump_finish(wtap_dumper *wdh, int *err, char **err_info)
6217{
6218 unsigned i, j;
6219
6220 /* Flush any hostname resolution or decryption secrets info we may have */
6221 if (!pcapng_write_internal_blocks(wdh, err)) {
6222 return false0;
6223 }
6224
6225 for (i = 0; i < wdh->interface_data->len; i++) {
6226
6227 /* Get the interface description */
6228 wtap_block_t int_data;
6229 wtapng_if_descr_mandatory_t *int_data_mand;
6230
6231 int_data = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
6232 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
6233
6234 for (j = 0; j < int_data_mand->num_stat_entries; j++) {
6235 wtap_block_t if_stats;
6236
6237 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)])
;
6238 ws_debug("write ISB for interface %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6239, __func__, "write ISB for interface %u", ((wtapng_if_stats_mandatory_t
*)wtap_block_get_mandatory_data(if_stats))->interface_id);
} } while (0)
6239 ((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"
, 6239, __func__, "write ISB for interface %u", ((wtapng_if_stats_mandatory_t
*)wtap_block_get_mandatory_data(if_stats))->interface_id);
} } while (0)
;
6240 if (!pcapng_write_interface_statistics_block(wdh, if_stats,
6241 err, err_info)) {
6242 return false0;
6243 }
6244 }
6245 }
6246
6247 ws_debug("leaving function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6247, __func__, "leaving function"); } } while (0)
;
6248 return true1;
6249}
6250
6251/* Returns true on success, false on failure; sets "*err" to an error code on
6252 failure */
6253static bool_Bool
6254pcapng_dump_open(wtap_dumper *wdh, int *err, char **err_info)
6255{
6256 unsigned i;
6257
6258 ws_debug("entering function")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6258, __func__, "entering function"); } } while (0)
;
6259 /* This is a pcapng file */
6260 wdh->subtype_add_idb = pcapng_add_idb;
6261 wdh->subtype_write = pcapng_dump;
6262 wdh->subtype_finish = pcapng_dump_finish;
6263
6264 /* write the section header block */
6265 if (!pcapng_write_section_header_block(wdh, err, err_info)) {
6266 return false0;
6267 }
6268 ws_debug("wrote section header block.")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6268, __func__, "wrote section header block."); } } while (
0)
;
6269
6270 /* Write the Interface description blocks */
6271 ws_debug("Number of IDBs to write (number of interfaces) %u",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6272, __func__, "Number of IDBs to write (number of interfaces) %u"
, wdh->interface_data->len); } } while (0)
6272 wdh->interface_data->len)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6272, __func__, "Number of IDBs to write (number of interfaces) %u"
, wdh->interface_data->len); } } while (0)
;
6273
6274 for (i = 0; i < wdh->interface_data->len; i++) {
6275
6276 /* Get the interface description */
6277 wtap_block_t idb;
6278
6279 idb = g_array_index(wdh->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->interface_data)->data)
[(i)])
;
6280
6281 if (!pcapng_write_if_descr_block(wdh, idb, err, err_info)) {
6282 return false0;
6283 }
6284
6285 }
6286
6287 /* Write (optional) fixed Decryption Secrets Blocks. */
6288 if (wdh->dsbs_initial) {
6289 for (i = 0; i < wdh->dsbs_initial->len; i++) {
6290 wtap_block_t dsb = g_array_index(wdh->dsbs_initial, wtap_block_t, i)(((wtap_block_t*) (void *) (wdh->dsbs_initial)->data) [
(i)])
;
6291 if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6292 return false0;
6293 }
6294 }
6295 }
6296
6297 return true1;
6298}
6299
6300/* Returns 0 if we could write the specified encapsulation type,
6301 an error indication otherwise. */
6302static int pcapng_dump_can_write_encap(int wtap_encap)
6303{
6304 ws_debug("encap = %d (%s)",do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6306, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
6305 wtap_encap,do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6306, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
6306 wtap_encap_description(wtap_encap))do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/pcapng.c"
, 6306, __func__, "encap = %d (%s)", wtap_encap, wtap_encap_description
(wtap_encap)); } } while (0)
;
6307
6308 /* Per-packet encapsulation is supported. */
6309 if (wtap_encap == WTAP_ENCAP_PER_PACKET-1)
6310 return 0;
6311
6312 /* No encapsulation type (yet) is supported. */
6313 if (wtap_encap == WTAP_ENCAP_NONE-2)
6314 return 0;
6315
6316 /* Is it a filetype-specific encapsulation that we support? */
6317 if (pcapng_encap_is_ft_specific(wtap_encap)) {
6318 return 0;
6319 }
6320
6321 /* Make sure we can figure out this DLT type */
6322 if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
6323 return WTAP_ERR_UNWRITABLE_ENCAP-8;
6324
6325 return 0;
6326}
6327
6328/*
6329 * Returns true if the specified encapsulation type is filetype-specific
6330 * and one that we support.
6331 */
6332bool_Bool pcapng_encap_is_ft_specific(int encap)
6333{
6334 switch (encap) {
6335 case WTAP_ENCAP_SYSTEMD_JOURNAL203:
6336 return true1;
6337 }
6338 return false0;
6339}
6340
6341/*
6342 * pcapng supports several block types, and supports more than one
6343 * of them.
6344 *
6345 * It also supports comments for many block types, as well as other
6346 * option types.
6347 */
6348
6349/* Options for section blocks. */
6350static const struct supported_option_type section_block_options_supported[] = {
6351 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6352 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6353 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6354 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6355 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED },
6356 { OPT_SHB_HARDWARE2, ONE_OPTION_SUPPORTED },
6357 { OPT_SHB_USERAPPL4, ONE_OPTION_SUPPORTED }
6358};
6359
6360/* Options for interface blocks. */
6361static const struct supported_option_type interface_block_options_supported[] = {
6362 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6363 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6364 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6365 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6366 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED },
6367 { OPT_IDB_NAME2, ONE_OPTION_SUPPORTED },
6368 { OPT_IDB_DESCRIPTION3, ONE_OPTION_SUPPORTED },
6369 { OPT_IDB_IP4ADDR4, MULTIPLE_OPTIONS_SUPPORTED },
6370 { OPT_IDB_IP6ADDR5, MULTIPLE_OPTIONS_SUPPORTED },
6371 { OPT_IDB_MACADDR6, ONE_OPTION_SUPPORTED },
6372 { OPT_IDB_EUIADDR7, ONE_OPTION_SUPPORTED },
6373 { OPT_IDB_SPEED8, ONE_OPTION_SUPPORTED },
6374 { OPT_IDB_TSRESOL9, ONE_OPTION_SUPPORTED },
6375 { OPT_IDB_TZONE10, ONE_OPTION_SUPPORTED },
6376 { OPT_IDB_FILTER11, ONE_OPTION_SUPPORTED },
6377 { OPT_IDB_OS12, ONE_OPTION_SUPPORTED },
6378 { OPT_IDB_FCSLEN13, ONE_OPTION_SUPPORTED },
6379 { OPT_IDB_TSOFFSET14, ONE_OPTION_SUPPORTED },
6380 { OPT_IDB_HARDWARE15, ONE_OPTION_SUPPORTED },
6381 { OPT_IDB_TXSPEED16, ONE_OPTION_SUPPORTED },
6382 { OPT_IDB_RXSPEED17, ONE_OPTION_SUPPORTED },
6383 { OPT_IDB_IANA_TZNAME18, ONE_OPTION_SUPPORTED }
6384};
6385
6386/* Options for name resolution blocks. */
6387static const struct supported_option_type name_resolution_block_options_supported[] = {
6388 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6389 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6390 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6391 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6392 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED },
6393 { OPT_NS_DNSNAME2, ONE_OPTION_SUPPORTED },
6394 { OPT_NS_DNSIP4ADDR3, ONE_OPTION_SUPPORTED },
6395 { OPT_NS_DNSIP6ADDR4, ONE_OPTION_SUPPORTED }
6396};
6397
6398/* Options for interface statistics blocks. */
6399static const struct supported_option_type interface_statistics_block_options_supported[] = {
6400 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6401 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6402 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6403 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6404 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED },
6405 { OPT_ISB_STARTTIME2, ONE_OPTION_SUPPORTED },
6406 { OPT_ISB_ENDTIME3, ONE_OPTION_SUPPORTED },
6407 { OPT_ISB_IFRECV4, ONE_OPTION_SUPPORTED },
6408 { OPT_ISB_IFDROP5, ONE_OPTION_SUPPORTED },
6409 { OPT_ISB_FILTERACCEPT6, ONE_OPTION_SUPPORTED },
6410 { OPT_ISB_OSDROP7, ONE_OPTION_SUPPORTED },
6411 { OPT_ISB_USRDELIV8, ONE_OPTION_SUPPORTED }
6412};
6413
6414/* Options for decryption secrets blocks. */
6415static const struct supported_option_type decryption_secrets_block_options_supported[] = {
6416 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6417 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6418 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6419 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6420 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6421};
6422
6423/* Options for meta event blocks. */
6424static const struct supported_option_type meta_events_block_options_supported[] = {
6425 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6426 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6427 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6428 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6429 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6430};
6431
6432/* Options for packet blocks. */
6433static const struct supported_option_type packet_block_options_supported[] = {
6434 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6435 { OPT_PKT_FLAGS2, ONE_OPTION_SUPPORTED },
6436 { OPT_PKT_HASH3, MULTIPLE_OPTIONS_SUPPORTED },
6437 { OPT_PKT_DROPCOUNT4, ONE_OPTION_SUPPORTED },
6438 { OPT_PKT_PACKETID5, ONE_OPTION_SUPPORTED },
6439 { OPT_PKT_QUEUE6, ONE_OPTION_SUPPORTED },
6440 { OPT_PKT_VERDICT7, MULTIPLE_OPTIONS_SUPPORTED },
6441 { OPT_PKT_PROCIDTHRDID8, ONE_OPTION_SUPPORTED },
6442 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6443 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6444 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6445 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6446};
6447
6448/* Options for file-type-specific reports. */
6449static const struct supported_option_type ft_specific_report_block_options_supported[] = {
6450 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6451 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6452 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6453 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6454 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6455};
6456
6457/* Options for file-type-specific event. */
6458static const struct supported_option_type ft_specific_event_block_options_supported[] = {
6459 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6460 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6461 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6462 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6463 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6464};
6465
6466/* Options for systemd journal entry. */
6467static const struct supported_option_type systemd_journal_export_block_options_supported[] = {
6468 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
6469 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
6470 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
6471 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
6472 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
6473};
6474
6475static const struct supported_block_type pcapng_blocks_supported[] = {
6476 /* Multiple sections. */
6477 { 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
},
6478
6479 /* Multiple interfaces. */
6480 { 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
},
6481
6482 /* Multiple blocks of name resolution information */
6483 { 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
},
6484
6485 /* Multiple blocks of interface statistics. */
6486 { 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
},
6487
6488 /* Multiple blocks of decryption secrets. */
6489 { 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
},
6490
6491 /* Multiple blocks of meta evens.. */
6492 { 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
},
6493
6494 /* And, obviously, multiple packets. */
6495 { 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
},
6496
6497 /* Multiple file-type specific reports (including local ones). */
6498 { 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
},
6499
6500 /* Multiple file-type specific events (including local ones). */
6501 { 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
},
6502
6503 /* Multiple systemd journal export records. */
6504 { 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
},
6505
6506 /* Multiple custom blocks. */
6507 { WTAP_BLOCK_CUSTOM, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED0, ((void*)0) },
6508};
6509
6510static const struct file_type_subtype_info wireshark_pcapng_info = {
6511 "Wireshark/... - pcapng", "pcapng", "pcapng", "ntar",
6512 false0, BLOCKS_SUPPORTED(pcapng_blocks_supported)(sizeof (pcapng_blocks_supported) / sizeof (pcapng_blocks_supported
)[0]), pcapng_blocks_supported
,
6513 pcapng_dump_can_write_encap, pcapng_dump_open, NULL((void*)0)
6514};
6515
6516static const struct file_type_subtype_info stratoshark_pcapng_info = {
6517 "Stratoshark/... - scap", "scap", "scap", "scap",
6518 false0, BLOCKS_SUPPORTED(pcapng_blocks_supported)(sizeof (pcapng_blocks_supported) / sizeof (pcapng_blocks_supported
)[0]), pcapng_blocks_supported
,
6519 pcapng_dump_can_write_encap, pcapng_dump_open, NULL((void*)0)
6520};
6521
6522void register_pcapng(void)
6523{
6524 if (application_flavor_is_wireshark()) {
6525 pcapng_file_type_subtype = wtap_register_file_type_subtype(&wireshark_pcapng_info);
6526 } else {
6527 pcapng_file_type_subtype = wtap_register_file_type_subtype(&stratoshark_pcapng_info);
6528 }
6529
6530 wtap_register_backwards_compatibility_lua_name("PCAPNG",
6531 pcapng_file_type_subtype);
6532
6533 /* Setup the tables that will be used to handle custom block options */
6534
6535 /*
6536 * Create the table of option handlers for this block type.
6537 *
6538 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
6539 * so we use "g_direct_hash()" and "g_direct_equal()".
6540 */
6541 block_handlers = g_hash_table_new_full(g_direct_hash,
6542 g_direct_equal,
6543 NULL((void*)0), g_free);
6544
6545 custom_enterprise_handlers = g_hash_table_new_full(g_direct_hash,
6546 g_direct_equal,
6547 NULL((void*)0), g_free);
6548
6549 /* SHBs require special handling, so they don't have handlers here. */
6550 static pcapng_block_type_information_t SHB = { BLOCK_TYPE_SHB0x0A0D0D0A, NULL((void*)0), NULL((void*)0), NULL((void*)0), true1, NULL((void*)0) };
6551 SHB.option_handlers = pcapng_create_option_handler_table();
6552 register_pcapng_block_type_information(&SHB);
6553
6554 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) };
6555 IDB.option_handlers = pcapng_create_option_handler_table();
6556 register_pcapng_block_type_information(&IDB);
6557
6558 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) };
6559 EPB.option_handlers = pcapng_create_option_handler_table();
6560 register_pcapng_block_type_information(&EPB);
6561
6562 static pcapng_block_type_information_t PB = { BLOCK_TYPE_PB0x00000002, pcapng_read_packet_block, NULL((void*)0), NULL((void*)0), false0, NULL((void*)0) };
6563 /* PBs and EPBs have the same options. */
6564 PB.option_handlers = EPB.option_handlers;
6565 register_pcapng_block_type_information(&PB);
6566
6567 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) };
6568 /* SPBs don't support options */
6569 register_pcapng_block_type_information(&SPB);
6570
6571 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) };
6572 NRB.option_handlers = pcapng_create_option_handler_table();
6573 register_pcapng_block_type_information(&NRB);
6574
6575 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) };
6576 ISB.option_handlers = pcapng_create_option_handler_table();
6577 register_pcapng_block_type_information(&ISB);
6578
6579 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) };
6580 DSB.option_handlers = pcapng_create_option_handler_table();
6581 register_pcapng_block_type_information(&DSB);
6582
6583 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) };
6584 CB_COPY.option_handlers = pcapng_create_option_handler_table();
6585 register_pcapng_block_type_information(&CB_COPY);
6586
6587 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) };
6588 /* Copy and no-copy and CBs have the same options. */
6589 CB_NO_COPY.option_handlers = CB_COPY.option_handlers;
6590 register_pcapng_block_type_information(&CB_NO_COPY);
6591
6592 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) };
6593 SYSTEMD_JOURNAL_EXPORT.option_handlers = pcapng_create_option_handler_table();
6594 register_pcapng_block_type_information(&SYSTEMD_JOURNAL_EXPORT);
6595}
6596
6597/*
6598 * Editor modelines - https://www.wireshark.org/tools/modelines.html
6599 *
6600 * Local variables:
6601 * c-basic-offset: 4
6602 * tab-width: 8
6603 * indent-tabs-mode: nil
6604 * End:
6605 *
6606 * vi: set shiftwidth=4 tabstop=8 expandtab:
6607 * :indentSize=4:tabSize=8:noTabs=true:
6608 */