4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * File format support for pcap-ng file format
7 * Copyright (c) 2007 by Ulf Lamping <ulf.lamping@web.de>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 /* File format specification:
25 * https://github.com/pcapng/pcapng
27 * https://wiki.wireshark.org/Development/PcapNg
38 #include "file_wrappers.h"
39 #include "pcap-common.h"
40 #include "pcap-encap.h"
42 #include "pcapng_module.h"
45 #define pcapng_debug(...) g_warning(__VA_ARGS__)
47 #define pcapng_debug(...)
51 pcapng_read(wtap *wth, int *err, gchar **err_info,
54 pcapng_seek_read(wtap *wth, gint64 seek_off,
55 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
57 pcapng_close(wtap *wth);
60 * Minimum block size = size of block header + size of block trailer.
62 #define MIN_BLOCK_SIZE ((guint32)(sizeof(pcapng_block_header_t) + sizeof(guint32)))
65 * In order to keep from trying to allocate large chunks of memory,
66 * which could either fail or, even if it succeeds, chew up so much
67 * address space or memory+backing store as not to leave room for
68 * anything else, we impose an upper limit on the size of blocks
69 * we're willing to handle.
71 * For now, we pick an arbitrary limit of 16MB (OK, fine, 16MiB, but
72 * don't try saying that on Wikipedia :-) :-) :-)).
74 #define MAX_BLOCK_SIZE (16*1024*1024)
77 * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
79 #define MIN_SHB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
81 /* pcapng: packet block file encoding (obsolete) */
82 typedef struct pcapng_packet_block_s {
85 guint32 timestamp_high;
86 guint32 timestamp_low;
89 /* ... Packet Data ... */
92 } pcapng_packet_block_t;
95 * Minimum PB size = minimum block size + size of fixed length portion of PB.
97 #define MIN_PB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
99 /* pcapng: enhanced packet block file encoding */
100 typedef struct pcapng_enhanced_packet_block_s {
101 guint32 interface_id;
102 guint32 timestamp_high;
103 guint32 timestamp_low;
104 guint32 captured_len;
106 /* ... Packet Data ... */
107 /* ... Padding ... */
108 /* ... Options ... */
109 } pcapng_enhanced_packet_block_t;
112 * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
114 #define MIN_EPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
116 /* pcapng: simple packet block file encoding */
117 typedef struct pcapng_simple_packet_block_s {
119 /* ... Packet Data ... */
120 /* ... Padding ... */
121 } pcapng_simple_packet_block_t;
124 * Minimum SPB size = minimum block size + size of fixed length portion of SPB.
126 #define MIN_SPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
128 /* pcapng: name resolution block file encoding */
129 typedef struct pcapng_name_resolution_block_s {
133 } pcapng_name_resolution_block_t;
136 * Minimum NRB size = minimum block size + size of smallest NRB record
137 * (there must at least be an "end of records" record).
139 #define MIN_NRB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
142 * Minimum ISB size = minimum block size + size of fixed length portion of ISB.
144 #define MIN_ISB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
147 * Minimum Sysdig size = minimum block size + packed size of sysdig_event_phdr.
149 #define MIN_SYSDIG_EVENT_SIZE ((guint32)(MIN_BLOCK_SIZE)) + ((16 + 64 + 64 + 32 + 16) / 8)
151 /* pcapng: common option header file encoding for every option type */
152 typedef struct pcapng_option_header_s {
154 guint16 option_length;
155 /* ... x bytes Option Body ... */
156 /* ... Padding ... */
157 } pcapng_option_header_t;
161 guint16 value_length;
164 /* Option codes: 16-bit field */
165 #define OPT_EPB_FLAGS 0x0002
166 #define OPT_EPB_HASH 0x0003
167 #define OPT_EPB_DROPCOUNT 0x0004
169 #define OPT_NRB_DNSNAME 0x0002
170 #define OPT_NRB_DNSV4ADDR 0x0003
171 #define OPT_NRB_DNSV6ADDR 0x0004
173 /* MSBit of option code means "local type" */
174 #define OPT_LOCAL_FLAG 0x8000
176 /* Note: many of the defined structures for block data are defined in wtap.h */
178 /* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
179 typedef struct wtapng_packet_s {
181 guint32 ts_high; /* seconds since 1.1.1970 */
182 guint32 ts_low; /* fraction of seconds, depends on if_tsresol */
183 guint32 cap_len; /* data length in the file */
184 guint32 packet_len; /* data length on the wire */
185 guint32 interface_id; /* identifier of the interface. */
186 guint16 drops_count; /* drops count, only valid for packet block */
187 /* 0xffff if information no available */
189 /* XXX - put the packet data / pseudo_header here as well? */
192 /* Simple Packet data */
193 typedef struct wtapng_simple_packet_s {
195 guint32 cap_len; /* data length in the file */
196 guint32 packet_len; /* data length on the wire */
197 /* XXX - put the packet data / pseudo_header here as well? */
198 } wtapng_simple_packet_t;
200 /* Block data to be passed between functions during reading */
201 typedef struct wtapng_block_s {
202 guint32 type; /* block_type as defined by pcapng */
203 wtap_optionblock_t block;
206 * XXX - currently don't know how to handle these!
208 * For one thing, when we're reading a block, they must be
209 * writable, i.e. not const, so that we can read into them,
210 * but, when we're writing a block, they can be const, and,
211 * in fact, they sometimes point to const values.
213 struct wtap_pkthdr *packet_header;
214 Buffer *frame_buffer;
217 /* Interface data in private struct */
218 typedef struct interface_info_s {
221 guint64 time_units_per_second;
226 gboolean shb_read; /**< Set when first SHB read, second read will fail */
227 gboolean byte_swapped;
228 guint16 version_major;
229 guint16 version_minor;
230 GArray *interfaces; /**< Interfaces found in the capture file. */
232 wtap_new_ipv4_callback_t add_new_ipv4;
233 wtap_new_ipv6_callback_t add_new_ipv6;
238 * Table for plugins to handle particular block types.
240 * A handler has a "read" routine and a "write" routine.
242 * A "read" routine returns a block as a libwiretap record, filling
243 * in the wtap_pkthdr structure with the appropriate record type and
244 * other information, and filling in the supplied Buffer with
245 * data for which there's no place in the wtap_pkthdr structure.
247 * A "write" routine takes a libwiretap record and Buffer and writes
255 static GHashTable *block_handlers;
258 register_pcapng_block_type_handler(guint block_type, block_reader reader,
261 block_handler *handler;
263 if (block_handlers == NULL) {
265 * Create the table of block handlers.
267 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
268 * so we use "g_direct_hash()" and "g_direct_equal()".
270 block_handlers = g_hash_table_new_full(g_direct_hash,
274 handler = g_new(block_handler, 1);
275 handler->reader = reader;
276 handler->writer = writer;
277 g_hash_table_insert(block_handlers, GUINT_TO_POINTER(block_type),
282 * Tables for plugins to handle particular options for particular block
285 * An option has a handler routine, which is passed an indication of
286 * whether this section of the file is byte-swapped, the length of the
287 * option, the data of the option, a pointer to an error code, and a
288 * pointer to a pointer variable for an error string.
290 * It checks whether the length and option are valid, and, if they aren't,
291 * returns FALSE, setting the error code to the appropriate error (normally
292 * WTAP_ERR_BAD_FILE) and the error string to an appropriate string
293 * indicating the problem.
295 * Otherwise, if this section of the file is byte-swapped, it byte-swaps
296 * multi-byte numerical values, so that it's in the host byte order.
300 * Block types indices in the table of tables of option handlers.
302 * Block types are not guaranteed to be sequential, so we map the
303 * block types we support to a sequential set. Furthermore, all
304 * packet block types have the same set of options.
306 #define BT_INDEX_SHB 0
307 #define BT_INDEX_IDB 1
308 #define BT_INDEX_PBS 2 /* all packet blocks */
309 #define BT_INDEX_NRB 3
310 #define BT_INDEX_ISB 4
311 #define BT_INDEX_EVT 5
313 #define NUM_BT_INDICES 6
316 option_handler_fn hfunc;
319 static GHashTable *option_handlers[NUM_BT_INDICES];
322 get_block_type_index(guint block_type, guint *bt_index)
326 switch (block_type) {
329 *bt_index = BT_INDEX_SHB;
333 *bt_index = BT_INDEX_IDB;
339 *bt_index = BT_INDEX_PBS;
343 *bt_index = BT_INDEX_NRB;
347 *bt_index = BT_INDEX_ISB;
350 case BLOCK_TYPE_SYSDIG_EVENT:
351 /* case BLOCK_TYPE_SYSDIG_EVF: */
352 *bt_index = BT_INDEX_EVT;
357 * This is a block type we don't process; either we ignore it,
358 * in which case the options don't get processed, or there's
359 * a plugin routine to handle it, in which case that routine
360 * will do the option processing itself.
362 * XXX - report an error?
371 register_pcapng_option_handler(guint block_type, guint option_code,
372 option_handler_fn hfunc)
375 option_handler *handler;
377 if (!get_block_type_index(block_type, &bt_index))
380 if (option_handlers[bt_index] == NULL) {
382 * Create the table of option handlers for this block type.
384 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
385 * so we use "g_direct_hash()" and "g_direct_equal()".
387 option_handlers[bt_index] = g_hash_table_new_full(g_direct_hash,
391 handler = g_new(option_handler, 1);
392 handler->hfunc = hfunc;
393 g_hash_table_insert(option_handlers[bt_index],
394 GUINT_TO_POINTER(option_code), handler);
396 #endif /* HAVE_PLUGINS */
399 pcapng_read_option(FILE_T fh, pcapng_t *pn, pcapng_option_header_t *oh,
400 guint8 *content, guint len, guint to_read,
401 int *err, gchar **err_info, gchar* block_name)
405 /* sanity check: don't run past the end of the block */
406 if (to_read < sizeof (*oh)) {
407 *err = WTAP_ERR_BAD_FILE;
408 *err_info = g_strdup_printf("pcapng_read_option: Not enough data to read header of the %s block",
413 /* read option header */
414 if (!wtap_read_bytes(fh, oh, sizeof (*oh), err, err_info)) {
415 pcapng_debug("pcapng_read_option: failed to read option");
418 block_read = sizeof (*oh);
419 if (pn->byte_swapped) {
420 oh->option_code = GUINT16_SWAP_LE_BE(oh->option_code);
421 oh->option_length = GUINT16_SWAP_LE_BE(oh->option_length);
424 /* sanity check: don't run past the end of the block */
425 if (to_read < sizeof (*oh) + oh->option_length) {
426 *err = WTAP_ERR_BAD_FILE;
427 *err_info = g_strdup_printf("pcapng_read_option: Not enough data to handle option length (%d) of the %s block",
428 oh->option_length, block_name);
432 /* sanity check: option length */
433 if (len < oh->option_length) {
434 *err = WTAP_ERR_BAD_FILE;
435 *err_info = g_strdup_printf("pcapng_read_option: option length (%d) to long for %s block",
440 /* read option content */
441 if (!wtap_read_bytes(fh, content, oh->option_length, err, err_info)) {
442 pcapng_debug("pcapng_read_option: failed to read content of option %u", oh->option_code);
445 block_read += oh->option_length;
447 /* jump over potential padding bytes at end of option */
448 if ( (oh->option_length % 4) != 0) {
449 if (!file_skip(fh, 4 - (oh->option_length % 4), err))
451 block_read += 4 - (oh->option_length % 4);
459 PCAPNG_BLOCK_NOT_SHB,
463 static block_return_val
464 pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
465 pcapng_t *pn, wtapng_block_t *wblock,
466 int *err, gchar **err_info)
469 gboolean byte_swapped;
470 guint16 version_major;
471 guint16 version_minor;
472 guint to_read, opt_cont_buf_len;
473 pcapng_section_header_block_t shb;
474 pcapng_option_header_t oh;
475 wtapng_mandatory_section_t* section_data;
478 guint8 *option_content = NULL; /* Allocate as large as the options block */
480 /* read fixed-length part of the block */
481 if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
482 if (*err == WTAP_ERR_SHORT_READ) {
484 * This block is too short to be an SHB.
486 * If we're reading this as part of an open,
487 * the file is too short to be a pcap-ng file.
489 * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
490 * PCAPNG_BLOCK_ERROR the same, so we can just return
491 * PCAPNG_BLOCK_NOT_SHB in both cases.
493 return PCAPNG_BLOCK_NOT_SHB;
495 return PCAPNG_BLOCK_ERROR;
498 /* is the magic number one we expect? */
501 /* this seems pcapng with correct byte order */
502 byte_swapped = FALSE;
503 version_major = shb.version_major;
504 version_minor = shb.version_minor;
506 pcapng_debug("pcapng_read_section_header_block: SHB (our byte order) V%u.%u, len %u",
507 version_major, version_minor, bh->block_total_length);
510 /* this seems pcapng with swapped byte order */
512 version_major = GUINT16_SWAP_LE_BE(shb.version_major);
513 version_minor = GUINT16_SWAP_LE_BE(shb.version_minor);
515 /* tweak the block length to meet current swapping that we know now */
516 bh->block_total_length = GUINT32_SWAP_LE_BE(bh->block_total_length);
518 pcapng_debug("pcapng_read_section_header_block: SHB (byte-swapped) V%u.%u, len %u",
519 version_major, version_minor, bh->block_total_length);
522 /* Not a "pcapng" magic number we know about. */
523 *err = WTAP_ERR_BAD_FILE;
524 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown byte-order magic number 0x%08x", shb.magic);
527 * See above comment about PCAPNG_BLOCK_NOT_SHB.
529 return PCAPNG_BLOCK_NOT_SHB;
533 * Is this block long enough to be an SHB?
535 if (bh->block_total_length < MIN_SHB_SIZE) {
539 *err = WTAP_ERR_BAD_FILE;
540 *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",
541 bh->block_total_length, MIN_SHB_SIZE);
542 return PCAPNG_BLOCK_ERROR;
545 /* OK, at this point we assume it's a pcap-ng file.
547 Don't try to allocate memory for a huge number of options, as
548 that might fail and, even if it succeeds, it might not leave
549 any address space or memory+backing store for anything else.
551 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
552 We check for this *after* checking the SHB for its byte
553 order magic number, so that non-pcap-ng files are less
554 likely to be treated as bad pcap-ng files. */
555 if (bh->block_total_length > MAX_BLOCK_SIZE) {
556 *err = WTAP_ERR_BAD_FILE;
557 *err_info = g_strdup_printf("pcapng_read_section_header_block: total block length %u is too large (> %u)",
558 bh->block_total_length, MAX_BLOCK_SIZE);
559 return PCAPNG_BLOCK_ERROR;
562 /* We currently only suport one SHB */
563 if (pn->shb_read == TRUE) {
564 *err = WTAP_ERR_UNSUPPORTED;
565 *err_info = g_strdup_printf("pcapng_read_section_header_block: multiple section header blocks not supported");
566 return PCAPNG_BLOCK_ERROR;
569 /* we currently only understand SHB V1.0 */
570 if (version_major != 1 || version_minor > 0) {
571 *err = WTAP_ERR_UNSUPPORTED;
572 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown SHB version %u.%u",
573 pn->version_major, pn->version_minor);
574 return PCAPNG_BLOCK_ERROR;
577 pn->byte_swapped = byte_swapped;
578 pn->version_major = version_major;
579 pn->version_minor = version_minor;
581 wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
582 section_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(wblock->block);
583 /* 64bit section_length (currently unused) */
584 if (pn->byte_swapped) {
585 section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length);
587 section_data->section_length = shb.section_length;
591 to_read = bh->block_total_length - MIN_SHB_SIZE;
593 /* Allocate enough memory to hold all options */
594 opt_cont_buf_len = to_read;
595 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
596 if (opt_cont_buf_len != 0 && option_content == NULL) {
597 *err = ENOMEM; /* we assume we're out of memory */
598 return PCAPNG_BLOCK_ERROR;
600 pcapng_debug("pcapng_read_section_header_block: Options %u bytes", to_read);
601 while (to_read != 0) {
603 pcapng_debug("pcapng_read_section_header_block: Options %u bytes remaining", to_read);
604 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "section_header");
605 if (bytes_read <= 0) {
606 pcapng_debug("pcapng_read_section_header_block: failed to read option");
607 return PCAPNG_BLOCK_ERROR;
609 to_read -= bytes_read;
611 /* handle option content */
612 switch (oh.option_code) {
615 pcapng_debug("pcapng_read_section_header_block: %u bytes after opt_endofopt", to_read);
617 /* padding should be ok here, just get out of this */
621 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
622 tmp_content = g_strndup((char *)option_content, oh.option_length);
623 wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length);
624 pcapng_debug("pcapng_read_section_header_block: opt_comment %s", tmp_content);
627 pcapng_debug("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
630 case(OPT_SHB_HARDWARE):
631 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
632 tmp_content = g_strndup((char *)option_content, oh.option_length);
633 wtap_optionblock_set_option_string(wblock->block, OPT_SHB_HARDWARE, option_content, oh.option_length);
634 pcapng_debug("pcapng_read_section_header_block: shb_hardware %s", tmp_content);
637 pcapng_debug("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
641 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
642 tmp_content = g_strndup((char *)option_content, oh.option_length);
643 wtap_optionblock_set_option_string(wblock->block, OPT_SHB_OS, option_content, oh.option_length);
644 pcapng_debug("pcapng_read_section_header_block: shb_os %s", tmp_content);
647 pcapng_debug("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
650 case(OPT_SHB_USERAPPL):
651 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
652 tmp_content = g_strndup((char *)option_content, oh.option_length);
653 wtap_optionblock_set_option_string(wblock->block, OPT_SHB_USERAPPL, option_content, oh.option_length);
654 pcapng_debug("pcapng_read_section_header_block: shb_user_appl %s", tmp_content);
657 pcapng_debug("pcapng_read_section_header_block: shb_user_appl length %u seems strange", oh.option_length);
661 pcapng_debug("pcapng_read_section_header_block: unknown option %u - ignoring %u bytes",
662 oh.option_code, oh.option_length);
665 g_free(option_content);
667 return PCAPNG_BLOCK_OK;
671 /* "Interface Description Block" */
673 pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
674 pcapng_t *pn, wtapng_block_t *wblock, int *err,
677 guint64 time_units_per_second = 1000000; /* default = 10^6 */
678 int tsprecision = WTAP_TSPREC_USEC;
680 guint to_read, opt_cont_buf_len;
681 pcapng_interface_description_block_t idb;
682 wtapng_if_descr_mandatory_t* if_descr_mand;
683 pcapng_option_header_t oh;
684 guint8 *option_content = NULL; /* Allocate as large as the options block */
689 * Is this block long enough to be an IDB?
691 if (bh->block_total_length < MIN_IDB_SIZE) {
695 *err = WTAP_ERR_BAD_FILE;
696 *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",
697 bh->block_total_length, MIN_IDB_SIZE);
701 /* Don't try to allocate memory for a huge number of options, as
702 that might fail and, even if it succeeds, it might not leave
703 any address space or memory+backing store for anything else.
705 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
706 We check for this *after* checking the SHB for its byte
707 order magic number, so that non-pcap-ng files are less
708 likely to be treated as bad pcap-ng files. */
709 if (bh->block_total_length > MAX_BLOCK_SIZE) {
710 *err = WTAP_ERR_BAD_FILE;
711 *err_info = g_strdup_printf("pcapng_read_if_descr_block: total block length %u is too large (> %u)",
712 bh->block_total_length, MAX_BLOCK_SIZE);
716 /* read block content */
717 if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
718 pcapng_debug("pcapng_read_if_descr_block: failed to read IDB");
722 /* mandatory values */
723 wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
724 if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
725 if (pn->byte_swapped) {
726 if_descr_mand->link_type = GUINT16_SWAP_LE_BE(idb.linktype);
727 if_descr_mand->snap_len = GUINT32_SWAP_LE_BE(idb.snaplen);
729 if_descr_mand->link_type = idb.linktype;
730 if_descr_mand->snap_len = idb.snaplen;
733 if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(if_descr_mand->link_type);
734 if_descr_mand->time_units_per_second = time_units_per_second;
735 if_descr_mand->tsprecision = tsprecision;
737 pcapng_debug("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u",
738 if_descr_mand->link_type,
739 wtap_encap_string(if_descr_mand->wtap_encap),
740 if_descr_mand->snap_len);
742 if (if_descr_mand->snap_len > WTAP_MAX_PACKET_SIZE) {
743 /* This is unrealistic, but text2pcap currently uses 102400.
744 * We do not use this value, maybe we should check the
745 * snap_len of the packets against it. For now, only warn.
747 pcapng_debug("pcapng_read_if_descr_block: snapshot length %u unrealistic.",
748 if_descr_mand->snap_len);
749 /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE;*/
753 to_read = bh->block_total_length - MIN_IDB_SIZE;
755 /* Allocate enough memory to hold all options */
756 opt_cont_buf_len = to_read;
757 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
758 if (opt_cont_buf_len != 0 && option_content == NULL) {
759 *err = ENOMEM; /* we assume we're out of memory */
763 while (to_read != 0) {
765 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "if_descr");
766 if (bytes_read <= 0) {
767 pcapng_debug("pcapng_read_if_descr_block: failed to read option");
770 to_read -= bytes_read;
772 /* handle option content */
773 switch (oh.option_code) {
774 case(OPT_EOFOPT): /* opt_endofopt */
776 pcapng_debug("pcapng_read_if_descr_block: %u bytes after opt_endofopt", to_read);
778 /* padding should be ok here, just get out of this */
781 case(OPT_COMMENT): /* opt_comment */
782 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
783 tmp_content = g_strndup((char *)option_content, oh.option_length);
784 wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length);
785 pcapng_debug("pcapng_read_if_descr_block: opt_comment %s", tmp_content);
788 pcapng_debug("pcapng_read_if_descr_block: opt_comment length %u seems strange", oh.option_length);
791 case(OPT_IDB_NAME): /* if_name */
792 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
793 tmp_content = g_strndup((char *)option_content, oh.option_length);
794 wtap_optionblock_set_option_string(wblock->block, OPT_IDB_NAME, option_content, oh.option_length);
795 pcapng_debug("pcapng_read_if_descr_block: if_name %s", tmp_content);
798 pcapng_debug("pcapng_read_if_descr_block: if_name length %u seems strange", oh.option_length);
801 case(OPT_IDB_DESCR): /* if_description */
802 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
803 tmp_content = g_strndup((char *)option_content, oh.option_length);
804 wtap_optionblock_set_option_string(wblock->block, OPT_IDB_DESCR, option_content, oh.option_length);
805 pcapng_debug("pcapng_read_if_descr_block: if_description %s", tmp_content);
808 pcapng_debug("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
811 case(OPT_IDB_SPEED): /* if_speed */
812 if (oh.option_length == 8) {
813 /* Don't cast a guint8 * into a guint64 *--the
814 * guint8 * may not point to something that's
817 memcpy(&tmp64, option_content, sizeof(guint64));
818 if (pn->byte_swapped)
819 tmp64 = GUINT64_SWAP_LE_BE(tmp64);
820 wtap_optionblock_set_option_uint64(wblock->block, OPT_IDB_SPEED, tmp64);
821 pcapng_debug("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", tmp64);
823 pcapng_debug("pcapng_read_if_descr_block: if_speed length %u not 8 as expected", oh.option_length);
826 case(OPT_IDB_TSRESOL): /* if_tsresol */
827 if (oh.option_length == 1) {
830 guint8 i, exponent, if_tsresol;
832 if_tsresol = option_content[0];
833 if (if_tsresol & 0x80) {
838 exponent = (guint8)(if_tsresol & 0x7f);
839 if (((base == 2) && (exponent < 64)) || ((base == 10) && (exponent < 20))) {
841 for (i = 0; i < exponent; i++) {
844 time_units_per_second = result;
846 time_units_per_second = G_MAXUINT64;
848 if (time_units_per_second > (((guint64)1) << 32)) {
849 pcapng_debug("pcapng_open: time conversion might be inaccurate");
851 if_descr_mand->time_units_per_second = time_units_per_second;
852 wtap_optionblock_set_option_uint8(wblock->block, OPT_IDB_TSRESOL, if_tsresol);
853 if (time_units_per_second >= 1000000000)
854 tsprecision = WTAP_TSPREC_NSEC;
855 else if (time_units_per_second >= 1000000)
856 tsprecision = WTAP_TSPREC_USEC;
857 else if (time_units_per_second >= 1000)
858 tsprecision = WTAP_TSPREC_MSEC;
859 else if (time_units_per_second >= 100)
860 tsprecision = WTAP_TSPREC_CSEC;
861 else if (time_units_per_second >= 10)
862 tsprecision = WTAP_TSPREC_DSEC;
864 tsprecision = WTAP_TSPREC_SEC;
865 if_descr_mand->tsprecision = tsprecision;
866 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);
868 pcapng_debug("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length);
872 * if_tzone 10 Time zone for GMT support (TODO: specify better). TODO: give a good example
874 case(OPT_IDB_FILTER): /* if_filter */
875 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
876 wtapng_if_descr_filter_t if_filter;
877 memset(&if_filter, 0, sizeof(if_filter));
879 /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
882 if (option_content[0] == 0) {
883 if_filter.if_filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
884 pcapng_debug("pcapng_read_if_descr_block: if_filter_str %s oh.option_length %u", if_filter.if_filter_str, oh.option_length);
885 } else if (option_content[0] == 1) {
886 if_filter.bpf_filter_len = oh.option_length-1;
887 if_filter.if_filter_bpf_bytes = (gchar *)g_malloc(oh.option_length-1);
888 memcpy(if_filter.if_filter_bpf_bytes, (char *)option_content+1, oh.option_length-1);
890 wtap_optionblock_set_option_custom(wblock->block, OPT_IDB_FILTER, &if_filter);
892 pcapng_debug("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
895 case(OPT_IDB_OS): /* if_os */
897 * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
898 * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
899 * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
901 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
902 tmp_content = g_strndup((char *)option_content, oh.option_length);
903 wtap_optionblock_set_option_string(wblock->block, OPT_IDB_OS, option_content, oh.option_length);
904 pcapng_debug("pcapng_read_if_descr_block: if_os %s", tmp_content);
907 pcapng_debug("pcapng_read_if_descr_block: if_os length %u seems strange", oh.option_length);
910 case(OPT_IDB_FCSLEN): /* if_fcslen */
911 if (oh.option_length == 1) {
912 wtap_optionblock_set_option_uint8(wblock->block, OPT_IDB_TSRESOL, option_content[0]);
913 pn->if_fcslen = option_content[0];
914 pcapng_debug("pcapng_read_if_descr_block: if_fcslen %u", pn->if_fcslen);
915 /* XXX - add sanity check */
917 pcapng_debug("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
921 /* TODO: process these! */
922 case(OPT_IDB_IP4ADDR):
924 * Interface network address and netmask. This option can be
925 * repeated multiple times within the same Interface
926 * Description Block when multiple IPv4 addresses are assigned
927 * to the interface. 192 168 1 1 255 255 255 0
929 case(OPT_IDB_IP6ADDR):
931 * Interface network address and prefix length (stored in the
932 * last byte). This option can be repeated multiple times
933 * within the same Interface Description Block when multiple
934 * IPv6 addresses are assigned to the interface.
935 * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
936 * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
939 case(OPT_IDB_MACADDR):
941 * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
943 case(OPT_IDB_EUIADDR):
945 * Interface Hardware EUI address (64 bits), if available.
946 * TODO: give a good example
950 * Time zone for GMT support. TODO: specify better.
951 * TODO: give a good example.
953 case(OPT_IDB_TSOFFSET):
955 * A 64 bits integer value that specifies an offset (in
956 * seconds) that must be added to the timestamp of each packet
957 * to obtain the absolute timestamp of a packet. If the option
958 * is missing, the timestamps stored in the packet must be
959 * considered absolute timestamps. The time zone of the offset
960 * can be specified with the option if_tzone.
962 * TODO: won't a if_tsoffset_low for fractional second offsets
963 * be useful for highly synchronized capture systems? 1234
966 pcapng_debug("pcapng_read_if_descr_block: unknown option %u - ignoring %u bytes",
967 oh.option_code, oh.option_length);
971 g_free(option_content);
974 * If the per-file encapsulation isn't known, set it to this
975 * interface's encapsulation.
977 * If it *is* known, and it isn't this interface's encapsulation,
978 * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
979 * have a single encapsulation for all interfaces in the file,
980 * so it probably doesn't have a single encapsulation for all
981 * packets in the file.
983 if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
984 wth->file_encap = if_descr_mand->wtap_encap;
986 if (wth->file_encap != if_descr_mand->wtap_encap) {
987 wth->file_encap = WTAP_ENCAP_PER_PACKET;
992 * The same applies to the per-file time stamp resolution.
994 if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
995 wth->file_tsprec = if_descr_mand->tsprecision;
997 if (wth->file_tsprec != if_descr_mand->tsprecision) {
998 wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
1007 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)
1011 guint to_read, opt_cont_buf_len;
1012 pcapng_enhanced_packet_block_t epb;
1013 pcapng_packet_block_t pb;
1014 wtapng_packet_t packet;
1015 guint32 block_total_length;
1017 interface_info_t iface_info;
1020 pcapng_option_header_t *oh;
1021 guint8 *option_content;
1022 int pseudo_header_len;
1025 option_handler *handler;
1028 /* Don't try to allocate memory for a huge number of options, as
1029 that might fail and, even if it succeeds, it might not leave
1030 any address space or memory+backing store for anything else.
1032 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1033 We check for this *after* checking the SHB for its byte
1034 order magic number, so that non-pcap-ng files are less
1035 likely to be treated as bad pcap-ng files. */
1036 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1037 *err = WTAP_ERR_BAD_FILE;
1038 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u is too large (> %u)",
1039 bh->block_total_length, MAX_BLOCK_SIZE);
1043 /* "(Enhanced) Packet Block" read fixed part */
1046 * Is this block long enough to be an EPB?
1048 if (bh->block_total_length < MIN_EPB_SIZE) {
1052 *err = WTAP_ERR_BAD_FILE;
1053 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of an EPB is less than the minimum EPB size %u",
1054 bh->block_total_length, MIN_EPB_SIZE);
1057 if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
1058 pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1061 block_read = (guint)sizeof epb;
1063 if (pn->byte_swapped) {
1064 packet.interface_id = GUINT32_SWAP_LE_BE(epb.interface_id);
1065 packet.drops_count = -1; /* invalid */
1066 packet.ts_high = GUINT32_SWAP_LE_BE(epb.timestamp_high);
1067 packet.ts_low = GUINT32_SWAP_LE_BE(epb.timestamp_low);
1068 packet.cap_len = GUINT32_SWAP_LE_BE(epb.captured_len);
1069 packet.packet_len = GUINT32_SWAP_LE_BE(epb.packet_len);
1071 packet.interface_id = epb.interface_id;
1072 packet.drops_count = -1; /* invalid */
1073 packet.ts_high = epb.timestamp_high;
1074 packet.ts_low = epb.timestamp_low;
1075 packet.cap_len = epb.captured_len;
1076 packet.packet_len = epb.packet_len;
1078 pcapng_debug("pcapng_read_packet_block: EPB on interface_id %d, cap_len %d, packet_len %d",
1079 packet.interface_id, packet.cap_len, packet.packet_len);
1082 * Is this block long enough to be a PB?
1084 if (bh->block_total_length < MIN_PB_SIZE) {
1088 *err = WTAP_ERR_BAD_FILE;
1089 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of a PB is less than the minimum PB size %u",
1090 bh->block_total_length, MIN_PB_SIZE);
1093 if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
1094 pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1097 block_read = (guint)sizeof pb;
1099 if (pn->byte_swapped) {
1100 packet.interface_id = GUINT16_SWAP_LE_BE(pb.interface_id);
1101 packet.drops_count = GUINT16_SWAP_LE_BE(pb.drops_count);
1102 packet.ts_high = GUINT32_SWAP_LE_BE(pb.timestamp_high);
1103 packet.ts_low = GUINT32_SWAP_LE_BE(pb.timestamp_low);
1104 packet.cap_len = GUINT32_SWAP_LE_BE(pb.captured_len);
1105 packet.packet_len = GUINT32_SWAP_LE_BE(pb.packet_len);
1107 packet.interface_id = pb.interface_id;
1108 packet.drops_count = pb.drops_count;
1109 packet.ts_high = pb.timestamp_high;
1110 packet.ts_low = pb.timestamp_low;
1111 packet.cap_len = pb.captured_len;
1112 packet.packet_len = pb.packet_len;
1114 pcapng_debug("pcapng_read_packet_block: PB on interface_id %d, cap_len %d, packet_len %d",
1115 packet.interface_id, packet.cap_len, packet.packet_len);
1119 * How much padding is there at the end of the packet data?
1121 if ((packet.cap_len % 4) != 0)
1122 padding = 4 - (packet.cap_len % 4);
1126 /* add padding bytes to "block total length" */
1127 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1128 if (bh->block_total_length % 4) {
1129 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1131 block_total_length = bh->block_total_length;
1133 pcapng_debug("pcapng_read_packet_block: block_total_length %d", block_total_length);
1136 * Is this block long enough to hold the packet data?
1139 if (block_total_length <
1140 MIN_EPB_SIZE + packet.cap_len + padding) {
1144 *err = WTAP_ERR_BAD_FILE;
1145 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of EPB is too small for %u bytes of packet data",
1146 block_total_length, packet.cap_len);
1150 if (block_total_length <
1151 MIN_PB_SIZE + packet.cap_len + padding) {
1155 *err = WTAP_ERR_BAD_FILE;
1156 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of PB is too small for %u bytes of packet data",
1157 block_total_length, packet.cap_len);
1162 if (packet.cap_len > WTAP_MAX_PACKET_SIZE) {
1163 *err = WTAP_ERR_BAD_FILE;
1164 *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u",
1165 packet.cap_len, WTAP_MAX_PACKET_SIZE);
1168 pcapng_debug("pcapng_read_packet_block: packet data: packet_len %u captured_len %u interface_id %u",
1171 packet.interface_id);
1173 if (packet.interface_id >= pn->interfaces->len) {
1174 *err = WTAP_ERR_BAD_FILE;
1175 *err_info = g_strdup_printf("pcapng_read_packet_block: interface index %u is not less than interface count %u",
1176 packet.interface_id, pn->interfaces->len);
1179 iface_info = g_array_index(pn->interfaces, interface_info_t,
1180 packet.interface_id);
1182 wblock->packet_header->rec_type = REC_TYPE_PACKET;
1183 wblock->packet_header->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1185 pcapng_debug("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.",
1186 iface_info.wtap_encap,
1187 wtap_encap_string(iface_info.wtap_encap),
1188 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header));
1189 wblock->packet_header->interface_id = packet.interface_id;
1190 wblock->packet_header->pkt_encap = iface_info.wtap_encap;
1191 wblock->packet_header->pkt_tsprec = iface_info.tsprecision;
1193 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1194 pseudo_header_len = pcap_process_pseudo_header(fh,
1195 WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1196 iface_info.wtap_encap,
1199 wblock->packet_header,
1202 if (pseudo_header_len < 0) {
1205 block_read += pseudo_header_len;
1206 if (pseudo_header_len != pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header)) {
1207 pcapng_debug("pcapng_read_packet_block: Could only read %d bytes for pseudo header.",
1210 wblock->packet_header->caplen = packet.cap_len - pseudo_header_len;
1211 wblock->packet_header->len = packet.packet_len - pseudo_header_len;
1213 /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
1214 ts = (((guint64)packet.ts_high) << 32) | ((guint64)packet.ts_low);
1215 wblock->packet_header->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
1216 wblock->packet_header->ts.nsecs = (int)(((ts % iface_info.time_units_per_second) * 1000000000) / iface_info.time_units_per_second);
1218 /* "(Enhanced) Packet Block" read capture data */
1219 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1220 packet.cap_len - pseudo_header_len, err, err_info))
1222 block_read += packet.cap_len - pseudo_header_len;
1224 /* jump over potential padding bytes at end of the packet data */
1226 if (!file_skip(fh, padding, err))
1228 block_read += padding;
1231 /* Option defaults */
1232 wblock->packet_header->opt_comment = NULL;
1233 wblock->packet_header->drop_count = -1;
1234 wblock->packet_header->pack_flags = 0;
1236 /* FCS length default */
1237 fcslen = pn->if_fcslen;
1245 to_read = block_total_length -
1246 (int)sizeof(pcapng_block_header_t) -
1247 block_read - /* fixed and variable part, including padding */
1248 (int)sizeof(bh->block_total_length);
1250 /* Allocate enough memory to hold all options */
1251 opt_cont_buf_len = to_read;
1252 ws_buffer_assure_space(&wblock->packet_header->ft_specific_data, opt_cont_buf_len);
1253 opt_ptr = ws_buffer_start_ptr(&wblock->packet_header->ft_specific_data);
1255 while (to_read != 0) {
1257 oh = (pcapng_option_header_t *)(void *)opt_ptr;
1258 option_content = opt_ptr + sizeof (pcapng_option_header_t);
1259 bytes_read = pcapng_read_option(fh, pn, oh, option_content, opt_cont_buf_len, to_read, err, err_info, "packet");
1260 if (bytes_read <= 0) {
1261 pcapng_debug("pcapng_read_packet_block: failed to read option");
1262 /* XXX - free anything? */
1265 block_read += bytes_read;
1266 to_read -= bytes_read;
1268 /* handle option content */
1269 switch (oh->option_code) {
1272 pcapng_debug("pcapng_read_packet_block: %u bytes after opt_endofopt", to_read);
1274 /* padding should be ok here, just get out of this */
1278 if (oh->option_length > 0 && oh->option_length < opt_cont_buf_len) {
1279 wblock->packet_header->presence_flags |= WTAP_HAS_COMMENTS;
1280 wblock->packet_header->opt_comment = g_strndup((char *)option_content, oh->option_length);
1281 pcapng_debug("pcapng_read_packet_block: length %u opt_comment '%s'", oh->option_length, wblock->packet_header->opt_comment);
1283 pcapng_debug("pcapng_read_packet_block: opt_comment length %u seems strange", oh->option_length);
1286 case(OPT_EPB_FLAGS):
1287 if (oh->option_length != 4) {
1288 *err = WTAP_ERR_BAD_FILE;
1289 *err_info = g_strdup_printf("pcapng_read_packet_block: packet block flags option length %u is not 4",
1291 /* XXX - free anything? */
1294 /* Don't cast a guint8 * into a guint32 *--the
1295 * guint8 * may not point to something that's
1296 * aligned correctly.
1298 wblock->packet_header->presence_flags |= WTAP_HAS_PACK_FLAGS;
1299 memcpy(&wblock->packet_header->pack_flags, option_content, sizeof(guint32));
1300 if (pn->byte_swapped) {
1301 wblock->packet_header->pack_flags = GUINT32_SWAP_LE_BE(wblock->packet_header->pack_flags);
1302 memcpy(option_content, &wblock->packet_header->pack_flags, sizeof(guint32));
1304 if (wblock->packet_header->pack_flags & 0x000001E0) {
1305 /* The FCS length is present */
1306 fcslen = (wblock->packet_header->pack_flags & 0x000001E0) >> 5;
1308 pcapng_debug("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->packet_header->pack_flags);
1311 pcapng_debug("pcapng_read_packet_block: epb_hash %u currently not handled - ignoring %u bytes",
1312 oh->option_code, oh->option_length);
1314 case(OPT_EPB_DROPCOUNT):
1315 if (oh->option_length != 8) {
1316 *err = WTAP_ERR_BAD_FILE;
1317 *err_info = g_strdup_printf("pcapng_read_packet_block: packet block drop count option length %u is not 8",
1319 /* XXX - free anything? */
1322 /* Don't cast a guint8 * into a guint64 *--the
1323 * guint8 * may not point to something that's
1324 * aligned correctly.
1326 wblock->packet_header->presence_flags |= WTAP_HAS_DROP_COUNT;
1327 memcpy(&wblock->packet_header->drop_count, option_content, sizeof(guint64));
1328 if (pn->byte_swapped) {
1329 wblock->packet_header->drop_count = GUINT64_SWAP_LE_BE(wblock->packet_header->drop_count);
1330 memcpy(option_content, &wblock->packet_header->drop_count, sizeof(guint64));
1333 pcapng_debug("pcapng_read_packet_block: drop_count %" G_GINT64_MODIFIER "u", wblock->packet_header->drop_count);
1338 * Do we have a handler for this packet block option code?
1340 if (option_handlers[BT_INDEX_PBS] != NULL &&
1341 (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_PBS],
1342 GUINT_TO_POINTER((guint)oh->option_code))) != NULL) {
1343 /* Yes - call the handler. */
1344 if (!handler->hfunc(pn->byte_swapped, oh->option_length,
1345 option_content, err, err_info))
1346 /* XXX - free anything? */
1351 pcapng_debug("pcapng_read_packet_block: unknown option %u - ignoring %u bytes",
1352 oh->option_code, oh->option_length);
1357 pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1358 wblock->packet_header, ws_buffer_start_ptr(wblock->frame_buffer),
1359 pn->byte_swapped, fcslen);
1365 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)
1367 interface_info_t iface_info;
1368 pcapng_simple_packet_block_t spb;
1369 wtapng_simple_packet_t simple_packet;
1370 guint32 block_total_length;
1372 int pseudo_header_len;
1375 * Is this block long enough to be an SPB?
1377 if (bh->block_total_length < MIN_SPB_SIZE) {
1381 *err = WTAP_ERR_BAD_FILE;
1382 *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",
1383 bh->block_total_length, MIN_SPB_SIZE);
1387 /* Don't try to allocate memory for a huge number of options, as
1388 that might fail and, even if it succeeds, it might not leave
1389 any address space or memory+backing store for anything else.
1391 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1392 We check for this *after* checking the SHB for its byte
1393 order magic number, so that non-pcap-ng files are less
1394 likely to be treated as bad pcap-ng files. */
1395 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1396 *err = WTAP_ERR_BAD_FILE;
1397 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u is too large (> %u)",
1398 bh->block_total_length, MAX_BLOCK_SIZE);
1402 /* "Simple Packet Block" read fixed part */
1403 if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
1404 pcapng_debug("pcapng_read_simple_packet_block: failed to read packet data");
1408 if (0 >= pn->interfaces->len) {
1409 *err = WTAP_ERR_BAD_FILE;
1410 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: SPB appeared before any IDBs");
1413 iface_info = g_array_index(pn->interfaces, interface_info_t, 0);
1415 if (pn->byte_swapped) {
1416 simple_packet.packet_len = GUINT32_SWAP_LE_BE(spb.packet_len);
1418 simple_packet.packet_len = spb.packet_len;
1422 * The captured length is not a field in the SPB; it can be
1423 * calculated as the minimum of the snapshot length from the
1424 * IDB and the packet length, as per the pcap-ng spec. An IDB
1425 * snapshot length of 0 means no limit.
1427 simple_packet.cap_len = simple_packet.packet_len;
1428 if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
1429 simple_packet.cap_len = iface_info.snap_len;
1432 * How much padding is there at the end of the packet data?
1434 if ((simple_packet.cap_len % 4) != 0)
1435 padding = 4 - (simple_packet.cap_len % 4);
1439 /* add padding bytes to "block total length" */
1440 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1441 if (bh->block_total_length % 4) {
1442 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1444 block_total_length = bh->block_total_length;
1446 pcapng_debug("pcapng_read_simple_packet_block: block_total_length %d", block_total_length);
1449 * Is this block long enough to hold the packet data?
1451 if (block_total_length < MIN_SPB_SIZE + simple_packet.cap_len + padding) {
1453 * No. That means that the problem is with the packet
1454 * length; the snapshot length can be bigger than the amount
1455 * of packet data in the block, as it's a *maximum* length,
1456 * not a *minimum* length.
1458 *err = WTAP_ERR_BAD_FILE;
1459 *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",
1460 block_total_length, simple_packet.packet_len);
1464 if (simple_packet.cap_len > WTAP_MAX_PACKET_SIZE) {
1465 *err = WTAP_ERR_BAD_FILE;
1466 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u",
1467 simple_packet.cap_len, WTAP_MAX_PACKET_SIZE);
1470 pcapng_debug("pcapng_read_simple_packet_block: packet data: packet_len %u",
1471 simple_packet.packet_len);
1473 pcapng_debug("pcapng_read_simple_packet_block: Need to read pseudo header of size %d",
1474 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header));
1476 /* No time stamp in a simple packet block; no options, either */
1477 wblock->packet_header->rec_type = REC_TYPE_PACKET;
1478 wblock->packet_header->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1479 wblock->packet_header->interface_id = 0;
1480 wblock->packet_header->pkt_encap = iface_info.wtap_encap;
1481 wblock->packet_header->pkt_tsprec = iface_info.tsprecision;
1482 wblock->packet_header->ts.secs = 0;
1483 wblock->packet_header->ts.nsecs = 0;
1484 wblock->packet_header->interface_id = 0;
1485 wblock->packet_header->opt_comment = NULL;
1486 wblock->packet_header->drop_count = 0;
1487 wblock->packet_header->pack_flags = 0;
1489 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1490 pseudo_header_len = pcap_process_pseudo_header(fh,
1491 WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1492 iface_info.wtap_encap,
1493 simple_packet.cap_len,
1495 wblock->packet_header,
1498 if (pseudo_header_len < 0) {
1501 wblock->packet_header->caplen = simple_packet.cap_len - pseudo_header_len;
1502 wblock->packet_header->len = simple_packet.packet_len - pseudo_header_len;
1503 if (pseudo_header_len != pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header)) {
1504 pcapng_debug("pcapng_read_simple_packet_block: Could only read %d bytes for pseudo header.",
1508 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1510 /* "Simple Packet Block" read capture data */
1511 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1512 simple_packet.cap_len, err, err_info))
1515 /* jump over potential padding bytes at end of the packet data */
1516 if ((simple_packet.cap_len % 4) != 0) {
1517 if (!file_skip(fh, 4 - (simple_packet.cap_len % 4), err))
1521 pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1522 wblock->packet_header, ws_buffer_start_ptr(wblock->frame_buffer),
1523 pn->byte_swapped, pn->if_fcslen);
1527 #define NRES_ENDOFRECORD 0
1528 #define NRES_IP4RECORD 1
1529 #define NRES_IP6RECORD 2
1530 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
1531 /* IPv6 + MAXNAMELEN */
1532 #define INITIAL_NRB_REC_SIZE (16 + 64)
1535 * Find the end of the NUL-terminated name the beginning of which is pointed
1536 * to by p; record_len is the number of bytes remaining in the record.
1538 * Return the length of the name, including the terminating NUL.
1540 * If we don't find a terminating NUL, return -1 and set *err and
1541 * *err_info appropriately.
1544 name_resolution_block_find_name_end(const char *p, guint record_len, int *err,
1551 if (record_len == 0) {
1553 * We ran out of bytes in the record without
1556 *err = WTAP_ERR_BAD_FILE;
1557 *err_info = g_strdup("pcapng_read_name_resolution_block: NRB record has non-null-terminated host name");
1561 break; /* that's the terminating NUL */
1564 namelen++; /* count this byte */
1567 /* Include the NUL in the name length. */
1572 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)
1576 pcapng_name_resolution_block_t nrb;
1579 guint record_len, opt_cont_buf_len;
1583 pcapng_option_header_t oh;
1584 guint8 *option_content;
1586 option_handler *handler;
1591 * Is this block long enough to be an NRB?
1593 if (bh->block_total_length < MIN_NRB_SIZE) {
1597 *err = WTAP_ERR_BAD_FILE;
1598 *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",
1599 bh->block_total_length, MIN_NRB_SIZE);
1603 /* Don't try to allocate memory for a huge number of options, as
1604 that might fail and, even if it succeeds, it might not leave
1605 any address space or memory+backing store for anything else.
1607 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1608 We check for this *after* checking the SHB for its byte
1609 order magic number, so that non-pcap-ng files are less
1610 likely to be treated as bad pcap-ng files. */
1611 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1612 *err = WTAP_ERR_BAD_FILE;
1613 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: total block length %u is too large (> %u)",
1614 bh->block_total_length, MAX_BLOCK_SIZE);
1618 to_read = bh->block_total_length - 8 - 4; /* We have read the header and should not read the final block_total_length */
1620 pcapng_debug("pcapng_read_name_resolution_block, total %d bytes", bh->block_total_length);
1622 /* Ensure we have a name resolution block */
1623 if (wblock->block == NULL) {
1624 wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB);
1628 * Start out with a buffer big enough for an IPv6 address and one
1629 * 64-byte name; we'll make the buffer bigger if necessary.
1631 ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
1633 while (block_read < to_read) {
1635 * There must be at least one record's worth of data
1638 if ((size_t)(to_read - block_read) < sizeof nrb) {
1639 ws_buffer_free(&nrb_rec);
1640 *err = WTAP_ERR_BAD_FILE;
1641 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record header size %u",
1642 to_read - block_read,
1646 if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
1647 ws_buffer_free(&nrb_rec);
1648 pcapng_debug("pcapng_read_name_resolution_block: failed to read record header");
1651 block_read += (int)sizeof nrb;
1653 if (pn->byte_swapped) {
1654 nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type);
1655 nrb.record_len = GUINT16_SWAP_LE_BE(nrb.record_len);
1658 if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
1659 ws_buffer_free(&nrb_rec);
1660 *err = WTAP_ERR_BAD_FILE;
1661 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record length + padding %u",
1662 to_read - block_read,
1663 nrb.record_len + PADDING4(nrb.record_len));
1666 switch (nrb.record_type) {
1667 case NRES_ENDOFRECORD:
1668 /* There shouldn't be any more data - but there MAY be options */
1671 case NRES_IP4RECORD:
1673 * The smallest possible record must have
1674 * a 4-byte IPv4 address, hence a minimum
1677 * (The pcap-NG spec really indicates
1678 * that it must be at least 5 bytes,
1679 * as there must be at least one name,
1680 * and it really must be at least 6
1681 * bytes, as the name mustn't be null,
1682 * but there's no need to fail if there
1683 * aren't any names at all, and we
1684 * should report a null name as such.)
1686 if (nrb.record_len < 4) {
1687 ws_buffer_free(&nrb_rec);
1688 *err = WTAP_ERR_BAD_FILE;
1689 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv4 record %u < minimum length 4",
1693 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1694 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1695 nrb.record_len, err, err_info)) {
1696 ws_buffer_free(&nrb_rec);
1697 pcapng_debug("pcapng_read_name_resolution_block: failed to read IPv4 record data");
1700 block_read += nrb.record_len;
1702 if (pn->add_new_ipv4) {
1704 * Scan through all the names in
1705 * the record and add them.
1708 ws_buffer_start_ptr(&nrb_rec), 4);
1709 /* IPv4 address is in big-endian order in the file always, which is how we store
1710 it internally as well, so don't byte-swap it */
1711 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
1713 namep += namelen, record_len -= namelen) {
1715 * Scan forward for a null
1718 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1719 if (namelen == -1) {
1720 ws_buffer_free(&nrb_rec);
1721 return FALSE; /* fail */
1723 pn->add_new_ipv4(v4_addr, namep);
1727 if (!file_skip(fh, PADDING4(nrb.record_len), err)) {
1728 ws_buffer_free(&nrb_rec);
1731 block_read += PADDING4(nrb.record_len);
1733 case NRES_IP6RECORD:
1735 * The smallest possible record must have
1736 * a 16-byte IPv6 address, hence a minimum
1739 * (The pcap-NG spec really indicates
1740 * that it must be at least 17 bytes,
1741 * as there must be at least one name,
1742 * and it really must be at least 18
1743 * bytes, as the name mustn't be null,
1744 * but there's no need to fail if there
1745 * aren't any names at all, and we
1746 * should report a null name as such.)
1748 if (nrb.record_len < 16) {
1749 ws_buffer_free(&nrb_rec);
1750 *err = WTAP_ERR_BAD_FILE;
1751 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u < minimum length 16",
1755 if (to_read < nrb.record_len) {
1756 ws_buffer_free(&nrb_rec);
1757 *err = WTAP_ERR_BAD_FILE;
1758 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u > remaining data in NRB",
1762 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1763 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1764 nrb.record_len, err, err_info)) {
1765 ws_buffer_free(&nrb_rec);
1768 block_read += nrb.record_len;
1770 if (pn->add_new_ipv6) {
1771 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
1773 namep += namelen, record_len -= namelen) {
1775 * Scan forward for a null
1778 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1779 if (namelen == -1) {
1780 ws_buffer_free(&nrb_rec);
1781 return FALSE; /* fail */
1783 pn->add_new_ipv6(ws_buffer_start_ptr(&nrb_rec),
1788 if (!file_skip(fh, PADDING4(nrb.record_len), err)) {
1789 ws_buffer_free(&nrb_rec);
1792 block_read += PADDING4(nrb.record_len);
1795 pcapng_debug("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
1796 if (!file_skip(fh, nrb.record_len + PADDING4(nrb.record_len), err)) {
1797 ws_buffer_free(&nrb_rec);
1800 block_read += nrb.record_len + PADDING4(nrb.record_len);
1807 to_read -= block_read;
1818 /* Allocate enough memory to hold all options */
1819 opt_cont_buf_len = to_read;
1820 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1821 if (opt_cont_buf_len != 0 && option_content == NULL) {
1822 *err = ENOMEM; /* we assume we're out of memory */
1823 ws_buffer_free(&nrb_rec);
1827 while (to_read != 0) {
1829 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "name_resolution");
1830 if (bytes_read <= 0) {
1831 pcapng_debug("pcapng_read_name_resolution_block: failed to read option");
1832 g_free(option_content);
1833 ws_buffer_free(&nrb_rec);
1836 to_read -= bytes_read;
1838 /* handle option content */
1839 switch (oh.option_code) {
1842 pcapng_debug("pcapng_read_name_resolution_block: %u bytes after opt_endofopt", to_read);
1844 /* padding should be ok here, just get out of this */
1848 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1849 tmp_content = g_strndup((char *)option_content, oh.option_length);
1850 wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1851 pcapng_debug("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, tmp_content);
1852 g_free(tmp_content);
1854 pcapng_debug("pcapng_read_name_resolution_block: opt_comment length %u seems strange", oh.option_length);
1860 * Do we have a handler for this network resolution block option code?
1862 if (option_handlers[BT_INDEX_NRB] != NULL &&
1863 (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_NRB],
1864 GUINT_TO_POINTER((guint)oh.option_code))) != NULL) {
1865 /* Yes - call the handler. */
1866 if (!handler->hfunc(pn->byte_swapped, oh.option_length,
1867 option_content, err, err_info)) {
1869 g_free(option_content);
1870 ws_buffer_free(&nrb_rec);
1876 pcapng_debug("pcapng_read_name_resolution_block: unknown option %u - ignoring %u bytes",
1877 oh.option_code, oh.option_length);
1882 g_free(option_content);
1883 ws_buffer_free(&nrb_rec);
1888 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)
1891 guint to_read, opt_cont_buf_len;
1892 pcapng_interface_statistics_block_t isb;
1893 pcapng_option_header_t oh;
1894 guint8 *option_content = NULL; /* Allocate as large as the options block */
1895 wtapng_if_stats_mandatory_t* if_stats_mand;
1899 * Is this block long enough to be an ISB?
1901 if (bh->block_total_length < MIN_ISB_SIZE) {
1905 *err = WTAP_ERR_BAD_FILE;
1906 *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too small (< %u)",
1907 bh->block_total_length, MIN_ISB_SIZE);
1911 /* Don't try to allocate memory for a huge number of options, as
1912 that might fail and, even if it succeeds, it might not leave
1913 any address space or memory+backing store for anything else.
1915 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1916 We check for this *after* checking the SHB for its byte
1917 order magic number, so that non-pcap-ng files are less
1918 likely to be treated as bad pcap-ng files. */
1919 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1920 *err = WTAP_ERR_BAD_FILE;
1921 *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too large (> %u)",
1922 bh->block_total_length, MAX_BLOCK_SIZE);
1926 /* "Interface Statistics Block" read fixed part */
1927 if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
1928 pcapng_debug("pcapng_read_interface_statistics_block: failed to read packet data");
1932 wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS);
1933 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
1934 if (pn->byte_swapped) {
1935 if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
1936 if_stats_mand->ts_high = GUINT32_SWAP_LE_BE(isb.timestamp_high);
1937 if_stats_mand->ts_low = GUINT32_SWAP_LE_BE(isb.timestamp_low);
1939 if_stats_mand->interface_id = isb.interface_id;
1940 if_stats_mand->ts_high = isb.timestamp_high;
1941 if_stats_mand->ts_low = isb.timestamp_low;
1943 pcapng_debug("pcapng_read_interface_statistics_block: interface_id %u", if_stats_mand->interface_id);
1946 to_read = bh->block_total_length -
1947 (MIN_BLOCK_SIZE + (guint)sizeof isb); /* fixed and variable part, including padding */
1949 /* Allocate enough memory to hold all options */
1950 opt_cont_buf_len = to_read;
1951 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1952 if (opt_cont_buf_len != 0 && option_content == NULL) {
1953 *err = ENOMEM; /* we assume we're out of memory */
1957 while (to_read != 0) {
1959 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "interface_statistics");
1960 if (bytes_read <= 0) {
1961 pcapng_debug("pcapng_read_interface_statistics_block: failed to read option");
1964 to_read -= bytes_read;
1966 /* handle option content */
1967 switch (oh.option_code) {
1968 case(OPT_EOFOPT): /* opt_endofopt */
1970 pcapng_debug("pcapng_read_interface_statistics_block: %u bytes after opt_endofopt", to_read);
1972 /* padding should be ok here, just get out of this */
1975 case(OPT_COMMENT): /* opt_comment */
1976 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1977 tmp_content = g_strndup((char *)option_content, oh.option_length);
1978 wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1979 pcapng_debug("pcapng_read_interface_statistics_block: opt_comment %s", tmp_content);
1980 g_free(tmp_content);
1982 pcapng_debug("pcapng_read_interface_statistics_block: opt_comment length %u seems strange", oh.option_length);
1985 case(OPT_ISB_STARTTIME): /* isb_starttime */
1986 if (oh.option_length == 8) {
1990 /* Don't cast a guint8 * into a guint32 *--the
1991 * guint8 * may not point to something that's
1992 * aligned correctly.
1994 memcpy(&high, option_content, sizeof(guint32));
1995 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
1996 if (pn->byte_swapped) {
1997 high = GUINT32_SWAP_LE_BE(high);
1998 low = GUINT32_SWAP_LE_BE(low);
2000 starttime = (guint64)high;
2002 starttime += (guint64)low;
2003 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_STARTTIME, starttime);
2004 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime %" G_GINT64_MODIFIER "u", starttime);
2006 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2009 case(OPT_ISB_ENDTIME): /* isb_endtime */
2010 if (oh.option_length == 8) {
2014 /* Don't cast a guint8 * into a guint32 *--the
2015 * guint8 * may not point to something that's
2016 * aligned correctly.
2018 memcpy(&high, option_content, sizeof(guint32));
2019 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
2020 if (pn->byte_swapped) {
2021 high = GUINT32_SWAP_LE_BE(high);
2022 low = GUINT32_SWAP_LE_BE(low);
2024 endtime = (guint64)high;
2026 endtime += (guint64)low;
2027 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_ENDTIME, endtime);
2028 pcapng_debug("pcapng_read_interface_statistics_block: isb_endtime %" G_GINT64_MODIFIER "u", endtime);
2030 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2033 case(OPT_ISB_IFRECV): /* isb_ifrecv */
2034 if (oh.option_length == 8) {
2036 /* Don't cast a guint8 * into a guint64 *--the
2037 * guint8 * may not point to something that's
2038 * aligned correctly.
2040 memcpy(&ifrecv, option_content, sizeof(guint64));
2041 if (pn->byte_swapped)
2042 ifrecv = GUINT64_SWAP_LE_BE(ifrecv);
2043 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_IFRECV, ifrecv);
2044 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", ifrecv);
2046 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv length %u not 8 as expected", oh.option_length);
2049 case(OPT_ISB_IFDROP): /* isb_ifdrop */
2050 if (oh.option_length == 8) {
2052 /* Don't cast a guint8 * into a guint64 *--the
2053 * guint8 * may not point to something that's
2054 * aligned correctly.
2056 memcpy(&ifdrop, option_content, sizeof(guint64));
2057 if (pn->byte_swapped)
2058 ifdrop = GUINT64_SWAP_LE_BE(ifdrop);
2059 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_IFDROP, ifdrop);
2060 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", ifdrop);
2062 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop length %u not 8 as expected", oh.option_length);
2065 case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
2066 if (oh.option_length == 8) {
2067 guint64 filteraccept;
2068 /* Don't cast a guint8 * into a guint64 *--the
2069 * guint8 * may not point to something that's
2070 * aligned correctly.
2072 memcpy(&filteraccept, option_content, sizeof(guint64));
2073 if (pn->byte_swapped)
2074 filteraccept = GUINT64_SWAP_LE_BE(filteraccept);
2075 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_FILTERACCEPT, filteraccept);
2076 pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept %" G_GINT64_MODIFIER "u", filteraccept);
2078 pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept length %u not 8 as expected", oh.option_length);
2081 case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
2082 if (oh.option_length == 8) {
2084 /* Don't cast a guint8 * into a guint64 *--the
2085 * guint8 * may not point to something that's
2086 * aligned correctly.
2088 memcpy(&osdrop, option_content, sizeof(guint64));
2089 if (pn->byte_swapped)
2090 osdrop = GUINT64_SWAP_LE_BE(osdrop);
2091 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_OSDROP, osdrop);
2092 pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop %" G_GINT64_MODIFIER "u", osdrop);
2094 pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop length %u not 8 as expected", oh.option_length);
2097 case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8 */
2098 if (oh.option_length == 8) {
2100 /* Don't cast a guint8 * into a guint64 *--the
2101 * guint8 * may not point to something that's
2102 * aligned correctly.
2104 memcpy(&usrdeliv, option_content, sizeof(guint64));
2105 if (pn->byte_swapped)
2106 usrdeliv = GUINT64_SWAP_LE_BE(usrdeliv);
2107 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_USRDELIV, usrdeliv);
2108 pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv %" G_GINT64_MODIFIER "u", usrdeliv);
2110 pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv length %u not 8 as expected", oh.option_length);
2114 pcapng_debug("pcapng_read_interface_statistics_block: unknown option %u - ignoring %u bytes",
2115 oh.option_code, oh.option_length);
2119 g_free(option_content);
2125 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)
2127 unsigned block_read;
2128 guint32 block_total_length;
2136 if (bh->block_total_length < MIN_SYSDIG_EVENT_SIZE) {
2137 *err = WTAP_ERR_BAD_FILE;
2138 *err_info = g_strdup_printf("%s: total block length %u is too small (< %u)", G_STRFUNC,
2139 bh->block_total_length, MIN_SYSDIG_EVENT_SIZE);
2143 /* add padding bytes to "block total length" */
2144 /* (the "block total length" of some example files don't contain any padding bytes!) */
2145 if (bh->block_total_length % 4) {
2146 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2148 block_total_length = bh->block_total_length;
2151 pcapng_debug("pcapng_read_sysdig_event_block: block_total_length %u",
2152 bh->block_total_length);
2154 wblock->packet_header->rec_type = REC_TYPE_FT_SPECIFIC_EVENT;
2155 wblock->packet_header->pseudo_header.sysdig_event.record_type = BLOCK_TYPE_SYSDIG_EVENT;
2156 wblock->packet_header->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
2157 wblock->packet_header->pkt_tsprec = WTAP_TSPREC_NSEC;
2159 block_read = block_total_length;
2161 if (!wtap_read_bytes(fh, &cpu_id, sizeof cpu_id, err, err_info)) {
2162 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event cpu id");
2165 if (!wtap_read_bytes(fh, &wire_ts, sizeof wire_ts, err, err_info)) {
2166 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event timestamp");
2169 if (!wtap_read_bytes(fh, &thread_id, sizeof thread_id, err, err_info)) {
2170 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event thread id");
2173 if (!wtap_read_bytes(fh, &event_len, sizeof event_len, err, err_info)) {
2174 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event length");
2177 if (!wtap_read_bytes(fh, &event_type, sizeof event_type, err, err_info)) {
2178 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event type");
2182 block_read -= MIN_SYSDIG_EVENT_SIZE;
2183 wblock->packet_header->pseudo_header.sysdig_event.byte_order = G_BYTE_ORDER;
2185 if (pn->byte_swapped) {
2186 wblock->packet_header->pseudo_header.sysdig_event.byte_order =
2187 G_BYTE_ORDER == G_LITTLE_ENDIAN ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
2188 wblock->packet_header->pseudo_header.sysdig_event.cpu_id = GUINT16_SWAP_LE_BE(cpu_id);
2189 ts = GUINT64_SWAP_LE_BE(wire_ts);
2190 wblock->packet_header->pseudo_header.sysdig_event.thread_id = GUINT64_SWAP_LE_BE(thread_id);
2191 wblock->packet_header->pseudo_header.sysdig_event.event_len = GUINT32_SWAP_LE_BE(event_len);
2192 wblock->packet_header->pseudo_header.sysdig_event.event_type = GUINT16_SWAP_LE_BE(event_type);
2194 wblock->packet_header->pseudo_header.sysdig_event.cpu_id = cpu_id;
2196 wblock->packet_header->pseudo_header.sysdig_event.thread_id = thread_id;
2197 wblock->packet_header->pseudo_header.sysdig_event.event_len = event_len;
2198 wblock->packet_header->pseudo_header.sysdig_event.event_type = event_type;
2201 wblock->packet_header->ts.secs = (time_t) (ts / 1000000000);
2202 wblock->packet_header->ts.nsecs = (int) (ts % 1000000000);
2204 wblock->packet_header->caplen = block_read;
2205 wblock->packet_header->len = wblock->packet_header->pseudo_header.sysdig_event.event_len;
2207 /* "Sysdig Event Block" read event data */
2208 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2209 block_read, err, err_info))
2216 pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh,
2220 wtapng_block_t *wblock,
2223 wtapng_block_t *wblock _U_,
2225 int *err, gchar **err_info)
2228 guint32 block_total_length;
2230 block_handler *handler;
2233 if (bh->block_total_length < MIN_BLOCK_SIZE) {
2234 *err = WTAP_ERR_BAD_FILE;
2235 *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",
2236 bh->block_total_length, MIN_BLOCK_SIZE);
2240 /* add padding bytes to "block total length" */
2241 /* (the "block total length" of some example files don't contain any padding bytes!) */
2242 if (bh->block_total_length % 4) {
2243 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2245 block_total_length = bh->block_total_length;
2248 block_read = block_total_length - MIN_BLOCK_SIZE;
2252 * Do we have a handler for this block type?
2254 if (block_handlers != NULL &&
2255 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
2256 GUINT_TO_POINTER(bh->block_type))) != NULL) {
2257 /* Yes - call it to read this block type. */
2258 if (!handler->reader(fh, block_read, pn->byte_swapped,
2259 wblock->packet_header, wblock->frame_buffer,
2265 /* No. Skip over this unknown block. */
2266 if (!file_skip(fh, block_read, err)) {
2275 static block_return_val
2276 pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
2278 block_return_val ret;
2279 pcapng_block_header_t bh;
2280 guint32 block_total_length;
2282 wblock->block = NULL;
2284 /* Try to read the (next) block header */
2285 if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
2286 pcapng_debug("pcapng_read_block: wtap_read_bytes_or_eof() failed, err = %d.", *err);
2287 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
2289 * Short read or EOF.
2291 * If we're reading this as part of an open,
2292 * the file is too short to be a pcap-ng file.
2294 * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
2295 * PCAPNG_BLOCK_ERROR the same, so we can just return
2296 * PCAPNG_BLOCK_NOT_SHB in both cases.
2298 return PCAPNG_BLOCK_NOT_SHB;
2300 return PCAPNG_BLOCK_ERROR;
2304 * SHBs have to be treated differently from other blocks, as we
2305 * might be doing an open and attempting to read a block at the
2306 * beginning of the file to see if it's a pcap-ng file or not,
2307 * and as they do not necessarily have the same byte order as
2310 if (bh.block_type == BLOCK_TYPE_SHB) {
2312 * BLOCK_TYPE_SHB has the same value regardless of byte order,
2313 * so we don't need to byte-swap it.
2315 wblock->type = bh.block_type;
2317 pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2319 ret = pcapng_read_section_header_block(fh, &bh, pn, wblock, err, err_info);
2320 if (ret != PCAPNG_BLOCK_OK) {
2324 if (pn->byte_swapped) {
2325 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
2326 bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length);
2329 wblock->type = bh.block_type;
2331 pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2333 if (!pn->shb_read) {
2335 * No SHB seen yet, so we're trying to read the first block
2336 * during an open, to see whether it's an SHB; if what we
2337 * read doesn't look like an SHB, this isn't a pcap-ng file.
2341 return PCAPNG_BLOCK_NOT_SHB;
2343 switch (bh.block_type) {
2344 case(BLOCK_TYPE_IDB):
2345 if (!pcapng_read_if_descr_block(wth, fh, &bh, pn, wblock, err, err_info))
2346 return PCAPNG_BLOCK_ERROR;
2348 case(BLOCK_TYPE_PB):
2349 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE))
2350 return PCAPNG_BLOCK_ERROR;
2352 case(BLOCK_TYPE_SPB):
2353 if (!pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info))
2354 return PCAPNG_BLOCK_ERROR;
2356 case(BLOCK_TYPE_EPB):
2357 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE))
2358 return PCAPNG_BLOCK_ERROR;
2360 case(BLOCK_TYPE_NRB):
2361 if (!pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info))
2362 return PCAPNG_BLOCK_ERROR;
2364 case(BLOCK_TYPE_ISB):
2365 if (!pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info))
2366 return PCAPNG_BLOCK_ERROR;
2368 case(BLOCK_TYPE_SYSDIG_EVENT):
2369 /* case(BLOCK_TYPE_SYSDIG_EVF): */
2370 if (!pcapng_read_sysdig_event_block(fh, &bh, pn, wblock, err, err_info))
2371 return PCAPNG_BLOCK_ERROR;
2374 pcapng_debug("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
2375 if (!pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info))
2376 return PCAPNG_BLOCK_ERROR;
2381 /* sanity check: first and second block lengths must match */
2382 if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
2384 pcapng_debug("pcapng_check_block_trailer: couldn't read second block length");
2385 return PCAPNG_BLOCK_ERROR;
2388 if (pn->byte_swapped)
2389 block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
2391 if (block_total_length != bh.block_total_length) {
2392 *err = WTAP_ERR_BAD_FILE;
2393 *err_info = g_strdup_printf("pcapng_check_block_trailer: total block lengths (first %u and second %u) don't match",
2394 bh.block_total_length, block_total_length);
2395 return PCAPNG_BLOCK_ERROR;
2397 return PCAPNG_BLOCK_OK;
2400 /* Process an IDB that we've just read. */
2402 pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
2404 wtap_optionblock_t int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
2405 interface_info_t iface_info;
2406 wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data),
2407 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
2409 wtap_optionblock_copy_options(int_data, wblock->block);
2411 /* XXX if_tsoffset; opt 14 A 64 bits integer value that specifies an offset (in seconds)...*/
2412 /* Interface statistics */
2413 if_descr_mand->num_stat_entries = 0;
2414 if_descr_mand->interface_statistics = NULL;
2416 g_array_append_val(wth->interface_data, int_data);
2418 iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
2419 iface_info.snap_len = wblock_if_descr_mand->snap_len;
2420 iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
2421 iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
2423 g_array_append_val(pcapng->interfaces, iface_info);
2426 /* classic wtap: open capture file */
2427 wtap_open_return_val
2428 pcapng_open(wtap *wth, int *err, gchar **err_info)
2431 wtapng_block_t wblock;
2433 pcapng_block_header_t bh;
2434 gint64 saved_offset;
2436 pn.shb_read = FALSE;
2437 /* we don't know the byte swapping of the file yet */
2438 pn.byte_swapped = FALSE;
2440 pn.version_major = -1;
2441 pn.version_minor = -1;
2442 pn.interfaces = NULL;
2444 /* we don't expect any packet blocks yet */
2445 wblock.frame_buffer = NULL;
2446 wblock.packet_header = NULL;
2448 pcapng_debug("pcapng_open: opening file");
2449 /* read first block */
2450 switch (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info)) {
2452 case PCAPNG_BLOCK_OK:
2456 case PCAPNG_BLOCK_NOT_SHB:
2457 /* An error indicating that this isn't a pcap-ng file. */
2458 wtap_optionblock_free(wblock.block);
2459 wblock.block = NULL;
2462 return WTAP_OPEN_NOT_MINE;
2464 case PCAPNG_BLOCK_ERROR:
2465 /* An I/O error, or this probably *is* a pcap-ng file but not a valid one. */
2466 wtap_optionblock_free(wblock.block);
2467 wblock.block = NULL;
2468 return WTAP_OPEN_ERROR;
2471 /* first block must be a "Section Header Block" */
2472 if (wblock.type != BLOCK_TYPE_SHB) {
2474 * XXX - check for damage from transferring a file
2475 * between Windows and UN*X as text rather than
2478 pcapng_debug("pcapng_open: first block type %u not SHB", wblock.type);
2479 wtap_optionblock_free(wblock.block);
2480 wblock.block = NULL;
2481 return WTAP_OPEN_NOT_MINE;
2486 * At this point, we've decided this is a pcap-NG file, not
2487 * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
2490 wtap_optionblock_copy_options(wth->shb_hdr, wblock.block);
2492 wth->file_encap = WTAP_ENCAP_UNKNOWN;
2493 wth->snapshot_length = 0;
2494 wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
2495 pcapng = (pcapng_t *)g_malloc(sizeof(pcapng_t));
2496 wth->priv = (void *)pcapng;
2498 pcapng->interfaces = g_array_new(FALSE, FALSE, sizeof(interface_info_t));
2500 wth->subtype_read = pcapng_read;
2501 wth->subtype_seek_read = pcapng_seek_read;
2502 wth->subtype_close = pcapng_close;
2503 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
2505 /* Loop over all IDB:s that appear before any packets */
2507 /* peek at next block */
2508 /* Try to read the (next) block header */
2509 saved_offset = file_tell(wth->fh);
2510 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
2513 pcapng_debug("No more IDBs available...");
2516 pcapng_debug("pcapng_open: Check for more IDB:s, wtap_read_bytes_or_eof() failed, err = %d.", *err);
2517 return WTAP_OPEN_ERROR;
2520 /* go back to where we were */
2521 file_seek(wth->fh, saved_offset, SEEK_SET, err);
2523 if (pn.byte_swapped) {
2524 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
2527 pcapng_debug("pcapng_open: Check for more IDB:s block_type 0x%x", bh.block_type);
2529 if (bh.block_type != BLOCK_TYPE_IDB) {
2530 break; /* No more IDB:s */
2532 if (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2534 pcapng_debug("No more IDBs available...");
2535 wtap_optionblock_free(wblock.block);
2536 wblock.block = NULL;
2539 pcapng_debug("pcapng_open: couldn't read IDB");
2540 wtap_optionblock_free(wblock.block);
2541 wblock.block = NULL;
2542 return WTAP_OPEN_ERROR;
2545 pcapng_process_idb(wth, pcapng, &wblock);
2546 pcapng_debug("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i",
2547 wth->interface_data->len, wth->file_encap);
2549 return WTAP_OPEN_MINE;
2553 /* classic wtap: read packet */
2555 pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
2557 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2558 wtapng_block_t wblock;
2559 wtap_optionblock_t wtapng_if_descr;
2560 wtap_optionblock_t if_stats;
2561 wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
2562 wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
2564 wblock.frame_buffer = wth->frame_buffer;
2565 wblock.packet_header = &wth->phdr;
2567 pcapng->add_new_ipv4 = wth->add_new_ipv4;
2568 pcapng->add_new_ipv6 = wth->add_new_ipv6;
2570 /* read next block */
2572 *data_offset = file_tell(wth->fh);
2573 pcapng_debug("pcapng_read: data_offset is %" G_GINT64_MODIFIER "d", *data_offset);
2574 if (pcapng_read_block(wth, wth->fh, pcapng, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2575 pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2576 pcapng_debug("pcapng_read: couldn't read packet block");
2580 switch (wblock.type) {
2582 case(BLOCK_TYPE_SHB):
2583 /* We don't currently support multi-section files. */
2584 wth->phdr.pkt_encap = WTAP_ENCAP_UNKNOWN;
2585 wth->phdr.pkt_tsprec = WTAP_TSPREC_UNKNOWN;
2586 *err = WTAP_ERR_UNSUPPORTED;
2587 *err_info = g_strdup_printf("pcapng: multi-section files not currently supported");
2590 case(BLOCK_TYPE_PB):
2591 case(BLOCK_TYPE_SPB):
2592 case(BLOCK_TYPE_EPB):
2593 case(BLOCK_TYPE_SYSDIG_EVENT):
2594 case(BLOCK_TYPE_SYSDIG_EVF):
2595 /* packet block - we've found a packet */
2598 case(BLOCK_TYPE_IDB):
2599 /* A new interface */
2600 pcapng_debug("pcapng_read: block type BLOCK_TYPE_IDB");
2601 pcapng_process_idb(wth, pcapng, &wblock);
2604 case(BLOCK_TYPE_NRB):
2605 /* More name resolution entries */
2606 pcapng_debug("pcapng_read: block type BLOCK_TYPE_NRB");
2609 case(BLOCK_TYPE_ISB):
2610 /* Another interface statistics report */
2611 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB");
2612 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock.block);
2613 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
2614 pcapng_debug("pcapng_read: BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces", if_stats_mand_block->interface_id);
2616 /* Get the interface description */
2617 wtapng_if_descr = g_array_index(wth->interface_data, wtap_optionblock_t, if_stats_mand_block->interface_id);
2618 wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wtapng_if_descr);
2619 if (wtapng_if_descr_mand->num_stat_entries == 0) {
2620 /* First ISB found, no previous entry */
2621 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
2622 wtapng_if_descr_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2625 if_stats = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS);
2626 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats);
2627 if_stats_mand->interface_id = if_stats_mand_block->interface_id;
2628 if_stats_mand->ts_high = if_stats_mand_block->ts_high;
2629 if_stats_mand->ts_low = if_stats_mand_block->ts_low;
2631 wtap_optionblock_copy_options(if_stats, wblock.block);
2632 g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
2633 wtapng_if_descr_mand->num_stat_entries++;
2638 /* XXX - improve handling of "unknown" blocks */
2639 pcapng_debug("pcapng_read: Unknown block type 0x%08x", wblock.type);
2646 /*pcapng_debug("Read length: %u Packet length: %u", bytes_read, wth->phdr.caplen);*/
2647 pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2653 /* classic wtap: seek to file position and read packet */
2655 pcapng_seek_read(wtap *wth, gint64 seek_off,
2656 struct wtap_pkthdr *phdr, Buffer *buf,
2657 int *err, gchar **err_info)
2659 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2660 block_return_val ret;
2661 wtapng_block_t wblock;
2664 /* seek to the right file position */
2665 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
2666 return FALSE; /* Seek error */
2668 pcapng_debug("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
2670 wblock.frame_buffer = buf;
2671 wblock.packet_header = phdr;
2673 /* read the block */
2674 ret = pcapng_read_block(wth, wth->random_fh, pcapng, &wblock, err, err_info);
2675 wtap_optionblock_free(wblock.block);
2676 if (ret != PCAPNG_BLOCK_OK) {
2677 pcapng_debug("pcapng_seek_read: couldn't read packet block (err=%d).",
2682 /* block must be a "Packet Block", an "Enhanced Packet Block",
2683 a "Simple Packet Block", or an event */
2684 if (wblock.type != BLOCK_TYPE_PB && wblock.type != BLOCK_TYPE_EPB &&
2685 wblock.type != BLOCK_TYPE_SPB &&
2686 wblock.type != BLOCK_TYPE_SYSDIG_EVENT && wblock.type != BLOCK_TYPE_SYSDIG_EVF) {
2687 pcapng_debug("pcapng_seek_read: block type %u not PB/EPB/SPB", wblock.type);
2695 /* classic wtap: close capture file */
2697 pcapng_close(wtap *wth)
2699 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2701 pcapng_debug("pcapng_close: closing file");
2702 g_array_free(pcapng->interfaces, TRUE);
2705 typedef struct pcapng_optionblock_size_t
2708 } pcapng_optionblock_size_t;
2710 static guint32 pcapng_compute_option_string_size(char *str)
2712 guint32 size = 0, pad;
2717 size = (guint32)strlen(str) & 0xffff;
2719 pad = 4 - (size % 4);
2729 static void compute_shb_option_size(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data)
2731 pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data;
2737 case OPT_SHB_HARDWARE:
2739 case OPT_SHB_USERAPPL:
2741 size = pcapng_compute_option_string_size(option->stringval);
2744 /* Unknown options - size by datatype? */
2748 block_size->size += size;
2749 /* Add bytes for option header if option should be written */
2751 /* Add optional padding to 32 bits */
2752 if ((block_size->size & 0x03) != 0)
2754 block_size->size += 4 - (block_size->size & 0x03);
2756 block_size->size += 4;
2760 typedef struct pcapng_write_block_t
2766 pcapng_write_block_t;
2768 static gboolean pcapng_write_option_string(wtap_dumper *wdh, guint option_id, char *str, int *err)
2770 struct pcapng_option_header option_hdr;
2771 guint32 size = (guint32)strlen(str) & 0xffff;
2772 const guint32 zero_pad = 0;
2778 /* String options don't consider pad bytes part of the length */
2779 option_hdr.type = (guint16)option_id;
2780 option_hdr.value_length = (guint16)size;
2781 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2783 wdh->bytes_dumped += 4;
2785 if (!wtap_dump_file_write(wdh, str, size, err))
2787 wdh->bytes_dumped += size;
2790 pad = 4 - (size % 4);
2795 /* write padding (if any) */
2797 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
2800 wdh->bytes_dumped += pad;
2806 static void write_wtap_shb_block(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data)
2808 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
2810 /* Don't continue if there has been an error */
2811 if (!write_block->success)
2817 case OPT_SHB_HARDWARE:
2819 case OPT_SHB_USERAPPL:
2820 if ((option != NULL) && (option->stringval != NULL)) {
2821 if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) {
2822 write_block->success = FALSE;
2828 /* Unknown options - write by datatype? */
2833 /* Write a section header block.
2834 * If we don't have a section block header already, create a default
2835 * one with no options.
2838 pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
2840 pcapng_block_header_t bh;
2841 pcapng_section_header_block_t shb;
2842 pcapng_optionblock_size_t block_size;
2843 struct pcapng_option_header option_hdr;
2845 block_size.size = 0;
2846 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + 4);
2848 pcapng_debug("pcapng_write_section_header_block: Have shb_hdr");
2850 /* Compute block size */
2851 wtap_optionblock_foreach_option(wdh->shb_hdr, compute_shb_option_size, &block_size);
2853 if (block_size.size > 0) {
2854 /* End-of-options tag */
2855 block_size.size += 4;
2858 bh.block_total_length += block_size.size;
2861 pcapng_debug("pcapng_write_section_header_block: Total len %u", bh.block_total_length);
2863 /* write block header */
2864 bh.block_type = BLOCK_TYPE_SHB;
2866 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
2868 wdh->bytes_dumped += sizeof bh;
2870 /* write block fixed content */
2871 shb.magic = 0x1A2B3C4D;
2872 shb.version_major = 1;
2873 shb.version_minor = 0;
2875 wtapng_mandatory_section_t* section_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(wdh->shb_hdr);
2876 shb.section_length = section_data->section_length;
2878 shb.section_length = -1;
2881 if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
2883 wdh->bytes_dumped += sizeof shb;
2886 pcapng_write_block_t block_data;
2888 if (block_size.size > 0) {
2890 block_data.wdh = wdh;
2891 block_data.err = err;
2892 block_data.success = TRUE;
2893 wtap_optionblock_foreach_option(wdh->shb_hdr, write_wtap_shb_block, &block_data);
2895 if (!block_data.success)
2898 /* Write end of options */
2899 option_hdr.type = OPT_EOFOPT;
2900 option_hdr.value_length = 0;
2901 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2903 wdh->bytes_dumped += 4;
2907 /* write block footer */
2908 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
2909 sizeof bh.block_total_length, err))
2911 wdh->bytes_dumped += sizeof bh.block_total_length;
2917 pcapng_write_enhanced_packet_block(wtap_dumper *wdh,
2918 const struct wtap_pkthdr *phdr,
2919 const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err)
2921 pcapng_block_header_t bh;
2922 pcapng_enhanced_packet_block_t epb;
2924 const guint32 zero_pad = 0;
2927 gboolean have_options = FALSE;
2928 guint32 options_total_length = 0;
2929 struct option option_hdr;
2930 guint32 comment_len = 0, comment_pad_len = 0;
2931 wtap_optionblock_t int_data;
2932 wtapng_if_descr_mandatory_t *int_data_mand;
2934 /* Don't write anything we're not willing to read. */
2935 if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
2936 *err = WTAP_ERR_PACKET_TOO_LARGE;
2940 phdr_len = (guint32)pcap_get_phdr_size(phdr->pkt_encap, pseudo_header);
2941 if ((phdr_len + phdr->caplen) % 4) {
2942 pad_len = 4 - ((phdr_len + phdr->caplen) % 4);
2947 /* Check if we should write comment option */
2948 if (phdr->opt_comment) {
2949 have_options = TRUE;
2950 comment_len = (guint32)strlen(phdr->opt_comment) & 0xffff;
2951 if ((comment_len % 4)) {
2952 comment_pad_len = 4 - (comment_len % 4);
2954 comment_pad_len = 0;
2956 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
2958 if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
2959 have_options = TRUE;
2960 options_total_length = options_total_length + 8;
2963 /* End-of options tag */
2964 options_total_length += 4;
2967 /* write (enhanced) packet block header */
2968 bh.block_type = BLOCK_TYPE_EPB;
2969 bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + phdr->caplen + pad_len + options_total_length + 4;
2971 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
2973 wdh->bytes_dumped += sizeof bh;
2975 /* write block fixed content */
2976 if (phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
2977 epb.interface_id = phdr->interface_id;
2980 * XXX - we should support writing WTAP_ENCAP_PER_PACKET
2981 * data to pcap-NG files even if we *don't* have interface
2984 epb.interface_id = 0;
2987 * Split the 64-bit timestamp into two 32-bit pieces, using
2988 * the time stamp resolution for the interface.
2990 if (epb.interface_id >= wdh->interface_data->len) {
2992 * Our caller is doing something bad.
2994 *err = WTAP_ERR_INTERNAL;
2997 int_data = g_array_index(wdh->interface_data, wtap_optionblock_t,
2999 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
3000 ts = ((guint64)phdr->ts.secs) * int_data_mand->time_units_per_second +
3001 (((guint64)phdr->ts.nsecs) * int_data_mand->time_units_per_second) / 1000000000;
3002 epb.timestamp_high = (guint32)(ts >> 32);
3003 epb.timestamp_low = (guint32)ts;
3004 epb.captured_len = phdr->caplen + phdr_len;
3005 epb.packet_len = phdr->len + phdr_len;
3007 if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
3009 wdh->bytes_dumped += sizeof epb;
3011 /* write pseudo header */
3012 if (!pcap_write_phdr(wdh, phdr->pkt_encap, pseudo_header, err)) {
3015 wdh->bytes_dumped += phdr_len;
3017 /* write packet data */
3018 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
3020 wdh->bytes_dumped += phdr->caplen;
3022 /* write padding (if any) */
3024 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3026 wdh->bytes_dumped += pad_len;
3029 /* XXX - write (optional) block options */
3030 /* options defined in Section 2.5 (Options)
3031 * Name Code Length Description
3032 * opt_comment 1 variable A UTF-8 string containing a comment that is associated to the current block.
3034 * Enhanced Packet Block options
3035 * epb_flags 2 4 A flags word containing link-layer information. A complete specification of
3036 * the allowed flags can be found in Appendix A (Packet Block Flags Word).
3037 * epb_hash 3 variable This option contains a hash of the packet. The first byte specifies the hashing algorithm,
3038 * while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
3039 * and hence from the value in the first bit. The hashing algorithm can be: 2s complement
3040 * (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
3041 * MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
3042 * The hash covers only the packet, not the header added by the capture driver:
3043 * this gives the possibility to calculate it inside the network card.
3044 * The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
3045 * data acquisition system and the capture library.
3046 * epb_dropcount 4 8 A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
3047 * between this packet and the preceding one.
3048 * opt_endofopt 0 0 It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
3050 if (phdr->opt_comment) {
3051 option_hdr.type = OPT_COMMENT;
3052 option_hdr.value_length = comment_len;
3053 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3055 wdh->bytes_dumped += 4;
3057 /* Write the comments string */
3058 pcapng_debug("pcapng_write_enhanced_packet_block, comment:'%s' comment_len %u comment_pad_len %u" , phdr->opt_comment, comment_len, comment_pad_len);
3059 if (!wtap_dump_file_write(wdh, phdr->opt_comment, comment_len, err))
3061 wdh->bytes_dumped += comment_len;
3063 /* write padding (if any) */
3064 if (comment_pad_len != 0) {
3065 if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
3067 wdh->bytes_dumped += comment_pad_len;
3070 pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
3074 if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
3075 option_hdr.type = OPT_EPB_FLAGS;
3076 option_hdr.value_length = 4;
3077 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3079 wdh->bytes_dumped += 4;
3080 if (!wtap_dump_file_write(wdh, &phdr->pack_flags, 4, err))
3082 wdh->bytes_dumped += 4;
3083 pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options packet flags: %x", phdr->pack_flags);
3085 /* Write end of options if we have options */
3087 if (!wtap_dump_file_write(wdh, &zero_pad, 4, err))
3089 wdh->bytes_dumped += 4;
3092 /* write block footer */
3093 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3094 sizeof bh.block_total_length, err))
3096 wdh->bytes_dumped += sizeof bh.block_total_length;
3102 #define NRES_REC_MAX_SIZE ((WTAP_MAX_PACKET_SIZE * 4) + 16)
3104 pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
3106 pcapng_block_header_t bh;
3107 pcapng_name_resolution_block_t nrb;
3112 guint32 tot_rec_len;
3113 hashipv4_t *ipv4_hash_list_entry;
3114 hashipv6_t *ipv6_hash_list_entry;
3117 if ((!wdh->addrinfo_lists) || ((!wdh->addrinfo_lists->ipv4_addr_list)&&(!wdh->addrinfo_lists->ipv6_addr_list))) {
3121 rec_off = 8; /* block type + block total length */
3122 bh.block_type = BLOCK_TYPE_NRB;
3123 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
3124 rec_data = (guint8 *)g_malloc(NRES_REC_MAX_SIZE);
3126 if (wdh->addrinfo_lists->ipv4_addr_list){
3128 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3129 while(ipv4_hash_list_entry != NULL){
3131 nrb.record_type = NRES_IP4RECORD;
3132 hostnamelen = strlen(ipv4_hash_list_entry->name);
3133 if (hostnamelen > (G_MAXUINT16 - 4) - 1) {
3135 * This won't fit in a maximum-sized record; discard it.
3138 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3141 namelen = (guint16)(hostnamelen + 1);
3142 nrb.record_len = 4 + namelen;
3143 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3145 if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE){
3146 /* We know the total length now; copy the block header. */
3147 memcpy(rec_data, &bh, sizeof(bh));
3150 memset(rec_data + rec_off, 0, 4);
3153 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
3155 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
3157 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
3161 wdh->bytes_dumped += bh.block_total_length;
3163 /*Start a new NRB */
3164 rec_off = 8; /* block type + block total length */
3165 bh.block_type = BLOCK_TYPE_NRB;
3166 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
3170 bh.block_total_length += tot_rec_len;
3171 memcpy(rec_data + rec_off, &nrb, sizeof(nrb));
3173 memcpy(rec_data + rec_off, &(ipv4_hash_list_entry->addr), 4);
3175 memcpy(rec_data + rec_off, ipv4_hash_list_entry->name, namelen);
3177 memset(rec_data + rec_off, 0, PADDING4(namelen));
3178 rec_off += PADDING4(namelen);
3179 pcapng_debug("NRB: added IPv4 record for %s", ipv4_hash_list_entry->name);
3182 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3184 g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
3185 wdh->addrinfo_lists->ipv4_addr_list = NULL;
3188 if (wdh->addrinfo_lists->ipv6_addr_list){
3190 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3191 while(ipv6_hash_list_entry != NULL){
3193 nrb.record_type = NRES_IP6RECORD;
3194 hostnamelen = strlen(ipv6_hash_list_entry->name);
3195 if (hostnamelen > (G_MAXUINT16 - 16) - 1) {
3197 * This won't fit in a maximum-sized record; discard it.
3200 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3203 namelen = (guint16)(hostnamelen + 1);
3204 nrb.record_len = 16 + namelen; /* 16 bytes IPv6 address length */
3205 /* 2 bytes record type, 2 bytes length field */
3206 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3208 if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE){
3210 * This record would overflow our maximum size for Name
3211 * Resolution Blocks; write out all the records we created
3212 * before it, and start a new NRB.
3215 /* First, copy the block header. */
3216 memcpy(rec_data, &bh, sizeof(bh));
3219 memset(rec_data + rec_off, 0, 4);
3222 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
3224 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
3226 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
3230 wdh->bytes_dumped += bh.block_total_length;
3232 /*Start a new NRB */
3233 rec_off = 8; /* block type + block total length */
3234 bh.block_type = BLOCK_TYPE_NRB;
3235 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
3239 bh.block_total_length += tot_rec_len;
3240 memcpy(rec_data + rec_off, &nrb, sizeof(nrb));
3242 memcpy(rec_data + rec_off, &(ipv6_hash_list_entry->addr), 16);
3244 memcpy(rec_data + rec_off, ipv6_hash_list_entry->name, namelen);
3246 memset(rec_data + rec_off, 0, PADDING4(namelen));
3247 rec_off += PADDING4(namelen);
3248 pcapng_debug("NRB: added IPv6 record for %s", ipv6_hash_list_entry->name);
3251 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3253 g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
3254 wdh->addrinfo_lists->ipv6_addr_list = NULL;
3257 /* add options, if any */
3259 gboolean have_options = FALSE;
3260 guint32 options_total_length = 0;
3261 struct option option_hdr;
3262 guint32 comment_len = 0, comment_pad_len = 0;
3263 wtap_optionblock_t nrb_hdr = wdh->nrb_hdr;
3264 guint32 prev_rec_off = rec_off;
3267 /* get lengths first to make sure we can fit this into the block */
3268 wtap_optionblock_get_option_string(nrb_hdr, OPT_COMMENT, &opt_comment);
3270 have_options = TRUE;
3271 comment_len = (guint32)strlen(opt_comment) & 0xffff;
3272 if ((comment_len % 4)) {
3273 comment_pad_len = 4 - (comment_len % 4);
3275 comment_pad_len = 0;
3277 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3281 /* End-of options tag */
3282 options_total_length += 4;
3284 if (rec_off + options_total_length > NRES_REC_MAX_SIZE) {
3286 * This record would overflow our maximum size for Name
3287 * Resolution Blocks; write out all the records we created
3288 * before it, and start a new NRB.
3291 /* First, copy the block header. */
3292 memcpy(rec_data, &bh, sizeof(bh));
3295 memset(rec_data + rec_off, 0, 4);
3298 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
3300 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
3302 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
3306 wdh->bytes_dumped += bh.block_total_length;
3308 /*Start a new NRB */
3309 prev_rec_off = rec_off = 8; /* block type + block total length */
3310 bh.block_type = BLOCK_TYPE_NRB;
3311 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
3314 bh.block_total_length += options_total_length;
3316 if (comment_len > 0) {
3317 option_hdr.type = OPT_COMMENT;
3318 option_hdr.value_length = comment_len;
3320 memcpy(rec_data + rec_off, &option_hdr, sizeof(option_hdr));
3321 rec_off += (guint32)sizeof(option_hdr);
3323 /* Write the comments string */
3324 memcpy(rec_data + rec_off, opt_comment, comment_len);
3325 rec_off += comment_len;
3326 memset(rec_data + rec_off, 0, comment_pad_len);
3327 rec_off += comment_pad_len;
3329 pcapng_debug("pcapng_write_name_resolution_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
3334 /* Write end of options */
3335 memset(rec_data + rec_off, 0, 4);
3339 g_assert(options_total_length == rec_off - prev_rec_off);
3343 /* We know the total length now; copy the block header. */
3344 memcpy(rec_data, &bh, sizeof(bh));
3347 memset(rec_data + rec_off, 0, 4);
3350 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
3352 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
3354 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
3360 wdh->bytes_dumped += bh.block_total_length;
3364 static void compute_isb_option_size(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data)
3366 pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data;
3372 if (option != NULL) {
3373 size = pcapng_compute_option_string_size(option->stringval);
3376 case OPT_ISB_STARTTIME:
3377 case OPT_ISB_ENDTIME:
3378 if ((option != NULL) && (option->uint64val != 0)) {
3382 case OPT_ISB_IFRECV:
3383 case OPT_ISB_IFDROP:
3384 case OPT_ISB_FILTERACCEPT:
3385 case OPT_ISB_OSDROP:
3386 case OPT_ISB_USRDELIV:
3387 if ((option != NULL) && (option->uint64val != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))) {
3392 /* Unknown options - size by datatype? */
3396 block_size->size += size;
3397 /* Add bytes for option header if option should be written */
3399 /* Add optional padding to 32 bits */
3400 if ((block_size->size & 0x03) != 0)
3402 block_size->size += 4 - (block_size->size & 0x03);
3404 block_size->size += 4;
3408 static void write_wtap_isb_block(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data)
3410 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
3411 struct pcapng_option_header option_hdr;
3413 /* Don't continue if there has been an error */
3414 if (!write_block->success)
3420 if ((option != NULL) && (option->stringval != NULL)) {
3421 if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) {
3422 write_block->success = FALSE;
3427 case OPT_ISB_STARTTIME:
3428 case OPT_ISB_ENDTIME:
3429 if ((option != NULL) && (option->uint64val != 0)) {
3432 option_hdr.type = option_id;
3433 option_hdr.value_length = 8;
3434 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3435 write_block->success = FALSE;
3438 write_block->wdh->bytes_dumped += 4;
3440 high = (guint32)(option->uint64val >> 32);
3441 low = (guint32)(option->uint64val >> 0);
3442 if (!wtap_dump_file_write(write_block->wdh, &high, sizeof(guint32), write_block->err)) {
3443 write_block->success = FALSE;
3446 write_block->wdh->bytes_dumped += 4;
3447 if (!wtap_dump_file_write(write_block->wdh, &low, sizeof(guint32), write_block->err)) {
3448 write_block->success = FALSE;
3451 write_block->wdh->bytes_dumped += 4;
3454 case OPT_ISB_IFRECV:
3455 case OPT_ISB_IFDROP:
3456 case OPT_ISB_FILTERACCEPT:
3457 case OPT_ISB_OSDROP:
3458 case OPT_ISB_USRDELIV:
3459 if ((option != NULL) && (option->uint64val != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))) {
3460 option_hdr.type = option_id;
3461 option_hdr.value_length = 8;
3462 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3463 write_block->success = FALSE;
3466 write_block->wdh->bytes_dumped += 4;
3468 if (!wtap_dump_file_write(write_block->wdh, &option->uint64val, sizeof(guint64), write_block->err)) {
3469 write_block->success = FALSE;
3472 write_block->wdh->bytes_dumped += 8;
3476 /* Unknown options - write by datatype? */
3482 pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_optionblock_t if_stats, int *err)
3484 pcapng_block_header_t bh;
3485 pcapng_interface_statistics_block_t isb;
3486 pcapng_optionblock_size_t block_size;
3487 pcapng_write_block_t block_data;
3488 struct pcapng_option_header option_hdr;
3489 wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats);
3491 pcapng_debug("pcapng_write_interface_statistics_block");
3493 /* Compute block size */
3494 block_size.size = 0;
3495 wtap_optionblock_foreach_option(if_stats, compute_isb_option_size, &block_size);
3497 if (block_size.size > 0) {
3498 /* End-of-options tag */
3499 block_size.size += 4;
3502 /* write block header */
3503 bh.block_type = BLOCK_TYPE_ISB;
3504 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(isb) + block_size.size + 4);
3505 pcapng_debug("pcapng_write_interface_statistics_block: Total len %u", bh.block_total_length);
3507 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3509 wdh->bytes_dumped += sizeof bh;
3511 /* write block fixed content */
3512 isb.interface_id = mand_data->interface_id;
3513 isb.timestamp_high = mand_data->ts_high;
3514 isb.timestamp_low = mand_data->ts_low;
3516 if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
3518 wdh->bytes_dumped += sizeof isb;
3521 if (block_size.size > 0) {
3522 block_data.wdh = wdh;
3523 block_data.err = err;
3524 block_data.success = TRUE;
3525 wtap_optionblock_foreach_option(if_stats, write_wtap_isb_block, &block_data);
3527 if (!block_data.success)
3530 /* Write end of options */
3531 option_hdr.type = OPT_EOFOPT;
3532 option_hdr.value_length = 0;
3533 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3535 wdh->bytes_dumped += 4;
3538 /* write block footer */
3539 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3540 sizeof bh.block_total_length, err))
3542 wdh->bytes_dumped += sizeof bh.block_total_length;
3546 static void compute_idb_option_size(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data)
3548 pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data;
3557 if (option != NULL) {
3558 size = pcapng_compute_option_string_size(option->stringval);
3562 if ((option != NULL) && (option->uint64val != 0)) {
3566 case OPT_IDB_TSRESOL:
3567 if ((option != NULL) && (option->uint8val != 0)) {
3571 case OPT_IDB_FILTER:
3572 if (option != NULL) {
3573 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)option->customval.data;
3575 if ((filter != NULL) && (filter->if_filter_str != NULL)) {
3576 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
3578 pad = 4 - (size % 4);
3587 case OPT_IDB_FCSLEN:
3588 /* XXX - Not currently writing value */
3591 /* Unknown options - size by datatype? */
3595 block_size->size += size;
3596 /* Add bytes for option header if option should be written */
3598 /* Add optional padding to 32 bits */
3599 if ((block_size->size & 0x03) != 0)
3601 block_size->size += 4 - (block_size->size & 0x03);
3603 block_size->size += 4;
3607 static void write_wtap_idb_block(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data)
3609 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
3610 struct pcapng_option_header option_hdr;
3611 const guint32 zero_pad = 0;
3619 if ((option != NULL) && (option->stringval != NULL)) {
3620 if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) {
3621 write_block->success = FALSE;
3627 if ((option != NULL) && (option->uint64val != 0)) {
3628 option_hdr.type = option_id;
3629 option_hdr.value_length = 8;
3630 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3631 write_block->success = FALSE;
3634 write_block->wdh->bytes_dumped += 4;
3636 if (!wtap_dump_file_write(write_block->wdh, &option->uint64val, sizeof(guint64), write_block->err)) {
3637 write_block->success = FALSE;
3640 write_block->wdh->bytes_dumped += 8;
3643 case OPT_IDB_TSRESOL:
3644 if ((option != NULL) && (option->uint8val != 0)) {
3645 option_hdr.type = option_id;
3646 option_hdr.value_length = 1;
3647 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3648 write_block->success = FALSE;
3651 write_block->wdh->bytes_dumped += 4;
3653 if (!wtap_dump_file_write(write_block->wdh, &option->uint8val, 1, write_block->err)) {
3654 write_block->success = FALSE;
3657 write_block->wdh->bytes_dumped += 1;
3659 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 3, write_block->err)) {
3660 write_block->success = FALSE;
3663 write_block->wdh->bytes_dumped += 3;
3666 case OPT_IDB_FILTER:
3667 if (option != NULL) {
3668 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)option->customval.data;
3670 if ((filter != NULL) && (filter->if_filter_str != NULL)) {
3671 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
3673 pad = 4 - (size % 4);
3678 option_hdr.type = option_id;
3679 option_hdr.value_length = size;
3680 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3681 write_block->success = FALSE;
3684 write_block->wdh->bytes_dumped += 4;
3686 /* Write the zero indicating libpcap filter variant */
3687 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 1, write_block->err)) {
3688 write_block->success = FALSE;
3691 write_block->wdh->bytes_dumped += 1;
3693 /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
3694 if (!wtap_dump_file_write(write_block->wdh, filter->if_filter_str, size-1, write_block->err)) {
3695 write_block->success = FALSE;
3698 write_block->wdh->bytes_dumped += size - 1;
3700 /* write padding (if any) */
3702 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, pad, write_block->err)) {
3703 write_block->success = FALSE;
3706 write_block->wdh->bytes_dumped += pad;
3712 case OPT_IDB_FCSLEN:
3713 /* XXX - Not currently writing value */
3716 /* Unknown options - size by datatype? */
3722 pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_optionblock_t int_data, int *err)
3724 pcapng_block_header_t bh;
3725 pcapng_interface_description_block_t idb;
3726 pcapng_optionblock_size_t block_size;
3727 pcapng_write_block_t block_data;
3728 struct pcapng_option_header option_hdr;
3729 wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
3731 pcapng_debug("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d",
3732 mand_data->link_type,
3733 wtap_encap_string(wtap_pcap_encap_to_wtap_encap(mand_data->link_type)),
3734 mand_data->snap_len);
3736 if (mand_data->link_type == (guint16)-1) {
3737 *err = WTAP_ERR_UNWRITABLE_ENCAP;
3741 /* Compute block size */
3742 block_size.size = 0;
3743 wtap_optionblock_foreach_option(int_data, compute_idb_option_size, &block_size);
3745 if (block_size.size > 0) {
3746 /* End-of-options tag */
3747 block_size.size += 4;
3750 /* write block header */
3751 bh.block_type = BLOCK_TYPE_IDB;
3752 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + block_size.size + 4);
3753 pcapng_debug("pcapng_write_if_descr_block: Total len %u", bh.block_total_length);
3755 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3757 wdh->bytes_dumped += sizeof bh;
3759 /* write block fixed content */
3760 idb.linktype = mand_data->link_type;
3762 idb.snaplen = mand_data->snap_len;
3764 if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
3766 wdh->bytes_dumped += sizeof idb;
3768 if (block_size.size > 0) {
3770 block_data.wdh = wdh;
3771 block_data.err = err;
3772 block_data.success = TRUE;
3773 wtap_optionblock_foreach_option(int_data, write_wtap_idb_block, &block_data);
3775 if (!block_data.success)
3778 /* Write end of options */
3779 option_hdr.type = OPT_EOFOPT;
3780 option_hdr.value_length = 0;
3781 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3783 wdh->bytes_dumped += 4;
3786 /* write block footer */
3787 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3788 sizeof bh.block_total_length, err))
3791 wdh->bytes_dumped += sizeof bh.block_total_length;
3795 static gboolean pcapng_dump(wtap_dumper *wdh,
3796 const struct wtap_pkthdr *phdr,
3797 const guint8 *pd, int *err, gchar **err_info _U_)
3799 const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
3801 block_handler *handler;
3804 pcapng_debug("pcapng_dump: encap = %d (%s)",
3806 wtap_encap_string(phdr->pkt_encap));
3808 switch (phdr->rec_type) {
3810 case REC_TYPE_PACKET:
3811 if (!pcapng_write_enhanced_packet_block(wdh, phdr, pseudo_header, pd, err)) {
3816 case REC_TYPE_FT_SPECIFIC_EVENT:
3817 case REC_TYPE_FT_SPECIFIC_REPORT:
3820 * Do we have a handler for this block type?
3822 if (block_handlers != NULL &&
3823 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
3824 GUINT_TO_POINTER(pseudo_header->ftsrec.record_type))) != NULL) {
3825 /* Yes. Call it to write out this record. */
3826 if (!handler->writer(wdh, phdr, pd, err))
3832 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
3838 /* We don't support writing this record type. */
3839 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
3847 /* Finish writing to a dump file.
3848 Returns TRUE on success, FALSE on failure. */
3849 static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err)
3853 /* Flush any hostname resolution info we may have */
3854 pcapng_write_name_resolution_block(wdh, err);
3856 for (i = 0; i < wdh->interface_data->len; i++) {
3858 /* Get the interface description */
3859 wtap_optionblock_t int_data;
3860 wtapng_if_descr_mandatory_t *int_data_mand;
3862 int_data = g_array_index(wdh->interface_data, wtap_optionblock_t, i);
3863 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
3865 for (j = 0; j < int_data_mand->num_stat_entries; j++) {
3866 wtap_optionblock_t if_stats;
3868 if_stats = g_array_index(int_data_mand->interface_statistics, wtap_optionblock_t, j);
3869 pcapng_debug("pcapng_dump_finish: write ISB for interface %u", ((wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats))->interface_id);
3870 if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) {
3876 pcapng_debug("pcapng_dump_finish");
3881 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
3884 pcapng_dump_open(wtap_dumper *wdh, int *err)
3888 pcapng_debug("pcapng_dump_open");
3889 /* This is a pcapng file */
3890 wdh->subtype_write = pcapng_dump;
3891 wdh->subtype_finish = pcapng_dump_finish;
3893 if (wdh->interface_data->len == 0) {
3894 pcapng_debug("There are no interfaces. Can't handle that...");
3895 *err = WTAP_ERR_INTERNAL;
3899 /* write the section header block */
3900 if (!pcapng_write_section_header_block(wdh, err)) {
3903 pcapng_debug("pcapng_dump_open: wrote section header block.");
3905 /* Write the Interface description blocks */
3906 pcapng_debug("pcapng_dump_open: Number of IDB:s to write (number of interfaces) %u",
3907 wdh->interface_data->len);
3909 for (i = 0; i < wdh->interface_data->len; i++) {
3911 /* Get the interface description */
3912 wtap_optionblock_t idb;
3914 idb = g_array_index(wdh->interface_data, wtap_optionblock_t, i);
3916 if (!pcapng_write_if_descr_block(wdh, idb, err)) {
3926 /* Returns 0 if we could write the specified encapsulation type,
3927 an error indication otherwise. */
3928 int pcapng_dump_can_write_encap(int wtap_encap)
3930 pcapng_debug("pcapng_dump_can_write_encap: encap = %d (%s)",
3932 wtap_encap_string(wtap_encap));
3934 /* Per-packet encapsulation is supported. */
3935 if (wtap_encap == WTAP_ENCAP_PER_PACKET)
3938 /* Make sure we can figure out this DLT type */
3939 if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
3940 return WTAP_ERR_UNWRITABLE_ENCAP;
3946 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3951 * indent-tabs-mode: nil
3954 * vi: set shiftwidth=4 tabstop=8 expandtab:
3955 * :indentSize=4:tabSize=8:noTabs=true: