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+
12 /* File format specification:
13 * https://github.com/pcapng/pcapng
15 * https://wiki.wireshark.org/Development/PcapNg
26 #include "file_wrappers.h"
27 #include "pcap-common.h"
28 #include "pcap-encap.h"
30 #include "pcapng_module.h"
33 #define pcapng_debug(...) g_warning(__VA_ARGS__)
35 #define pcapng_debug(...)
39 pcapng_read(wtap *wth, int *err, gchar **err_info,
42 pcapng_seek_read(wtap *wth, gint64 seek_off,
43 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
45 pcapng_close(wtap *wth);
48 * Minimum block size = size of block header + size of block trailer.
50 #define MIN_BLOCK_SIZE ((guint32)(sizeof(pcapng_block_header_t) + sizeof(guint32)))
53 * In order to keep from trying to allocate large chunks of memory,
54 * which could either fail or, even if it succeeds, chew up so much
55 * address space or memory+backing store as not to leave room for
56 * anything else, we impose an upper limit on the size of blocks
57 * we're willing to handle.
59 * For now, we pick an arbitrary limit of 16MB (OK, fine, 16MiB, but
60 * don't try saying that on Wikipedia :-) :-) :-)).
62 #define MAX_BLOCK_SIZE (16*1024*1024)
65 * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
67 #define MIN_SHB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
69 /* pcapng: packet block file encoding (obsolete) */
70 typedef struct pcapng_packet_block_s {
73 guint32 timestamp_high;
74 guint32 timestamp_low;
77 /* ... Packet Data ... */
80 } pcapng_packet_block_t;
83 * Minimum PB size = minimum block size + size of fixed length portion of PB.
85 #define MIN_PB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
87 /* pcapng: enhanced packet block file encoding */
88 typedef struct pcapng_enhanced_packet_block_s {
90 guint32 timestamp_high;
91 guint32 timestamp_low;
94 /* ... Packet Data ... */
97 } pcapng_enhanced_packet_block_t;
100 * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
102 #define MIN_EPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
104 /* pcapng: simple packet block file encoding */
105 typedef struct pcapng_simple_packet_block_s {
107 /* ... Packet Data ... */
108 /* ... Padding ... */
109 } pcapng_simple_packet_block_t;
112 * Minimum SPB size = minimum block size + size of fixed length portion of SPB.
114 #define MIN_SPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
116 /* pcapng: name resolution block file encoding */
117 typedef struct pcapng_name_resolution_block_s {
121 } pcapng_name_resolution_block_t;
124 * Minimum NRB size = minimum block size + size of smallest NRB record
125 * (there must at least be an "end of records" record).
127 #define MIN_NRB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
130 * Minimum ISB size = minimum block size + size of fixed length portion of ISB.
132 #define MIN_ISB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
135 * Minimum Sysdig size = minimum block size + packed size of sysdig_event_phdr.
137 #define SYSDIG_EVENT_HEADER_SIZE ((16 + 64 + 64 + 32 + 16)/8) /* CPU ID + TS + TID + Event len + Event type */
138 #define MIN_SYSDIG_EVENT_SIZE ((guint32)(MIN_BLOCK_SIZE + SYSDIG_EVENT_HEADER_SIZE))
140 /* pcapng: common option header file encoding for every option type */
141 typedef struct pcapng_option_header_s {
143 guint16 option_length;
144 /* ... x bytes Option Body ... */
145 /* ... Padding ... */
146 } pcapng_option_header_t;
150 guint16 value_length;
153 /* Option codes: 16-bit field */
154 #define OPT_EPB_FLAGS 0x0002
155 #define OPT_EPB_HASH 0x0003
156 #define OPT_EPB_DROPCOUNT 0x0004
158 #define OPT_NRB_DNSNAME 0x0002
159 #define OPT_NRB_DNSV4ADDR 0x0003
160 #define OPT_NRB_DNSV6ADDR 0x0004
162 /* MSBit of option code means "local type" */
163 #define OPT_LOCAL_FLAG 0x8000
165 /* Note: many of the defined structures for block data are defined in wtap.h */
167 /* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
168 typedef struct wtapng_packet_s {
170 guint32 ts_high; /* seconds since 1.1.1970 */
171 guint32 ts_low; /* fraction of seconds, depends on if_tsresol */
172 guint32 cap_len; /* data length in the file */
173 guint32 packet_len; /* data length on the wire */
174 guint32 interface_id; /* identifier of the interface. */
175 guint16 drops_count; /* drops count, only valid for packet block */
176 /* 0xffff if information no available */
178 /* XXX - put the packet data / pseudo_header here as well? */
181 /* Simple Packet data */
182 typedef struct wtapng_simple_packet_s {
184 guint32 cap_len; /* data length in the file */
185 guint32 packet_len; /* data length on the wire */
186 /* XXX - put the packet data / pseudo_header here as well? */
187 } wtapng_simple_packet_t;
189 /* Block data to be passed between functions during reading */
190 typedef struct wtapng_block_s {
191 guint32 type; /* block_type as defined by pcapng */
195 * XXX - currently don't know how to handle these!
197 * For one thing, when we're reading a block, they must be
198 * writable, i.e. not const, so that we can read into them,
199 * but, when we're writing a block, they can be const, and,
200 * in fact, they sometimes point to const values.
202 struct wtap_pkthdr *packet_header;
203 Buffer *frame_buffer;
206 /* Interface data in private struct */
207 typedef struct interface_info_s {
210 guint64 time_units_per_second;
215 gboolean shb_read; /**< Set when first SHB read */
216 gboolean byte_swapped;
217 guint16 version_major;
218 guint16 version_minor;
219 GArray *interfaces; /**< Interfaces found in the capture file. */
221 wtap_new_ipv4_callback_t add_new_ipv4;
222 wtap_new_ipv6_callback_t add_new_ipv6;
227 * Table for plugins to handle particular block types.
229 * A handler has a "read" routine and a "write" routine.
231 * A "read" routine returns a block as a libwiretap record, filling
232 * in the wtap_pkthdr structure with the appropriate record type and
233 * other information, and filling in the supplied Buffer with
234 * data for which there's no place in the wtap_pkthdr structure.
236 * A "write" routine takes a libwiretap record and Buffer and writes
244 static GHashTable *block_handlers;
247 register_pcapng_block_type_handler(guint block_type, block_reader reader,
250 block_handler *handler;
253 * Is this a known block type?
255 switch (block_type) {
264 case BLOCK_TYPE_SYSDIG_EVENT:
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 return PCAPNG_BLOCK_ERROR;
645 to_read -= bytes_read;
647 /* handle option content */
648 switch (oh.option_code) {
651 pcapng_debug("pcapng_read_section_header_block: %u bytes after opt_endofopt", to_read);
653 /* padding should be ok here, just get out of this */
657 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
658 tmp_content = g_strndup((char *)option_content, oh.option_length);
659 wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
660 pcapng_debug("pcapng_read_section_header_block: opt_comment %s", tmp_content);
663 pcapng_debug("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
666 case(OPT_SHB_HARDWARE):
667 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
668 tmp_content = g_strndup((char *)option_content, oh.option_length);
669 /* Fails with multiple options; we silently ignore the failure */
670 wtap_block_add_string_option(wblock->block, OPT_SHB_HARDWARE, option_content, oh.option_length);
671 pcapng_debug("pcapng_read_section_header_block: shb_hardware %s", tmp_content);
674 pcapng_debug("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
678 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
679 tmp_content = g_strndup((char *)option_content, oh.option_length);
680 /* Fails with multiple options; we silently ignore the failure */
681 wtap_block_add_string_option(wblock->block, OPT_SHB_OS, option_content, oh.option_length);
682 pcapng_debug("pcapng_read_section_header_block: shb_os %s", tmp_content);
685 pcapng_debug("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
688 case(OPT_SHB_USERAPPL):
689 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
690 tmp_content = g_strndup((char *)option_content, oh.option_length);
691 /* Fails with multiple options; we silently ignore the failure */
692 wtap_block_add_string_option(wblock->block, OPT_SHB_USERAPPL, option_content, oh.option_length);
693 pcapng_debug("pcapng_read_section_header_block: shb_user_appl %s", tmp_content);
696 pcapng_debug("pcapng_read_section_header_block: shb_user_appl length %u seems strange", oh.option_length);
700 pcapng_debug("pcapng_read_section_header_block: unknown option %u - ignoring %u bytes",
701 oh.option_code, oh.option_length);
704 g_free(option_content);
706 return PCAPNG_BLOCK_OK;
710 /* "Interface Description Block" */
712 pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
713 pcapng_t *pn, wtapng_block_t *wblock, int *err,
716 guint64 time_units_per_second = 1000000; /* default = 10^6 */
717 int tsprecision = WTAP_TSPREC_USEC;
719 guint to_read, opt_cont_buf_len;
720 pcapng_interface_description_block_t idb;
721 wtapng_if_descr_mandatory_t* if_descr_mand;
723 pcapng_option_header_t oh;
724 guint8 *option_content = NULL; /* Allocate as large as the options block */
729 * Is this block long enough to be an IDB?
731 if (bh->block_total_length < MIN_IDB_SIZE) {
735 *err = WTAP_ERR_BAD_FILE;
736 *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",
737 bh->block_total_length, MIN_IDB_SIZE);
741 /* Don't try to allocate memory for a huge number of options, as
742 that might fail and, even if it succeeds, it might not leave
743 any address space or memory+backing store for anything else.
745 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
746 We check for this *after* checking the SHB for its byte
747 order magic number, so that non-pcapng files are less
748 likely to be treated as bad pcapng files. */
749 if (bh->block_total_length > MAX_BLOCK_SIZE) {
750 *err = WTAP_ERR_BAD_FILE;
751 *err_info = g_strdup_printf("pcapng_read_if_descr_block: total block length %u is too large (> %u)",
752 bh->block_total_length, MAX_BLOCK_SIZE);
756 /* read block content */
757 if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
758 pcapng_debug("pcapng_read_if_descr_block: failed to read IDB");
762 /* mandatory values */
763 wblock->block = wtap_block_create(WTAP_BLOCK_IF_DESCR);
764 if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
765 if (pn->byte_swapped) {
766 link_type = GUINT16_SWAP_LE_BE(idb.linktype);
767 if_descr_mand->snap_len = GUINT32_SWAP_LE_BE(idb.snaplen);
769 link_type = idb.linktype;
770 if_descr_mand->snap_len = idb.snaplen;
773 if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(link_type);
774 if_descr_mand->time_units_per_second = time_units_per_second;
775 if_descr_mand->tsprecision = tsprecision;
777 pcapng_debug("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u",
779 wtap_encap_string(if_descr_mand->wtap_encap),
780 if_descr_mand->snap_len);
782 if (if_descr_mand->snap_len > wtap_max_snaplen_for_encap(if_descr_mand->wtap_encap)) {
784 * We do not use this value, maybe we should check the
785 * snap_len of the packets against it. For now, only warn.
787 pcapng_debug("pcapng_read_if_descr_block: snapshot length %u unrealistic.",
788 if_descr_mand->snap_len);
789 /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;*/
793 to_read = bh->block_total_length - MIN_IDB_SIZE;
795 /* Allocate enough memory to hold all options */
796 opt_cont_buf_len = to_read;
797 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
798 if (opt_cont_buf_len != 0 && option_content == NULL) {
799 *err = ENOMEM; /* we assume we're out of memory */
803 while (to_read != 0) {
805 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "if_descr");
806 if (bytes_read <= 0) {
807 pcapng_debug("pcapng_read_if_descr_block: failed to read option");
810 to_read -= bytes_read;
812 /* handle option content */
813 switch (oh.option_code) {
814 case(OPT_EOFOPT): /* opt_endofopt */
816 pcapng_debug("pcapng_read_if_descr_block: %u bytes after opt_endofopt", to_read);
818 /* padding should be ok here, just get out of this */
821 case(OPT_COMMENT): /* opt_comment */
822 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
823 tmp_content = g_strndup((char *)option_content, oh.option_length);
824 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
825 pcapng_debug("pcapng_read_if_descr_block: opt_comment %s", tmp_content);
828 pcapng_debug("pcapng_read_if_descr_block: opt_comment length %u seems strange", oh.option_length);
831 case(OPT_IDB_NAME): /* if_name */
832 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
833 tmp_content = g_strndup((char *)option_content, oh.option_length);
834 /* Fails with multiple options; we silently ignore the failure */
835 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
836 pcapng_debug("pcapng_read_if_descr_block: if_name %s", tmp_content);
839 pcapng_debug("pcapng_read_if_descr_block: if_name length %u seems strange", oh.option_length);
842 case(OPT_IDB_DESCR): /* if_description */
843 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
844 tmp_content = g_strndup((char *)option_content, oh.option_length);
845 /* Fails with multiple options; we silently ignore the failure */
846 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
847 pcapng_debug("pcapng_read_if_descr_block: if_description %s", tmp_content);
850 pcapng_debug("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
853 case(OPT_IDB_SPEED): /* if_speed */
854 if (oh.option_length == 8) {
855 /* Don't cast a guint8 * into a guint64 *--the
856 * guint8 * may not point to something that's
859 memcpy(&tmp64, option_content, sizeof(guint64));
860 if (pn->byte_swapped)
861 tmp64 = GUINT64_SWAP_LE_BE(tmp64);
862 /* Fails with multiple options; we silently ignore the failure */
863 wtap_block_add_uint64_option(wblock->block, oh.option_code, tmp64);
864 pcapng_debug("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", tmp64);
866 pcapng_debug("pcapng_read_if_descr_block: if_speed length %u not 8 as expected", oh.option_length);
869 case(OPT_IDB_TSRESOL): /* if_tsresol */
870 if (oh.option_length == 1) {
873 guint8 i, exponent, if_tsresol;
875 if_tsresol = option_content[0];
876 if (if_tsresol & 0x80) {
881 exponent = (guint8)(if_tsresol & 0x7f);
882 if (((base == 2) && (exponent < 64)) || ((base == 10) && (exponent < 20))) {
884 for (i = 0; i < exponent; i++) {
887 time_units_per_second = result;
889 time_units_per_second = G_MAXUINT64;
891 if (time_units_per_second > (((guint64)1) << 32)) {
892 pcapng_debug("pcapng_open: time conversion might be inaccurate");
894 if_descr_mand->time_units_per_second = time_units_per_second;
895 /* Fails with multiple options; we silently ignore the failure */
896 wtap_block_add_uint8_option(wblock->block, oh.option_code, if_tsresol);
897 if (time_units_per_second >= 1000000000)
898 tsprecision = WTAP_TSPREC_NSEC;
899 else if (time_units_per_second >= 1000000)
900 tsprecision = WTAP_TSPREC_USEC;
901 else if (time_units_per_second >= 1000)
902 tsprecision = WTAP_TSPREC_MSEC;
903 else if (time_units_per_second >= 100)
904 tsprecision = WTAP_TSPREC_CSEC;
905 else if (time_units_per_second >= 10)
906 tsprecision = WTAP_TSPREC_DSEC;
908 tsprecision = WTAP_TSPREC_SEC;
909 if_descr_mand->tsprecision = tsprecision;
910 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);
912 pcapng_debug("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length);
916 * if_tzone 10 Time zone for GMT support (TODO: specify better). TODO: give a good example
918 case(OPT_IDB_FILTER): /* if_filter */
919 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
920 wtapng_if_descr_filter_t if_filter;
921 memset(&if_filter, 0, sizeof(if_filter));
923 /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
926 if (option_content[0] == 0) {
927 if_filter.if_filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
928 pcapng_debug("pcapng_read_if_descr_block: if_filter_str %s oh.option_length %u", if_filter.if_filter_str, oh.option_length);
929 } else if (option_content[0] == 1) {
930 if_filter.bpf_filter_len = oh.option_length-1;
931 if_filter.if_filter_bpf_bytes = (guint8 *)option_content+1;
933 /* Fails with multiple options; we silently ignore the failure */
934 wtap_block_add_custom_option(wblock->block, oh.option_code, &if_filter, sizeof if_filter);
935 g_free(if_filter.if_filter_str);
937 pcapng_debug("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
940 case(OPT_IDB_OS): /* if_os */
942 * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
943 * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
944 * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
946 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
947 tmp_content = g_strndup((char *)option_content, oh.option_length);
948 /* Fails with multiple options; we silently ignore the failure */
949 wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
950 pcapng_debug("pcapng_read_if_descr_block: if_os %s", tmp_content);
953 pcapng_debug("pcapng_read_if_descr_block: if_os length %u seems strange", oh.option_length);
956 case(OPT_IDB_FCSLEN): /* if_fcslen */
957 if (oh.option_length == 1) {
958 /* Fails with multiple options; we silently ignore the failure */
959 wtap_block_add_uint8_option(wblock->block, oh.option_code, option_content[0]);
960 pn->if_fcslen = option_content[0];
961 pcapng_debug("pcapng_read_if_descr_block: if_fcslen %u", pn->if_fcslen);
962 /* XXX - add sanity check */
964 pcapng_debug("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
968 /* TODO: process these! */
969 case(OPT_IDB_IP4ADDR):
971 * Interface network address and netmask. This option can be
972 * repeated multiple times within the same Interface
973 * Description Block when multiple IPv4 addresses are assigned
974 * to the interface. 192 168 1 1 255 255 255 0
976 case(OPT_IDB_IP6ADDR):
978 * Interface network address and prefix length (stored in the
979 * last byte). This option can be repeated multiple times
980 * within the same Interface Description Block when multiple
981 * IPv6 addresses are assigned to the interface.
982 * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
983 * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
986 case(OPT_IDB_MACADDR):
988 * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
990 case(OPT_IDB_EUIADDR):
992 * Interface Hardware EUI address (64 bits), if available.
993 * TODO: give a good example
997 * Time zone for GMT support. TODO: specify better.
998 * TODO: give a good example.
1000 case(OPT_IDB_TSOFFSET):
1002 * A 64 bits integer value that specifies an offset (in
1003 * seconds) that must be added to the timestamp of each packet
1004 * to obtain the absolute timestamp of a packet. If the option
1005 * is missing, the timestamps stored in the packet must be
1006 * considered absolute timestamps. The time zone of the offset
1007 * can be specified with the option if_tzone.
1009 * TODO: won't a if_tsoffset_low for fractional second offsets
1010 * be useful for highly synchronized capture systems? 1234
1013 pcapng_debug("pcapng_read_if_descr_block: unknown option %u - ignoring %u bytes",
1014 oh.option_code, oh.option_length);
1018 g_free(option_content);
1021 * If the per-file encapsulation isn't known, set it to this
1022 * interface's encapsulation.
1024 * If it *is* known, and it isn't this interface's encapsulation,
1025 * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
1026 * have a single encapsulation for all interfaces in the file,
1027 * so it probably doesn't have a single encapsulation for all
1028 * packets in the file.
1030 if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
1031 wth->file_encap = if_descr_mand->wtap_encap;
1033 if (wth->file_encap != if_descr_mand->wtap_encap) {
1034 wth->file_encap = WTAP_ENCAP_PER_PACKET;
1039 * The same applies to the per-file time stamp resolution.
1041 if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
1042 wth->file_tsprec = if_descr_mand->tsprecision;
1044 if (wth->file_tsprec != if_descr_mand->tsprecision) {
1045 wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
1054 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)
1058 guint to_read, opt_cont_buf_len;
1059 pcapng_enhanced_packet_block_t epb;
1060 pcapng_packet_block_t pb;
1061 wtapng_packet_t packet;
1062 guint32 block_total_length;
1064 interface_info_t iface_info;
1067 pcapng_option_header_t *oh;
1068 guint8 *option_content;
1069 int pseudo_header_len;
1072 option_handler *handler;
1075 /* Don't try to allocate memory for a huge number of options, as
1076 that might fail and, even if it succeeds, it might not leave
1077 any address space or memory+backing store for anything else.
1079 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1080 We check for this *after* checking the SHB for its byte
1081 order magic number, so that non-pcapng files are less
1082 likely to be treated as bad pcapng files. */
1083 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1084 *err = WTAP_ERR_BAD_FILE;
1085 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u is too large (> %u)",
1086 bh->block_total_length, MAX_BLOCK_SIZE);
1090 /* "(Enhanced) Packet Block" read fixed part */
1093 * Is this block long enough to be an EPB?
1095 if (bh->block_total_length < MIN_EPB_SIZE) {
1099 *err = WTAP_ERR_BAD_FILE;
1100 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of an EPB is less than the minimum EPB size %u",
1101 bh->block_total_length, MIN_EPB_SIZE);
1104 if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
1105 pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1108 block_read = (guint)sizeof epb;
1110 if (pn->byte_swapped) {
1111 packet.interface_id = GUINT32_SWAP_LE_BE(epb.interface_id);
1112 packet.drops_count = -1; /* invalid */
1113 packet.ts_high = GUINT32_SWAP_LE_BE(epb.timestamp_high);
1114 packet.ts_low = GUINT32_SWAP_LE_BE(epb.timestamp_low);
1115 packet.cap_len = GUINT32_SWAP_LE_BE(epb.captured_len);
1116 packet.packet_len = GUINT32_SWAP_LE_BE(epb.packet_len);
1118 packet.interface_id = epb.interface_id;
1119 packet.drops_count = -1; /* invalid */
1120 packet.ts_high = epb.timestamp_high;
1121 packet.ts_low = epb.timestamp_low;
1122 packet.cap_len = epb.captured_len;
1123 packet.packet_len = epb.packet_len;
1125 pcapng_debug("pcapng_read_packet_block: EPB on interface_id %d, cap_len %d, packet_len %d",
1126 packet.interface_id, packet.cap_len, packet.packet_len);
1129 * Is this block long enough to be a PB?
1131 if (bh->block_total_length < MIN_PB_SIZE) {
1135 *err = WTAP_ERR_BAD_FILE;
1136 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of a PB is less than the minimum PB size %u",
1137 bh->block_total_length, MIN_PB_SIZE);
1140 if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
1141 pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1144 block_read = (guint)sizeof pb;
1146 if (pn->byte_swapped) {
1147 packet.interface_id = GUINT16_SWAP_LE_BE(pb.interface_id);
1148 packet.drops_count = GUINT16_SWAP_LE_BE(pb.drops_count);
1149 packet.ts_high = GUINT32_SWAP_LE_BE(pb.timestamp_high);
1150 packet.ts_low = GUINT32_SWAP_LE_BE(pb.timestamp_low);
1151 packet.cap_len = GUINT32_SWAP_LE_BE(pb.captured_len);
1152 packet.packet_len = GUINT32_SWAP_LE_BE(pb.packet_len);
1154 packet.interface_id = pb.interface_id;
1155 packet.drops_count = pb.drops_count;
1156 packet.ts_high = pb.timestamp_high;
1157 packet.ts_low = pb.timestamp_low;
1158 packet.cap_len = pb.captured_len;
1159 packet.packet_len = pb.packet_len;
1161 pcapng_debug("pcapng_read_packet_block: PB on interface_id %d, cap_len %d, packet_len %d",
1162 packet.interface_id, packet.cap_len, packet.packet_len);
1166 * How much padding is there at the end of the packet data?
1168 if ((packet.cap_len % 4) != 0)
1169 padding = 4 - (packet.cap_len % 4);
1173 /* add padding bytes to "block total length" */
1174 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1175 if (bh->block_total_length % 4) {
1176 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1178 block_total_length = bh->block_total_length;
1180 pcapng_debug("pcapng_read_packet_block: block_total_length %d", block_total_length);
1183 * Is this block long enough to hold the packet data?
1186 if (block_total_length <
1187 MIN_EPB_SIZE + packet.cap_len + padding) {
1191 *err = WTAP_ERR_BAD_FILE;
1192 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of EPB is too small for %u bytes of packet data",
1193 block_total_length, packet.cap_len);
1197 if (block_total_length <
1198 MIN_PB_SIZE + packet.cap_len + padding) {
1202 *err = WTAP_ERR_BAD_FILE;
1203 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of PB is too small for %u bytes of packet data",
1204 block_total_length, packet.cap_len);
1209 pcapng_debug("pcapng_read_packet_block: packet data: packet_len %u captured_len %u interface_id %u",
1212 packet.interface_id);
1214 if (packet.interface_id >= pn->interfaces->len) {
1215 *err = WTAP_ERR_BAD_FILE;
1216 *err_info = g_strdup_printf("pcapng_read_packet_block: interface index %u is not less than interface count %u",
1217 packet.interface_id, pn->interfaces->len);
1220 iface_info = g_array_index(pn->interfaces, interface_info_t,
1221 packet.interface_id);
1223 if (packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
1224 *err = WTAP_ERR_BAD_FILE;
1225 *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than %u",
1227 wtap_max_snaplen_for_encap(iface_info.wtap_encap));
1231 wblock->packet_header->rec_type = REC_TYPE_PACKET;
1232 wblock->packet_header->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1234 pcapng_debug("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.",
1235 iface_info.wtap_encap,
1236 wtap_encap_string(iface_info.wtap_encap),
1237 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header));
1238 wblock->packet_header->interface_id = packet.interface_id;
1239 wblock->packet_header->pkt_encap = iface_info.wtap_encap;
1240 wblock->packet_header->pkt_tsprec = iface_info.tsprecision;
1242 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1243 pseudo_header_len = pcap_process_pseudo_header(fh,
1244 WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1245 iface_info.wtap_encap,
1248 wblock->packet_header,
1251 if (pseudo_header_len < 0) {
1254 block_read += pseudo_header_len;
1255 if (pseudo_header_len != pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header)) {
1256 pcapng_debug("pcapng_read_packet_block: Could only read %d bytes for pseudo header.",
1259 wblock->packet_header->caplen = packet.cap_len - pseudo_header_len;
1260 wblock->packet_header->len = packet.packet_len - pseudo_header_len;
1262 /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
1263 ts = (((guint64)packet.ts_high) << 32) | ((guint64)packet.ts_low);
1264 wblock->packet_header->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
1265 wblock->packet_header->ts.nsecs = (int)(((ts % iface_info.time_units_per_second) * 1000000000) / iface_info.time_units_per_second);
1267 /* "(Enhanced) Packet Block" read capture data */
1268 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1269 packet.cap_len - pseudo_header_len, err, err_info))
1271 block_read += packet.cap_len - pseudo_header_len;
1273 /* jump over potential padding bytes at end of the packet data */
1275 if (!wtap_read_bytes(fh, NULL, padding, err, err_info))
1277 block_read += padding;
1280 /* Option defaults */
1281 wblock->packet_header->opt_comment = NULL;
1282 wblock->packet_header->drop_count = -1;
1283 wblock->packet_header->pack_flags = 0;
1285 /* FCS length default */
1286 fcslen = pn->if_fcslen;
1294 to_read = block_total_length -
1295 (int)sizeof(pcapng_block_header_t) -
1296 block_read - /* fixed and variable part, including padding */
1297 (int)sizeof(bh->block_total_length);
1299 /* Allocate enough memory to hold all options */
1300 opt_cont_buf_len = to_read;
1301 ws_buffer_assure_space(&wblock->packet_header->ft_specific_data, opt_cont_buf_len);
1302 opt_ptr = ws_buffer_start_ptr(&wblock->packet_header->ft_specific_data);
1304 while (to_read != 0) {
1306 oh = (pcapng_option_header_t *)(void *)opt_ptr;
1307 option_content = opt_ptr + sizeof (pcapng_option_header_t);
1308 bytes_read = pcapng_read_option(fh, pn, oh, option_content, opt_cont_buf_len, to_read, err, err_info, "packet");
1309 if (bytes_read <= 0) {
1310 pcapng_debug("pcapng_read_packet_block: failed to read option");
1311 /* XXX - free anything? */
1314 block_read += bytes_read;
1315 to_read -= bytes_read;
1317 /* handle option content */
1318 switch (oh->option_code) {
1321 pcapng_debug("pcapng_read_packet_block: %u bytes after opt_endofopt", to_read);
1323 /* padding should be ok here, just get out of this */
1327 if (oh->option_length > 0 && oh->option_length < opt_cont_buf_len) {
1328 wblock->packet_header->presence_flags |= WTAP_HAS_COMMENTS;
1329 wblock->packet_header->opt_comment = g_strndup((char *)option_content, oh->option_length);
1330 pcapng_debug("pcapng_read_packet_block: length %u opt_comment '%s'", oh->option_length, wblock->packet_header->opt_comment);
1332 pcapng_debug("pcapng_read_packet_block: opt_comment length %u seems strange", oh->option_length);
1335 case(OPT_EPB_FLAGS):
1336 if (oh->option_length != 4) {
1337 *err = WTAP_ERR_BAD_FILE;
1338 *err_info = g_strdup_printf("pcapng_read_packet_block: packet block flags option length %u is not 4",
1340 /* XXX - free anything? */
1343 /* Don't cast a guint8 * into a guint32 *--the
1344 * guint8 * may not point to something that's
1345 * aligned correctly.
1347 wblock->packet_header->presence_flags |= WTAP_HAS_PACK_FLAGS;
1348 memcpy(&wblock->packet_header->pack_flags, option_content, sizeof(guint32));
1349 if (pn->byte_swapped) {
1350 wblock->packet_header->pack_flags = GUINT32_SWAP_LE_BE(wblock->packet_header->pack_flags);
1351 memcpy(option_content, &wblock->packet_header->pack_flags, sizeof(guint32));
1353 if (wblock->packet_header->pack_flags & 0x000001E0) {
1354 /* The FCS length is present */
1355 fcslen = (wblock->packet_header->pack_flags & 0x000001E0) >> 5;
1357 pcapng_debug("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->packet_header->pack_flags);
1360 pcapng_debug("pcapng_read_packet_block: epb_hash %u currently not handled - ignoring %u bytes",
1361 oh->option_code, oh->option_length);
1363 case(OPT_EPB_DROPCOUNT):
1364 if (oh->option_length != 8) {
1365 *err = WTAP_ERR_BAD_FILE;
1366 *err_info = g_strdup_printf("pcapng_read_packet_block: packet block drop count option length %u is not 8",
1368 /* XXX - free anything? */
1371 /* Don't cast a guint8 * into a guint64 *--the
1372 * guint8 * may not point to something that's
1373 * aligned correctly.
1375 wblock->packet_header->presence_flags |= WTAP_HAS_DROP_COUNT;
1376 memcpy(&wblock->packet_header->drop_count, option_content, sizeof(guint64));
1377 if (pn->byte_swapped) {
1378 wblock->packet_header->drop_count = GUINT64_SWAP_LE_BE(wblock->packet_header->drop_count);
1379 memcpy(option_content, &wblock->packet_header->drop_count, sizeof(guint64));
1382 pcapng_debug("pcapng_read_packet_block: drop_count %" G_GINT64_MODIFIER "u", wblock->packet_header->drop_count);
1387 * Do we have a handler for this packet block option code?
1389 if (option_handlers[BT_INDEX_PBS] != NULL &&
1390 (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_PBS],
1391 GUINT_TO_POINTER((guint)oh->option_code))) != NULL) {
1392 /* Yes - call the handler. */
1393 if (!handler->hfunc(pn->byte_swapped, oh->option_length,
1394 option_content, err, err_info))
1395 /* XXX - free anything? */
1400 pcapng_debug("pcapng_read_packet_block: unknown option %u - ignoring %u bytes",
1401 oh->option_code, oh->option_length);
1406 pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1407 wblock->packet_header, ws_buffer_start_ptr(wblock->frame_buffer),
1408 pn->byte_swapped, fcslen);
1414 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)
1416 interface_info_t iface_info;
1417 pcapng_simple_packet_block_t spb;
1418 wtapng_simple_packet_t simple_packet;
1419 guint32 block_total_length;
1421 int pseudo_header_len;
1424 * Is this block long enough to be an SPB?
1426 if (bh->block_total_length < MIN_SPB_SIZE) {
1430 *err = WTAP_ERR_BAD_FILE;
1431 *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",
1432 bh->block_total_length, MIN_SPB_SIZE);
1436 /* Don't try to allocate memory for a huge number of options, as
1437 that might fail and, even if it succeeds, it might not leave
1438 any address space or memory+backing store for anything else.
1440 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1441 We check for this *after* checking the SHB for its byte
1442 order magic number, so that non-pcapng files are less
1443 likely to be treated as bad pcapng files. */
1444 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1445 *err = WTAP_ERR_BAD_FILE;
1446 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u is too large (> %u)",
1447 bh->block_total_length, MAX_BLOCK_SIZE);
1451 /* "Simple Packet Block" read fixed part */
1452 if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
1453 pcapng_debug("pcapng_read_simple_packet_block: failed to read packet data");
1457 if (0 >= pn->interfaces->len) {
1458 *err = WTAP_ERR_BAD_FILE;
1459 *err_info = g_strdup("pcapng_read_simple_packet_block: SPB appeared before any IDBs");
1462 iface_info = g_array_index(pn->interfaces, interface_info_t, 0);
1464 if (pn->byte_swapped) {
1465 simple_packet.packet_len = GUINT32_SWAP_LE_BE(spb.packet_len);
1467 simple_packet.packet_len = spb.packet_len;
1471 * The captured length is not a field in the SPB; it can be
1472 * calculated as the minimum of the snapshot length from the
1473 * IDB and the packet length, as per the pcapng spec. An IDB
1474 * snapshot length of 0 means no limit.
1476 simple_packet.cap_len = simple_packet.packet_len;
1477 if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
1478 simple_packet.cap_len = iface_info.snap_len;
1481 * How much padding is there at the end of the packet data?
1483 if ((simple_packet.cap_len % 4) != 0)
1484 padding = 4 - (simple_packet.cap_len % 4);
1488 /* add padding bytes to "block total length" */
1489 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1490 if (bh->block_total_length % 4) {
1491 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1493 block_total_length = bh->block_total_length;
1495 pcapng_debug("pcapng_read_simple_packet_block: block_total_length %d", block_total_length);
1498 * Is this block long enough to hold the packet data?
1500 if (block_total_length < MIN_SPB_SIZE + simple_packet.cap_len + padding) {
1502 * No. That means that the problem is with the packet
1503 * length; the snapshot length can be bigger than the amount
1504 * of packet data in the block, as it's a *maximum* length,
1505 * not a *minimum* length.
1507 *err = WTAP_ERR_BAD_FILE;
1508 *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",
1509 block_total_length, simple_packet.packet_len);
1513 if (simple_packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
1514 *err = WTAP_ERR_BAD_FILE;
1515 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: cap_len %u is larger than %u",
1516 simple_packet.cap_len,
1517 wtap_max_snaplen_for_encap(iface_info.wtap_encap));
1520 pcapng_debug("pcapng_read_simple_packet_block: packet data: packet_len %u",
1521 simple_packet.packet_len);
1523 pcapng_debug("pcapng_read_simple_packet_block: Need to read pseudo header of size %d",
1524 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header));
1526 /* No time stamp in a simple packet block; no options, either */
1527 wblock->packet_header->rec_type = REC_TYPE_PACKET;
1528 wblock->packet_header->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1529 wblock->packet_header->interface_id = 0;
1530 wblock->packet_header->pkt_encap = iface_info.wtap_encap;
1531 wblock->packet_header->pkt_tsprec = iface_info.tsprecision;
1532 wblock->packet_header->ts.secs = 0;
1533 wblock->packet_header->ts.nsecs = 0;
1534 wblock->packet_header->interface_id = 0;
1535 wblock->packet_header->opt_comment = NULL;
1536 wblock->packet_header->drop_count = 0;
1537 wblock->packet_header->pack_flags = 0;
1539 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1540 pseudo_header_len = pcap_process_pseudo_header(fh,
1541 WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1542 iface_info.wtap_encap,
1543 simple_packet.cap_len,
1545 wblock->packet_header,
1548 if (pseudo_header_len < 0) {
1551 wblock->packet_header->caplen = simple_packet.cap_len - pseudo_header_len;
1552 wblock->packet_header->len = simple_packet.packet_len - pseudo_header_len;
1553 if (pseudo_header_len != pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header)) {
1554 pcapng_debug("pcapng_read_simple_packet_block: Could only read %d bytes for pseudo header.",
1558 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1560 /* "Simple Packet Block" read capture data */
1561 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1562 simple_packet.cap_len, err, err_info))
1565 /* jump over potential padding bytes at end of the packet data */
1566 if ((simple_packet.cap_len % 4) != 0) {
1567 if (!wtap_read_bytes(fh, NULL, 4 - (simple_packet.cap_len % 4), err, err_info))
1571 pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1572 wblock->packet_header, ws_buffer_start_ptr(wblock->frame_buffer),
1573 pn->byte_swapped, pn->if_fcslen);
1577 #define NRES_ENDOFRECORD 0
1578 #define NRES_IP4RECORD 1
1579 #define NRES_IP6RECORD 2
1580 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
1581 /* IPv6 + MAXNAMELEN */
1582 #define INITIAL_NRB_REC_SIZE (16 + 64)
1585 * Find the end of the NUL-terminated name the beginning of which is pointed
1586 * to by p; record_len is the number of bytes remaining in the record.
1588 * Return the length of the name, including the terminating NUL.
1590 * If we don't find a terminating NUL, return -1 and set *err and
1591 * *err_info appropriately.
1594 name_resolution_block_find_name_end(const char *p, guint record_len, int *err,
1601 if (record_len == 0) {
1603 * We ran out of bytes in the record without
1606 *err = WTAP_ERR_BAD_FILE;
1607 *err_info = g_strdup("pcapng_read_name_resolution_block: NRB record has non-null-terminated host name");
1611 break; /* that's the terminating NUL */
1614 namelen++; /* count this byte */
1617 /* Include the NUL in the name length. */
1622 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)
1626 pcapng_name_resolution_block_t nrb;
1629 guint record_len, opt_cont_buf_len;
1633 pcapng_option_header_t oh;
1634 guint8 *option_content;
1636 option_handler *handler;
1641 * Is this block long enough to be an NRB?
1643 if (bh->block_total_length < MIN_NRB_SIZE) {
1647 *err = WTAP_ERR_BAD_FILE;
1648 *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",
1649 bh->block_total_length, MIN_NRB_SIZE);
1653 /* Don't try to allocate memory for a huge number of options, as
1654 that might fail and, even if it succeeds, it might not leave
1655 any address space or memory+backing store for anything else.
1657 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1658 We check for this *after* checking the SHB for its byte
1659 order magic number, so that non-pcapng files are less
1660 likely to be treated as bad pcapng files. */
1661 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1662 *err = WTAP_ERR_BAD_FILE;
1663 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: total block length %u is too large (> %u)",
1664 bh->block_total_length, MAX_BLOCK_SIZE);
1668 to_read = bh->block_total_length - 8 - 4; /* We have read the header and should not read the final block_total_length */
1670 pcapng_debug("pcapng_read_name_resolution_block, total %d bytes", bh->block_total_length);
1672 /* Ensure we have a name resolution block */
1673 if (wblock->block == NULL) {
1674 wblock->block = wtap_block_create(WTAP_BLOCK_NG_NRB);
1678 * Start out with a buffer big enough for an IPv6 address and one
1679 * 64-byte name; we'll make the buffer bigger if necessary.
1681 ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
1683 while (block_read < to_read) {
1685 * There must be at least one record's worth of data
1688 if ((size_t)(to_read - block_read) < sizeof nrb) {
1689 ws_buffer_free(&nrb_rec);
1690 *err = WTAP_ERR_BAD_FILE;
1691 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record header size %u",
1692 to_read - block_read,
1696 if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
1697 ws_buffer_free(&nrb_rec);
1698 pcapng_debug("pcapng_read_name_resolution_block: failed to read record header");
1701 block_read += (int)sizeof nrb;
1703 if (pn->byte_swapped) {
1704 nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type);
1705 nrb.record_len = GUINT16_SWAP_LE_BE(nrb.record_len);
1708 if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
1709 ws_buffer_free(&nrb_rec);
1710 *err = WTAP_ERR_BAD_FILE;
1711 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record length + padding %u",
1712 to_read - block_read,
1713 nrb.record_len + PADDING4(nrb.record_len));
1716 switch (nrb.record_type) {
1717 case NRES_ENDOFRECORD:
1718 /* There shouldn't be any more data - but there MAY be options */
1721 case NRES_IP4RECORD:
1723 * The smallest possible record must have
1724 * a 4-byte IPv4 address, hence a minimum
1727 * (The pcapng spec really indicates
1728 * that it must be at least 5 bytes,
1729 * as there must be at least one name,
1730 * and it really must be at least 6
1731 * bytes, as the name mustn't be null,
1732 * but there's no need to fail if there
1733 * aren't any names at all, and we
1734 * should report a null name as such.)
1736 if (nrb.record_len < 4) {
1737 ws_buffer_free(&nrb_rec);
1738 *err = WTAP_ERR_BAD_FILE;
1739 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv4 record %u < minimum length 4",
1743 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1744 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1745 nrb.record_len, err, err_info)) {
1746 ws_buffer_free(&nrb_rec);
1747 pcapng_debug("pcapng_read_name_resolution_block: failed to read IPv4 record data");
1750 block_read += nrb.record_len;
1752 if (pn->add_new_ipv4) {
1754 * Scan through all the names in
1755 * the record and add them.
1758 ws_buffer_start_ptr(&nrb_rec), 4);
1759 /* IPv4 address is in big-endian order in the file always, which is how we store
1760 it internally as well, so don't byte-swap it */
1761 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
1763 namep += namelen, record_len -= namelen) {
1765 * Scan forward for a null
1768 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1769 if (namelen == -1) {
1770 ws_buffer_free(&nrb_rec);
1771 return FALSE; /* fail */
1773 pn->add_new_ipv4(v4_addr, namep);
1777 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
1778 ws_buffer_free(&nrb_rec);
1781 block_read += PADDING4(nrb.record_len);
1783 case NRES_IP6RECORD:
1785 * The smallest possible record must have
1786 * a 16-byte IPv6 address, hence a minimum
1789 * (The pcapng spec really indicates
1790 * that it must be at least 17 bytes,
1791 * as there must be at least one name,
1792 * and it really must be at least 18
1793 * bytes, as the name mustn't be null,
1794 * but there's no need to fail if there
1795 * aren't any names at all, and we
1796 * should report a null name as such.)
1798 if (nrb.record_len < 16) {
1799 ws_buffer_free(&nrb_rec);
1800 *err = WTAP_ERR_BAD_FILE;
1801 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u < minimum length 16",
1805 if (to_read < nrb.record_len) {
1806 ws_buffer_free(&nrb_rec);
1807 *err = WTAP_ERR_BAD_FILE;
1808 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u > remaining data in NRB",
1812 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1813 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1814 nrb.record_len, err, err_info)) {
1815 ws_buffer_free(&nrb_rec);
1818 block_read += nrb.record_len;
1820 if (pn->add_new_ipv6) {
1821 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
1823 namep += namelen, record_len -= namelen) {
1825 * Scan forward for a null
1828 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1829 if (namelen == -1) {
1830 ws_buffer_free(&nrb_rec);
1831 return FALSE; /* fail */
1833 pn->add_new_ipv6(ws_buffer_start_ptr(&nrb_rec),
1838 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
1839 ws_buffer_free(&nrb_rec);
1842 block_read += PADDING4(nrb.record_len);
1845 pcapng_debug("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
1846 if (!wtap_read_bytes(fh, NULL, nrb.record_len + PADDING4(nrb.record_len), err, err_info)) {
1847 ws_buffer_free(&nrb_rec);
1850 block_read += nrb.record_len + PADDING4(nrb.record_len);
1857 to_read -= block_read;
1868 /* Allocate enough memory to hold all options */
1869 opt_cont_buf_len = to_read;
1870 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1871 if (opt_cont_buf_len != 0 && option_content == NULL) {
1872 *err = ENOMEM; /* we assume we're out of memory */
1873 ws_buffer_free(&nrb_rec);
1877 while (to_read != 0) {
1879 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "name_resolution");
1880 if (bytes_read <= 0) {
1881 pcapng_debug("pcapng_read_name_resolution_block: failed to read option");
1882 g_free(option_content);
1883 ws_buffer_free(&nrb_rec);
1886 to_read -= bytes_read;
1888 /* handle option content */
1889 switch (oh.option_code) {
1892 pcapng_debug("pcapng_read_name_resolution_block: %u bytes after opt_endofopt", to_read);
1894 /* padding should be ok here, just get out of this */
1898 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1899 tmp_content = g_strndup((char *)option_content, oh.option_length);
1900 wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1901 pcapng_debug("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, tmp_content);
1902 g_free(tmp_content);
1904 pcapng_debug("pcapng_read_name_resolution_block: opt_comment length %u seems strange", oh.option_length);
1910 * Do we have a handler for this network resolution block option code?
1912 if (option_handlers[BT_INDEX_NRB] != NULL &&
1913 (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_NRB],
1914 GUINT_TO_POINTER((guint)oh.option_code))) != NULL) {
1915 /* Yes - call the handler. */
1916 if (!handler->hfunc(pn->byte_swapped, oh.option_length,
1917 option_content, err, err_info)) {
1919 g_free(option_content);
1920 ws_buffer_free(&nrb_rec);
1926 pcapng_debug("pcapng_read_name_resolution_block: unknown option %u - ignoring %u bytes",
1927 oh.option_code, oh.option_length);
1932 g_free(option_content);
1933 ws_buffer_free(&nrb_rec);
1938 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)
1941 guint to_read, opt_cont_buf_len;
1942 pcapng_interface_statistics_block_t isb;
1943 pcapng_option_header_t oh;
1944 guint8 *option_content = NULL; /* Allocate as large as the options block */
1945 wtapng_if_stats_mandatory_t* if_stats_mand;
1949 * Is this block long enough to be an ISB?
1951 if (bh->block_total_length < MIN_ISB_SIZE) {
1955 *err = WTAP_ERR_BAD_FILE;
1956 *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too small (< %u)",
1957 bh->block_total_length, MIN_ISB_SIZE);
1961 /* Don't try to allocate memory for a huge number of options, as
1962 that might fail and, even if it succeeds, it might not leave
1963 any address space or memory+backing store for anything else.
1965 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1966 We check for this *after* checking the SHB for its byte
1967 order magic number, so that non-pcapng files are less
1968 likely to be treated as bad pcapng files. */
1969 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1970 *err = WTAP_ERR_BAD_FILE;
1971 *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too large (> %u)",
1972 bh->block_total_length, MAX_BLOCK_SIZE);
1976 /* "Interface Statistics Block" read fixed part */
1977 if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
1978 pcapng_debug("pcapng_read_interface_statistics_block: failed to read packet data");
1982 wblock->block = wtap_block_create(WTAP_BLOCK_IF_STATS);
1983 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1984 if (pn->byte_swapped) {
1985 if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
1986 if_stats_mand->ts_high = GUINT32_SWAP_LE_BE(isb.timestamp_high);
1987 if_stats_mand->ts_low = GUINT32_SWAP_LE_BE(isb.timestamp_low);
1989 if_stats_mand->interface_id = isb.interface_id;
1990 if_stats_mand->ts_high = isb.timestamp_high;
1991 if_stats_mand->ts_low = isb.timestamp_low;
1993 pcapng_debug("pcapng_read_interface_statistics_block: interface_id %u", if_stats_mand->interface_id);
1996 to_read = bh->block_total_length -
1997 (MIN_BLOCK_SIZE + (guint)sizeof isb); /* fixed and variable part, including padding */
1999 /* Allocate enough memory to hold all options */
2000 opt_cont_buf_len = to_read;
2001 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
2002 if (opt_cont_buf_len != 0 && option_content == NULL) {
2003 *err = ENOMEM; /* we assume we're out of memory */
2007 while (to_read != 0) {
2009 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "interface_statistics");
2010 if (bytes_read <= 0) {
2011 pcapng_debug("pcapng_read_interface_statistics_block: failed to read option");
2014 to_read -= bytes_read;
2016 /* handle option content */
2017 switch (oh.option_code) {
2018 case(OPT_EOFOPT): /* opt_endofopt */
2020 pcapng_debug("pcapng_read_interface_statistics_block: %u bytes after opt_endofopt", to_read);
2022 /* padding should be ok here, just get out of this */
2025 case(OPT_COMMENT): /* opt_comment */
2026 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
2027 tmp_content = g_strndup((char *)option_content, oh.option_length);
2028 wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
2029 pcapng_debug("pcapng_read_interface_statistics_block: opt_comment %s", tmp_content);
2030 g_free(tmp_content);
2032 pcapng_debug("pcapng_read_interface_statistics_block: opt_comment length %u seems strange", oh.option_length);
2035 case(OPT_ISB_STARTTIME): /* isb_starttime */
2036 if (oh.option_length == 8) {
2040 /* Don't cast a guint8 * into a guint32 *--the
2041 * guint8 * may not point to something that's
2042 * aligned correctly.
2044 memcpy(&high, option_content, sizeof(guint32));
2045 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
2046 if (pn->byte_swapped) {
2047 high = GUINT32_SWAP_LE_BE(high);
2048 low = GUINT32_SWAP_LE_BE(low);
2050 starttime = (guint64)high;
2052 starttime += (guint64)low;
2053 /* Fails with multiple options; we silently ignore the failure */
2054 wtap_block_add_uint64_option(wblock->block, OPT_ISB_STARTTIME, starttime);
2055 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime %" G_GINT64_MODIFIER "u", starttime);
2057 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2060 case(OPT_ISB_ENDTIME): /* isb_endtime */
2061 if (oh.option_length == 8) {
2065 /* Don't cast a guint8 * into a guint32 *--the
2066 * guint8 * may not point to something that's
2067 * aligned correctly.
2069 memcpy(&high, option_content, sizeof(guint32));
2070 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
2071 if (pn->byte_swapped) {
2072 high = GUINT32_SWAP_LE_BE(high);
2073 low = GUINT32_SWAP_LE_BE(low);
2075 endtime = (guint64)high;
2077 endtime += (guint64)low;
2078 /* Fails with multiple options; we silently ignore the failure */
2079 wtap_block_add_uint64_option(wblock->block, OPT_ISB_ENDTIME, endtime);
2080 pcapng_debug("pcapng_read_interface_statistics_block: isb_endtime %" G_GINT64_MODIFIER "u", endtime);
2082 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2085 case(OPT_ISB_IFRECV): /* isb_ifrecv */
2086 if (oh.option_length == 8) {
2088 /* Don't cast a guint8 * into a guint64 *--the
2089 * guint8 * may not point to something that's
2090 * aligned correctly.
2092 memcpy(&ifrecv, option_content, sizeof(guint64));
2093 if (pn->byte_swapped)
2094 ifrecv = GUINT64_SWAP_LE_BE(ifrecv);
2095 /* Fails with multiple options; we silently ignore the failure */
2096 wtap_block_add_uint64_option(wblock->block, OPT_ISB_IFRECV, ifrecv);
2097 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", ifrecv);
2099 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv length %u not 8 as expected", oh.option_length);
2102 case(OPT_ISB_IFDROP): /* isb_ifdrop */
2103 if (oh.option_length == 8) {
2105 /* Don't cast a guint8 * into a guint64 *--the
2106 * guint8 * may not point to something that's
2107 * aligned correctly.
2109 memcpy(&ifdrop, option_content, sizeof(guint64));
2110 if (pn->byte_swapped)
2111 ifdrop = GUINT64_SWAP_LE_BE(ifdrop);
2112 /* Fails with multiple options; we silently ignore the failure */
2113 wtap_block_add_uint64_option(wblock->block, OPT_ISB_IFDROP, ifdrop);
2114 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", ifdrop);
2116 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop length %u not 8 as expected", oh.option_length);
2119 case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
2120 if (oh.option_length == 8) {
2121 guint64 filteraccept;
2122 /* Don't cast a guint8 * into a guint64 *--the
2123 * guint8 * may not point to something that's
2124 * aligned correctly.
2126 memcpy(&filteraccept, option_content, sizeof(guint64));
2127 if (pn->byte_swapped)
2128 filteraccept = GUINT64_SWAP_LE_BE(filteraccept);
2129 /* Fails with multiple options; we silently ignore the failure */
2130 wtap_block_add_uint64_option(wblock->block, OPT_ISB_FILTERACCEPT, filteraccept);
2131 pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept %" G_GINT64_MODIFIER "u", filteraccept);
2133 pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept length %u not 8 as expected", oh.option_length);
2136 case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
2137 if (oh.option_length == 8) {
2139 /* Don't cast a guint8 * into a guint64 *--the
2140 * guint8 * may not point to something that's
2141 * aligned correctly.
2143 memcpy(&osdrop, option_content, sizeof(guint64));
2144 if (pn->byte_swapped)
2145 osdrop = GUINT64_SWAP_LE_BE(osdrop);
2146 /* Fails with multiple options; we silently ignore the failure */
2147 wtap_block_add_uint64_option(wblock->block, OPT_ISB_OSDROP, osdrop);
2148 pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop %" G_GINT64_MODIFIER "u", osdrop);
2150 pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop length %u not 8 as expected", oh.option_length);
2153 case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8 */
2154 if (oh.option_length == 8) {
2156 /* Don't cast a guint8 * into a guint64 *--the
2157 * guint8 * may not point to something that's
2158 * aligned correctly.
2160 memcpy(&usrdeliv, option_content, sizeof(guint64));
2161 if (pn->byte_swapped)
2162 usrdeliv = GUINT64_SWAP_LE_BE(usrdeliv);
2163 /* Fails with multiple options; we silently ignore the failure */
2164 wtap_block_add_uint64_option(wblock->block, OPT_ISB_USRDELIV, usrdeliv);
2165 pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv %" G_GINT64_MODIFIER "u", usrdeliv);
2167 pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv length %u not 8 as expected", oh.option_length);
2171 pcapng_debug("pcapng_read_interface_statistics_block: unknown option %u - ignoring %u bytes",
2172 oh.option_code, oh.option_length);
2176 g_free(option_content);
2182 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)
2184 unsigned block_read;
2185 guint32 block_total_length;
2193 if (bh->block_total_length < MIN_SYSDIG_EVENT_SIZE) {
2194 *err = WTAP_ERR_BAD_FILE;
2195 *err_info = g_strdup_printf("%s: total block length %u is too small (< %u)", G_STRFUNC,
2196 bh->block_total_length, MIN_SYSDIG_EVENT_SIZE);
2200 /* add padding bytes to "block total length" */
2201 /* (the "block total length" of some example files don't contain any padding bytes!) */
2202 if (bh->block_total_length % 4) {
2203 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2205 block_total_length = bh->block_total_length;
2208 pcapng_debug("pcapng_read_sysdig_event_block: block_total_length %u",
2209 bh->block_total_length);
2211 wblock->packet_header->rec_type = REC_TYPE_SYSCALL;
2212 wblock->packet_header->pseudo_header.sysdig_event.record_type = BLOCK_TYPE_SYSDIG_EVENT;
2213 wblock->packet_header->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
2214 wblock->packet_header->pkt_tsprec = WTAP_TSPREC_NSEC;
2216 block_read = block_total_length;
2218 if (!wtap_read_bytes(fh, &cpu_id, sizeof cpu_id, err, err_info)) {
2219 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event cpu id");
2222 if (!wtap_read_bytes(fh, &wire_ts, sizeof wire_ts, err, err_info)) {
2223 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event timestamp");
2226 if (!wtap_read_bytes(fh, &thread_id, sizeof thread_id, err, err_info)) {
2227 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event thread id");
2230 if (!wtap_read_bytes(fh, &event_len, sizeof event_len, err, err_info)) {
2231 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event length");
2234 if (!wtap_read_bytes(fh, &event_type, sizeof event_type, err, err_info)) {
2235 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event type");
2239 block_read -= MIN_SYSDIG_EVENT_SIZE;
2240 wblock->packet_header->pseudo_header.sysdig_event.byte_order = G_BYTE_ORDER;
2242 /* XXX Use Gxxx_FROM_LE macros instead? */
2243 if (pn->byte_swapped) {
2244 wblock->packet_header->pseudo_header.sysdig_event.byte_order =
2245 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2250 wblock->packet_header->pseudo_header.sysdig_event.cpu_id = GUINT16_SWAP_LE_BE(cpu_id);
2251 ts = GUINT64_SWAP_LE_BE(wire_ts);
2252 wblock->packet_header->pseudo_header.sysdig_event.thread_id = GUINT64_SWAP_LE_BE(thread_id);
2253 wblock->packet_header->pseudo_header.sysdig_event.event_len = GUINT32_SWAP_LE_BE(event_len);
2254 wblock->packet_header->pseudo_header.sysdig_event.event_type = GUINT16_SWAP_LE_BE(event_type);
2256 wblock->packet_header->pseudo_header.sysdig_event.cpu_id = cpu_id;
2258 wblock->packet_header->pseudo_header.sysdig_event.thread_id = thread_id;
2259 wblock->packet_header->pseudo_header.sysdig_event.event_len = event_len;
2260 wblock->packet_header->pseudo_header.sysdig_event.event_type = event_type;
2263 wblock->packet_header->ts.secs = (time_t) (ts / 1000000000);
2264 wblock->packet_header->ts.nsecs = (int) (ts % 1000000000);
2266 wblock->packet_header->caplen = block_read;
2267 wblock->packet_header->len = wblock->packet_header->pseudo_header.sysdig_event.event_len;
2269 /* "Sysdig Event Block" read event data */
2270 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2271 block_read, err, err_info))
2274 /* XXX Read comment? */
2280 pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh,
2284 wtapng_block_t *wblock,
2287 wtapng_block_t *wblock _U_,
2289 int *err, gchar **err_info)
2292 guint32 block_total_length;
2294 block_handler *handler;
2297 if (bh->block_total_length < MIN_BLOCK_SIZE) {
2298 *err = WTAP_ERR_BAD_FILE;
2299 *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",
2300 bh->block_total_length, MIN_BLOCK_SIZE);
2304 /* add padding bytes to "block total length" */
2305 /* (the "block total length" of some example files don't contain any padding bytes!) */
2306 if (bh->block_total_length % 4) {
2307 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2309 block_total_length = bh->block_total_length;
2312 block_read = block_total_length - MIN_BLOCK_SIZE;
2316 * Do we have a handler for this block type?
2318 if (block_handlers != NULL &&
2319 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
2320 GUINT_TO_POINTER(bh->block_type))) != NULL) {
2321 /* Yes - call it to read this block type. */
2322 if (!handler->reader(fh, block_read, pn->byte_swapped,
2323 wblock->packet_header, wblock->frame_buffer,
2329 /* No. Skip over this unknown block. */
2330 if (!wtap_read_bytes(fh, NULL, block_read, err, err_info)) {
2339 static block_return_val
2340 pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
2342 block_return_val ret;
2343 pcapng_block_header_t bh;
2344 guint32 block_total_length;
2346 wblock->block = NULL;
2348 /* Try to read the (next) block header */
2349 if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
2350 pcapng_debug("pcapng_read_block: wtap_read_bytes_or_eof() failed, err = %d.", *err);
2351 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
2353 * Short read or EOF.
2355 * If we're reading this as part of an open,
2356 * the file is too short to be a pcapng file.
2358 * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
2359 * PCAPNG_BLOCK_ERROR the same, so we can just return
2360 * PCAPNG_BLOCK_NOT_SHB in both cases.
2362 return PCAPNG_BLOCK_NOT_SHB;
2364 return PCAPNG_BLOCK_ERROR;
2368 * SHBs have to be treated differently from other blocks, as we
2369 * might be doing an open and attempting to read a block at the
2370 * beginning of the file to see if it's a pcapng file or not,
2371 * and as they do not necessarily have the same byte order as
2374 if (bh.block_type == BLOCK_TYPE_SHB) {
2376 * BLOCK_TYPE_SHB has the same value regardless of byte order,
2377 * so we don't need to byte-swap it.
2379 wblock->type = bh.block_type;
2381 pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2383 ret = pcapng_read_section_header_block(fh, &bh, pn, wblock, err, err_info);
2384 if (ret != PCAPNG_BLOCK_OK) {
2388 if (pn->byte_swapped) {
2389 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
2390 bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length);
2393 wblock->type = bh.block_type;
2395 pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2397 if (!pn->shb_read) {
2399 * No SHB seen yet, so we're trying to read the first block
2400 * during an open, to see whether it's an SHB; if what we
2401 * read doesn't look like an SHB, this isn't a pcapng file.
2405 return PCAPNG_BLOCK_NOT_SHB;
2407 switch (bh.block_type) {
2408 case(BLOCK_TYPE_IDB):
2409 if (!pcapng_read_if_descr_block(wth, fh, &bh, pn, wblock, err, err_info))
2410 return PCAPNG_BLOCK_ERROR;
2412 case(BLOCK_TYPE_PB):
2413 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE))
2414 return PCAPNG_BLOCK_ERROR;
2416 case(BLOCK_TYPE_SPB):
2417 if (!pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info))
2418 return PCAPNG_BLOCK_ERROR;
2420 case(BLOCK_TYPE_EPB):
2421 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE))
2422 return PCAPNG_BLOCK_ERROR;
2424 case(BLOCK_TYPE_NRB):
2425 if (!pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info))
2426 return PCAPNG_BLOCK_ERROR;
2428 case(BLOCK_TYPE_ISB):
2429 if (!pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info))
2430 return PCAPNG_BLOCK_ERROR;
2432 case(BLOCK_TYPE_SYSDIG_EVENT):
2433 /* case(BLOCK_TYPE_SYSDIG_EVF): */
2434 if (!pcapng_read_sysdig_event_block(fh, &bh, pn, wblock, err, err_info))
2435 return PCAPNG_BLOCK_ERROR;
2438 pcapng_debug("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
2439 if (!pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info))
2440 return PCAPNG_BLOCK_ERROR;
2445 /* sanity check: first and second block lengths must match */
2446 if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
2448 pcapng_debug("pcapng_check_block_trailer: couldn't read second block length");
2449 return PCAPNG_BLOCK_ERROR;
2452 if (pn->byte_swapped)
2453 block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
2455 if (block_total_length != bh.block_total_length) {
2456 *err = WTAP_ERR_BAD_FILE;
2457 *err_info = g_strdup_printf("pcapng_check_block_trailer: total block lengths (first %u and second %u) don't match",
2458 bh.block_total_length, block_total_length);
2459 return PCAPNG_BLOCK_ERROR;
2461 return PCAPNG_BLOCK_OK;
2464 /* Process an IDB that we've just read. The contents of wblock are copied as needed. */
2466 pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
2468 wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_DESCR);
2469 interface_info_t iface_info;
2470 wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data),
2471 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
2473 wtap_block_copy(int_data, wblock->block);
2475 /* XXX if_tsoffset; opt 14 A 64 bits integer value that specifies an offset (in seconds)...*/
2476 /* Interface statistics */
2477 if_descr_mand->num_stat_entries = 0;
2478 if_descr_mand->interface_statistics = NULL;
2480 g_array_append_val(wth->interface_data, int_data);
2482 iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
2483 iface_info.snap_len = wblock_if_descr_mand->snap_len;
2484 iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
2485 iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
2487 g_array_append_val(pcapng->interfaces, iface_info);
2490 /* classic wtap: open capture file */
2491 wtap_open_return_val
2492 pcapng_open(wtap *wth, int *err, gchar **err_info)
2495 wtapng_block_t wblock;
2497 pcapng_block_header_t bh;
2498 gint64 saved_offset;
2500 pn.shb_read = FALSE;
2501 /* we don't know the byte swapping of the file yet */
2502 pn.byte_swapped = FALSE;
2504 pn.version_major = -1;
2505 pn.version_minor = -1;
2506 pn.interfaces = NULL;
2508 /* we don't expect any packet blocks yet */
2509 wblock.frame_buffer = NULL;
2510 wblock.packet_header = NULL;
2512 pcapng_debug("pcapng_open: opening file");
2513 /* read first block */
2514 switch (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info)) {
2516 case PCAPNG_BLOCK_OK:
2520 case PCAPNG_BLOCK_NOT_SHB:
2521 /* An error indicating that this isn't a pcapng file. */
2522 wtap_block_free(wblock.block);
2525 return WTAP_OPEN_NOT_MINE;
2527 case PCAPNG_BLOCK_ERROR:
2528 /* An I/O error, or this probably *is* a pcapng file but not a valid one. */
2529 wtap_block_free(wblock.block);
2530 return WTAP_OPEN_ERROR;
2533 /* first block must be a "Section Header Block" */
2534 if (wblock.type != BLOCK_TYPE_SHB) {
2536 * XXX - check for damage from transferring a file
2537 * between Windows and UN*X as text rather than
2540 pcapng_debug("pcapng_open: first block type %u not SHB", wblock.type);
2541 wtap_block_free(wblock.block);
2542 return WTAP_OPEN_NOT_MINE;
2547 * At this point, we've decided this is a pcapng file, not
2548 * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
2551 wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0), wblock.block);
2552 wtap_block_free(wblock.block);
2553 wblock.block = NULL;
2555 wth->file_encap = WTAP_ENCAP_UNKNOWN;
2556 wth->snapshot_length = 0;
2557 wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
2558 pcapng = (pcapng_t *)g_malloc(sizeof(pcapng_t));
2559 wth->priv = (void *)pcapng;
2561 pcapng->interfaces = g_array_new(FALSE, FALSE, sizeof(interface_info_t));
2563 wth->subtype_read = pcapng_read;
2564 wth->subtype_seek_read = pcapng_seek_read;
2565 wth->subtype_close = pcapng_close;
2566 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
2568 /* Loop over all IDB:s that appear before any packets */
2570 /* peek at next block */
2571 /* Try to read the (next) block header */
2572 saved_offset = file_tell(wth->fh);
2573 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
2576 pcapng_debug("No more IDBs available...");
2579 pcapng_debug("pcapng_open: Check for more IDB:s, wtap_read_bytes_or_eof() failed, err = %d.", *err);
2580 return WTAP_OPEN_ERROR;
2583 /* go back to where we were */
2584 file_seek(wth->fh, saved_offset, SEEK_SET, err);
2586 if (pn.byte_swapped) {
2587 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
2590 pcapng_debug("pcapng_open: Check for more IDB:s block_type 0x%x", bh.block_type);
2592 if (bh.block_type != BLOCK_TYPE_IDB) {
2593 break; /* No more IDB:s */
2595 if (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2596 wtap_block_free(wblock.block);
2598 pcapng_debug("No more IDBs available...");
2601 pcapng_debug("pcapng_open: couldn't read IDB");
2602 return WTAP_OPEN_ERROR;
2605 pcapng_process_idb(wth, pcapng, &wblock);
2606 wtap_block_free(wblock.block);
2607 pcapng_debug("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i",
2608 wth->interface_data->len, wth->file_encap);
2610 return WTAP_OPEN_MINE;
2614 /* classic wtap: read packet */
2616 pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
2618 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2619 wtapng_block_t wblock;
2620 wtap_block_t wtapng_if_descr;
2621 wtap_block_t if_stats;
2622 wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
2623 wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
2625 wblock.frame_buffer = wth->frame_buffer;
2626 wblock.packet_header = &wth->phdr;
2628 pcapng->add_new_ipv4 = wth->add_new_ipv4;
2629 pcapng->add_new_ipv6 = wth->add_new_ipv6;
2631 /* read next block */
2633 *data_offset = file_tell(wth->fh);
2634 pcapng_debug("pcapng_read: data_offset is %" G_GINT64_MODIFIER "d", *data_offset);
2635 if (pcapng_read_block(wth, wth->fh, pcapng, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2636 pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2637 pcapng_debug("pcapng_read: couldn't read packet block");
2638 wtap_block_free(wblock.block);
2642 switch (wblock.type) {
2644 case(BLOCK_TYPE_SHB):
2645 pcapng_debug("pcapng_read: another section header block");
2646 g_array_append_val(wth->shb_hdrs, wblock.block);
2649 case(BLOCK_TYPE_PB):
2650 case(BLOCK_TYPE_SPB):
2651 case(BLOCK_TYPE_EPB):
2652 case(BLOCK_TYPE_SYSDIG_EVENT):
2653 case(BLOCK_TYPE_SYSDIG_EVF):
2654 /* packet block - we've found a packet */
2657 case(BLOCK_TYPE_IDB):
2658 /* A new interface */
2659 pcapng_debug("pcapng_read: block type BLOCK_TYPE_IDB");
2660 pcapng_process_idb(wth, pcapng, &wblock);
2661 wtap_block_free(wblock.block);
2664 case(BLOCK_TYPE_NRB):
2665 /* More name resolution entries */
2666 pcapng_debug("pcapng_read: block type BLOCK_TYPE_NRB");
2667 if (wth->nrb_hdrs == NULL) {
2668 wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
2670 g_array_append_val(wth->nrb_hdrs, wblock.block);
2673 case(BLOCK_TYPE_ISB):
2675 * Another interface statistics report
2677 * XXX - given that they're reports, we should be
2678 * supplying them in read calls, and displaying them
2679 * in the "packet" list, so you can see what the
2680 * statistics were *at the time when the report was
2683 * The statistics from the *last* ISB could be displayed
2684 * in the summary, but if there are packets after the
2685 * last ISB, that could be misleading.
2687 * If we only display them if that ISB has an isb_endtime
2688 * option, which *should* only appear when capturing ended
2689 * on that interface (so there should be no more packet
2690 * blocks or ISBs for that interface after that point,
2691 * that would be the best way of showing "summary"
2694 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB");
2695 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock.block);
2696 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
2697 pcapng_debug("pcapng_read: BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces", if_stats_mand_block->interface_id);
2699 /* Get the interface description */
2700 wtapng_if_descr = g_array_index(wth->interface_data, wtap_block_t, if_stats_mand_block->interface_id);
2701 wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
2702 if (wtapng_if_descr_mand->num_stat_entries == 0) {
2703 /* First ISB found, no previous entry */
2704 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
2705 wtapng_if_descr_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
2708 if_stats = wtap_block_create(WTAP_BLOCK_IF_STATS);
2709 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
2710 if_stats_mand->interface_id = if_stats_mand_block->interface_id;
2711 if_stats_mand->ts_high = if_stats_mand_block->ts_high;
2712 if_stats_mand->ts_low = if_stats_mand_block->ts_low;
2714 wtap_block_copy(if_stats, wblock.block);
2715 g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
2716 wtapng_if_descr_mand->num_stat_entries++;
2718 wtap_block_free(wblock.block);
2722 /* XXX - improve handling of "unknown" blocks */
2723 pcapng_debug("pcapng_read: Unknown block type 0x%08x", wblock.type);
2730 /*pcapng_debug("Read length: %u Packet length: %u", bytes_read, wth->phdr.caplen);*/
2731 pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2737 /* classic wtap: seek to file position and read packet */
2739 pcapng_seek_read(wtap *wth, gint64 seek_off,
2740 struct wtap_pkthdr *phdr, Buffer *buf,
2741 int *err, gchar **err_info)
2743 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2744 block_return_val ret;
2745 wtapng_block_t wblock;
2748 /* seek to the right file position */
2749 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
2750 return FALSE; /* Seek error */
2752 pcapng_debug("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
2754 wblock.frame_buffer = buf;
2755 wblock.packet_header = phdr;
2757 /* read the block */
2758 ret = pcapng_read_block(wth, wth->random_fh, pcapng, &wblock, err, err_info);
2759 wtap_block_free(wblock.block);
2760 if (ret != PCAPNG_BLOCK_OK) {
2761 pcapng_debug("pcapng_seek_read: couldn't read packet block (err=%d).",
2766 /* block must be a "Packet Block", an "Enhanced Packet Block",
2767 a "Simple Packet Block", or an event */
2768 if (wblock.type != BLOCK_TYPE_PB && wblock.type != BLOCK_TYPE_EPB &&
2769 wblock.type != BLOCK_TYPE_SPB &&
2770 wblock.type != BLOCK_TYPE_SYSDIG_EVENT && wblock.type != BLOCK_TYPE_SYSDIG_EVF) {
2771 pcapng_debug("pcapng_seek_read: block type %u not PB/EPB/SPB", wblock.type);
2779 /* classic wtap: close capture file */
2781 pcapng_close(wtap *wth)
2783 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2785 pcapng_debug("pcapng_close: closing file");
2786 g_array_free(pcapng->interfaces, TRUE);
2789 typedef struct pcapng_block_size_t
2792 } pcapng_block_size_t;
2794 static guint32 pcapng_compute_option_string_size(char *str)
2796 guint32 size = 0, pad;
2798 size = (guint32)strlen(str) & 0xffff;
2800 pad = 4 - (size % 4);
2810 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)
2812 pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
2818 case OPT_SHB_HARDWARE:
2820 case OPT_SHB_USERAPPL:
2821 size = pcapng_compute_option_string_size(optval->stringval);
2824 /* Unknown options - size by datatype? */
2828 block_size->size += size;
2829 /* Add bytes for option header if option should be written */
2831 /* Add optional padding to 32 bits */
2832 if ((block_size->size & 0x03) != 0)
2834 block_size->size += 4 - (block_size->size & 0x03);
2836 block_size->size += 4;
2840 typedef struct pcapng_write_block_t
2846 pcapng_write_block_t;
2848 static gboolean pcapng_write_option_string(wtap_dumper *wdh, guint option_id, char *str, int *err)
2850 struct pcapng_option_header option_hdr;
2851 guint32 size = (guint32)strlen(str) & 0xffff;
2852 const guint32 zero_pad = 0;
2858 /* String options don't consider pad bytes part of the length */
2859 option_hdr.type = (guint16)option_id;
2860 option_hdr.value_length = (guint16)size;
2861 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2863 wdh->bytes_dumped += 4;
2865 if (!wtap_dump_file_write(wdh, str, size, err))
2867 wdh->bytes_dumped += size;
2870 pad = 4 - (size % 4);
2875 /* write padding (if any) */
2877 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
2880 wdh->bytes_dumped += pad;
2886 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)
2888 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
2890 /* Don't continue if there has been an error */
2891 if (!write_block->success)
2897 case OPT_SHB_HARDWARE:
2899 case OPT_SHB_USERAPPL:
2900 if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
2901 write_block->success = FALSE;
2906 /* Unknown options - write by datatype? */
2911 /* Write a section header block.
2912 * If we don't have a section block header already, create a default
2913 * one with no options.
2916 pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
2918 pcapng_block_header_t bh;
2919 pcapng_section_header_block_t shb;
2920 pcapng_block_size_t block_size;
2921 struct pcapng_option_header option_hdr;
2922 wtap_block_t wdh_shb = NULL;
2924 if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
2925 wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0);
2928 block_size.size = 0;
2929 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + 4);
2931 pcapng_debug("pcapng_write_section_header_block: Have shb_hdr");
2933 /* Compute block size */
2934 wtap_block_foreach_option(wdh_shb, compute_shb_option_size, &block_size);
2936 if (block_size.size > 0) {
2937 /* End-of-options tag */
2938 block_size.size += 4;
2941 bh.block_total_length += block_size.size;
2944 pcapng_debug("pcapng_write_section_header_block: Total len %u", bh.block_total_length);
2946 /* write block header */
2947 bh.block_type = BLOCK_TYPE_SHB;
2949 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
2951 wdh->bytes_dumped += sizeof bh;
2953 /* write block fixed content */
2954 shb.magic = 0x1A2B3C4D;
2955 shb.version_major = 1;
2956 shb.version_minor = 0;
2958 wtapng_mandatory_section_t* section_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(wdh_shb);
2959 shb.section_length = section_data->section_length;
2961 shb.section_length = -1;
2964 if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
2966 wdh->bytes_dumped += sizeof shb;
2969 pcapng_write_block_t block_data;
2971 if (block_size.size > 0) {
2973 block_data.wdh = wdh;
2974 block_data.err = err;
2975 block_data.success = TRUE;
2976 wtap_block_foreach_option(wdh_shb, write_wtap_shb_option, &block_data);
2978 if (!block_data.success)
2981 /* Write end of options */
2982 option_hdr.type = OPT_EOFOPT;
2983 option_hdr.value_length = 0;
2984 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2986 wdh->bytes_dumped += 4;
2990 /* write block footer */
2991 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
2992 sizeof bh.block_total_length, err))
2994 wdh->bytes_dumped += sizeof bh.block_total_length;
3000 pcapng_write_enhanced_packet_block(wtap_dumper *wdh,
3001 const struct wtap_pkthdr *phdr,
3002 const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err)
3004 pcapng_block_header_t bh;
3005 pcapng_enhanced_packet_block_t epb;
3007 const guint32 zero_pad = 0;
3010 gboolean have_options = FALSE;
3011 guint32 options_total_length = 0;
3012 struct option option_hdr;
3013 guint32 comment_len = 0, comment_pad_len = 0;
3014 wtap_block_t int_data;
3015 wtapng_if_descr_mandatory_t *int_data_mand;
3017 /* Don't write anything we're not willing to read. */
3018 if (phdr->caplen > wtap_max_snaplen_for_encap(wdh->encap)) {
3019 *err = WTAP_ERR_PACKET_TOO_LARGE;
3023 phdr_len = (guint32)pcap_get_phdr_size(phdr->pkt_encap, pseudo_header);
3024 if ((phdr_len + phdr->caplen) % 4) {
3025 pad_len = 4 - ((phdr_len + phdr->caplen) % 4);
3030 /* Check if we should write comment option */
3031 if (phdr->opt_comment) {
3032 have_options = TRUE;
3033 comment_len = (guint32)strlen(phdr->opt_comment) & 0xffff;
3034 if ((comment_len % 4)) {
3035 comment_pad_len = 4 - (comment_len % 4);
3037 comment_pad_len = 0;
3039 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3041 if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
3042 have_options = TRUE;
3043 options_total_length = options_total_length + 8;
3046 /* End-of options tag */
3047 options_total_length += 4;
3050 /* write (enhanced) packet block header */
3051 bh.block_type = BLOCK_TYPE_EPB;
3052 bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + phdr->caplen + pad_len + options_total_length + 4;
3054 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3056 wdh->bytes_dumped += sizeof bh;
3058 /* write block fixed content */
3059 if (phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
3060 epb.interface_id = phdr->interface_id;
3063 * XXX - we should support writing WTAP_ENCAP_PER_PACKET
3064 * data to pcapng files even if we *don't* have interface
3067 epb.interface_id = 0;
3070 * Split the 64-bit timestamp into two 32-bit pieces, using
3071 * the time stamp resolution for the interface.
3073 if (epb.interface_id >= wdh->interface_data->len) {
3075 * Our caller is doing something bad.
3077 *err = WTAP_ERR_INTERNAL;
3080 int_data = g_array_index(wdh->interface_data, wtap_block_t,
3082 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
3083 ts = ((guint64)phdr->ts.secs) * int_data_mand->time_units_per_second +
3084 (((guint64)phdr->ts.nsecs) * int_data_mand->time_units_per_second) / 1000000000;
3085 epb.timestamp_high = (guint32)(ts >> 32);
3086 epb.timestamp_low = (guint32)ts;
3087 epb.captured_len = phdr->caplen + phdr_len;
3088 epb.packet_len = phdr->len + phdr_len;
3090 if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
3092 wdh->bytes_dumped += sizeof epb;
3094 /* write pseudo header */
3095 if (!pcap_write_phdr(wdh, phdr->pkt_encap, pseudo_header, err)) {
3098 wdh->bytes_dumped += phdr_len;
3100 /* write packet data */
3101 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
3103 wdh->bytes_dumped += phdr->caplen;
3105 /* write padding (if any) */
3107 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3109 wdh->bytes_dumped += pad_len;
3112 /* XXX - write (optional) block options */
3113 /* options defined in Section 2.5 (Options)
3114 * Name Code Length Description
3115 * opt_comment 1 variable A UTF-8 string containing a comment that is associated to the current block.
3117 * Enhanced Packet Block options
3118 * epb_flags 2 4 A flags word containing link-layer information. A complete specification of
3119 * the allowed flags can be found in Appendix A (Packet Block Flags Word).
3120 * epb_hash 3 variable This option contains a hash of the packet. The first byte specifies the hashing algorithm,
3121 * while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
3122 * and hence from the value in the first bit. The hashing algorithm can be: 2s complement
3123 * (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
3124 * MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
3125 * The hash covers only the packet, not the header added by the capture driver:
3126 * this gives the possibility to calculate it inside the network card.
3127 * The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
3128 * data acquisition system and the capture library.
3129 * epb_dropcount 4 8 A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
3130 * between this packet and the preceding one.
3131 * opt_endofopt 0 0 It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
3133 if (phdr->opt_comment) {
3134 option_hdr.type = OPT_COMMENT;
3135 option_hdr.value_length = comment_len;
3136 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3138 wdh->bytes_dumped += 4;
3140 /* Write the comments string */
3141 pcapng_debug("pcapng_write_enhanced_packet_block, comment:'%s' comment_len %u comment_pad_len %u" , phdr->opt_comment, comment_len, comment_pad_len);
3142 if (!wtap_dump_file_write(wdh, phdr->opt_comment, comment_len, err))
3144 wdh->bytes_dumped += comment_len;
3146 /* write padding (if any) */
3147 if (comment_pad_len != 0) {
3148 if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
3150 wdh->bytes_dumped += comment_pad_len;
3153 pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
3157 if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
3158 option_hdr.type = OPT_EPB_FLAGS;
3159 option_hdr.value_length = 4;
3160 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3162 wdh->bytes_dumped += 4;
3163 if (!wtap_dump_file_write(wdh, &phdr->pack_flags, 4, err))
3165 wdh->bytes_dumped += 4;
3166 pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options packet flags: %x", phdr->pack_flags);
3168 /* Write end of options if we have options */
3170 if (!wtap_dump_file_write(wdh, &zero_pad, 4, err))
3172 wdh->bytes_dumped += 4;
3175 /* write block footer */
3176 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3177 sizeof bh.block_total_length, err))
3179 wdh->bytes_dumped += sizeof bh.block_total_length;
3185 pcapng_write_sysdig_event_block(wtap_dumper *wdh,
3186 const struct wtap_pkthdr *phdr,
3187 const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err)
3189 pcapng_block_header_t bh;
3190 const guint32 zero_pad = 0;
3194 gboolean have_options = FALSE;
3195 struct option option_hdr;
3196 guint32 comment_len = 0, comment_pad_len = 0;
3198 guint32 options_total_length = 0;
3206 /* Don't write anything we're not willing to read. */
3207 if (phdr->caplen > WTAP_MAX_PACKET_SIZE_STANDARD) {
3208 *err = WTAP_ERR_PACKET_TOO_LARGE;
3212 phdr_len = (guint32)pcap_get_phdr_size(phdr->pkt_encap, pseudo_header);
3213 if ((phdr_len + phdr->caplen) % 4) {
3214 pad_len = 4 - ((phdr_len + phdr->caplen) % 4);
3220 /* Check if we should write comment option */
3221 if (phdr->opt_comment) {
3222 have_options = TRUE;
3223 comment_len = (guint32)strlen(phdr->opt_comment) & 0xffff;
3224 if ((comment_len % 4)) {
3225 comment_pad_len = 4 - (comment_len % 4);
3227 comment_pad_len = 0;
3229 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3232 /* End-of options tag */
3233 options_total_length += 4;
3237 /* write sysdig event block header */
3238 bh.block_type = BLOCK_TYPE_SYSDIG_EVENT;
3239 bh.block_total_length = (guint32)sizeof(bh) + SYSDIG_EVENT_HEADER_SIZE + phdr_len + phdr->caplen + pad_len + options_total_length + 4;
3241 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3243 wdh->bytes_dumped += sizeof bh;
3245 /* Sysdig is always LE? */
3246 cpu_id = GUINT16_TO_LE(pseudo_header->sysdig_event.cpu_id);
3247 hdr_ts = (((guint64)phdr->ts.secs) * 1000000000) + phdr->ts.nsecs;
3248 ts = GUINT64_TO_LE(hdr_ts);
3249 thread_id = GUINT64_TO_LE(pseudo_header->sysdig_event.thread_id);
3250 event_len = GUINT32_TO_LE(pseudo_header->sysdig_event.event_len);
3251 event_type = GUINT16_TO_LE(pseudo_header->sysdig_event.event_type);
3253 if (!wtap_dump_file_write(wdh, &cpu_id, sizeof cpu_id, err))
3255 wdh->bytes_dumped += sizeof cpu_id;
3257 if (!wtap_dump_file_write(wdh, &ts, sizeof ts, err))
3259 wdh->bytes_dumped += sizeof ts;
3261 if (!wtap_dump_file_write(wdh, &thread_id, sizeof thread_id, err))
3263 wdh->bytes_dumped += sizeof thread_id;
3265 if (!wtap_dump_file_write(wdh, &event_len, sizeof event_len, err))
3267 wdh->bytes_dumped += sizeof event_len;
3269 if (!wtap_dump_file_write(wdh, &event_type, sizeof event_type, err))
3271 wdh->bytes_dumped += sizeof event_type;
3273 /* write event data */
3274 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
3276 wdh->bytes_dumped += phdr->caplen;
3278 /* write padding (if any) */
3280 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3282 wdh->bytes_dumped += pad_len;
3285 /* XXX Write comment? */
3287 /* write block footer */
3288 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3289 sizeof bh.block_total_length, err))
3297 * libpcap's maximum pcapng block size is currently 16MB.
3299 * The maximum pcapng block size in macOS's private pcapng reading code
3300 * is 1MB. (Yes, this means that a program using the standard pcap
3301 * code to read pcapng files can handle bigger blocks than can programs
3302 * using the private code, such as Apple's tcpdump, can handle.)
3304 * The pcapng reading code here can handle NRBs of arbitrary size (less
3305 * than 4GB, obviously), as they read each NRB record independently,
3306 * rather than reading the entire block into memory.
3308 * So, for now, we set the maximum NRB block size we write as 1 MB.
3310 * (Yes, for the benefit of the fussy, "MB" is really "MiB".)
3313 #define NRES_BLOCK_MAX_SIZE (1024*1024)
3316 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)
3318 pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
3324 case OPT_NS_DNSNAME:
3325 size = pcapng_compute_option_string_size(optval->stringval);
3327 case OPT_NS_DNSIP4ADDR:
3330 case OPT_NS_DNSIP6ADDR:
3334 /* Unknown options - size by datatype? */
3338 block_size->size += size;
3339 /* Add bytes for option header if option should be written */
3341 /* Add optional padding to 32 bits */
3342 if ((block_size->size & 0x03) != 0)
3344 block_size->size += 4 - (block_size->size & 0x03);
3346 block_size->size += 4;
3351 put_nrb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
3353 guint8 **opt_ptrp = (guint8 **)user_data;
3355 struct pcapng_option_header option_hdr;
3361 case OPT_NS_DNSNAME:
3362 /* String options don't consider pad bytes part of the length */
3363 size = (guint32)strlen(optval->stringval) & 0xffff;
3364 option_hdr.type = (guint16)option_id;
3365 option_hdr.value_length = (guint16)size;
3366 memcpy(*opt_ptrp, &option_hdr, 4);
3369 memcpy(*opt_ptrp, optval->stringval, size);
3373 pad = 4 - (size % 4);
3378 /* put padding (if any) */
3380 memset(*opt_ptrp, 0, pad);
3384 case OPT_NS_DNSIP4ADDR:
3385 option_hdr.type = (guint16)option_id;
3386 option_hdr.value_length = 4;
3387 memcpy(*opt_ptrp, &option_hdr, 4);
3390 memcpy(*opt_ptrp, &optval->ipv4val, 4);
3393 case OPT_NS_DNSIP6ADDR:
3394 option_hdr.type = (guint16)option_id;
3395 option_hdr.value_length = 16;
3396 memcpy(*opt_ptrp, &option_hdr, 4);
3399 memcpy(*opt_ptrp, &optval->ipv6val, 16);
3403 /* Unknown options - size by datatype? */
3409 put_nrb_options(wtap_dumper *wdh, guint8 *opt_ptr)
3411 if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
3412 wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
3413 struct option option_hdr;
3415 wtap_block_foreach_option(nrb_hdr, put_nrb_option, &opt_ptr);
3417 /* Put end of options */
3418 option_hdr.type = OPT_EOFOPT;
3419 option_hdr.value_length = 0;
3420 memcpy(opt_ptr, &option_hdr, 4);
3425 pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
3427 pcapng_block_header_t bh;
3428 pcapng_name_resolution_block_t nrb;
3429 pcapng_block_size_t opts_size;
3430 size_t max_rec_data_size;
3435 guint32 tot_rec_len;
3436 hashipv4_t *ipv4_hash_list_entry;
3437 hashipv6_t *ipv6_hash_list_entry;
3440 if (wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
3442 * No name/address pairs to write.
3443 * XXX - what if we have options?
3448 /* Calculate the space needed for options. */
3450 if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
3451 wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
3453 wtap_block_foreach_option(nrb_hdr, compute_nrb_option_size, &opts_size);
3454 if (opts_size.size > 0) {
3455 /* End-of options tag */
3456 opts_size.size += 4;
3461 * Make sure we can fit at least one maximum-sized record, plus
3462 * an end-of-records record, plus the options, into a maximum-sized
3465 * That requires that there be enough space for the block header
3466 * (8 bytes), a maximum-sized record (2 bytes of record type, 2
3467 * bytes of record value length, 65535 bytes of record value,
3468 * and 1 byte of padding), an end-of-records record (4 bytes),
3469 * the options (opts_size.size bytes), and the block trailer (4
3472 if (8 + 2 + 2 + 65535 + 1 + 4 + opts_size.size + 4 > NRES_BLOCK_MAX_SIZE) {
3474 * XXX - we can't even fit the options in the largest NRB size
3475 * we're willing to write and still have room enough for a
3476 * maximum-sized record. Just discard the information for now.
3482 * Allocate a buffer for the largest block we'll write.
3484 block_data = (guint8 *)g_malloc(NRES_BLOCK_MAX_SIZE);
3487 * Calculate the maximum amount of record data we'll be able to
3488 * fit into such a block, after taking into account the block header
3489 * (8 bytes), the end-of-records record (4 bytes), the options
3490 * (opts_size.size bytes), and the block trailer (4 bytes).
3492 max_rec_data_size = NRES_BLOCK_MAX_SIZE - (8 + 4 + opts_size.size + 4);
3494 block_off = 8; /* block type + block total length */
3495 bh.block_type = BLOCK_TYPE_NRB;
3496 bh.block_total_length = 12; /* block header + block trailer */
3499 * Write out the IPv4 resolved addresses, if any.
3501 if (wdh->addrinfo_lists->ipv4_addr_list){
3503 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3504 while(ipv4_hash_list_entry != NULL){
3506 nrb.record_type = NRES_IP4RECORD;
3507 hostnamelen = strlen(ipv4_hash_list_entry->name);
3508 if (hostnamelen > (G_MAXUINT16 - 4) - 1) {
3510 * This won't fit in the largest possible NRB record;
3514 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3517 namelen = (guint16)(hostnamelen + 1);
3518 nrb.record_len = 4 + namelen; /* 4 bytes IPv4 address length */
3519 /* 2 bytes record type, 2 bytes length field */
3520 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3522 if (block_off + tot_rec_len > max_rec_data_size) {
3524 * This record would overflow our maximum size for Name
3525 * Resolution Blocks; write out all the records we created
3526 * before it, and start a new NRB.
3529 /* Append the end-of-records record */
3530 memset(block_data + block_off, 0, 4);
3532 bh.block_total_length += 4;
3535 * Put the options into the block.
3537 * XXX - this puts the same options in all NRBs.
3539 put_nrb_options(wdh, block_data + block_off);
3540 block_off += opts_size.size;
3541 bh.block_total_length += opts_size.size;
3543 /* Copy the block header. */
3544 memcpy(block_data, &bh, sizeof(bh));
3546 /* Copy the block trailer. */
3547 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3549 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3551 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3555 wdh->bytes_dumped += bh.block_total_length;
3557 /*Start a new NRB */
3558 block_off = 8; /* block type + block total length */
3559 bh.block_type = BLOCK_TYPE_NRB;
3560 bh.block_total_length = 12; /* block header + block trailer */
3563 bh.block_total_length += tot_rec_len;
3564 memcpy(block_data + block_off, &nrb, sizeof(nrb));
3566 memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4);
3568 memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen);
3569 block_off += namelen;
3570 memset(block_data + block_off, 0, PADDING4(namelen));
3571 block_off += PADDING4(namelen);
3572 pcapng_debug("NRB: added IPv4 record for %s", ipv4_hash_list_entry->name);
3575 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3577 g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
3578 wdh->addrinfo_lists->ipv4_addr_list = NULL;
3581 if (wdh->addrinfo_lists->ipv6_addr_list){
3583 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3584 while(ipv6_hash_list_entry != NULL){
3586 nrb.record_type = NRES_IP6RECORD;
3587 hostnamelen = strlen(ipv6_hash_list_entry->name);
3588 if (hostnamelen > (G_MAXUINT16 - 16) - 1) {
3590 * This won't fit in the largest possible NRB record;
3594 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3597 namelen = (guint16)(hostnamelen + 1);
3598 nrb.record_len = 16 + namelen; /* 16 bytes IPv6 address length */
3599 /* 2 bytes record type, 2 bytes length field */
3600 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3602 if (block_off + tot_rec_len > max_rec_data_size) {
3604 * This record would overflow our maximum size for Name
3605 * Resolution Blocks; write out all the records we created
3606 * before it, and start a new NRB.
3609 /* Append the end-of-records record */
3610 memset(block_data + block_off, 0, 4);
3612 bh.block_total_length += 4;
3615 * Put the options into the block.
3617 * XXX - this puts the same options in all NRBs.
3619 put_nrb_options(wdh, block_data + block_off);
3620 block_off += opts_size.size;
3621 bh.block_total_length += opts_size.size;
3623 /* Copy the block header. */
3624 memcpy(block_data, &bh, sizeof(bh));
3626 /* Copy the block trailer. */
3627 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3629 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3631 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3635 wdh->bytes_dumped += bh.block_total_length;
3637 /*Start a new NRB */
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 bh.block_total_length += tot_rec_len;
3644 memcpy(block_data + block_off, &nrb, sizeof(nrb));
3646 memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16);
3648 memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen);
3649 block_off += namelen;
3650 memset(block_data + block_off, 0, PADDING4(namelen));
3651 block_off += PADDING4(namelen);
3652 pcapng_debug("NRB: added IPv6 record for %s", ipv6_hash_list_entry->name);
3655 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3657 g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
3658 wdh->addrinfo_lists->ipv6_addr_list = NULL;
3661 /* Append the end-of-records record */
3662 memset(block_data + block_off, 0, 4);
3664 bh.block_total_length += 4;
3667 * Put the options into the block.
3669 put_nrb_options(wdh, block_data + block_off);
3670 block_off += opts_size.size;
3671 bh.block_total_length += opts_size.size;
3673 /* Copy the block header. */
3674 memcpy(block_data, &bh, sizeof(bh));
3676 /* Copy the block trailer. */
3677 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3679 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3681 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3685 wdh->bytes_dumped += bh.block_total_length;
3692 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)
3694 pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
3700 size = pcapng_compute_option_string_size(optval->stringval);
3702 case OPT_ISB_STARTTIME:
3703 case OPT_ISB_ENDTIME:
3706 case OPT_ISB_IFRECV:
3707 case OPT_ISB_IFDROP:
3708 case OPT_ISB_FILTERACCEPT:
3709 case OPT_ISB_OSDROP:
3710 case OPT_ISB_USRDELIV:
3714 /* Unknown options - size by datatype? */
3718 block_size->size += size;
3719 /* Add bytes for option header if option should be written */
3721 /* Add optional padding to 32 bits */
3722 if ((block_size->size & 0x03) != 0)
3724 block_size->size += 4 - (block_size->size & 0x03);
3726 block_size->size += 4;
3730 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)
3732 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
3733 struct pcapng_option_header option_hdr;
3735 /* Don't continue if there has been an error */
3736 if (!write_block->success)
3742 if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
3743 write_block->success = FALSE;
3747 case OPT_ISB_STARTTIME:
3748 case OPT_ISB_ENDTIME:
3752 option_hdr.type = option_id;
3753 option_hdr.value_length = 8;
3754 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3755 write_block->success = FALSE;
3758 write_block->wdh->bytes_dumped += 4;
3760 high = (guint32)(optval->uint64val >> 32);
3761 low = (guint32)(optval->uint64val >> 0);
3762 if (!wtap_dump_file_write(write_block->wdh, &high, sizeof(guint32), write_block->err)) {
3763 write_block->success = FALSE;
3766 write_block->wdh->bytes_dumped += 4;
3767 if (!wtap_dump_file_write(write_block->wdh, &low, sizeof(guint32), write_block->err)) {
3768 write_block->success = FALSE;
3771 write_block->wdh->bytes_dumped += 4;
3774 case OPT_ISB_IFRECV:
3775 case OPT_ISB_IFDROP:
3776 case OPT_ISB_FILTERACCEPT:
3777 case OPT_ISB_OSDROP:
3778 case OPT_ISB_USRDELIV:
3780 option_hdr.type = option_id;
3781 option_hdr.value_length = 8;
3782 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3783 write_block->success = FALSE;
3786 write_block->wdh->bytes_dumped += 4;
3788 if (!wtap_dump_file_write(write_block->wdh, &optval->uint64val, sizeof(guint64), write_block->err)) {
3789 write_block->success = FALSE;
3792 write_block->wdh->bytes_dumped += 8;
3796 /* Unknown options - write by datatype? */
3802 pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_block_t if_stats, int *err)
3804 pcapng_block_header_t bh;
3805 pcapng_interface_statistics_block_t isb;
3806 pcapng_block_size_t block_size;
3807 pcapng_write_block_t block_data;
3808 struct pcapng_option_header option_hdr;
3809 wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
3811 pcapng_debug("pcapng_write_interface_statistics_block");
3813 /* Compute block size */
3814 block_size.size = 0;
3815 wtap_block_foreach_option(if_stats, compute_isb_option_size, &block_size);
3817 if (block_size.size > 0) {
3818 /* End-of-options tag */
3819 block_size.size += 4;
3822 /* write block header */
3823 bh.block_type = BLOCK_TYPE_ISB;
3824 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(isb) + block_size.size + 4);
3825 pcapng_debug("pcapng_write_interface_statistics_block: Total len %u", bh.block_total_length);
3827 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3829 wdh->bytes_dumped += sizeof bh;
3831 /* write block fixed content */
3832 isb.interface_id = mand_data->interface_id;
3833 isb.timestamp_high = mand_data->ts_high;
3834 isb.timestamp_low = mand_data->ts_low;
3836 if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
3838 wdh->bytes_dumped += sizeof isb;
3841 if (block_size.size > 0) {
3842 block_data.wdh = wdh;
3843 block_data.err = err;
3844 block_data.success = TRUE;
3845 wtap_block_foreach_option(if_stats, write_wtap_isb_option, &block_data);
3847 if (!block_data.success)
3850 /* Write end of options */
3851 option_hdr.type = OPT_EOFOPT;
3852 option_hdr.value_length = 0;
3853 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3855 wdh->bytes_dumped += 4;
3858 /* write block footer */
3859 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3860 sizeof bh.block_total_length, err))
3862 wdh->bytes_dumped += sizeof bh.block_total_length;
3866 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)
3868 pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
3877 size = pcapng_compute_option_string_size(optval->stringval);
3882 case OPT_IDB_TSRESOL:
3885 case OPT_IDB_FILTER:
3887 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->customval.data;
3889 if (filter->if_filter_str != NULL) {
3890 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
3892 pad = 4 - (size % 4);
3901 case OPT_IDB_FCSLEN:
3902 /* XXX - Not currently writing value */
3905 /* Unknown options - size by datatype? */
3909 block_size->size += size;
3910 /* Add bytes for option header if option should be written */
3912 /* Add optional padding to 32 bits */
3913 if ((block_size->size & 0x03) != 0)
3915 block_size->size += 4 - (block_size->size & 0x03);
3917 block_size->size += 4;
3921 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)
3923 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
3924 struct pcapng_option_header option_hdr;
3925 const guint32 zero_pad = 0;
3933 if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
3934 write_block->success = FALSE;
3939 option_hdr.type = option_id;
3940 option_hdr.value_length = 8;
3941 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3942 write_block->success = FALSE;
3945 write_block->wdh->bytes_dumped += 4;
3947 if (!wtap_dump_file_write(write_block->wdh, &optval->uint64val, sizeof(guint64), write_block->err)) {
3948 write_block->success = FALSE;
3951 write_block->wdh->bytes_dumped += 8;
3953 case OPT_IDB_TSRESOL:
3954 option_hdr.type = option_id;
3955 option_hdr.value_length = 1;
3956 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3957 write_block->success = FALSE;
3960 write_block->wdh->bytes_dumped += 4;
3962 if (!wtap_dump_file_write(write_block->wdh, &optval->uint8val, 1, write_block->err)) {
3963 write_block->success = FALSE;
3966 write_block->wdh->bytes_dumped += 1;
3968 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 3, write_block->err)) {
3969 write_block->success = FALSE;
3972 write_block->wdh->bytes_dumped += 3;
3974 case OPT_IDB_FILTER:
3976 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->customval.data;
3978 if (filter->if_filter_str != NULL) {
3979 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
3981 pad = 4 - (size % 4);
3986 option_hdr.type = option_id;
3987 option_hdr.value_length = size;
3988 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3989 write_block->success = FALSE;
3992 write_block->wdh->bytes_dumped += 4;
3994 /* Write the zero indicating libpcap filter variant */
3995 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 1, write_block->err)) {
3996 write_block->success = FALSE;
3999 write_block->wdh->bytes_dumped += 1;
4001 /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
4002 if (!wtap_dump_file_write(write_block->wdh, filter->if_filter_str, size-1, write_block->err)) {
4003 write_block->success = FALSE;
4006 write_block->wdh->bytes_dumped += size - 1;
4008 /* write padding (if any) */
4010 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, pad, write_block->err)) {
4011 write_block->success = FALSE;
4014 write_block->wdh->bytes_dumped += pad;
4020 case OPT_IDB_FCSLEN:
4021 /* XXX - Not currently writing value */
4024 /* Unknown options - size by datatype? */
4030 pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data, int *err)
4032 pcapng_block_header_t bh;
4033 pcapng_interface_description_block_t idb;
4034 pcapng_block_size_t block_size;
4035 pcapng_write_block_t block_data;
4036 struct pcapng_option_header option_hdr;
4037 wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
4040 pcapng_debug("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d",
4041 mand_data->wtap_encap,
4042 wtap_encap_string(mand_data->wtap_encap),
4043 mand_data->snap_len);
4045 link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap);
4046 if (link_type == -1) {
4047 *err = WTAP_ERR_UNWRITABLE_ENCAP;
4051 /* Compute block size */
4052 block_size.size = 0;
4053 wtap_block_foreach_option(int_data, compute_idb_option_size, &block_size);
4055 if (block_size.size > 0) {
4056 /* End-of-options tag */
4057 block_size.size += 4;
4060 /* write block header */
4061 bh.block_type = BLOCK_TYPE_IDB;
4062 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + block_size.size + 4);
4063 pcapng_debug("pcapng_write_if_descr_block: Total len %u", bh.block_total_length);
4065 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
4067 wdh->bytes_dumped += sizeof bh;
4069 /* write block fixed content */
4070 idb.linktype = link_type;
4072 idb.snaplen = mand_data->snap_len;
4074 if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
4076 wdh->bytes_dumped += sizeof idb;
4078 if (block_size.size > 0) {
4080 block_data.wdh = wdh;
4081 block_data.err = err;
4082 block_data.success = TRUE;
4083 wtap_block_foreach_option(int_data, write_wtap_idb_option, &block_data);
4085 if (!block_data.success)
4088 /* Write end of options */
4089 option_hdr.type = OPT_EOFOPT;
4090 option_hdr.value_length = 0;
4091 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4093 wdh->bytes_dumped += 4;
4096 /* write block footer */
4097 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
4098 sizeof bh.block_total_length, err))
4101 wdh->bytes_dumped += sizeof bh.block_total_length;
4105 static gboolean pcapng_dump(wtap_dumper *wdh,
4106 const struct wtap_pkthdr *phdr,
4107 const guint8 *pd, int *err, gchar **err_info _U_)
4109 const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
4111 block_handler *handler;
4114 pcapng_debug("pcapng_dump: encap = %d (%s)",
4116 wtap_encap_string(phdr->pkt_encap));
4118 switch (phdr->rec_type) {
4120 case REC_TYPE_PACKET:
4121 if (!pcapng_write_enhanced_packet_block(wdh, phdr, pseudo_header, pd, err)) {
4126 case REC_TYPE_FT_SPECIFIC_EVENT:
4127 case REC_TYPE_FT_SPECIFIC_REPORT:
4130 * Do we have a handler for this block type?
4132 if (block_handlers != NULL &&
4133 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
4134 GUINT_TO_POINTER(pseudo_header->ftsrec.record_type))) != NULL) {
4135 /* Yes. Call it to write out this record. */
4136 if (!handler->writer(wdh, phdr, pd, err))
4142 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
4147 case REC_TYPE_SYSCALL:
4148 if (!pcapng_write_sysdig_event_block(wdh, phdr, pseudo_header, pd, err)) {
4154 /* We don't support writing this record type. */
4155 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
4163 /* Finish writing to a dump file.
4164 Returns TRUE on success, FALSE on failure. */
4165 static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err)
4169 /* Flush any hostname resolution info we may have */
4170 pcapng_write_name_resolution_block(wdh, err);
4172 for (i = 0; i < wdh->interface_data->len; i++) {
4174 /* Get the interface description */
4175 wtap_block_t int_data;
4176 wtapng_if_descr_mandatory_t *int_data_mand;
4178 int_data = g_array_index(wdh->interface_data, wtap_block_t, i);
4179 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
4181 for (j = 0; j < int_data_mand->num_stat_entries; j++) {
4182 wtap_block_t if_stats;
4184 if_stats = g_array_index(int_data_mand->interface_statistics, wtap_block_t, j);
4185 pcapng_debug("pcapng_dump_finish: write ISB for interface %u", ((wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats))->interface_id);
4186 if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) {
4192 pcapng_debug("pcapng_dump_finish");
4197 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
4200 pcapng_dump_open(wtap_dumper *wdh, int *err)
4204 pcapng_debug("pcapng_dump_open");
4205 /* This is a pcapng file */
4206 wdh->subtype_write = pcapng_dump;
4207 wdh->subtype_finish = pcapng_dump_finish;
4209 if (wdh->interface_data->len == 0) {
4210 pcapng_debug("There are no interfaces. Can't handle that...");
4211 *err = WTAP_ERR_INTERNAL;
4215 /* write the section header block */
4216 if (!pcapng_write_section_header_block(wdh, err)) {
4219 pcapng_debug("pcapng_dump_open: wrote section header block.");
4221 /* Write the Interface description blocks */
4222 pcapng_debug("pcapng_dump_open: Number of IDB:s to write (number of interfaces) %u",
4223 wdh->interface_data->len);
4225 for (i = 0; i < wdh->interface_data->len; i++) {
4227 /* Get the interface description */
4230 idb = g_array_index(wdh->interface_data, wtap_block_t, i);
4232 if (!pcapng_write_if_descr_block(wdh, idb, err)) {
4242 /* Returns 0 if we could write the specified encapsulation type,
4243 an error indication otherwise. */
4244 int pcapng_dump_can_write_encap(int wtap_encap)
4246 pcapng_debug("pcapng_dump_can_write_encap: encap = %d (%s)",
4248 wtap_encap_string(wtap_encap));
4250 /* Per-packet encapsulation is supported. */
4251 if (wtap_encap == WTAP_ENCAP_PER_PACKET)
4254 /* Make sure we can figure out this DLT type */
4255 if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
4256 return WTAP_ERR_UNWRITABLE_ENCAP;
4262 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4267 * indent-tabs-mode: nil
4270 * vi: set shiftwidth=4 tabstop=8 expandtab:
4271 * :indentSize=4:tabSize=8:noTabs=true: