Revert "UNUSED enc_key_id_{equal,hash}"
[wireshark-sm.git] / wiretap / pcapng.c
blob6056952ec72b4c4e7c8af750c9c01546c8ba809c
1 /* pcapng.c
3 * Wiretap Library
4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * File format support for pcapng file format
7 * Copyright (c) 2007 by Ulf Lamping <ulf.lamping@web.de>
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 /* File format specification:
13 * https://github.com/pcapng/pcapng
14 * Related Wiki page:
15 * https://gitlab.com/wireshark/wireshark/-/wikis/Development/PcapNg
18 #include "config.h"
19 #define WS_LOG_DOMAIN LOG_DOMAIN_WIRETAP
20 #include "pcapng.h"
22 #include "wtap_opttypes.h"
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
28 #include <wsutil/wslog.h>
29 #include <wsutil/strtoi.h>
30 #include <wsutil/glib-compat.h>
31 #include <wsutil/ws_assert.h>
32 #include <wsutil/ws_roundup.h>
33 #include <wsutil/unicode-utils.h>
35 #include "wtap-int.h"
36 #include "file_wrappers.h"
37 #include "required_file_handlers.h"
38 #include "pcap-common.h"
39 #include "pcap-encap.h"
40 #include "pcapng_module.h"
41 #include "secrets-types.h"
43 #define ROUND_TO_4BYTE(len) WS_ROUNDUP_4(len)
45 static bool
46 pcapng_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err,
47 char **err_info, int64_t *data_offset);
48 static bool
49 pcapng_seek_read(wtap *wth, int64_t seek_off,
50 wtap_rec *rec, Buffer *buf, int *err, char **err_info);
51 static void
52 pcapng_close(wtap *wth);
54 static bool
55 pcapng_encap_is_ft_specific(int encap);
57 static bool
58 pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data, int *err);
61 * Minimum block size = size of block header + size of block trailer.
63 #define MIN_BLOCK_SIZE ((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t)))
66 * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
68 #define MIN_SHB_SIZE ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
70 /* pcapng: packet block file encoding (obsolete) */
71 typedef struct pcapng_packet_block_s {
72 uint16_t interface_id;
73 uint16_t drops_count;
74 uint32_t timestamp_high;
75 uint32_t timestamp_low;
76 uint32_t captured_len;
77 uint32_t packet_len;
78 /* ... Packet Data ... */
79 /* ... Padding ... */
80 /* ... Options ... */
81 } pcapng_packet_block_t;
84 * Minimum PB size = minimum block size + size of fixed length portion of PB.
86 #define MIN_PB_SIZE ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
88 /* pcapng: enhanced packet block file encoding */
89 typedef 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;
101 * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
103 #define MIN_EPB_SIZE ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
105 /* pcapng: simple packet block file encoding */
106 typedef struct pcapng_simple_packet_block_s {
107 uint32_t packet_len;
108 /* ... Packet Data ... */
109 /* ... Padding ... */
110 } pcapng_simple_packet_block_t;
113 * Minimum SPB size = minimum block size + size of fixed length portion of SPB.
115 #define MIN_SPB_SIZE ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
117 /* pcapng: name resolution block file encoding */
118 typedef struct pcapng_name_resolution_block_s {
119 uint16_t record_type;
120 uint16_t record_len;
121 /* ... Record ... */
122 } pcapng_name_resolution_block_t;
125 * Minimum NRB size = minimum block size + size of smallest NRB record
126 * (there must at least be an "end of records" record).
128 #define MIN_NRB_SIZE ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
130 /* pcapng: custom block file encoding */
131 typedef struct pcapng_custom_block_s {
132 uint32_t pen;
133 /* Custom data and options */
134 } pcapng_custom_block_t;
137 * Minimum CB size = minimum block size + size of fixed length portion of CB.
140 #define MIN_CB_SIZE ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_custom_block_t)))
143 * Minimum ISB size = minimum block size + size of fixed length portion of ISB.
145 #define MIN_ISB_SIZE ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
148 * Minimum Sysdig size = minimum block size + packed size of sysdig_event_phdr.
149 * Minimum Sysdig event v2 header size = minimum block size + packed size of sysdig_event_v2_phdr (which, in addition
150 * to sysdig_event_phdr, includes the nparams 32bit value).
152 #define SYSDIG_EVENT_HEADER_SIZE ((16 + 64 + 64 + 32 + 16)/8) /* CPU ID + TS + TID + Event len + Event type */
153 #define MIN_SYSDIG_EVENT_SIZE ((uint32_t)(MIN_BLOCK_SIZE + SYSDIG_EVENT_HEADER_SIZE))
154 #define SYSDIG_EVENT_V2_HEADER_SIZE ((16 + 64 + 64 + 32 + 16 + 32)/8) /* CPU ID + TS + TID + Event len + Event type + nparams */
155 #define MIN_SYSDIG_EVENT_V2_SIZE ((uint32_t)(MIN_BLOCK_SIZE + SYSDIG_EVENT_V2_HEADER_SIZE))
158 * We require __REALTIME_TIMESTAMP in the Journal Export Format reader in
159 * order to set each packet timestamp. Require it here as well, although
160 * it's not strictly necessary.
162 #define SDJ__REALTIME_TIMESTAMP "__REALTIME_TIMESTAMP="
163 #define MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE 23 // "__REALTIME_TIMESTAMP=0\n"
164 #define MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE ((uint32_t)(MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE + MIN_BLOCK_SIZE))
166 /* pcapng: common option header file encoding for every option type */
167 typedef struct pcapng_option_header_s {
168 uint16_t option_code;
169 uint16_t option_length;
170 /* ... x bytes Option Body ... */
171 /* ... Padding ... */
172 } pcapng_option_header_t;
174 struct pcapng_option {
175 uint16_t type;
176 uint16_t value_length;
179 /* Option codes: 16-bit field */
180 #define OPT_EPB_FLAGS 0x0002
181 #define OPT_EPB_HASH 0x0003
182 #define OPT_EPB_DROPCOUNT 0x0004
183 #define OPT_EPB_PACKETID 0x0005
184 #define OPT_EPB_QUEUE 0x0006
185 #define OPT_EPB_VERDICT 0x0007
187 #define OPT_NRB_DNSNAME 0x0002
188 #define OPT_NRB_DNSV4ADDR 0x0003
189 #define OPT_NRB_DNSV6ADDR 0x0004
191 /* MSBit of option code means "local type" */
192 #define OPT_LOCAL_FLAG 0x8000
194 /* OPT_EPB_VERDICT sub-types */
195 #define OPT_VERDICT_TYPE_HW 0
196 #define OPT_VERDICT_TYPE_TC 1
197 #define OPT_VERDICT_TYPE_XDP 2
199 /* OPT_EPB_HASH sub-types */
200 #define OPT_HASH_2COMP 0
201 #define OPT_HASH_XOR 1
202 #define OPT_HASH_CRC32 2
203 #define OPT_HASH_MD5 3
204 #define OPT_HASH_SHA1 4
205 #define OPT_HASH_TOEPLITZ 5
208 * In order to keep from trying to allocate large chunks of memory,
209 * which could either fail or, even if it succeeds, chew up so much
210 * address space or memory+backing store as not to leave room for
211 * anything else, we impose upper limits on the size of blocks we're
212 * willing to handle.
214 * We pick a limit of an EPB with a maximum-sized D-Bus packet and 128 KiB
215 * worth of options; we use the maximum D-Bus packet size as that's larger
216 * than the maximum packet size for other link-layer types, and the maximum
217 * packet size for other link-layer types is currently small enough that
218 * the resulting block size would be less than the previous 16 MiB limit.
220 #define MAX_BLOCK_SIZE (MIN_EPB_SIZE + WTAP_MAX_PACKET_SIZE_DBUS + 131072)
222 /* Note: many of the defined structures for block data are defined in wtap.h */
224 /* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
225 typedef struct wtapng_packet_s {
226 /* mandatory */
227 uint32_t ts_high; /* seconds since 1.1.1970 */
228 uint32_t ts_low; /* fraction of seconds, depends on if_tsresol */
229 uint32_t cap_len; /* data length in the file */
230 uint32_t packet_len; /* data length on the wire */
231 uint32_t interface_id; /* identifier of the interface. */
232 uint16_t drops_count; /* drops count, only valid for packet block */
233 /* 0xffff if information no available */
234 /* pack_hash */
235 /* XXX - put the packet data / pseudo_header here as well? */
236 } wtapng_packet_t;
238 /* Simple Packet data */
239 typedef struct wtapng_simple_packet_s {
240 /* mandatory */
241 uint32_t cap_len; /* data length in the file */
242 uint32_t packet_len; /* data length on the wire */
243 /* XXX - put the packet data / pseudo_header here as well? */
244 } wtapng_simple_packet_t;
246 /* Interface data in private struct */
247 typedef struct interface_info_s {
248 int wtap_encap;
249 uint32_t snap_len;
250 uint64_t time_units_per_second;
251 int tsprecision;
252 int64_t tsoffset;
253 int fcslen;
254 } interface_info_t;
256 typedef struct {
257 unsigned current_section_number; /**< Section number of the current section being read sequentially */
258 GArray *sections; /**< Sections found in the capture file. */
259 } pcapng_t;
262 * Table for plugins to handle particular block types.
264 * A handler has a "read" routine and a "write" routine.
266 * A "read" routine returns a block as a libwiretap record, filling
267 * in the wtap_rec structure with the appropriate record type and
268 * other information, and filling in the supplied Buffer with
269 * data for which there's no place in the wtap_rec structure.
271 * A "write" routine takes a libwiretap record and Buffer and writes
272 * out a block.
274 typedef struct {
275 block_reader reader;
276 block_writer writer;
277 } block_handler;
279 static GHashTable *block_handlers;
281 void
282 register_pcapng_block_type_handler(unsigned block_type, block_reader reader,
283 block_writer writer)
285 block_handler *handler;
288 * Is this a known block type?
290 switch (block_type) {
292 case BLOCK_TYPE_SHB:
293 case BLOCK_TYPE_IDB:
294 case BLOCK_TYPE_PB:
295 case BLOCK_TYPE_SPB:
296 case BLOCK_TYPE_NRB:
297 case BLOCK_TYPE_ISB:
298 case BLOCK_TYPE_EPB:
299 case BLOCK_TYPE_DSB:
300 case BLOCK_TYPE_CB_COPY:
301 case BLOCK_TYPE_CB_NO_COPY:
302 case BLOCK_TYPE_SYSDIG_MI:
303 case BLOCK_TYPE_SYSDIG_PL_V1:
304 case BLOCK_TYPE_SYSDIG_FDL_V1:
305 case BLOCK_TYPE_SYSDIG_EVENT:
306 case BLOCK_TYPE_SYSDIG_IL_V1:
307 case BLOCK_TYPE_SYSDIG_UL_V1:
308 case BLOCK_TYPE_SYSDIG_PL_V2:
309 case BLOCK_TYPE_SYSDIG_EVF:
310 case BLOCK_TYPE_SYSDIG_PL_V3:
311 case BLOCK_TYPE_SYSDIG_PL_V4:
312 case BLOCK_TYPE_SYSDIG_PL_V5:
313 case BLOCK_TYPE_SYSDIG_PL_V6:
314 case BLOCK_TYPE_SYSDIG_PL_V7:
315 case BLOCK_TYPE_SYSDIG_PL_V8:
316 case BLOCK_TYPE_SYSDIG_PL_V9:
317 case BLOCK_TYPE_SYSDIG_EVENT_V2:
318 case BLOCK_TYPE_SYSDIG_EVF_V2:
319 case BLOCK_TYPE_SYSDIG_FDL_V2:
320 case BLOCK_TYPE_SYSDIG_IL_V2:
321 case BLOCK_TYPE_SYSDIG_UL_V2:
322 case BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT:
324 * Yes; we already handle it, and don't allow a replacement to
325 * be registered (if there's a bug in our code, or there's
326 * something we don't handle in that block, submit a change
327 * to the main Wireshark source).
329 ws_warning("Attempt to register plugin for block type 0x%08x not allowed",
330 block_type);
331 return;
333 case BLOCK_TYPE_IRIG_TS:
334 case BLOCK_TYPE_ARINC_429:
336 * Yes, and we don't already handle it. Allow a plugin to
337 * handle it.
339 * (But why not submit the plugin source to Wireshark?)
341 break;
343 default:
345 * No; is it a local block type?
347 if (!(block_type & 0x80000000)) {
349 * No; don't allow a plugin to be registered for it, as
350 * the block type needs to be registered before it's used.
352 ws_warning("Attempt to register plugin for reserved block type 0x%08x not allowed",
353 block_type);
354 return;
358 * Yes; allow the registration.
360 break;
363 if (block_handlers == NULL) {
365 * Create the table of block handlers.
367 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
368 * so we use "g_direct_hash()" and "g_direct_equal()".
370 block_handlers = g_hash_table_new_full(g_direct_hash,
371 g_direct_equal,
372 NULL, g_free);
374 handler = g_new(block_handler, 1);
375 handler->reader = reader;
376 handler->writer = writer;
377 g_hash_table_insert(block_handlers, GUINT_TO_POINTER(block_type),
378 handler);
382 * Tables for plugins to handle particular options for particular block
383 * types.
385 * An option has three handler routines:
387 * An option parser, used when reading an option from a file:
389 * The option parser is passed an indication of whether this section
390 * of the file is byte-swapped, the length of the option, the data of
391 * the option, a pointer to an error code, and a pointer to a pointer
392 * variable for an error string.
394 * It checks whether the length and option are valid, and, if they
395 * aren't, returns false, setting the error code to the appropriate
396 * error (normally WTAP_ERR_BAD_FILE) and the error string to an
397 * appropriate string indicating the problem.
399 * Otherwise, if this section of the file is byte-swapped, it byte-swaps
400 * multi-byte numerical values, so that it's in the host byte order.
402 * An option sizer, used when writing an option to a file:
404 * The option sizer is passed the option identifier for the option
405 * and a wtap_optval_t * that points to the data for the option.
407 * It calculates how many bytes the option's data requires, not
408 * including any padding bytes, and returns that value.
410 * An option writer, used when writing an option to a file:
412 * The option writer is passed a wtap_dumper * to which the
413 * option data should be written, the option identifier for
414 * the option, a wtap_optval_t * that points to the data for
415 * the option, and an int * into which an error code should
416 * be stored if an error occurs when writing the option.
418 * It returns a bool value of true if the attempt to
419 * write the option succeeds and false if the attempt to
420 * write the option gets an error.
424 * Block types indices in the table of tables of option handlers.
426 * Block types are not guaranteed to be sequential, so we map the
427 * block types we support to a sequential set. Furthermore, all
428 * packet block types have the same set of options.
430 #define BT_INDEX_SHB 0
431 #define BT_INDEX_IDB 1
432 #define BT_INDEX_PBS 2 /* all packet blocks */
433 #define BT_INDEX_NRB 3
434 #define BT_INDEX_ISB 4
435 #define BT_INDEX_EVT 5
436 #define BT_INDEX_DSB 6
438 #define NUM_BT_INDICES 7
440 typedef struct {
441 option_parser parser;
442 option_sizer sizer;
443 option_writer writer;
444 } option_handler;
446 static GHashTable *option_handlers[NUM_BT_INDICES];
448 /* Return whether this block type is handled interally, or
449 * if it is returned to the caller in pcapng_read().
450 * This is used by pcapng_open() to decide if it can process
451 * the block.
452 * Note that for block types that are registered from plugins,
453 * we don't know the true answer without actually reading the block,
454 * or even if there is a fixed answer for all blocks of that type,
455 * so we err on the side of not processing.
457 static bool
458 get_block_type_internal(unsigned block_type)
460 switch (block_type) {
462 case BLOCK_TYPE_SHB:
463 case BLOCK_TYPE_IDB:
464 case BLOCK_TYPE_NRB:
465 case BLOCK_TYPE_DSB:
466 case BLOCK_TYPE_ISB: /* XXX: ISBs should probably not be internal. */
467 case BLOCK_TYPE_SYSDIG_MI:
468 case BLOCK_TYPE_SYSDIG_PL_V1:
469 case BLOCK_TYPE_SYSDIG_FDL_V1:
470 case BLOCK_TYPE_SYSDIG_IL_V1:
471 case BLOCK_TYPE_SYSDIG_UL_V1:
472 case BLOCK_TYPE_SYSDIG_PL_V2:
473 case BLOCK_TYPE_SYSDIG_PL_V3:
474 case BLOCK_TYPE_SYSDIG_PL_V4:
475 case BLOCK_TYPE_SYSDIG_PL_V5:
476 case BLOCK_TYPE_SYSDIG_PL_V6:
477 case BLOCK_TYPE_SYSDIG_PL_V7:
478 case BLOCK_TYPE_SYSDIG_PL_V8:
479 case BLOCK_TYPE_SYSDIG_PL_V9:
480 case BLOCK_TYPE_SYSDIG_FDL_V2:
481 case BLOCK_TYPE_SYSDIG_IL_V2:
482 case BLOCK_TYPE_SYSDIG_UL_V2:
483 return true;
485 case BLOCK_TYPE_PB:
486 case BLOCK_TYPE_EPB:
487 case BLOCK_TYPE_SPB:
488 return false;
490 case BLOCK_TYPE_CB_COPY:
491 case BLOCK_TYPE_CB_NO_COPY:
492 case BLOCK_TYPE_SYSDIG_EVENT:
493 case BLOCK_TYPE_SYSDIG_EVENT_V2:
494 case BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE:
495 case BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT:
496 return false;
498 default:
499 #ifdef HAVE_PLUGINS
501 * Do we have a handler for this block type?
503 if (block_handlers != NULL &&
504 (g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(block_type))) != NULL) {
505 /* Yes. We don't know if the handler sets this block internal
506 * or needs to return it to the pcap_read() caller without
507 * reading it. Since this is called by pcap_open(), play it
508 * safe and tell pcap_open() to stop processing blocks.
509 * (XXX: Maybe the block type handler registration interface
510 * should include some way of indicating whether blocks are
511 * handled internally, which should hopefully be the same
512 * for all blocks of a type.)
514 return false;
516 #endif
517 return true;
519 return false;
522 static bool
523 get_block_type_index(unsigned block_type, unsigned *bt_index)
525 ws_assert(bt_index);
527 switch (block_type) {
529 case BLOCK_TYPE_SHB:
530 *bt_index = BT_INDEX_SHB;
531 break;
533 case BLOCK_TYPE_IDB:
534 *bt_index = BT_INDEX_IDB;
535 break;
537 case BLOCK_TYPE_PB:
538 case BLOCK_TYPE_EPB:
539 case BLOCK_TYPE_SPB:
540 *bt_index = BT_INDEX_PBS;
541 break;
543 case BLOCK_TYPE_NRB:
544 *bt_index = BT_INDEX_NRB;
545 break;
547 case BLOCK_TYPE_ISB:
548 *bt_index = BT_INDEX_ISB;
549 break;
551 case BLOCK_TYPE_SYSDIG_EVENT:
552 case BLOCK_TYPE_SYSDIG_EVENT_V2:
553 case BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE:
554 case BLOCK_TYPE_SYSDIG_MI:
555 case BLOCK_TYPE_SYSDIG_PL_V1:
556 case BLOCK_TYPE_SYSDIG_FDL_V1:
557 case BLOCK_TYPE_SYSDIG_IL_V1:
558 case BLOCK_TYPE_SYSDIG_UL_V1:
559 case BLOCK_TYPE_SYSDIG_PL_V2:
560 case BLOCK_TYPE_SYSDIG_PL_V3:
561 case BLOCK_TYPE_SYSDIG_PL_V4:
562 case BLOCK_TYPE_SYSDIG_PL_V5:
563 case BLOCK_TYPE_SYSDIG_PL_V6:
564 case BLOCK_TYPE_SYSDIG_PL_V7:
565 case BLOCK_TYPE_SYSDIG_PL_V8:
566 case BLOCK_TYPE_SYSDIG_PL_V9:
567 case BLOCK_TYPE_SYSDIG_FDL_V2:
568 case BLOCK_TYPE_SYSDIG_IL_V2:
569 case BLOCK_TYPE_SYSDIG_UL_V2:
570 *bt_index = BT_INDEX_EVT;
571 break;
573 case BLOCK_TYPE_DSB:
574 *bt_index = BT_INDEX_DSB;
575 break;
577 default:
579 * This is a block type we don't process; either we ignore it,
580 * in which case the options don't get processed, or there's
581 * a plugin routine to handle it, in which case that routine
582 * will do the option processing itself.
584 * XXX - report an error?
586 return false;
589 return true;
592 void
593 register_pcapng_option_handler(unsigned block_type, unsigned option_code,
594 option_parser parser,
595 option_sizer sizer,
596 option_writer writer)
598 unsigned bt_index;
599 option_handler *handler;
601 if (!get_block_type_index(block_type, &bt_index))
602 return;
604 if (option_handlers[bt_index] == NULL) {
606 * Create the table of option handlers for this block type.
608 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
609 * so we use "g_direct_hash()" and "g_direct_equal()".
611 option_handlers[bt_index] = g_hash_table_new_full(g_direct_hash,
612 g_direct_equal,
613 NULL, g_free);
615 handler = g_new(option_handler, 1);
616 handler->parser = parser;
617 handler->sizer = sizer;
618 handler->writer = writer;
619 g_hash_table_insert(option_handlers[bt_index],
620 GUINT_TO_POINTER(option_code), handler);
623 void
624 pcapng_process_uint8_option(wtapng_block_t *wblock,
625 uint16_t option_code, uint16_t option_length,
626 const uint8_t *option_content)
628 if (option_length == 1) {
630 * If this option can appear only once in a block, this call
631 * will fail on the second and later occurrences of the option;
632 * we silently ignore the failure.
634 wtap_block_add_uint8_option(wblock->block, option_code, option_content[0]);
638 void
639 pcapng_process_uint32_option(wtapng_block_t *wblock,
640 const section_info_t *section_info,
641 pcapng_opt_byte_order_e byte_order,
642 uint16_t option_code, uint16_t option_length,
643 const uint8_t *option_content)
645 uint32_t uint32;
647 if (option_length == 4) {
648 /* Don't cast a uint8_t * into a uint32_t *--the
649 * uint8_t * may not point to something that's
650 * aligned correctly.
652 * XXX - options are aligned on 32-bit boundaries, so, while
653 * it may be true that 64-bit options aren't guaranteed to be
654 * aligned on 64-bit bounaries, it shouldn't be true that 32-bit
655 * options aren't guaranteed to be aligned on 32-bit boundaries.
657 memcpy(&uint32, option_content, sizeof(uint32_t));
658 switch (byte_order) {
660 case OPT_SECTION_BYTE_ORDER:
661 if (section_info->byte_swapped) {
662 uint32 = GUINT32_SWAP_LE_BE(uint32);
664 break;
666 case OPT_BIG_ENDIAN:
667 uint32 = GUINT32_FROM_BE(uint32);
668 break;
670 case OPT_LITTLE_ENDIAN:
671 uint32 = GUINT32_FROM_LE(uint32);
672 break;
674 default:
676 * This should not happen - this is called by pcapng_process_options(),
677 * which returns an error for an invalid byte_order argument, and
678 * otherwise passes the known-to-be-valid byte_order argument to
679 * us.
681 * Just ignore the option.
683 return;
687 * If this option can appear only once in a block, this call
688 * will fail on the second and later occurrences of the option;
689 * we silently ignore the failure.
691 wtap_block_add_uint32_option(wblock->block, option_code, uint32);
695 void
696 pcapng_process_timestamp_option(wtapng_block_t *wblock,
697 const section_info_t *section_info,
698 pcapng_opt_byte_order_e byte_order,
699 uint16_t option_code, uint16_t option_length,
700 const uint8_t *option_content)
702 if (option_length == 8) {
703 uint32_t high, low;
704 uint64_t timestamp;
706 /* Don't cast a uint8_t * into a uint32_t *--the
707 * uint8_t * may not point to something that's
708 * aligned correctly.
710 memcpy(&high, option_content, sizeof(uint32_t));
711 memcpy(&low, option_content + sizeof(uint32_t), sizeof(uint32_t));
712 switch (byte_order) {
714 case OPT_SECTION_BYTE_ORDER:
715 if (section_info->byte_swapped) {
716 high = GUINT32_SWAP_LE_BE(high);
717 low = GUINT32_SWAP_LE_BE(low);
719 break;
721 case OPT_BIG_ENDIAN:
722 high = GUINT32_FROM_BE(high);
723 low = GUINT32_FROM_BE(low);
724 break;
726 case OPT_LITTLE_ENDIAN:
727 high = GUINT32_FROM_LE(high);
728 low = GUINT32_FROM_LE(low);
729 break;
731 default:
733 * This should not happen - this is called by pcapng_process_options(),
734 * which returns an error for an invalid byte_order argument, and
735 * otherwise passes the known-to-be-valid byte_order argument to
736 * us.
738 * Just ignore the option.
740 return;
742 timestamp = (uint64_t)high;
743 timestamp <<= 32;
744 timestamp += (uint64_t)low;
746 * If this option can appear only once in a block, this call
747 * will fail on the second and later occurrences of the option;
748 * we silently ignore the failure.
750 wtap_block_add_uint64_option(wblock->block, option_code, timestamp);
754 void
755 pcapng_process_uint64_option(wtapng_block_t *wblock,
756 const section_info_t *section_info,
757 pcapng_opt_byte_order_e byte_order,
758 uint16_t option_code, uint16_t option_length,
759 const uint8_t *option_content)
761 uint64_t uint64;
763 if (option_length == 8) {
764 /* Don't cast a uint8_t * into a uint64_t *--the
765 * uint8_t * may not point to something that's
766 * aligned correctly.
768 memcpy(&uint64, option_content, sizeof(uint64_t));
769 switch (byte_order) {
771 case OPT_SECTION_BYTE_ORDER:
772 if (section_info->byte_swapped) {
773 uint64 = GUINT64_SWAP_LE_BE(uint64);
775 break;
777 case OPT_BIG_ENDIAN:
778 uint64 = GUINT64_FROM_BE(uint64);
779 break;
781 case OPT_LITTLE_ENDIAN:
782 uint64 = GUINT64_FROM_LE(uint64);
783 break;
785 default:
787 * This should not happen - this is called by pcapng_process_options(),
788 * which returns an error for an invalid byte_order argument, and
789 * otherwise passes the known-to-be-valid byte_order argument to
790 * us.
792 * Just ignore the option.
794 return;
798 * If this option can appear only once in a block, this call
799 * will fail on the second and later occurrences of the option;
800 * we silently ignore the failure.
802 wtap_block_add_uint64_option(wblock->block, option_code, uint64);
806 void
807 pcapng_process_int64_option(wtapng_block_t *wblock,
808 const section_info_t *section_info,
809 pcapng_opt_byte_order_e byte_order,
810 uint16_t option_code, uint16_t option_length,
811 const uint8_t *option_content)
813 int64_t int64;
815 if (option_length == 8) {
816 /* Don't cast a int8_t * into a int64_t *--the
817 * uint8_t * may not point to something that's
818 * aligned correctly.
820 memcpy(&int64, option_content, sizeof(int64_t));
821 switch (byte_order) {
823 case OPT_SECTION_BYTE_ORDER:
824 if (section_info->byte_swapped) {
825 int64 = GUINT64_SWAP_LE_BE(int64);
827 break;
829 case OPT_BIG_ENDIAN:
830 int64 = GUINT64_FROM_BE(int64);
831 break;
833 case OPT_LITTLE_ENDIAN:
834 int64 = GUINT64_FROM_LE(int64);
835 break;
837 default:
839 * This should not happen - this is called by pcapng_process_options(),
840 * which returns an error for an invalid byte_order argument, and
841 * otherwise passes the known-to-be-valid byte_order argument to
842 * us.
844 * Just ignore the option.
846 return;
850 * If this option can appear only once in a block, this call
851 * will fail on the second and later occurrences of the option;
852 * we silently ignore the failure.
854 wtap_block_add_int64_option(wblock->block, option_code, int64);
858 void
859 pcapng_process_string_option(wtapng_block_t *wblock, uint16_t option_code,
860 uint16_t option_length, const uint8_t *option_content)
862 const char *opt = (const char *)option_content;
863 size_t optlen = option_length;
864 char *str;
866 /* Validate UTF-8 encoding. */
867 str = ws_utf8_make_valid(NULL, opt, optlen);
869 wtap_block_add_string_option_owned(wblock->block, option_code, str);
872 void
873 pcapng_process_bytes_option(wtapng_block_t *wblock, uint16_t option_code,
874 uint16_t option_length, const uint8_t *option_content)
876 wtap_block_add_bytes_option(wblock->block, option_code, (const char *)option_content, option_length);
879 static bool
880 pcapng_process_nflx_custom_option(wtapng_block_t *wblock,
881 section_info_t *section_info,
882 const uint8_t *value, uint16_t length)
884 struct nflx_dumpinfo dumpinfo;
885 uint32_t type, version;
886 int64_t dumptime, temp;
888 if (length < 4) {
889 ws_debug("Length = %u too small", length);
890 return false;
892 memcpy(&type, value, sizeof(uint32_t));
893 type = GUINT32_FROM_LE(type);
894 value += 4;
895 length -= 4;
896 ws_debug("Handling type = %u, payload of length = %u", type, length);
897 switch (type) {
898 case NFLX_OPT_TYPE_VERSION:
899 if (length == sizeof(uint32_t)) {
900 memcpy(&version, value, sizeof(uint32_t));
901 version = GUINT32_FROM_LE(version);
902 ws_debug("BBLog version: %u", version);
903 section_info->bblog_version = version;
904 } else {
905 ws_debug("BBLog version parameter has strange length: %u", length);
907 break;
908 case NFLX_OPT_TYPE_TCPINFO:
909 ws_debug("BBLog tcpinfo of length: %u", length);
910 if (wblock->type == BLOCK_TYPE_CB_COPY) {
911 ws_buffer_assure_space(wblock->frame_buffer, length);
912 wblock->rec->rec_header.custom_block_header.length = length + 4;
913 memcpy(ws_buffer_start_ptr(wblock->frame_buffer), value, length);
914 memcpy(&temp, value, sizeof(uint64_t));
915 temp = GUINT64_FROM_LE(temp);
916 wblock->rec->ts.secs = section_info->bblog_offset_tv_sec + temp;
917 memcpy(&temp, value + sizeof(uint64_t), sizeof(uint64_t));
918 temp = GUINT64_FROM_LE(temp);
919 wblock->rec->ts.nsecs = (uint32_t)(section_info->bblog_offset_tv_usec + temp) * 1000;
920 if (wblock->rec->ts.nsecs >= 1000000000) {
921 wblock->rec->ts.secs += 1;
922 wblock->rec->ts.nsecs -= 1000000000;
924 wblock->rec->presence_flags = WTAP_HAS_TS;
925 wblock->internal = false;
927 break;
928 case NFLX_OPT_TYPE_DUMPINFO:
929 if (length == sizeof(struct nflx_dumpinfo)) {
930 memcpy(&dumpinfo, value, sizeof(struct nflx_dumpinfo));
931 section_info->bblog_offset_tv_sec = GUINT64_FROM_LE(dumpinfo.tlh_offset_tv_sec);
932 section_info->bblog_offset_tv_usec = GUINT64_FROM_LE(dumpinfo.tlh_offset_tv_usec);
933 ws_debug("BBLog dumpinfo time offset: %" PRIu64, section_info->bblog_offset_tv_sec);
934 } else {
935 ws_debug("BBLog dumpinfo parameter has strange length: %u", length);
937 break;
938 case NFLX_OPT_TYPE_DUMPTIME:
939 if (length == sizeof(int64_t)) {
940 memcpy(&dumptime, value, sizeof(int64_t));
941 dumptime = GINT64_FROM_LE(dumptime);
942 ws_debug("BBLog dumpinfo time offset: %" PRIu64, dumptime);
943 } else {
944 ws_debug("BBLog dumptime parameter has strange length: %u", length);
946 break;
947 case NFLX_OPT_TYPE_STACKNAME:
948 if (length >= 2) {
949 ws_debug("BBLog stack name: %.*s(%u)", length - 1, value + 1, *(uint8_t *)value);
950 } else {
951 ws_debug("BBLog stack name has strange length: %u)", length);
953 break;
954 default:
955 ws_debug("Unknown type: %u, length: %u", type, length);
956 break;
958 return wtap_block_add_nflx_custom_option(wblock->block, type, value, length) == WTAP_OPTTYPE_SUCCESS;
961 static bool
962 pcapng_process_custom_option(wtapng_block_t *wblock,
963 section_info_t *section_info,
964 uint16_t option_code, uint16_t option_length,
965 const uint8_t *option_content,
966 pcapng_opt_byte_order_e byte_order,
967 int *err, char **err_info)
969 uint32_t pen;
970 bool ret;
972 if (option_length < 4) {
973 *err = WTAP_ERR_BAD_FILE;
974 *err_info = ws_strdup_printf("pcapng: option length (%d) too small for custom option",
975 option_length);
976 return false;
978 memcpy(&pen, option_content, sizeof(uint32_t));
979 switch (byte_order) {
981 case OPT_SECTION_BYTE_ORDER:
982 if (section_info->byte_swapped) {
983 pen = GUINT32_SWAP_LE_BE(pen);
985 break;
987 case OPT_BIG_ENDIAN:
988 pen = GUINT32_FROM_BE(pen);
989 break;
991 case OPT_LITTLE_ENDIAN:
992 pen = GUINT32_FROM_LE(pen);
993 break;
995 default:
997 * This should not happen - this is called by pcapng_process_options(),
998 * which returns an error for an invalid byte_order argument, and
999 * otherwise passes the known-to-be-valid byte_order argument to
1000 * us.
1002 *err = WTAP_ERR_INTERNAL;
1003 *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_process_custom_option()",
1004 byte_order);
1005 return false;
1007 switch (pen) {
1008 case PEN_NFLX:
1009 ret = pcapng_process_nflx_custom_option(wblock, section_info, option_content + 4, option_length - 4);
1010 break;
1011 default:
1012 ret = wtap_block_add_custom_option(wblock->block, option_code, pen, option_content + 4, option_length - 4) == WTAP_OPTTYPE_SUCCESS;
1013 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);
1014 break;
1016 ws_debug("returning %d", ret);
1017 return ret;
1020 #ifdef HAVE_PLUGINS
1021 static bool
1022 pcapng_process_unhandled_option(wtapng_block_t *wblock,
1023 unsigned bt_index,
1024 const section_info_t *section_info,
1025 uint16_t option_code, uint16_t option_length,
1026 const uint8_t *option_content,
1027 int *err, char **err_info)
1029 option_handler *handler;
1032 * Do we have a handler for this packet block option code?
1034 if (option_handlers[bt_index] != NULL &&
1035 (handler = (option_handler *)g_hash_table_lookup(option_handlers[bt_index],
1036 GUINT_TO_POINTER((unsigned)option_code))) != NULL) {
1037 /* Yes - call the handler. */
1038 if (!handler->parser(wblock->block, section_info->byte_swapped,
1039 option_length, option_content, err, err_info))
1040 /* XXX - free anything? */
1041 return false;
1043 return true;
1045 #else
1046 static bool
1047 pcapng_process_unhandled_option(wtapng_block_t *wblock _U_,
1048 unsigned bt_index _U_,
1049 const section_info_t *section_info _U_,
1050 uint16_t option_code _U_, uint16_t option_length _U_,
1051 const uint8_t *option_content _U_,
1052 int *err _U_, char **err_info _U_)
1054 return true;
1056 #endif
1058 bool
1059 pcapng_process_options(FILE_T fh, wtapng_block_t *wblock,
1060 section_info_t *section_info,
1061 unsigned opt_cont_buf_len,
1062 bool (*process_option)(wtapng_block_t *,
1063 const section_info_t *,
1064 uint16_t, uint16_t,
1065 const uint8_t *,
1066 int *, char **),
1067 pcapng_opt_byte_order_e byte_order,
1068 int *err, char **err_info)
1070 uint8_t *option_content; /* Allocate as large as the options block */
1071 unsigned opt_bytes_remaining;
1072 const uint8_t *option_ptr;
1073 const pcapng_option_header_t *oh;
1074 uint16_t option_code, option_length;
1075 unsigned rounded_option_length;
1077 ws_debug("Options %u bytes", opt_cont_buf_len);
1078 if (opt_cont_buf_len == 0) {
1079 /* No options, so nothing to do */
1080 return true;
1083 /* Allocate enough memory to hold all options */
1084 option_content = (uint8_t *)g_try_malloc(opt_cont_buf_len);
1085 if (option_content == NULL) {
1086 *err = ENOMEM; /* we assume we're out of memory */
1087 return false;
1090 /* Read all the options into the buffer */
1091 if (!wtap_read_bytes(fh, option_content, opt_cont_buf_len, err, err_info)) {
1092 ws_debug("failed to read options");
1093 g_free(option_content);
1094 return false;
1098 * Now process them.
1099 * option_ptr starts out aligned on at least a 4-byte boundary, as
1100 * that's what g_try_malloc() gives us, and each option is padded
1101 * to a length that's a multiple of 4 bytes, so it remains aligned.
1103 option_ptr = &option_content[0];
1104 opt_bytes_remaining = opt_cont_buf_len;
1105 while (opt_bytes_remaining != 0) {
1106 /* Get option header. */
1107 oh = (const pcapng_option_header_t *)(const void *)option_ptr;
1108 /* Sanity check: don't run past the end of the options. */
1109 if (sizeof (*oh) > opt_bytes_remaining) {
1110 *err = WTAP_ERR_BAD_FILE;
1111 *err_info = ws_strdup_printf("pcapng: Not enough data for option header");
1112 g_free(option_content);
1113 return false;
1115 option_code = oh->option_code;
1116 option_length = oh->option_length;
1117 switch (byte_order) {
1119 case OPT_SECTION_BYTE_ORDER:
1120 if (section_info->byte_swapped) {
1121 option_code = GUINT16_SWAP_LE_BE(option_code);
1122 option_length = GUINT16_SWAP_LE_BE(option_length);
1124 break;
1126 case OPT_BIG_ENDIAN:
1127 option_code = GUINT16_FROM_BE(option_code);
1128 option_length = GUINT16_FROM_BE(option_length);
1129 break;
1131 case OPT_LITTLE_ENDIAN:
1132 option_code = GUINT16_FROM_LE(option_code);
1133 option_length = GUINT16_FROM_LE(option_length);
1134 break;
1136 default:
1137 /* Don't do that. */
1138 *err = WTAP_ERR_INTERNAL;
1139 *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_process_options()",
1140 byte_order);
1141 return false;
1143 option_ptr += sizeof (*oh); /* 4 bytes, so it remains aligned */
1144 opt_bytes_remaining -= sizeof (*oh);
1146 /* Round up option length to a multiple of 4. */
1147 rounded_option_length = ROUND_TO_4BYTE(option_length);
1149 /* Sanity check: don't run past the end of the options. */
1150 if (rounded_option_length > opt_bytes_remaining) {
1151 *err = WTAP_ERR_BAD_FILE;
1152 *err_info = ws_strdup_printf("pcapng: Not enough data to handle option of length %u",
1153 option_length);
1154 g_free(option_content);
1155 return false;
1158 switch (option_code) {
1159 case(OPT_EOFOPT): /* opt_endofopt */
1160 if (opt_bytes_remaining != 0) {
1161 ws_debug("%u bytes after opt_endofopt", opt_bytes_remaining);
1163 /* padding should be ok here, just get out of this */
1164 opt_bytes_remaining = rounded_option_length;
1165 break;
1166 case(OPT_COMMENT):
1167 pcapng_process_string_option(wblock, option_code, option_length,
1168 option_ptr);
1169 break;
1170 case(OPT_CUSTOM_STR_COPY):
1171 case(OPT_CUSTOM_BIN_COPY):
1172 case(OPT_CUSTOM_STR_NO_COPY):
1173 case(OPT_CUSTOM_BIN_NO_COPY):
1174 if (!pcapng_process_custom_option(wblock, section_info,
1175 option_code, option_length,
1176 option_ptr,
1177 byte_order,
1178 err, err_info)) {
1179 g_free(option_content);
1180 return false;
1182 break;
1184 default:
1185 if (process_option == NULL ||
1186 !(*process_option)(wblock, (const section_info_t *)section_info, option_code,
1187 option_length, option_ptr,
1188 err, err_info)) {
1189 g_free(option_content);
1190 return false;
1193 option_ptr += rounded_option_length; /* multiple of 4 bytes, so it remains aligned */
1194 opt_bytes_remaining -= rounded_option_length;
1196 g_free(option_content);
1197 return true;
1200 typedef enum {
1201 PCAPNG_BLOCK_OK,
1202 PCAPNG_BLOCK_NOT_SHB,
1203 PCAPNG_BLOCK_ERROR
1204 } block_return_val;
1206 static bool
1207 pcapng_process_section_header_block_option(wtapng_block_t *wblock,
1208 const section_info_t *section_info,
1209 uint16_t option_code,
1210 uint16_t option_length,
1211 const uint8_t *option_content,
1212 int *err, char **err_info)
1215 * Handle option content.
1217 * ***DO NOT*** add any items to this table that are not
1218 * standardized option codes in either section 3.5 "Options"
1219 * of the current pcapng spec, at
1221 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1223 * or in the list of options in section 4.1 "Section Header Block"
1224 * of the current pcapng spec, at
1226 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
1228 * All option codes in this switch statement here must be listed
1229 * in one of those places as standardized option types.
1231 switch (option_code) {
1232 case(OPT_SHB_HARDWARE):
1233 pcapng_process_string_option(wblock, option_code, option_length,
1234 option_content);
1235 break;
1236 case(OPT_SHB_OS):
1237 pcapng_process_string_option(wblock, option_code, option_length,
1238 option_content);
1239 break;
1240 case(OPT_SHB_USERAPPL):
1241 pcapng_process_string_option(wblock, option_code, option_length,
1242 option_content);
1243 break;
1244 default:
1245 if (!pcapng_process_unhandled_option(wblock, BT_INDEX_SHB,
1246 section_info, option_code,
1247 option_length, option_content,
1248 err, err_info))
1249 return false;
1250 break;
1252 return true;
1255 static block_return_val
1256 pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
1257 section_info_t *section_info,
1258 wtapng_block_t *wblock,
1259 int *err, char **err_info)
1261 bool byte_swapped;
1262 uint16_t version_major;
1263 uint16_t version_minor;
1264 unsigned opt_cont_buf_len;
1265 pcapng_section_header_block_t shb;
1266 wtapng_section_mandatory_t* section_data;
1268 /* read fixed-length part of the block */
1269 if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
1271 * Even if this is just a short read, report it as an error.
1272 * It *is* a read error except when we're doing an open, in
1273 * which case it's a "this isn't a pcapng file" indication.
1274 * The open code will call us directly, and treat a short
1275 * read error as such an indication.
1277 return PCAPNG_BLOCK_ERROR;
1280 /* is the magic number one we expect? */
1281 switch (shb.magic) {
1282 case(0x1A2B3C4D):
1283 /* this seems pcapng with correct byte order */
1284 byte_swapped = false;
1285 version_major = shb.version_major;
1286 version_minor = shb.version_minor;
1288 ws_debug("SHB (our byte order) V%u.%u, len %u",
1289 version_major, version_minor, bh->block_total_length);
1290 break;
1291 case(0x4D3C2B1A):
1292 /* this seems pcapng with swapped byte order */
1293 byte_swapped = true;
1294 version_major = GUINT16_SWAP_LE_BE(shb.version_major);
1295 version_minor = GUINT16_SWAP_LE_BE(shb.version_minor);
1297 /* tweak the block length to meet current swapping that we know now */
1298 bh->block_total_length = GUINT32_SWAP_LE_BE(bh->block_total_length);
1300 ws_debug("SHB (byte-swapped) V%u.%u, len %u",
1301 version_major, version_minor, bh->block_total_length);
1302 break;
1303 default:
1304 /* Not a "pcapng" magic number we know about. */
1305 *err = WTAP_ERR_BAD_FILE;
1306 *err_info = ws_strdup_printf("pcapng: unknown byte-order magic number 0x%08x", shb.magic);
1309 * See above comment about PCAPNG_BLOCK_NOT_SHB.
1311 return PCAPNG_BLOCK_NOT_SHB;
1315 * Add padding bytes to the block total length.
1317 * See the comment in pcapng_read_block() for a long discussion
1318 * of this.
1320 bh->block_total_length = ROUND_TO_4BYTE(bh->block_total_length);
1323 * Is this block long enough to be an SHB?
1325 if (bh->block_total_length < MIN_SHB_SIZE) {
1327 * No.
1329 *err = WTAP_ERR_BAD_FILE;
1330 *err_info = ws_strdup_printf("pcapng: total block length %u of an SHB is less than the minimum SHB size %u",
1331 bh->block_total_length, MIN_SHB_SIZE);
1332 return PCAPNG_BLOCK_ERROR;
1335 /* OK, at this point we assume it's a pcapng file.
1337 Don't try to allocate memory for a huge number of options, as
1338 that might fail and, even if it succeeds, it might not leave
1339 any address space or memory+backing store for anything else.
1341 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1342 We check for this *after* checking the SHB for its byte
1343 order magic number, so that non-pcapng files are less
1344 likely to be treated as bad pcapng files. */
1345 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1346 *err = WTAP_ERR_BAD_FILE;
1347 *err_info = ws_strdup_printf("pcapng: total block length %u is too large (> %u)",
1348 bh->block_total_length, MAX_BLOCK_SIZE);
1349 return PCAPNG_BLOCK_ERROR;
1352 /* Currently only SHB versions 1.0 and 1.2 are supported;
1353 version 1.2 is treated as being the same as version 1.0.
1354 See the current version of the pcapng specification.
1356 Version 1.2 is written by some programs that write additional
1357 block types (which can be read by any code that handles them,
1358 regarless of whether the minor version if 0 or 2, so that's
1359 not a reason to change the minor version number).
1361 XXX - the pcapng specification says that readers should
1362 just ignore sections with an unsupported version number;
1363 presumably they can also report an error if they skip
1364 all the way to the end of the file without finding
1365 any versions that they support. */
1366 if (!(version_major == 1 &&
1367 (version_minor == 0 || version_minor == 2))) {
1368 *err = WTAP_ERR_UNSUPPORTED;
1369 *err_info = ws_strdup_printf("pcapng: unknown SHB version %u.%u",
1370 version_major, version_minor);
1371 return PCAPNG_BLOCK_ERROR;
1374 memset(section_info, 0, sizeof(section_info_t));
1375 section_info->byte_swapped = byte_swapped;
1376 section_info->version_major = version_major;
1377 section_info->version_minor = version_minor;
1380 * Set wblock->block to a newly-allocated section header block.
1382 wblock->block = wtap_block_create(WTAP_BLOCK_SECTION);
1385 * Set the mandatory values for the block.
1387 section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1388 /* 64bit section_length (currently unused) */
1389 if (section_info->byte_swapped) {
1390 section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length);
1391 } else {
1392 section_data->section_length = shb.section_length;
1395 /* Options */
1396 opt_cont_buf_len = bh->block_total_length - MIN_SHB_SIZE;
1397 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
1398 pcapng_process_section_header_block_option,
1399 OPT_SECTION_BYTE_ORDER, err, err_info))
1400 return PCAPNG_BLOCK_ERROR;
1403 * We don't return these to the caller in pcapng_read().
1405 wblock->internal = true;
1407 return PCAPNG_BLOCK_OK;
1410 static bool
1411 pcapng_process_if_descr_block_option(wtapng_block_t *wblock,
1412 const section_info_t *section_info,
1413 uint16_t option_code,
1414 uint16_t option_length,
1415 const uint8_t *option_content,
1416 int *err, char **err_info)
1418 if_filter_opt_t if_filter;
1421 * Handle option content.
1423 * ***DO NOT*** add any items to this table that are not
1424 * standardized option codes in either section 3.5 "Options"
1425 * of the current pcapng spec, at
1427 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1429 * or in the list of options in section 4.1 "Section Header Block"
1430 * of the current pcapng spec, at
1432 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
1434 * All option codes in this switch statement here must be listed
1435 * in one of those places as standardized option types.
1437 switch (option_code) {
1438 case(OPT_IDB_NAME): /* if_name */
1439 pcapng_process_string_option(wblock, option_code, option_length,
1440 option_content);
1441 break;
1442 case(OPT_IDB_DESCRIPTION): /* if_description */
1443 pcapng_process_string_option(wblock, option_code, option_length,
1444 option_content);
1445 break;
1446 case(OPT_IDB_SPEED): /* if_speed */
1447 pcapng_process_uint64_option(wblock, section_info,
1448 OPT_SECTION_BYTE_ORDER,
1449 option_code, option_length,
1450 option_content);
1451 break;
1452 case(OPT_IDB_TSRESOL): /* if_tsresol */
1453 pcapng_process_uint8_option(wblock, option_code, option_length,
1454 option_content);
1455 break;
1457 * if_tzone 10 Time zone for GMT support (TODO: specify better). TODO: give a good example
1459 case(OPT_IDB_FILTER): /* if_filter */
1460 if (option_length < 1) {
1461 *err = WTAP_ERR_BAD_FILE;
1462 *err_info = ws_strdup_printf("pcapng: packet block verdict option length %u is < 1",
1463 option_length);
1464 /* XXX - free anything? */
1465 return false;
1467 /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
1468 * or BPF bytecode.
1470 if (option_content[0] == 0) {
1471 if_filter.type = if_filter_pcap;
1472 if_filter.data.filter_str = g_strndup((char *)option_content+1, option_length-1);
1473 ws_debug("filter_str %s option_length %u",
1474 if_filter.data.filter_str, option_length);
1475 /* Fails with multiple options; we silently ignore the failure */
1476 wtap_block_add_if_filter_option(wblock->block, option_code, &if_filter);
1477 g_free(if_filter.data.filter_str);
1478 } else if (option_content[0] == 1) {
1480 * XXX - byte-swap the code and k fields
1481 * of each instruction as needed!
1483 * XXX - what if option_length-1 is not a
1484 * multiple of the size of a BPF instruction?
1486 unsigned num_insns;
1487 const uint8_t *insn_in;
1489 if_filter.type = if_filter_bpf;
1490 num_insns = (option_length-1)/8;
1491 insn_in = option_content+1;
1492 if_filter.data.bpf_prog.bpf_prog_len = num_insns;
1493 if_filter.data.bpf_prog.bpf_prog = g_new(wtap_bpf_insn_t, num_insns);
1494 for (unsigned i = 0; i < num_insns; i++) {
1495 wtap_bpf_insn_t *insn = &if_filter.data.bpf_prog.bpf_prog[i];
1497 memcpy(&insn->code, insn_in, 2);
1498 if (section_info->byte_swapped)
1499 insn->code = GUINT16_SWAP_LE_BE(insn->code);
1500 insn_in += 2;
1501 memcpy(&insn->jt, insn_in, 1);
1502 insn_in += 1;
1503 memcpy(&insn->jf, insn_in, 1);
1504 insn_in += 1;
1505 memcpy(&insn->k, insn_in, 4);
1506 if (section_info->byte_swapped)
1507 insn->k = GUINT32_SWAP_LE_BE(insn->k);
1508 insn_in += 4;
1510 /* Fails with multiple options; we silently ignore the failure */
1511 wtap_block_add_if_filter_option(wblock->block, option_code, &if_filter);
1512 g_free(if_filter.data.bpf_prog.bpf_prog);
1514 break;
1515 case(OPT_IDB_OS): /* if_os */
1517 * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
1518 * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
1519 * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
1521 pcapng_process_string_option(wblock, option_code, option_length,
1522 option_content);
1523 break;
1524 case(OPT_IDB_FCSLEN): /* if_fcslen */
1525 pcapng_process_uint8_option(wblock, option_code, option_length,
1526 option_content);
1527 break;
1528 case(OPT_IDB_HARDWARE): /* if_hardware */
1529 pcapng_process_string_option(wblock, option_code, option_length,
1530 option_content);
1531 break;
1532 /* TODO: process these! */
1533 case(OPT_IDB_IP4ADDR):
1535 * Interface network address and netmask. This option can be
1536 * repeated multiple times within the same Interface
1537 * Description Block when multiple IPv4 addresses are assigned
1538 * to the interface. 192 168 1 1 255 255 255 0
1540 break;
1541 case(OPT_IDB_IP6ADDR):
1543 * Interface network address and prefix length (stored in the
1544 * last byte). This option can be repeated multiple times
1545 * within the same Interface Description Block when multiple
1546 * IPv6 addresses are assigned to the interface.
1547 * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
1548 * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
1549 * 40"
1551 break;
1552 case(OPT_IDB_MACADDR):
1554 * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
1556 break;
1557 case(OPT_IDB_EUIADDR):
1559 * Interface Hardware EUI address (64 bits), if available.
1560 * TODO: give a good example
1562 break;
1563 case(OPT_IDB_TZONE):
1565 * Time zone for GMT support. This option has never been
1566 * specified in greater detail and, unless it were to identify
1567 * something such as an IANA time zone database timezone,
1568 * would be insufficient for converting between UTC and local
1569 * time. Therefore, it SHOULD NOT be used; instead, the
1570 * if_iana_tzname option SHOULD be used if time zone
1571 * information is to be specified.
1573 * Given that, we don't do anything with it.
1575 break;
1576 case(OPT_IDB_TSOFFSET):
1578 * A 64-bit integer value that specifies an offset (in
1579 * seconds) that must be added to the timestamp of each packet
1580 * to obtain the absolute timestamp of a packet. If this optio
1581 * is not present, an offset of 0 is assumed (i.e., timestamps
1582 * in blocks are absolute timestamps.)
1584 pcapng_process_int64_option(wblock, section_info,
1585 OPT_SECTION_BYTE_ORDER,
1586 option_code, option_length,
1587 option_content);
1588 break;
1589 default:
1590 if (!pcapng_process_unhandled_option(wblock, BT_INDEX_IDB,
1591 section_info, option_code,
1592 option_length, option_content,
1593 err, err_info))
1594 return false;
1595 break;
1597 return true;
1600 /* "Interface Description Block" */
1601 static bool
1602 pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
1603 section_info_t *section_info,
1604 wtapng_block_t *wblock, int *err, char **err_info)
1606 /* Default time stamp resolution is 10^6 */
1607 uint64_t time_units_per_second = 1000000;
1608 int tsprecision = 6;
1609 unsigned opt_cont_buf_len;
1610 pcapng_interface_description_block_t idb;
1611 wtapng_if_descr_mandatory_t* if_descr_mand;
1612 unsigned link_type;
1613 uint8_t if_tsresol;
1616 * Is this block long enough to be an IDB?
1618 if (bh->block_total_length < MIN_IDB_SIZE) {
1620 * No.
1622 *err = WTAP_ERR_BAD_FILE;
1623 *err_info = ws_strdup_printf("pcapng: total block length %u of an IDB is less than the minimum IDB size %u",
1624 bh->block_total_length, MIN_IDB_SIZE);
1625 return false;
1628 /* read block content */
1629 if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
1630 ws_debug("failed to read IDB");
1631 return false;
1635 * Set wblock->block to a newly-allocated interface ID and information
1636 * block.
1638 wblock->block = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
1641 * Set the mandatory values for the block.
1643 if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1644 if (section_info->byte_swapped) {
1645 link_type = GUINT16_SWAP_LE_BE(idb.linktype);
1646 if_descr_mand->snap_len = GUINT32_SWAP_LE_BE(idb.snaplen);
1647 } else {
1648 link_type = idb.linktype;
1649 if_descr_mand->snap_len = idb.snaplen;
1652 if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(link_type);
1654 ws_debug("IDB link_type %u (%s), snap %u",
1655 link_type,
1656 wtap_encap_description(if_descr_mand->wtap_encap),
1657 if_descr_mand->snap_len);
1659 if (if_descr_mand->snap_len > wtap_max_snaplen_for_encap(if_descr_mand->wtap_encap)) {
1661 * We do not use this value, maybe we should check the
1662 * snap_len of the packets against it. For now, only warn.
1664 ws_debug("snapshot length %u unrealistic.",
1665 if_descr_mand->snap_len);
1666 /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;*/
1669 /* Options */
1670 opt_cont_buf_len = bh->block_total_length - MIN_IDB_SIZE;
1671 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
1672 pcapng_process_if_descr_block_option,
1673 OPT_SECTION_BYTE_ORDER, err, err_info))
1674 return false;
1677 * Did we get a time stamp precision option?
1679 if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_TSRESOL,
1680 &if_tsresol) == WTAP_OPTTYPE_SUCCESS) {
1682 * Yes. Set time_units_per_second appropriately.
1684 uint8_t exponent;
1686 exponent = (uint8_t)(if_tsresol & 0x7f);
1687 if (if_tsresol & 0x80) {
1689 * 2^63 fits in a 64-bit unsigned number; 2^64 does not.
1691 * ((2^64-1)/(2^63) is about 1.99, so, in practice, that
1692 * fine a time stamp resolution works only if you start
1693 * capturing at the Unix/POSIX epoch and capture for about
1694 * 1.9 seconds, so the maximum useful power-of-2 exponent
1695 * in a pcapng file is less than 63.)
1697 if (exponent > 63) {
1699 * Time units per second won't fit in a 64-bit integer,
1700 * so Wireshark's current code can't read the file.
1702 *err = WTAP_ERR_UNSUPPORTED;
1703 *err_info = ws_strdup_printf("pcapng: IDB power-of-2 time stamp resolution %u > 63",
1704 exponent);
1705 return false;
1708 /* 2^exponent */
1709 time_units_per_second = UINT64_C(1) << exponent;
1712 * Set the display precision to a value large enough to
1713 * show the fractional time units we get, so that we
1714 * don't display more digits than are justified.
1716 * (That's also used as the base-10 if_tsresol value we use
1717 * if we write this file as a pcapng file. Yes, that means
1718 * that we won't write out the exact value we read in.
1720 * Dealing with base-2 time stamps is a bit of a mess,
1721 * thanks to humans counting with their fingers rather
1722 * than their hands, and it applies to more files than
1723 * pcapng files, e.g. ERF files.)
1725 if (time_units_per_second >= 1000000000)
1726 tsprecision = WTAP_TSPREC_NSEC;
1727 else if (time_units_per_second >= 100000000)
1728 tsprecision = WTAP_TSPREC_10_NSEC;
1729 else if (time_units_per_second >= 10000000)
1730 tsprecision = WTAP_TSPREC_100_NSEC;
1731 else if (time_units_per_second >= 1000000)
1732 tsprecision = WTAP_TSPREC_USEC;
1733 else if (time_units_per_second >= 100000)
1734 tsprecision = WTAP_TSPREC_10_USEC;
1735 else if (time_units_per_second >= 10000)
1736 tsprecision = WTAP_TSPREC_100_USEC;
1737 else if (time_units_per_second >= 1000)
1738 tsprecision = WTAP_TSPREC_MSEC;
1739 else if (time_units_per_second >= 100)
1740 tsprecision = WTAP_TSPREC_10_MSEC;
1741 else if (time_units_per_second >= 10)
1742 tsprecision = WTAP_TSPREC_100_MSEC;
1743 else
1744 tsprecision = WTAP_TSPREC_SEC;
1745 } else {
1747 * 10^19 fits in a 64-bit unsigned number; 10^20 does not.
1749 * ((2^64-1)/(10^19) is about 1.84, so, in practice, that
1750 * fine a time stamp resolution works only if you start
1751 * capturing at the Unix/POSIX epoch and capture for about
1752 * 1.8 seconds, so the maximum useful power-of-10 exponent
1753 * in a pcapng file is less than 19.)
1755 uint64_t result;
1757 if (exponent > 19) {
1759 * Time units per second won't fit in a 64-bit integer,
1760 * so Wireshark's current code can't read the file.
1762 *err = WTAP_ERR_UNSUPPORTED;
1763 *err_info = ws_strdup_printf("pcapng: IDB power-of-10 time stamp resolution %u > 19",
1764 exponent);
1765 return false;
1768 /* 10^exponent */
1769 result = 1;
1770 for (unsigned i = 0; i < exponent; i++) {
1771 result *= 10U;
1773 time_units_per_second = result;
1776 * Set the display precision to min(exponent, WS_TSPREC_MAX),
1777 * so that we don't display more digits than are justified.
1778 * (That's also used as the base-10 if_tsresol value we use
1779 * if we write this file as a pcapng file.)
1781 if (exponent <= WS_TSPREC_MAX) {
1782 tsprecision = exponent;
1783 } else {
1784 tsprecision = WS_TSPREC_MAX;
1787 if (time_units_per_second > (((uint64_t)1) << 32)) {
1788 ws_debug("time conversion might be inaccurate");
1793 * Set the time units per second for this interface.
1795 if_descr_mand->time_units_per_second = time_units_per_second;
1798 * Set the number of digits of precision to display (and the
1799 * number to use for this interface if saving to a pcapng
1800 * file).
1802 if_descr_mand->tsprecision = tsprecision;
1805 * If the per-file encapsulation isn't known, set it to this
1806 * interface's encapsulation.
1808 * If it *is* known, and it isn't this interface's encapsulation,
1809 * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
1810 * have a single encapsulation for all interfaces in the file,
1811 * so it probably doesn't have a single encapsulation for all
1812 * packets in the file.
1814 if (wth->file_encap == WTAP_ENCAP_NONE) {
1815 wth->file_encap = if_descr_mand->wtap_encap;
1816 } else {
1817 if (wth->file_encap != if_descr_mand->wtap_encap) {
1818 wth->file_encap = WTAP_ENCAP_PER_PACKET;
1823 * The same applies to the per-file time stamp resolution.
1825 if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
1826 wth->file_tsprec = if_descr_mand->tsprecision;
1827 } else {
1828 if (wth->file_tsprec != if_descr_mand->tsprecision) {
1829 wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
1834 * We don't return these to the caller in pcapng_read().
1836 wblock->internal = true;
1838 return true;
1841 static bool
1842 pcapng_read_decryption_secrets_block(FILE_T fh, pcapng_block_header_t *bh,
1843 const section_info_t *section_info,
1844 wtapng_block_t *wblock,
1845 int *err, char **err_info)
1847 unsigned to_read;
1848 pcapng_decryption_secrets_block_t dsb;
1849 wtapng_dsb_mandatory_t *dsb_mand;
1851 /* read block content */
1852 if (!wtap_read_bytes(fh, &dsb, sizeof(dsb), err, err_info)) {
1853 ws_debug("failed to read DSB");
1854 return false;
1858 * Set wblock->block to a newly-allocated decryption secrets block.
1860 wblock->block = wtap_block_create(WTAP_BLOCK_DECRYPTION_SECRETS);
1863 * Set the mandatory values for the block.
1865 dsb_mand = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
1866 if (section_info->byte_swapped) {
1867 dsb_mand->secrets_type = GUINT32_SWAP_LE_BE(dsb.secrets_type);
1868 dsb_mand->secrets_len = GUINT32_SWAP_LE_BE(dsb.secrets_len);
1869 } else {
1870 dsb_mand->secrets_type = dsb.secrets_type;
1871 dsb_mand->secrets_len = dsb.secrets_len;
1873 /* Sanity check: assume the secrets are not larger than 1 GiB */
1874 if (dsb_mand->secrets_len > 1024 * 1024 * 1024) {
1875 *err = WTAP_ERR_BAD_FILE;
1876 *err_info = ws_strdup_printf("pcapng: secrets block is too large: %u", dsb_mand->secrets_len);
1877 return false;
1879 dsb_mand->secrets_data = (uint8_t *)g_malloc0(dsb_mand->secrets_len);
1880 if (!wtap_read_bytes(fh, dsb_mand->secrets_data, dsb_mand->secrets_len, err, err_info)) {
1881 ws_debug("failed to read DSB");
1882 return false;
1885 /* Skip past padding and discard options (not supported yet). */
1886 to_read = bh->block_total_length - MIN_DSB_SIZE - dsb_mand->secrets_len;
1887 if (!wtap_read_bytes(fh, NULL, to_read, err, err_info)) {
1888 ws_debug("failed to read DSB options");
1889 return false;
1893 * We don't return these to the caller in pcapng_read().
1895 wblock->internal = true;
1897 return true;
1900 static bool
1901 pcapng_read_meta_event_block(FILE_T fh, pcapng_block_header_t *bh,
1902 wtapng_block_t *wblock,
1903 int *err, char **err_info)
1905 unsigned to_read;
1906 wtapng_meta_event_mandatory_t *mev_mand;
1909 * Set wblock->block to a newly-allocated Sysdig meta event block.
1911 wblock->block = wtap_block_create(WTAP_BLOCK_META_EVENT);
1914 * Set the mandatory values for the block.
1916 mev_mand = (wtapng_meta_event_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
1917 mev_mand->mev_block_type = bh->block_type;
1918 mev_mand->mev_data_len = bh->block_total_length -
1919 (int)sizeof(pcapng_block_header_t) -
1920 (int)sizeof(bh->block_total_length);
1922 /* Sanity check: assume event data can't be larger than 1 GiB */
1923 if (mev_mand->mev_data_len > 1024 * 1024 * 1024) {
1924 *err = WTAP_ERR_BAD_FILE;
1925 *err_info = ws_strdup_printf("pcapng: Sysdig mev block is too large: %u", mev_mand->mev_data_len);
1926 return false;
1928 mev_mand->mev_data = (uint8_t *)g_malloc(mev_mand->mev_data_len);
1929 if (!wtap_read_bytes(fh, mev_mand->mev_data, mev_mand->mev_data_len, err, err_info)) {
1930 ws_debug("failed to read Sysdig mev");
1931 return false;
1934 /* Skip past padding and discard options (not supported yet). */
1935 to_read = bh->block_total_length - MIN_BLOCK_SIZE - mev_mand->mev_data_len;
1936 if (!wtap_read_bytes(fh, NULL, to_read, err, err_info)) {
1937 ws_debug("failed to read Sysdig mev options");
1938 return false;
1942 * We don't return these to the caller in pcapng_read().
1944 wblock->internal = true;
1946 return true;
1949 static bool
1950 pcapng_process_packet_block_option(wtapng_block_t *wblock,
1951 const section_info_t *section_info,
1952 uint16_t option_code,
1953 uint16_t option_length,
1954 const uint8_t *option_content,
1955 int *err, char **err_info)
1957 uint64_t tmp64;
1958 packet_verdict_opt_t packet_verdict;
1959 packet_hash_opt_t packet_hash;
1962 * Handle option content.
1964 * ***DO NOT*** add any items to this table that are not
1965 * standardized option codes in either section 3.5 "Options"
1966 * of the current pcapng spec, at
1968 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1970 * or in the list of options in section 4.3 "Enhanced Packet Block"
1971 * of the current pcapng spec, at
1973 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-enhanced-packet-block
1975 * All option codes in this switch statement here must be listed
1976 * in one of those places as standardized option types.
1978 switch (option_code) {
1979 case(OPT_EPB_FLAGS):
1980 if (option_length != 4) {
1981 *err = WTAP_ERR_BAD_FILE;
1982 *err_info = ws_strdup_printf("pcapng: packet block flags option length %u is not 4",
1983 option_length);
1984 /* XXX - free anything? */
1985 return false;
1987 pcapng_process_uint32_option(wblock, section_info,
1988 OPT_SECTION_BYTE_ORDER,
1989 option_code, option_length,
1990 option_content);
1991 break;
1992 case(OPT_EPB_HASH):
1993 if (option_length < 1) {
1994 *err = WTAP_ERR_BAD_FILE;
1995 *err_info = ws_strdup_printf("pcapng: packet block hash option length %u is < 1",
1996 option_length);
1997 /* XXX - free anything? */
1998 return false;
2000 packet_hash.type = option_content[0];
2001 packet_hash.hash_bytes =
2002 g_byte_array_new_take((uint8_t *)g_memdup2(&option_content[1],
2003 option_length - 1),
2004 option_length - 1);
2005 wtap_block_add_packet_hash_option(wblock->block, option_code, &packet_hash);
2006 wtap_packet_hash_free(&packet_hash);
2007 ws_debug("hash type %u, data len %u",
2008 option_content[0], option_length - 1);
2009 break;
2010 case(OPT_EPB_DROPCOUNT):
2011 if (option_length != 8) {
2012 *err = WTAP_ERR_BAD_FILE;
2013 *err_info = ws_strdup_printf("pcapng: packet block drop count option length %u is not 8",
2014 option_length);
2015 /* XXX - free anything? */
2016 return false;
2018 pcapng_process_uint64_option(wblock, section_info,
2019 OPT_SECTION_BYTE_ORDER,
2020 option_code, option_length,
2021 option_content);
2022 break;
2023 case(OPT_EPB_PACKETID):
2024 if (option_length != 8) {
2025 *err = WTAP_ERR_BAD_FILE;
2026 *err_info = ws_strdup_printf("pcapng: packet block packet id option length %u is not 8",
2027 option_length);
2028 /* XXX - free anything? */
2029 return false;
2031 pcapng_process_uint64_option(wblock, section_info,
2032 OPT_SECTION_BYTE_ORDER,
2033 option_code, option_length,
2034 option_content);
2035 break;
2036 case(OPT_EPB_QUEUE):
2037 if (option_length != 4) {
2038 *err = WTAP_ERR_BAD_FILE;
2039 *err_info = ws_strdup_printf("pcapng: packet block queue option length %u is not 4",
2040 option_length);
2041 /* XXX - free anything? */
2042 return false;
2044 pcapng_process_uint32_option(wblock, section_info,
2045 OPT_SECTION_BYTE_ORDER,
2046 option_code, option_length,
2047 option_content);
2048 break;
2049 case(OPT_EPB_VERDICT):
2050 if (option_length < 1) {
2051 *err = WTAP_ERR_BAD_FILE;
2052 *err_info = ws_strdup_printf("pcapng: packet block verdict option length %u is < 1",
2053 option_length);
2054 /* XXX - free anything? */
2055 return false;
2057 switch (option_content[0]) {
2059 case(OPT_VERDICT_TYPE_HW):
2060 packet_verdict.type = packet_verdict_hardware;
2061 packet_verdict.data.verdict_bytes =
2062 g_byte_array_new_take((uint8_t *)g_memdup2(&option_content[1],
2063 option_length - 1),
2064 option_length - 1);
2065 break;
2067 case(OPT_VERDICT_TYPE_TC):
2068 if (option_length != 9) {
2069 *err = WTAP_ERR_BAD_FILE;
2070 *err_info = ws_strdup_printf("pcapng: packet block TC verdict option length %u is != 9",
2071 option_length);
2072 /* XXX - free anything? */
2073 return false;
2075 /* Don't cast a uint8_t * into a uint64_t *--the
2076 * uint8_t * may not point to something that's
2077 * aligned correctly.
2079 memcpy(&tmp64, &option_content[1], sizeof(uint64_t));
2080 if (section_info->byte_swapped)
2081 tmp64 = GUINT64_SWAP_LE_BE(tmp64);
2082 packet_verdict.type = packet_verdict_linux_ebpf_tc;
2083 packet_verdict.data.verdict_linux_ebpf_tc = tmp64;
2084 break;
2086 case(OPT_VERDICT_TYPE_XDP):
2087 if (option_length != 9) {
2088 *err = WTAP_ERR_BAD_FILE;
2089 *err_info = ws_strdup_printf("pcapng: packet block XDP verdict option length %u is != 9",
2090 option_length);
2091 /* XXX - free anything? */
2092 return false;
2094 /* Don't cast a uint8_t * into a uint64_t *--the
2095 * uint8_t * may not point to something that's
2096 * aligned correctly.
2098 memcpy(&tmp64, &option_content[1], sizeof(uint64_t));
2099 if (section_info->byte_swapped)
2100 tmp64 = GUINT64_SWAP_LE_BE(tmp64);
2101 packet_verdict.type = packet_verdict_linux_ebpf_xdp;
2102 packet_verdict.data.verdict_linux_ebpf_xdp = tmp64;
2103 break;
2105 default:
2106 /* Silently ignore unknown verdict types */
2107 return true;
2109 wtap_block_add_packet_verdict_option(wblock->block, option_code, &packet_verdict);
2110 wtap_packet_verdict_free(&packet_verdict);
2111 ws_debug("verdict type %u, data len %u",
2112 option_content[0], option_length - 1);
2113 break;
2114 default:
2115 if (!pcapng_process_unhandled_option(wblock, BT_INDEX_PBS,
2116 section_info, option_code,
2117 option_length, option_content,
2118 err, err_info))
2119 return false;
2120 break;
2122 return true;
2125 static bool
2126 pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh,
2127 section_info_t *section_info,
2128 wtapng_block_t *wblock,
2129 int *err, char **err_info, bool enhanced)
2131 unsigned block_read;
2132 unsigned opt_cont_buf_len;
2133 pcapng_enhanced_packet_block_t epb;
2134 pcapng_packet_block_t pb;
2135 wtapng_packet_t packet;
2136 uint32_t padding;
2137 uint32_t flags;
2138 uint64_t tmp64;
2139 interface_info_t iface_info;
2140 uint64_t ts;
2141 int pseudo_header_len;
2142 int fcslen;
2144 wblock->block = wtap_block_create(WTAP_BLOCK_PACKET);
2146 /* "(Enhanced) Packet Block" read fixed part */
2147 if (enhanced) {
2149 * Is this block long enough to be an EPB?
2151 if (bh->block_total_length < MIN_EPB_SIZE) {
2153 * No.
2155 *err = WTAP_ERR_BAD_FILE;
2156 *err_info = ws_strdup_printf("pcapng: total block length %u of an EPB is less than the minimum EPB size %u",
2157 bh->block_total_length, MIN_EPB_SIZE);
2158 return false;
2160 if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
2161 ws_debug("failed to read packet data");
2162 return false;
2164 block_read = (unsigned)sizeof epb;
2166 if (section_info->byte_swapped) {
2167 packet.interface_id = GUINT32_SWAP_LE_BE(epb.interface_id);
2168 packet.drops_count = 0xFFFF; /* invalid */
2169 packet.ts_high = GUINT32_SWAP_LE_BE(epb.timestamp_high);
2170 packet.ts_low = GUINT32_SWAP_LE_BE(epb.timestamp_low);
2171 packet.cap_len = GUINT32_SWAP_LE_BE(epb.captured_len);
2172 packet.packet_len = GUINT32_SWAP_LE_BE(epb.packet_len);
2173 } else {
2174 packet.interface_id = epb.interface_id;
2175 packet.drops_count = 0xFFFF; /* invalid */
2176 packet.ts_high = epb.timestamp_high;
2177 packet.ts_low = epb.timestamp_low;
2178 packet.cap_len = epb.captured_len;
2179 packet.packet_len = epb.packet_len;
2181 ws_debug("EPB on interface_id %d, cap_len %d, packet_len %d",
2182 packet.interface_id, packet.cap_len, packet.packet_len);
2183 } else {
2185 * Is this block long enough to be a PB?
2187 if (bh->block_total_length < MIN_PB_SIZE) {
2189 * No.
2191 *err = WTAP_ERR_BAD_FILE;
2192 *err_info = ws_strdup_printf("pcapng: total block length %u of a PB is less than the minimum PB size %u",
2193 bh->block_total_length, MIN_PB_SIZE);
2194 return false;
2196 if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
2197 ws_debug("failed to read packet data");
2198 return false;
2200 block_read = (unsigned)sizeof pb;
2202 if (section_info->byte_swapped) {
2203 packet.interface_id = GUINT16_SWAP_LE_BE(pb.interface_id);
2204 packet.drops_count = GUINT16_SWAP_LE_BE(pb.drops_count);
2205 packet.ts_high = GUINT32_SWAP_LE_BE(pb.timestamp_high);
2206 packet.ts_low = GUINT32_SWAP_LE_BE(pb.timestamp_low);
2207 packet.cap_len = GUINT32_SWAP_LE_BE(pb.captured_len);
2208 packet.packet_len = GUINT32_SWAP_LE_BE(pb.packet_len);
2209 } else {
2210 packet.interface_id = pb.interface_id;
2211 packet.drops_count = pb.drops_count;
2212 packet.ts_high = pb.timestamp_high;
2213 packet.ts_low = pb.timestamp_low;
2214 packet.cap_len = pb.captured_len;
2215 packet.packet_len = pb.packet_len;
2217 ws_debug("PB on interface_id %d, cap_len %d, packet_len %d",
2218 packet.interface_id, packet.cap_len, packet.packet_len);
2222 * How much padding is there at the end of the packet data?
2224 if ((packet.cap_len % 4) != 0)
2225 padding = 4 - (packet.cap_len % 4);
2226 else
2227 padding = 0;
2230 * Is this block long enough to hold the packet data?
2232 if (enhanced) {
2233 if (bh->block_total_length <
2234 MIN_EPB_SIZE + packet.cap_len + padding) {
2236 * No.
2238 *err = WTAP_ERR_BAD_FILE;
2239 *err_info = ws_strdup_printf("pcapng: total block length %u of an EPB is too small for %u bytes of packet data",
2240 bh->block_total_length, packet.cap_len);
2241 return false;
2243 } else {
2244 if (bh->block_total_length <
2245 MIN_PB_SIZE + packet.cap_len + padding) {
2247 * No.
2249 *err = WTAP_ERR_BAD_FILE;
2250 *err_info = ws_strdup_printf("pcapng: total block length %u of a PB is too small for %u bytes of packet data",
2251 bh->block_total_length, packet.cap_len);
2252 return false;
2256 ws_debug("packet data: packet_len %u captured_len %u interface_id %u",
2257 packet.packet_len,
2258 packet.cap_len,
2259 packet.interface_id);
2261 if (packet.interface_id >= section_info->interfaces->len) {
2262 *err = WTAP_ERR_BAD_FILE;
2263 *err_info = ws_strdup_printf("pcapng: interface index %u is not less than section interface count %u",
2264 packet.interface_id,
2265 section_info->interfaces->len);
2266 return false;
2268 iface_info = g_array_index(section_info->interfaces, interface_info_t,
2269 packet.interface_id);
2271 if (packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
2272 *err = WTAP_ERR_BAD_FILE;
2273 *err_info = ws_strdup_printf("pcapng: cap_len %u is larger than %u",
2274 packet.cap_len,
2275 wtap_max_snaplen_for_encap(iface_info.wtap_encap));
2276 return false;
2279 wblock->rec->rec_type = REC_TYPE_PACKET;
2280 wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
2282 ws_debug("encapsulation = %d (%s), pseudo header size = %d.",
2283 iface_info.wtap_encap,
2284 wtap_encap_description(iface_info.wtap_encap),
2285 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
2286 wblock->rec->rec_header.packet_header.interface_id = packet.interface_id;
2287 wblock->rec->rec_header.packet_header.pkt_encap = iface_info.wtap_encap;
2288 wblock->rec->tsprec = iface_info.tsprecision;
2290 memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2291 pseudo_header_len = pcap_process_pseudo_header(fh,
2292 false, /* not a Nokia pcap - not a pcap at all */
2293 iface_info.wtap_encap,
2294 packet.cap_len,
2295 wblock->rec,
2296 err,
2297 err_info);
2298 if (pseudo_header_len < 0) {
2299 return false;
2301 block_read += pseudo_header_len;
2302 wblock->rec->rec_header.packet_header.caplen = packet.cap_len - pseudo_header_len;
2303 wblock->rec->rec_header.packet_header.len = packet.packet_len - pseudo_header_len;
2305 /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
2306 ts = (((uint64_t)packet.ts_high) << 32) | ((uint64_t)packet.ts_low);
2308 /* Convert it to seconds and nanoseconds. */
2309 wblock->rec->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
2310 wblock->rec->ts.nsecs = (int)(((ts % iface_info.time_units_per_second) * 1000000000) / iface_info.time_units_per_second);
2312 /* Add the time stamp offset. */
2313 wblock->rec->ts.secs = (time_t)(wblock->rec->ts.secs + iface_info.tsoffset);
2315 /* "(Enhanced) Packet Block" read capture data */
2316 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2317 packet.cap_len - pseudo_header_len, err, err_info))
2318 return false;
2319 block_read += packet.cap_len - pseudo_header_len;
2321 /* jump over potential padding bytes at end of the packet data */
2322 if (padding != 0) {
2323 if (!wtap_read_bytes(fh, NULL, padding, err, err_info))
2324 return false;
2325 block_read += padding;
2328 /* FCS length default */
2329 fcslen = iface_info.fcslen;
2331 /* Options */
2332 opt_cont_buf_len = bh->block_total_length -
2333 (int)sizeof(pcapng_block_header_t) -
2334 block_read - /* fixed and variable part, including padding */
2335 (int)sizeof(bh->block_total_length);
2336 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2337 pcapng_process_packet_block_option,
2338 OPT_SECTION_BYTE_ORDER, err, err_info))
2339 return false;
2342 * Did we get a packet flags option?
2344 if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(wblock->block, OPT_PKT_FLAGS, &flags)) {
2345 if (PACK_FLAGS_FCS_LENGTH(flags) != 0) {
2347 * The FCS length is present, but in units of octets, not
2348 * bits; convert it to bits.
2350 fcslen = PACK_FLAGS_FCS_LENGTH(flags)*8;
2354 * How about a drop_count option? If not, set it from other sources
2356 if (WTAP_OPTTYPE_SUCCESS != wtap_block_get_uint64_option_value(wblock->block, OPT_PKT_DROPCOUNT, &tmp64) && packet.drops_count != 0xFFFF) {
2357 wtap_block_add_uint64_option(wblock->block, OPT_PKT_DROPCOUNT, (uint64_t)packet.drops_count);
2360 pcap_read_post_process(false, iface_info.wtap_encap,
2361 wblock->rec, ws_buffer_start_ptr(wblock->frame_buffer),
2362 section_info->byte_swapped, fcslen);
2365 * We return these to the caller in pcapng_read().
2367 wblock->internal = false;
2370 * We want dissectors (particularly packet_frame) to be able to
2371 * access packet comments and whatnot that are in the block. wblock->block
2372 * will be unref'd by pcapng_seek_read(), so move the block to where
2373 * dissectors can find it.
2375 wblock->rec->block = wblock->block;
2376 wblock->block = NULL;
2378 return true;
2382 static bool
2383 pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh,
2384 const section_info_t *section_info,
2385 wtapng_block_t *wblock,
2386 int *err, char **err_info)
2388 interface_info_t iface_info;
2389 pcapng_simple_packet_block_t spb;
2390 wtapng_simple_packet_t simple_packet;
2391 uint32_t padding;
2392 int pseudo_header_len;
2395 * Is this block long enough to be an SPB?
2397 if (bh->block_total_length < MIN_SPB_SIZE) {
2399 * No.
2401 *err = WTAP_ERR_BAD_FILE;
2402 *err_info = ws_strdup_printf("pcapng: total block length %u of an SPB is less than the minimum SPB size %u",
2403 bh->block_total_length, MIN_SPB_SIZE);
2404 return false;
2407 /* "Simple Packet Block" read fixed part */
2408 if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
2409 ws_debug("failed to read packet data");
2410 return false;
2413 if (0 >= section_info->interfaces->len) {
2414 *err = WTAP_ERR_BAD_FILE;
2415 *err_info = g_strdup("pcapng: SPB appeared before any IDBs in the section");
2416 return false;
2418 iface_info = g_array_index(section_info->interfaces, interface_info_t, 0);
2420 if (section_info->byte_swapped) {
2421 simple_packet.packet_len = GUINT32_SWAP_LE_BE(spb.packet_len);
2422 } else {
2423 simple_packet.packet_len = spb.packet_len;
2427 * The captured length is not a field in the SPB; it can be
2428 * calculated as the minimum of the snapshot length from the
2429 * IDB and the packet length, as per the pcapng spec. An IDB
2430 * snapshot length of 0 means no limit.
2432 simple_packet.cap_len = simple_packet.packet_len;
2433 if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
2434 simple_packet.cap_len = iface_info.snap_len;
2437 * How much padding is there at the end of the packet data?
2439 if ((simple_packet.cap_len % 4) != 0)
2440 padding = 4 - (simple_packet.cap_len % 4);
2441 else
2442 padding = 0;
2445 * Is this block long enough to hold the packet data?
2447 if (bh->block_total_length < MIN_SPB_SIZE + simple_packet.cap_len + padding) {
2449 * No. That means that the problem is with the packet
2450 * length; the snapshot length can be bigger than the amount
2451 * of packet data in the block, as it's a *maximum* length,
2452 * not a *minimum* length.
2454 *err = WTAP_ERR_BAD_FILE;
2455 *err_info = ws_strdup_printf("pcapng: total block length %u of an SPB is too small for %u bytes of packet data",
2456 bh->block_total_length, simple_packet.packet_len);
2457 return false;
2460 if (simple_packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
2461 *err = WTAP_ERR_BAD_FILE;
2462 *err_info = ws_strdup_printf("pcapng: cap_len %u is larger than %u",
2463 simple_packet.cap_len,
2464 wtap_max_snaplen_for_encap(iface_info.wtap_encap));
2465 return false;
2467 ws_debug("packet data: packet_len %u",
2468 simple_packet.packet_len);
2470 ws_debug("Need to read pseudo header of size %d",
2471 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
2473 /* No time stamp in a simple packet block; no options, either */
2474 wblock->rec->rec_type = REC_TYPE_PACKET;
2475 wblock->rec->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
2476 wblock->rec->rec_header.packet_header.interface_id = 0;
2477 wblock->rec->rec_header.packet_header.pkt_encap = iface_info.wtap_encap;
2478 wblock->rec->tsprec = iface_info.tsprecision;
2479 wblock->rec->ts.secs = 0;
2480 wblock->rec->ts.nsecs = 0;
2481 wblock->rec->rec_header.packet_header.interface_id = 0;
2483 memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2484 pseudo_header_len = pcap_process_pseudo_header(fh,
2485 false,
2486 iface_info.wtap_encap,
2487 simple_packet.cap_len,
2488 wblock->rec,
2489 err,
2490 err_info);
2491 if (pseudo_header_len < 0) {
2492 return false;
2494 wblock->rec->rec_header.packet_header.caplen = simple_packet.cap_len - pseudo_header_len;
2495 wblock->rec->rec_header.packet_header.len = simple_packet.packet_len - pseudo_header_len;
2497 memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2499 /* "Simple Packet Block" read capture data */
2500 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2501 simple_packet.cap_len, err, err_info))
2502 return false;
2504 /* jump over potential padding bytes at end of the packet data */
2505 if ((simple_packet.cap_len % 4) != 0) {
2506 if (!wtap_read_bytes(fh, NULL, 4 - (simple_packet.cap_len % 4), err, err_info))
2507 return false;
2510 pcap_read_post_process(false, iface_info.wtap_encap,
2511 wblock->rec, ws_buffer_start_ptr(wblock->frame_buffer),
2512 section_info->byte_swapped, iface_info.fcslen);
2515 * We return these to the caller in pcapng_read().
2517 wblock->internal = false;
2519 return true;
2522 #define NRES_ENDOFRECORD 0
2523 #define NRES_IP4RECORD 1
2524 #define NRES_IP6RECORD 2
2525 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
2526 /* IPv6 + MAXDNSNAMELEN */
2527 #define INITIAL_NRB_REC_SIZE (16 + MAXDNSNAMELEN)
2530 * Find the end of the NUL-terminated name the beginning of which is pointed
2531 * to by p; record_len is the number of bytes remaining in the record.
2533 * Return the length of the name, including the terminating NUL.
2535 * If we don't find a terminating NUL, return -1 and set *err and
2536 * *err_info appropriately.
2538 static int
2539 name_resolution_block_find_name_end(const char *p, unsigned record_len, int *err,
2540 char **err_info)
2542 int namelen;
2544 namelen = 0;
2545 for (;;) {
2546 if (record_len == 0) {
2548 * We ran out of bytes in the record without
2549 * finding a NUL.
2551 *err = WTAP_ERR_BAD_FILE;
2552 *err_info = g_strdup("pcapng: NRB record has non-null-terminated host name");
2553 return -1;
2555 if (*p == '\0')
2556 break; /* that's the terminating NUL */
2557 p++;
2558 record_len--;
2559 namelen++; /* count this byte */
2562 /* Include the NUL in the name length. */
2563 return namelen + 1;
2566 static bool
2567 pcapng_process_name_resolution_block_option(wtapng_block_t *wblock,
2568 const section_info_t *section_info,
2569 uint16_t option_code,
2570 uint16_t option_length,
2571 const uint8_t *option_content,
2572 int *err, char **err_info)
2575 * Handle option content.
2577 * ***DO NOT*** add any items to this table that are not
2578 * standardized option codes in either section 3.5 "Options"
2579 * of the current pcapng spec, at
2581 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
2583 * or in the list of options in section 4.1 "Section Header Block"
2584 * of the current pcapng spec, at
2586 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
2588 * All option codes in this switch statement here must be listed
2589 * in one of those places as standardized option types.
2591 switch (option_code) {
2592 /* TODO:
2593 * ns_dnsname 2
2594 * ns_dnsIP4addr 3
2595 * ns_dnsIP6addr 4
2597 default:
2598 if (!pcapng_process_unhandled_option(wblock, BT_INDEX_NRB,
2599 section_info, option_code,
2600 option_length, option_content,
2601 err, err_info))
2602 return false;
2603 break;
2605 return true;
2608 static bool
2609 pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh,
2610 section_info_t *section_info,
2611 wtapng_block_t *wblock,
2612 int *err, char **err_info)
2614 int block_read;
2615 int to_read;
2616 pcapng_name_resolution_block_t nrb;
2617 Buffer nrb_rec;
2618 uint32_t v4_addr;
2619 unsigned record_len, opt_cont_buf_len;
2620 char *namep;
2621 int namelen;
2622 wtapng_nrb_mandatory_t *nrb_mand;
2625 * Is this block long enough to be an NRB?
2627 if (bh->block_total_length < MIN_NRB_SIZE) {
2629 * No.
2631 *err = WTAP_ERR_BAD_FILE;
2632 *err_info = ws_strdup_printf("pcapng: total block length %u of an NRB is less than the minimum NRB size %u",
2633 bh->block_total_length, MIN_NRB_SIZE);
2634 return false;
2637 to_read = bh->block_total_length - 8 - 4; /* We have read the header and should not read the final block_total_length */
2639 ws_debug("total %d bytes", bh->block_total_length);
2641 /* Ensure we have a name resolution block */
2642 if (wblock->block == NULL) {
2643 wblock->block = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
2647 * Set the mandatory values for the block.
2649 nrb_mand = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
2652 * Start out with a buffer big enough for an IPv6 address and one
2653 * 64-byte name; we'll make the buffer bigger if necessary.
2655 ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
2656 block_read = 0;
2657 while (block_read < to_read) {
2659 * There must be at least one record's worth of data
2660 * here.
2662 if ((size_t)(to_read - block_read) < sizeof nrb) {
2663 ws_buffer_free(&nrb_rec);
2664 *err = WTAP_ERR_BAD_FILE;
2665 *err_info = ws_strdup_printf("pcapng: %d bytes left in the block < NRB record header size %u",
2666 to_read - block_read,
2667 (unsigned)sizeof nrb);
2668 return false;
2670 if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
2671 ws_buffer_free(&nrb_rec);
2672 ws_debug("failed to read record header");
2673 return false;
2675 block_read += (int)sizeof nrb;
2677 if (section_info->byte_swapped) {
2678 nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type);
2679 nrb.record_len = GUINT16_SWAP_LE_BE(nrb.record_len);
2682 if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
2683 ws_buffer_free(&nrb_rec);
2684 *err = WTAP_ERR_BAD_FILE;
2685 *err_info = ws_strdup_printf("pcapng: %d bytes left in the block < NRB record length + padding %u",
2686 to_read - block_read,
2687 nrb.record_len + PADDING4(nrb.record_len));
2688 return false;
2690 switch (nrb.record_type) {
2691 case NRES_ENDOFRECORD:
2692 /* There shouldn't be any more data - but there MAY be options */
2693 goto read_options;
2694 break;
2695 case NRES_IP4RECORD:
2697 * The smallest possible record must have
2698 * a 4-byte IPv4 address, hence a minimum
2699 * of 4 bytes.
2701 * (The pcapng spec really indicates
2702 * that it must be at least 5 bytes,
2703 * as there must be at least one name,
2704 * and it really must be at least 6
2705 * bytes, as the name mustn't be null,
2706 * but there's no need to fail if there
2707 * aren't any names at all, and we
2708 * should report a null name as such.)
2710 if (nrb.record_len < 4) {
2711 ws_buffer_free(&nrb_rec);
2712 *err = WTAP_ERR_BAD_FILE;
2713 *err_info = ws_strdup_printf("pcapng: NRB record length for IPv4 record %u < minimum length 4",
2714 nrb.record_len);
2715 return false;
2717 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
2718 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
2719 nrb.record_len, err, err_info)) {
2720 ws_buffer_free(&nrb_rec);
2721 ws_debug("failed to read IPv4 record data");
2722 return false;
2724 block_read += nrb.record_len;
2727 * Scan through all the names in
2728 * the record and add them.
2730 memcpy(&v4_addr,
2731 ws_buffer_start_ptr(&nrb_rec), 4);
2732 /* IPv4 address is in big-endian order in the file always, which is how we store
2733 it internally as well, so don't byte-swap it */
2734 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
2735 record_len != 0;
2736 namep += namelen, record_len -= namelen) {
2738 * Scan forward for a null
2739 * byte.
2741 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
2742 if (namelen == -1) {
2743 ws_buffer_free(&nrb_rec);
2744 return false; /* fail */
2746 hashipv4_t *tp = g_new0(hashipv4_t, 1);
2747 tp->addr = v4_addr;
2748 (void) g_strlcpy(tp->name, namep, MAXDNSNAMELEN);
2749 nrb_mand->ipv4_addr_list = g_list_prepend(nrb_mand->ipv4_addr_list, tp);
2752 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
2753 ws_buffer_free(&nrb_rec);
2754 return false;
2756 block_read += PADDING4(nrb.record_len);
2757 break;
2758 case NRES_IP6RECORD:
2760 * The smallest possible record must have
2761 * a 16-byte IPv6 address, hence a minimum
2762 * of 16 bytes.
2764 * (The pcapng spec really indicates
2765 * that it must be at least 17 bytes,
2766 * as there must be at least one name,
2767 * and it really must be at least 18
2768 * bytes, as the name mustn't be null,
2769 * but there's no need to fail if there
2770 * aren't any names at all, and we
2771 * should report a null name as such.)
2773 if (nrb.record_len < 16) {
2774 ws_buffer_free(&nrb_rec);
2775 *err = WTAP_ERR_BAD_FILE;
2776 *err_info = ws_strdup_printf("pcapng: NRB record length for IPv6 record %u < minimum length 16",
2777 nrb.record_len);
2778 return false;
2780 if (to_read < nrb.record_len) {
2781 ws_buffer_free(&nrb_rec);
2782 *err = WTAP_ERR_BAD_FILE;
2783 *err_info = ws_strdup_printf("pcapng: NRB record length for IPv6 record %u > remaining data in NRB",
2784 nrb.record_len);
2785 return false;
2787 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
2788 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
2789 nrb.record_len, err, err_info)) {
2790 ws_buffer_free(&nrb_rec);
2791 return false;
2793 block_read += nrb.record_len;
2795 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
2796 record_len != 0;
2797 namep += namelen, record_len -= namelen) {
2799 * Scan forward for a null
2800 * byte.
2802 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
2803 if (namelen == -1) {
2804 ws_buffer_free(&nrb_rec);
2805 return false; /* fail */
2807 hashipv6_t *tp = g_new0(hashipv6_t, 1);
2808 memcpy(tp->addr, ws_buffer_start_ptr(&nrb_rec), sizeof tp->addr);
2809 (void) g_strlcpy(tp->name, namep, MAXDNSNAMELEN);
2810 nrb_mand->ipv6_addr_list = g_list_prepend(nrb_mand->ipv6_addr_list, tp);
2813 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
2814 ws_buffer_free(&nrb_rec);
2815 return false;
2817 block_read += PADDING4(nrb.record_len);
2818 break;
2819 default:
2820 ws_debug("unknown record type 0x%x", nrb.record_type);
2821 if (!wtap_read_bytes(fh, NULL, nrb.record_len + PADDING4(nrb.record_len), err, err_info)) {
2822 ws_buffer_free(&nrb_rec);
2823 return false;
2825 block_read += nrb.record_len + PADDING4(nrb.record_len);
2826 break;
2830 read_options:
2831 to_read -= block_read;
2833 /* Options */
2834 opt_cont_buf_len = to_read;
2835 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2836 pcapng_process_name_resolution_block_option,
2837 OPT_SECTION_BYTE_ORDER, err, err_info))
2838 return false;
2840 ws_buffer_free(&nrb_rec);
2843 * We don't return these to the caller in pcapng_read().
2845 wblock->internal = true;
2847 return true;
2850 static bool
2851 pcapng_process_interface_statistics_block_option(wtapng_block_t *wblock,
2852 const section_info_t *section_info,
2853 uint16_t option_code,
2854 uint16_t option_length,
2855 const uint8_t *option_content,
2856 int *err, char **err_info)
2859 * Handle option content.
2861 * ***DO NOT*** add any items to this table that are not
2862 * standardized option codes in either section 3.5 "Options"
2863 * of the current pcapng spec, at
2865 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
2867 * or in the list of options in section 4.1 "Section Header Block"
2868 * of the current pcapng spec, at
2870 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
2872 * All option codes in this switch statement here must be listed
2873 * in one of those places as standardized option types.
2875 switch (option_code) {
2876 case(OPT_ISB_STARTTIME): /* isb_starttime */
2877 pcapng_process_timestamp_option(wblock, section_info,
2878 OPT_SECTION_BYTE_ORDER,
2879 option_code, option_length,
2880 option_content);
2881 break;
2882 case(OPT_ISB_ENDTIME): /* isb_endtime */
2883 pcapng_process_timestamp_option(wblock, section_info,
2884 OPT_SECTION_BYTE_ORDER,
2885 option_code, option_length,
2886 option_content);
2887 break;
2888 case(OPT_ISB_IFRECV): /* isb_ifrecv */
2889 pcapng_process_uint64_option(wblock, section_info,
2890 OPT_SECTION_BYTE_ORDER,
2891 option_code, option_length,
2892 option_content);
2893 break;
2894 case(OPT_ISB_IFDROP): /* isb_ifdrop */
2895 pcapng_process_uint64_option(wblock, section_info,
2896 OPT_SECTION_BYTE_ORDER,
2897 option_code, option_length,
2898 option_content);
2899 break;
2900 case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
2901 pcapng_process_uint64_option(wblock, section_info,
2902 OPT_SECTION_BYTE_ORDER,
2903 option_code, option_length,
2904 option_content);
2905 break;
2906 case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
2907 pcapng_process_uint64_option(wblock, section_info,
2908 OPT_SECTION_BYTE_ORDER,
2909 option_code, option_length,
2910 option_content);
2911 break;
2912 case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8 */
2913 pcapng_process_uint64_option(wblock, section_info,
2914 OPT_SECTION_BYTE_ORDER,
2915 option_code, option_length,
2916 option_content);
2917 break;
2918 default:
2919 if (!pcapng_process_unhandled_option(wblock, BT_INDEX_ISB,
2920 section_info, option_code,
2921 option_length, option_content,
2922 err, err_info))
2923 return false;
2924 break;
2926 return true;
2929 static bool
2930 pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh,
2931 section_info_t *section_info,
2932 wtapng_block_t *wblock,
2933 int *err, char **err_info)
2935 unsigned opt_cont_buf_len;
2936 pcapng_interface_statistics_block_t isb;
2937 wtapng_if_stats_mandatory_t* if_stats_mand;
2940 * Is this block long enough to be an ISB?
2942 if (bh->block_total_length < MIN_ISB_SIZE) {
2944 * No.
2946 *err = WTAP_ERR_BAD_FILE;
2947 *err_info = ws_strdup_printf("pcapng: total block length %u of an ISB is too small (< %u)",
2948 bh->block_total_length, MIN_ISB_SIZE);
2949 return false;
2952 /* "Interface Statistics Block" read fixed part */
2953 if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
2954 ws_debug("failed to read packet data");
2955 return false;
2959 * Set wblock->block to a newly-allocated interface statistics block.
2961 wblock->block = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
2964 * Set the mandatory values for the block.
2966 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
2967 if (section_info->byte_swapped) {
2968 if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
2969 if_stats_mand->ts_high = GUINT32_SWAP_LE_BE(isb.timestamp_high);
2970 if_stats_mand->ts_low = GUINT32_SWAP_LE_BE(isb.timestamp_low);
2971 } else {
2972 if_stats_mand->interface_id = isb.interface_id;
2973 if_stats_mand->ts_high = isb.timestamp_high;
2974 if_stats_mand->ts_low = isb.timestamp_low;
2976 ws_debug("interface_id %u", if_stats_mand->interface_id);
2978 /* Options */
2979 opt_cont_buf_len = bh->block_total_length -
2980 (MIN_BLOCK_SIZE + (unsigned)sizeof isb); /* fixed and variable part, including padding */
2981 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2982 pcapng_process_interface_statistics_block_option,
2983 OPT_SECTION_BYTE_ORDER, err, err_info))
2984 return false;
2987 * We don't return these to the caller in pcapng_read().
2989 wblock->internal = true;
2991 return true;
2994 #define NFLX_BLOCK_TYPE_EVENT 1
2995 #define NFLX_BLOCK_TYPE_SKIP 2
2997 typedef struct pcapng_nflx_custom_block_s {
2998 uint32_t nflx_type;
2999 } pcapng_nflx_custom_block_t;
3001 #define MIN_NFLX_CB_SIZE ((uint32_t)(MIN_CB_SIZE + sizeof(pcapng_nflx_custom_block_t)))
3003 static bool
3004 pcapng_read_nflx_custom_block(FILE_T fh, pcapng_block_header_t *bh,
3005 section_info_t *section_info,
3006 wtapng_block_t *wblock,
3007 int *err, char **err_info)
3009 pcapng_nflx_custom_block_t nflx_cb;
3010 unsigned opt_cont_buf_len;
3011 uint32_t type, skipped;
3013 if (bh->block_total_length < MIN_NFLX_CB_SIZE) {
3014 *err = WTAP_ERR_BAD_FILE;
3015 *err_info = ws_strdup_printf("pcapng: total block length %u of a Netflix CB is too small (< %u)",
3016 bh->block_total_length, MIN_NFLX_CB_SIZE);
3017 return false;
3020 wblock->rec->rec_type = REC_TYPE_CUSTOM_BLOCK;
3021 wblock->rec->rec_header.custom_block_header.pen = PEN_NFLX;
3022 /* "NFLX Custom Block" read fixed part */
3023 if (!wtap_read_bytes(fh, &nflx_cb, sizeof nflx_cb, err, err_info)) {
3024 ws_debug("Failed to read nflx type");
3025 return false;
3027 type = GUINT32_FROM_LE(nflx_cb.nflx_type);
3028 ws_debug("BBLog type: %u", type);
3029 switch (type) {
3030 case NFLX_BLOCK_TYPE_EVENT:
3032 * The fixed-length portion is MIN_NFLX_CB_SIZE bytes.
3033 * We already know we have that much data in the block.
3035 wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type = BBLOG_TYPE_EVENT_BLOCK;
3036 opt_cont_buf_len = bh->block_total_length - MIN_NFLX_CB_SIZE;
3037 ws_debug("event");
3038 break;
3039 case NFLX_BLOCK_TYPE_SKIP:
3041 * The fixed-length portion is MIN_NFLX_CB_SIZE bytes plus a
3042 * 32-bit value.
3044 * Make sure we have that much data in the block.
3046 if (bh->block_total_length < MIN_NFLX_CB_SIZE + (uint32_t)sizeof(uint32_t)) {
3047 *err = WTAP_ERR_BAD_FILE;
3048 *err_info = ws_strdup_printf("pcapng: total block length %u of a Netflix skip CB is too small (< %u)",
3049 bh->block_total_length,
3050 MIN_NFLX_CB_SIZE + (uint32_t)sizeof(uint32_t));
3051 return false;
3053 if (!wtap_read_bytes(fh, &skipped, sizeof(uint32_t), err, err_info)) {
3054 ws_debug("Failed to read skipped");
3055 return false;
3057 wblock->rec->presence_flags = 0;
3058 wblock->rec->rec_header.custom_block_header.length = 4;
3059 wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type = BBLOG_TYPE_SKIPPED_BLOCK;
3060 wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped = GUINT32_FROM_LE(skipped);
3061 wblock->internal = false;
3062 opt_cont_buf_len = bh->block_total_length - MIN_NFLX_CB_SIZE - sizeof(uint32_t);
3063 ws_debug("skipped: %u", wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
3064 break;
3065 default:
3066 ws_debug("Unknown type %u", type);
3067 return false;
3070 /* Options */
3071 if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
3072 NULL, OPT_LITTLE_ENDIAN, err, err_info))
3073 return false;
3075 return true;
3078 static bool
3079 pcapng_handle_generic_custom_block(FILE_T fh, pcapng_block_header_t *bh,
3080 uint32_t pen, wtapng_block_t *wblock,
3081 int *err, char **err_info)
3083 unsigned to_read;
3085 ws_debug("unknown pen %u", pen);
3086 if (bh->block_total_length % 4) {
3087 to_read = bh->block_total_length + 4 - (bh->block_total_length % 4);
3088 } else {
3089 to_read = bh->block_total_length;
3091 to_read -= MIN_CB_SIZE;
3092 wblock->rec->rec_type = REC_TYPE_CUSTOM_BLOCK;
3093 wblock->rec->presence_flags = 0;
3094 wblock->rec->rec_header.custom_block_header.length = bh->block_total_length - MIN_CB_SIZE;
3095 wblock->rec->rec_header.custom_block_header.pen = pen;
3096 wblock->rec->rec_header.custom_block_header.copy_allowed = (bh->block_type == BLOCK_TYPE_CB_COPY);
3097 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer, to_read, err, err_info)) {
3098 return false;
3101 * We return these to the caller in pcapng_read().
3103 wblock->internal = false;
3104 return true;
3107 static bool
3108 pcapng_read_custom_block(FILE_T fh, pcapng_block_header_t *bh,
3109 section_info_t *section_info,
3110 wtapng_block_t *wblock,
3111 int *err, char **err_info)
3113 pcapng_custom_block_t cb;
3114 uint32_t pen;
3116 /* Is this block long enough to be an CB? */
3117 if (bh->block_total_length < MIN_CB_SIZE) {
3119 * No.
3121 *err = WTAP_ERR_BAD_FILE;
3122 *err_info = ws_strdup_printf("pcapng: total block length %u of a CB is too small (< %u)",
3123 bh->block_total_length, MIN_CB_SIZE);
3124 return false;
3127 wblock->block = wtap_block_create(WTAP_BLOCK_CUSTOM);
3129 /* Custom block read fixed part */
3130 if (!wtap_read_bytes(fh, &cb, sizeof cb, err, err_info)) {
3131 ws_debug("failed to read pen");
3132 return false;
3134 if (section_info->byte_swapped) {
3135 pen = GUINT32_SWAP_LE_BE(cb.pen);
3136 } else {
3137 pen = cb.pen;
3139 ws_debug("pen %u, custom data and option length %u", pen, bh->block_total_length - MIN_CB_SIZE);
3141 switch (pen) {
3142 case PEN_NFLX:
3143 if (!pcapng_read_nflx_custom_block(fh, bh, section_info, wblock, err, err_info))
3144 return false;
3145 break;
3146 default:
3147 if (!pcapng_handle_generic_custom_block(fh, bh, pen, wblock, err, err_info)) {
3148 return false;
3150 break;
3153 wblock->rec->block = wblock->block;
3154 wblock->block = NULL;
3155 wblock->internal = false;
3157 return true;
3160 static bool
3161 pcapng_read_sysdig_event_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
3162 const section_info_t *section_info,
3163 wtapng_block_t *wblock,
3164 int *err, char **err_info)
3166 unsigned block_read;
3167 uint16_t cpu_id;
3168 uint64_t wire_ts;
3169 uint64_t ts;
3170 uint64_t thread_id;
3171 uint32_t event_len;
3172 uint16_t event_type;
3173 uint32_t nparams = 0;
3174 unsigned min_event_size;
3176 switch (bh->block_type) {
3177 case BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE:
3178 case BLOCK_TYPE_SYSDIG_EVENT_V2:
3179 min_event_size = MIN_SYSDIG_EVENT_V2_SIZE;
3180 break;
3181 default:
3182 min_event_size = MIN_SYSDIG_EVENT_SIZE;
3183 break;
3186 if (bh->block_total_length < min_event_size) {
3187 *err = WTAP_ERR_BAD_FILE;
3188 *err_info = ws_strdup_printf("pcapng: total block length %u of a Sysdig event block is too small (< %u)",
3189 bh->block_total_length, min_event_size);
3190 return false;
3193 wblock->rec->rec_type = REC_TYPE_SYSCALL;
3194 wblock->rec->rec_header.syscall_header.record_type = bh->block_type;
3195 wblock->rec->presence_flags = WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
3196 wblock->rec->tsprec = WTAP_TSPREC_NSEC;
3198 if (!wtap_read_bytes(fh, &cpu_id, sizeof cpu_id, err, err_info)) {
3199 ws_debug("failed to read sysdig event cpu id");
3200 return false;
3202 if (!wtap_read_bytes(fh, &wire_ts, sizeof wire_ts, err, err_info)) {
3203 ws_debug("failed to read sysdig event timestamp");
3204 return false;
3206 if (!wtap_read_bytes(fh, &thread_id, sizeof thread_id, err, err_info)) {
3207 ws_debug("failed to read sysdig event thread id");
3208 return false;
3210 if (!wtap_read_bytes(fh, &event_len, sizeof event_len, err, err_info)) {
3211 ws_debug("failed to read sysdig event length");
3212 return false;
3214 if (!wtap_read_bytes(fh, &event_type, sizeof event_type, err, err_info)) {
3215 ws_debug("failed to read sysdig event type");
3216 return false;
3218 if (bh->block_type == BLOCK_TYPE_SYSDIG_EVENT_V2 || bh->block_type == BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE) {
3219 if (!wtap_read_bytes(fh, &nparams, sizeof nparams, err, err_info)) {
3220 ws_debug("failed to read sysdig number of parameters");
3221 return false;
3225 wblock->rec->rec_header.syscall_header.pathname = wth->pathname;
3226 wblock->rec->rec_header.syscall_header.byte_order = G_BYTE_ORDER;
3228 /* XXX Use Gxxx_FROM_LE macros instead? */
3229 if (section_info->byte_swapped) {
3230 wblock->rec->rec_header.syscall_header.byte_order =
3231 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3232 G_BIG_ENDIAN;
3233 #else
3234 G_LITTLE_ENDIAN;
3235 #endif
3236 wblock->rec->rec_header.syscall_header.cpu_id = GUINT16_SWAP_LE_BE(cpu_id);
3237 ts = GUINT64_SWAP_LE_BE(wire_ts);
3238 wblock->rec->rec_header.syscall_header.thread_id = GUINT64_SWAP_LE_BE(thread_id);
3239 wblock->rec->rec_header.syscall_header.event_len = GUINT32_SWAP_LE_BE(event_len);
3240 wblock->rec->rec_header.syscall_header.event_type = GUINT16_SWAP_LE_BE(event_type);
3241 wblock->rec->rec_header.syscall_header.nparams = GUINT32_SWAP_LE_BE(nparams);
3242 } else {
3243 wblock->rec->rec_header.syscall_header.cpu_id = cpu_id;
3244 ts = wire_ts;
3245 wblock->rec->rec_header.syscall_header.thread_id = thread_id;
3246 wblock->rec->rec_header.syscall_header.event_len = event_len;
3247 wblock->rec->rec_header.syscall_header.event_type = event_type;
3248 wblock->rec->rec_header.syscall_header.nparams = nparams;
3251 if (ts) {
3252 wblock->rec->presence_flags |= WTAP_HAS_TS;
3255 wblock->rec->ts.secs = (time_t) (ts / 1000000000);
3256 wblock->rec->ts.nsecs = (int) (ts % 1000000000);
3258 block_read = bh->block_total_length - min_event_size;
3260 wblock->rec->rec_header.syscall_header.event_filelen = block_read;
3262 /* "Sysdig Event Block" read event data */
3263 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
3264 block_read, err, err_info))
3265 return false;
3267 /* XXX Read comment? */
3270 * We return these to the caller in pcapng_read().
3272 wblock->internal = false;
3274 return true;
3277 static bool
3278 pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_, wtapng_block_t *wblock, int *err, char **err_info)
3280 uint32_t entry_length;
3281 uint64_t rt_ts;
3282 bool have_ts = false;
3284 if (bh->block_total_length < MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE) {
3285 *err = WTAP_ERR_BAD_FILE;
3286 *err_info = ws_strdup_printf("pcapng: total block length %u of a systemd journal export block is too small (< %u)",
3287 bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE);
3288 return false;
3291 entry_length = bh->block_total_length - MIN_BLOCK_SIZE;
3293 /* Includes padding bytes. */
3294 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
3295 entry_length, err, err_info)) {
3296 return false;
3300 * We don't have memmem available everywhere, so we get to add space for
3301 * a trailing \0 for strstr below.
3303 ws_buffer_assure_space(wblock->frame_buffer, entry_length+1);
3305 char *buf_ptr = (char *) ws_buffer_start_ptr(wblock->frame_buffer);
3306 while (entry_length > 0 && buf_ptr[entry_length-1] == '\0') {
3307 entry_length--;
3310 if (entry_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE) {
3311 *err = WTAP_ERR_BAD_FILE;
3312 *err_info = ws_strdup_printf("pcapng: entry length %u is too small (< %u)",
3313 bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE);
3314 return false;
3317 ws_debug("entry_length %u", entry_length);
3319 size_t rt_ts_len = strlen(SDJ__REALTIME_TIMESTAMP);
3321 buf_ptr[entry_length] = '\0';
3322 char *ts_pos = strstr(buf_ptr, SDJ__REALTIME_TIMESTAMP);
3324 if (!ts_pos) {
3325 ws_debug("no timestamp");
3326 } else if (ts_pos+rt_ts_len >= (char *) buf_ptr+entry_length) {
3327 ws_debug("timestamp past end of buffer");
3328 } else {
3329 const char *ts_end;
3330 have_ts = ws_strtou64(ts_pos+rt_ts_len, &ts_end, &rt_ts);
3332 if (!have_ts) {
3333 ws_debug("invalid timestamp");
3337 wblock->rec->rec_type = REC_TYPE_SYSTEMD_JOURNAL_EXPORT;
3338 wblock->rec->rec_header.systemd_journal_export_header.record_len = entry_length;
3339 wblock->rec->presence_flags = WTAP_HAS_CAP_LEN;
3340 if (have_ts) {
3341 wblock->rec->presence_flags |= WTAP_HAS_TS;
3342 wblock->rec->tsprec = WTAP_TSPREC_USEC;
3343 wblock->rec->ts.secs = (time_t) (rt_ts / 1000000);
3344 wblock->rec->ts.nsecs = (rt_ts % 1000000) * 1000;
3348 * We return these to the caller in pcapng_read().
3350 wblock->internal = false;
3352 if (wth->file_encap == WTAP_ENCAP_NONE) {
3354 * Nothing (most notably an IDB) has set a file encap at this point.
3355 * Do so here.
3356 * XXX Should we set WTAP_ENCAP_SYSTEMD_JOURNAL if appropriate?
3358 wth->file_encap = WTAP_ENCAP_PER_PACKET;
3361 return true;
3364 static bool
3365 pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh,
3366 #ifdef HAVE_PLUGINS
3367 const section_info_t *section_info,
3368 #else
3369 const section_info_t *section_info _U_,
3370 #endif
3371 wtapng_block_t *wblock,
3372 int *err, char **err_info)
3374 uint32_t block_read;
3375 #ifdef HAVE_PLUGINS
3376 block_handler *handler;
3377 #endif
3379 if (bh->block_total_length < MIN_BLOCK_SIZE) {
3380 *err = WTAP_ERR_BAD_FILE;
3381 *err_info = ws_strdup_printf("pcapng: total block length %u of an unknown block type is less than the minimum block size %u",
3382 bh->block_total_length, MIN_BLOCK_SIZE);
3383 return false;
3386 block_read = bh->block_total_length - MIN_BLOCK_SIZE;
3388 #ifdef HAVE_PLUGINS
3390 * Do we have a handler for this block type?
3392 if (block_handlers != NULL &&
3393 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
3394 GUINT_TO_POINTER(bh->block_type))) != NULL) {
3395 /* Yes - call it to read this block type. */
3396 if (!handler->reader(fh, block_read, section_info->byte_swapped, wblock,
3397 err, err_info))
3398 return false;
3399 } else
3400 #endif
3402 /* No. Skip over this unknown block. */
3403 if (!wtap_read_bytes(fh, NULL, block_read, err, err_info)) {
3404 return false;
3408 * We're skipping this, so we won't return these to the caller
3409 * in pcapng_read().
3411 wblock->internal = true;
3414 return true;
3417 static bool
3418 pcapng_read_and_check_block_trailer(FILE_T fh, pcapng_block_header_t *bh,
3419 section_info_t *section_info,
3420 int *err, char **err_info)
3422 uint32_t block_total_length;
3424 /* sanity check: first and second block lengths must match */
3425 if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
3426 err, err_info)) {
3427 ws_debug("couldn't read second block length");
3428 return false;
3431 if (section_info->byte_swapped)
3432 block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
3435 * According to the pcapng spec, this should equal the block total
3436 * length value at the beginning of the block, which MUST (in the
3437 * IANA sense) be a multiple of 4.
3439 * We round the value at the beginning of the block to a multiple
3440 * of 4, so do so with this value as well. This *does* mean that
3441 * the two values, if they're not both multiples of 4, can differ
3442 * and this code won't detect that, but we're already not detecting
3443 * non-multiple-of-4 total lengths.
3445 block_total_length = ROUND_TO_4BYTE(block_total_length);
3447 if (block_total_length != bh->block_total_length) {
3448 *err = WTAP_ERR_BAD_FILE;
3449 *err_info = ws_strdup_printf("pcapng: total block lengths (first %u and second %u) don't match",
3450 bh->block_total_length, block_total_length);
3451 return false;
3453 return true;
3456 static bool
3457 pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn,
3458 section_info_t *section_info,
3459 section_info_t *new_section_info,
3460 wtapng_block_t *wblock,
3461 int *err, char **err_info)
3463 block_return_val ret;
3464 pcapng_block_header_t bh;
3466 wblock->block = NULL;
3468 /* Try to read the (next) block header */
3469 if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
3470 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err);
3471 return false;
3475 * SHBs have to be treated differently from other blocks, because
3476 * the byte order of the fields in the block can only be determined
3477 * by looking at the byte-order magic number inside the block, not
3478 * by using the byte order of the section to which it belongs, as
3479 * it is the block that *defines* the byte order of the section to
3480 * which it belongs.
3482 if (bh.block_type == BLOCK_TYPE_SHB) {
3484 * BLOCK_TYPE_SHB has the same value regardless of byte order,
3485 * so we don't need to byte-swap it.
3487 * We *might* need to byte-swap the total length, but we
3488 * can't determine whether we do until we look inside the
3489 * block and find the byte-order magic number, so we rely
3490 * on pcapng_read_section_header_block() to do that and
3491 * to swap the total length (as it needs to get the total
3492 * length in the right byte order in order to read the
3493 * entire block).
3495 wblock->type = bh.block_type;
3497 ws_debug("block_type BLOCK_TYPE_SHB (0x%08x)", bh.block_type);
3500 * Fill in the section_info_t passed to us for use when
3501 * there's a new SHB; don't overwrite the existing SHB,
3502 * if there is one.
3504 ret = pcapng_read_section_header_block(fh, &bh, new_section_info,
3505 wblock, err, err_info);
3506 if (ret != PCAPNG_BLOCK_OK) {
3507 return false;
3511 * This is the current section; use its byte order, not that
3512 * of the section pointed to by section_info (which could be
3513 * null).
3515 section_info = new_section_info;
3516 } else {
3518 * Not an SHB.
3520 if (section_info->byte_swapped) {
3521 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
3522 bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length);
3526 * Add padding bytes to the block total length.
3527 * (The "block total length" fields of some example files
3528 * don't contain the packet data padding bytes!)
3530 * For all block types currently defined in the pcapng
3531 * specification, the portion of the block that precedes
3532 * the options is, if necessary, padded to be a multiple
3533 * of 4 octets, the header of an option is 4 octets long,
3534 * and the value of an option is also padded to be a
3535 * multiple of 4 octets, so the total length of a block
3536 * is always a multiple of 4 octets.
3538 * If you have defined a block where that is not true, you
3539 * have violated the pcapng specification - hwere it says
3540 * that "[The value fo the Block Total Length] MUST be a
3541 * multiple of 4.", with MUST as described in BCP 14 (RFC 2119/
3542 * RFC 8174).
3544 * Therefore, if adjusting the block total length causes the
3545 * code to read your block type not to work, that's your
3546 * problem. It's bad enough that some blocks were written
3547 * out with the block total length not including the padding.
3548 * (Please note that libpcap is less forgiving that we are;
3549 * it reports an error if the block total length isn't a
3550 * multiple of 4.)
3552 bh.block_total_length = ROUND_TO_4BYTE(bh.block_total_length);
3554 wblock->type = bh.block_type;
3556 ws_noisy("block_type 0x%08x", bh.block_type);
3558 /* Don't try to allocate memory for a huge number of options, as
3559 that might fail and, even if it succeeds, it might not leave
3560 any address space or memory+backing store for anything else.
3562 We do that by imposing a maximum block size of MAX_BLOCK_SIZE. */
3563 if (bh.block_total_length > MAX_BLOCK_SIZE) {
3564 *err = WTAP_ERR_BAD_FILE;
3565 *err_info = ws_strdup_printf("pcapng: total block length %u is too large (> %u)",
3566 bh.block_total_length, MAX_BLOCK_SIZE);
3567 return false;
3571 * ***DO NOT*** add any items to this table that are not
3572 * standardized block types in the current pcapng spec at
3574 * https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html
3576 * All block types in this switch statement here must be
3577 * listed there as standardized block types, ideally with
3578 * a description.
3580 switch (bh.block_type) {
3581 case(BLOCK_TYPE_IDB):
3582 if (!pcapng_read_if_descr_block(wth, fh, &bh, section_info, wblock, err, err_info))
3583 return false;
3584 break;
3585 case(BLOCK_TYPE_PB):
3586 if (!pcapng_read_packet_block(fh, &bh, section_info, wblock, err, err_info, false))
3587 return false;
3588 break;
3589 case(BLOCK_TYPE_SPB):
3590 if (!pcapng_read_simple_packet_block(fh, &bh, section_info, wblock, err, err_info))
3591 return false;
3592 break;
3593 case(BLOCK_TYPE_EPB):
3594 if (!pcapng_read_packet_block(fh, &bh, section_info, wblock, err, err_info, true))
3595 return false;
3596 break;
3597 case(BLOCK_TYPE_NRB):
3598 if (!pcapng_read_name_resolution_block(fh, &bh, section_info, wblock, err, err_info))
3599 return false;
3600 break;
3601 case(BLOCK_TYPE_ISB):
3602 if (!pcapng_read_interface_statistics_block(fh, &bh, section_info, wblock, err, err_info))
3603 return false;
3604 break;
3605 case(BLOCK_TYPE_DSB):
3606 if (!pcapng_read_decryption_secrets_block(fh, &bh, section_info, wblock, err, err_info))
3607 return false;
3608 break;
3609 case BLOCK_TYPE_SYSDIG_MI:
3610 case BLOCK_TYPE_SYSDIG_PL_V1:
3611 case BLOCK_TYPE_SYSDIG_FDL_V1:
3612 case BLOCK_TYPE_SYSDIG_IL_V1:
3613 case BLOCK_TYPE_SYSDIG_UL_V1:
3614 case BLOCK_TYPE_SYSDIG_PL_V2:
3615 case BLOCK_TYPE_SYSDIG_PL_V3:
3616 case BLOCK_TYPE_SYSDIG_PL_V4:
3617 case BLOCK_TYPE_SYSDIG_PL_V5:
3618 case BLOCK_TYPE_SYSDIG_PL_V6:
3619 case BLOCK_TYPE_SYSDIG_PL_V7:
3620 case BLOCK_TYPE_SYSDIG_PL_V8:
3621 case BLOCK_TYPE_SYSDIG_PL_V9:
3622 case BLOCK_TYPE_SYSDIG_FDL_V2:
3623 case BLOCK_TYPE_SYSDIG_IL_V2:
3624 case BLOCK_TYPE_SYSDIG_UL_V2:
3625 if (!pcapng_read_meta_event_block(fh, &bh, wblock, err, err_info))
3626 return false;
3627 break;
3628 case(BLOCK_TYPE_CB_COPY):
3629 case(BLOCK_TYPE_CB_NO_COPY):
3630 if (!pcapng_read_custom_block(fh, &bh, section_info, wblock, err, err_info))
3631 return false;
3632 break;
3633 case(BLOCK_TYPE_SYSDIG_EVENT):
3634 case(BLOCK_TYPE_SYSDIG_EVENT_V2):
3635 case(BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE):
3636 /* case(BLOCK_TYPE_SYSDIG_EVF): */
3637 if (!pcapng_read_sysdig_event_block(wth, fh, &bh, section_info, wblock, err, err_info))
3638 return false;
3639 break;
3640 case(BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT):
3641 if (!pcapng_read_systemd_journal_export_block(wth, fh, &bh, pn, wblock, err, err_info))
3642 return false;
3643 break;
3644 default:
3645 ws_debug("Unknown block_type: 0x%08x (block ignored), block total length %d",
3646 bh.block_type, bh.block_total_length);
3647 if (!pcapng_read_unknown_block(fh, &bh, section_info, wblock, err, err_info))
3648 return false;
3649 break;
3654 * Read and check the block trailer.
3656 if (!pcapng_read_and_check_block_trailer(fh, &bh, section_info, err, err_info)) {
3657 /* Not readable or not valid. */
3658 return false;
3660 return true;
3663 /* Process an IDB that we've just read. The contents of wblock are copied as needed. */
3664 static void
3665 pcapng_process_idb(wtap *wth, section_info_t *section_info,
3666 wtapng_block_t *wblock)
3668 wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
3669 interface_info_t iface_info;
3670 wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data),
3671 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3672 uint8_t if_fcslen;
3674 wtap_block_copy(int_data, wblock->block);
3676 /* XXX if_tsoffset; opt 14 A 64 bits integer value that specifies an offset (in seconds)...*/
3677 /* Interface statistics */
3678 if_descr_mand->num_stat_entries = 0;
3679 if_descr_mand->interface_statistics = NULL;
3681 wtap_add_idb(wth, int_data);
3683 iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
3684 iface_info.snap_len = wblock_if_descr_mand->snap_len;
3685 iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
3686 iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
3689 * Did we get an FCS length option?
3691 if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_FCSLEN,
3692 &if_fcslen) == WTAP_OPTTYPE_SUCCESS) {
3694 * Yes.
3696 iface_info.fcslen = if_fcslen;
3697 } else {
3699 * No. Mark the FCS length as unknown.
3701 iface_info.fcslen = -1;
3705 * Did we get a time stamp offset option?
3707 if (wtap_block_get_int64_option_value(wblock->block, OPT_IDB_TSOFFSET,
3708 &iface_info.tsoffset) == WTAP_OPTTYPE_SUCCESS) {
3710 * Yes.
3712 * Remove the option, as the time stamps we provide will be
3713 * absolute time stamps, with the offset added in, so it will
3714 * appear as if there were no such option.
3716 wtap_block_remove_option(wblock->block, OPT_IDB_TSOFFSET);
3717 } else {
3719 * No. Default to 0, meahing that time stamps in the file are
3720 * absolute time stamps.
3722 iface_info.tsoffset = 0;
3725 g_array_append_val(section_info->interfaces, iface_info);
3728 /* Process an NRB that we have just read. */
3729 static void
3730 pcapng_process_nrb(wtap *wth, wtapng_block_t *wblock)
3732 wtapng_process_nrb(wth, wblock->block);
3734 if (wth->nrbs == NULL) {
3735 wth->nrbs = g_array_new(false, false, sizeof(wtap_block_t));
3737 /* Store NRB such that it can be saved by the dumper. */
3738 g_array_append_val(wth->nrbs, wblock->block);
3741 /* Process a DSB that we have just read. */
3742 static void
3743 pcapng_process_dsb(wtap *wth, wtapng_block_t *wblock)
3745 wtapng_process_dsb(wth, wblock->block);
3747 /* Store DSB such that it can be saved by the dumper. */
3748 g_array_append_val(wth->dsbs, wblock->block);
3751 /* Process a Sysdig meta event block that we have just read. */
3752 static void
3753 pcapng_process_meta_event(wtap *wth, wtapng_block_t *wblock)
3755 // XXX add wtapng_process_meta_event(wth, wblock->block);
3757 /* Store meta event such that it can be saved by the dumper. */
3758 g_array_append_val(wth->meta_events, wblock->block);
3761 static void
3762 pcapng_process_internal_block(wtap *wth, pcapng_t *pcapng, section_info_t *current_section, section_info_t new_section, wtapng_block_t *wblock, const int64_t *data_offset)
3764 wtap_block_t wtapng_if_descr;
3765 wtap_block_t if_stats;
3766 wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
3767 wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
3769 switch (wblock->type) {
3771 case(BLOCK_TYPE_SHB):
3772 ws_debug("another section header block");
3775 * Add this SHB to the table of SHBs.
3777 g_array_append_val(wth->shb_hdrs, wblock->block);
3778 g_array_append_val(wth->shb_iface_to_global, wth->interface_data->len);
3781 * Update the current section number, and add
3782 * the updated section_info_t to the array of
3783 * section_info_t's for this file.
3785 pcapng->current_section_number++;
3786 new_section.interfaces = g_array_new(false, false, sizeof(interface_info_t));
3787 new_section.shb_off = *data_offset;
3788 g_array_append_val(pcapng->sections, new_section);
3789 break;
3791 case(BLOCK_TYPE_IDB):
3792 /* A new interface */
3793 ws_debug("block type BLOCK_TYPE_IDB");
3794 pcapng_process_idb(wth, current_section, wblock);
3795 wtap_block_unref(wblock->block);
3796 break;
3798 case(BLOCK_TYPE_DSB):
3799 /* Decryption secrets. */
3800 ws_debug("block type BLOCK_TYPE_DSB");
3801 pcapng_process_dsb(wth, wblock);
3802 /* Do not free wblock->block, it is consumed by pcapng_process_dsb */
3803 break;
3805 case(BLOCK_TYPE_NRB):
3806 /* More name resolution entries */
3807 ws_debug("block type BLOCK_TYPE_NRB");
3808 pcapng_process_nrb(wth, wblock);
3809 /* Do not free wblock->block, it is consumed by pcapng_process_nrb */
3810 break;
3812 case(BLOCK_TYPE_ISB):
3814 * Another interface statistics report
3816 * XXX - given that they're reports, we should be
3817 * supplying them in read calls, and displaying them
3818 * in the "packet" list, so you can see what the
3819 * statistics were *at the time when the report was
3820 * made*.
3822 * The statistics from the *last* ISB could be displayed
3823 * in the summary, but if there are packets after the
3824 * last ISB, that could be misleading.
3826 * If we only display them if that ISB has an isb_endtime
3827 * option, which *should* only appear when capturing ended
3828 * on that interface (so there should be no more packet
3829 * blocks or ISBs for that interface after that point,
3830 * that would be the best way of showing "summary"
3831 * statistics.
3833 ws_debug("block type BLOCK_TYPE_ISB");
3834 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3835 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
3836 ws_debug("BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces",
3837 if_stats_mand_block->interface_id);
3838 } else {
3839 /* Get the interface description */
3840 wtapng_if_descr = g_array_index(wth->interface_data, wtap_block_t, if_stats_mand_block->interface_id);
3841 wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
3842 if (wtapng_if_descr_mand->num_stat_entries == 0) {
3843 /* First ISB found, no previous entry */
3844 ws_debug("block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
3845 wtapng_if_descr_mand->interface_statistics = g_array_new(false, false, sizeof(wtap_block_t));
3848 if_stats = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
3849 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
3850 if_stats_mand->interface_id = if_stats_mand_block->interface_id;
3851 if_stats_mand->ts_high = if_stats_mand_block->ts_high;
3852 if_stats_mand->ts_low = if_stats_mand_block->ts_low;
3854 wtap_block_copy(if_stats, wblock->block);
3855 g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
3856 wtapng_if_descr_mand->num_stat_entries++;
3858 wtap_block_unref(wblock->block);
3859 break;
3861 case BLOCK_TYPE_SYSDIG_MI:
3862 case BLOCK_TYPE_SYSDIG_PL_V1:
3863 case BLOCK_TYPE_SYSDIG_FDL_V1:
3864 case BLOCK_TYPE_SYSDIG_IL_V1:
3865 case BLOCK_TYPE_SYSDIG_UL_V1:
3866 case BLOCK_TYPE_SYSDIG_PL_V2:
3867 case BLOCK_TYPE_SYSDIG_PL_V3:
3868 case BLOCK_TYPE_SYSDIG_PL_V4:
3869 case BLOCK_TYPE_SYSDIG_PL_V5:
3870 case BLOCK_TYPE_SYSDIG_PL_V6:
3871 case BLOCK_TYPE_SYSDIG_PL_V7:
3872 case BLOCK_TYPE_SYSDIG_PL_V8:
3873 case BLOCK_TYPE_SYSDIG_PL_V9:
3874 case BLOCK_TYPE_SYSDIG_FDL_V2:
3875 case BLOCK_TYPE_SYSDIG_IL_V2:
3876 case BLOCK_TYPE_SYSDIG_UL_V2:
3877 /* Meta events */
3878 ws_debug("block type Sysdig meta event");
3879 pcapng_process_meta_event(wth, wblock);
3880 /* Do not free wblock->block, it is consumed by pcapng_process_sysdig_meb */
3881 break;
3883 default:
3884 /* XXX - improve handling of "unknown" blocks */
3885 ws_debug("Unknown block type 0x%08x", wblock->type);
3886 break;
3890 /* classic wtap: open capture file */
3891 wtap_open_return_val
3892 pcapng_open(wtap *wth, int *err, char **err_info)
3894 wtapng_block_t wblock;
3895 pcapng_t *pcapng;
3896 pcapng_block_header_t bh;
3897 int64_t saved_offset;
3898 section_info_t first_section, new_section, *current_section;
3900 ws_debug("opening file");
3902 * Read first block.
3904 * First, try to read the block header.
3906 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3907 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err);
3908 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
3910 * Short read or EOF.
3912 * We're reading this as part of an open, so
3913 * the file is too short to be a pcapng file.
3915 *err = 0;
3916 g_free(*err_info);
3917 *err_info = NULL;
3918 return WTAP_OPEN_NOT_MINE;
3920 return WTAP_OPEN_ERROR;
3924 * If this is a pcapng file, the first block must be a
3925 * Section Header Block.
3927 if (bh.block_type != BLOCK_TYPE_SHB) {
3929 * Not an SHB, so this isn't a pcapng file.
3931 * XXX - check for damage from transferring a file
3932 * between Windows and UN*X as text rather than
3933 * binary data?
3935 ws_debug("first block type 0x%08x not SHB", bh.block_type);
3936 return WTAP_OPEN_NOT_MINE;
3939 ws_debug("got an SHB");
3942 * Now try to read the block body, filling in the section_info_t
3943 * for the first section.
3945 wblock.type = bh.block_type;
3946 wblock.block = NULL;
3947 /* we don't expect any packet blocks yet */
3948 wblock.frame_buffer = NULL;
3949 wblock.rec = NULL;
3951 switch (pcapng_read_section_header_block(wth->fh, &bh, &first_section,
3952 &wblock, err, err_info)) {
3953 case PCAPNG_BLOCK_OK:
3954 /* No problem */
3955 break;
3957 case PCAPNG_BLOCK_NOT_SHB:
3958 /* This doesn't look like an SHB, so this isn't a pcapng file. */
3959 wtap_block_unref(wblock.block);
3960 *err = 0;
3961 g_free(*err_info);
3962 *err_info = NULL;
3963 return WTAP_OPEN_NOT_MINE;
3965 case PCAPNG_BLOCK_ERROR:
3966 wtap_block_unref(wblock.block);
3967 if (*err == WTAP_ERR_SHORT_READ) {
3969 * Short read.
3971 * We're reading this as part of an open, so
3972 * the file is too short to be a pcapng file.
3974 *err = 0;
3975 g_free(*err_info);
3976 *err_info = NULL;
3977 return WTAP_OPEN_NOT_MINE;
3979 /* An I/O error. */
3980 return WTAP_OPEN_ERROR;
3984 * Read and check the block trailer.
3986 if (!pcapng_read_and_check_block_trailer(wth->fh, &bh, &first_section, err, err_info)) {
3987 /* Not readable or not valid. */
3988 wtap_block_unref(wblock.block);
3989 return WTAP_OPEN_ERROR;
3993 * At this point, we've decided this is a pcapng file, not
3994 * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
3995 * past this point.
3997 * Copy the SHB that we just read to the first entry in the table of
3998 * SHBs for this file.
4000 wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0), wblock.block);
4001 wtap_block_unref(wblock.block);
4002 wblock.block = NULL;
4004 wth->file_encap = WTAP_ENCAP_NONE;
4005 wth->snapshot_length = 0;
4006 wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
4007 pcapng = g_new(pcapng_t, 1);
4008 wth->priv = (void *)pcapng;
4010 * We're currently processing the first section; as this is written
4011 * in C, that's section 0. :-)
4013 pcapng->current_section_number = 0;
4016 * Create the array of interfaces for the first section.
4018 first_section.interfaces = g_array_new(false, false, sizeof(interface_info_t));
4021 * The first section is at the very beginning of the file.
4023 first_section.shb_off = 0;
4026 * Allocate the sections table with space reserved for the first
4027 * section, and add that section.
4029 pcapng->sections = g_array_sized_new(false, false, sizeof(section_info_t), 1);
4030 g_array_append_val(pcapng->sections, first_section);
4032 wth->subtype_read = pcapng_read;
4033 wth->subtype_seek_read = pcapng_seek_read;
4034 wth->subtype_close = pcapng_close;
4035 wth->file_type_subtype = pcapng_file_type_subtype;
4037 /* Always initialize the lists of Decryption Secret Blocks, Name
4038 * Resolution Blocks, and Sysdig meta event blocks such that a
4039 * wtap_dumper can refer to them right after opening the capture
4040 * file. */
4041 wth->dsbs = g_array_new(false, false, sizeof(wtap_block_t));
4042 wth->nrbs = g_array_new(false, false, sizeof(wtap_block_t));
4043 wth->meta_events = g_array_new(false, false, sizeof(wtap_block_t));
4045 /* Most other capture types (such as pcap) support a single link-layer
4046 * type, indicated in the header, and don't support WTAP_ENCAP_PER_PACKET.
4047 * Most programs that write such capture files want to know the link-layer
4048 * type when initially opening the destination file, and (unlike Wireshark)
4049 * don't want to read the entire source file to find all the link-layer
4050 * types before writing (particularly if reading from a pipe or FIFO.)
4052 * In support of this, read all the internally-processed, non packet
4053 * blocks that appear before the first packet block (EPB or SPB).
4055 * Note that such programs will still have issues when trying to read
4056 * a pcapng that has a new link-layer type in an IDB in the middle of
4057 * the file, as they will discover in the middle that no, they can't
4058 * successfully write the output file as desired.
4060 while (1) {
4061 /* peek at next block */
4062 /* Try to read the (next) block header */
4063 saved_offset = file_tell(wth->fh);
4064 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
4065 if (*err == 0) {
4066 /* EOF */
4067 ws_debug("No more blocks available...");
4068 break;
4070 ws_debug("Check for more initial blocks, wtap_read_bytes_or_eof() failed, err = %d.",
4071 *err);
4072 return WTAP_OPEN_ERROR;
4075 /* go back to where we were */
4076 file_seek(wth->fh, saved_offset, SEEK_SET, err);
4079 * Get a pointer to the current section's section_info_t.
4081 current_section = &g_array_index(pcapng->sections, section_info_t,
4082 pcapng->current_section_number);
4084 if (current_section->byte_swapped) {
4085 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
4088 ws_debug("Check for more initial internal blocks, block_type 0x%08x",
4089 bh.block_type);
4091 if (!get_block_type_internal(bh.block_type)) {
4092 break; /* Next block has to be returned in pcap_read */
4094 /* Note that some custom block types, unlike packet blocks,
4095 * don't need to be preceded by an IDB and so theoretically
4096 * we could skip past them here. However, then there's no good
4097 * way to both later return those blocks in pcap_read() and
4098 * ensure that we don't read and process the IDBs (and other
4099 * internal block types) a second time.
4101 * pcapng_read_systemd_journal_export_block() sets the file level
4102 * link-layer type if it's still UNKNOWN. We could do the same here
4103 * for it and possibly other types based on block type, even without
4104 * reading them.
4106 if (!pcapng_read_block(wth, wth->fh, pcapng, current_section,
4107 &new_section, &wblock, err, err_info)) {
4108 wtap_block_unref(wblock.block);
4109 if (*err == 0) {
4110 ws_debug("No more initial blocks available...");
4111 break;
4112 } else {
4113 ws_debug("couldn't read block");
4114 return WTAP_OPEN_ERROR;
4117 pcapng_process_internal_block(wth, pcapng, current_section, new_section, &wblock, &saved_offset);
4118 ws_debug("Read IDB number_of_interfaces %u, wtap_encap %i",
4119 wth->interface_data->len, wth->file_encap);
4121 return WTAP_OPEN_MINE;
4124 /* classic wtap: read packet */
4125 static bool
4126 pcapng_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err,
4127 char **err_info, int64_t *data_offset)
4129 pcapng_t *pcapng = (pcapng_t *)wth->priv;
4130 section_info_t *current_section, new_section;
4131 wtapng_block_t wblock;
4133 wblock.frame_buffer = buf;
4134 wblock.rec = rec;
4136 /* read next block */
4137 while (1) {
4138 *data_offset = file_tell(wth->fh);
4139 ws_noisy("data_offset is %" PRId64, *data_offset);
4142 * Get the section_info_t for the current section.
4144 current_section = &g_array_index(pcapng->sections, section_info_t,
4145 pcapng->current_section_number);
4148 * Read the next block.
4150 if (!pcapng_read_block(wth, wth->fh, pcapng, current_section,
4151 &new_section, &wblock, err, err_info)) {
4152 ws_noisy("data_offset is finally %" PRId64, *data_offset);
4153 ws_debug("couldn't read packet block");
4154 wtap_block_unref(wblock.block);
4155 return false;
4158 if (!wblock.internal) {
4160 * This is a block type we return to the caller to process.
4162 ws_noisy("rec_type %u", wblock.rec->rec_type);
4163 break;
4167 * This is a block type we process internally, rather than
4168 * returning it for the caller to process.
4170 pcapng_process_internal_block(wth, pcapng, current_section, new_section, &wblock, data_offset);
4173 /*ws_debug("Read length: %u Packet length: %u", bytes_read, rec->rec_header.packet_header.caplen);*/
4174 ws_noisy("data_offset is finally %" PRId64, *data_offset);
4176 /* Provide the section number */
4177 rec->presence_flags |= WTAP_HAS_SECTION_NUMBER;
4178 rec->section_number = pcapng->current_section_number;
4180 return true;
4183 /* classic wtap: seek to file position and read packet */
4184 static bool
4185 pcapng_seek_read(wtap *wth, int64_t seek_off,
4186 wtap_rec *rec, Buffer *buf,
4187 int *err, char **err_info)
4189 pcapng_t *pcapng = (pcapng_t *)wth->priv;
4190 section_info_t *section_info, new_section;
4191 wtapng_block_t wblock;
4194 /* seek to the right file position */
4195 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
4196 return false; /* Seek error */
4198 ws_noisy("reading at offset %" PRIu64, seek_off);
4201 * Find the section_info_t for the section in which this block
4202 * appears.
4204 * First, make sure we have at least one section; if we don't, that's
4205 * an internal error.
4207 ws_assert(pcapng->sections->len >= 1);
4210 * Now scan backwards through the array to find the first section
4211 * that begins at or before the offset of the block we're reading.
4213 * Yes, that's O(n) in the number of blocks, but we're unlikely to
4214 * have many blocks and pretty unlikely to have more than one.
4216 unsigned section_number = pcapng->sections->len - 1;
4217 for (;;) {
4218 section_info = &g_array_index(pcapng->sections, section_info_t,
4219 section_number);
4220 if (section_info->shb_off <= seek_off)
4221 break;
4224 * If that's section 0, something's wrong; that section should
4225 * have an offset of 0.
4227 ws_assert(section_number != 0);
4228 section_number--;
4231 wblock.frame_buffer = buf;
4232 wblock.rec = rec;
4234 /* read the block */
4235 if (!pcapng_read_block(wth, wth->random_fh, pcapng, section_info,
4236 &new_section, &wblock, err, err_info)) {
4237 ws_debug("couldn't read packet block (err=%d).", *err);
4238 wtap_block_unref(wblock.block);
4239 return false;
4242 /* block must not be one we process internally rather than supplying */
4243 if (wblock.internal) {
4244 ws_debug("block type 0x%08x is not one we return",
4245 wblock.type);
4246 wtap_block_unref(wblock.block);
4247 return false;
4250 wtap_block_unref(wblock.block);
4252 /* Provide the section number */
4253 rec->presence_flags |= WTAP_HAS_SECTION_NUMBER;
4254 rec->section_number = section_number;
4256 return true;
4259 /* classic wtap: close capture file */
4260 static void
4261 pcapng_close(wtap *wth)
4263 pcapng_t *pcapng = (pcapng_t *)wth->priv;
4265 ws_debug("closing file");
4268 * Free up the interfaces tables for all the sections.
4270 for (unsigned i = 0; i < pcapng->sections->len; i++) {
4271 section_info_t *section_info = &g_array_index(pcapng->sections,
4272 section_info_t, i);
4273 g_array_free(section_info->interfaces, true);
4275 g_array_free(pcapng->sections, true);
4278 typedef uint32_t (*compute_option_size_func)(wtap_block_t, unsigned, wtap_opttype_e, wtap_optval_t*);
4280 typedef struct compute_options_size_t
4282 uint32_t size;
4283 compute_option_size_func compute_option_size;
4284 } compute_options_size_t;
4287 * As it says at the top of the file, an option sizer "calculates how many
4288 * bytes the option's data requires, not including any padding bytes."
4289 * Callers are responsible for rounding up to multiples of 4 bytes.
4290 * compute_block_options_size() does that for each option in the block;
4291 * option writers that call an option sizer (which helps ensure that the
4292 * sizes are internally consistent) should do the same.
4295 static uint32_t pcapng_compute_string_option_size(wtap_optval_t *optval)
4297 uint32_t size = 0;
4299 size = (uint32_t)strlen(optval->stringval) & 0xffff;
4301 return size;
4304 #if 0
4305 static uint32_t pcapng_compute_bytes_option_size(wtap_optval_t *optval)
4307 uint32_t size = 0;
4309 size = (uint32_t)g_bytes_get_size(optval->byteval) & 0xffff;
4311 return size;
4313 #endif
4315 static uint32_t pcapng_compute_if_filter_option_size(wtap_optval_t *optval)
4317 if_filter_opt_t* filter = &optval->if_filterval;
4318 uint32_t size;
4320 if (filter->type == if_filter_pcap) {
4321 size = (uint32_t)(strlen(filter->data.filter_str) + 1) & 0xffff;
4322 } else if (filter->type == if_filter_bpf) {
4323 size = (uint32_t)((filter->data.bpf_prog.bpf_prog_len * 8) + 1) & 0xffff;
4324 } else {
4325 /* Unknown type; don't write it */
4326 size = 0;
4328 return size;
4331 static uint32_t pcapng_compute_custom_option_size(wtap_optval_t *optval)
4333 size_t size;
4335 /* PEN */
4336 size = sizeof(uint32_t);
4337 switch (optval->custom_opt.pen) {
4338 case PEN_NFLX:
4339 /* NFLX type */
4340 size += sizeof(uint32_t);
4341 size += optval->custom_opt.data.nflx_data.custom_data_len;
4342 break;
4343 default:
4344 size += optval->custom_opt.data.generic_data.custom_data_len;
4345 break;
4347 if (size > 65535) {
4348 size = 65535;
4351 return (uint32_t)size;
4354 static uint32_t pcapng_compute_packet_hash_option_size(wtap_optval_t *optval)
4356 packet_hash_opt_t* hash = &optval->packet_hash;
4357 uint32_t size;
4359 switch (hash->type) {
4360 case OPT_HASH_CRC32:
4361 size = 4;
4362 break;
4363 case OPT_HASH_MD5:
4364 size = 16;
4365 break;
4366 case OPT_HASH_SHA1:
4367 size = 20;
4368 break;
4369 case OPT_HASH_TOEPLITZ:
4370 size = 4;
4371 break;
4372 default:
4373 /* 2COMP and XOR size not defined in standard (yet) */
4374 size = hash->hash_bytes->len;
4375 break;
4377 /* XXX - What if the size of the hash bytes doesn't match the
4378 * expected size? We can:
4379 * 1) Return 0, and omit it when writing
4380 * 2) Return hash_bytes->len, and write it out exactly as we have it
4381 * 3) Return the correct size here, and when writing err or possibly
4382 * truncate.
4384 /* Account for the size of the algorithm type field. */
4385 size += 1;
4387 return size;
4390 static uint32_t pcapng_compute_packet_verdict_option_size(wtap_optval_t *optval)
4392 packet_verdict_opt_t* verdict = &optval->packet_verdictval;
4393 uint32_t size;
4395 switch (verdict->type) {
4397 case packet_verdict_hardware:
4398 size = verdict->data.verdict_bytes->len;
4399 break;
4401 case packet_verdict_linux_ebpf_tc:
4402 size = 8;
4403 break;
4405 case packet_verdict_linux_ebpf_xdp:
4406 size = 8;
4407 break;
4409 default:
4410 size = 0;
4411 break;
4413 /* Account for the type octet */
4414 if (size) {
4415 size += 1;
4418 return size;
4421 static bool
4422 compute_block_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type, wtap_optval_t *optval, void *user_data)
4424 compute_options_size_t* options_size = (compute_options_size_t*)user_data;
4425 uint32_t size = 0;
4428 * Process the option IDs that are the same for all block types here;
4429 * call the block-type-specific compute_size function for others.
4431 switch(option_id)
4433 case OPT_COMMENT:
4434 size = pcapng_compute_string_option_size(optval);
4435 break;
4436 case OPT_CUSTOM_STR_COPY:
4437 case OPT_CUSTOM_BIN_COPY:
4438 size = pcapng_compute_custom_option_size(optval);
4439 break;
4440 case OPT_CUSTOM_STR_NO_COPY:
4441 case OPT_CUSTOM_BIN_NO_COPY:
4443 * Do not count these, as they're not supposed to be copied to
4444 * new files.
4446 * XXX - what if we're writing out a file that's *not* based on
4447 * another file, so that we're *not* copying it from that file?
4449 break;
4450 default:
4451 /* Block-type dependent; call the callback. */
4452 size = (*options_size->compute_option_size)(block, option_id, option_type, optval);
4453 break;
4457 * Are we writing this option?
4460 * XXX: The option length field is 16 bits. If size > 65535 (how?
4461 * was the block was obtained from some format other than pcapng?),
4462 * are we going to silently omit the option (in which case we shouldn't
4463 * add the size here), or err out when writing it (in which case
4464 * it's probably fine to add the size or not?) Adding it here and
4465 * then omitting it when writing, as some of the routines do, means
4466 * creating a corrupt file.
4468 if (size != 0) {
4470 * Yes. Add the size of the option header to the size of the
4471 * option data.
4473 options_size->size += 4;
4475 /* Now add the size of the option value. */
4476 options_size->size += size;
4478 /* Add optional padding to 32 bits */
4479 if ((size & 0x03) != 0)
4481 options_size->size += 4 - (size & 0x03);
4484 return true; /* we always succeed */
4487 static uint32_t
4488 compute_options_size(wtap_block_t block, compute_option_size_func compute_option_size)
4490 compute_options_size_t compute_options_size;
4493 * Compute the total size of all the options in the block.
4494 * This always succeeds, so we don't check the return value.
4496 compute_options_size.size = 0;
4497 compute_options_size.compute_option_size = compute_option_size;
4498 wtap_block_foreach_option(block, compute_block_option_size, &compute_options_size);
4500 /* Are we writing any options? */
4501 if (compute_options_size.size != 0) {
4502 /* Yes, add the size of the End-of-options tag. */
4503 compute_options_size.size += 4;
4505 return compute_options_size.size;
4508 static uint32_t compute_shb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
4510 uint32_t size;
4512 switch(option_id)
4514 case OPT_SHB_HARDWARE:
4515 case OPT_SHB_OS:
4516 case OPT_SHB_USERAPPL:
4517 size = pcapng_compute_string_option_size(optval);
4518 break;
4519 default:
4520 /* Unknown options - size by datatype? */
4521 size = 0;
4522 break;
4524 return size;
4527 typedef bool (*write_option_func)(wtap_dumper *, wtap_block_t, unsigned, wtap_opttype_e, wtap_optval_t*, int*);
4529 typedef struct write_options_t
4531 wtap_dumper *wdh;
4532 int *err;
4533 write_option_func write_option;
4535 write_options_t;
4537 static bool pcapng_write_option_eofopt(wtap_dumper *wdh, int *err)
4539 struct pcapng_option_header option_hdr;
4541 /* Write end of options */
4542 option_hdr.type = OPT_EOFOPT;
4543 option_hdr.value_length = 0;
4544 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4545 return false;
4546 return true;
4549 static bool pcapng_write_uint8_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4551 struct pcapng_option_header option_hdr;
4552 const uint32_t zero_pad = 0;
4554 option_hdr.type = (uint16_t)option_id;
4555 option_hdr.value_length = (uint16_t)1;
4556 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4557 return false;
4559 if (!wtap_dump_file_write(wdh, &optval->uint8val, 1, err))
4560 return false;
4562 if (!wtap_dump_file_write(wdh, &zero_pad, 3, err))
4563 return false;
4565 return true;
4568 static bool pcapng_write_uint32_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4570 struct pcapng_option_header option_hdr;
4572 option_hdr.type = (uint16_t)option_id;
4573 option_hdr.value_length = (uint16_t)4;
4574 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4575 return false;
4577 if (!wtap_dump_file_write(wdh, &optval->uint32val, 4, err))
4578 return false;
4580 return true;
4583 static bool pcapng_write_uint64_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4585 struct pcapng_option_header option_hdr;
4587 option_hdr.type = (uint16_t)option_id;
4588 option_hdr.value_length = (uint16_t)8;
4589 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4590 return false;
4592 if (!wtap_dump_file_write(wdh, &optval->uint64val, 8, err))
4593 return false;
4595 return true;
4598 static bool pcapng_write_timestamp_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4600 struct pcapng_option_header option_hdr;
4601 uint32_t high, low;
4603 option_hdr.type = (uint16_t)option_id;
4604 option_hdr.value_length = (uint16_t)8;
4605 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4606 return false;
4608 high = (uint32_t)(optval->uint64val >> 32);
4609 low = (uint32_t)(optval->uint64val >> 0);
4610 if (!wtap_dump_file_write(wdh, &high, 4, err))
4611 return false;
4612 if (!wtap_dump_file_write(wdh, &low, 4, err))
4613 return false;
4615 return true;
4618 static bool pcapng_write_string_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4620 struct pcapng_option_header option_hdr;
4621 size_t size = strlen(optval->stringval);
4622 const uint32_t zero_pad = 0;
4623 uint32_t pad;
4625 if (size == 0)
4626 return true;
4627 if (size > 65535) {
4629 * Too big to fit in the option.
4630 * Don't write anything.
4632 * XXX - truncate it? Report an error?
4634 return true;
4637 /* String options don't consider pad bytes part of the length */
4638 option_hdr.type = (uint16_t)option_id;
4639 option_hdr.value_length = (uint16_t)size;
4640 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4641 return false;
4643 if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4644 return false;
4646 if ((size % 4)) {
4647 pad = 4 - (size % 4);
4648 } else {
4649 pad = 0;
4652 /* write padding (if any) */
4653 if (pad != 0) {
4654 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
4655 return false;
4658 return true;
4661 #if 0
4662 static bool pcapng_write_bytes_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4664 struct pcapng_option_header option_hdr;
4665 size_t size = g_bytes_get_size(optval->byteval);
4666 const uint32_t zero_pad = 0;
4667 uint32_t pad;
4669 if (size == 0)
4670 return true;
4671 if (size > 65535) {
4673 * Too big to fit in the option.
4674 * Don't write anything.
4676 * XXX - truncate it? Report an error?
4678 return true;
4681 /* Bytes options don't consider pad bytes part of the length */
4682 option_hdr.type = (uint16_t)option_id;
4683 option_hdr.value_length = (uint16_t)size;
4684 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4685 return false;
4687 if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4688 return false;
4690 if ((size % 4)) {
4691 pad = 4 - (size % 4);
4692 } else {
4693 pad = 0;
4696 /* write padding (if any) */
4697 if (pad != 0) {
4698 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
4699 return false;
4702 return true;
4705 static bool pcapng_write_ipv4_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4707 struct pcapng_option_header option_hdr;
4709 option_hdr.type = (uint16_t)option_id;
4710 option_hdr.value_length = (uint16_t)4;
4711 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4712 return false;
4714 if (!wtap_dump_file_write(wdh, &optval->ipv4val, 1, err))
4715 return false;
4717 return true;
4720 static bool pcapng_write_ipv6_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4722 struct pcapng_option_header option_hdr;
4724 option_hdr.type = (uint16_t)option_id;
4725 option_hdr.value_length = (uint16_t)IPv6_ADDR_SIZE;
4726 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4727 return false;
4729 if (!wtap_dump_file_write(wdh, &optval->ipv6val.bytes, IPv6_ADDR_SIZE, err))
4730 return false;
4732 return true;
4734 #endif
4736 static bool pcapng_write_if_filter_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4738 if_filter_opt_t* filter = &optval->if_filterval;
4739 uint32_t size, pad;
4740 uint8_t filter_type;
4741 size_t filter_data_len;
4742 struct pcapng_option_header option_hdr;
4743 const uint32_t zero_pad = 0;
4745 switch (filter->type) {
4747 case if_filter_pcap:
4748 filter_type = 0; /* pcap filter string */
4749 filter_data_len = strlen(filter->data.filter_str);
4750 if (filter_data_len > 65534) {
4752 * Too big to fit in the option.
4753 * Don't write anything.
4755 * XXX - truncate it? Report an error?
4757 return true;
4759 break;
4761 case if_filter_bpf:
4762 filter_type = 1; /* BPF filter program */
4763 filter_data_len = filter->data.bpf_prog.bpf_prog_len*8;
4764 if (filter_data_len > 65528) {
4766 * Too big to fit in the option. (The filter length
4767 * must be a multiple of 8, as that's the length
4768 * of a BPF instruction.) Don't write anything.
4770 * XXX - truncate it? Report an error?
4772 return true;
4774 break;
4776 default:
4777 /* Unknown filter type; don't write anything. */
4778 return true;
4780 size = (uint32_t)(filter_data_len + 1);
4781 if ((size % 4)) {
4782 pad = 4 - (size % 4);
4783 } else {
4784 pad = 0;
4787 option_hdr.type = option_id;
4788 option_hdr.value_length = size;
4789 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4790 return false;
4792 /* Write the filter type */
4793 if (!wtap_dump_file_write(wdh, &filter_type, 1, err))
4794 return false;
4796 switch (filter->type) {
4798 case if_filter_pcap:
4799 /* Write the filter string */
4800 if (!wtap_dump_file_write(wdh, filter->data.filter_str, filter_data_len, err))
4801 return false;
4802 break;
4804 case if_filter_bpf:
4805 if (!wtap_dump_file_write(wdh, filter->data.bpf_prog.bpf_prog, filter_data_len, err))
4806 return false;
4807 break;
4809 default:
4810 ws_assert_not_reached();
4811 return true;
4814 /* write padding (if any) */
4815 if (pad != 0) {
4816 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
4817 return false;
4819 return true;
4822 static bool pcapng_write_custom_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4824 struct pcapng_option_header option_hdr;
4825 size_t pad;
4826 size_t size;
4827 const uint32_t zero_pad = 0;
4828 uint32_t pen, type;
4829 bool use_little_endian;
4831 if ((option_id == OPT_CUSTOM_STR_NO_COPY) ||
4832 (option_id == OPT_CUSTOM_BIN_NO_COPY))
4833 return true;
4834 ws_debug("PEN %d", optval->custom_opt.pen);
4835 switch (optval->custom_opt.pen) {
4836 case PEN_NFLX:
4837 size = sizeof(uint32_t) + sizeof(uint32_t) + optval->custom_opt.data.nflx_data.custom_data_len;
4838 use_little_endian = optval->custom_opt.data.nflx_data.use_little_endian;
4839 break;
4840 default:
4841 size = sizeof(uint32_t) + optval->custom_opt.data.generic_data.custom_data_len;
4842 use_little_endian = false;
4843 break;
4845 ws_debug("use_little_endian %d", use_little_endian);
4846 if (size > 65535) {
4848 * Too big to fit in the option.
4849 * Don't write anything.
4851 * XXX - truncate it? Report an error?
4853 return true;
4856 /* write option header */
4857 option_hdr.type = (uint16_t)option_id;
4858 option_hdr.value_length = (uint16_t)size;
4859 if (use_little_endian) {
4860 option_hdr.type = GUINT16_TO_LE(option_hdr.type);
4861 option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length);
4863 if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
4864 return false;
4866 /* write PEN */
4867 pen = optval->custom_opt.pen;
4868 if (use_little_endian) {
4869 pen = GUINT32_TO_LE(pen);
4871 if (!wtap_dump_file_write(wdh, &pen, sizeof(uint32_t), err))
4872 return false;
4874 switch (optval->custom_opt.pen) {
4875 case PEN_NFLX:
4876 /* write NFLX type */
4877 type = GUINT32_TO_LE(optval->custom_opt.data.nflx_data.type);
4878 ws_debug("type=%d", type);
4879 if (!wtap_dump_file_write(wdh, &type, sizeof(uint32_t), err))
4880 return false;
4881 /* write custom data */
4882 if (!wtap_dump_file_write(wdh, optval->custom_opt.data.nflx_data.custom_data, optval->custom_opt.data.nflx_data.custom_data_len, err)) {
4883 return false;
4885 break;
4886 default:
4887 /* write custom data */
4888 if (!wtap_dump_file_write(wdh, optval->custom_opt.data.generic_data.custom_data, optval->custom_opt.data.generic_data.custom_data_len, err)) {
4889 return false;
4891 break;
4894 /* write padding (if any) */
4895 if (size % 4 != 0) {
4896 pad = 4 - (size % 4);
4897 } else {
4898 pad = 0;
4900 if (pad != 0) {
4901 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err)) {
4902 return false;
4905 ws_debug("Wrote custom option: type %u, length %u", option_hdr.type, option_hdr.value_length);
4907 return true;
4910 static bool pcapng_write_packet_verdict_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4912 packet_verdict_opt_t* verdict = &optval->packet_verdictval;
4913 struct pcapng_option_header option_hdr;
4914 uint8_t type;
4915 size_t size;
4916 const uint32_t zero_pad = 0;
4917 uint32_t pad;
4919 size = pcapng_compute_packet_verdict_option_size(optval);
4921 switch (verdict->type) {
4923 case packet_verdict_hardware:
4924 if (size > 65535) {
4926 * Too big to fit in the option.
4927 * Don't write anything.
4929 * XXX - truncate it? Report an error?
4931 return true;
4933 option_hdr.type = option_id;
4934 option_hdr.value_length = (uint16_t)size;
4935 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4936 return false;
4938 type = packet_verdict_hardware;
4939 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4940 return false;
4942 if (!wtap_dump_file_write(wdh, verdict->data.verdict_bytes->data,
4943 verdict->data.verdict_bytes->len, err))
4944 return false;
4945 break;
4947 case packet_verdict_linux_ebpf_tc:
4948 option_hdr.type = option_id;
4949 option_hdr.value_length = (uint16_t)size;
4950 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4951 return false;
4953 type = packet_verdict_linux_ebpf_tc;
4954 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4955 return false;
4957 if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_tc,
4958 sizeof(uint64_t), err))
4959 return false;
4960 break;
4962 case packet_verdict_linux_ebpf_xdp:
4963 option_hdr.type = option_id;
4964 option_hdr.value_length = (uint16_t)size;
4965 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4966 return false;
4968 type = packet_verdict_linux_ebpf_xdp;
4969 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4970 return false;
4972 if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_xdp,
4973 sizeof(uint64_t), err))
4974 return false;
4975 break;
4977 default:
4978 /* Unknown - don't write it out. */
4979 return true;
4982 /* write padding (if any) */
4983 if ((size % 4)) {
4984 pad = 4 - (size % 4);
4985 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
4986 return false;
4988 return true;
4991 static bool pcapng_write_packet_hash_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4993 packet_hash_opt_t* hash = &optval->packet_hash;
4994 struct pcapng_option_header option_hdr;
4995 uint8_t type;
4996 size_t size;
4997 const uint32_t zero_pad = 0;
4998 uint32_t pad;
5000 size = pcapng_compute_packet_hash_option_size(optval);
5002 if (size > 65535) {
5004 * Too big to fit in the option.
5005 * Don't write anything.
5007 * XXX - truncate it? Report an error?
5009 return true;
5012 if (size > hash->hash_bytes->len + 1) {
5014 * We don't have enough bytes to write.
5015 * pcapng_compute_packet_hash_option_size() should return 0 if
5016 * we want to silently omit the option instead, or should return
5017 * the length if we want to blindly copy it.
5018 * XXX - Is this the best error type?
5020 *err = WTAP_ERR_UNWRITABLE_REC_DATA;
5021 return false;
5024 type = hash->type;
5026 option_hdr.type = option_id;
5027 /* Include type byte */
5028 option_hdr.value_length = (uint16_t)size;
5029 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
5030 return false;
5032 if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
5033 return false;
5035 if (!wtap_dump_file_write(wdh, hash->hash_bytes->data, size - 1,
5036 err))
5037 return false;
5039 /* write padding (if any) */
5040 if ((size % 4)) {
5041 pad = 4 - (size % 4);
5042 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
5043 return false;
5045 return true;
5048 static bool write_block_option(wtap_block_t block, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
5050 write_options_t* options = (write_options_t*)user_data;
5053 * Process the option IDs that are the same for all block types here;
5054 * call the block-type-specific compute_size function for others.
5056 switch(option_id)
5058 case OPT_COMMENT:
5059 if (!pcapng_write_string_option(options->wdh, option_id, optval, options->err))
5060 return false;
5061 break;
5062 case OPT_CUSTOM_STR_COPY:
5063 case OPT_CUSTOM_BIN_COPY:
5064 if (!pcapng_write_custom_option(options->wdh, option_id, optval, options->err))
5065 return false;
5066 break;
5067 case OPT_CUSTOM_STR_NO_COPY:
5068 case OPT_CUSTOM_BIN_NO_COPY:
5070 * Do not write these, as they're not supposed to be copied to
5071 * new files.
5073 * XXX - what if we're writing out a file that's *not* based on
5074 * another file, so that we're *not* copying it from that file?
5076 break;
5077 default:
5078 /* Block-type dependent; call the callback, if we have one. */
5079 if (options->write_option != NULL &&
5080 !(*options->write_option)(options->wdh, block, option_id, option_type, optval, options->err))
5081 return false;
5082 break;
5084 return true;
5087 static bool
5088 write_options(wtap_dumper *wdh, wtap_block_t block, write_option_func write_option, int *err)
5090 write_options_t options;
5092 options.wdh = wdh;
5093 options.err = err;
5094 options.write_option = write_option;
5095 if (!wtap_block_foreach_option(block, write_block_option, &options))
5096 return false;
5098 /* Write end of options */
5099 return pcapng_write_option_eofopt(wdh, err);
5102 static bool write_wtap_shb_option(wtap_dumper *wdh, wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, int *err)
5104 switch(option_id)
5106 case OPT_SHB_HARDWARE:
5107 case OPT_SHB_OS:
5108 case OPT_SHB_USERAPPL:
5109 if (!pcapng_write_string_option(wdh, option_id, optval, err))
5110 return false;
5111 break;
5112 default:
5113 /* Unknown options - write by datatype? */
5114 break;
5116 return true; /* success */
5119 /* Write a section header block.
5120 * If we don't have a section block header already, create a default
5121 * one with no options.
5123 static bool
5124 pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
5126 pcapng_block_header_t bh;
5127 pcapng_section_header_block_t shb;
5128 uint32_t options_size;
5129 wtap_block_t wdh_shb = NULL;
5131 if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
5132 wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0);
5135 bh.block_total_length = (uint32_t)(sizeof(bh) + sizeof(shb) + 4);
5136 options_size = 0;
5137 if (wdh_shb) {
5138 ws_debug("Have shb_hdr");
5140 /* Compute size of all the options */
5141 options_size = compute_options_size(wdh_shb, compute_shb_option_size);
5143 bh.block_total_length += options_size;
5146 ws_debug("Total len %u", bh.block_total_length);
5148 /* write block header */
5149 bh.block_type = BLOCK_TYPE_SHB;
5151 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5152 return false;
5154 /* write block fixed content */
5155 shb.magic = 0x1A2B3C4D;
5156 shb.version_major = 1;
5157 shb.version_minor = 0;
5158 if (wdh_shb) {
5159 wtapng_section_mandatory_t* section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wdh_shb);
5160 shb.section_length = section_data->section_length;
5161 } else {
5162 shb.section_length = -1;
5165 if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
5166 return false;
5168 if (wdh_shb) {
5169 /* Write options, if we have any */
5170 if (options_size != 0) {
5171 if (!write_options(wdh, wdh_shb, write_wtap_shb_option, err))
5172 return false;
5176 /* write block footer */
5177 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5178 sizeof bh.block_total_length, err))
5179 return false;
5181 return true;
5184 /* options defined in Section 2.5 (Options)
5185 * Name Code Length Description
5186 * opt_comment 1 variable A UTF-8 string containing a comment that is associated to the current block.
5188 * Enhanced Packet Block options
5189 * epb_flags 2 4 A flags word containing link-layer information. A complete specification of
5190 * the allowed flags can be found in Appendix A (Packet Block Flags Word).
5191 * epb_hash 3 variable This option contains a hash of the packet. The first byte specifies the hashing algorithm,
5192 * while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
5193 * and hence from the value in the first bit. The hashing algorithm can be: 2s complement
5194 * (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
5195 * MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
5196 * The hash covers only the packet, not the header added by the capture driver:
5197 * this gives the possibility to calculate it inside the network card.
5198 * The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
5199 * data acquisition system and the capture library.
5200 * epb_dropcount 4 8 A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
5201 * between this packet and the preceding one.
5202 * epb_packetid 5 8 The epb_packetid option is a 64-bit unsigned integer that
5203 * uniquely identifies the packet. If the same packet is seen
5204 * by multiple interfaces and there is a way for the capture
5205 * application to correlate them, the same epb_packetid value
5206 * must be used. An example could be a router that captures
5207 * packets on all its interfaces in both directions. When a
5208 * packet hits interface A on ingress, an EPB entry gets
5209 * created, TTL gets decremented, and right before it egresses
5210 * on interface B another EPB entry gets created in the trace
5211 * file. In this case, two packets are in the capture file,
5212 * which are not identical but the epb_packetid can be used to
5213 * correlate them.
5214 * epb_queue 6 4 The epb_queue option is a 32-bit unsigned integer that
5215 * identifies on which queue of the interface the specific
5216 * packet was received.
5217 * epb_verdict 7 variable The epb_verdict option stores a verdict of the packet. The
5218 * verdict indicates what would be done with the packet after
5219 * processing it. For example, a firewall could drop the
5220 * packet. This verdict can be set by various components, i.e.
5221 * Hardware, Linux's eBPF TC or XDP framework, etc. etc. The
5222 * first octet specifies the verdict type, while the following
5223 * octets contain the actual verdict data, whose size depends on
5224 * the verdict type, and hence from the value in the first
5225 * octet. The verdict type can be: Hardware (type octet = 0,
5226 * size = variable), Linux_eBPF_TC (type octet = 1, size = 8
5227 * (64-bit unsigned integer), value = TC_ACT_* as defined in the
5228 * Linux pck_cls.h include), Linux_eBPF_XDP (type octet = 2,
5229 * size = 8 (64-bit unsigned integer), value = xdp_action as
5230 * defined in the Linux pbf.h include).
5231 * opt_endofopt 0 0 It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
5233 static uint32_t
5234 compute_epb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
5236 uint32_t size;
5238 switch(option_id)
5240 case OPT_EPB_FLAGS:
5241 size = 4;
5242 break;
5243 case OPT_EPB_DROPCOUNT:
5244 size = 8;
5245 break;
5246 case OPT_EPB_PACKETID:
5247 size = 8;
5248 break;
5249 case OPT_EPB_QUEUE:
5250 size = 4;
5251 break;
5252 case OPT_EPB_VERDICT:
5253 size = pcapng_compute_packet_verdict_option_size(optval);
5254 break;
5255 case OPT_EPB_HASH:
5256 size = pcapng_compute_packet_hash_option_size(optval);
5257 break;
5258 default:
5259 /* Unknown options - size by datatype? */
5260 size = 0;
5261 break;
5263 return size;
5266 static bool write_wtap_epb_option(wtap_dumper *wdh, wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, int *err)
5268 switch(option_id)
5270 case OPT_PKT_FLAGS:
5271 if (!pcapng_write_uint32_option(wdh, OPT_EPB_FLAGS, optval, err))
5272 return false;
5273 break;
5274 case OPT_PKT_DROPCOUNT:
5275 if (!pcapng_write_uint64_option(wdh, OPT_EPB_DROPCOUNT, optval, err))
5276 return false;
5277 break;
5278 case OPT_PKT_PACKETID:
5279 if (!pcapng_write_uint64_option(wdh, OPT_EPB_PACKETID, optval, err))
5280 return false;
5281 break;
5282 case OPT_PKT_QUEUE:
5283 if (!pcapng_write_uint32_option(wdh, OPT_EPB_QUEUE, optval, err))
5284 return false;
5285 break;
5286 case OPT_PKT_VERDICT:
5287 if (!pcapng_write_packet_verdict_option(wdh, OPT_EPB_VERDICT, optval,
5288 err))
5289 return false;
5290 break;
5291 case OPT_PKT_HASH:
5292 if (!pcapng_write_packet_hash_option(wdh, OPT_EPB_HASH, optval,
5293 err))
5294 return false;
5295 break;
5296 default:
5297 /* Unknown options - write by datatype? */
5298 break;
5300 return true; /* success */
5303 static bool
5304 pcapng_write_simple_packet_block(wtap_dumper* wdh, const wtap_rec* rec,
5305 const uint8_t* pd, int* err, char** err_info _U_)
5307 const union wtap_pseudo_header* pseudo_header = &rec->rec_header.packet_header.pseudo_header;
5308 pcapng_block_header_t bh;
5309 pcapng_simple_packet_block_t spb;
5310 const uint32_t zero_pad = 0;
5311 uint32_t pad_len;
5312 uint32_t phdr_len;
5314 /* Don't write anything we're not willing to read. */
5315 if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->file_encap)) {
5316 *err = WTAP_ERR_PACKET_TOO_LARGE;
5317 return false;
5320 phdr_len = (uint32_t)pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
5321 if ((phdr_len + rec->rec_header.packet_header.caplen) % 4) {
5322 pad_len = 4 - ((phdr_len + rec->rec_header.packet_header.caplen) % 4);
5324 else {
5325 pad_len = 0;
5328 /* write (simple) packet block header */
5329 bh.block_type = BLOCK_TYPE_SPB;
5330 bh.block_total_length = (uint32_t)sizeof(bh) + (uint32_t)sizeof(spb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len + 4;
5332 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5333 return false;
5335 /* write block fixed content */
5336 spb.packet_len = rec->rec_header.packet_header.len + phdr_len;
5338 if (!wtap_dump_file_write(wdh, &spb, sizeof spb, err))
5339 return false;
5341 /* write pseudo header */
5342 if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
5343 return false;
5346 /* write packet data */
5347 if (!wtap_dump_file_write(wdh, pd, rec->rec_header.packet_header.caplen, err))
5348 return false;
5350 /* write padding (if any) */
5351 if (pad_len != 0) {
5352 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5353 return false;
5356 /* write block footer */
5357 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5358 sizeof bh.block_total_length, err))
5359 return false;
5361 return true;
5364 static bool
5365 pcapng_write_enhanced_packet_block(wtap_dumper *wdh, const wtap_rec *rec,
5366 const uint8_t *pd, int *err, char **err_info)
5368 const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
5369 pcapng_block_header_t bh;
5370 pcapng_enhanced_packet_block_t epb;
5371 uint32_t options_size = 0;
5372 uint64_t ts;
5373 const uint32_t zero_pad = 0;
5374 uint32_t pad_len;
5375 uint32_t phdr_len;
5376 uint32_t options_total_length = 0;
5377 wtap_block_t int_data;
5378 wtapng_if_descr_mandatory_t *int_data_mand;
5380 /* Don't write anything we're not willing to read. */
5381 if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->file_encap)) {
5382 *err = WTAP_ERR_PACKET_TOO_LARGE;
5383 return false;
5386 phdr_len = (uint32_t)pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
5387 if ((phdr_len + rec->rec_header.packet_header.caplen) % 4) {
5388 pad_len = 4 - ((phdr_len + rec->rec_header.packet_header.caplen) % 4);
5389 } else {
5390 pad_len = 0;
5393 if (rec->block != NULL) {
5394 /* Compute size of all the options */
5395 options_size = compute_options_size(rec->block, compute_epb_option_size);
5399 * Check the interface ID. Do this before writing the header,
5400 * in case we need to add a new IDB.
5402 if (rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
5403 epb.interface_id = rec->rec_header.packet_header.interface_id;
5404 if (rec->presence_flags & WTAP_HAS_SECTION_NUMBER && wdh->shb_iface_to_global) {
5406 * In the extremely unlikely event this overflows we give the
5407 * wrong interface ID.
5409 epb.interface_id += g_array_index(wdh->shb_iface_to_global, unsigned, rec->section_number);
5411 } else {
5413 * The source isn't sending us IDBs. See if we already have a
5414 * matching interface, and use it if so.
5416 for (epb.interface_id = 0; epb.interface_id < wdh->interface_data->len; ++epb.interface_id) {
5417 int_data = g_array_index(wdh->interface_data, wtap_block_t,
5418 epb.interface_id);
5419 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5420 if (int_data_mand->wtap_encap == rec->rec_header.packet_header.pkt_encap) {
5421 if (int_data_mand->tsprecision == rec->tsprec || (!(rec->presence_flags & WTAP_HAS_TS))) {
5422 break;
5426 if (epb.interface_id == wdh->interface_data->len) {
5428 * We don't have a matching IDB. Generate a new one
5429 * and write it to the file.
5431 int_data = wtap_rec_generate_idb(rec);
5432 g_array_append_val(wdh->interface_data, int_data);
5433 if (!pcapng_write_if_descr_block(wdh, int_data, err)) {
5434 return false;
5438 if (epb.interface_id >= wdh->interface_data->len) {
5440 * Our caller is doing something bad.
5442 *err = WTAP_ERR_INTERNAL;
5443 *err_info = ws_strdup_printf("pcapng: epb.interface_id (%u) >= wdh->interface_data->len (%u)",
5444 epb.interface_id, wdh->interface_data->len);
5445 return false;
5447 int_data = g_array_index(wdh->interface_data, wtap_block_t,
5448 epb.interface_id);
5449 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5450 if (int_data_mand->wtap_encap != rec->rec_header.packet_header.pkt_encap) {
5452 * Our caller is doing something bad.
5454 *err = WTAP_ERR_INTERNAL;
5455 *err_info = ws_strdup_printf("pcapng: interface %u encap %d != packet encap %d",
5456 epb.interface_id,
5457 int_data_mand->wtap_encap,
5458 rec->rec_header.packet_header.pkt_encap);
5459 return false;
5462 /* write (enhanced) packet block header */
5463 bh.block_type = BLOCK_TYPE_EPB;
5464 bh.block_total_length = (uint32_t)sizeof(bh) + (uint32_t)sizeof(epb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len + options_total_length + options_size + 4;
5466 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5467 return false;
5469 /* write block fixed content */
5470 /* Calculate the time stamp as a 64-bit integer. */
5471 ts = ((uint64_t)rec->ts.secs) * int_data_mand->time_units_per_second +
5472 (((uint64_t)rec->ts.nsecs) * int_data_mand->time_units_per_second) / 1000000000;
5474 * Split the 64-bit timestamp into two 32-bit pieces, using
5475 * the time stamp resolution for the interface.
5477 epb.timestamp_high = (uint32_t)(ts >> 32);
5478 epb.timestamp_low = (uint32_t)ts;
5479 epb.captured_len = rec->rec_header.packet_header.caplen + phdr_len;
5480 epb.packet_len = rec->rec_header.packet_header.len + phdr_len;
5482 if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
5483 return false;
5485 /* write pseudo header */
5486 if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
5487 return false;
5490 /* write packet data */
5491 if (!wtap_dump_file_write(wdh, pd, rec->rec_header.packet_header.caplen, err))
5492 return false;
5494 /* write padding (if any) */
5495 if (pad_len != 0) {
5496 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5497 return false;
5500 /* Write options, if we have any */
5501 if (options_size != 0) {
5502 if (!write_options(wdh, rec->block, write_wtap_epb_option, err))
5503 return false;
5506 /* write block footer */
5507 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5508 sizeof bh.block_total_length, err))
5509 return false;
5511 return true;
5514 static bool
5515 pcapng_write_sysdig_event_block(wtap_dumper *wdh, const wtap_rec *rec,
5516 const uint8_t *pd, int *err)
5518 pcapng_block_header_t bh;
5519 const uint32_t zero_pad = 0;
5520 uint32_t pad_len;
5521 #if 0
5522 bool have_options = false;
5523 struct pcapng_option option_hdr;
5524 uint32_t comment_len = 0, comment_pad_len = 0;
5525 #endif
5526 uint32_t options_total_length = 0;
5527 uint16_t cpu_id;
5528 uint64_t hdr_ts;
5529 uint64_t ts;
5530 uint64_t thread_id;
5531 uint32_t event_len;
5532 uint16_t event_type;
5534 /* Don't write anything we're not willing to read. */
5535 if (rec->rec_header.syscall_header.event_filelen > WTAP_MAX_PACKET_SIZE_STANDARD) {
5536 *err = WTAP_ERR_PACKET_TOO_LARGE;
5537 return false;
5540 if (rec->rec_header.syscall_header.event_filelen % 4) {
5541 pad_len = 4 - (rec->rec_header.syscall_header.event_filelen % 4);
5542 } else {
5543 pad_len = 0;
5546 #if 0
5547 /* Check if we should write comment option */
5548 if (rec->opt_comment) {
5549 have_options = true;
5550 comment_len = (uint32_t)strlen(rec->opt_comment) & 0xffff;
5551 if ((comment_len % 4)) {
5552 comment_pad_len = 4 - (comment_len % 4);
5553 } else {
5554 comment_pad_len = 0;
5556 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
5558 if (have_options) {
5559 /* End-of options tag */
5560 options_total_length += 4;
5562 #endif
5564 /* write sysdig event block header */
5565 bh.block_type = BLOCK_TYPE_SYSDIG_EVENT;
5566 bh.block_total_length = (uint32_t)sizeof(bh) + SYSDIG_EVENT_HEADER_SIZE + rec->rec_header.syscall_header.event_filelen + pad_len + options_total_length + 4;
5568 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5569 return false;
5571 /* Sysdig is always LE? */
5572 cpu_id = GUINT16_TO_LE(rec->rec_header.syscall_header.cpu_id);
5573 hdr_ts = (((uint64_t)rec->ts.secs) * 1000000000) + rec->ts.nsecs;
5574 ts = GUINT64_TO_LE(hdr_ts);
5575 thread_id = GUINT64_TO_LE(rec->rec_header.syscall_header.thread_id);
5576 event_len = GUINT32_TO_LE(rec->rec_header.syscall_header.event_len);
5577 event_type = GUINT16_TO_LE(rec->rec_header.syscall_header.event_type);
5579 if (!wtap_dump_file_write(wdh, &cpu_id, sizeof cpu_id, err))
5580 return false;
5582 if (!wtap_dump_file_write(wdh, &ts, sizeof ts, err))
5583 return false;
5585 if (!wtap_dump_file_write(wdh, &thread_id, sizeof thread_id, err))
5586 return false;
5588 if (!wtap_dump_file_write(wdh, &event_len, sizeof event_len, err))
5589 return false;
5591 if (!wtap_dump_file_write(wdh, &event_type, sizeof event_type, err))
5592 return false;
5594 /* write event data */
5595 if (!wtap_dump_file_write(wdh, pd, rec->rec_header.syscall_header.event_filelen, err))
5596 return false;
5598 /* write padding (if any) */
5599 if (pad_len != 0) {
5600 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5601 return false;
5604 /* XXX Write comment? */
5606 /* write block footer */
5607 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5608 sizeof bh.block_total_length, err))
5609 return false;
5611 return true;
5615 static bool
5616 pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
5617 const uint8_t *pd, int *err)
5619 pcapng_block_header_t bh;
5620 const uint32_t zero_pad = 0;
5621 uint32_t pad_len;
5623 /* Don't write anything we're not willing to read. */
5624 if (rec->rec_header.systemd_journal_export_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
5625 *err = WTAP_ERR_PACKET_TOO_LARGE;
5626 return false;
5629 if (rec->rec_header.systemd_journal_export_header.record_len % 4) {
5630 pad_len = 4 - (rec->rec_header.systemd_journal_export_header.record_len % 4);
5631 } else {
5632 pad_len = 0;
5635 /* write systemd journal export block header */
5636 bh.block_type = BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT;
5637 bh.block_total_length = (uint32_t)sizeof(bh) + rec->rec_header.systemd_journal_export_header.record_len + pad_len + 4;
5639 ws_debug("writing %u bytes, %u padded",
5640 rec->rec_header.systemd_journal_export_header.record_len,
5641 bh.block_total_length);
5643 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5644 return false;
5646 /* write entry data */
5647 if (!wtap_dump_file_write(wdh, pd, rec->rec_header.systemd_journal_export_header.record_len, err))
5648 return false;
5650 /* write padding (if any) */
5651 if (pad_len != 0) {
5652 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5653 return false;
5656 /* write block footer */
5657 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5658 sizeof bh.block_total_length, err))
5659 return false;
5661 return true;
5665 static bool
5666 pcapng_write_custom_block(wtap_dumper *wdh, const wtap_rec *rec,
5667 const uint8_t *pd, int *err)
5669 pcapng_block_header_t bh;
5670 pcapng_custom_block_t cb;
5671 const uint32_t zero_pad = 0;
5672 uint32_t pad_len;
5674 /* Don't write anything we are not supposed to. */
5675 if (!rec->rec_header.custom_block_header.copy_allowed) {
5676 return true;
5679 /* Don't write anything we're not willing to read. */
5680 if (rec->rec_header.custom_block_header.length > WTAP_MAX_PACKET_SIZE_STANDARD) {
5681 *err = WTAP_ERR_PACKET_TOO_LARGE;
5682 return false;
5685 if (rec->rec_header.custom_block_header.length % 4) {
5686 pad_len = 4 - (rec->rec_header.custom_block_header.length % 4);
5687 } else {
5688 pad_len = 0;
5691 /* write block header */
5692 bh.block_type = BLOCK_TYPE_CB_COPY;
5693 bh.block_total_length = (uint32_t)sizeof(bh) + (uint32_t)sizeof(cb) + rec->rec_header.custom_block_header.length + pad_len + 4;
5694 ws_debug("writing %u bytes, %u padded, PEN %u",
5695 rec->rec_header.custom_block_header.length,
5696 bh.block_total_length, rec->rec_header.custom_block_header.pen);
5697 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err)) {
5698 return false;
5701 /* write custom block header */
5702 cb.pen = rec->rec_header.custom_block_header.pen;
5703 if (!wtap_dump_file_write(wdh, &cb, sizeof cb, err)) {
5704 return false;
5706 ws_debug("wrote PEN = %u", cb.pen);
5708 /* write custom data */
5709 if (!wtap_dump_file_write(wdh, pd, rec->rec_header.custom_block_header.length, err)) {
5710 return false;
5713 /* write padding (if any) */
5714 if (pad_len > 0) {
5715 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err)) {
5716 return false;
5720 /* write block footer */
5721 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5722 sizeof bh.block_total_length, err)) {
5723 return false;
5726 return true;
5729 static bool
5730 pcapng_write_bblog_block(wtap_dumper *wdh, const wtap_rec *rec,
5731 const uint8_t *pd _U_, int *err)
5733 pcapng_block_header_t bh;
5734 uint32_t options_size = 0;
5735 uint32_t pen, skipped, type;
5737 /* Compute size of all the options */
5738 options_size = compute_options_size(rec->block, compute_epb_option_size);
5740 /* write block header */
5741 bh.block_type = BLOCK_TYPE_CB_COPY;
5742 bh.block_total_length = (uint32_t)(sizeof(bh) + sizeof(uint32_t) + sizeof(uint32_t) + options_size + 4);
5743 if (rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type == BBLOG_TYPE_SKIPPED_BLOCK) {
5744 bh.block_total_length += (uint32_t)sizeof(uint32_t);
5746 ws_debug("writing %u bytes, type %u",
5747 bh.block_total_length, rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
5748 if (!wtap_dump_file_write(wdh, &bh, sizeof(bh), err)) {
5749 return false;
5752 /* write PEN */
5753 pen = PEN_NFLX;
5754 if (!wtap_dump_file_write(wdh, &pen, sizeof(uint32_t), err)) {
5755 return false;
5757 ws_debug("wrote PEN = %u", pen);
5759 /* write type */
5760 type = GUINT32_TO_LE(rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
5761 if (!wtap_dump_file_write(wdh, &type, sizeof(uint32_t), err)) {
5762 return false;
5764 ws_debug("wrote type = %u", rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
5766 if (rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type == BBLOG_TYPE_SKIPPED_BLOCK) {
5767 skipped = GUINT32_TO_LE(rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
5768 if (!wtap_dump_file_write(wdh, &skipped, sizeof(uint32_t), err)) {
5769 return false;
5771 ws_debug("wrote skipped = %u", rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
5774 /* Write options, if we have any */
5775 if (options_size != 0) {
5777 * This block type supports only comments and custom options,
5778 * so it doesn't need a callback.
5780 if (!write_options(wdh, rec->block, NULL, err))
5781 return false;
5784 /* write block footer */
5785 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5786 sizeof bh.block_total_length, err)) {
5787 return false;
5790 return true;
5793 static bool
5794 pcapng_write_decryption_secrets_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
5796 pcapng_block_header_t bh;
5797 pcapng_decryption_secrets_block_t dsb;
5798 wtapng_dsb_mandatory_t *mand_data = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
5799 unsigned pad_len = (4 - (mand_data->secrets_len & 3)) & 3;
5801 /* write block header */
5802 bh.block_type = BLOCK_TYPE_DSB;
5803 bh.block_total_length = MIN_DSB_SIZE + mand_data->secrets_len + pad_len;
5804 ws_debug("Total len %u", bh.block_total_length);
5806 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5807 return false;
5809 /* write block fixed content */
5810 dsb.secrets_type = mand_data->secrets_type;
5811 dsb.secrets_len = mand_data->secrets_len;
5812 if (!wtap_dump_file_write(wdh, &dsb, sizeof dsb, err))
5813 return false;
5815 if (!wtap_dump_file_write(wdh, mand_data->secrets_data, mand_data->secrets_len, err))
5816 return false;
5817 if (pad_len) {
5818 const uint32_t zero_pad = 0;
5819 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5820 return false;
5823 /* write block footer */
5824 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5825 sizeof bh.block_total_length, err))
5826 return false;
5828 return true;
5831 static bool
5832 pcapng_write_meta_event_block(wtap_dumper *wdh, wtap_block_t mev_data, int *err)
5834 pcapng_block_header_t bh;
5835 wtapng_meta_event_mandatory_t *mand_data = (wtapng_meta_event_mandatory_t *)wtap_block_get_mandatory_data(mev_data);
5836 unsigned pad_len = (4 - (mand_data->mev_data_len & 3)) & 3;
5838 /* write block header */
5839 bh.block_type = mand_data->mev_block_type;
5840 bh.block_total_length = MIN_BLOCK_SIZE + mand_data->mev_data_len + pad_len;
5841 ws_debug("Sysdig mev total len %u", bh.block_total_length);
5843 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5844 return false;
5846 /* write block fixed content */
5847 if (!wtap_dump_file_write(wdh, mand_data->mev_data, mand_data->mev_data_len, err))
5848 return false;
5850 if (pad_len) {
5851 const uint32_t zero_pad = 0;
5852 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5853 return false;
5856 /* write block footer */
5857 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5858 sizeof bh.block_total_length, err))
5859 return false;
5861 return true;
5865 * libpcap's maximum pcapng block size is currently 16MB.
5867 * The maximum pcapng block size in macOS's private pcapng reading code
5868 * is 1MB. (Yes, this means that a program using the standard pcap
5869 * code to read pcapng files can handle bigger blocks than can programs
5870 * using the private code, such as Apple's tcpdump, can handle.)
5872 * The pcapng reading code here can handle NRBs of arbitrary size (less
5873 * than 4GB, obviously), as they read each NRB record independently,
5874 * rather than reading the entire block into memory.
5876 * So, for now, we set the maximum NRB block size we write as 1 MB.
5878 * (Yes, for the benefit of the fussy, "MB" is really "MiB".)
5881 #define NRES_BLOCK_MAX_SIZE (1024*1024)
5883 static uint32_t
5884 compute_nrb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
5886 uint32_t size;
5888 switch(option_id)
5890 case OPT_NS_DNSNAME:
5891 size = pcapng_compute_string_option_size(optval);
5892 break;
5893 case OPT_NS_DNSIP4ADDR:
5894 size = 4;
5895 break;
5896 case OPT_NS_DNSIP6ADDR:
5897 size = 16;
5898 break;
5899 default:
5900 /* Unknown options - size by datatype? */
5901 size = 0;
5902 break;
5904 return size;
5907 static bool
5908 put_nrb_option(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
5910 uint8_t **opt_ptrp = (uint8_t **)user_data;
5911 uint32_t size = 0;
5912 struct pcapng_option_header option_hdr;
5913 uint32_t pad;
5915 switch(option_id)
5917 case OPT_COMMENT:
5918 case OPT_NS_DNSNAME:
5919 /* String options don't consider pad bytes part of the length */
5920 size = (uint32_t)strlen(optval->stringval) & 0xffff;
5921 option_hdr.type = (uint16_t)option_id;
5922 option_hdr.value_length = (uint16_t)size;
5923 memcpy(*opt_ptrp, &option_hdr, 4);
5924 *opt_ptrp += 4;
5926 memcpy(*opt_ptrp, optval->stringval, size);
5927 *opt_ptrp += size;
5929 if ((size % 4)) {
5930 pad = 4 - (size % 4);
5931 } else {
5932 pad = 0;
5935 /* put padding (if any) */
5936 if (pad != 0) {
5937 memset(*opt_ptrp, 0, pad);
5938 *opt_ptrp += pad;
5940 break;
5941 case OPT_CUSTOM_STR_COPY:
5942 case OPT_CUSTOM_BIN_COPY:
5943 /* Custom options don't consider pad bytes part of the length */
5944 size = (uint32_t)(optval->custom_opt.data.generic_data.custom_data_len + sizeof(uint32_t)) & 0xffff;
5945 option_hdr.type = (uint16_t)option_id;
5946 option_hdr.value_length = (uint16_t)size;
5947 memcpy(*opt_ptrp, &option_hdr, 4);
5948 *opt_ptrp += 4;
5950 memcpy(*opt_ptrp, &optval->custom_opt.pen, sizeof(uint32_t));
5951 *opt_ptrp += sizeof(uint32_t);
5953 memcpy(*opt_ptrp, optval->custom_opt.data.generic_data.custom_data, optval->custom_opt.data.generic_data.custom_data_len);
5954 *opt_ptrp += optval->custom_opt.data.generic_data.custom_data_len;
5956 if ((size % 4)) {
5957 pad = 4 - (size % 4);
5958 } else {
5959 pad = 0;
5962 /* put padding (if any) */
5963 if (pad != 0) {
5964 memset(*opt_ptrp, 0, pad);
5965 *opt_ptrp += pad;
5967 break;
5968 case OPT_NS_DNSIP4ADDR:
5969 option_hdr.type = (uint16_t)option_id;
5970 option_hdr.value_length = 4;
5971 memcpy(*opt_ptrp, &option_hdr, 4);
5972 *opt_ptrp += 4;
5974 memcpy(*opt_ptrp, &optval->ipv4val, 4);
5975 *opt_ptrp += 4;
5976 break;
5977 case OPT_NS_DNSIP6ADDR:
5978 option_hdr.type = (uint16_t)option_id;
5979 option_hdr.value_length = 16;
5980 memcpy(*opt_ptrp, &option_hdr, 4);
5981 *opt_ptrp += 4;
5983 memcpy(*opt_ptrp, &optval->ipv6val, 16);
5984 *opt_ptrp += 16;
5985 break;
5986 default:
5987 /* Unknown options - size by datatype? */
5988 break;
5990 return true; /* we always succeed */
5993 static void
5994 put_nrb_options(wtap_dumper *wdh _U_, wtap_block_t nrb, uint8_t *opt_ptr)
5996 struct pcapng_option option_hdr;
5998 wtap_block_foreach_option(nrb, put_nrb_option, &opt_ptr);
6000 /* Put end of options */
6001 option_hdr.type = OPT_EOFOPT;
6002 option_hdr.value_length = 0;
6003 memcpy(opt_ptr, &option_hdr, 4);
6006 static bool
6007 pcapng_write_name_resolution_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
6009 pcapng_block_header_t bh;
6010 pcapng_name_resolution_block_t nrb;
6011 wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
6012 uint32_t options_size;
6013 size_t max_rec_data_size;
6014 uint8_t *block_data;
6015 uint32_t block_off;
6016 size_t hostnamelen;
6017 uint16_t namelen;
6018 uint32_t tot_rec_len;
6019 hashipv4_t *ipv4_hash_list_entry;
6020 hashipv6_t *ipv6_hash_list_entry;
6021 int i;
6023 if (!mand_data) {
6025 * No name/address pairs to write.
6026 * XXX - what if we have options?
6028 return true;
6031 /* Calculate the space needed for options. */
6032 options_size = compute_options_size(sdata, compute_nrb_option_size);
6035 * Make sure we can fit at least one maximum-sized record, plus
6036 * an end-of-records record, plus the options, into a maximum-sized
6037 * block.
6039 * That requires that there be enough space for the block header
6040 * (8 bytes), a maximum-sized record (2 bytes of record type, 2
6041 * bytes of record value length, 65535 bytes of record value,
6042 * and 1 byte of padding), an end-of-records record (4 bytes),
6043 * the options (options_size bytes), and the block trailer (4
6044 * bytes).
6046 if (8 + 2 + 2 + 65535 + 1 + 4 + options_size + 4 > NRES_BLOCK_MAX_SIZE) {
6048 * XXX - we can't even fit the options in the largest NRB size
6049 * we're willing to write and still have room enough for a
6050 * maximum-sized record. Just discard the information for now.
6052 return true;
6056 * Allocate a buffer for the largest block we'll write.
6058 block_data = (uint8_t *)g_malloc(NRES_BLOCK_MAX_SIZE);
6061 * Calculate the maximum amount of record data we'll be able to
6062 * fit into such a block, after taking into account the block header
6063 * (8 bytes), the end-of-records record (4 bytes), the options
6064 * (options_size bytes), and the block trailer (4 bytes).
6066 max_rec_data_size = NRES_BLOCK_MAX_SIZE - (8 + 4 + options_size + 4);
6068 block_off = 8; /* block type + block total length */
6069 bh.block_type = BLOCK_TYPE_NRB;
6070 bh.block_total_length = 12; /* block header + block trailer */
6073 * Write out the IPv4 resolved addresses, if any.
6075 if (mand_data->ipv4_addr_list){
6076 i = 0;
6077 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
6078 while(ipv4_hash_list_entry != NULL){
6080 nrb.record_type = NRES_IP4RECORD;
6081 hostnamelen = strlen(ipv4_hash_list_entry->name);
6082 if (hostnamelen > (UINT16_MAX - 4) - 1) {
6084 * This won't fit in the largest possible NRB record;
6085 * discard it.
6087 i++;
6088 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
6089 continue;
6091 namelen = (uint16_t)(hostnamelen + 1);
6092 nrb.record_len = 4 + namelen; /* 4 bytes IPv4 address length */
6093 /* 2 bytes record type, 2 bytes length field */
6094 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
6096 if (block_off + tot_rec_len > max_rec_data_size) {
6098 * This record would overflow our maximum size for Name
6099 * Resolution Blocks; write out all the records we created
6100 * before it, and start a new NRB.
6103 /* Append the end-of-records record */
6104 memset(block_data + block_off, 0, 4);
6105 block_off += 4;
6106 bh.block_total_length += 4;
6109 * Put the options into the block.
6111 put_nrb_options(wdh, sdata, block_data + block_off);
6112 block_off += options_size;
6113 bh.block_total_length += options_size;
6115 /* Copy the block header. */
6116 memcpy(block_data, &bh, sizeof(bh));
6118 /* Copy the block trailer. */
6119 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
6121 ws_debug("Write bh.block_total_length bytes %d, block_off %u",
6122 bh.block_total_length, block_off);
6124 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
6125 g_free(block_data);
6126 return false;
6129 /*Start a new NRB */
6130 block_off = 8; /* block type + block total length */
6131 bh.block_type = BLOCK_TYPE_NRB;
6132 bh.block_total_length = 12; /* block header + block trailer */
6135 bh.block_total_length += tot_rec_len;
6136 memcpy(block_data + block_off, &nrb, sizeof(nrb));
6137 block_off += 4;
6138 memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4);
6139 block_off += 4;
6140 memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen);
6141 block_off += namelen;
6142 memset(block_data + block_off, 0, PADDING4(namelen));
6143 block_off += PADDING4(namelen);
6144 ws_debug("added IPv4 record for %s", ipv4_hash_list_entry->name);
6146 i++;
6147 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
6151 if (mand_data->ipv6_addr_list){
6152 i = 0;
6153 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
6154 while(ipv6_hash_list_entry != NULL){
6156 nrb.record_type = NRES_IP6RECORD;
6157 hostnamelen = strlen(ipv6_hash_list_entry->name);
6158 if (hostnamelen > (UINT16_MAX - 16) - 1) {
6160 * This won't fit in the largest possible NRB record;
6161 * discard it.
6163 i++;
6164 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
6165 continue;
6167 namelen = (uint16_t)(hostnamelen + 1);
6168 nrb.record_len = 16 + namelen; /* 16 bytes IPv6 address length */
6169 /* 2 bytes record type, 2 bytes length field */
6170 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
6172 if (block_off + tot_rec_len > max_rec_data_size) {
6174 * This record would overflow our maximum size for Name
6175 * Resolution Blocks; write out all the records we created
6176 * before it, and start a new NRB.
6179 /* Append the end-of-records record */
6180 memset(block_data + block_off, 0, 4);
6181 block_off += 4;
6182 bh.block_total_length += 4;
6185 * Put the options into the block.
6187 put_nrb_options(wdh, sdata, block_data + block_off);
6188 block_off += options_size;
6189 bh.block_total_length += options_size;
6191 /* Copy the block header. */
6192 memcpy(block_data, &bh, sizeof(bh));
6194 /* Copy the block trailer. */
6195 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
6197 ws_debug("write bh.block_total_length bytes %d, block_off %u",
6198 bh.block_total_length, block_off);
6200 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
6201 g_free(block_data);
6202 return false;
6205 /*Start a new NRB */
6206 block_off = 8; /* block type + block total length */
6207 bh.block_type = BLOCK_TYPE_NRB;
6208 bh.block_total_length = 12; /* block header + block trailer */
6211 bh.block_total_length += tot_rec_len;
6212 memcpy(block_data + block_off, &nrb, sizeof(nrb));
6213 block_off += 4;
6214 memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16);
6215 block_off += 16;
6216 memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen);
6217 block_off += namelen;
6218 memset(block_data + block_off, 0, PADDING4(namelen));
6219 block_off += PADDING4(namelen);
6220 ws_debug("added IPv6 record for %s", ipv6_hash_list_entry->name);
6222 i++;
6223 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
6227 /* Append the end-of-records record */
6228 memset(block_data + block_off, 0, 4);
6229 block_off += 4;
6230 bh.block_total_length += 4;
6233 * Put the options into the block.
6235 put_nrb_options(wdh, sdata, block_data + block_off);
6236 block_off += options_size;
6237 bh.block_total_length += options_size;
6239 /* Copy the block header. */
6240 memcpy(block_data, &bh, sizeof(bh));
6242 /* Copy the block trailer. */
6243 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
6245 ws_debug("Write bh.block_total_length bytes %d, block_off %u",
6246 bh.block_total_length, block_off);
6248 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
6249 g_free(block_data);
6250 return false;
6253 g_free(block_data);
6255 return true;
6258 static uint32_t compute_isb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval _U_)
6260 uint32_t size;
6262 switch(option_id)
6264 case OPT_ISB_STARTTIME:
6265 case OPT_ISB_ENDTIME:
6266 size = 8;
6267 break;
6268 case OPT_ISB_IFRECV:
6269 case OPT_ISB_IFDROP:
6270 case OPT_ISB_FILTERACCEPT:
6271 case OPT_ISB_OSDROP:
6272 case OPT_ISB_USRDELIV:
6273 size = 8;
6274 break;
6275 default:
6276 /* Unknown options - size by datatype? */
6277 size = 0;
6278 break;
6280 return size;
6283 static bool write_wtap_isb_option(wtap_dumper *wdh, wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, int *err)
6285 switch(option_id)
6287 case OPT_ISB_STARTTIME:
6288 case OPT_ISB_ENDTIME:
6289 if (!pcapng_write_timestamp_option(wdh, option_id, optval, err))
6290 return false;
6291 break;
6292 case OPT_ISB_IFRECV:
6293 case OPT_ISB_IFDROP:
6294 case OPT_ISB_FILTERACCEPT:
6295 case OPT_ISB_OSDROP:
6296 case OPT_ISB_USRDELIV:
6297 if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
6298 return false;
6299 break;
6300 default:
6301 /* Unknown options - write by datatype? */
6302 break;
6304 return true; /* success */
6307 static bool
6308 pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_block_t if_stats, int *err)
6310 pcapng_block_header_t bh;
6311 pcapng_interface_statistics_block_t isb;
6312 uint32_t options_size;
6313 wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
6315 ws_debug("entering function");
6317 /* Compute size of all the options */
6318 options_size = compute_options_size(if_stats, compute_isb_option_size);
6320 /* write block header */
6321 bh.block_type = BLOCK_TYPE_ISB;
6322 bh.block_total_length = (uint32_t)(sizeof(bh) + sizeof(isb) + options_size + 4);
6323 ws_debug("Total len %u", bh.block_total_length);
6325 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
6326 return false;
6328 /* write block fixed content */
6329 isb.interface_id = mand_data->interface_id;
6330 isb.timestamp_high = mand_data->ts_high;
6331 isb.timestamp_low = mand_data->ts_low;
6333 if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
6334 return false;
6336 /* Write options */
6337 if (options_size != 0) {
6338 if (!write_options(wdh, if_stats, write_wtap_isb_option, err))
6339 return false;
6342 /* write block footer */
6343 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
6344 sizeof bh.block_total_length, err))
6345 return false;
6346 return true;
6349 static uint32_t compute_idb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval)
6351 uint32_t size;
6353 switch(option_id)
6355 case OPT_IDB_NAME:
6356 case OPT_IDB_DESCRIPTION:
6357 case OPT_IDB_OS:
6358 case OPT_IDB_HARDWARE:
6359 size = pcapng_compute_string_option_size(optval);
6360 break;
6361 case OPT_IDB_SPEED:
6362 size = 8;
6363 break;
6364 case OPT_IDB_TSRESOL:
6365 size = 1;
6366 break;
6367 case OPT_IDB_FILTER:
6368 size = pcapng_compute_if_filter_option_size(optval);
6369 break;
6370 case OPT_IDB_FCSLEN:
6371 size = 1;
6372 break;
6373 case OPT_IDB_TSOFFSET:
6375 * The time stamps handed to us when writing a file are
6376 * absolute time staps, so the time stamp offset is
6377 * zero.
6379 * We do not adjust them when writing, so we should not
6380 * write if_tsoffset options; that is interpreted as
6381 * the offset is zero, i.e. the time stamps in the file
6382 * are absolute.
6384 size = 0;
6385 break;
6386 default:
6387 /* Unknown options - size by datatype? */
6388 size = 0;
6389 break;
6391 return size;
6394 static bool write_wtap_idb_option(wtap_dumper *wdh, wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, int *err)
6396 switch(option_id)
6398 case OPT_IDB_NAME:
6399 case OPT_IDB_DESCRIPTION:
6400 case OPT_IDB_OS:
6401 case OPT_IDB_HARDWARE:
6402 if (!pcapng_write_string_option(wdh, option_id, optval, err))
6403 return false;
6404 break;
6405 case OPT_IDB_SPEED:
6406 if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
6407 return false;
6408 break;
6409 case OPT_IDB_TSRESOL:
6410 if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
6411 return false;
6412 break;
6413 case OPT_IDB_FILTER:
6414 if (!pcapng_write_if_filter_option(wdh, option_id, optval, err))
6415 return false;
6416 break;
6417 case OPT_IDB_FCSLEN:
6418 if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
6419 return false;
6420 break;
6421 case OPT_IDB_TSOFFSET:
6423 * As noted above, we discard these.
6425 break;
6426 default:
6427 /* Unknown options - size by datatype? */
6428 break;
6430 return true;
6433 static bool
6434 pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data, int *err)
6436 pcapng_block_header_t bh;
6437 pcapng_interface_description_block_t idb;
6438 uint32_t options_size;
6439 wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
6440 int link_type;
6442 ws_debug("encap = %d (%s), snaplen = %d",
6443 mand_data->wtap_encap,
6444 wtap_encap_description(mand_data->wtap_encap),
6445 mand_data->snap_len);
6447 link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap);
6448 if (link_type == -1) {
6449 if (!pcapng_encap_is_ft_specific(mand_data->wtap_encap)) {
6450 *err = WTAP_ERR_UNWRITABLE_ENCAP;
6451 return false;
6455 /* Compute size of all the options */
6456 options_size = compute_options_size(int_data, compute_idb_option_size);
6458 /* write block header */
6459 bh.block_type = BLOCK_TYPE_IDB;
6460 bh.block_total_length = (uint32_t)(sizeof(bh) + sizeof(idb) + options_size + 4);
6461 ws_debug("Total len %u", bh.block_total_length);
6463 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
6464 return false;
6466 /* write block fixed content */
6467 idb.linktype = link_type;
6468 idb.reserved = 0;
6469 idb.snaplen = mand_data->snap_len;
6471 if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
6472 return false;
6474 if (options_size != 0) {
6475 /* Write options */
6476 if (!write_options(wdh, int_data, write_wtap_idb_option, err))
6477 return false;
6480 /* write block footer */
6481 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
6482 sizeof bh.block_total_length, err))
6483 return false;
6485 return true;
6488 static bool pcapng_add_idb(wtap_dumper *wdh, wtap_block_t idb,
6489 int *err, char **err_info _U_)
6491 wtap_block_t idb_copy;
6494 * Add a copy of this IDB to our array of IDBs.
6496 idb_copy = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
6497 wtap_block_copy(idb_copy, idb);
6498 g_array_append_val(wdh->interface_data, idb_copy);
6501 * And write it to the output file.
6503 return pcapng_write_if_descr_block(wdh, idb_copy, err);
6506 static bool pcapng_write_internal_blocks(wtap_dumper *wdh, int *err)
6509 /* Write (optional) Decryption Secrets Blocks that were collected while
6510 * reading packet blocks. */
6511 if (wdh->dsbs_growing) {
6512 for (unsigned i = wdh->dsbs_growing_written; i < wdh->dsbs_growing->len; i++) {
6513 ws_debug("writing DSB %u", i);
6514 wtap_block_t dsb = g_array_index(wdh->dsbs_growing, wtap_block_t, i);
6515 if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6516 return false;
6518 ++wdh->dsbs_growing_written;
6522 /* Write (optional) Sysdig Meta Event Blocks that were collected while
6523 * reading packet blocks. */
6524 if (wdh->mevs_growing) {
6525 for (unsigned i = wdh->mevs_growing_written; i < wdh->mevs_growing->len; i++) {
6526 ws_debug("writing Sysdig mev %u", i);
6527 wtap_block_t mev = g_array_index(wdh->mevs_growing, wtap_block_t, i);
6528 if (!pcapng_write_meta_event_block(wdh, mev, err)) {
6529 return false;
6531 ++wdh->mevs_growing_written;
6535 /* Write any hostname resolution info from wtap_dump_set_addrinfo_list() */
6536 if (!wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
6538 * XXX: get_addrinfo_list() returns a list of all known and used
6539 * resolved addresses, regardless of origin: existing NRBs, externally
6540 * resolved, DNS packet data, a hosts file, and manual host resolution
6541 * through the GUI. It does not include the source for each.
6543 * If it did, we could instead create multiple NRBs, one for each
6544 * server (as the options can only be included once per block.)
6545 * Instead, we copy the options from the first already existing NRB
6546 * (if there is one), since some of the name resolutions may be
6547 * from that block.
6549 wtap_block_t nrb;
6550 if (wdh->nrbs_growing && wdh->nrbs_growing->len) {
6551 nrb = wtap_block_make_copy(g_array_index(wdh->nrbs_growing, wtap_block_t, 0));
6552 } else {
6553 nrb = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
6555 wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(nrb);
6556 mand_data->ipv4_addr_list = wdh->addrinfo_lists->ipv4_addr_list;
6557 mand_data->ipv6_addr_list = wdh->addrinfo_lists->ipv6_addr_list;
6559 if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
6560 return false;
6562 mand_data->ipv4_addr_list = NULL;
6563 mand_data->ipv6_addr_list = NULL;
6564 wtap_block_unref(nrb);
6565 g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
6566 wdh->addrinfo_lists->ipv4_addr_list = NULL;
6567 g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
6568 wdh->addrinfo_lists->ipv6_addr_list = NULL;
6569 /* Since the addrinfo lists include information from existing NRBs,
6570 * avoid writing them to avoid duplication.
6572 * XXX: Perhaps we don't want to include information from the NRBs
6573 * in get_addrinfo_list at all, so that we could write existing
6574 * NRBs as-is.
6576 * This is still not well oriented for one-pass programs, where we
6577 * don't have addrinfo_lists until we've already written the
6578 * NRBs. We should not write both in such a situation. See bug 15502.
6580 wtap_dump_discard_name_resolution(wdh);
6583 /* Write (optional) Name Resolution Blocks that were collected while
6584 * reading packet blocks. */
6585 if (wdh->nrbs_growing) {
6586 for (unsigned i = wdh->nrbs_growing_written; i < wdh->nrbs_growing->len; i++) {
6587 wtap_block_t nrb = g_array_index(wdh->nrbs_growing, wtap_block_t, i);
6588 if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
6589 return false;
6591 ++wdh->nrbs_growing_written;
6595 return true;
6598 static bool pcapng_dump(wtap_dumper *wdh,
6599 const wtap_rec *rec,
6600 const uint8_t *pd, int *err, char **err_info)
6602 #ifdef HAVE_PLUGINS
6603 block_handler *handler;
6604 #endif
6606 if (!pcapng_write_internal_blocks(wdh, err)) {
6607 return false;
6610 ws_debug("encap = %d (%s) rec type = %u",
6611 rec->rec_header.packet_header.pkt_encap,
6612 wtap_encap_description(rec->rec_header.packet_header.pkt_encap),
6613 rec->rec_type);
6615 switch (rec->rec_type) {
6617 case REC_TYPE_PACKET:
6618 /* Write Simple Packet Block if appropriate, Enhanced Packet Block otherwise. */
6619 if (!(rec->presence_flags & WTAP_HAS_TS) &&
6620 (!(rec->presence_flags & WTAP_HAS_INTERFACE_ID) || rec->rec_header.packet_header.interface_id == 0) &&
6621 (!(rec->presence_flags & WTAP_HAS_CAP_LEN) || rec->rec_header.packet_header.len == rec->rec_header.packet_header.caplen) &&
6622 (rec->block == NULL || compute_options_size(rec->block, compute_epb_option_size) == 0)) {
6623 if (!pcapng_write_simple_packet_block(wdh, rec, pd, err, err_info)) {
6624 return false;
6627 else {
6628 if (!pcapng_write_enhanced_packet_block(wdh, rec, pd, err, err_info)) {
6629 return false;
6632 break;
6634 case REC_TYPE_FT_SPECIFIC_EVENT:
6635 case REC_TYPE_FT_SPECIFIC_REPORT:
6636 #ifdef HAVE_PLUGINS
6638 * Do we have a handler for this block type?
6640 if (block_handlers != NULL &&
6641 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
6642 GUINT_TO_POINTER(rec->rec_header.ft_specific_header.record_type))) != NULL) {
6643 /* Yes. Call it to write out this record. */
6644 if (!handler->writer(wdh, rec, pd, err))
6645 return false;
6646 } else
6647 #endif
6649 /* No. */
6650 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
6651 return false;
6653 break;
6655 case REC_TYPE_SYSCALL:
6656 if (!pcapng_write_sysdig_event_block(wdh, rec, pd, err)) {
6657 return false;
6659 break;
6661 case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
6662 if (!pcapng_write_systemd_journal_export_block(wdh, rec, pd, err)) {
6663 return false;
6665 break;
6667 case REC_TYPE_CUSTOM_BLOCK:
6668 switch (rec->rec_header.custom_block_header.pen) {
6669 case PEN_NFLX:
6670 if (!pcapng_write_bblog_block(wdh, rec, pd, err)) {
6671 return false;
6673 break;
6674 default:
6675 if (!pcapng_write_custom_block(wdh, rec, pd, err)) {
6676 return false;
6678 break;
6680 break;
6682 default:
6683 /* We don't support writing this record type. */
6684 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
6685 return false;
6688 return true;
6691 /* Finish writing to a dump file.
6692 Returns true on success, false on failure. */
6693 static bool pcapng_dump_finish(wtap_dumper *wdh, int *err,
6694 char **err_info _U_)
6696 unsigned i, j;
6698 /* Flush any hostname resolution or decryption secrets info we may have */
6699 if (!pcapng_write_internal_blocks(wdh, err)) {
6700 return false;
6703 for (i = 0; i < wdh->interface_data->len; i++) {
6705 /* Get the interface description */
6706 wtap_block_t int_data;
6707 wtapng_if_descr_mandatory_t *int_data_mand;
6709 int_data = g_array_index(wdh->interface_data, wtap_block_t, i);
6710 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
6712 for (j = 0; j < int_data_mand->num_stat_entries; j++) {
6713 wtap_block_t if_stats;
6715 if_stats = g_array_index(int_data_mand->interface_statistics, wtap_block_t, j);
6716 ws_debug("write ISB for interface %u",
6717 ((wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats))->interface_id);
6718 if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) {
6719 return false;
6724 ws_debug("leaving function");
6725 return true;
6728 /* Returns true on success, false on failure; sets "*err" to an error code on
6729 failure */
6730 static bool
6731 pcapng_dump_open(wtap_dumper *wdh, int *err, char **err_info _U_)
6733 unsigned i;
6735 ws_debug("entering function");
6736 /* This is a pcapng file */
6737 wdh->subtype_add_idb = pcapng_add_idb;
6738 wdh->subtype_write = pcapng_dump;
6739 wdh->subtype_finish = pcapng_dump_finish;
6741 /* write the section header block */
6742 if (!pcapng_write_section_header_block(wdh, err)) {
6743 return false;
6745 ws_debug("wrote section header block.");
6747 /* Write the Interface description blocks */
6748 ws_debug("Number of IDBs to write (number of interfaces) %u",
6749 wdh->interface_data->len);
6751 for (i = 0; i < wdh->interface_data->len; i++) {
6753 /* Get the interface description */
6754 wtap_block_t idb;
6756 idb = g_array_index(wdh->interface_data, wtap_block_t, i);
6758 if (!pcapng_write_if_descr_block(wdh, idb, err)) {
6759 return false;
6764 /* Write (optional) fixed Decryption Secrets Blocks. */
6765 if (wdh->dsbs_initial) {
6766 for (i = 0; i < wdh->dsbs_initial->len; i++) {
6767 wtap_block_t dsb = g_array_index(wdh->dsbs_initial, wtap_block_t, i);
6768 if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6769 return false;
6774 return true;
6777 /* Returns 0 if we could write the specified encapsulation type,
6778 an error indication otherwise. */
6779 static int pcapng_dump_can_write_encap(int wtap_encap)
6781 ws_debug("encap = %d (%s)",
6782 wtap_encap,
6783 wtap_encap_description(wtap_encap));
6785 /* Per-packet encapsulation is supported. */
6786 if (wtap_encap == WTAP_ENCAP_PER_PACKET)
6787 return 0;
6789 /* No encapsulation type (yet) is supported. */
6790 if (wtap_encap == WTAP_ENCAP_NONE)
6791 return 0;
6793 /* Is it a filetype-specific encapsulation that we support? */
6794 if (pcapng_encap_is_ft_specific(wtap_encap)) {
6795 return 0;
6798 /* Make sure we can figure out this DLT type */
6799 if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
6800 return WTAP_ERR_UNWRITABLE_ENCAP;
6802 return 0;
6806 * Returns true if the specified encapsulation type is filetype-specific
6807 * and one that we support.
6809 bool pcapng_encap_is_ft_specific(int encap)
6811 switch (encap) {
6812 case WTAP_ENCAP_SYSTEMD_JOURNAL:
6813 return true;
6815 return false;
6819 * pcapng supports several block types, and supports more than one
6820 * of them.
6822 * It also supports comments for many block types, as well as other
6823 * option types.
6826 /* Options for section blocks. */
6827 static const struct supported_option_type section_block_options_supported[] = {
6828 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6829 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6830 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6831 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6832 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6833 { OPT_SHB_HARDWARE, ONE_OPTION_SUPPORTED },
6834 { OPT_SHB_USERAPPL, ONE_OPTION_SUPPORTED }
6837 /* Options for interface blocks. */
6838 static const struct supported_option_type interface_block_options_supported[] = {
6839 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6840 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6841 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6842 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6843 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6844 { OPT_IDB_NAME, ONE_OPTION_SUPPORTED },
6845 { OPT_IDB_DESCRIPTION, ONE_OPTION_SUPPORTED },
6846 { OPT_IDB_IP4ADDR, MULTIPLE_OPTIONS_SUPPORTED },
6847 { OPT_IDB_IP6ADDR, MULTIPLE_OPTIONS_SUPPORTED },
6848 { OPT_IDB_MACADDR, ONE_OPTION_SUPPORTED },
6849 { OPT_IDB_EUIADDR, ONE_OPTION_SUPPORTED },
6850 { OPT_IDB_SPEED, ONE_OPTION_SUPPORTED },
6851 { OPT_IDB_TSRESOL, ONE_OPTION_SUPPORTED },
6852 { OPT_IDB_TZONE, ONE_OPTION_SUPPORTED },
6853 { OPT_IDB_FILTER, ONE_OPTION_SUPPORTED },
6854 { OPT_IDB_OS, ONE_OPTION_SUPPORTED },
6855 { OPT_IDB_FCSLEN, ONE_OPTION_SUPPORTED },
6856 { OPT_IDB_TSOFFSET, ONE_OPTION_SUPPORTED },
6857 { OPT_IDB_HARDWARE, ONE_OPTION_SUPPORTED }
6860 /* Options for name resolution blocks. */
6861 static const struct supported_option_type name_resolution_block_options_supported[] = {
6862 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6863 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6864 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6865 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6866 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6867 { OPT_NS_DNSNAME, ONE_OPTION_SUPPORTED },
6868 { OPT_NS_DNSIP4ADDR, ONE_OPTION_SUPPORTED },
6869 { OPT_NS_DNSIP6ADDR, ONE_OPTION_SUPPORTED }
6872 /* Options for interface statistics blocks. */
6873 static const struct supported_option_type interface_statistics_block_options_supported[] = {
6874 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6875 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6876 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6877 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6878 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6879 { OPT_ISB_STARTTIME, ONE_OPTION_SUPPORTED },
6880 { OPT_ISB_ENDTIME, ONE_OPTION_SUPPORTED },
6881 { OPT_ISB_IFRECV, ONE_OPTION_SUPPORTED },
6882 { OPT_ISB_IFDROP, ONE_OPTION_SUPPORTED },
6883 { OPT_ISB_FILTERACCEPT, ONE_OPTION_SUPPORTED },
6884 { OPT_ISB_OSDROP, ONE_OPTION_SUPPORTED },
6885 { OPT_ISB_USRDELIV, ONE_OPTION_SUPPORTED }
6888 /* Options for decryption secrets blocks. */
6889 static const struct supported_option_type decryption_secrets_block_options_supported[] = {
6890 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6891 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6892 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6893 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6894 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6897 /* Options for meta event blocks. */
6898 static const struct supported_option_type meta_events_block_options_supported[] = {
6899 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6900 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6901 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6902 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6903 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6906 /* Options for packet blocks. */
6907 static const struct supported_option_type packet_block_options_supported[] = {
6908 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6909 { OPT_PKT_FLAGS, ONE_OPTION_SUPPORTED },
6910 { OPT_PKT_DROPCOUNT, ONE_OPTION_SUPPORTED },
6911 { OPT_PKT_PACKETID, ONE_OPTION_SUPPORTED },
6912 { OPT_PKT_QUEUE, ONE_OPTION_SUPPORTED },
6913 { OPT_PKT_HASH, MULTIPLE_OPTIONS_SUPPORTED },
6914 { OPT_PKT_VERDICT, MULTIPLE_OPTIONS_SUPPORTED },
6915 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6916 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6917 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6918 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6921 /* Options for file-type-specific reports. */
6922 static const struct supported_option_type ft_specific_report_block_options_supported[] = {
6923 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6924 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6925 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6926 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6927 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6930 /* Options for file-type-specific event. */
6931 static const struct supported_option_type ft_specific_event_block_options_supported[] = {
6932 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6933 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6934 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6935 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6936 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6939 /* Options for systemd journal entry. */
6940 static const struct supported_option_type systemd_journal_export_block_options_supported[] = {
6941 { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6942 { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6943 { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6944 { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6945 { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6948 static const struct supported_block_type pcapng_blocks_supported[] = {
6949 /* Multiple sections. */
6950 { WTAP_BLOCK_SECTION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(section_block_options_supported) },
6952 /* Multiple interfaces. */
6953 { WTAP_BLOCK_IF_ID_AND_INFO, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_block_options_supported) },
6955 /* Multiple blocks of name resolution information */
6956 { WTAP_BLOCK_NAME_RESOLUTION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(name_resolution_block_options_supported) },
6958 /* Multiple blocks of interface statistics. */
6959 { WTAP_BLOCK_IF_STATISTICS, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_statistics_block_options_supported) },
6961 /* Multiple blocks of decryption secrets. */
6962 { WTAP_BLOCK_DECRYPTION_SECRETS, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(decryption_secrets_block_options_supported) },
6964 /* Multiple blocks of decryption secrets. */
6965 { WTAP_BLOCK_META_EVENT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(meta_events_block_options_supported) },
6967 /* And, obviously, multiple packets. */
6968 { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(packet_block_options_supported) },
6970 /* Multiple file-type specific reports (including local ones). */
6971 { WTAP_BLOCK_FT_SPECIFIC_REPORT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_report_block_options_supported) },
6973 /* Multiple file-type specific events (including local ones). */
6974 { WTAP_BLOCK_FT_SPECIFIC_EVENT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_event_block_options_supported) },
6976 /* Multiple systemd journal export records. */
6977 { WTAP_BLOCK_SYSTEMD_JOURNAL_EXPORT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(systemd_journal_export_block_options_supported) },
6979 /* Multiple custom blocks. */
6980 { WTAP_BLOCK_CUSTOM, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED },
6983 static const struct file_type_subtype_info pcapng_info = {
6984 "Wireshark/... - pcapng", "pcapng", "pcapng", "scap;ntar",
6985 false, BLOCKS_SUPPORTED(pcapng_blocks_supported),
6986 pcapng_dump_can_write_encap, pcapng_dump_open, NULL
6989 void register_pcapng(void)
6991 pcapng_file_type_subtype = wtap_register_file_type_subtype(&pcapng_info);
6993 wtap_register_backwards_compatibility_lua_name("PCAPNG",
6994 pcapng_file_type_subtype);
6998 * Editor modelines - https://www.wireshark.org/tools/modelines.html
7000 * Local variables:
7001 * c-basic-offset: 4
7002 * tab-width: 8
7003 * indent-tabs-mode: nil
7004 * End:
7006 * vi: set shiftwidth=4 tabstop=8 expandtab:
7007 * :indentSize=4:tabSize=8:noTabs=true: