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
15 * https://wiki.wireshark.org/Development/PcapNg
24 #include <wsutil/ws_printf.h>
27 #include "file_wrappers.h"
28 #include "pcap-common.h"
29 #include "pcap-encap.h"
31 #include "pcapng_module.h"
34 #define pcapng_debug(...) g_warning(__VA_ARGS__)
36 #define pcapng_debug(...)
40 pcapng_read(wtap *wth, int *err, gchar **err_info,
43 pcapng_seek_read(wtap *wth, gint64 seek_off,
44 wtap_rec *rec, Buffer *buf, int *err, gchar **err_info);
46 pcapng_close(wtap *wth);
49 pcapng_encap_is_ft_specific(int encap);
52 * Minimum block size = size of block header + size of block trailer.
54 #define MIN_BLOCK_SIZE ((guint32)(sizeof(pcapng_block_header_t) + sizeof(guint32)))
57 * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
59 #define MIN_SHB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
61 /* pcapng: packet block file encoding (obsolete) */
62 typedef struct pcapng_packet_block_s {
65 guint32 timestamp_high;
66 guint32 timestamp_low;
69 /* ... Packet Data ... */
72 } pcapng_packet_block_t;
75 * Minimum PB size = minimum block size + size of fixed length portion of PB.
77 #define MIN_PB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
79 /* pcapng: enhanced packet block file encoding */
80 typedef struct pcapng_enhanced_packet_block_s {
82 guint32 timestamp_high;
83 guint32 timestamp_low;
86 /* ... Packet Data ... */
89 } pcapng_enhanced_packet_block_t;
92 * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
94 #define MIN_EPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
96 /* pcapng: simple packet block file encoding */
97 typedef struct pcapng_simple_packet_block_s {
99 /* ... Packet Data ... */
100 /* ... Padding ... */
101 } pcapng_simple_packet_block_t;
104 * Minimum SPB size = minimum block size + size of fixed length portion of SPB.
106 #define MIN_SPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
108 /* pcapng: name resolution block file encoding */
109 typedef struct pcapng_name_resolution_block_s {
113 } pcapng_name_resolution_block_t;
116 * Minimum NRB size = minimum block size + size of smallest NRB record
117 * (there must at least be an "end of records" record).
119 #define MIN_NRB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
122 * Minimum ISB size = minimum block size + size of fixed length portion of ISB.
124 #define MIN_ISB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
127 * Minimum Sysdig size = minimum block size + packed size of sysdig_event_phdr.
129 #define SYSDIG_EVENT_HEADER_SIZE ((16 + 64 + 64 + 32 + 16)/8) /* CPU ID + TS + TID + Event len + Event type */
130 #define MIN_SYSDIG_EVENT_SIZE ((guint32)(MIN_BLOCK_SIZE + SYSDIG_EVENT_HEADER_SIZE))
133 * We require __CURSOR + __REALTIME_TIMESTAMP + __MONOTONIC_TIMESTAMP in
134 * systemd journal export entries, which is 200 bytes or so (203 on a test
137 #define SDJ__REALTIME_TIMESTAMP "__REALTIME_TIMESTAMP="
138 #define MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE 200
139 #define MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE ((guint32)(MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE + MIN_BLOCK_SIZE))
141 /* pcapng: common option header file encoding for every option type */
142 typedef struct pcapng_option_header_s {
144 guint16 option_length;
145 /* ... x bytes Option Body ... */
146 /* ... Padding ... */
147 } pcapng_option_header_t;
151 guint16 value_length;
154 /* Option codes: 16-bit field */
155 #define OPT_EPB_FLAGS 0x0002
156 #define OPT_EPB_HASH 0x0003
157 #define OPT_EPB_DROPCOUNT 0x0004
159 #define OPT_NRB_DNSNAME 0x0002
160 #define OPT_NRB_DNSV4ADDR 0x0003
161 #define OPT_NRB_DNSV6ADDR 0x0004
163 /* MSBit of option code means "local type" */
164 #define OPT_LOCAL_FLAG 0x8000
167 * In order to keep from trying to allocate large chunks of memory,
168 * which could either fail or, even if it succeeds, chew up so much
169 * address space or memory+backing store as not to leave room for
170 * anything else, we impose upper limits on the size of blocks we're
173 * We pick a limit of an EPB with a maximum-sized D-Bus packet and 128 KiB
174 * worth of options; we use the maximum D-Bus packet size as that's larger
175 * than the maximum packet size for other link-layer types, and the maximum
176 * packet size for other link-layer types is currently small enough that
177 * the resulting block size would be less than the previous 16 MiB limit.
179 #define MAX_BLOCK_SIZE (MIN_EPB_SIZE + WTAP_MAX_PACKET_SIZE_DBUS + 131072)
181 /* Note: many of the defined structures for block data are defined in wtap.h */
183 /* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
184 typedef struct wtapng_packet_s {
186 guint32 ts_high; /* seconds since 1.1.1970 */
187 guint32 ts_low; /* fraction of seconds, depends on if_tsresol */
188 guint32 cap_len; /* data length in the file */
189 guint32 packet_len; /* data length on the wire */
190 guint32 interface_id; /* identifier of the interface. */
191 guint16 drops_count; /* drops count, only valid for packet block */
192 /* 0xffff if information no available */
194 /* XXX - put the packet data / pseudo_header here as well? */
197 /* Simple Packet data */
198 typedef struct wtapng_simple_packet_s {
200 guint32 cap_len; /* data length in the file */
201 guint32 packet_len; /* data length on the wire */
202 /* XXX - put the packet data / pseudo_header here as well? */
203 } wtapng_simple_packet_t;
205 /* Interface data in private struct */
206 typedef struct interface_info_s {
209 guint64 time_units_per_second;
214 gboolean shb_read; /**< Set when first SHB read */
215 gboolean byte_swapped;
216 guint16 version_major;
217 guint16 version_minor;
218 GArray *interfaces; /**< Interfaces found in the capture file. */
220 wtap_new_ipv4_callback_t add_new_ipv4;
221 wtap_new_ipv6_callback_t add_new_ipv6;
226 * Table for plugins to handle particular block types.
228 * A handler has a "read" routine and a "write" routine.
230 * A "read" routine returns a block as a libwiretap record, filling
231 * in the wtap_pkthdr structure with the appropriate record type and
232 * other information, and filling in the supplied Buffer with
233 * data for which there's no place in the wtap_pkthdr structure.
235 * A "write" routine takes a libwiretap record and Buffer and writes
243 static GHashTable *block_handlers;
246 register_pcapng_block_type_handler(guint block_type, block_reader reader,
249 block_handler *handler;
252 * Is this a known block type?
254 switch (block_type) {
263 case BLOCK_TYPE_SYSDIG_EVENT:
264 case BLOCK_TYPE_SYSTEMD_JOURNAL:
266 * Yes; we already handle it, and don't allow a replacement to
267 * be registeted (if there's a bug in our code, or there's
268 * something we don't handle in that block, submit a change
269 * to the main Wireshark source).
271 g_warning("Attempt to register plugin for block type 0x%08x not allowed",
275 case BLOCK_TYPE_IRIG_TS:
276 case BLOCK_TYPE_ARINC_429:
277 case BLOCK_TYPE_SYSDIG_EVF:
279 * Yes, and we don't already handle it. Allow a plugin to
282 * (But why not submit the plugin source to Wireshark?)
288 * No; is it a local block type?
290 if (!(block_type & 0x80000000)) {
292 * No; don't allow a plugin to be registered for it, as
293 * the block type needs to be registered before it's used.
295 g_warning("Attempt to register plugin for reserved block type 0x%08x not allowed",
301 * Yes; allow the registration.
306 if (block_handlers == NULL) {
308 * Create the table of block handlers.
310 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
311 * so we use "g_direct_hash()" and "g_direct_equal()".
313 block_handlers = g_hash_table_new_full(g_direct_hash,
317 handler = g_new(block_handler, 1);
318 handler->reader = reader;
319 handler->writer = writer;
320 g_hash_table_insert(block_handlers, GUINT_TO_POINTER(block_type),
325 * Tables for plugins to handle particular options for particular block
328 * An option has a handler routine, which is passed an indication of
329 * whether this section of the file is byte-swapped, the length of the
330 * option, the data of the option, a pointer to an error code, and a
331 * pointer to a pointer variable for an error string.
333 * It checks whether the length and option are valid, and, if they aren't,
334 * returns FALSE, setting the error code to the appropriate error (normally
335 * WTAP_ERR_BAD_FILE) and the error string to an appropriate string
336 * indicating the problem.
338 * Otherwise, if this section of the file is byte-swapped, it byte-swaps
339 * multi-byte numerical values, so that it's in the host byte order.
343 * Block types indices in the table of tables of option handlers.
345 * Block types are not guaranteed to be sequential, so we map the
346 * block types we support to a sequential set. Furthermore, all
347 * packet block types have the same set of options.
349 #define BT_INDEX_SHB 0
350 #define BT_INDEX_IDB 1
351 #define BT_INDEX_PBS 2 /* all packet blocks */
352 #define BT_INDEX_NRB 3
353 #define BT_INDEX_ISB 4
354 #define BT_INDEX_EVT 5
356 #define NUM_BT_INDICES 6
359 option_handler_fn hfunc;
362 static GHashTable *option_handlers[NUM_BT_INDICES];
365 get_block_type_index(guint block_type, guint *bt_index)
369 switch (block_type) {
372 *bt_index = BT_INDEX_SHB;
376 *bt_index = BT_INDEX_IDB;
382 *bt_index = BT_INDEX_PBS;
386 *bt_index = BT_INDEX_NRB;
390 *bt_index = BT_INDEX_ISB;
393 case BLOCK_TYPE_SYSDIG_EVENT:
394 /* case BLOCK_TYPE_SYSDIG_EVF: */
395 *bt_index = BT_INDEX_EVT;
400 * This is a block type we don't process; either we ignore it,
401 * in which case the options don't get processed, or there's
402 * a plugin routine to handle it, in which case that routine
403 * will do the option processing itself.
405 * XXX - report an error?
414 register_pcapng_option_handler(guint block_type, guint option_code,
415 option_handler_fn hfunc)
418 option_handler *handler;
420 if (!get_block_type_index(block_type, &bt_index))
423 if (option_handlers[bt_index] == NULL) {
425 * Create the table of option handlers for this block type.
427 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
428 * so we use "g_direct_hash()" and "g_direct_equal()".
430 option_handlers[bt_index] = g_hash_table_new_full(g_direct_hash,
434 handler = g_new(option_handler, 1);
435 handler->hfunc = hfunc;
436 g_hash_table_insert(option_handlers[bt_index],
437 GUINT_TO_POINTER(option_code), handler);
439 #endif /* HAVE_PLUGINS */
442 pcapng_read_option(FILE_T fh, pcapng_t *pn, pcapng_option_header_t *oh,
443 guint8 *content, guint len, guint to_read,
444 int *err, gchar **err_info, gchar* block_name)
448 /* sanity check: don't run past the end of the block */
449 if (to_read < sizeof (*oh)) {
450 *err = WTAP_ERR_BAD_FILE;
451 *err_info = g_strdup_printf("pcapng_read_option: Not enough data to read header of the %s block",
456 /* read option header */
457 if (!wtap_read_bytes(fh, oh, sizeof (*oh), err, err_info)) {
458 pcapng_debug("pcapng_read_option: failed to read option");
461 block_read = sizeof (*oh);
462 if (pn->byte_swapped) {
463 oh->option_code = GUINT16_SWAP_LE_BE(oh->option_code);
464 oh->option_length = GUINT16_SWAP_LE_BE(oh->option_length);
467 /* sanity check: don't run past the end of the block */
468 if (to_read < sizeof (*oh) + oh->option_length) {
469 *err = WTAP_ERR_BAD_FILE;
470 *err_info = g_strdup_printf("pcapng_read_option: Not enough data to handle option length (%d) of the %s block",
471 oh->option_length, block_name);
475 /* sanity check: option length */
476 if (len < oh->option_length) {
477 *err = WTAP_ERR_BAD_FILE;
478 *err_info = g_strdup_printf("pcapng_read_option: option length (%d) to long for %s block",
483 /* read option content */
484 if (!wtap_read_bytes(fh, content, oh->option_length, err, err_info)) {
485 pcapng_debug("pcapng_read_option: failed to read content of option %u", oh->option_code);
488 block_read += oh->option_length;
490 /* jump over potential padding bytes at end of option */
491 if ( (oh->option_length % 4) != 0) {
492 if (!wtap_read_bytes(fh, NULL, 4 - (oh->option_length % 4), err, err_info))
494 block_read += 4 - (oh->option_length % 4);
502 PCAPNG_BLOCK_NOT_SHB,
506 static block_return_val
507 pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
508 pcapng_t *pn, wtapng_block_t *wblock,
509 int *err, gchar **err_info)
512 gboolean byte_swapped;
513 guint16 version_major;
514 guint16 version_minor;
515 guint to_read, opt_cont_buf_len;
516 pcapng_section_header_block_t shb;
517 pcapng_option_header_t oh;
518 wtapng_mandatory_section_t* section_data;
521 guint8 *option_content = NULL; /* Allocate as large as the options block */
523 /* read fixed-length part of the block */
524 if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
525 if (*err == WTAP_ERR_SHORT_READ) {
527 * This block is too short to be an SHB.
529 * If we're reading this as part of an open,
530 * the file is too short to be a pcapng file.
532 * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
533 * PCAPNG_BLOCK_ERROR the same, so we can just return
534 * PCAPNG_BLOCK_NOT_SHB in both cases.
536 return PCAPNG_BLOCK_NOT_SHB;
538 return PCAPNG_BLOCK_ERROR;
541 /* is the magic number one we expect? */
544 /* this seems pcapng with correct byte order */
545 byte_swapped = FALSE;
546 version_major = shb.version_major;
547 version_minor = shb.version_minor;
549 pcapng_debug("pcapng_read_section_header_block: SHB (our byte order) V%u.%u, len %u",
550 version_major, version_minor, bh->block_total_length);
553 /* this seems pcapng with swapped byte order */
555 version_major = GUINT16_SWAP_LE_BE(shb.version_major);
556 version_minor = GUINT16_SWAP_LE_BE(shb.version_minor);
558 /* tweak the block length to meet current swapping that we know now */
559 bh->block_total_length = GUINT32_SWAP_LE_BE(bh->block_total_length);
561 pcapng_debug("pcapng_read_section_header_block: SHB (byte-swapped) V%u.%u, len %u",
562 version_major, version_minor, bh->block_total_length);
565 /* Not a "pcapng" magic number we know about. */
566 *err = WTAP_ERR_BAD_FILE;
567 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown byte-order magic number 0x%08x", shb.magic);
570 * See above comment about PCAPNG_BLOCK_NOT_SHB.
572 return PCAPNG_BLOCK_NOT_SHB;
576 * Is this block long enough to be an SHB?
578 if (bh->block_total_length < MIN_SHB_SIZE) {
582 *err = WTAP_ERR_BAD_FILE;
583 *err_info = g_strdup_printf("pcapng_read_section_header_block: total block length %u of an SHB is less than the minimum SHB size %u",
584 bh->block_total_length, MIN_SHB_SIZE);
585 return PCAPNG_BLOCK_ERROR;
588 /* OK, at this point we assume it's a pcapng file.
590 Don't try to allocate memory for a huge number of options, as
591 that might fail and, even if it succeeds, it might not leave
592 any address space or memory+backing store for anything else.
594 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
595 We check for this *after* checking the SHB for its byte
596 order magic number, so that non-pcapng files are less
597 likely to be treated as bad pcapng files. */
598 if (bh->block_total_length > MAX_BLOCK_SIZE) {
599 *err = WTAP_ERR_BAD_FILE;
600 *err_info = g_strdup_printf("pcapng_read_section_header_block: total block length %u is too large (> %u)",
601 bh->block_total_length, MAX_BLOCK_SIZE);
602 return PCAPNG_BLOCK_ERROR;
605 /* we currently only understand SHB V1.0 */
606 if (version_major != 1 || version_minor > 0) {
607 *err = WTAP_ERR_UNSUPPORTED;
608 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown SHB version %u.%u",
609 pn->version_major, pn->version_minor);
610 return PCAPNG_BLOCK_ERROR;
613 pn->byte_swapped = byte_swapped;
614 pn->version_major = version_major;
615 pn->version_minor = version_minor;
617 wblock->block = wtap_block_create(WTAP_BLOCK_NG_SECTION);
618 section_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(wblock->block);
619 /* 64bit section_length (currently unused) */
620 if (pn->byte_swapped) {
621 section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length);
623 section_data->section_length = shb.section_length;
627 to_read = bh->block_total_length - MIN_SHB_SIZE;
629 /* Allocate enough memory to hold all options */
630 opt_cont_buf_len = to_read;
631 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
632 if (opt_cont_buf_len != 0 && option_content == NULL) {
633 *err = ENOMEM; /* we assume we're out of memory */
634 return PCAPNG_BLOCK_ERROR;
636 pcapng_debug("pcapng_read_section_header_block: Options %u bytes", to_read);
637 while (to_read != 0) {
639 pcapng_debug("pcapng_read_section_header_block: Options %u bytes remaining", to_read);
640 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "section_header");
641 if (bytes_read <= 0) {
642 pcapng_debug("pcapng_read_section_header_block: failed to read option");
643 g_free(option_content);
644 return PCAPNG_BLOCK_ERROR;
646 to_read -= bytes_read;
648 /* handle option content */
649 switch (oh.option_code) {
652 pcapng_debug("pcapng_read_section_header_block: %u bytes after opt_endofopt", to_read);
654 /* padding should be ok here, just get out of this */
658 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
659 tmp_content = g_strndup((char *)option_content, oh.option_length);
660 wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
661 pcapng_debug("pcapng_read_section_header_block: opt_comment %s", tmp_content);
664 pcapng_debug("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
667 case(OPT_SHB_HARDWARE):
668 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
669 tmp_content = g_strndup((char *)option_content, oh.option_length);
670 /* Fails with multiple options; we silently ignore the failure */
671 wtap_block_add_string_option(wblock->block, OPT_SHB_HARDWARE, option_content, oh.option_length);
672 pcapng_debug("pcapng_read_section_header_block: shb_hardware %s", tmp_content);
675 pcapng_debug("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
679 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
680 tmp_content = g_strndup((char *)option_content, oh.option_length);
681 /* Fails with multiple options; we silently ignore the failure */
682 wtap_block_add_string_option(wblock->block, OPT_SHB_OS, option_content, oh.option_length);
683 pcapng_debug("pcapng_read_section_header_block: shb_os %s", tmp_content);
686 pcapng_debug("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
689 case(OPT_SHB_USERAPPL):
690 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
691 tmp_content = g_strndup((char *)option_content, oh.option_length);
692 /* Fails with multiple options; we silently ignore the failure */
693 wtap_block_add_string_option(wblock->block, OPT_SHB_USERAPPL, option_content, oh.option_length);
694 pcapng_debug("pcapng_read_section_header_block: shb_user_appl %s", tmp_content);
697 pcapng_debug("pcapng_read_section_header_block: shb_user_appl length %u seems strange", oh.option_length);
701 pcapng_debug("pcapng_read_section_header_block: unknown option %u - ignoring %u bytes",
702 oh.option_code, oh.option_length);
705 g_free(option_content);
708 * We don't return these to the caller in pcapng_read().
710 wblock->internal = TRUE;
712 return PCAPNG_BLOCK_OK;
716 /* "Interface Description Block" */
718 pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
719 pcapng_t *pn, wtapng_block_t *wblock, int *err,
722 guint64 time_units_per_second = 1000000; /* default = 10^6 */
723 int tsprecision = WTAP_TSPREC_USEC;
725 guint to_read, opt_cont_buf_len;
726 pcapng_interface_description_block_t idb;
727 wtapng_if_descr_mandatory_t* if_descr_mand;
729 pcapng_option_header_t oh;
730 guint8 *option_content = NULL; /* Allocate as large as the options block */
735 * Is this block long enough to be an IDB?
737 if (bh->block_total_length < MIN_IDB_SIZE) {
741 *err = WTAP_ERR_BAD_FILE;
742 *err_info = g_strdup_printf("pcapng_read_if_descr_block: total block length %u of an IDB is less than the minimum IDB size %u",
743 bh->block_total_length, MIN_IDB_SIZE);
747 /* read block content */
748 if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
749 pcapng_debug("pcapng_read_if_descr_block: failed to read IDB");
753 /* mandatory values */
754 wblock->block = wtap_block_create(WTAP_BLOCK_IF_DESCR);
755 if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
756 if (pn->byte_swapped) {
757 link_type = GUINT16_SWAP_LE_BE(idb.linktype);
758 if_descr_mand->snap_len = GUINT32_SWAP_LE_BE(idb.snaplen);
760 link_type = idb.linktype;
761 if_descr_mand->snap_len = idb.snaplen;
764 if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(link_type);
765 if_descr_mand->time_units_per_second = time_units_per_second;
766 if_descr_mand->tsprecision = tsprecision;
768 pcapng_debug("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u",
770 wtap_encap_string(if_descr_mand->wtap_encap),
771 if_descr_mand->snap_len);
773 if (if_descr_mand->snap_len > wtap_max_snaplen_for_encap(if_descr_mand->wtap_encap)) {
775 * We do not use this value, maybe we should check the
776 * snap_len of the packets against it. For now, only warn.
778 pcapng_debug("pcapng_read_if_descr_block: snapshot length %u unrealistic.",
779 if_descr_mand->snap_len);
780 /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;*/
784 to_read = bh->block_total_length - MIN_IDB_SIZE;
786 /* Allocate enough memory to hold all options */
787 opt_cont_buf_len = to_read;
788 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
789 if (opt_cont_buf_len != 0 && option_content == NULL) {
790 *err = ENOMEM; /* we assume we're out of memory */
794 while (to_read != 0) {
796 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "if_descr");
797 if (bytes_read <= 0) {
798 pcapng_debug("pcapng_read_if_descr_block: failed to read option");
799 g_free(option_content);
802 to_read -= bytes_read;
804 /* handle option content */
805 switch (oh.option_code) {
806 case(OPT_EOFOPT): /* opt_endofopt */
808 pcapng_debug("pcapng_read_if_descr_block: %u bytes after opt_endofopt", to_read);
810 /* padding should be ok here, just get out of this */
813 case(OPT_COMMENT): /* opt_comment */
814 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
815 tmp_content = g_strndup((char *)option_content, oh.option_length);
816 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
817 pcapng_debug("pcapng_read_if_descr_block: opt_comment %s", tmp_content);
820 pcapng_debug("pcapng_read_if_descr_block: opt_comment length %u seems strange", oh.option_length);
823 case(OPT_IDB_NAME): /* if_name */
824 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
825 tmp_content = g_strndup((char *)option_content, oh.option_length);
826 /* Fails with multiple options; we silently ignore the failure */
827 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
828 pcapng_debug("pcapng_read_if_descr_block: if_name %s", tmp_content);
831 pcapng_debug("pcapng_read_if_descr_block: if_name length %u seems strange", oh.option_length);
834 case(OPT_IDB_DESCR): /* if_description */
835 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
836 tmp_content = g_strndup((char *)option_content, oh.option_length);
837 /* Fails with multiple options; we silently ignore the failure */
838 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
839 pcapng_debug("pcapng_read_if_descr_block: if_description %s", tmp_content);
842 pcapng_debug("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
845 case(OPT_IDB_SPEED): /* if_speed */
846 if (oh.option_length == 8) {
847 /* Don't cast a guint8 * into a guint64 *--the
848 * guint8 * may not point to something that's
851 memcpy(&tmp64, option_content, sizeof(guint64));
852 if (pn->byte_swapped)
853 tmp64 = GUINT64_SWAP_LE_BE(tmp64);
854 /* Fails with multiple options; we silently ignore the failure */
855 wtap_block_add_uint64_option(wblock->block, oh.option_code, tmp64);
856 pcapng_debug("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", tmp64);
858 pcapng_debug("pcapng_read_if_descr_block: if_speed length %u not 8 as expected", oh.option_length);
861 case(OPT_IDB_TSRESOL): /* if_tsresol */
862 if (oh.option_length == 1) {
865 guint8 i, exponent, if_tsresol;
867 if_tsresol = option_content[0];
868 if (if_tsresol & 0x80) {
873 exponent = (guint8)(if_tsresol & 0x7f);
874 if (((base == 2) && (exponent < 64)) || ((base == 10) && (exponent < 20))) {
876 for (i = 0; i < exponent; i++) {
879 time_units_per_second = result;
881 time_units_per_second = G_MAXUINT64;
883 if (time_units_per_second > (((guint64)1) << 32)) {
884 pcapng_debug("pcapng_open: time conversion might be inaccurate");
886 if_descr_mand->time_units_per_second = time_units_per_second;
887 /* Fails with multiple options; we silently ignore the failure */
888 wtap_block_add_uint8_option(wblock->block, oh.option_code, if_tsresol);
889 if (time_units_per_second >= 1000000000)
890 tsprecision = WTAP_TSPREC_NSEC;
891 else if (time_units_per_second >= 1000000)
892 tsprecision = WTAP_TSPREC_USEC;
893 else if (time_units_per_second >= 1000)
894 tsprecision = WTAP_TSPREC_MSEC;
895 else if (time_units_per_second >= 100)
896 tsprecision = WTAP_TSPREC_CSEC;
897 else if (time_units_per_second >= 10)
898 tsprecision = WTAP_TSPREC_DSEC;
900 tsprecision = WTAP_TSPREC_SEC;
901 if_descr_mand->tsprecision = tsprecision;
902 pcapng_debug("pcapng_read_if_descr_block: if_tsresol %u, units/s %" G_GINT64_MODIFIER "u, tsprecision %d", if_tsresol, if_descr_mand->time_units_per_second, tsprecision);
904 pcapng_debug("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length);
908 * if_tzone 10 Time zone for GMT support (TODO: specify better). TODO: give a good example
910 case(OPT_IDB_FILTER): /* if_filter */
911 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
912 wtapng_if_descr_filter_t if_filter;
913 memset(&if_filter, 0, sizeof(if_filter));
915 /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
918 if (option_content[0] == 0) {
919 if_filter.if_filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
920 pcapng_debug("pcapng_read_if_descr_block: if_filter_str %s oh.option_length %u", if_filter.if_filter_str, oh.option_length);
921 } else if (option_content[0] == 1) {
922 if_filter.bpf_filter_len = oh.option_length-1;
923 if_filter.if_filter_bpf_bytes = (guint8 *)option_content+1;
925 /* Fails with multiple options; we silently ignore the failure */
926 wtap_block_add_custom_option(wblock->block, oh.option_code, &if_filter, sizeof if_filter);
927 g_free(if_filter.if_filter_str);
929 pcapng_debug("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
932 case(OPT_IDB_OS): /* if_os */
934 * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
935 * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
936 * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
938 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
939 tmp_content = g_strndup((char *)option_content, oh.option_length);
940 /* Fails with multiple options; we silently ignore the failure */
941 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
942 pcapng_debug("pcapng_read_if_descr_block: if_os %s", tmp_content);
945 pcapng_debug("pcapng_read_if_descr_block: if_os length %u seems strange", oh.option_length);
948 case(OPT_IDB_FCSLEN): /* if_fcslen */
949 if (oh.option_length == 1) {
950 /* Fails with multiple options; we silently ignore the failure */
951 wtap_block_add_uint8_option(wblock->block, oh.option_code, option_content[0]);
952 pn->if_fcslen = option_content[0];
953 pcapng_debug("pcapng_read_if_descr_block: if_fcslen %u", pn->if_fcslen);
954 /* XXX - add sanity check */
956 pcapng_debug("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
959 case(OPT_IDB_HARDWARE): /* if_hardware */
960 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
961 tmp_content = g_strndup((char *)option_content, oh.option_length);
962 /* Fails with multiple options; we silently ignore the failure */
963 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
964 pcapng_debug("pcapng_read_if_descr_block: if_hardware %s", tmp_content);
967 pcapng_debug("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
971 /* TODO: process these! */
972 case(OPT_IDB_IP4ADDR):
974 * Interface network address and netmask. This option can be
975 * repeated multiple times within the same Interface
976 * Description Block when multiple IPv4 addresses are assigned
977 * to the interface. 192 168 1 1 255 255 255 0
979 case(OPT_IDB_IP6ADDR):
981 * Interface network address and prefix length (stored in the
982 * last byte). This option can be repeated multiple times
983 * within the same Interface Description Block when multiple
984 * IPv6 addresses are assigned to the interface.
985 * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
986 * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
989 case(OPT_IDB_MACADDR):
991 * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
993 case(OPT_IDB_EUIADDR):
995 * Interface Hardware EUI address (64 bits), if available.
996 * TODO: give a good example
1000 * Time zone for GMT support. TODO: specify better.
1001 * TODO: give a good example.
1003 case(OPT_IDB_TSOFFSET):
1005 * A 64 bits integer value that specifies an offset (in
1006 * seconds) that must be added to the timestamp of each packet
1007 * to obtain the absolute timestamp of a packet. If the option
1008 * is missing, the timestamps stored in the packet must be
1009 * considered absolute timestamps. The time zone of the offset
1010 * can be specified with the option if_tzone.
1012 * TODO: won't a if_tsoffset_low for fractional second offsets
1013 * be useful for highly synchronized capture systems? 1234
1016 pcapng_debug("pcapng_read_if_descr_block: unknown option %u - ignoring %u bytes",
1017 oh.option_code, oh.option_length);
1021 g_free(option_content);
1024 * If the per-file encapsulation isn't known, set it to this
1025 * interface's encapsulation.
1027 * If it *is* known, and it isn't this interface's encapsulation,
1028 * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
1029 * have a single encapsulation for all interfaces in the file,
1030 * so it probably doesn't have a single encapsulation for all
1031 * packets in the file.
1033 if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
1034 wth->file_encap = if_descr_mand->wtap_encap;
1036 if (wth->file_encap != if_descr_mand->wtap_encap) {
1037 wth->file_encap = WTAP_ENCAP_PER_PACKET;
1042 * The same applies to the per-file time stamp resolution.
1044 if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
1045 wth->file_tsprec = if_descr_mand->tsprecision;
1047 if (wth->file_tsprec != if_descr_mand->tsprecision) {
1048 wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
1053 * We don't return these to the caller in pcapng_read().
1055 wblock->internal = TRUE;
1062 pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info, gboolean enhanced)
1066 guint to_read, opt_cont_buf_len;
1067 pcapng_enhanced_packet_block_t epb;
1068 pcapng_packet_block_t pb;
1069 wtapng_packet_t packet;
1070 guint32 block_total_length;
1072 interface_info_t iface_info;
1075 pcapng_option_header_t *oh;
1076 guint8 *option_content;
1077 int pseudo_header_len;
1080 option_handler *handler;
1083 /* "(Enhanced) Packet Block" read fixed part */
1086 * Is this block long enough to be an EPB?
1088 if (bh->block_total_length < MIN_EPB_SIZE) {
1092 *err = WTAP_ERR_BAD_FILE;
1093 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of an EPB is less than the minimum EPB size %u",
1094 bh->block_total_length, MIN_EPB_SIZE);
1097 if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
1098 pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1101 block_read = (guint)sizeof epb;
1103 if (pn->byte_swapped) {
1104 packet.interface_id = GUINT32_SWAP_LE_BE(epb.interface_id);
1105 packet.drops_count = -1; /* invalid */
1106 packet.ts_high = GUINT32_SWAP_LE_BE(epb.timestamp_high);
1107 packet.ts_low = GUINT32_SWAP_LE_BE(epb.timestamp_low);
1108 packet.cap_len = GUINT32_SWAP_LE_BE(epb.captured_len);
1109 packet.packet_len = GUINT32_SWAP_LE_BE(epb.packet_len);
1111 packet.interface_id = epb.interface_id;
1112 packet.drops_count = -1; /* invalid */
1113 packet.ts_high = epb.timestamp_high;
1114 packet.ts_low = epb.timestamp_low;
1115 packet.cap_len = epb.captured_len;
1116 packet.packet_len = epb.packet_len;
1118 pcapng_debug("pcapng_read_packet_block: EPB on interface_id %d, cap_len %d, packet_len %d",
1119 packet.interface_id, packet.cap_len, packet.packet_len);
1122 * Is this block long enough to be a PB?
1124 if (bh->block_total_length < MIN_PB_SIZE) {
1128 *err = WTAP_ERR_BAD_FILE;
1129 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of a PB is less than the minimum PB size %u",
1130 bh->block_total_length, MIN_PB_SIZE);
1133 if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
1134 pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1137 block_read = (guint)sizeof pb;
1139 if (pn->byte_swapped) {
1140 packet.interface_id = GUINT16_SWAP_LE_BE(pb.interface_id);
1141 packet.drops_count = GUINT16_SWAP_LE_BE(pb.drops_count);
1142 packet.ts_high = GUINT32_SWAP_LE_BE(pb.timestamp_high);
1143 packet.ts_low = GUINT32_SWAP_LE_BE(pb.timestamp_low);
1144 packet.cap_len = GUINT32_SWAP_LE_BE(pb.captured_len);
1145 packet.packet_len = GUINT32_SWAP_LE_BE(pb.packet_len);
1147 packet.interface_id = pb.interface_id;
1148 packet.drops_count = pb.drops_count;
1149 packet.ts_high = pb.timestamp_high;
1150 packet.ts_low = pb.timestamp_low;
1151 packet.cap_len = pb.captured_len;
1152 packet.packet_len = pb.packet_len;
1154 pcapng_debug("pcapng_read_packet_block: PB on interface_id %d, cap_len %d, packet_len %d",
1155 packet.interface_id, packet.cap_len, packet.packet_len);
1159 * How much padding is there at the end of the packet data?
1161 if ((packet.cap_len % 4) != 0)
1162 padding = 4 - (packet.cap_len % 4);
1166 /* add padding bytes to "block total length" */
1167 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1168 if (bh->block_total_length % 4) {
1169 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1171 block_total_length = bh->block_total_length;
1173 pcapng_debug("pcapng_read_packet_block: block_total_length %d", block_total_length);
1176 * Is this block long enough to hold the packet data?
1179 if (block_total_length <
1180 MIN_EPB_SIZE + packet.cap_len + padding) {
1184 *err = WTAP_ERR_BAD_FILE;
1185 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of EPB is too small for %u bytes of packet data",
1186 block_total_length, packet.cap_len);
1190 if (block_total_length <
1191 MIN_PB_SIZE + packet.cap_len + padding) {
1195 *err = WTAP_ERR_BAD_FILE;
1196 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of PB is too small for %u bytes of packet data",
1197 block_total_length, packet.cap_len);
1202 pcapng_debug("pcapng_read_packet_block: packet data: packet_len %u captured_len %u interface_id %u",
1205 packet.interface_id);
1207 if (packet.interface_id >= pn->interfaces->len) {
1208 *err = WTAP_ERR_BAD_FILE;
1209 *err_info = g_strdup_printf("pcapng_read_packet_block: interface index %u is not less than interface count %u",
1210 packet.interface_id, pn->interfaces->len);
1213 iface_info = g_array_index(pn->interfaces, interface_info_t,
1214 packet.interface_id);
1216 if (packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
1217 *err = WTAP_ERR_BAD_FILE;
1218 *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than %u",
1220 wtap_max_snaplen_for_encap(iface_info.wtap_encap));
1224 wblock->rec->rec_type = REC_TYPE_PACKET;
1225 wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1227 pcapng_debug("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.",
1228 iface_info.wtap_encap,
1229 wtap_encap_string(iface_info.wtap_encap),
1230 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
1231 wblock->rec->rec_header.packet_header.interface_id = packet.interface_id;
1232 wblock->rec->rec_header.packet_header.pkt_encap = iface_info.wtap_encap;
1233 wblock->rec->tsprec = iface_info.tsprecision;
1235 memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
1236 pseudo_header_len = pcap_process_pseudo_header(fh,
1237 WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1238 iface_info.wtap_encap,
1243 if (pseudo_header_len < 0) {
1246 block_read += pseudo_header_len;
1247 wblock->rec->rec_header.packet_header.caplen = packet.cap_len - pseudo_header_len;
1248 wblock->rec->rec_header.packet_header.len = packet.packet_len - pseudo_header_len;
1250 /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
1251 ts = (((guint64)packet.ts_high) << 32) | ((guint64)packet.ts_low);
1252 wblock->rec->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
1253 wblock->rec->ts.nsecs = (int)(((ts % iface_info.time_units_per_second) * 1000000000) / iface_info.time_units_per_second);
1255 /* "(Enhanced) Packet Block" read capture data */
1256 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1257 packet.cap_len - pseudo_header_len, err, err_info))
1259 block_read += packet.cap_len - pseudo_header_len;
1261 /* jump over potential padding bytes at end of the packet data */
1263 if (!wtap_read_bytes(fh, NULL, padding, err, err_info))
1265 block_read += padding;
1268 /* Option defaults */
1269 wblock->rec->opt_comment = NULL;
1270 wblock->rec->rec_header.packet_header.drop_count = -1;
1271 wblock->rec->rec_header.packet_header.pack_flags = 0;
1273 /* FCS length default */
1274 fcslen = pn->if_fcslen;
1282 to_read = block_total_length -
1283 (int)sizeof(pcapng_block_header_t) -
1284 block_read - /* fixed and variable part, including padding */
1285 (int)sizeof(bh->block_total_length);
1287 /* Allocate enough memory to hold all options */
1288 opt_cont_buf_len = to_read;
1289 ws_buffer_assure_space(&wblock->rec->options_buf, opt_cont_buf_len);
1290 opt_ptr = ws_buffer_start_ptr(&wblock->rec->options_buf);
1292 while (to_read != 0) {
1294 oh = (pcapng_option_header_t *)(void *)opt_ptr;
1295 option_content = opt_ptr + sizeof (pcapng_option_header_t);
1296 bytes_read = pcapng_read_option(fh, pn, oh, option_content, opt_cont_buf_len, to_read, err, err_info, "packet");
1297 if (bytes_read <= 0) {
1298 pcapng_debug("pcapng_read_packet_block: failed to read option");
1299 /* XXX - free anything? */
1302 to_read -= bytes_read;
1304 /* handle option content */
1305 switch (oh->option_code) {
1308 pcapng_debug("pcapng_read_packet_block: %u bytes after opt_endofopt", to_read);
1310 /* padding should be ok here, just get out of this */
1314 if (oh->option_length > 0 && oh->option_length < opt_cont_buf_len) {
1315 wblock->rec->presence_flags |= WTAP_HAS_COMMENTS;
1316 wblock->rec->opt_comment = g_strndup((char *)option_content, oh->option_length);
1317 pcapng_debug("pcapng_read_packet_block: length %u opt_comment '%s'", oh->option_length, wblock->rec->opt_comment);
1319 pcapng_debug("pcapng_read_packet_block: opt_comment length %u seems strange", oh->option_length);
1322 case(OPT_EPB_FLAGS):
1323 if (oh->option_length != 4) {
1324 *err = WTAP_ERR_BAD_FILE;
1325 *err_info = g_strdup_printf("pcapng_read_packet_block: packet block flags option length %u is not 4",
1327 /* XXX - free anything? */
1330 /* Don't cast a guint8 * into a guint32 *--the
1331 * guint8 * may not point to something that's
1332 * aligned correctly.
1334 wblock->rec->presence_flags |= WTAP_HAS_PACK_FLAGS;
1335 memcpy(&wblock->rec->rec_header.packet_header.pack_flags, option_content, sizeof(guint32));
1336 if (pn->byte_swapped) {
1337 wblock->rec->rec_header.packet_header.pack_flags = GUINT32_SWAP_LE_BE(wblock->rec->rec_header.packet_header.pack_flags);
1338 memcpy(option_content, &wblock->rec->rec_header.packet_header.pack_flags, sizeof(guint32));
1340 if (wblock->rec->rec_header.packet_header.pack_flags & 0x000001E0) {
1341 /* The FCS length is present */
1342 fcslen = (wblock->rec->rec_header.packet_header.pack_flags & 0x000001E0) >> 5;
1344 pcapng_debug("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->rec->rec_header.packet_header.pack_flags);
1347 pcapng_debug("pcapng_read_packet_block: epb_hash %u currently not handled - ignoring %u bytes",
1348 oh->option_code, oh->option_length);
1350 case(OPT_EPB_DROPCOUNT):
1351 if (oh->option_length != 8) {
1352 *err = WTAP_ERR_BAD_FILE;
1353 *err_info = g_strdup_printf("pcapng_read_packet_block: packet block drop count option length %u is not 8",
1355 /* XXX - free anything? */
1358 /* Don't cast a guint8 * into a guint64 *--the
1359 * guint8 * may not point to something that's
1360 * aligned correctly.
1362 wblock->rec->presence_flags |= WTAP_HAS_DROP_COUNT;
1363 memcpy(&wblock->rec->rec_header.packet_header.drop_count, option_content, sizeof(guint64));
1364 if (pn->byte_swapped) {
1365 wblock->rec->rec_header.packet_header.drop_count = GUINT64_SWAP_LE_BE(wblock->rec->rec_header.packet_header.drop_count);
1366 memcpy(option_content, &wblock->rec->rec_header.packet_header.drop_count, sizeof(guint64));
1369 pcapng_debug("pcapng_read_packet_block: drop_count %" G_GINT64_MODIFIER "u", wblock->rec->rec_header.packet_header.drop_count);
1374 * Do we have a handler for this packet block option code?
1376 if (option_handlers[BT_INDEX_PBS] != NULL &&
1377 (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_PBS],
1378 GUINT_TO_POINTER((guint)oh->option_code))) != NULL) {
1379 /* Yes - call the handler. */
1380 if (!handler->hfunc(pn->byte_swapped, oh->option_length,
1381 option_content, err, err_info))
1382 /* XXX - free anything? */
1387 pcapng_debug("pcapng_read_packet_block: unknown option %u - ignoring %u bytes",
1388 oh->option_code, oh->option_length);
1393 pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1394 wblock->rec, ws_buffer_start_ptr(wblock->frame_buffer),
1395 pn->byte_swapped, fcslen);
1398 * We return these to the caller in pcapng_read().
1400 wblock->internal = FALSE;
1407 pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
1409 interface_info_t iface_info;
1410 pcapng_simple_packet_block_t spb;
1411 wtapng_simple_packet_t simple_packet;
1412 guint32 block_total_length;
1414 int pseudo_header_len;
1417 * Is this block long enough to be an SPB?
1419 if (bh->block_total_length < MIN_SPB_SIZE) {
1423 *err = WTAP_ERR_BAD_FILE;
1424 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u of an SPB is less than the minimum SPB size %u",
1425 bh->block_total_length, MIN_SPB_SIZE);
1429 /* "Simple Packet Block" read fixed part */
1430 if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
1431 pcapng_debug("pcapng_read_simple_packet_block: failed to read packet data");
1435 if (0 >= pn->interfaces->len) {
1436 *err = WTAP_ERR_BAD_FILE;
1437 *err_info = g_strdup("pcapng_read_simple_packet_block: SPB appeared before any IDBs");
1440 iface_info = g_array_index(pn->interfaces, interface_info_t, 0);
1442 if (pn->byte_swapped) {
1443 simple_packet.packet_len = GUINT32_SWAP_LE_BE(spb.packet_len);
1445 simple_packet.packet_len = spb.packet_len;
1449 * The captured length is not a field in the SPB; it can be
1450 * calculated as the minimum of the snapshot length from the
1451 * IDB and the packet length, as per the pcapng spec. An IDB
1452 * snapshot length of 0 means no limit.
1454 simple_packet.cap_len = simple_packet.packet_len;
1455 if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
1456 simple_packet.cap_len = iface_info.snap_len;
1459 * How much padding is there at the end of the packet data?
1461 if ((simple_packet.cap_len % 4) != 0)
1462 padding = 4 - (simple_packet.cap_len % 4);
1466 /* add padding bytes to "block total length" */
1467 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1468 if (bh->block_total_length % 4) {
1469 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1471 block_total_length = bh->block_total_length;
1473 pcapng_debug("pcapng_read_simple_packet_block: block_total_length %d", block_total_length);
1476 * Is this block long enough to hold the packet data?
1478 if (block_total_length < MIN_SPB_SIZE + simple_packet.cap_len + padding) {
1480 * No. That means that the problem is with the packet
1481 * length; the snapshot length can be bigger than the amount
1482 * of packet data in the block, as it's a *maximum* length,
1483 * not a *minimum* length.
1485 *err = WTAP_ERR_BAD_FILE;
1486 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u of PB is too small for %u bytes of packet data",
1487 block_total_length, simple_packet.packet_len);
1491 if (simple_packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
1492 *err = WTAP_ERR_BAD_FILE;
1493 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: cap_len %u is larger than %u",
1494 simple_packet.cap_len,
1495 wtap_max_snaplen_for_encap(iface_info.wtap_encap));
1498 pcapng_debug("pcapng_read_simple_packet_block: packet data: packet_len %u",
1499 simple_packet.packet_len);
1501 pcapng_debug("pcapng_read_simple_packet_block: Need to read pseudo header of size %d",
1502 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
1504 /* No time stamp in a simple packet block; no options, either */
1505 wblock->rec->rec_type = REC_TYPE_PACKET;
1506 wblock->rec->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1507 wblock->rec->rec_header.packet_header.interface_id = 0;
1508 wblock->rec->rec_header.packet_header.pkt_encap = iface_info.wtap_encap;
1509 wblock->rec->tsprec = iface_info.tsprecision;
1510 wblock->rec->ts.secs = 0;
1511 wblock->rec->ts.nsecs = 0;
1512 wblock->rec->rec_header.packet_header.interface_id = 0;
1513 wblock->rec->opt_comment = NULL;
1514 wblock->rec->rec_header.packet_header.drop_count = 0;
1515 wblock->rec->rec_header.packet_header.pack_flags = 0;
1517 memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
1518 pseudo_header_len = pcap_process_pseudo_header(fh,
1519 WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1520 iface_info.wtap_encap,
1521 simple_packet.cap_len,
1525 if (pseudo_header_len < 0) {
1528 wblock->rec->rec_header.packet_header.caplen = simple_packet.cap_len - pseudo_header_len;
1529 wblock->rec->rec_header.packet_header.len = simple_packet.packet_len - pseudo_header_len;
1531 memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
1533 /* "Simple Packet Block" read capture data */
1534 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1535 simple_packet.cap_len, err, err_info))
1538 /* jump over potential padding bytes at end of the packet data */
1539 if ((simple_packet.cap_len % 4) != 0) {
1540 if (!wtap_read_bytes(fh, NULL, 4 - (simple_packet.cap_len % 4), err, err_info))
1544 pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1545 wblock->rec, ws_buffer_start_ptr(wblock->frame_buffer),
1546 pn->byte_swapped, pn->if_fcslen);
1549 * We return these to the caller in pcapng_read().
1551 wblock->internal = FALSE;
1556 #define NRES_ENDOFRECORD 0
1557 #define NRES_IP4RECORD 1
1558 #define NRES_IP6RECORD 2
1559 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
1560 /* IPv6 + MAXNAMELEN */
1561 #define INITIAL_NRB_REC_SIZE (16 + 64)
1564 * Find the end of the NUL-terminated name the beginning of which is pointed
1565 * to by p; record_len is the number of bytes remaining in the record.
1567 * Return the length of the name, including the terminating NUL.
1569 * If we don't find a terminating NUL, return -1 and set *err and
1570 * *err_info appropriately.
1573 name_resolution_block_find_name_end(const char *p, guint record_len, int *err,
1580 if (record_len == 0) {
1582 * We ran out of bytes in the record without
1585 *err = WTAP_ERR_BAD_FILE;
1586 *err_info = g_strdup("pcapng_read_name_resolution_block: NRB record has non-null-terminated host name");
1590 break; /* that's the terminating NUL */
1593 namelen++; /* count this byte */
1596 /* Include the NUL in the name length. */
1601 pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
1605 pcapng_name_resolution_block_t nrb;
1608 guint record_len, opt_cont_buf_len;
1612 pcapng_option_header_t oh;
1613 guint8 *option_content;
1615 option_handler *handler;
1620 * Is this block long enough to be an NRB?
1622 if (bh->block_total_length < MIN_NRB_SIZE) {
1626 *err = WTAP_ERR_BAD_FILE;
1627 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: total block length %u of an NRB is less than the minimum NRB size %u",
1628 bh->block_total_length, MIN_NRB_SIZE);
1632 to_read = bh->block_total_length - 8 - 4; /* We have read the header and should not read the final block_total_length */
1634 pcapng_debug("pcapng_read_name_resolution_block, total %d bytes", bh->block_total_length);
1636 /* Ensure we have a name resolution block */
1637 if (wblock->block == NULL) {
1638 wblock->block = wtap_block_create(WTAP_BLOCK_NG_NRB);
1642 * Start out with a buffer big enough for an IPv6 address and one
1643 * 64-byte name; we'll make the buffer bigger if necessary.
1645 ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
1647 while (block_read < to_read) {
1649 * There must be at least one record's worth of data
1652 if ((size_t)(to_read - block_read) < sizeof nrb) {
1653 ws_buffer_free(&nrb_rec);
1654 *err = WTAP_ERR_BAD_FILE;
1655 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record header size %u",
1656 to_read - block_read,
1660 if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
1661 ws_buffer_free(&nrb_rec);
1662 pcapng_debug("pcapng_read_name_resolution_block: failed to read record header");
1665 block_read += (int)sizeof nrb;
1667 if (pn->byte_swapped) {
1668 nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type);
1669 nrb.record_len = GUINT16_SWAP_LE_BE(nrb.record_len);
1672 if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
1673 ws_buffer_free(&nrb_rec);
1674 *err = WTAP_ERR_BAD_FILE;
1675 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record length + padding %u",
1676 to_read - block_read,
1677 nrb.record_len + PADDING4(nrb.record_len));
1680 switch (nrb.record_type) {
1681 case NRES_ENDOFRECORD:
1682 /* There shouldn't be any more data - but there MAY be options */
1685 case NRES_IP4RECORD:
1687 * The smallest possible record must have
1688 * a 4-byte IPv4 address, hence a minimum
1691 * (The pcapng spec really indicates
1692 * that it must be at least 5 bytes,
1693 * as there must be at least one name,
1694 * and it really must be at least 6
1695 * bytes, as the name mustn't be null,
1696 * but there's no need to fail if there
1697 * aren't any names at all, and we
1698 * should report a null name as such.)
1700 if (nrb.record_len < 4) {
1701 ws_buffer_free(&nrb_rec);
1702 *err = WTAP_ERR_BAD_FILE;
1703 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv4 record %u < minimum length 4",
1707 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1708 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1709 nrb.record_len, err, err_info)) {
1710 ws_buffer_free(&nrb_rec);
1711 pcapng_debug("pcapng_read_name_resolution_block: failed to read IPv4 record data");
1714 block_read += nrb.record_len;
1716 if (pn->add_new_ipv4) {
1718 * Scan through all the names in
1719 * the record and add them.
1722 ws_buffer_start_ptr(&nrb_rec), 4);
1723 /* IPv4 address is in big-endian order in the file always, which is how we store
1724 it internally as well, so don't byte-swap it */
1725 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
1727 namep += namelen, record_len -= namelen) {
1729 * Scan forward for a null
1732 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1733 if (namelen == -1) {
1734 ws_buffer_free(&nrb_rec);
1735 return FALSE; /* fail */
1737 pn->add_new_ipv4(v4_addr, namep);
1741 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
1742 ws_buffer_free(&nrb_rec);
1745 block_read += PADDING4(nrb.record_len);
1747 case NRES_IP6RECORD:
1749 * The smallest possible record must have
1750 * a 16-byte IPv6 address, hence a minimum
1753 * (The pcapng spec really indicates
1754 * that it must be at least 17 bytes,
1755 * as there must be at least one name,
1756 * and it really must be at least 18
1757 * bytes, as the name mustn't be null,
1758 * but there's no need to fail if there
1759 * aren't any names at all, and we
1760 * should report a null name as such.)
1762 if (nrb.record_len < 16) {
1763 ws_buffer_free(&nrb_rec);
1764 *err = WTAP_ERR_BAD_FILE;
1765 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u < minimum length 16",
1769 if (to_read < nrb.record_len) {
1770 ws_buffer_free(&nrb_rec);
1771 *err = WTAP_ERR_BAD_FILE;
1772 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u > remaining data in NRB",
1776 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1777 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1778 nrb.record_len, err, err_info)) {
1779 ws_buffer_free(&nrb_rec);
1782 block_read += nrb.record_len;
1784 if (pn->add_new_ipv6) {
1785 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
1787 namep += namelen, record_len -= namelen) {
1789 * Scan forward for a null
1792 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1793 if (namelen == -1) {
1794 ws_buffer_free(&nrb_rec);
1795 return FALSE; /* fail */
1797 pn->add_new_ipv6(ws_buffer_start_ptr(&nrb_rec),
1802 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
1803 ws_buffer_free(&nrb_rec);
1806 block_read += PADDING4(nrb.record_len);
1809 pcapng_debug("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
1810 if (!wtap_read_bytes(fh, NULL, nrb.record_len + PADDING4(nrb.record_len), err, err_info)) {
1811 ws_buffer_free(&nrb_rec);
1814 block_read += nrb.record_len + PADDING4(nrb.record_len);
1821 to_read -= block_read;
1832 /* Allocate enough memory to hold all options */
1833 opt_cont_buf_len = to_read;
1834 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1835 if (opt_cont_buf_len != 0 && option_content == NULL) {
1836 *err = ENOMEM; /* we assume we're out of memory */
1837 ws_buffer_free(&nrb_rec);
1841 while (to_read != 0) {
1843 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "name_resolution");
1844 if (bytes_read <= 0) {
1845 pcapng_debug("pcapng_read_name_resolution_block: failed to read option");
1846 g_free(option_content);
1847 ws_buffer_free(&nrb_rec);
1850 to_read -= bytes_read;
1852 /* handle option content */
1853 switch (oh.option_code) {
1856 pcapng_debug("pcapng_read_name_resolution_block: %u bytes after opt_endofopt", to_read);
1858 /* padding should be ok here, just get out of this */
1862 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1863 tmp_content = g_strndup((char *)option_content, oh.option_length);
1864 wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1865 pcapng_debug("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, tmp_content);
1866 g_free(tmp_content);
1868 pcapng_debug("pcapng_read_name_resolution_block: opt_comment length %u seems strange", oh.option_length);
1874 * Do we have a handler for this network resolution block option code?
1876 if (option_handlers[BT_INDEX_NRB] != NULL &&
1877 (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_NRB],
1878 GUINT_TO_POINTER((guint)oh.option_code))) != NULL) {
1879 /* Yes - call the handler. */
1880 if (!handler->hfunc(pn->byte_swapped, oh.option_length,
1881 option_content, err, err_info)) {
1883 g_free(option_content);
1884 ws_buffer_free(&nrb_rec);
1890 pcapng_debug("pcapng_read_name_resolution_block: unknown option %u - ignoring %u bytes",
1891 oh.option_code, oh.option_length);
1896 g_free(option_content);
1897 ws_buffer_free(&nrb_rec);
1900 * We don't return these to the caller in pcapng_read().
1902 wblock->internal = TRUE;
1908 pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock,int *err, gchar **err_info)
1911 guint to_read, opt_cont_buf_len;
1912 pcapng_interface_statistics_block_t isb;
1913 pcapng_option_header_t oh;
1914 guint8 *option_content = NULL; /* Allocate as large as the options block */
1915 wtapng_if_stats_mandatory_t* if_stats_mand;
1919 * Is this block long enough to be an ISB?
1921 if (bh->block_total_length < MIN_ISB_SIZE) {
1925 *err = WTAP_ERR_BAD_FILE;
1926 *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too small (< %u)",
1927 bh->block_total_length, MIN_ISB_SIZE);
1931 /* "Interface Statistics Block" read fixed part */
1932 if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
1933 pcapng_debug("pcapng_read_interface_statistics_block: failed to read packet data");
1937 wblock->block = wtap_block_create(WTAP_BLOCK_IF_STATS);
1938 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1939 if (pn->byte_swapped) {
1940 if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
1941 if_stats_mand->ts_high = GUINT32_SWAP_LE_BE(isb.timestamp_high);
1942 if_stats_mand->ts_low = GUINT32_SWAP_LE_BE(isb.timestamp_low);
1944 if_stats_mand->interface_id = isb.interface_id;
1945 if_stats_mand->ts_high = isb.timestamp_high;
1946 if_stats_mand->ts_low = isb.timestamp_low;
1948 pcapng_debug("pcapng_read_interface_statistics_block: interface_id %u", if_stats_mand->interface_id);
1951 to_read = bh->block_total_length -
1952 (MIN_BLOCK_SIZE + (guint)sizeof isb); /* fixed and variable part, including padding */
1954 /* Allocate enough memory to hold all options */
1955 opt_cont_buf_len = to_read;
1956 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1957 if (opt_cont_buf_len != 0 && option_content == NULL) {
1958 *err = ENOMEM; /* we assume we're out of memory */
1962 while (to_read != 0) {
1964 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "interface_statistics");
1965 if (bytes_read <= 0) {
1966 pcapng_debug("pcapng_read_interface_statistics_block: failed to read option");
1967 g_free(option_content);
1970 to_read -= bytes_read;
1972 /* handle option content */
1973 switch (oh.option_code) {
1974 case(OPT_EOFOPT): /* opt_endofopt */
1976 pcapng_debug("pcapng_read_interface_statistics_block: %u bytes after opt_endofopt", to_read);
1978 /* padding should be ok here, just get out of this */
1981 case(OPT_COMMENT): /* opt_comment */
1982 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1983 tmp_content = g_strndup((char *)option_content, oh.option_length);
1984 wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1985 pcapng_debug("pcapng_read_interface_statistics_block: opt_comment %s", tmp_content);
1986 g_free(tmp_content);
1988 pcapng_debug("pcapng_read_interface_statistics_block: opt_comment length %u seems strange", oh.option_length);
1991 case(OPT_ISB_STARTTIME): /* isb_starttime */
1992 if (oh.option_length == 8) {
1996 /* Don't cast a guint8 * into a guint32 *--the
1997 * guint8 * may not point to something that's
1998 * aligned correctly.
2000 memcpy(&high, option_content, sizeof(guint32));
2001 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
2002 if (pn->byte_swapped) {
2003 high = GUINT32_SWAP_LE_BE(high);
2004 low = GUINT32_SWAP_LE_BE(low);
2006 starttime = (guint64)high;
2008 starttime += (guint64)low;
2009 /* Fails with multiple options; we silently ignore the failure */
2010 wtap_block_add_uint64_option(wblock->block, OPT_ISB_STARTTIME, starttime);
2011 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime %" G_GINT64_MODIFIER "u", starttime);
2013 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2016 case(OPT_ISB_ENDTIME): /* isb_endtime */
2017 if (oh.option_length == 8) {
2021 /* Don't cast a guint8 * into a guint32 *--the
2022 * guint8 * may not point to something that's
2023 * aligned correctly.
2025 memcpy(&high, option_content, sizeof(guint32));
2026 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
2027 if (pn->byte_swapped) {
2028 high = GUINT32_SWAP_LE_BE(high);
2029 low = GUINT32_SWAP_LE_BE(low);
2031 endtime = (guint64)high;
2033 endtime += (guint64)low;
2034 /* Fails with multiple options; we silently ignore the failure */
2035 wtap_block_add_uint64_option(wblock->block, OPT_ISB_ENDTIME, endtime);
2036 pcapng_debug("pcapng_read_interface_statistics_block: isb_endtime %" G_GINT64_MODIFIER "u", endtime);
2038 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2041 case(OPT_ISB_IFRECV): /* isb_ifrecv */
2042 if (oh.option_length == 8) {
2044 /* Don't cast a guint8 * into a guint64 *--the
2045 * guint8 * may not point to something that's
2046 * aligned correctly.
2048 memcpy(&ifrecv, option_content, sizeof(guint64));
2049 if (pn->byte_swapped)
2050 ifrecv = GUINT64_SWAP_LE_BE(ifrecv);
2051 /* Fails with multiple options; we silently ignore the failure */
2052 wtap_block_add_uint64_option(wblock->block, OPT_ISB_IFRECV, ifrecv);
2053 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", ifrecv);
2055 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv length %u not 8 as expected", oh.option_length);
2058 case(OPT_ISB_IFDROP): /* isb_ifdrop */
2059 if (oh.option_length == 8) {
2061 /* Don't cast a guint8 * into a guint64 *--the
2062 * guint8 * may not point to something that's
2063 * aligned correctly.
2065 memcpy(&ifdrop, option_content, sizeof(guint64));
2066 if (pn->byte_swapped)
2067 ifdrop = GUINT64_SWAP_LE_BE(ifdrop);
2068 /* Fails with multiple options; we silently ignore the failure */
2069 wtap_block_add_uint64_option(wblock->block, OPT_ISB_IFDROP, ifdrop);
2070 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", ifdrop);
2072 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop length %u not 8 as expected", oh.option_length);
2075 case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
2076 if (oh.option_length == 8) {
2077 guint64 filteraccept;
2078 /* Don't cast a guint8 * into a guint64 *--the
2079 * guint8 * may not point to something that's
2080 * aligned correctly.
2082 memcpy(&filteraccept, option_content, sizeof(guint64));
2083 if (pn->byte_swapped)
2084 filteraccept = GUINT64_SWAP_LE_BE(filteraccept);
2085 /* Fails with multiple options; we silently ignore the failure */
2086 wtap_block_add_uint64_option(wblock->block, OPT_ISB_FILTERACCEPT, filteraccept);
2087 pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept %" G_GINT64_MODIFIER "u", filteraccept);
2089 pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept length %u not 8 as expected", oh.option_length);
2092 case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
2093 if (oh.option_length == 8) {
2095 /* Don't cast a guint8 * into a guint64 *--the
2096 * guint8 * may not point to something that's
2097 * aligned correctly.
2099 memcpy(&osdrop, option_content, sizeof(guint64));
2100 if (pn->byte_swapped)
2101 osdrop = GUINT64_SWAP_LE_BE(osdrop);
2102 /* Fails with multiple options; we silently ignore the failure */
2103 wtap_block_add_uint64_option(wblock->block, OPT_ISB_OSDROP, osdrop);
2104 pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop %" G_GINT64_MODIFIER "u", osdrop);
2106 pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop length %u not 8 as expected", oh.option_length);
2109 case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8 */
2110 if (oh.option_length == 8) {
2112 /* Don't cast a guint8 * into a guint64 *--the
2113 * guint8 * may not point to something that's
2114 * aligned correctly.
2116 memcpy(&usrdeliv, option_content, sizeof(guint64));
2117 if (pn->byte_swapped)
2118 usrdeliv = GUINT64_SWAP_LE_BE(usrdeliv);
2119 /* Fails with multiple options; we silently ignore the failure */
2120 wtap_block_add_uint64_option(wblock->block, OPT_ISB_USRDELIV, usrdeliv);
2121 pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv %" G_GINT64_MODIFIER "u", usrdeliv);
2123 pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv length %u not 8 as expected", oh.option_length);
2127 pcapng_debug("pcapng_read_interface_statistics_block: unknown option %u - ignoring %u bytes",
2128 oh.option_code, oh.option_length);
2132 g_free(option_content);
2135 * We don't return these to the caller in pcapng_read().
2137 wblock->internal = TRUE;
2143 pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
2145 unsigned block_read;
2146 guint32 block_total_length;
2154 if (bh->block_total_length < MIN_SYSDIG_EVENT_SIZE) {
2155 *err = WTAP_ERR_BAD_FILE;
2156 *err_info = g_strdup_printf("%s: total block length %u is too small (< %u)", G_STRFUNC,
2157 bh->block_total_length, MIN_SYSDIG_EVENT_SIZE);
2161 /* add padding bytes to "block total length" */
2162 /* (the "block total length" of some example files don't contain any padding bytes!) */
2163 if (bh->block_total_length % 4) {
2164 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2166 block_total_length = bh->block_total_length;
2169 pcapng_debug("pcapng_read_sysdig_event_block: block_total_length %u",
2170 bh->block_total_length);
2172 wblock->rec->rec_type = REC_TYPE_SYSCALL;
2173 wblock->rec->rec_header.syscall_header.record_type = BLOCK_TYPE_SYSDIG_EVENT;
2174 wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
2175 wblock->rec->tsprec = WTAP_TSPREC_NSEC;
2177 block_read = block_total_length;
2179 if (!wtap_read_bytes(fh, &cpu_id, sizeof cpu_id, err, err_info)) {
2180 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event cpu id");
2183 if (!wtap_read_bytes(fh, &wire_ts, sizeof wire_ts, err, err_info)) {
2184 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event timestamp");
2187 if (!wtap_read_bytes(fh, &thread_id, sizeof thread_id, err, err_info)) {
2188 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event thread id");
2191 if (!wtap_read_bytes(fh, &event_len, sizeof event_len, err, err_info)) {
2192 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event length");
2195 if (!wtap_read_bytes(fh, &event_type, sizeof event_type, err, err_info)) {
2196 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event type");
2200 block_read -= MIN_SYSDIG_EVENT_SIZE;
2201 wblock->rec->rec_header.syscall_header.byte_order = G_BYTE_ORDER;
2203 /* XXX Use Gxxx_FROM_LE macros instead? */
2204 if (pn->byte_swapped) {
2205 wblock->rec->rec_header.syscall_header.byte_order =
2206 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2211 wblock->rec->rec_header.syscall_header.cpu_id = GUINT16_SWAP_LE_BE(cpu_id);
2212 ts = GUINT64_SWAP_LE_BE(wire_ts);
2213 wblock->rec->rec_header.syscall_header.thread_id = GUINT64_SWAP_LE_BE(thread_id);
2214 wblock->rec->rec_header.syscall_header.event_len = GUINT32_SWAP_LE_BE(event_len);
2215 wblock->rec->rec_header.syscall_header.event_type = GUINT16_SWAP_LE_BE(event_type);
2217 wblock->rec->rec_header.syscall_header.cpu_id = cpu_id;
2219 wblock->rec->rec_header.syscall_header.thread_id = thread_id;
2220 wblock->rec->rec_header.syscall_header.event_len = event_len;
2221 wblock->rec->rec_header.syscall_header.event_type = event_type;
2224 wblock->rec->ts.secs = (time_t) (ts / 1000000000);
2225 wblock->rec->ts.nsecs = (int) (ts % 1000000000);
2227 wblock->rec->rec_header.syscall_header.event_filelen = block_read;
2229 /* "Sysdig Event Block" read event data */
2230 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2231 block_read, err, err_info))
2234 /* XXX Read comment? */
2237 * We return these to the caller in pcapng_read().
2239 wblock->internal = FALSE;
2245 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, gchar **err_info)
2247 guint32 entry_length;
2248 guint32 block_total_length;
2251 if (bh->block_total_length < MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE) {
2252 *err = WTAP_ERR_BAD_FILE;
2253 *err_info = g_strdup_printf("%s: total block length %u is too small (< %u)", G_STRFUNC,
2254 bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE);
2258 /* add padding bytes to "block total length" */
2259 /* (the "block total length" of some example files don't contain any padding bytes!) */
2260 if (bh->block_total_length % 4) {
2261 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2263 block_total_length = bh->block_total_length;
2266 pcapng_debug("%s: block_total_length %u", G_STRFUNC, bh->block_total_length);
2268 entry_length = block_total_length - MIN_BLOCK_SIZE;
2270 /* Includes padding bytes. */
2271 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2272 entry_length, err, err_info)) {
2275 ws_buffer_increase_length(wblock->frame_buffer, entry_length);
2277 /* We don't have memmem available everywhere, so we get to use strstr. */
2278 ws_buffer_append(wblock->frame_buffer, (guint8 * ) "", 1);
2280 gchar *buf_ptr = (gchar *) ws_buffer_start_ptr(wblock->frame_buffer);
2281 while (entry_length > 0 && buf_ptr[entry_length] == '\0') {
2285 if (entry_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE) {
2286 *err = WTAP_ERR_BAD_FILE;
2287 *err_info = g_strdup_printf("%s: entry length %u is too small (< %u)", G_STRFUNC,
2288 bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE);
2292 pcapng_debug("%s: entry_length %u", G_STRFUNC, entry_length);
2294 size_t rt_ts_len = strlen(SDJ__REALTIME_TIMESTAMP);
2295 char *ts_pos = strstr(buf_ptr, SDJ__REALTIME_TIMESTAMP);
2298 *err = WTAP_ERR_BAD_FILE;
2299 *err_info = g_strdup_printf("%s: no timestamp", G_STRFUNC);
2303 if (ts_pos+rt_ts_len >= (char *) buf_ptr+entry_length) {
2304 *err = WTAP_ERR_BAD_FILE;
2305 *err_info = g_strdup_printf("%s: timestamp past end of buffer", G_STRFUNC);
2310 rt_ts = strtoul(ts_pos+rt_ts_len, NULL, 10);
2312 *err = WTAP_ERR_BAD_FILE;
2313 *err_info = g_strdup_printf("%s: invalid timestamp", G_STRFUNC);
2317 wblock->rec->rec_type = REC_TYPE_FT_SPECIFIC_EVENT;
2318 wblock->rec->rec_header.ft_specific_header.record_type = BLOCK_TYPE_SYSTEMD_JOURNAL;
2319 wblock->rec->rec_header.ft_specific_header.record_len = entry_length;
2320 wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
2321 wblock->rec->tsprec = WTAP_TSPREC_USEC;
2323 wblock->rec->ts.secs = (time_t) rt_ts / 1000000;
2324 wblock->rec->ts.nsecs = (rt_ts % 1000000) * 1000;
2327 * We return these to the caller in pcapng_read().
2329 wblock->internal = FALSE;
2331 if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
2333 * Nothing (most notably an IDB) has set a file encap at this point.
2335 * XXX Should we set WTAP_ENCAP_SYSTEMD_JOURNAL if appropriate?
2337 wth->file_encap = WTAP_ENCAP_PER_PACKET;
2344 pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh,
2351 wtapng_block_t *wblock,
2352 int *err, gchar **err_info)
2355 guint32 block_total_length;
2357 block_handler *handler;
2360 if (bh->block_total_length < MIN_BLOCK_SIZE) {
2361 *err = WTAP_ERR_BAD_FILE;
2362 *err_info = g_strdup_printf("pcapng_read_unknown_block: total block length %u of an unknown block type is less than the minimum block size %u",
2363 bh->block_total_length, MIN_BLOCK_SIZE);
2367 /* add padding bytes to "block total length" */
2368 /* (the "block total length" of some example files don't contain any padding bytes!) */
2369 if (bh->block_total_length % 4) {
2370 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2372 block_total_length = bh->block_total_length;
2375 block_read = block_total_length - MIN_BLOCK_SIZE;
2379 * Do we have a handler for this block type?
2381 if (block_handlers != NULL &&
2382 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
2383 GUINT_TO_POINTER(bh->block_type))) != NULL) {
2384 /* Yes - call it to read this block type. */
2385 if (!handler->reader(fh, block_read, pn->byte_swapped, wblock,
2391 /* No. Skip over this unknown block. */
2392 if (!wtap_read_bytes(fh, NULL, block_read, err, err_info)) {
2397 * We're skipping this, so we won't return these to the caller
2400 wblock->internal = TRUE;
2407 static block_return_val
2408 pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
2410 block_return_val ret;
2411 pcapng_block_header_t bh;
2412 guint32 block_total_length;
2414 wblock->block = NULL;
2416 /* Try to read the (next) block header */
2417 if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
2418 pcapng_debug("pcapng_read_block: wtap_read_bytes_or_eof() failed, err = %d.", *err);
2419 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
2421 * Short read or EOF.
2423 * If we're reading this as part of an open,
2424 * the file is too short to be a pcapng file.
2426 * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
2427 * PCAPNG_BLOCK_ERROR the same, so we can just return
2428 * PCAPNG_BLOCK_NOT_SHB in both cases.
2430 return PCAPNG_BLOCK_NOT_SHB;
2432 return PCAPNG_BLOCK_ERROR;
2436 * SHBs have to be treated differently from other blocks, because
2437 * the byte order of the fields in the block can only be determined
2438 * by looking at the byte-order magic number inside the block, not
2439 * by using the byte order of the section to which it belongs, as
2440 * it is the block that *defines* the byte order of the section to
2443 if (bh.block_type == BLOCK_TYPE_SHB) {
2445 * BLOCK_TYPE_SHB has the same value regardless of byte order,
2446 * so we don't need to byte-swap it.
2448 * We *might* need to byte-swap the total length, but we
2449 * can't determine whether we do until we look inside the
2450 * block and find the byte-order magic number, so we rely
2451 * on pcapng_read_section_header_block() to do that and
2452 * to swap the total length (as it needs to get the total
2453 * length in the right byte order in order to read the
2456 wblock->type = bh.block_type;
2458 pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2460 ret = pcapng_read_section_header_block(fh, &bh, pn, wblock, err, err_info);
2461 if (ret != PCAPNG_BLOCK_OK) {
2465 if (pn->byte_swapped) {
2466 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
2467 bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length);
2470 wblock->type = bh.block_type;
2472 pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2474 if (!pn->shb_read) {
2476 * No SHB seen yet, so we're trying to read the first block
2477 * during an open, to see whether it's an SHB; if what we
2478 * read doesn't look like an SHB, this isn't a pcapng file.
2482 return PCAPNG_BLOCK_NOT_SHB;
2485 /* Don't try to allocate memory for a huge number of options, as
2486 that might fail and, even if it succeeds, it might not leave
2487 any address space or memory+backing store for anything else.
2489 We do that by imposing a maximum block size of MAX_BLOCK_SIZE. */
2490 if (bh.block_total_length > MAX_BLOCK_SIZE) {
2491 *err = WTAP_ERR_BAD_FILE;
2492 *err_info = g_strdup_printf("pcapng_read_block: total block length %u is too large (> %u)",
2493 bh.block_total_length, MAX_BLOCK_SIZE);
2494 return PCAPNG_BLOCK_ERROR;
2497 switch (bh.block_type) {
2498 case(BLOCK_TYPE_IDB):
2499 if (!pcapng_read_if_descr_block(wth, fh, &bh, pn, wblock, err, err_info))
2500 return PCAPNG_BLOCK_ERROR;
2502 case(BLOCK_TYPE_PB):
2503 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE))
2504 return PCAPNG_BLOCK_ERROR;
2506 case(BLOCK_TYPE_SPB):
2507 if (!pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info))
2508 return PCAPNG_BLOCK_ERROR;
2510 case(BLOCK_TYPE_EPB):
2511 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE))
2512 return PCAPNG_BLOCK_ERROR;
2514 case(BLOCK_TYPE_NRB):
2515 if (!pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info))
2516 return PCAPNG_BLOCK_ERROR;
2518 case(BLOCK_TYPE_ISB):
2519 if (!pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info))
2520 return PCAPNG_BLOCK_ERROR;
2522 case(BLOCK_TYPE_SYSDIG_EVENT):
2523 /* case(BLOCK_TYPE_SYSDIG_EVF): */
2524 if (!pcapng_read_sysdig_event_block(fh, &bh, pn, wblock, err, err_info))
2525 return PCAPNG_BLOCK_ERROR;
2527 case(BLOCK_TYPE_SYSTEMD_JOURNAL):
2528 if (!pcapng_read_systemd_journal_export_block(wth, fh, &bh, pn, wblock, err, err_info))
2529 return PCAPNG_BLOCK_ERROR;
2532 pcapng_debug("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
2533 if (!pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info))
2534 return PCAPNG_BLOCK_ERROR;
2539 /* sanity check: first and second block lengths must match */
2540 if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
2542 pcapng_debug("pcapng_check_block_trailer: couldn't read second block length");
2543 return PCAPNG_BLOCK_ERROR;
2546 if (pn->byte_swapped)
2547 block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
2549 if (block_total_length != bh.block_total_length) {
2550 *err = WTAP_ERR_BAD_FILE;
2551 *err_info = g_strdup_printf("pcapng_check_block_trailer: total block lengths (first %u and second %u) don't match",
2552 bh.block_total_length, block_total_length);
2553 return PCAPNG_BLOCK_ERROR;
2555 return PCAPNG_BLOCK_OK;
2558 /* Process an IDB that we've just read. The contents of wblock are copied as needed. */
2560 pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
2562 wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_DESCR);
2563 interface_info_t iface_info;
2564 wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data),
2565 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
2567 wtap_block_copy(int_data, wblock->block);
2569 /* XXX if_tsoffset; opt 14 A 64 bits integer value that specifies an offset (in seconds)...*/
2570 /* Interface statistics */
2571 if_descr_mand->num_stat_entries = 0;
2572 if_descr_mand->interface_statistics = NULL;
2574 g_array_append_val(wth->interface_data, int_data);
2576 iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
2577 iface_info.snap_len = wblock_if_descr_mand->snap_len;
2578 iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
2579 iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
2581 g_array_append_val(pcapng->interfaces, iface_info);
2584 /* classic wtap: open capture file */
2585 wtap_open_return_val
2586 pcapng_open(wtap *wth, int *err, gchar **err_info)
2589 wtapng_block_t wblock;
2591 pcapng_block_header_t bh;
2592 gint64 saved_offset;
2594 pn.shb_read = FALSE;
2595 /* we don't know the byte swapping of the file yet */
2596 pn.byte_swapped = FALSE;
2598 pn.version_major = -1;
2599 pn.version_minor = -1;
2600 pn.interfaces = NULL;
2602 /* we don't expect any packet blocks yet */
2603 wblock.frame_buffer = NULL;
2606 pcapng_debug("pcapng_open: opening file");
2607 /* read first block */
2608 switch (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info)) {
2610 case PCAPNG_BLOCK_OK:
2614 case PCAPNG_BLOCK_NOT_SHB:
2615 /* This doesn't look like an SHB, so this isn't a pcapng file. */
2616 wtap_block_free(wblock.block);
2620 return WTAP_OPEN_NOT_MINE;
2622 case PCAPNG_BLOCK_ERROR:
2623 /* An I/O error, or this probably *is* a pcapng file but not a valid one. */
2624 wtap_block_free(wblock.block);
2625 return WTAP_OPEN_ERROR;
2628 /* first block must be a "Section Header Block" */
2629 if (wblock.type != BLOCK_TYPE_SHB) {
2631 * XXX - check for damage from transferring a file
2632 * between Windows and UN*X as text rather than
2635 pcapng_debug("pcapng_open: first block type %u not SHB", wblock.type);
2636 wtap_block_free(wblock.block);
2637 return WTAP_OPEN_NOT_MINE;
2642 * At this point, we've decided this is a pcapng file, not
2643 * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
2646 wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0), wblock.block);
2647 wtap_block_free(wblock.block);
2648 wblock.block = NULL;
2650 wth->file_encap = WTAP_ENCAP_UNKNOWN;
2651 wth->snapshot_length = 0;
2652 wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
2653 pcapng = (pcapng_t *)g_malloc(sizeof(pcapng_t));
2654 wth->priv = (void *)pcapng;
2656 pcapng->interfaces = g_array_new(FALSE, FALSE, sizeof(interface_info_t));
2658 wth->subtype_read = pcapng_read;
2659 wth->subtype_seek_read = pcapng_seek_read;
2660 wth->subtype_close = pcapng_close;
2661 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
2663 /* Loop over all IDB:s that appear before any packets */
2665 /* peek at next block */
2666 /* Try to read the (next) block header */
2667 saved_offset = file_tell(wth->fh);
2668 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
2671 pcapng_debug("No more IDBs available...");
2674 pcapng_debug("pcapng_open: Check for more IDB:s, wtap_read_bytes_or_eof() failed, err = %d.", *err);
2675 return WTAP_OPEN_ERROR;
2678 /* go back to where we were */
2679 file_seek(wth->fh, saved_offset, SEEK_SET, err);
2681 if (pn.byte_swapped) {
2682 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
2685 pcapng_debug("pcapng_open: Check for more IDB:s block_type 0x%x", bh.block_type);
2687 if (bh.block_type != BLOCK_TYPE_IDB) {
2688 break; /* No more IDB:s */
2690 if (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2691 wtap_block_free(wblock.block);
2693 pcapng_debug("No more IDBs available...");
2696 pcapng_debug("pcapng_open: couldn't read IDB");
2697 return WTAP_OPEN_ERROR;
2700 pcapng_process_idb(wth, pcapng, &wblock);
2701 wtap_block_free(wblock.block);
2702 pcapng_debug("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i",
2703 wth->interface_data->len, wth->file_encap);
2705 return WTAP_OPEN_MINE;
2709 /* classic wtap: read packet */
2711 pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
2713 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2714 wtapng_block_t wblock;
2715 wtap_block_t wtapng_if_descr;
2716 wtap_block_t if_stats;
2717 wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
2718 wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
2720 wblock.frame_buffer = wth->rec_data;
2721 wblock.rec = &wth->rec;
2723 pcapng->add_new_ipv4 = wth->add_new_ipv4;
2724 pcapng->add_new_ipv6 = wth->add_new_ipv6;
2726 /* read next block */
2728 *data_offset = file_tell(wth->fh);
2729 pcapng_debug("pcapng_read: data_offset is %" G_GINT64_MODIFIER "d", *data_offset);
2730 if (pcapng_read_block(wth, wth->fh, pcapng, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2731 pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2732 pcapng_debug("pcapng_read: couldn't read packet block");
2733 wtap_block_free(wblock.block);
2737 if (!wblock.internal) {
2739 * This is a block type we return to the caller to process.
2745 * This is a block type we process internally, rather than
2746 * returning it for the caller to process.
2748 switch (wblock.type) {
2750 case(BLOCK_TYPE_SHB):
2751 pcapng_debug("pcapng_read: another section header block");
2752 g_array_append_val(wth->shb_hdrs, wblock.block);
2755 case(BLOCK_TYPE_IDB):
2756 /* A new interface */
2757 pcapng_debug("pcapng_read: block type BLOCK_TYPE_IDB");
2758 pcapng_process_idb(wth, pcapng, &wblock);
2759 wtap_block_free(wblock.block);
2762 case(BLOCK_TYPE_NRB):
2763 /* More name resolution entries */
2764 pcapng_debug("pcapng_read: block type BLOCK_TYPE_NRB");
2765 if (wth->nrb_hdrs == NULL) {
2766 wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
2768 g_array_append_val(wth->nrb_hdrs, wblock.block);
2771 case(BLOCK_TYPE_ISB):
2773 * Another interface statistics report
2775 * XXX - given that they're reports, we should be
2776 * supplying them in read calls, and displaying them
2777 * in the "packet" list, so you can see what the
2778 * statistics were *at the time when the report was
2781 * The statistics from the *last* ISB could be displayed
2782 * in the summary, but if there are packets after the
2783 * last ISB, that could be misleading.
2785 * If we only display them if that ISB has an isb_endtime
2786 * option, which *should* only appear when capturing ended
2787 * on that interface (so there should be no more packet
2788 * blocks or ISBs for that interface after that point,
2789 * that would be the best way of showing "summary"
2792 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB");
2793 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock.block);
2794 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
2795 pcapng_debug("pcapng_read: BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces", if_stats_mand_block->interface_id);
2797 /* Get the interface description */
2798 wtapng_if_descr = g_array_index(wth->interface_data, wtap_block_t, if_stats_mand_block->interface_id);
2799 wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
2800 if (wtapng_if_descr_mand->num_stat_entries == 0) {
2801 /* First ISB found, no previous entry */
2802 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
2803 wtapng_if_descr_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
2806 if_stats = wtap_block_create(WTAP_BLOCK_IF_STATS);
2807 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
2808 if_stats_mand->interface_id = if_stats_mand_block->interface_id;
2809 if_stats_mand->ts_high = if_stats_mand_block->ts_high;
2810 if_stats_mand->ts_low = if_stats_mand_block->ts_low;
2812 wtap_block_copy(if_stats, wblock.block);
2813 g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
2814 wtapng_if_descr_mand->num_stat_entries++;
2816 wtap_block_free(wblock.block);
2820 /* XXX - improve handling of "unknown" blocks */
2821 pcapng_debug("pcapng_read: Unknown block type 0x%08x", wblock.type);
2826 /*pcapng_debug("Read length: %u Packet length: %u", bytes_read, wth->rec.rec_header.packet_header.caplen);*/
2827 pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2833 /* classic wtap: seek to file position and read packet */
2835 pcapng_seek_read(wtap *wth, gint64 seek_off,
2836 wtap_rec *rec, Buffer *buf,
2837 int *err, gchar **err_info)
2839 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2840 wtapng_block_t wblock;
2843 /* seek to the right file position */
2844 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
2845 return FALSE; /* Seek error */
2847 pcapng_debug("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
2849 wblock.frame_buffer = buf;
2852 /* read the block */
2853 if (pcapng_read_block(wth, wth->random_fh, pcapng, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2854 pcapng_debug("pcapng_seek_read: couldn't read packet block (err=%d).",
2856 wtap_block_free(wblock.block);
2860 /* block must not be one we process internally rather than supplying */
2861 if (wblock.internal) {
2862 pcapng_debug("pcapng_seek_read: block type %u is not one we return",
2864 wtap_block_free(wblock.block);
2868 wtap_block_free(wblock.block);
2873 /* classic wtap: close capture file */
2875 pcapng_close(wtap *wth)
2877 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2879 pcapng_debug("pcapng_close: closing file");
2880 g_array_free(pcapng->interfaces, TRUE);
2883 typedef struct pcapng_block_size_t
2886 } pcapng_block_size_t;
2888 static guint32 pcapng_compute_option_string_size(char *str)
2890 guint32 size = 0, pad;
2892 size = (guint32)strlen(str) & 0xffff;
2894 pad = 4 - (size % 4);
2904 static void compute_shb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
2906 pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
2912 case OPT_SHB_HARDWARE:
2914 case OPT_SHB_USERAPPL:
2915 size = pcapng_compute_option_string_size(optval->stringval);
2918 /* Unknown options - size by datatype? */
2922 block_size->size += size;
2923 /* Add bytes for option header if option should be written */
2925 /* Add optional padding to 32 bits */
2926 if ((block_size->size & 0x03) != 0)
2928 block_size->size += 4 - (block_size->size & 0x03);
2930 block_size->size += 4;
2934 typedef struct pcapng_write_block_t
2940 pcapng_write_block_t;
2942 static gboolean pcapng_write_option_string(wtap_dumper *wdh, guint option_id, char *str, int *err)
2944 struct pcapng_option_header option_hdr;
2945 guint32 size = (guint32)strlen(str) & 0xffff;
2946 const guint32 zero_pad = 0;
2952 /* String options don't consider pad bytes part of the length */
2953 option_hdr.type = (guint16)option_id;
2954 option_hdr.value_length = (guint16)size;
2955 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2957 wdh->bytes_dumped += 4;
2959 if (!wtap_dump_file_write(wdh, str, size, err))
2961 wdh->bytes_dumped += size;
2964 pad = 4 - (size % 4);
2969 /* write padding (if any) */
2971 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
2974 wdh->bytes_dumped += pad;
2980 static void write_wtap_shb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
2982 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
2984 /* Don't continue if there has been an error */
2985 if (!write_block->success)
2991 case OPT_SHB_HARDWARE:
2993 case OPT_SHB_USERAPPL:
2994 if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
2995 write_block->success = FALSE;
3000 /* Unknown options - write by datatype? */
3005 /* Write a section header block.
3006 * If we don't have a section block header already, create a default
3007 * one with no options.
3010 pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
3012 pcapng_block_header_t bh;
3013 pcapng_section_header_block_t shb;
3014 pcapng_block_size_t block_size;
3015 struct pcapng_option_header option_hdr;
3016 wtap_block_t wdh_shb = NULL;
3018 if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
3019 wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0);
3022 block_size.size = 0;
3023 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + 4);
3025 pcapng_debug("pcapng_write_section_header_block: Have shb_hdr");
3027 /* Compute block size */
3028 wtap_block_foreach_option(wdh_shb, compute_shb_option_size, &block_size);
3030 if (block_size.size > 0) {
3031 /* End-of-options tag */
3032 block_size.size += 4;
3035 bh.block_total_length += block_size.size;
3038 pcapng_debug("pcapng_write_section_header_block: Total len %u", bh.block_total_length);
3040 /* write block header */
3041 bh.block_type = BLOCK_TYPE_SHB;
3043 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3045 wdh->bytes_dumped += sizeof bh;
3047 /* write block fixed content */
3048 shb.magic = 0x1A2B3C4D;
3049 shb.version_major = 1;
3050 shb.version_minor = 0;
3052 wtapng_mandatory_section_t* section_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(wdh_shb);
3053 shb.section_length = section_data->section_length;
3055 shb.section_length = -1;
3058 if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
3060 wdh->bytes_dumped += sizeof shb;
3063 pcapng_write_block_t block_data;
3065 if (block_size.size > 0) {
3067 block_data.wdh = wdh;
3068 block_data.err = err;
3069 block_data.success = TRUE;
3070 wtap_block_foreach_option(wdh_shb, write_wtap_shb_option, &block_data);
3072 if (!block_data.success)
3075 /* Write end of options */
3076 option_hdr.type = OPT_EOFOPT;
3077 option_hdr.value_length = 0;
3078 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3080 wdh->bytes_dumped += 4;
3084 /* write block footer */
3085 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3086 sizeof bh.block_total_length, err))
3088 wdh->bytes_dumped += sizeof bh.block_total_length;
3094 pcapng_write_enhanced_packet_block(wtap_dumper *wdh, const wtap_rec *rec,
3095 const guint8 *pd, int *err)
3097 const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
3098 pcapng_block_header_t bh;
3099 pcapng_enhanced_packet_block_t epb;
3101 const guint32 zero_pad = 0;
3104 gboolean have_options = FALSE;
3105 guint32 options_total_length = 0;
3106 struct option option_hdr;
3107 guint32 comment_len = 0, comment_pad_len = 0;
3108 wtap_block_t int_data;
3109 wtapng_if_descr_mandatory_t *int_data_mand;
3111 /* Don't write anything we're not willing to read. */
3112 if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->encap)) {
3113 *err = WTAP_ERR_PACKET_TOO_LARGE;
3117 phdr_len = (guint32)pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
3118 if ((phdr_len + rec->rec_header.packet_header.caplen) % 4) {
3119 pad_len = 4 - ((phdr_len + rec->rec_header.packet_header.caplen) % 4);
3124 /* Check if we should write comment option */
3125 if (rec->opt_comment) {
3126 have_options = TRUE;
3127 comment_len = (guint32)strlen(rec->opt_comment) & 0xffff;
3128 if ((comment_len % 4)) {
3129 comment_pad_len = 4 - (comment_len % 4);
3131 comment_pad_len = 0;
3133 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3135 if (rec->presence_flags & WTAP_HAS_PACK_FLAGS) {
3136 have_options = TRUE;
3137 options_total_length = options_total_length + 8;
3140 /* End-of options tag */
3141 options_total_length += 4;
3144 /* write (enhanced) packet block header */
3145 bh.block_type = BLOCK_TYPE_EPB;
3146 bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len + options_total_length + 4;
3148 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3150 wdh->bytes_dumped += sizeof bh;
3152 /* write block fixed content */
3153 if (rec->presence_flags & WTAP_HAS_INTERFACE_ID)
3154 epb.interface_id = rec->rec_header.packet_header.interface_id;
3157 * XXX - we should support writing WTAP_ENCAP_PER_PACKET
3158 * data to pcapng files even if we *don't* have interface
3161 epb.interface_id = 0;
3164 * Split the 64-bit timestamp into two 32-bit pieces, using
3165 * the time stamp resolution for the interface.
3167 if (epb.interface_id >= wdh->interface_data->len) {
3169 * Our caller is doing something bad.
3171 *err = WTAP_ERR_INTERNAL;
3174 int_data = g_array_index(wdh->interface_data, wtap_block_t,
3176 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
3177 ts = ((guint64)rec->ts.secs) * int_data_mand->time_units_per_second +
3178 (((guint64)rec->ts.nsecs) * int_data_mand->time_units_per_second) / 1000000000;
3179 epb.timestamp_high = (guint32)(ts >> 32);
3180 epb.timestamp_low = (guint32)ts;
3181 epb.captured_len = rec->rec_header.packet_header.caplen + phdr_len;
3182 epb.packet_len = rec->rec_header.packet_header.len + phdr_len;
3184 if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
3186 wdh->bytes_dumped += sizeof epb;
3188 /* write pseudo header */
3189 if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
3192 wdh->bytes_dumped += phdr_len;
3194 /* write packet data */
3195 if (!wtap_dump_file_write(wdh, pd, rec->rec_header.packet_header.caplen, err))
3197 wdh->bytes_dumped += rec->rec_header.packet_header.caplen;
3199 /* write padding (if any) */
3201 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3203 wdh->bytes_dumped += pad_len;
3206 /* XXX - write (optional) block options */
3207 /* options defined in Section 2.5 (Options)
3208 * Name Code Length Description
3209 * opt_comment 1 variable A UTF-8 string containing a comment that is associated to the current block.
3211 * Enhanced Packet Block options
3212 * epb_flags 2 4 A flags word containing link-layer information. A complete specification of
3213 * the allowed flags can be found in Appendix A (Packet Block Flags Word).
3214 * epb_hash 3 variable This option contains a hash of the packet. The first byte specifies the hashing algorithm,
3215 * while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
3216 * and hence from the value in the first bit. The hashing algorithm can be: 2s complement
3217 * (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
3218 * MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
3219 * The hash covers only the packet, not the header added by the capture driver:
3220 * this gives the possibility to calculate it inside the network card.
3221 * The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
3222 * data acquisition system and the capture library.
3223 * epb_dropcount 4 8 A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
3224 * between this packet and the preceding one.
3225 * opt_endofopt 0 0 It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
3227 if (rec->opt_comment) {
3228 option_hdr.type = OPT_COMMENT;
3229 option_hdr.value_length = comment_len;
3230 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3232 wdh->bytes_dumped += 4;
3234 /* Write the comments string */
3235 pcapng_debug("pcapng_write_enhanced_packet_block, comment:'%s' comment_len %u comment_pad_len %u" , rec->opt_comment, comment_len, comment_pad_len);
3236 if (!wtap_dump_file_write(wdh, rec->opt_comment, comment_len, err))
3238 wdh->bytes_dumped += comment_len;
3240 /* write padding (if any) */
3241 if (comment_pad_len != 0) {
3242 if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
3244 wdh->bytes_dumped += comment_pad_len;
3247 pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
3251 if (rec->presence_flags & WTAP_HAS_PACK_FLAGS) {
3252 option_hdr.type = OPT_EPB_FLAGS;
3253 option_hdr.value_length = 4;
3254 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3256 wdh->bytes_dumped += 4;
3257 if (!wtap_dump_file_write(wdh, &rec->rec_header.packet_header.pack_flags, 4, err))
3259 wdh->bytes_dumped += 4;
3260 pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options packet flags: %x", rec->rec_header.packet_header.pack_flags);
3262 /* Write end of options if we have options */
3264 if (!wtap_dump_file_write(wdh, &zero_pad, 4, err))
3266 wdh->bytes_dumped += 4;
3269 /* write block footer */
3270 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3271 sizeof bh.block_total_length, err))
3273 wdh->bytes_dumped += sizeof bh.block_total_length;
3279 pcapng_write_sysdig_event_block(wtap_dumper *wdh, const wtap_rec *rec,
3280 const guint8 *pd, int *err)
3282 pcapng_block_header_t bh;
3283 const guint32 zero_pad = 0;
3286 gboolean have_options = FALSE;
3287 struct option option_hdr;
3288 guint32 comment_len = 0, comment_pad_len = 0;
3290 guint32 options_total_length = 0;
3298 /* Don't write anything we're not willing to read. */
3299 if (rec->rec_header.syscall_header.event_filelen > WTAP_MAX_PACKET_SIZE_STANDARD) {
3300 *err = WTAP_ERR_PACKET_TOO_LARGE;
3304 if (rec->rec_header.syscall_header.event_filelen % 4) {
3305 pad_len = 4 - (rec->rec_header.syscall_header.event_filelen % 4);
3311 /* Check if we should write comment option */
3312 if (rec->opt_comment) {
3313 have_options = TRUE;
3314 comment_len = (guint32)strlen(rec->opt_comment) & 0xffff;
3315 if ((comment_len % 4)) {
3316 comment_pad_len = 4 - (comment_len % 4);
3318 comment_pad_len = 0;
3320 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3323 /* End-of options tag */
3324 options_total_length += 4;
3328 /* write sysdig event block header */
3329 bh.block_type = BLOCK_TYPE_SYSDIG_EVENT;
3330 bh.block_total_length = (guint32)sizeof(bh) + SYSDIG_EVENT_HEADER_SIZE + rec->rec_header.syscall_header.event_filelen + pad_len + options_total_length + 4;
3332 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3334 wdh->bytes_dumped += sizeof bh;
3336 /* Sysdig is always LE? */
3337 cpu_id = GUINT16_TO_LE(rec->rec_header.syscall_header.cpu_id);
3338 hdr_ts = (((guint64)rec->ts.secs) * 1000000000) + rec->ts.nsecs;
3339 ts = GUINT64_TO_LE(hdr_ts);
3340 thread_id = GUINT64_TO_LE(rec->rec_header.syscall_header.thread_id);
3341 event_len = GUINT32_TO_LE(rec->rec_header.syscall_header.event_len);
3342 event_type = GUINT16_TO_LE(rec->rec_header.syscall_header.event_type);
3344 if (!wtap_dump_file_write(wdh, &cpu_id, sizeof cpu_id, err))
3346 wdh->bytes_dumped += sizeof cpu_id;
3348 if (!wtap_dump_file_write(wdh, &ts, sizeof ts, err))
3350 wdh->bytes_dumped += sizeof ts;
3352 if (!wtap_dump_file_write(wdh, &thread_id, sizeof thread_id, err))
3354 wdh->bytes_dumped += sizeof thread_id;
3356 if (!wtap_dump_file_write(wdh, &event_len, sizeof event_len, err))
3358 wdh->bytes_dumped += sizeof event_len;
3360 if (!wtap_dump_file_write(wdh, &event_type, sizeof event_type, err))
3362 wdh->bytes_dumped += sizeof event_type;
3364 /* write event data */
3365 if (!wtap_dump_file_write(wdh, pd, rec->rec_header.syscall_header.event_filelen, err))
3367 wdh->bytes_dumped += rec->rec_header.syscall_header.event_filelen;
3369 /* write padding (if any) */
3371 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3373 wdh->bytes_dumped += pad_len;
3376 /* XXX Write comment? */
3378 /* write block footer */
3379 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3380 sizeof bh.block_total_length, err))
3388 pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
3389 const guint8 *pd, int *err)
3391 pcapng_block_header_t bh;
3392 const guint32 zero_pad = 0;
3395 /* Don't write anything we're not willing to read. */
3396 if (rec->rec_header.ft_specific_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
3397 *err = WTAP_ERR_PACKET_TOO_LARGE;
3401 if (rec->rec_header.ft_specific_header.record_len % 4) {
3402 pad_len = 4 - (rec->rec_header.ft_specific_header.record_len % 4);
3407 /* write systemd journal export block header */
3408 bh.block_type = BLOCK_TYPE_SYSTEMD_JOURNAL;
3409 bh.block_total_length = (guint32)sizeof(bh) + rec->rec_header.ft_specific_header.record_len + pad_len + 4;
3411 pcapng_debug("%s: writing %u bytes, %u padded", G_STRFUNC,
3412 rec->rec_header.ft_specific_header.record_len,
3413 bh.block_total_length);
3415 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3417 wdh->bytes_dumped += sizeof bh;
3419 /* write entry data */
3420 if (!wtap_dump_file_write(wdh, pd, rec->rec_header.ft_specific_header.record_len, err))
3422 wdh->bytes_dumped += rec->rec_header.ft_specific_header.record_len;
3424 /* write padding (if any) */
3426 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3428 wdh->bytes_dumped += pad_len;
3431 /* write block footer */
3432 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3433 sizeof bh.block_total_length, err))
3441 * libpcap's maximum pcapng block size is currently 16MB.
3443 * The maximum pcapng block size in macOS's private pcapng reading code
3444 * is 1MB. (Yes, this means that a program using the standard pcap
3445 * code to read pcapng files can handle bigger blocks than can programs
3446 * using the private code, such as Apple's tcpdump, can handle.)
3448 * The pcapng reading code here can handle NRBs of arbitrary size (less
3449 * than 4GB, obviously), as they read each NRB record independently,
3450 * rather than reading the entire block into memory.
3452 * So, for now, we set the maximum NRB block size we write as 1 MB.
3454 * (Yes, for the benefit of the fussy, "MB" is really "MiB".)
3457 #define NRES_BLOCK_MAX_SIZE (1024*1024)
3460 compute_nrb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
3462 pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
3468 case OPT_NS_DNSNAME:
3469 size = pcapng_compute_option_string_size(optval->stringval);
3471 case OPT_NS_DNSIP4ADDR:
3474 case OPT_NS_DNSIP6ADDR:
3478 /* Unknown options - size by datatype? */
3482 block_size->size += size;
3483 /* Add bytes for option header if option should be written */
3485 /* Add optional padding to 32 bits */
3486 if ((block_size->size & 0x03) != 0)
3488 block_size->size += 4 - (block_size->size & 0x03);
3490 block_size->size += 4;
3495 put_nrb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
3497 guint8 **opt_ptrp = (guint8 **)user_data;
3499 struct pcapng_option_header option_hdr;
3505 case OPT_NS_DNSNAME:
3506 /* String options don't consider pad bytes part of the length */
3507 size = (guint32)strlen(optval->stringval) & 0xffff;
3508 option_hdr.type = (guint16)option_id;
3509 option_hdr.value_length = (guint16)size;
3510 memcpy(*opt_ptrp, &option_hdr, 4);
3513 memcpy(*opt_ptrp, optval->stringval, size);
3517 pad = 4 - (size % 4);
3522 /* put padding (if any) */
3524 memset(*opt_ptrp, 0, pad);
3528 case OPT_NS_DNSIP4ADDR:
3529 option_hdr.type = (guint16)option_id;
3530 option_hdr.value_length = 4;
3531 memcpy(*opt_ptrp, &option_hdr, 4);
3534 memcpy(*opt_ptrp, &optval->ipv4val, 4);
3537 case OPT_NS_DNSIP6ADDR:
3538 option_hdr.type = (guint16)option_id;
3539 option_hdr.value_length = 16;
3540 memcpy(*opt_ptrp, &option_hdr, 4);
3543 memcpy(*opt_ptrp, &optval->ipv6val, 16);
3547 /* Unknown options - size by datatype? */
3553 put_nrb_options(wtap_dumper *wdh, guint8 *opt_ptr)
3555 if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
3556 wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
3557 struct option option_hdr;
3559 wtap_block_foreach_option(nrb_hdr, put_nrb_option, &opt_ptr);
3561 /* Put end of options */
3562 option_hdr.type = OPT_EOFOPT;
3563 option_hdr.value_length = 0;
3564 memcpy(opt_ptr, &option_hdr, 4);
3569 pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
3571 pcapng_block_header_t bh;
3572 pcapng_name_resolution_block_t nrb;
3573 pcapng_block_size_t opts_size;
3574 size_t max_rec_data_size;
3579 guint32 tot_rec_len;
3580 hashipv4_t *ipv4_hash_list_entry;
3581 hashipv6_t *ipv6_hash_list_entry;
3584 if (wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
3586 * No name/address pairs to write.
3587 * XXX - what if we have options?
3592 /* Calculate the space needed for options. */
3594 if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
3595 wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
3597 wtap_block_foreach_option(nrb_hdr, compute_nrb_option_size, &opts_size);
3598 if (opts_size.size > 0) {
3599 /* End-of options tag */
3600 opts_size.size += 4;
3605 * Make sure we can fit at least one maximum-sized record, plus
3606 * an end-of-records record, plus the options, into a maximum-sized
3609 * That requires that there be enough space for the block header
3610 * (8 bytes), a maximum-sized record (2 bytes of record type, 2
3611 * bytes of record value length, 65535 bytes of record value,
3612 * and 1 byte of padding), an end-of-records record (4 bytes),
3613 * the options (opts_size.size bytes), and the block trailer (4
3616 if (8 + 2 + 2 + 65535 + 1 + 4 + opts_size.size + 4 > NRES_BLOCK_MAX_SIZE) {
3618 * XXX - we can't even fit the options in the largest NRB size
3619 * we're willing to write and still have room enough for a
3620 * maximum-sized record. Just discard the information for now.
3626 * Allocate a buffer for the largest block we'll write.
3628 block_data = (guint8 *)g_malloc(NRES_BLOCK_MAX_SIZE);
3631 * Calculate the maximum amount of record data we'll be able to
3632 * fit into such a block, after taking into account the block header
3633 * (8 bytes), the end-of-records record (4 bytes), the options
3634 * (opts_size.size bytes), and the block trailer (4 bytes).
3636 max_rec_data_size = NRES_BLOCK_MAX_SIZE - (8 + 4 + opts_size.size + 4);
3638 block_off = 8; /* block type + block total length */
3639 bh.block_type = BLOCK_TYPE_NRB;
3640 bh.block_total_length = 12; /* block header + block trailer */
3643 * Write out the IPv4 resolved addresses, if any.
3645 if (wdh->addrinfo_lists->ipv4_addr_list){
3647 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3648 while(ipv4_hash_list_entry != NULL){
3650 nrb.record_type = NRES_IP4RECORD;
3651 hostnamelen = strlen(ipv4_hash_list_entry->name);
3652 if (hostnamelen > (G_MAXUINT16 - 4) - 1) {
3654 * This won't fit in the largest possible NRB record;
3658 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3661 namelen = (guint16)(hostnamelen + 1);
3662 nrb.record_len = 4 + namelen; /* 4 bytes IPv4 address length */
3663 /* 2 bytes record type, 2 bytes length field */
3664 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3666 if (block_off + tot_rec_len > max_rec_data_size) {
3668 * This record would overflow our maximum size for Name
3669 * Resolution Blocks; write out all the records we created
3670 * before it, and start a new NRB.
3673 /* Append the end-of-records record */
3674 memset(block_data + block_off, 0, 4);
3676 bh.block_total_length += 4;
3679 * Put the options into the block.
3681 * XXX - this puts the same options in all NRBs.
3683 put_nrb_options(wdh, block_data + block_off);
3684 block_off += opts_size.size;
3685 bh.block_total_length += opts_size.size;
3687 /* Copy the block header. */
3688 memcpy(block_data, &bh, sizeof(bh));
3690 /* Copy the block trailer. */
3691 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3693 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3695 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3699 wdh->bytes_dumped += bh.block_total_length;
3701 /*Start a new NRB */
3702 block_off = 8; /* block type + block total length */
3703 bh.block_type = BLOCK_TYPE_NRB;
3704 bh.block_total_length = 12; /* block header + block trailer */
3707 bh.block_total_length += tot_rec_len;
3708 memcpy(block_data + block_off, &nrb, sizeof(nrb));
3710 memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4);
3712 memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen);
3713 block_off += namelen;
3714 memset(block_data + block_off, 0, PADDING4(namelen));
3715 block_off += PADDING4(namelen);
3716 pcapng_debug("NRB: added IPv4 record for %s", ipv4_hash_list_entry->name);
3719 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3721 g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
3722 wdh->addrinfo_lists->ipv4_addr_list = NULL;
3725 if (wdh->addrinfo_lists->ipv6_addr_list){
3727 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3728 while(ipv6_hash_list_entry != NULL){
3730 nrb.record_type = NRES_IP6RECORD;
3731 hostnamelen = strlen(ipv6_hash_list_entry->name);
3732 if (hostnamelen > (G_MAXUINT16 - 16) - 1) {
3734 * This won't fit in the largest possible NRB record;
3738 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3741 namelen = (guint16)(hostnamelen + 1);
3742 nrb.record_len = 16 + namelen; /* 16 bytes IPv6 address length */
3743 /* 2 bytes record type, 2 bytes length field */
3744 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3746 if (block_off + tot_rec_len > max_rec_data_size) {
3748 * This record would overflow our maximum size for Name
3749 * Resolution Blocks; write out all the records we created
3750 * before it, and start a new NRB.
3753 /* Append the end-of-records record */
3754 memset(block_data + block_off, 0, 4);
3756 bh.block_total_length += 4;
3759 * Put the options into the block.
3761 * XXX - this puts the same options in all NRBs.
3763 put_nrb_options(wdh, block_data + block_off);
3764 block_off += opts_size.size;
3765 bh.block_total_length += opts_size.size;
3767 /* Copy the block header. */
3768 memcpy(block_data, &bh, sizeof(bh));
3770 /* Copy the block trailer. */
3771 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3773 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3775 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3779 wdh->bytes_dumped += bh.block_total_length;
3781 /*Start a new NRB */
3782 block_off = 8; /* block type + block total length */
3783 bh.block_type = BLOCK_TYPE_NRB;
3784 bh.block_total_length = 12; /* block header + block trailer */
3787 bh.block_total_length += tot_rec_len;
3788 memcpy(block_data + block_off, &nrb, sizeof(nrb));
3790 memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16);
3792 memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen);
3793 block_off += namelen;
3794 memset(block_data + block_off, 0, PADDING4(namelen));
3795 block_off += PADDING4(namelen);
3796 pcapng_debug("NRB: added IPv6 record for %s", ipv6_hash_list_entry->name);
3799 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3801 g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
3802 wdh->addrinfo_lists->ipv6_addr_list = NULL;
3805 /* Append the end-of-records record */
3806 memset(block_data + block_off, 0, 4);
3808 bh.block_total_length += 4;
3811 * Put the options into the block.
3813 put_nrb_options(wdh, block_data + block_off);
3814 block_off += opts_size.size;
3815 bh.block_total_length += opts_size.size;
3817 /* Copy the block header. */
3818 memcpy(block_data, &bh, sizeof(bh));
3820 /* Copy the block trailer. */
3821 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3823 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3825 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3829 wdh->bytes_dumped += bh.block_total_length;
3836 static void compute_isb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
3838 pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
3844 size = pcapng_compute_option_string_size(optval->stringval);
3846 case OPT_ISB_STARTTIME:
3847 case OPT_ISB_ENDTIME:
3850 case OPT_ISB_IFRECV:
3851 case OPT_ISB_IFDROP:
3852 case OPT_ISB_FILTERACCEPT:
3853 case OPT_ISB_OSDROP:
3854 case OPT_ISB_USRDELIV:
3858 /* Unknown options - size by datatype? */
3862 block_size->size += size;
3863 /* Add bytes for option header if option should be written */
3865 /* Add optional padding to 32 bits */
3866 if ((block_size->size & 0x03) != 0)
3868 block_size->size += 4 - (block_size->size & 0x03);
3870 block_size->size += 4;
3874 static void write_wtap_isb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
3876 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
3877 struct pcapng_option_header option_hdr;
3879 /* Don't continue if there has been an error */
3880 if (!write_block->success)
3886 if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
3887 write_block->success = FALSE;
3891 case OPT_ISB_STARTTIME:
3892 case OPT_ISB_ENDTIME:
3896 option_hdr.type = option_id;
3897 option_hdr.value_length = 8;
3898 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3899 write_block->success = FALSE;
3902 write_block->wdh->bytes_dumped += 4;
3904 high = (guint32)(optval->uint64val >> 32);
3905 low = (guint32)(optval->uint64val >> 0);
3906 if (!wtap_dump_file_write(write_block->wdh, &high, sizeof(guint32), write_block->err)) {
3907 write_block->success = FALSE;
3910 write_block->wdh->bytes_dumped += 4;
3911 if (!wtap_dump_file_write(write_block->wdh, &low, sizeof(guint32), write_block->err)) {
3912 write_block->success = FALSE;
3915 write_block->wdh->bytes_dumped += 4;
3918 case OPT_ISB_IFRECV:
3919 case OPT_ISB_IFDROP:
3920 case OPT_ISB_FILTERACCEPT:
3921 case OPT_ISB_OSDROP:
3922 case OPT_ISB_USRDELIV:
3924 option_hdr.type = option_id;
3925 option_hdr.value_length = 8;
3926 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3927 write_block->success = FALSE;
3930 write_block->wdh->bytes_dumped += 4;
3932 if (!wtap_dump_file_write(write_block->wdh, &optval->uint64val, sizeof(guint64), write_block->err)) {
3933 write_block->success = FALSE;
3936 write_block->wdh->bytes_dumped += 8;
3940 /* Unknown options - write by datatype? */
3946 pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_block_t if_stats, int *err)
3948 pcapng_block_header_t bh;
3949 pcapng_interface_statistics_block_t isb;
3950 pcapng_block_size_t block_size;
3951 pcapng_write_block_t block_data;
3952 struct pcapng_option_header option_hdr;
3953 wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
3955 pcapng_debug("pcapng_write_interface_statistics_block");
3957 /* Compute block size */
3958 block_size.size = 0;
3959 wtap_block_foreach_option(if_stats, compute_isb_option_size, &block_size);
3961 if (block_size.size > 0) {
3962 /* End-of-options tag */
3963 block_size.size += 4;
3966 /* write block header */
3967 bh.block_type = BLOCK_TYPE_ISB;
3968 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(isb) + block_size.size + 4);
3969 pcapng_debug("pcapng_write_interface_statistics_block: Total len %u", bh.block_total_length);
3971 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3973 wdh->bytes_dumped += sizeof bh;
3975 /* write block fixed content */
3976 isb.interface_id = mand_data->interface_id;
3977 isb.timestamp_high = mand_data->ts_high;
3978 isb.timestamp_low = mand_data->ts_low;
3980 if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
3982 wdh->bytes_dumped += sizeof isb;
3985 if (block_size.size > 0) {
3986 block_data.wdh = wdh;
3987 block_data.err = err;
3988 block_data.success = TRUE;
3989 wtap_block_foreach_option(if_stats, write_wtap_isb_option, &block_data);
3991 if (!block_data.success)
3994 /* Write end of options */
3995 option_hdr.type = OPT_EOFOPT;
3996 option_hdr.value_length = 0;
3997 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3999 wdh->bytes_dumped += 4;
4002 /* write block footer */
4003 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
4004 sizeof bh.block_total_length, err))
4006 wdh->bytes_dumped += sizeof bh.block_total_length;
4010 static void compute_idb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
4012 pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
4021 case OPT_IDB_HARDWARE:
4022 size = pcapng_compute_option_string_size(optval->stringval);
4027 case OPT_IDB_TSRESOL:
4030 case OPT_IDB_FILTER:
4032 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->customval.data;
4034 if (filter->if_filter_str != NULL) {
4035 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
4037 pad = 4 - (size % 4);
4046 case OPT_IDB_FCSLEN:
4047 /* XXX - Not currently writing value */
4050 /* Unknown options - size by datatype? */
4054 block_size->size += size;
4055 /* Add bytes for option header if option should be written */
4057 /* Add optional padding to 32 bits */
4058 if ((block_size->size & 0x03) != 0)
4060 block_size->size += 4 - (block_size->size & 0x03);
4062 block_size->size += 4;
4066 static void write_wtap_idb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
4068 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
4069 struct pcapng_option_header option_hdr;
4070 const guint32 zero_pad = 0;
4078 case OPT_IDB_HARDWARE:
4079 if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
4080 write_block->success = FALSE;
4085 option_hdr.type = option_id;
4086 option_hdr.value_length = 8;
4087 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
4088 write_block->success = FALSE;
4091 write_block->wdh->bytes_dumped += 4;
4093 if (!wtap_dump_file_write(write_block->wdh, &optval->uint64val, sizeof(guint64), write_block->err)) {
4094 write_block->success = FALSE;
4097 write_block->wdh->bytes_dumped += 8;
4099 case OPT_IDB_TSRESOL:
4100 option_hdr.type = option_id;
4101 option_hdr.value_length = 1;
4102 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
4103 write_block->success = FALSE;
4106 write_block->wdh->bytes_dumped += 4;
4108 if (!wtap_dump_file_write(write_block->wdh, &optval->uint8val, 1, write_block->err)) {
4109 write_block->success = FALSE;
4112 write_block->wdh->bytes_dumped += 1;
4114 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 3, write_block->err)) {
4115 write_block->success = FALSE;
4118 write_block->wdh->bytes_dumped += 3;
4120 case OPT_IDB_FILTER:
4122 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->customval.data;
4124 if (filter->if_filter_str != NULL) {
4125 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
4127 pad = 4 - (size % 4);
4132 option_hdr.type = option_id;
4133 option_hdr.value_length = size;
4134 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
4135 write_block->success = FALSE;
4138 write_block->wdh->bytes_dumped += 4;
4140 /* Write the zero indicating libpcap filter variant */
4141 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 1, write_block->err)) {
4142 write_block->success = FALSE;
4145 write_block->wdh->bytes_dumped += 1;
4147 /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
4148 if (!wtap_dump_file_write(write_block->wdh, filter->if_filter_str, size-1, write_block->err)) {
4149 write_block->success = FALSE;
4152 write_block->wdh->bytes_dumped += size - 1;
4154 /* write padding (if any) */
4156 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, pad, write_block->err)) {
4157 write_block->success = FALSE;
4160 write_block->wdh->bytes_dumped += pad;
4166 case OPT_IDB_FCSLEN:
4167 /* XXX - Not currently writing value */
4170 /* Unknown options - size by datatype? */
4176 pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data, int *err)
4178 pcapng_block_header_t bh;
4179 pcapng_interface_description_block_t idb;
4180 pcapng_block_size_t block_size;
4181 pcapng_write_block_t block_data;
4182 struct pcapng_option_header option_hdr;
4183 wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
4186 pcapng_debug("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d",
4187 mand_data->wtap_encap,
4188 wtap_encap_string(mand_data->wtap_encap),
4189 mand_data->snap_len);
4191 link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap);
4192 if (link_type == -1) {
4193 if (!pcapng_encap_is_ft_specific(mand_data->wtap_encap)) {
4194 *err = WTAP_ERR_UNWRITABLE_ENCAP;
4199 /* Compute block size */
4200 block_size.size = 0;
4201 wtap_block_foreach_option(int_data, compute_idb_option_size, &block_size);
4203 if (block_size.size > 0) {
4204 /* End-of-options tag */
4205 block_size.size += 4;
4208 /* write block header */
4209 bh.block_type = BLOCK_TYPE_IDB;
4210 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + block_size.size + 4);
4211 pcapng_debug("pcapng_write_if_descr_block: Total len %u", bh.block_total_length);
4213 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
4215 wdh->bytes_dumped += sizeof bh;
4217 /* write block fixed content */
4218 idb.linktype = link_type;
4220 idb.snaplen = mand_data->snap_len;
4222 if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
4224 wdh->bytes_dumped += sizeof idb;
4226 if (block_size.size > 0) {
4228 block_data.wdh = wdh;
4229 block_data.err = err;
4230 block_data.success = TRUE;
4231 wtap_block_foreach_option(int_data, write_wtap_idb_option, &block_data);
4233 if (!block_data.success)
4236 /* Write end of options */
4237 option_hdr.type = OPT_EOFOPT;
4238 option_hdr.value_length = 0;
4239 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4241 wdh->bytes_dumped += 4;
4244 /* write block footer */
4245 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
4246 sizeof bh.block_total_length, err))
4249 wdh->bytes_dumped += sizeof bh.block_total_length;
4253 static gboolean pcapng_dump(wtap_dumper *wdh,
4254 const wtap_rec *rec,
4255 const guint8 *pd, int *err, gchar **err_info _U_)
4258 block_handler *handler;
4261 pcapng_debug("%s: encap = %d (%s) rec type = %u", G_STRFUNC,
4262 rec->rec_header.packet_header.pkt_encap,
4263 wtap_encap_string(rec->rec_header.packet_header.pkt_encap),
4266 switch (rec->rec_type) {
4268 case REC_TYPE_PACKET:
4270 * XXX - write a Simple Packet Block if there's no time
4271 * stamp or other information that doesn't appear in an
4274 if (!pcapng_write_enhanced_packet_block(wdh, rec, pd, err)) {
4279 case REC_TYPE_FT_SPECIFIC_EVENT:
4280 case REC_TYPE_FT_SPECIFIC_REPORT:
4281 if (rec->rec_header.ft_specific_header.record_type == WTAP_FILE_TYPE_SUBTYPE_SYSTEMD_JOURNAL) {
4282 if (!pcapng_write_systemd_journal_export_block(wdh, rec, pd, err)) {
4289 * Do we have a handler for this block type?
4291 if (block_handlers != NULL &&
4292 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
4293 GUINT_TO_POINTER(rec->rec_header.ft_specific_header.record_type))) != NULL) {
4294 /* Yes. Call it to write out this record. */
4295 if (!handler->writer(wdh, rec, pd, err))
4301 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
4306 case REC_TYPE_SYSCALL:
4307 if (!pcapng_write_sysdig_event_block(wdh, rec, pd, err)) {
4313 /* We don't support writing this record type. */
4314 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
4322 /* Finish writing to a dump file.
4323 Returns TRUE on success, FALSE on failure. */
4324 static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err)
4328 /* Flush any hostname resolution info we may have */
4329 pcapng_write_name_resolution_block(wdh, err);
4331 for (i = 0; i < wdh->interface_data->len; i++) {
4333 /* Get the interface description */
4334 wtap_block_t int_data;
4335 wtapng_if_descr_mandatory_t *int_data_mand;
4337 int_data = g_array_index(wdh->interface_data, wtap_block_t, i);
4338 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
4340 for (j = 0; j < int_data_mand->num_stat_entries; j++) {
4341 wtap_block_t if_stats;
4343 if_stats = g_array_index(int_data_mand->interface_statistics, wtap_block_t, j);
4344 pcapng_debug("pcapng_dump_finish: write ISB for interface %u", ((wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats))->interface_id);
4345 if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) {
4351 pcapng_debug("pcapng_dump_finish");
4356 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
4359 pcapng_dump_open(wtap_dumper *wdh, int *err)
4363 pcapng_debug("pcapng_dump_open");
4364 /* This is a pcapng file */
4365 wdh->subtype_write = pcapng_dump;
4366 wdh->subtype_finish = pcapng_dump_finish;
4368 // XXX IDBs should be optional.
4369 if (wdh->interface_data->len == 0) {
4370 pcapng_debug("There are no interfaces. Can't handle that...");
4371 *err = WTAP_ERR_INTERNAL;
4375 /* write the section header block */
4376 if (!pcapng_write_section_header_block(wdh, err)) {
4379 pcapng_debug("pcapng_dump_open: wrote section header block.");
4381 /* Write the Interface description blocks */
4382 pcapng_debug("pcapng_dump_open: Number of IDB:s to write (number of interfaces) %u",
4383 wdh->interface_data->len);
4385 for (i = 0; i < wdh->interface_data->len; i++) {
4387 /* Get the interface description */
4390 idb = g_array_index(wdh->interface_data, wtap_block_t, i);
4392 if (!pcapng_write_if_descr_block(wdh, idb, err)) {
4402 /* Returns 0 if we could write the specified encapsulation type,
4403 an error indication otherwise. */
4404 int pcapng_dump_can_write_encap(int wtap_encap)
4406 pcapng_debug("pcapng_dump_can_write_encap: encap = %d (%s)",
4408 wtap_encap_string(wtap_encap));
4410 /* Per-packet encapsulation is supported. */
4411 if (wtap_encap == WTAP_ENCAP_PER_PACKET)
4414 /* Is it a filetype-specific encapsulation that we support? */
4415 if (pcapng_encap_is_ft_specific(wtap_encap)) {
4419 /* Make sure we can figure out this DLT type */
4420 if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
4421 return WTAP_ERR_UNWRITABLE_ENCAP;
4427 * Returns TRUE if the specified encapsulation type is filetype-specific
4428 * and one that we support.
4430 gboolean pcapng_encap_is_ft_specific(int encap)
4433 case WTAP_ENCAP_SYSTEMD_JOURNAL:
4440 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4445 * indent-tabs-mode: nil
4448 * vi: set shiftwidth=4 tabstop=8 expandtab:
4449 * :indentSize=4:tabSize=8:noTabs=true: