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 SYSDIG_EVENT_HEADER_SIZE ((16 + 64 + 64 + 32 + 16)/8) /* CPU ID + TS + TID + Event len + Event type */
150 #define MIN_SYSDIG_EVENT_SIZE ((guint32)(MIN_BLOCK_SIZE + SYSDIG_EVENT_HEADER_SIZE))
152 /* pcapng: common option header file encoding for every option type */
153 typedef struct pcapng_option_header_s {
155 guint16 option_length;
156 /* ... x bytes Option Body ... */
157 /* ... Padding ... */
158 } pcapng_option_header_t;
162 guint16 value_length;
165 /* Option codes: 16-bit field */
166 #define OPT_EPB_FLAGS 0x0002
167 #define OPT_EPB_HASH 0x0003
168 #define OPT_EPB_DROPCOUNT 0x0004
170 #define OPT_NRB_DNSNAME 0x0002
171 #define OPT_NRB_DNSV4ADDR 0x0003
172 #define OPT_NRB_DNSV6ADDR 0x0004
174 /* MSBit of option code means "local type" */
175 #define OPT_LOCAL_FLAG 0x8000
177 /* Note: many of the defined structures for block data are defined in wtap.h */
179 /* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
180 typedef struct wtapng_packet_s {
182 guint32 ts_high; /* seconds since 1.1.1970 */
183 guint32 ts_low; /* fraction of seconds, depends on if_tsresol */
184 guint32 cap_len; /* data length in the file */
185 guint32 packet_len; /* data length on the wire */
186 guint32 interface_id; /* identifier of the interface. */
187 guint16 drops_count; /* drops count, only valid for packet block */
188 /* 0xffff if information no available */
190 /* XXX - put the packet data / pseudo_header here as well? */
193 /* Simple Packet data */
194 typedef struct wtapng_simple_packet_s {
196 guint32 cap_len; /* data length in the file */
197 guint32 packet_len; /* data length on the wire */
198 /* XXX - put the packet data / pseudo_header here as well? */
199 } wtapng_simple_packet_t;
201 /* Block data to be passed between functions during reading */
202 typedef struct wtapng_block_s {
203 guint32 type; /* block_type as defined by pcapng */
204 wtap_optionblock_t block;
207 * XXX - currently don't know how to handle these!
209 * For one thing, when we're reading a block, they must be
210 * writable, i.e. not const, so that we can read into them,
211 * but, when we're writing a block, they can be const, and,
212 * in fact, they sometimes point to const values.
214 struct wtap_pkthdr *packet_header;
215 Buffer *frame_buffer;
218 /* Interface data in private struct */
219 typedef struct interface_info_s {
222 guint64 time_units_per_second;
227 gboolean shb_read; /**< Set when first SHB read */
228 gboolean byte_swapped;
229 guint16 version_major;
230 guint16 version_minor;
231 GArray *interfaces; /**< Interfaces found in the capture file. */
233 wtap_new_ipv4_callback_t add_new_ipv4;
234 wtap_new_ipv6_callback_t add_new_ipv6;
239 * Table for plugins to handle particular block types.
241 * A handler has a "read" routine and a "write" routine.
243 * A "read" routine returns a block as a libwiretap record, filling
244 * in the wtap_pkthdr structure with the appropriate record type and
245 * other information, and filling in the supplied Buffer with
246 * data for which there's no place in the wtap_pkthdr structure.
248 * A "write" routine takes a libwiretap record and Buffer and writes
256 static GHashTable *block_handlers;
259 register_pcapng_block_type_handler(guint block_type, block_reader reader,
262 block_handler *handler;
264 if (block_handlers == NULL) {
266 * Create the table of block handlers.
268 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
269 * so we use "g_direct_hash()" and "g_direct_equal()".
271 block_handlers = g_hash_table_new_full(g_direct_hash,
275 handler = g_new(block_handler, 1);
276 handler->reader = reader;
277 handler->writer = writer;
278 g_hash_table_insert(block_handlers, GUINT_TO_POINTER(block_type),
283 * Tables for plugins to handle particular options for particular block
286 * An option has a handler routine, which is passed an indication of
287 * whether this section of the file is byte-swapped, the length of the
288 * option, the data of the option, a pointer to an error code, and a
289 * pointer to a pointer variable for an error string.
291 * It checks whether the length and option are valid, and, if they aren't,
292 * returns FALSE, setting the error code to the appropriate error (normally
293 * WTAP_ERR_BAD_FILE) and the error string to an appropriate string
294 * indicating the problem.
296 * Otherwise, if this section of the file is byte-swapped, it byte-swaps
297 * multi-byte numerical values, so that it's in the host byte order.
301 * Block types indices in the table of tables of option handlers.
303 * Block types are not guaranteed to be sequential, so we map the
304 * block types we support to a sequential set. Furthermore, all
305 * packet block types have the same set of options.
307 #define BT_INDEX_SHB 0
308 #define BT_INDEX_IDB 1
309 #define BT_INDEX_PBS 2 /* all packet blocks */
310 #define BT_INDEX_NRB 3
311 #define BT_INDEX_ISB 4
312 #define BT_INDEX_EVT 5
314 #define NUM_BT_INDICES 6
317 option_handler_fn hfunc;
320 static GHashTable *option_handlers[NUM_BT_INDICES];
323 get_block_type_index(guint block_type, guint *bt_index)
327 switch (block_type) {
330 *bt_index = BT_INDEX_SHB;
334 *bt_index = BT_INDEX_IDB;
340 *bt_index = BT_INDEX_PBS;
344 *bt_index = BT_INDEX_NRB;
348 *bt_index = BT_INDEX_ISB;
351 case BLOCK_TYPE_SYSDIG_EVENT:
352 /* case BLOCK_TYPE_SYSDIG_EVF: */
353 *bt_index = BT_INDEX_EVT;
358 * This is a block type we don't process; either we ignore it,
359 * in which case the options don't get processed, or there's
360 * a plugin routine to handle it, in which case that routine
361 * will do the option processing itself.
363 * XXX - report an error?
372 register_pcapng_option_handler(guint block_type, guint option_code,
373 option_handler_fn hfunc)
376 option_handler *handler;
378 if (!get_block_type_index(block_type, &bt_index))
381 if (option_handlers[bt_index] == NULL) {
383 * Create the table of option handlers for this block type.
385 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
386 * so we use "g_direct_hash()" and "g_direct_equal()".
388 option_handlers[bt_index] = g_hash_table_new_full(g_direct_hash,
392 handler = g_new(option_handler, 1);
393 handler->hfunc = hfunc;
394 g_hash_table_insert(option_handlers[bt_index],
395 GUINT_TO_POINTER(option_code), handler);
397 #endif /* HAVE_PLUGINS */
400 pcapng_read_option(FILE_T fh, pcapng_t *pn, pcapng_option_header_t *oh,
401 guint8 *content, guint len, guint to_read,
402 int *err, gchar **err_info, gchar* block_name)
406 /* sanity check: don't run past the end of the block */
407 if (to_read < sizeof (*oh)) {
408 *err = WTAP_ERR_BAD_FILE;
409 *err_info = g_strdup_printf("pcapng_read_option: Not enough data to read header of the %s block",
414 /* read option header */
415 if (!wtap_read_bytes(fh, oh, sizeof (*oh), err, err_info)) {
416 pcapng_debug("pcapng_read_option: failed to read option");
419 block_read = sizeof (*oh);
420 if (pn->byte_swapped) {
421 oh->option_code = GUINT16_SWAP_LE_BE(oh->option_code);
422 oh->option_length = GUINT16_SWAP_LE_BE(oh->option_length);
425 /* sanity check: don't run past the end of the block */
426 if (to_read < sizeof (*oh) + oh->option_length) {
427 *err = WTAP_ERR_BAD_FILE;
428 *err_info = g_strdup_printf("pcapng_read_option: Not enough data to handle option length (%d) of the %s block",
429 oh->option_length, block_name);
433 /* sanity check: option length */
434 if (len < oh->option_length) {
435 *err = WTAP_ERR_BAD_FILE;
436 *err_info = g_strdup_printf("pcapng_read_option: option length (%d) to long for %s block",
441 /* read option content */
442 if (!wtap_read_bytes(fh, content, oh->option_length, err, err_info)) {
443 pcapng_debug("pcapng_read_option: failed to read content of option %u", oh->option_code);
446 block_read += oh->option_length;
448 /* jump over potential padding bytes at end of option */
449 if ( (oh->option_length % 4) != 0) {
450 if (!file_skip(fh, 4 - (oh->option_length % 4), err))
452 block_read += 4 - (oh->option_length % 4);
460 PCAPNG_BLOCK_NOT_SHB,
464 static block_return_val
465 pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
466 pcapng_t *pn, wtapng_block_t *wblock,
467 int *err, gchar **err_info)
470 gboolean byte_swapped;
471 guint16 version_major;
472 guint16 version_minor;
473 guint to_read, opt_cont_buf_len;
474 pcapng_section_header_block_t shb;
475 pcapng_option_header_t oh;
476 wtapng_mandatory_section_t* section_data;
479 guint8 *option_content = NULL; /* Allocate as large as the options block */
481 /* read fixed-length part of the block */
482 if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
483 if (*err == WTAP_ERR_SHORT_READ) {
485 * This block is too short to be an SHB.
487 * If we're reading this as part of an open,
488 * the file is too short to be a pcap-ng file.
490 * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
491 * PCAPNG_BLOCK_ERROR the same, so we can just return
492 * PCAPNG_BLOCK_NOT_SHB in both cases.
494 return PCAPNG_BLOCK_NOT_SHB;
496 return PCAPNG_BLOCK_ERROR;
499 /* is the magic number one we expect? */
502 /* this seems pcapng with correct byte order */
503 byte_swapped = FALSE;
504 version_major = shb.version_major;
505 version_minor = shb.version_minor;
507 pcapng_debug("pcapng_read_section_header_block: SHB (our byte order) V%u.%u, len %u",
508 version_major, version_minor, bh->block_total_length);
511 /* this seems pcapng with swapped byte order */
513 version_major = GUINT16_SWAP_LE_BE(shb.version_major);
514 version_minor = GUINT16_SWAP_LE_BE(shb.version_minor);
516 /* tweak the block length to meet current swapping that we know now */
517 bh->block_total_length = GUINT32_SWAP_LE_BE(bh->block_total_length);
519 pcapng_debug("pcapng_read_section_header_block: SHB (byte-swapped) V%u.%u, len %u",
520 version_major, version_minor, bh->block_total_length);
523 /* Not a "pcapng" magic number we know about. */
524 *err = WTAP_ERR_BAD_FILE;
525 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown byte-order magic number 0x%08x", shb.magic);
528 * See above comment about PCAPNG_BLOCK_NOT_SHB.
530 return PCAPNG_BLOCK_NOT_SHB;
534 * Is this block long enough to be an SHB?
536 if (bh->block_total_length < MIN_SHB_SIZE) {
540 *err = WTAP_ERR_BAD_FILE;
541 *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",
542 bh->block_total_length, MIN_SHB_SIZE);
543 return PCAPNG_BLOCK_ERROR;
546 /* OK, at this point we assume it's a pcap-ng file.
548 Don't try to allocate memory for a huge number of options, as
549 that might fail and, even if it succeeds, it might not leave
550 any address space or memory+backing store for anything else.
552 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
553 We check for this *after* checking the SHB for its byte
554 order magic number, so that non-pcap-ng files are less
555 likely to be treated as bad pcap-ng files. */
556 if (bh->block_total_length > MAX_BLOCK_SIZE) {
557 *err = WTAP_ERR_BAD_FILE;
558 *err_info = g_strdup_printf("pcapng_read_section_header_block: total block length %u is too large (> %u)",
559 bh->block_total_length, MAX_BLOCK_SIZE);
560 return PCAPNG_BLOCK_ERROR;
563 /* we currently only understand SHB V1.0 */
564 if (version_major != 1 || version_minor > 0) {
565 *err = WTAP_ERR_UNSUPPORTED;
566 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown SHB version %u.%u",
567 pn->version_major, pn->version_minor);
568 return PCAPNG_BLOCK_ERROR;
571 pn->byte_swapped = byte_swapped;
572 pn->version_major = version_major;
573 pn->version_minor = version_minor;
575 wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
576 section_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(wblock->block);
577 /* 64bit section_length (currently unused) */
578 if (pn->byte_swapped) {
579 section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length);
581 section_data->section_length = shb.section_length;
585 to_read = bh->block_total_length - MIN_SHB_SIZE;
587 /* Allocate enough memory to hold all options */
588 opt_cont_buf_len = to_read;
589 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
590 if (opt_cont_buf_len != 0 && option_content == NULL) {
591 *err = ENOMEM; /* we assume we're out of memory */
592 return PCAPNG_BLOCK_ERROR;
594 pcapng_debug("pcapng_read_section_header_block: Options %u bytes", to_read);
595 while (to_read != 0) {
597 pcapng_debug("pcapng_read_section_header_block: Options %u bytes remaining", to_read);
598 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "section_header");
599 if (bytes_read <= 0) {
600 pcapng_debug("pcapng_read_section_header_block: failed to read option");
601 return PCAPNG_BLOCK_ERROR;
603 to_read -= bytes_read;
605 /* handle option content */
606 switch (oh.option_code) {
609 pcapng_debug("pcapng_read_section_header_block: %u bytes after opt_endofopt", to_read);
611 /* padding should be ok here, just get out of this */
615 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
616 tmp_content = g_strndup((char *)option_content, oh.option_length);
617 wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length);
618 pcapng_debug("pcapng_read_section_header_block: opt_comment %s", tmp_content);
621 pcapng_debug("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
624 case(OPT_SHB_HARDWARE):
625 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
626 tmp_content = g_strndup((char *)option_content, oh.option_length);
627 wtap_optionblock_set_option_string(wblock->block, OPT_SHB_HARDWARE, option_content, oh.option_length);
628 pcapng_debug("pcapng_read_section_header_block: shb_hardware %s", tmp_content);
631 pcapng_debug("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
635 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
636 tmp_content = g_strndup((char *)option_content, oh.option_length);
637 wtap_optionblock_set_option_string(wblock->block, OPT_SHB_OS, option_content, oh.option_length);
638 pcapng_debug("pcapng_read_section_header_block: shb_os %s", tmp_content);
641 pcapng_debug("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
644 case(OPT_SHB_USERAPPL):
645 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
646 tmp_content = g_strndup((char *)option_content, oh.option_length);
647 wtap_optionblock_set_option_string(wblock->block, OPT_SHB_USERAPPL, option_content, oh.option_length);
648 pcapng_debug("pcapng_read_section_header_block: shb_user_appl %s", tmp_content);
651 pcapng_debug("pcapng_read_section_header_block: shb_user_appl length %u seems strange", oh.option_length);
655 pcapng_debug("pcapng_read_section_header_block: unknown option %u - ignoring %u bytes",
656 oh.option_code, oh.option_length);
659 g_free(option_content);
661 return PCAPNG_BLOCK_OK;
665 /* "Interface Description Block" */
667 pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
668 pcapng_t *pn, wtapng_block_t *wblock, int *err,
671 guint64 time_units_per_second = 1000000; /* default = 10^6 */
672 int tsprecision = WTAP_TSPREC_USEC;
674 guint to_read, opt_cont_buf_len;
675 pcapng_interface_description_block_t idb;
676 wtapng_if_descr_mandatory_t* if_descr_mand;
677 pcapng_option_header_t oh;
678 guint8 *option_content = NULL; /* Allocate as large as the options block */
683 * Is this block long enough to be an IDB?
685 if (bh->block_total_length < MIN_IDB_SIZE) {
689 *err = WTAP_ERR_BAD_FILE;
690 *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",
691 bh->block_total_length, MIN_IDB_SIZE);
695 /* Don't try to allocate memory for a huge number of options, as
696 that might fail and, even if it succeeds, it might not leave
697 any address space or memory+backing store for anything else.
699 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
700 We check for this *after* checking the SHB for its byte
701 order magic number, so that non-pcap-ng files are less
702 likely to be treated as bad pcap-ng files. */
703 if (bh->block_total_length > MAX_BLOCK_SIZE) {
704 *err = WTAP_ERR_BAD_FILE;
705 *err_info = g_strdup_printf("pcapng_read_if_descr_block: total block length %u is too large (> %u)",
706 bh->block_total_length, MAX_BLOCK_SIZE);
710 /* read block content */
711 if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
712 pcapng_debug("pcapng_read_if_descr_block: failed to read IDB");
716 /* mandatory values */
717 wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
718 if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
719 if (pn->byte_swapped) {
720 if_descr_mand->link_type = GUINT16_SWAP_LE_BE(idb.linktype);
721 if_descr_mand->snap_len = GUINT32_SWAP_LE_BE(idb.snaplen);
723 if_descr_mand->link_type = idb.linktype;
724 if_descr_mand->snap_len = idb.snaplen;
727 if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(if_descr_mand->link_type);
728 if_descr_mand->time_units_per_second = time_units_per_second;
729 if_descr_mand->tsprecision = tsprecision;
731 pcapng_debug("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u",
732 if_descr_mand->link_type,
733 wtap_encap_string(if_descr_mand->wtap_encap),
734 if_descr_mand->snap_len);
736 if (if_descr_mand->snap_len > WTAP_MAX_PACKET_SIZE) {
737 /* This is unrealistic, but text2pcap currently uses 102400.
738 * We do not use this value, maybe we should check the
739 * snap_len of the packets against it. For now, only warn.
741 pcapng_debug("pcapng_read_if_descr_block: snapshot length %u unrealistic.",
742 if_descr_mand->snap_len);
743 /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE;*/
747 to_read = bh->block_total_length - MIN_IDB_SIZE;
749 /* Allocate enough memory to hold all options */
750 opt_cont_buf_len = to_read;
751 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
752 if (opt_cont_buf_len != 0 && option_content == NULL) {
753 *err = ENOMEM; /* we assume we're out of memory */
757 while (to_read != 0) {
759 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "if_descr");
760 if (bytes_read <= 0) {
761 pcapng_debug("pcapng_read_if_descr_block: failed to read option");
764 to_read -= bytes_read;
766 /* handle option content */
767 switch (oh.option_code) {
768 case(OPT_EOFOPT): /* opt_endofopt */
770 pcapng_debug("pcapng_read_if_descr_block: %u bytes after opt_endofopt", to_read);
772 /* padding should be ok here, just get out of this */
775 case(OPT_COMMENT): /* opt_comment */
776 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
777 tmp_content = g_strndup((char *)option_content, oh.option_length);
778 wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length);
779 pcapng_debug("pcapng_read_if_descr_block: opt_comment %s", tmp_content);
782 pcapng_debug("pcapng_read_if_descr_block: opt_comment length %u seems strange", oh.option_length);
785 case(OPT_IDB_NAME): /* if_name */
786 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
787 tmp_content = g_strndup((char *)option_content, oh.option_length);
788 wtap_optionblock_set_option_string(wblock->block, OPT_IDB_NAME, option_content, oh.option_length);
789 pcapng_debug("pcapng_read_if_descr_block: if_name %s", tmp_content);
792 pcapng_debug("pcapng_read_if_descr_block: if_name length %u seems strange", oh.option_length);
795 case(OPT_IDB_DESCR): /* if_description */
796 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
797 tmp_content = g_strndup((char *)option_content, oh.option_length);
798 wtap_optionblock_set_option_string(wblock->block, OPT_IDB_DESCR, option_content, oh.option_length);
799 pcapng_debug("pcapng_read_if_descr_block: if_description %s", tmp_content);
802 pcapng_debug("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
805 case(OPT_IDB_SPEED): /* if_speed */
806 if (oh.option_length == 8) {
807 /* Don't cast a guint8 * into a guint64 *--the
808 * guint8 * may not point to something that's
811 memcpy(&tmp64, option_content, sizeof(guint64));
812 if (pn->byte_swapped)
813 tmp64 = GUINT64_SWAP_LE_BE(tmp64);
814 wtap_optionblock_set_option_uint64(wblock->block, OPT_IDB_SPEED, tmp64);
815 pcapng_debug("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", tmp64);
817 pcapng_debug("pcapng_read_if_descr_block: if_speed length %u not 8 as expected", oh.option_length);
820 case(OPT_IDB_TSRESOL): /* if_tsresol */
821 if (oh.option_length == 1) {
824 guint8 i, exponent, if_tsresol;
826 if_tsresol = option_content[0];
827 if (if_tsresol & 0x80) {
832 exponent = (guint8)(if_tsresol & 0x7f);
833 if (((base == 2) && (exponent < 64)) || ((base == 10) && (exponent < 20))) {
835 for (i = 0; i < exponent; i++) {
838 time_units_per_second = result;
840 time_units_per_second = G_MAXUINT64;
842 if (time_units_per_second > (((guint64)1) << 32)) {
843 pcapng_debug("pcapng_open: time conversion might be inaccurate");
845 if_descr_mand->time_units_per_second = time_units_per_second;
846 wtap_optionblock_set_option_uint8(wblock->block, OPT_IDB_TSRESOL, if_tsresol);
847 if (time_units_per_second >= 1000000000)
848 tsprecision = WTAP_TSPREC_NSEC;
849 else if (time_units_per_second >= 1000000)
850 tsprecision = WTAP_TSPREC_USEC;
851 else if (time_units_per_second >= 1000)
852 tsprecision = WTAP_TSPREC_MSEC;
853 else if (time_units_per_second >= 100)
854 tsprecision = WTAP_TSPREC_CSEC;
855 else if (time_units_per_second >= 10)
856 tsprecision = WTAP_TSPREC_DSEC;
858 tsprecision = WTAP_TSPREC_SEC;
859 if_descr_mand->tsprecision = tsprecision;
860 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);
862 pcapng_debug("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length);
866 * if_tzone 10 Time zone for GMT support (TODO: specify better). TODO: give a good example
868 case(OPT_IDB_FILTER): /* if_filter */
869 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
870 wtapng_if_descr_filter_t if_filter;
871 memset(&if_filter, 0, sizeof(if_filter));
873 /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
876 if (option_content[0] == 0) {
877 if_filter.if_filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
878 pcapng_debug("pcapng_read_if_descr_block: if_filter_str %s oh.option_length %u", if_filter.if_filter_str, oh.option_length);
879 } else if (option_content[0] == 1) {
880 if_filter.bpf_filter_len = oh.option_length-1;
881 if_filter.if_filter_bpf_bytes = (gchar *)g_malloc(oh.option_length-1);
882 memcpy(if_filter.if_filter_bpf_bytes, (char *)option_content+1, oh.option_length-1);
884 wtap_optionblock_set_option_custom(wblock->block, OPT_IDB_FILTER, &if_filter);
886 pcapng_debug("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
889 case(OPT_IDB_OS): /* if_os */
891 * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
892 * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
893 * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
895 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
896 tmp_content = g_strndup((char *)option_content, oh.option_length);
897 wtap_optionblock_set_option_string(wblock->block, OPT_IDB_OS, option_content, oh.option_length);
898 pcapng_debug("pcapng_read_if_descr_block: if_os %s", tmp_content);
901 pcapng_debug("pcapng_read_if_descr_block: if_os length %u seems strange", oh.option_length);
904 case(OPT_IDB_FCSLEN): /* if_fcslen */
905 if (oh.option_length == 1) {
906 wtap_optionblock_set_option_uint8(wblock->block, OPT_IDB_TSRESOL, option_content[0]);
907 pn->if_fcslen = option_content[0];
908 pcapng_debug("pcapng_read_if_descr_block: if_fcslen %u", pn->if_fcslen);
909 /* XXX - add sanity check */
911 pcapng_debug("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
915 /* TODO: process these! */
916 case(OPT_IDB_IP4ADDR):
918 * Interface network address and netmask. This option can be
919 * repeated multiple times within the same Interface
920 * Description Block when multiple IPv4 addresses are assigned
921 * to the interface. 192 168 1 1 255 255 255 0
923 case(OPT_IDB_IP6ADDR):
925 * Interface network address and prefix length (stored in the
926 * last byte). This option can be repeated multiple times
927 * within the same Interface Description Block when multiple
928 * IPv6 addresses are assigned to the interface.
929 * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
930 * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
933 case(OPT_IDB_MACADDR):
935 * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
937 case(OPT_IDB_EUIADDR):
939 * Interface Hardware EUI address (64 bits), if available.
940 * TODO: give a good example
944 * Time zone for GMT support. TODO: specify better.
945 * TODO: give a good example.
947 case(OPT_IDB_TSOFFSET):
949 * A 64 bits integer value that specifies an offset (in
950 * seconds) that must be added to the timestamp of each packet
951 * to obtain the absolute timestamp of a packet. If the option
952 * is missing, the timestamps stored in the packet must be
953 * considered absolute timestamps. The time zone of the offset
954 * can be specified with the option if_tzone.
956 * TODO: won't a if_tsoffset_low for fractional second offsets
957 * be useful for highly synchronized capture systems? 1234
960 pcapng_debug("pcapng_read_if_descr_block: unknown option %u - ignoring %u bytes",
961 oh.option_code, oh.option_length);
965 g_free(option_content);
968 * If the per-file encapsulation isn't known, set it to this
969 * interface's encapsulation.
971 * If it *is* known, and it isn't this interface's encapsulation,
972 * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
973 * have a single encapsulation for all interfaces in the file,
974 * so it probably doesn't have a single encapsulation for all
975 * packets in the file.
977 if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
978 wth->file_encap = if_descr_mand->wtap_encap;
980 if (wth->file_encap != if_descr_mand->wtap_encap) {
981 wth->file_encap = WTAP_ENCAP_PER_PACKET;
986 * The same applies to the per-file time stamp resolution.
988 if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
989 wth->file_tsprec = if_descr_mand->tsprecision;
991 if (wth->file_tsprec != if_descr_mand->tsprecision) {
992 wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
1001 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)
1005 guint to_read, opt_cont_buf_len;
1006 pcapng_enhanced_packet_block_t epb;
1007 pcapng_packet_block_t pb;
1008 wtapng_packet_t packet;
1009 guint32 block_total_length;
1011 interface_info_t iface_info;
1014 pcapng_option_header_t *oh;
1015 guint8 *option_content;
1016 int pseudo_header_len;
1019 option_handler *handler;
1022 /* Don't try to allocate memory for a huge number of options, as
1023 that might fail and, even if it succeeds, it might not leave
1024 any address space or memory+backing store for anything else.
1026 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1027 We check for this *after* checking the SHB for its byte
1028 order magic number, so that non-pcap-ng files are less
1029 likely to be treated as bad pcap-ng files. */
1030 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1031 *err = WTAP_ERR_BAD_FILE;
1032 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u is too large (> %u)",
1033 bh->block_total_length, MAX_BLOCK_SIZE);
1037 /* "(Enhanced) Packet Block" read fixed part */
1040 * Is this block long enough to be an EPB?
1042 if (bh->block_total_length < MIN_EPB_SIZE) {
1046 *err = WTAP_ERR_BAD_FILE;
1047 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of an EPB is less than the minimum EPB size %u",
1048 bh->block_total_length, MIN_EPB_SIZE);
1051 if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
1052 pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1055 block_read = (guint)sizeof epb;
1057 if (pn->byte_swapped) {
1058 packet.interface_id = GUINT32_SWAP_LE_BE(epb.interface_id);
1059 packet.drops_count = -1; /* invalid */
1060 packet.ts_high = GUINT32_SWAP_LE_BE(epb.timestamp_high);
1061 packet.ts_low = GUINT32_SWAP_LE_BE(epb.timestamp_low);
1062 packet.cap_len = GUINT32_SWAP_LE_BE(epb.captured_len);
1063 packet.packet_len = GUINT32_SWAP_LE_BE(epb.packet_len);
1065 packet.interface_id = epb.interface_id;
1066 packet.drops_count = -1; /* invalid */
1067 packet.ts_high = epb.timestamp_high;
1068 packet.ts_low = epb.timestamp_low;
1069 packet.cap_len = epb.captured_len;
1070 packet.packet_len = epb.packet_len;
1072 pcapng_debug("pcapng_read_packet_block: EPB on interface_id %d, cap_len %d, packet_len %d",
1073 packet.interface_id, packet.cap_len, packet.packet_len);
1076 * Is this block long enough to be a PB?
1078 if (bh->block_total_length < MIN_PB_SIZE) {
1082 *err = WTAP_ERR_BAD_FILE;
1083 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of a PB is less than the minimum PB size %u",
1084 bh->block_total_length, MIN_PB_SIZE);
1087 if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
1088 pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1091 block_read = (guint)sizeof pb;
1093 if (pn->byte_swapped) {
1094 packet.interface_id = GUINT16_SWAP_LE_BE(pb.interface_id);
1095 packet.drops_count = GUINT16_SWAP_LE_BE(pb.drops_count);
1096 packet.ts_high = GUINT32_SWAP_LE_BE(pb.timestamp_high);
1097 packet.ts_low = GUINT32_SWAP_LE_BE(pb.timestamp_low);
1098 packet.cap_len = GUINT32_SWAP_LE_BE(pb.captured_len);
1099 packet.packet_len = GUINT32_SWAP_LE_BE(pb.packet_len);
1101 packet.interface_id = pb.interface_id;
1102 packet.drops_count = pb.drops_count;
1103 packet.ts_high = pb.timestamp_high;
1104 packet.ts_low = pb.timestamp_low;
1105 packet.cap_len = pb.captured_len;
1106 packet.packet_len = pb.packet_len;
1108 pcapng_debug("pcapng_read_packet_block: PB on interface_id %d, cap_len %d, packet_len %d",
1109 packet.interface_id, packet.cap_len, packet.packet_len);
1113 * How much padding is there at the end of the packet data?
1115 if ((packet.cap_len % 4) != 0)
1116 padding = 4 - (packet.cap_len % 4);
1120 /* add padding bytes to "block total length" */
1121 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1122 if (bh->block_total_length % 4) {
1123 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1125 block_total_length = bh->block_total_length;
1127 pcapng_debug("pcapng_read_packet_block: block_total_length %d", block_total_length);
1130 * Is this block long enough to hold the packet data?
1133 if (block_total_length <
1134 MIN_EPB_SIZE + packet.cap_len + padding) {
1138 *err = WTAP_ERR_BAD_FILE;
1139 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of EPB is too small for %u bytes of packet data",
1140 block_total_length, packet.cap_len);
1144 if (block_total_length <
1145 MIN_PB_SIZE + packet.cap_len + padding) {
1149 *err = WTAP_ERR_BAD_FILE;
1150 *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of PB is too small for %u bytes of packet data",
1151 block_total_length, packet.cap_len);
1156 if (packet.cap_len > WTAP_MAX_PACKET_SIZE) {
1157 *err = WTAP_ERR_BAD_FILE;
1158 *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u",
1159 packet.cap_len, WTAP_MAX_PACKET_SIZE);
1162 pcapng_debug("pcapng_read_packet_block: packet data: packet_len %u captured_len %u interface_id %u",
1165 packet.interface_id);
1167 if (packet.interface_id >= pn->interfaces->len) {
1168 *err = WTAP_ERR_BAD_FILE;
1169 *err_info = g_strdup_printf("pcapng_read_packet_block: interface index %u is not less than interface count %u",
1170 packet.interface_id, pn->interfaces->len);
1173 iface_info = g_array_index(pn->interfaces, interface_info_t,
1174 packet.interface_id);
1176 wblock->packet_header->rec_type = REC_TYPE_PACKET;
1177 wblock->packet_header->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1179 pcapng_debug("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.",
1180 iface_info.wtap_encap,
1181 wtap_encap_string(iface_info.wtap_encap),
1182 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header));
1183 wblock->packet_header->interface_id = packet.interface_id;
1184 wblock->packet_header->pkt_encap = iface_info.wtap_encap;
1185 wblock->packet_header->pkt_tsprec = iface_info.tsprecision;
1187 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1188 pseudo_header_len = pcap_process_pseudo_header(fh,
1189 WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1190 iface_info.wtap_encap,
1193 wblock->packet_header,
1196 if (pseudo_header_len < 0) {
1199 block_read += pseudo_header_len;
1200 if (pseudo_header_len != pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header)) {
1201 pcapng_debug("pcapng_read_packet_block: Could only read %d bytes for pseudo header.",
1204 wblock->packet_header->caplen = packet.cap_len - pseudo_header_len;
1205 wblock->packet_header->len = packet.packet_len - pseudo_header_len;
1207 /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
1208 ts = (((guint64)packet.ts_high) << 32) | ((guint64)packet.ts_low);
1209 wblock->packet_header->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
1210 wblock->packet_header->ts.nsecs = (int)(((ts % iface_info.time_units_per_second) * 1000000000) / iface_info.time_units_per_second);
1212 /* "(Enhanced) Packet Block" read capture data */
1213 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1214 packet.cap_len - pseudo_header_len, err, err_info))
1216 block_read += packet.cap_len - pseudo_header_len;
1218 /* jump over potential padding bytes at end of the packet data */
1220 if (!file_skip(fh, padding, err))
1222 block_read += padding;
1225 /* Option defaults */
1226 wblock->packet_header->opt_comment = NULL;
1227 wblock->packet_header->drop_count = -1;
1228 wblock->packet_header->pack_flags = 0;
1230 /* FCS length default */
1231 fcslen = pn->if_fcslen;
1239 to_read = block_total_length -
1240 (int)sizeof(pcapng_block_header_t) -
1241 block_read - /* fixed and variable part, including padding */
1242 (int)sizeof(bh->block_total_length);
1244 /* Allocate enough memory to hold all options */
1245 opt_cont_buf_len = to_read;
1246 ws_buffer_assure_space(&wblock->packet_header->ft_specific_data, opt_cont_buf_len);
1247 opt_ptr = ws_buffer_start_ptr(&wblock->packet_header->ft_specific_data);
1249 while (to_read != 0) {
1251 oh = (pcapng_option_header_t *)(void *)opt_ptr;
1252 option_content = opt_ptr + sizeof (pcapng_option_header_t);
1253 bytes_read = pcapng_read_option(fh, pn, oh, option_content, opt_cont_buf_len, to_read, err, err_info, "packet");
1254 if (bytes_read <= 0) {
1255 pcapng_debug("pcapng_read_packet_block: failed to read option");
1256 /* XXX - free anything? */
1259 block_read += bytes_read;
1260 to_read -= bytes_read;
1262 /* handle option content */
1263 switch (oh->option_code) {
1266 pcapng_debug("pcapng_read_packet_block: %u bytes after opt_endofopt", to_read);
1268 /* padding should be ok here, just get out of this */
1272 if (oh->option_length > 0 && oh->option_length < opt_cont_buf_len) {
1273 wblock->packet_header->presence_flags |= WTAP_HAS_COMMENTS;
1274 wblock->packet_header->opt_comment = g_strndup((char *)option_content, oh->option_length);
1275 pcapng_debug("pcapng_read_packet_block: length %u opt_comment '%s'", oh->option_length, wblock->packet_header->opt_comment);
1277 pcapng_debug("pcapng_read_packet_block: opt_comment length %u seems strange", oh->option_length);
1280 case(OPT_EPB_FLAGS):
1281 if (oh->option_length != 4) {
1282 *err = WTAP_ERR_BAD_FILE;
1283 *err_info = g_strdup_printf("pcapng_read_packet_block: packet block flags option length %u is not 4",
1285 /* XXX - free anything? */
1288 /* Don't cast a guint8 * into a guint32 *--the
1289 * guint8 * may not point to something that's
1290 * aligned correctly.
1292 wblock->packet_header->presence_flags |= WTAP_HAS_PACK_FLAGS;
1293 memcpy(&wblock->packet_header->pack_flags, option_content, sizeof(guint32));
1294 if (pn->byte_swapped) {
1295 wblock->packet_header->pack_flags = GUINT32_SWAP_LE_BE(wblock->packet_header->pack_flags);
1296 memcpy(option_content, &wblock->packet_header->pack_flags, sizeof(guint32));
1298 if (wblock->packet_header->pack_flags & 0x000001E0) {
1299 /* The FCS length is present */
1300 fcslen = (wblock->packet_header->pack_flags & 0x000001E0) >> 5;
1302 pcapng_debug("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->packet_header->pack_flags);
1305 pcapng_debug("pcapng_read_packet_block: epb_hash %u currently not handled - ignoring %u bytes",
1306 oh->option_code, oh->option_length);
1308 case(OPT_EPB_DROPCOUNT):
1309 if (oh->option_length != 8) {
1310 *err = WTAP_ERR_BAD_FILE;
1311 *err_info = g_strdup_printf("pcapng_read_packet_block: packet block drop count option length %u is not 8",
1313 /* XXX - free anything? */
1316 /* Don't cast a guint8 * into a guint64 *--the
1317 * guint8 * may not point to something that's
1318 * aligned correctly.
1320 wblock->packet_header->presence_flags |= WTAP_HAS_DROP_COUNT;
1321 memcpy(&wblock->packet_header->drop_count, option_content, sizeof(guint64));
1322 if (pn->byte_swapped) {
1323 wblock->packet_header->drop_count = GUINT64_SWAP_LE_BE(wblock->packet_header->drop_count);
1324 memcpy(option_content, &wblock->packet_header->drop_count, sizeof(guint64));
1327 pcapng_debug("pcapng_read_packet_block: drop_count %" G_GINT64_MODIFIER "u", wblock->packet_header->drop_count);
1332 * Do we have a handler for this packet block option code?
1334 if (option_handlers[BT_INDEX_PBS] != NULL &&
1335 (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_PBS],
1336 GUINT_TO_POINTER((guint)oh->option_code))) != NULL) {
1337 /* Yes - call the handler. */
1338 if (!handler->hfunc(pn->byte_swapped, oh->option_length,
1339 option_content, err, err_info))
1340 /* XXX - free anything? */
1345 pcapng_debug("pcapng_read_packet_block: unknown option %u - ignoring %u bytes",
1346 oh->option_code, oh->option_length);
1351 pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1352 wblock->packet_header, ws_buffer_start_ptr(wblock->frame_buffer),
1353 pn->byte_swapped, fcslen);
1359 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)
1361 interface_info_t iface_info;
1362 pcapng_simple_packet_block_t spb;
1363 wtapng_simple_packet_t simple_packet;
1364 guint32 block_total_length;
1366 int pseudo_header_len;
1369 * Is this block long enough to be an SPB?
1371 if (bh->block_total_length < MIN_SPB_SIZE) {
1375 *err = WTAP_ERR_BAD_FILE;
1376 *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",
1377 bh->block_total_length, MIN_SPB_SIZE);
1381 /* Don't try to allocate memory for a huge number of options, as
1382 that might fail and, even if it succeeds, it might not leave
1383 any address space or memory+backing store for anything else.
1385 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1386 We check for this *after* checking the SHB for its byte
1387 order magic number, so that non-pcap-ng files are less
1388 likely to be treated as bad pcap-ng files. */
1389 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1390 *err = WTAP_ERR_BAD_FILE;
1391 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u is too large (> %u)",
1392 bh->block_total_length, MAX_BLOCK_SIZE);
1396 /* "Simple Packet Block" read fixed part */
1397 if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
1398 pcapng_debug("pcapng_read_simple_packet_block: failed to read packet data");
1402 if (0 >= pn->interfaces->len) {
1403 *err = WTAP_ERR_BAD_FILE;
1404 *err_info = g_strdup("pcapng_read_simple_packet_block: SPB appeared before any IDBs");
1407 iface_info = g_array_index(pn->interfaces, interface_info_t, 0);
1409 if (pn->byte_swapped) {
1410 simple_packet.packet_len = GUINT32_SWAP_LE_BE(spb.packet_len);
1412 simple_packet.packet_len = spb.packet_len;
1416 * The captured length is not a field in the SPB; it can be
1417 * calculated as the minimum of the snapshot length from the
1418 * IDB and the packet length, as per the pcap-ng spec. An IDB
1419 * snapshot length of 0 means no limit.
1421 simple_packet.cap_len = simple_packet.packet_len;
1422 if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
1423 simple_packet.cap_len = iface_info.snap_len;
1426 * How much padding is there at the end of the packet data?
1428 if ((simple_packet.cap_len % 4) != 0)
1429 padding = 4 - (simple_packet.cap_len % 4);
1433 /* add padding bytes to "block total length" */
1434 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1435 if (bh->block_total_length % 4) {
1436 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1438 block_total_length = bh->block_total_length;
1440 pcapng_debug("pcapng_read_simple_packet_block: block_total_length %d", block_total_length);
1443 * Is this block long enough to hold the packet data?
1445 if (block_total_length < MIN_SPB_SIZE + simple_packet.cap_len + padding) {
1447 * No. That means that the problem is with the packet
1448 * length; the snapshot length can be bigger than the amount
1449 * of packet data in the block, as it's a *maximum* length,
1450 * not a *minimum* length.
1452 *err = WTAP_ERR_BAD_FILE;
1453 *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",
1454 block_total_length, simple_packet.packet_len);
1458 if (simple_packet.cap_len > WTAP_MAX_PACKET_SIZE) {
1459 *err = WTAP_ERR_BAD_FILE;
1460 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u",
1461 simple_packet.cap_len, WTAP_MAX_PACKET_SIZE);
1464 pcapng_debug("pcapng_read_simple_packet_block: packet data: packet_len %u",
1465 simple_packet.packet_len);
1467 pcapng_debug("pcapng_read_simple_packet_block: Need to read pseudo header of size %d",
1468 pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header));
1470 /* No time stamp in a simple packet block; no options, either */
1471 wblock->packet_header->rec_type = REC_TYPE_PACKET;
1472 wblock->packet_header->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1473 wblock->packet_header->interface_id = 0;
1474 wblock->packet_header->pkt_encap = iface_info.wtap_encap;
1475 wblock->packet_header->pkt_tsprec = iface_info.tsprecision;
1476 wblock->packet_header->ts.secs = 0;
1477 wblock->packet_header->ts.nsecs = 0;
1478 wblock->packet_header->interface_id = 0;
1479 wblock->packet_header->opt_comment = NULL;
1480 wblock->packet_header->drop_count = 0;
1481 wblock->packet_header->pack_flags = 0;
1483 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1484 pseudo_header_len = pcap_process_pseudo_header(fh,
1485 WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1486 iface_info.wtap_encap,
1487 simple_packet.cap_len,
1489 wblock->packet_header,
1492 if (pseudo_header_len < 0) {
1495 wblock->packet_header->caplen = simple_packet.cap_len - pseudo_header_len;
1496 wblock->packet_header->len = simple_packet.packet_len - pseudo_header_len;
1497 if (pseudo_header_len != pcap_get_phdr_size(iface_info.wtap_encap, &wblock->packet_header->pseudo_header)) {
1498 pcapng_debug("pcapng_read_simple_packet_block: Could only read %d bytes for pseudo header.",
1502 memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1504 /* "Simple Packet Block" read capture data */
1505 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1506 simple_packet.cap_len, err, err_info))
1509 /* jump over potential padding bytes at end of the packet data */
1510 if ((simple_packet.cap_len % 4) != 0) {
1511 if (!file_skip(fh, 4 - (simple_packet.cap_len % 4), err))
1515 pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1516 wblock->packet_header, ws_buffer_start_ptr(wblock->frame_buffer),
1517 pn->byte_swapped, pn->if_fcslen);
1521 #define NRES_ENDOFRECORD 0
1522 #define NRES_IP4RECORD 1
1523 #define NRES_IP6RECORD 2
1524 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
1525 /* IPv6 + MAXNAMELEN */
1526 #define INITIAL_NRB_REC_SIZE (16 + 64)
1529 * Find the end of the NUL-terminated name the beginning of which is pointed
1530 * to by p; record_len is the number of bytes remaining in the record.
1532 * Return the length of the name, including the terminating NUL.
1534 * If we don't find a terminating NUL, return -1 and set *err and
1535 * *err_info appropriately.
1538 name_resolution_block_find_name_end(const char *p, guint record_len, int *err,
1545 if (record_len == 0) {
1547 * We ran out of bytes in the record without
1550 *err = WTAP_ERR_BAD_FILE;
1551 *err_info = g_strdup("pcapng_read_name_resolution_block: NRB record has non-null-terminated host name");
1555 break; /* that's the terminating NUL */
1558 namelen++; /* count this byte */
1561 /* Include the NUL in the name length. */
1566 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)
1570 pcapng_name_resolution_block_t nrb;
1573 guint record_len, opt_cont_buf_len;
1577 pcapng_option_header_t oh;
1578 guint8 *option_content;
1580 option_handler *handler;
1585 * Is this block long enough to be an NRB?
1587 if (bh->block_total_length < MIN_NRB_SIZE) {
1591 *err = WTAP_ERR_BAD_FILE;
1592 *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",
1593 bh->block_total_length, MIN_NRB_SIZE);
1597 /* Don't try to allocate memory for a huge number of options, as
1598 that might fail and, even if it succeeds, it might not leave
1599 any address space or memory+backing store for anything else.
1601 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1602 We check for this *after* checking the SHB for its byte
1603 order magic number, so that non-pcap-ng files are less
1604 likely to be treated as bad pcap-ng files. */
1605 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1606 *err = WTAP_ERR_BAD_FILE;
1607 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: total block length %u is too large (> %u)",
1608 bh->block_total_length, MAX_BLOCK_SIZE);
1612 to_read = bh->block_total_length - 8 - 4; /* We have read the header and should not read the final block_total_length */
1614 pcapng_debug("pcapng_read_name_resolution_block, total %d bytes", bh->block_total_length);
1616 /* Ensure we have a name resolution block */
1617 if (wblock->block == NULL) {
1618 wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB);
1622 * Start out with a buffer big enough for an IPv6 address and one
1623 * 64-byte name; we'll make the buffer bigger if necessary.
1625 ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
1627 while (block_read < to_read) {
1629 * There must be at least one record's worth of data
1632 if ((size_t)(to_read - block_read) < sizeof nrb) {
1633 ws_buffer_free(&nrb_rec);
1634 *err = WTAP_ERR_BAD_FILE;
1635 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record header size %u",
1636 to_read - block_read,
1640 if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
1641 ws_buffer_free(&nrb_rec);
1642 pcapng_debug("pcapng_read_name_resolution_block: failed to read record header");
1645 block_read += (int)sizeof nrb;
1647 if (pn->byte_swapped) {
1648 nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type);
1649 nrb.record_len = GUINT16_SWAP_LE_BE(nrb.record_len);
1652 if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
1653 ws_buffer_free(&nrb_rec);
1654 *err = WTAP_ERR_BAD_FILE;
1655 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record length + padding %u",
1656 to_read - block_read,
1657 nrb.record_len + PADDING4(nrb.record_len));
1660 switch (nrb.record_type) {
1661 case NRES_ENDOFRECORD:
1662 /* There shouldn't be any more data - but there MAY be options */
1665 case NRES_IP4RECORD:
1667 * The smallest possible record must have
1668 * a 4-byte IPv4 address, hence a minimum
1671 * (The pcap-NG spec really indicates
1672 * that it must be at least 5 bytes,
1673 * as there must be at least one name,
1674 * and it really must be at least 6
1675 * bytes, as the name mustn't be null,
1676 * but there's no need to fail if there
1677 * aren't any names at all, and we
1678 * should report a null name as such.)
1680 if (nrb.record_len < 4) {
1681 ws_buffer_free(&nrb_rec);
1682 *err = WTAP_ERR_BAD_FILE;
1683 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv4 record %u < minimum length 4",
1687 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1688 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1689 nrb.record_len, err, err_info)) {
1690 ws_buffer_free(&nrb_rec);
1691 pcapng_debug("pcapng_read_name_resolution_block: failed to read IPv4 record data");
1694 block_read += nrb.record_len;
1696 if (pn->add_new_ipv4) {
1698 * Scan through all the names in
1699 * the record and add them.
1702 ws_buffer_start_ptr(&nrb_rec), 4);
1703 /* IPv4 address is in big-endian order in the file always, which is how we store
1704 it internally as well, so don't byte-swap it */
1705 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
1707 namep += namelen, record_len -= namelen) {
1709 * Scan forward for a null
1712 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1713 if (namelen == -1) {
1714 ws_buffer_free(&nrb_rec);
1715 return FALSE; /* fail */
1717 pn->add_new_ipv4(v4_addr, namep);
1721 if (!file_skip(fh, PADDING4(nrb.record_len), err)) {
1722 ws_buffer_free(&nrb_rec);
1725 block_read += PADDING4(nrb.record_len);
1727 case NRES_IP6RECORD:
1729 * The smallest possible record must have
1730 * a 16-byte IPv6 address, hence a minimum
1733 * (The pcap-NG spec really indicates
1734 * that it must be at least 17 bytes,
1735 * as there must be at least one name,
1736 * and it really must be at least 18
1737 * bytes, as the name mustn't be null,
1738 * but there's no need to fail if there
1739 * aren't any names at all, and we
1740 * should report a null name as such.)
1742 if (nrb.record_len < 16) {
1743 ws_buffer_free(&nrb_rec);
1744 *err = WTAP_ERR_BAD_FILE;
1745 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u < minimum length 16",
1749 if (to_read < nrb.record_len) {
1750 ws_buffer_free(&nrb_rec);
1751 *err = WTAP_ERR_BAD_FILE;
1752 *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u > remaining data in NRB",
1756 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1757 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1758 nrb.record_len, err, err_info)) {
1759 ws_buffer_free(&nrb_rec);
1762 block_read += nrb.record_len;
1764 if (pn->add_new_ipv6) {
1765 for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
1767 namep += namelen, record_len -= namelen) {
1769 * Scan forward for a null
1772 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1773 if (namelen == -1) {
1774 ws_buffer_free(&nrb_rec);
1775 return FALSE; /* fail */
1777 pn->add_new_ipv6(ws_buffer_start_ptr(&nrb_rec),
1782 if (!file_skip(fh, PADDING4(nrb.record_len), err)) {
1783 ws_buffer_free(&nrb_rec);
1786 block_read += PADDING4(nrb.record_len);
1789 pcapng_debug("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
1790 if (!file_skip(fh, nrb.record_len + PADDING4(nrb.record_len), err)) {
1791 ws_buffer_free(&nrb_rec);
1794 block_read += nrb.record_len + PADDING4(nrb.record_len);
1801 to_read -= block_read;
1812 /* Allocate enough memory to hold all options */
1813 opt_cont_buf_len = to_read;
1814 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1815 if (opt_cont_buf_len != 0 && option_content == NULL) {
1816 *err = ENOMEM; /* we assume we're out of memory */
1817 ws_buffer_free(&nrb_rec);
1821 while (to_read != 0) {
1823 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "name_resolution");
1824 if (bytes_read <= 0) {
1825 pcapng_debug("pcapng_read_name_resolution_block: failed to read option");
1826 g_free(option_content);
1827 ws_buffer_free(&nrb_rec);
1830 to_read -= bytes_read;
1832 /* handle option content */
1833 switch (oh.option_code) {
1836 pcapng_debug("pcapng_read_name_resolution_block: %u bytes after opt_endofopt", to_read);
1838 /* padding should be ok here, just get out of this */
1842 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1843 tmp_content = g_strndup((char *)option_content, oh.option_length);
1844 wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1845 pcapng_debug("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, tmp_content);
1846 g_free(tmp_content);
1848 pcapng_debug("pcapng_read_name_resolution_block: opt_comment length %u seems strange", oh.option_length);
1854 * Do we have a handler for this network resolution block option code?
1856 if (option_handlers[BT_INDEX_NRB] != NULL &&
1857 (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_NRB],
1858 GUINT_TO_POINTER((guint)oh.option_code))) != NULL) {
1859 /* Yes - call the handler. */
1860 if (!handler->hfunc(pn->byte_swapped, oh.option_length,
1861 option_content, err, err_info)) {
1863 g_free(option_content);
1864 ws_buffer_free(&nrb_rec);
1870 pcapng_debug("pcapng_read_name_resolution_block: unknown option %u - ignoring %u bytes",
1871 oh.option_code, oh.option_length);
1876 g_free(option_content);
1877 ws_buffer_free(&nrb_rec);
1882 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)
1885 guint to_read, opt_cont_buf_len;
1886 pcapng_interface_statistics_block_t isb;
1887 pcapng_option_header_t oh;
1888 guint8 *option_content = NULL; /* Allocate as large as the options block */
1889 wtapng_if_stats_mandatory_t* if_stats_mand;
1893 * Is this block long enough to be an ISB?
1895 if (bh->block_total_length < MIN_ISB_SIZE) {
1899 *err = WTAP_ERR_BAD_FILE;
1900 *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too small (< %u)",
1901 bh->block_total_length, MIN_ISB_SIZE);
1905 /* Don't try to allocate memory for a huge number of options, as
1906 that might fail and, even if it succeeds, it might not leave
1907 any address space or memory+backing store for anything else.
1909 We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1910 We check for this *after* checking the SHB for its byte
1911 order magic number, so that non-pcap-ng files are less
1912 likely to be treated as bad pcap-ng files. */
1913 if (bh->block_total_length > MAX_BLOCK_SIZE) {
1914 *err = WTAP_ERR_BAD_FILE;
1915 *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too large (> %u)",
1916 bh->block_total_length, MAX_BLOCK_SIZE);
1920 /* "Interface Statistics Block" read fixed part */
1921 if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
1922 pcapng_debug("pcapng_read_interface_statistics_block: failed to read packet data");
1926 wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS);
1927 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
1928 if (pn->byte_swapped) {
1929 if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
1930 if_stats_mand->ts_high = GUINT32_SWAP_LE_BE(isb.timestamp_high);
1931 if_stats_mand->ts_low = GUINT32_SWAP_LE_BE(isb.timestamp_low);
1933 if_stats_mand->interface_id = isb.interface_id;
1934 if_stats_mand->ts_high = isb.timestamp_high;
1935 if_stats_mand->ts_low = isb.timestamp_low;
1937 pcapng_debug("pcapng_read_interface_statistics_block: interface_id %u", if_stats_mand->interface_id);
1940 to_read = bh->block_total_length -
1941 (MIN_BLOCK_SIZE + (guint)sizeof isb); /* fixed and variable part, including padding */
1943 /* Allocate enough memory to hold all options */
1944 opt_cont_buf_len = to_read;
1945 option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1946 if (opt_cont_buf_len != 0 && option_content == NULL) {
1947 *err = ENOMEM; /* we assume we're out of memory */
1951 while (to_read != 0) {
1953 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "interface_statistics");
1954 if (bytes_read <= 0) {
1955 pcapng_debug("pcapng_read_interface_statistics_block: failed to read option");
1958 to_read -= bytes_read;
1960 /* handle option content */
1961 switch (oh.option_code) {
1962 case(OPT_EOFOPT): /* opt_endofopt */
1964 pcapng_debug("pcapng_read_interface_statistics_block: %u bytes after opt_endofopt", to_read);
1966 /* padding should be ok here, just get out of this */
1969 case(OPT_COMMENT): /* opt_comment */
1970 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1971 tmp_content = g_strndup((char *)option_content, oh.option_length);
1972 wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1973 pcapng_debug("pcapng_read_interface_statistics_block: opt_comment %s", tmp_content);
1974 g_free(tmp_content);
1976 pcapng_debug("pcapng_read_interface_statistics_block: opt_comment length %u seems strange", oh.option_length);
1979 case(OPT_ISB_STARTTIME): /* isb_starttime */
1980 if (oh.option_length == 8) {
1984 /* Don't cast a guint8 * into a guint32 *--the
1985 * guint8 * may not point to something that's
1986 * aligned correctly.
1988 memcpy(&high, option_content, sizeof(guint32));
1989 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
1990 if (pn->byte_swapped) {
1991 high = GUINT32_SWAP_LE_BE(high);
1992 low = GUINT32_SWAP_LE_BE(low);
1994 starttime = (guint64)high;
1996 starttime += (guint64)low;
1997 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_STARTTIME, starttime);
1998 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime %" G_GINT64_MODIFIER "u", starttime);
2000 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2003 case(OPT_ISB_ENDTIME): /* isb_endtime */
2004 if (oh.option_length == 8) {
2008 /* Don't cast a guint8 * into a guint32 *--the
2009 * guint8 * may not point to something that's
2010 * aligned correctly.
2012 memcpy(&high, option_content, sizeof(guint32));
2013 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
2014 if (pn->byte_swapped) {
2015 high = GUINT32_SWAP_LE_BE(high);
2016 low = GUINT32_SWAP_LE_BE(low);
2018 endtime = (guint64)high;
2020 endtime += (guint64)low;
2021 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_ENDTIME, endtime);
2022 pcapng_debug("pcapng_read_interface_statistics_block: isb_endtime %" G_GINT64_MODIFIER "u", endtime);
2024 pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2027 case(OPT_ISB_IFRECV): /* isb_ifrecv */
2028 if (oh.option_length == 8) {
2030 /* Don't cast a guint8 * into a guint64 *--the
2031 * guint8 * may not point to something that's
2032 * aligned correctly.
2034 memcpy(&ifrecv, option_content, sizeof(guint64));
2035 if (pn->byte_swapped)
2036 ifrecv = GUINT64_SWAP_LE_BE(ifrecv);
2037 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_IFRECV, ifrecv);
2038 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", ifrecv);
2040 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv length %u not 8 as expected", oh.option_length);
2043 case(OPT_ISB_IFDROP): /* isb_ifdrop */
2044 if (oh.option_length == 8) {
2046 /* Don't cast a guint8 * into a guint64 *--the
2047 * guint8 * may not point to something that's
2048 * aligned correctly.
2050 memcpy(&ifdrop, option_content, sizeof(guint64));
2051 if (pn->byte_swapped)
2052 ifdrop = GUINT64_SWAP_LE_BE(ifdrop);
2053 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_IFDROP, ifdrop);
2054 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", ifdrop);
2056 pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop length %u not 8 as expected", oh.option_length);
2059 case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
2060 if (oh.option_length == 8) {
2061 guint64 filteraccept;
2062 /* Don't cast a guint8 * into a guint64 *--the
2063 * guint8 * may not point to something that's
2064 * aligned correctly.
2066 memcpy(&filteraccept, option_content, sizeof(guint64));
2067 if (pn->byte_swapped)
2068 filteraccept = GUINT64_SWAP_LE_BE(filteraccept);
2069 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_FILTERACCEPT, filteraccept);
2070 pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept %" G_GINT64_MODIFIER "u", filteraccept);
2072 pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept length %u not 8 as expected", oh.option_length);
2075 case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
2076 if (oh.option_length == 8) {
2078 /* Don't cast a guint8 * into a guint64 *--the
2079 * guint8 * may not point to something that's
2080 * aligned correctly.
2082 memcpy(&osdrop, option_content, sizeof(guint64));
2083 if (pn->byte_swapped)
2084 osdrop = GUINT64_SWAP_LE_BE(osdrop);
2085 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_OSDROP, osdrop);
2086 pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop %" G_GINT64_MODIFIER "u", osdrop);
2088 pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop length %u not 8 as expected", oh.option_length);
2091 case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8 */
2092 if (oh.option_length == 8) {
2094 /* Don't cast a guint8 * into a guint64 *--the
2095 * guint8 * may not point to something that's
2096 * aligned correctly.
2098 memcpy(&usrdeliv, option_content, sizeof(guint64));
2099 if (pn->byte_swapped)
2100 usrdeliv = GUINT64_SWAP_LE_BE(usrdeliv);
2101 wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_USRDELIV, usrdeliv);
2102 pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv %" G_GINT64_MODIFIER "u", usrdeliv);
2104 pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv length %u not 8 as expected", oh.option_length);
2108 pcapng_debug("pcapng_read_interface_statistics_block: unknown option %u - ignoring %u bytes",
2109 oh.option_code, oh.option_length);
2113 g_free(option_content);
2119 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)
2121 unsigned block_read;
2122 guint32 block_total_length;
2130 if (bh->block_total_length < MIN_SYSDIG_EVENT_SIZE) {
2131 *err = WTAP_ERR_BAD_FILE;
2132 *err_info = g_strdup_printf("%s: total block length %u is too small (< %u)", G_STRFUNC,
2133 bh->block_total_length, MIN_SYSDIG_EVENT_SIZE);
2137 /* add padding bytes to "block total length" */
2138 /* (the "block total length" of some example files don't contain any padding bytes!) */
2139 if (bh->block_total_length % 4) {
2140 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2142 block_total_length = bh->block_total_length;
2145 pcapng_debug("pcapng_read_sysdig_event_block: block_total_length %u",
2146 bh->block_total_length);
2148 wblock->packet_header->rec_type = REC_TYPE_SYSCALL;
2149 wblock->packet_header->pseudo_header.sysdig_event.record_type = BLOCK_TYPE_SYSDIG_EVENT;
2150 wblock->packet_header->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
2151 wblock->packet_header->pkt_tsprec = WTAP_TSPREC_NSEC;
2153 block_read = block_total_length;
2155 if (!wtap_read_bytes(fh, &cpu_id, sizeof cpu_id, err, err_info)) {
2156 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event cpu id");
2159 if (!wtap_read_bytes(fh, &wire_ts, sizeof wire_ts, err, err_info)) {
2160 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event timestamp");
2163 if (!wtap_read_bytes(fh, &thread_id, sizeof thread_id, err, err_info)) {
2164 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event thread id");
2167 if (!wtap_read_bytes(fh, &event_len, sizeof event_len, err, err_info)) {
2168 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event length");
2171 if (!wtap_read_bytes(fh, &event_type, sizeof event_type, err, err_info)) {
2172 pcapng_debug("pcapng_read_packet_block: failed to read sysdig event type");
2176 block_read -= MIN_SYSDIG_EVENT_SIZE;
2177 wblock->packet_header->pseudo_header.sysdig_event.byte_order = G_BYTE_ORDER;
2179 /* XXX Use Gxxx_FROM_LE macros instead? */
2180 if (pn->byte_swapped) {
2181 wblock->packet_header->pseudo_header.sysdig_event.byte_order =
2182 G_BYTE_ORDER == G_LITTLE_ENDIAN ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
2183 wblock->packet_header->pseudo_header.sysdig_event.cpu_id = GUINT16_SWAP_LE_BE(cpu_id);
2184 ts = GUINT64_SWAP_LE_BE(wire_ts);
2185 wblock->packet_header->pseudo_header.sysdig_event.thread_id = GUINT64_SWAP_LE_BE(thread_id);
2186 wblock->packet_header->pseudo_header.sysdig_event.event_len = GUINT32_SWAP_LE_BE(event_len);
2187 wblock->packet_header->pseudo_header.sysdig_event.event_type = GUINT16_SWAP_LE_BE(event_type);
2189 wblock->packet_header->pseudo_header.sysdig_event.cpu_id = cpu_id;
2191 wblock->packet_header->pseudo_header.sysdig_event.thread_id = thread_id;
2192 wblock->packet_header->pseudo_header.sysdig_event.event_len = event_len;
2193 wblock->packet_header->pseudo_header.sysdig_event.event_type = event_type;
2196 wblock->packet_header->ts.secs = (time_t) (ts / 1000000000);
2197 wblock->packet_header->ts.nsecs = (int) (ts % 1000000000);
2199 wblock->packet_header->caplen = block_read;
2200 wblock->packet_header->len = wblock->packet_header->pseudo_header.sysdig_event.event_len;
2202 /* "Sysdig Event Block" read event data */
2203 if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2204 block_read, err, err_info))
2207 /* XXX Read comment? */
2213 pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh,
2217 wtapng_block_t *wblock,
2220 wtapng_block_t *wblock _U_,
2222 int *err, gchar **err_info)
2225 guint32 block_total_length;
2227 block_handler *handler;
2230 if (bh->block_total_length < MIN_BLOCK_SIZE) {
2231 *err = WTAP_ERR_BAD_FILE;
2232 *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",
2233 bh->block_total_length, MIN_BLOCK_SIZE);
2237 /* add padding bytes to "block total length" */
2238 /* (the "block total length" of some example files don't contain any padding bytes!) */
2239 if (bh->block_total_length % 4) {
2240 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2242 block_total_length = bh->block_total_length;
2245 block_read = block_total_length - MIN_BLOCK_SIZE;
2249 * Do we have a handler for this block type?
2251 if (block_handlers != NULL &&
2252 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
2253 GUINT_TO_POINTER(bh->block_type))) != NULL) {
2254 /* Yes - call it to read this block type. */
2255 if (!handler->reader(fh, block_read, pn->byte_swapped,
2256 wblock->packet_header, wblock->frame_buffer,
2262 /* No. Skip over this unknown block. */
2263 if (!file_skip(fh, block_read, err)) {
2272 static block_return_val
2273 pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
2275 block_return_val ret;
2276 pcapng_block_header_t bh;
2277 guint32 block_total_length;
2279 wblock->block = NULL;
2281 /* Try to read the (next) block header */
2282 if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
2283 pcapng_debug("pcapng_read_block: wtap_read_bytes_or_eof() failed, err = %d.", *err);
2284 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
2286 * Short read or EOF.
2288 * If we're reading this as part of an open,
2289 * the file is too short to be a pcap-ng file.
2291 * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
2292 * PCAPNG_BLOCK_ERROR the same, so we can just return
2293 * PCAPNG_BLOCK_NOT_SHB in both cases.
2295 return PCAPNG_BLOCK_NOT_SHB;
2297 return PCAPNG_BLOCK_ERROR;
2301 * SHBs have to be treated differently from other blocks, as we
2302 * might be doing an open and attempting to read a block at the
2303 * beginning of the file to see if it's a pcap-ng file or not,
2304 * and as they do not necessarily have the same byte order as
2307 if (bh.block_type == BLOCK_TYPE_SHB) {
2309 * BLOCK_TYPE_SHB has the same value regardless of byte order,
2310 * so we don't need to byte-swap it.
2312 wblock->type = bh.block_type;
2314 pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2316 ret = pcapng_read_section_header_block(fh, &bh, pn, wblock, err, err_info);
2317 if (ret != PCAPNG_BLOCK_OK) {
2321 if (pn->byte_swapped) {
2322 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
2323 bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length);
2326 wblock->type = bh.block_type;
2328 pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2330 if (!pn->shb_read) {
2332 * No SHB seen yet, so we're trying to read the first block
2333 * during an open, to see whether it's an SHB; if what we
2334 * read doesn't look like an SHB, this isn't a pcap-ng file.
2338 return PCAPNG_BLOCK_NOT_SHB;
2340 switch (bh.block_type) {
2341 case(BLOCK_TYPE_IDB):
2342 if (!pcapng_read_if_descr_block(wth, fh, &bh, pn, wblock, err, err_info))
2343 return PCAPNG_BLOCK_ERROR;
2345 case(BLOCK_TYPE_PB):
2346 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE))
2347 return PCAPNG_BLOCK_ERROR;
2349 case(BLOCK_TYPE_SPB):
2350 if (!pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info))
2351 return PCAPNG_BLOCK_ERROR;
2353 case(BLOCK_TYPE_EPB):
2354 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE))
2355 return PCAPNG_BLOCK_ERROR;
2357 case(BLOCK_TYPE_NRB):
2358 if (!pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info))
2359 return PCAPNG_BLOCK_ERROR;
2361 case(BLOCK_TYPE_ISB):
2362 if (!pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info))
2363 return PCAPNG_BLOCK_ERROR;
2365 case(BLOCK_TYPE_SYSDIG_EVENT):
2366 /* case(BLOCK_TYPE_SYSDIG_EVF): */
2367 if (!pcapng_read_sysdig_event_block(fh, &bh, pn, wblock, err, err_info))
2368 return PCAPNG_BLOCK_ERROR;
2371 pcapng_debug("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
2372 if (!pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info))
2373 return PCAPNG_BLOCK_ERROR;
2378 /* sanity check: first and second block lengths must match */
2379 if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
2381 pcapng_debug("pcapng_check_block_trailer: couldn't read second block length");
2382 return PCAPNG_BLOCK_ERROR;
2385 if (pn->byte_swapped)
2386 block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
2388 if (block_total_length != bh.block_total_length) {
2389 *err = WTAP_ERR_BAD_FILE;
2390 *err_info = g_strdup_printf("pcapng_check_block_trailer: total block lengths (first %u and second %u) don't match",
2391 bh.block_total_length, block_total_length);
2392 return PCAPNG_BLOCK_ERROR;
2394 return PCAPNG_BLOCK_OK;
2397 /* Process an IDB that we've just read. */
2399 pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
2401 wtap_optionblock_t int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
2402 interface_info_t iface_info;
2403 wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data),
2404 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
2406 wtap_optionblock_copy_options(int_data, wblock->block);
2408 /* XXX if_tsoffset; opt 14 A 64 bits integer value that specifies an offset (in seconds)...*/
2409 /* Interface statistics */
2410 if_descr_mand->num_stat_entries = 0;
2411 if_descr_mand->interface_statistics = NULL;
2413 g_array_append_val(wth->interface_data, int_data);
2415 iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
2416 iface_info.snap_len = wblock_if_descr_mand->snap_len;
2417 iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
2418 iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
2420 g_array_append_val(pcapng->interfaces, iface_info);
2423 /* classic wtap: open capture file */
2424 wtap_open_return_val
2425 pcapng_open(wtap *wth, int *err, gchar **err_info)
2428 wtapng_block_t wblock;
2430 pcapng_block_header_t bh;
2431 gint64 saved_offset;
2433 pn.shb_read = FALSE;
2434 /* we don't know the byte swapping of the file yet */
2435 pn.byte_swapped = FALSE;
2437 pn.version_major = -1;
2438 pn.version_minor = -1;
2439 pn.interfaces = NULL;
2441 /* we don't expect any packet blocks yet */
2442 wblock.frame_buffer = NULL;
2443 wblock.packet_header = NULL;
2445 pcapng_debug("pcapng_open: opening file");
2446 /* read first block */
2447 switch (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info)) {
2449 case PCAPNG_BLOCK_OK:
2453 case PCAPNG_BLOCK_NOT_SHB:
2454 /* An error indicating that this isn't a pcap-ng file. */
2455 wtap_optionblock_free(wblock.block);
2456 wblock.block = NULL;
2459 return WTAP_OPEN_NOT_MINE;
2461 case PCAPNG_BLOCK_ERROR:
2462 /* An I/O error, or this probably *is* a pcap-ng file but not a valid one. */
2463 wtap_optionblock_free(wblock.block);
2464 wblock.block = NULL;
2465 return WTAP_OPEN_ERROR;
2468 /* first block must be a "Section Header Block" */
2469 if (wblock.type != BLOCK_TYPE_SHB) {
2471 * XXX - check for damage from transferring a file
2472 * between Windows and UN*X as text rather than
2475 pcapng_debug("pcapng_open: first block type %u not SHB", wblock.type);
2476 wtap_optionblock_free(wblock.block);
2477 wblock.block = NULL;
2478 return WTAP_OPEN_NOT_MINE;
2483 * At this point, we've decided this is a pcap-NG file, not
2484 * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
2487 wtap_optionblock_copy_options(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), wblock.block);
2489 wth->file_encap = WTAP_ENCAP_UNKNOWN;
2490 wth->snapshot_length = 0;
2491 wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
2492 pcapng = (pcapng_t *)g_malloc(sizeof(pcapng_t));
2493 wth->priv = (void *)pcapng;
2495 pcapng->interfaces = g_array_new(FALSE, FALSE, sizeof(interface_info_t));
2497 wth->subtype_read = pcapng_read;
2498 wth->subtype_seek_read = pcapng_seek_read;
2499 wth->subtype_close = pcapng_close;
2500 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
2502 /* Loop over all IDB:s that appear before any packets */
2504 /* peek at next block */
2505 /* Try to read the (next) block header */
2506 saved_offset = file_tell(wth->fh);
2507 if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
2510 pcapng_debug("No more IDBs available...");
2513 pcapng_debug("pcapng_open: Check for more IDB:s, wtap_read_bytes_or_eof() failed, err = %d.", *err);
2514 return WTAP_OPEN_ERROR;
2517 /* go back to where we were */
2518 file_seek(wth->fh, saved_offset, SEEK_SET, err);
2520 if (pn.byte_swapped) {
2521 bh.block_type = GUINT32_SWAP_LE_BE(bh.block_type);
2524 pcapng_debug("pcapng_open: Check for more IDB:s block_type 0x%x", bh.block_type);
2526 if (bh.block_type != BLOCK_TYPE_IDB) {
2527 break; /* No more IDB:s */
2529 if (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2531 pcapng_debug("No more IDBs available...");
2532 wtap_optionblock_free(wblock.block);
2533 wblock.block = NULL;
2536 pcapng_debug("pcapng_open: couldn't read IDB");
2537 wtap_optionblock_free(wblock.block);
2538 wblock.block = NULL;
2539 return WTAP_OPEN_ERROR;
2542 pcapng_process_idb(wth, pcapng, &wblock);
2543 pcapng_debug("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i",
2544 wth->interface_data->len, wth->file_encap);
2546 return WTAP_OPEN_MINE;
2550 /* classic wtap: read packet */
2552 pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
2554 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2555 wtapng_block_t wblock;
2556 wtap_optionblock_t wtapng_if_descr;
2557 wtap_optionblock_t if_stats;
2558 wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
2559 wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
2561 wblock.frame_buffer = wth->frame_buffer;
2562 wblock.packet_header = &wth->phdr;
2564 pcapng->add_new_ipv4 = wth->add_new_ipv4;
2565 pcapng->add_new_ipv6 = wth->add_new_ipv6;
2567 /* read next block */
2569 *data_offset = file_tell(wth->fh);
2570 pcapng_debug("pcapng_read: data_offset is %" G_GINT64_MODIFIER "d", *data_offset);
2571 if (pcapng_read_block(wth, wth->fh, pcapng, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2572 pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2573 pcapng_debug("pcapng_read: couldn't read packet block");
2577 switch (wblock.type) {
2579 case(BLOCK_TYPE_SHB):
2580 pcapng_debug("pcapng_read: another section header block");
2581 g_array_append_val(wth->shb_hdrs, wblock.block);
2584 case(BLOCK_TYPE_PB):
2585 case(BLOCK_TYPE_SPB):
2586 case(BLOCK_TYPE_EPB):
2587 case(BLOCK_TYPE_SYSDIG_EVENT):
2588 case(BLOCK_TYPE_SYSDIG_EVF):
2589 /* packet block - we've found a packet */
2592 case(BLOCK_TYPE_IDB):
2593 /* A new interface */
2594 pcapng_debug("pcapng_read: block type BLOCK_TYPE_IDB");
2595 pcapng_process_idb(wth, pcapng, &wblock);
2598 case(BLOCK_TYPE_NRB):
2599 /* More name resolution entries */
2600 pcapng_debug("pcapng_read: block type BLOCK_TYPE_NRB");
2601 if (wth->nrb_hdrs == NULL) {
2602 wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2604 g_array_append_val(wth->nrb_hdrs, wblock.block);
2607 case(BLOCK_TYPE_ISB):
2608 /* Another interface statistics report */
2609 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB");
2610 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock.block);
2611 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
2612 pcapng_debug("pcapng_read: BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces", if_stats_mand_block->interface_id);
2614 /* Get the interface description */
2615 wtapng_if_descr = g_array_index(wth->interface_data, wtap_optionblock_t, if_stats_mand_block->interface_id);
2616 wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wtapng_if_descr);
2617 if (wtapng_if_descr_mand->num_stat_entries == 0) {
2618 /* First ISB found, no previous entry */
2619 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
2620 wtapng_if_descr_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
2623 if_stats = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS);
2624 if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats);
2625 if_stats_mand->interface_id = if_stats_mand_block->interface_id;
2626 if_stats_mand->ts_high = if_stats_mand_block->ts_high;
2627 if_stats_mand->ts_low = if_stats_mand_block->ts_low;
2629 wtap_optionblock_copy_options(if_stats, wblock.block);
2630 g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
2631 wtapng_if_descr_mand->num_stat_entries++;
2636 /* XXX - improve handling of "unknown" blocks */
2637 pcapng_debug("pcapng_read: Unknown block type 0x%08x", wblock.type);
2644 /*pcapng_debug("Read length: %u Packet length: %u", bytes_read, wth->phdr.caplen);*/
2645 pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2651 /* classic wtap: seek to file position and read packet */
2653 pcapng_seek_read(wtap *wth, gint64 seek_off,
2654 struct wtap_pkthdr *phdr, Buffer *buf,
2655 int *err, gchar **err_info)
2657 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2658 block_return_val ret;
2659 wtapng_block_t wblock;
2662 /* seek to the right file position */
2663 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
2664 return FALSE; /* Seek error */
2666 pcapng_debug("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
2668 wblock.frame_buffer = buf;
2669 wblock.packet_header = phdr;
2671 /* read the block */
2672 ret = pcapng_read_block(wth, wth->random_fh, pcapng, &wblock, err, err_info);
2673 wtap_optionblock_free(wblock.block);
2674 if (ret != PCAPNG_BLOCK_OK) {
2675 pcapng_debug("pcapng_seek_read: couldn't read packet block (err=%d).",
2680 /* block must be a "Packet Block", an "Enhanced Packet Block",
2681 a "Simple Packet Block", or an event */
2682 if (wblock.type != BLOCK_TYPE_PB && wblock.type != BLOCK_TYPE_EPB &&
2683 wblock.type != BLOCK_TYPE_SPB &&
2684 wblock.type != BLOCK_TYPE_SYSDIG_EVENT && wblock.type != BLOCK_TYPE_SYSDIG_EVF) {
2685 pcapng_debug("pcapng_seek_read: block type %u not PB/EPB/SPB", wblock.type);
2693 /* classic wtap: close capture file */
2695 pcapng_close(wtap *wth)
2697 pcapng_t *pcapng = (pcapng_t *)wth->priv;
2699 pcapng_debug("pcapng_close: closing file");
2700 g_array_free(pcapng->interfaces, TRUE);
2703 typedef struct pcapng_optionblock_size_t
2706 } pcapng_optionblock_size_t;
2708 static guint32 pcapng_compute_option_string_size(char *str)
2710 guint32 size = 0, pad;
2715 size = (guint32)strlen(str) & 0xffff;
2717 pad = 4 - (size % 4);
2727 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)
2729 pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data;
2735 case OPT_SHB_HARDWARE:
2737 case OPT_SHB_USERAPPL:
2739 size = pcapng_compute_option_string_size(option->stringval);
2742 /* Unknown options - size by datatype? */
2746 block_size->size += size;
2747 /* Add bytes for option header if option should be written */
2749 /* Add optional padding to 32 bits */
2750 if ((block_size->size & 0x03) != 0)
2752 block_size->size += 4 - (block_size->size & 0x03);
2754 block_size->size += 4;
2758 typedef struct pcapng_write_block_t
2764 pcapng_write_block_t;
2766 static gboolean pcapng_write_option_string(wtap_dumper *wdh, guint option_id, char *str, int *err)
2768 struct pcapng_option_header option_hdr;
2769 guint32 size = (guint32)strlen(str) & 0xffff;
2770 const guint32 zero_pad = 0;
2776 /* String options don't consider pad bytes part of the length */
2777 option_hdr.type = (guint16)option_id;
2778 option_hdr.value_length = (guint16)size;
2779 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2781 wdh->bytes_dumped += 4;
2783 if (!wtap_dump_file_write(wdh, str, size, err))
2785 wdh->bytes_dumped += size;
2788 pad = 4 - (size % 4);
2793 /* write padding (if any) */
2795 if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
2798 wdh->bytes_dumped += pad;
2804 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)
2806 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
2808 /* Don't continue if there has been an error */
2809 if (!write_block->success)
2815 case OPT_SHB_HARDWARE:
2817 case OPT_SHB_USERAPPL:
2818 if ((option != NULL) && (option->stringval != NULL)) {
2819 if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) {
2820 write_block->success = FALSE;
2826 /* Unknown options - write by datatype? */
2831 /* Write a section header block.
2832 * If we don't have a section block header already, create a default
2833 * one with no options.
2836 pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
2838 pcapng_block_header_t bh;
2839 pcapng_section_header_block_t shb;
2840 pcapng_optionblock_size_t block_size;
2841 struct pcapng_option_header option_hdr;
2842 wtap_optionblock_t wdh_shb = NULL;
2844 if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
2845 wdh_shb = g_array_index(wdh->shb_hdrs, wtap_optionblock_t, 0);
2848 block_size.size = 0;
2849 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + 4);
2851 pcapng_debug("pcapng_write_section_header_block: Have shb_hdr");
2853 /* Compute block size */
2854 wtap_optionblock_foreach_option(wdh_shb, compute_shb_option_size, &block_size);
2856 if (block_size.size > 0) {
2857 /* End-of-options tag */
2858 block_size.size += 4;
2861 bh.block_total_length += block_size.size;
2864 pcapng_debug("pcapng_write_section_header_block: Total len %u", bh.block_total_length);
2866 /* write block header */
2867 bh.block_type = BLOCK_TYPE_SHB;
2869 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
2871 wdh->bytes_dumped += sizeof bh;
2873 /* write block fixed content */
2874 shb.magic = 0x1A2B3C4D;
2875 shb.version_major = 1;
2876 shb.version_minor = 0;
2878 wtapng_mandatory_section_t* section_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(wdh_shb);
2879 shb.section_length = section_data->section_length;
2881 shb.section_length = -1;
2884 if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
2886 wdh->bytes_dumped += sizeof shb;
2889 pcapng_write_block_t block_data;
2891 if (block_size.size > 0) {
2893 block_data.wdh = wdh;
2894 block_data.err = err;
2895 block_data.success = TRUE;
2896 wtap_optionblock_foreach_option(wdh_shb, write_wtap_shb_block, &block_data);
2898 if (!block_data.success)
2901 /* Write end of options */
2902 option_hdr.type = OPT_EOFOPT;
2903 option_hdr.value_length = 0;
2904 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2906 wdh->bytes_dumped += 4;
2910 /* write block footer */
2911 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
2912 sizeof bh.block_total_length, err))
2914 wdh->bytes_dumped += sizeof bh.block_total_length;
2920 pcapng_write_enhanced_packet_block(wtap_dumper *wdh,
2921 const struct wtap_pkthdr *phdr,
2922 const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err)
2924 pcapng_block_header_t bh;
2925 pcapng_enhanced_packet_block_t epb;
2927 const guint32 zero_pad = 0;
2930 gboolean have_options = FALSE;
2931 guint32 options_total_length = 0;
2932 struct option option_hdr;
2933 guint32 comment_len = 0, comment_pad_len = 0;
2934 wtap_optionblock_t int_data;
2935 wtapng_if_descr_mandatory_t *int_data_mand;
2937 /* Don't write anything we're not willing to read. */
2938 if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
2939 *err = WTAP_ERR_PACKET_TOO_LARGE;
2943 phdr_len = (guint32)pcap_get_phdr_size(phdr->pkt_encap, pseudo_header);
2944 if ((phdr_len + phdr->caplen) % 4) {
2945 pad_len = 4 - ((phdr_len + phdr->caplen) % 4);
2950 /* Check if we should write comment option */
2951 if (phdr->opt_comment) {
2952 have_options = TRUE;
2953 comment_len = (guint32)strlen(phdr->opt_comment) & 0xffff;
2954 if ((comment_len % 4)) {
2955 comment_pad_len = 4 - (comment_len % 4);
2957 comment_pad_len = 0;
2959 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
2961 if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
2962 have_options = TRUE;
2963 options_total_length = options_total_length + 8;
2966 /* End-of options tag */
2967 options_total_length += 4;
2970 /* write (enhanced) packet block header */
2971 bh.block_type = BLOCK_TYPE_EPB;
2972 bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + phdr->caplen + pad_len + options_total_length + 4;
2974 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
2976 wdh->bytes_dumped += sizeof bh;
2978 /* write block fixed content */
2979 if (phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
2980 epb.interface_id = phdr->interface_id;
2983 * XXX - we should support writing WTAP_ENCAP_PER_PACKET
2984 * data to pcap-NG files even if we *don't* have interface
2987 epb.interface_id = 0;
2990 * Split the 64-bit timestamp into two 32-bit pieces, using
2991 * the time stamp resolution for the interface.
2993 if (epb.interface_id >= wdh->interface_data->len) {
2995 * Our caller is doing something bad.
2997 *err = WTAP_ERR_INTERNAL;
3000 int_data = g_array_index(wdh->interface_data, wtap_optionblock_t,
3002 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
3003 ts = ((guint64)phdr->ts.secs) * int_data_mand->time_units_per_second +
3004 (((guint64)phdr->ts.nsecs) * int_data_mand->time_units_per_second) / 1000000000;
3005 epb.timestamp_high = (guint32)(ts >> 32);
3006 epb.timestamp_low = (guint32)ts;
3007 epb.captured_len = phdr->caplen + phdr_len;
3008 epb.packet_len = phdr->len + phdr_len;
3010 if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
3012 wdh->bytes_dumped += sizeof epb;
3014 /* write pseudo header */
3015 if (!pcap_write_phdr(wdh, phdr->pkt_encap, pseudo_header, err)) {
3018 wdh->bytes_dumped += phdr_len;
3020 /* write packet data */
3021 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
3023 wdh->bytes_dumped += phdr->caplen;
3025 /* write padding (if any) */
3027 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3029 wdh->bytes_dumped += pad_len;
3032 /* XXX - write (optional) block options */
3033 /* options defined in Section 2.5 (Options)
3034 * Name Code Length Description
3035 * opt_comment 1 variable A UTF-8 string containing a comment that is associated to the current block.
3037 * Enhanced Packet Block options
3038 * epb_flags 2 4 A flags word containing link-layer information. A complete specification of
3039 * the allowed flags can be found in Appendix A (Packet Block Flags Word).
3040 * epb_hash 3 variable This option contains a hash of the packet. The first byte specifies the hashing algorithm,
3041 * while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
3042 * and hence from the value in the first bit. The hashing algorithm can be: 2s complement
3043 * (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
3044 * MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
3045 * The hash covers only the packet, not the header added by the capture driver:
3046 * this gives the possibility to calculate it inside the network card.
3047 * The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
3048 * data acquisition system and the capture library.
3049 * epb_dropcount 4 8 A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
3050 * between this packet and the preceding one.
3051 * opt_endofopt 0 0 It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
3053 if (phdr->opt_comment) {
3054 option_hdr.type = OPT_COMMENT;
3055 option_hdr.value_length = comment_len;
3056 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3058 wdh->bytes_dumped += 4;
3060 /* Write the comments string */
3061 pcapng_debug("pcapng_write_enhanced_packet_block, comment:'%s' comment_len %u comment_pad_len %u" , phdr->opt_comment, comment_len, comment_pad_len);
3062 if (!wtap_dump_file_write(wdh, phdr->opt_comment, comment_len, err))
3064 wdh->bytes_dumped += comment_len;
3066 /* write padding (if any) */
3067 if (comment_pad_len != 0) {
3068 if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
3070 wdh->bytes_dumped += comment_pad_len;
3073 pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
3077 if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
3078 option_hdr.type = OPT_EPB_FLAGS;
3079 option_hdr.value_length = 4;
3080 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3082 wdh->bytes_dumped += 4;
3083 if (!wtap_dump_file_write(wdh, &phdr->pack_flags, 4, err))
3085 wdh->bytes_dumped += 4;
3086 pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options packet flags: %x", phdr->pack_flags);
3088 /* Write end of options if we have options */
3090 if (!wtap_dump_file_write(wdh, &zero_pad, 4, err))
3092 wdh->bytes_dumped += 4;
3095 /* write block footer */
3096 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3097 sizeof bh.block_total_length, err))
3099 wdh->bytes_dumped += sizeof bh.block_total_length;
3105 pcapng_write_sysdig_event_block(wtap_dumper *wdh,
3106 const struct wtap_pkthdr *phdr,
3107 const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err)
3109 pcapng_block_header_t bh;
3110 const guint32 zero_pad = 0;
3114 gboolean have_options = FALSE;
3115 struct option option_hdr;
3116 guint32 comment_len = 0, comment_pad_len = 0;
3118 guint32 options_total_length = 0;
3126 /* Don't write anything we're not willing to read. */
3127 if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
3128 *err = WTAP_ERR_PACKET_TOO_LARGE;
3132 phdr_len = (guint32)pcap_get_phdr_size(phdr->pkt_encap, pseudo_header);
3133 if ((phdr_len + phdr->caplen) % 4) {
3134 pad_len = 4 - ((phdr_len + phdr->caplen) % 4);
3140 /* Check if we should write comment option */
3141 if (phdr->opt_comment) {
3142 have_options = TRUE;
3143 comment_len = (guint32)strlen(phdr->opt_comment) & 0xffff;
3144 if ((comment_len % 4)) {
3145 comment_pad_len = 4 - (comment_len % 4);
3147 comment_pad_len = 0;
3149 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3152 /* End-of options tag */
3153 options_total_length += 4;
3157 /* write sysdig event block header */
3158 bh.block_type = BLOCK_TYPE_SYSDIG_EVENT;
3159 bh.block_total_length = (guint32)sizeof(bh) + SYSDIG_EVENT_HEADER_SIZE + phdr_len + phdr->caplen + pad_len + options_total_length + 4;
3161 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3163 wdh->bytes_dumped += sizeof bh;
3165 /* Sysdig is always LE? */
3166 cpu_id = GUINT16_TO_LE(pseudo_header->sysdig_event.cpu_id);
3167 hdr_ts = (((guint64)phdr->ts.secs) * 1000000000) + phdr->ts.nsecs;
3168 ts = GUINT64_TO_LE(hdr_ts);
3169 thread_id = GUINT64_TO_LE(pseudo_header->sysdig_event.thread_id);
3170 event_len = GUINT32_TO_LE(pseudo_header->sysdig_event.event_len);
3171 event_type = GUINT16_TO_LE(pseudo_header->sysdig_event.event_type);
3173 if (!wtap_dump_file_write(wdh, &cpu_id, sizeof cpu_id, err))
3175 wdh->bytes_dumped += sizeof cpu_id;
3177 if (!wtap_dump_file_write(wdh, &ts, sizeof ts, err))
3179 wdh->bytes_dumped += sizeof ts;
3181 if (!wtap_dump_file_write(wdh, &thread_id, sizeof thread_id, err))
3183 wdh->bytes_dumped += sizeof thread_id;
3185 if (!wtap_dump_file_write(wdh, &event_len, sizeof event_len, err))
3187 wdh->bytes_dumped += sizeof event_len;
3189 if (!wtap_dump_file_write(wdh, &event_type, sizeof event_type, err))
3191 wdh->bytes_dumped += sizeof event_type;
3193 /* write event data */
3194 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
3196 wdh->bytes_dumped += phdr->caplen;
3198 /* write padding (if any) */
3200 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3202 wdh->bytes_dumped += pad_len;
3205 /* XXX Write comment? */
3207 /* write block footer */
3208 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3209 sizeof bh.block_total_length, err))
3217 #define NRES_REC_MAX_SIZE ((WTAP_MAX_PACKET_SIZE * 4) + 16)
3219 pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
3221 pcapng_block_header_t bh;
3222 pcapng_name_resolution_block_t nrb;
3227 guint32 tot_rec_len;
3228 hashipv4_t *ipv4_hash_list_entry;
3229 hashipv6_t *ipv6_hash_list_entry;
3232 if ((!wdh->addrinfo_lists) || ((!wdh->addrinfo_lists->ipv4_addr_list)&&(!wdh->addrinfo_lists->ipv6_addr_list))) {
3236 rec_off = 8; /* block type + block total length */
3237 bh.block_type = BLOCK_TYPE_NRB;
3238 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
3239 rec_data = (guint8 *)g_malloc(NRES_REC_MAX_SIZE);
3241 if (wdh->addrinfo_lists->ipv4_addr_list){
3243 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3244 while(ipv4_hash_list_entry != NULL){
3246 nrb.record_type = NRES_IP4RECORD;
3247 hostnamelen = strlen(ipv4_hash_list_entry->name);
3248 if (hostnamelen > (G_MAXUINT16 - 4) - 1) {
3250 * This won't fit in the largest possible NRB record;
3254 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3257 namelen = (guint16)(hostnamelen + 1);
3258 nrb.record_len = 4 + namelen;
3259 /* 2 bytes record type, 2 bytes length field */
3260 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3262 if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE){
3264 * This record would overflow our maximum size for Name
3265 * Resolution Blocks; write out all the records we created
3266 * before it, and start a new NRB.
3269 /* First, copy the block header. */
3270 memcpy(rec_data, &bh, sizeof(bh));
3273 memset(rec_data + rec_off, 0, 4);
3276 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
3278 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
3280 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
3284 wdh->bytes_dumped += bh.block_total_length;
3286 /*Start a new NRB */
3287 rec_off = 8; /* block type + block total length */
3288 bh.block_type = BLOCK_TYPE_NRB;
3289 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
3293 bh.block_total_length += tot_rec_len;
3294 memcpy(rec_data + rec_off, &nrb, sizeof(nrb));
3296 memcpy(rec_data + rec_off, &(ipv4_hash_list_entry->addr), 4);
3298 memcpy(rec_data + rec_off, ipv4_hash_list_entry->name, namelen);
3300 memset(rec_data + rec_off, 0, PADDING4(namelen));
3301 rec_off += PADDING4(namelen);
3302 pcapng_debug("NRB: added IPv4 record for %s", ipv4_hash_list_entry->name);
3305 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3307 g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
3308 wdh->addrinfo_lists->ipv4_addr_list = NULL;
3311 if (wdh->addrinfo_lists->ipv6_addr_list){
3313 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3314 while(ipv6_hash_list_entry != NULL){
3316 nrb.record_type = NRES_IP6RECORD;
3317 hostnamelen = strlen(ipv6_hash_list_entry->name);
3318 if (hostnamelen > (G_MAXUINT16 - 16) - 1) {
3320 * This won't fit in the largest possible NRB record;
3324 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3327 namelen = (guint16)(hostnamelen + 1);
3328 nrb.record_len = 16 + namelen; /* 16 bytes IPv6 address length */
3329 /* 2 bytes record type, 2 bytes length field */
3330 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3332 if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE){
3334 * This record would overflow our maximum size for Name
3335 * Resolution Blocks; write out all the records we created
3336 * before it, and start a new NRB.
3339 /* First, copy the block header. */
3340 memcpy(rec_data, &bh, sizeof(bh));
3343 memset(rec_data + rec_off, 0, 4);
3346 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
3348 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
3350 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
3354 wdh->bytes_dumped += bh.block_total_length;
3356 /*Start a new NRB */
3357 rec_off = 8; /* block type + block total length */
3358 bh.block_type = BLOCK_TYPE_NRB;
3359 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
3363 bh.block_total_length += tot_rec_len;
3364 memcpy(rec_data + rec_off, &nrb, sizeof(nrb));
3366 memcpy(rec_data + rec_off, &(ipv6_hash_list_entry->addr), 16);
3368 memcpy(rec_data + rec_off, ipv6_hash_list_entry->name, namelen);
3370 memset(rec_data + rec_off, 0, PADDING4(namelen));
3371 rec_off += PADDING4(namelen);
3372 pcapng_debug("NRB: added IPv6 record for %s", ipv6_hash_list_entry->name);
3375 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3377 g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
3378 wdh->addrinfo_lists->ipv6_addr_list = NULL;
3381 /* add options, if any */
3382 if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
3383 gboolean have_options = FALSE;
3384 guint32 options_total_length = 0;
3385 struct option option_hdr;
3386 guint32 comment_len = 0, comment_pad_len = 0;
3387 wtap_optionblock_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_optionblock_t, 0);
3388 guint32 prev_rec_off = rec_off;
3391 /* get lengths first to make sure we can fit this into the block */
3392 wtap_optionblock_get_option_string(nrb_hdr, OPT_COMMENT, &opt_comment);
3394 have_options = TRUE;
3395 comment_len = (guint32)strlen(opt_comment) & 0xffff;
3396 if ((comment_len % 4)) {
3397 comment_pad_len = 4 - (comment_len % 4);
3399 comment_pad_len = 0;
3401 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3405 /* End-of options tag */
3406 options_total_length += 4;
3408 if (rec_off + options_total_length > NRES_REC_MAX_SIZE) {
3410 * This record would overflow our maximum size for Name
3411 * Resolution Blocks; write out all the records we created
3412 * before it, and start a new NRB.
3415 /* First, copy the block header. */
3416 memcpy(rec_data, &bh, sizeof(bh));
3419 memset(rec_data + rec_off, 0, 4);
3422 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
3424 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
3426 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
3430 wdh->bytes_dumped += bh.block_total_length;
3432 /*Start a new NRB */
3433 prev_rec_off = rec_off = 8; /* block type + block total length */
3434 bh.block_type = BLOCK_TYPE_NRB;
3435 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
3438 bh.block_total_length += options_total_length;
3440 if (comment_len > 0) {
3441 option_hdr.type = OPT_COMMENT;
3442 option_hdr.value_length = comment_len;
3444 memcpy(rec_data + rec_off, &option_hdr, sizeof(option_hdr));
3445 rec_off += (guint32)sizeof(option_hdr);
3447 /* Write the comments string */
3448 memcpy(rec_data + rec_off, opt_comment, comment_len);
3449 rec_off += comment_len;
3450 memset(rec_data + rec_off, 0, comment_pad_len);
3451 rec_off += comment_pad_len;
3453 pcapng_debug("pcapng_write_name_resolution_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
3458 /* Write end of options */
3459 memset(rec_data + rec_off, 0, 4);
3463 g_assert(options_total_length == rec_off - prev_rec_off);
3467 /* We know the total length now; copy the block header. */
3468 memcpy(rec_data, &bh, sizeof(bh));
3471 memset(rec_data + rec_off, 0, 4);
3474 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
3476 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
3478 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
3484 wdh->bytes_dumped += bh.block_total_length;
3488 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)
3490 pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data;
3496 if (option != NULL) {
3497 size = pcapng_compute_option_string_size(option->stringval);
3500 case OPT_ISB_STARTTIME:
3501 case OPT_ISB_ENDTIME:
3502 if ((option != NULL) && (option->uint64val != 0)) {
3506 case OPT_ISB_IFRECV:
3507 case OPT_ISB_IFDROP:
3508 case OPT_ISB_FILTERACCEPT:
3509 case OPT_ISB_OSDROP:
3510 case OPT_ISB_USRDELIV:
3511 if ((option != NULL) && (option->uint64val != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))) {
3516 /* Unknown options - size by datatype? */
3520 block_size->size += size;
3521 /* Add bytes for option header if option should be written */
3523 /* Add optional padding to 32 bits */
3524 if ((block_size->size & 0x03) != 0)
3526 block_size->size += 4 - (block_size->size & 0x03);
3528 block_size->size += 4;
3532 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)
3534 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
3535 struct pcapng_option_header option_hdr;
3537 /* Don't continue if there has been an error */
3538 if (!write_block->success)
3544 if ((option != NULL) && (option->stringval != NULL)) {
3545 if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) {
3546 write_block->success = FALSE;
3551 case OPT_ISB_STARTTIME:
3552 case OPT_ISB_ENDTIME:
3553 if ((option != NULL) && (option->uint64val != 0)) {
3556 option_hdr.type = option_id;
3557 option_hdr.value_length = 8;
3558 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3559 write_block->success = FALSE;
3562 write_block->wdh->bytes_dumped += 4;
3564 high = (guint32)(option->uint64val >> 32);
3565 low = (guint32)(option->uint64val >> 0);
3566 if (!wtap_dump_file_write(write_block->wdh, &high, sizeof(guint32), write_block->err)) {
3567 write_block->success = FALSE;
3570 write_block->wdh->bytes_dumped += 4;
3571 if (!wtap_dump_file_write(write_block->wdh, &low, sizeof(guint32), write_block->err)) {
3572 write_block->success = FALSE;
3575 write_block->wdh->bytes_dumped += 4;
3578 case OPT_ISB_IFRECV:
3579 case OPT_ISB_IFDROP:
3580 case OPT_ISB_FILTERACCEPT:
3581 case OPT_ISB_OSDROP:
3582 case OPT_ISB_USRDELIV:
3583 if ((option != NULL) && (option->uint64val != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))) {
3584 option_hdr.type = option_id;
3585 option_hdr.value_length = 8;
3586 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3587 write_block->success = FALSE;
3590 write_block->wdh->bytes_dumped += 4;
3592 if (!wtap_dump_file_write(write_block->wdh, &option->uint64val, sizeof(guint64), write_block->err)) {
3593 write_block->success = FALSE;
3596 write_block->wdh->bytes_dumped += 8;
3600 /* Unknown options - write by datatype? */
3606 pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_optionblock_t if_stats, int *err)
3608 pcapng_block_header_t bh;
3609 pcapng_interface_statistics_block_t isb;
3610 pcapng_optionblock_size_t block_size;
3611 pcapng_write_block_t block_data;
3612 struct pcapng_option_header option_hdr;
3613 wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats);
3615 pcapng_debug("pcapng_write_interface_statistics_block");
3617 /* Compute block size */
3618 block_size.size = 0;
3619 wtap_optionblock_foreach_option(if_stats, compute_isb_option_size, &block_size);
3621 if (block_size.size > 0) {
3622 /* End-of-options tag */
3623 block_size.size += 4;
3626 /* write block header */
3627 bh.block_type = BLOCK_TYPE_ISB;
3628 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(isb) + block_size.size + 4);
3629 pcapng_debug("pcapng_write_interface_statistics_block: Total len %u", bh.block_total_length);
3631 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3633 wdh->bytes_dumped += sizeof bh;
3635 /* write block fixed content */
3636 isb.interface_id = mand_data->interface_id;
3637 isb.timestamp_high = mand_data->ts_high;
3638 isb.timestamp_low = mand_data->ts_low;
3640 if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
3642 wdh->bytes_dumped += sizeof isb;
3645 if (block_size.size > 0) {
3646 block_data.wdh = wdh;
3647 block_data.err = err;
3648 block_data.success = TRUE;
3649 wtap_optionblock_foreach_option(if_stats, write_wtap_isb_block, &block_data);
3651 if (!block_data.success)
3654 /* Write end of options */
3655 option_hdr.type = OPT_EOFOPT;
3656 option_hdr.value_length = 0;
3657 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3659 wdh->bytes_dumped += 4;
3662 /* write block footer */
3663 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3664 sizeof bh.block_total_length, err))
3666 wdh->bytes_dumped += sizeof bh.block_total_length;
3670 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)
3672 pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data;
3681 if (option != NULL) {
3682 size = pcapng_compute_option_string_size(option->stringval);
3686 if ((option != NULL) && (option->uint64val != 0)) {
3690 case OPT_IDB_TSRESOL:
3691 if ((option != NULL) && (option->uint8val != 0)) {
3695 case OPT_IDB_FILTER:
3696 if (option != NULL) {
3697 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)option->customval.data;
3699 if ((filter != NULL) && (filter->if_filter_str != NULL)) {
3700 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
3702 pad = 4 - (size % 4);
3711 case OPT_IDB_FCSLEN:
3712 /* XXX - Not currently writing value */
3715 /* Unknown options - size by datatype? */
3719 block_size->size += size;
3720 /* Add bytes for option header if option should be written */
3722 /* Add optional padding to 32 bits */
3723 if ((block_size->size & 0x03) != 0)
3725 block_size->size += 4 - (block_size->size & 0x03);
3727 block_size->size += 4;
3731 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)
3733 pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
3734 struct pcapng_option_header option_hdr;
3735 const guint32 zero_pad = 0;
3743 if ((option != NULL) && (option->stringval != NULL)) {
3744 if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) {
3745 write_block->success = FALSE;
3751 if ((option != NULL) && (option->uint64val != 0)) {
3752 option_hdr.type = option_id;
3753 option_hdr.value_length = 8;
3754 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3755 write_block->success = FALSE;
3758 write_block->wdh->bytes_dumped += 4;
3760 if (!wtap_dump_file_write(write_block->wdh, &option->uint64val, sizeof(guint64), write_block->err)) {
3761 write_block->success = FALSE;
3764 write_block->wdh->bytes_dumped += 8;
3767 case OPT_IDB_TSRESOL:
3768 if ((option != NULL) && (option->uint8val != 0)) {
3769 option_hdr.type = option_id;
3770 option_hdr.value_length = 1;
3771 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3772 write_block->success = FALSE;
3775 write_block->wdh->bytes_dumped += 4;
3777 if (!wtap_dump_file_write(write_block->wdh, &option->uint8val, 1, write_block->err)) {
3778 write_block->success = FALSE;
3781 write_block->wdh->bytes_dumped += 1;
3783 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 3, write_block->err)) {
3784 write_block->success = FALSE;
3787 write_block->wdh->bytes_dumped += 3;
3790 case OPT_IDB_FILTER:
3791 if (option != NULL) {
3792 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)option->customval.data;
3794 if ((filter != NULL) && (filter->if_filter_str != NULL)) {
3795 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
3797 pad = 4 - (size % 4);
3802 option_hdr.type = option_id;
3803 option_hdr.value_length = size;
3804 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3805 write_block->success = FALSE;
3808 write_block->wdh->bytes_dumped += 4;
3810 /* Write the zero indicating libpcap filter variant */
3811 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 1, write_block->err)) {
3812 write_block->success = FALSE;
3815 write_block->wdh->bytes_dumped += 1;
3817 /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
3818 if (!wtap_dump_file_write(write_block->wdh, filter->if_filter_str, size-1, write_block->err)) {
3819 write_block->success = FALSE;
3822 write_block->wdh->bytes_dumped += size - 1;
3824 /* write padding (if any) */
3826 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, pad, write_block->err)) {
3827 write_block->success = FALSE;
3830 write_block->wdh->bytes_dumped += pad;
3836 case OPT_IDB_FCSLEN:
3837 /* XXX - Not currently writing value */
3840 /* Unknown options - size by datatype? */
3846 pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_optionblock_t int_data, int *err)
3848 pcapng_block_header_t bh;
3849 pcapng_interface_description_block_t idb;
3850 pcapng_optionblock_size_t block_size;
3851 pcapng_write_block_t block_data;
3852 struct pcapng_option_header option_hdr;
3853 wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
3855 pcapng_debug("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d",
3856 mand_data->link_type,
3857 wtap_encap_string(wtap_pcap_encap_to_wtap_encap(mand_data->link_type)),
3858 mand_data->snap_len);
3860 if (mand_data->link_type == (guint16)-1) {
3861 *err = WTAP_ERR_UNWRITABLE_ENCAP;
3865 /* Compute block size */
3866 block_size.size = 0;
3867 wtap_optionblock_foreach_option(int_data, compute_idb_option_size, &block_size);
3869 if (block_size.size > 0) {
3870 /* End-of-options tag */
3871 block_size.size += 4;
3874 /* write block header */
3875 bh.block_type = BLOCK_TYPE_IDB;
3876 bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + block_size.size + 4);
3877 pcapng_debug("pcapng_write_if_descr_block: Total len %u", bh.block_total_length);
3879 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3881 wdh->bytes_dumped += sizeof bh;
3883 /* write block fixed content */
3884 idb.linktype = mand_data->link_type;
3886 idb.snaplen = mand_data->snap_len;
3888 if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
3890 wdh->bytes_dumped += sizeof idb;
3892 if (block_size.size > 0) {
3894 block_data.wdh = wdh;
3895 block_data.err = err;
3896 block_data.success = TRUE;
3897 wtap_optionblock_foreach_option(int_data, write_wtap_idb_block, &block_data);
3899 if (!block_data.success)
3902 /* Write end of options */
3903 option_hdr.type = OPT_EOFOPT;
3904 option_hdr.value_length = 0;
3905 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3907 wdh->bytes_dumped += 4;
3910 /* write block footer */
3911 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3912 sizeof bh.block_total_length, err))
3915 wdh->bytes_dumped += sizeof bh.block_total_length;
3919 static gboolean pcapng_dump(wtap_dumper *wdh,
3920 const struct wtap_pkthdr *phdr,
3921 const guint8 *pd, int *err, gchar **err_info _U_)
3923 const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
3925 block_handler *handler;
3928 pcapng_debug("pcapng_dump: encap = %d (%s)",
3930 wtap_encap_string(phdr->pkt_encap));
3932 switch (phdr->rec_type) {
3934 case REC_TYPE_PACKET:
3935 if (!pcapng_write_enhanced_packet_block(wdh, phdr, pseudo_header, pd, err)) {
3940 case REC_TYPE_FT_SPECIFIC_EVENT:
3941 case REC_TYPE_FT_SPECIFIC_REPORT:
3944 * Do we have a handler for this block type?
3946 if (block_handlers != NULL &&
3947 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
3948 GUINT_TO_POINTER(pseudo_header->ftsrec.record_type))) != NULL) {
3949 /* Yes. Call it to write out this record. */
3950 if (!handler->writer(wdh, phdr, pd, err))
3956 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
3961 case REC_TYPE_SYSCALL:
3962 if (!pcapng_write_sysdig_event_block(wdh, phdr, pseudo_header, pd, err)) {
3968 /* We don't support writing this record type. */
3969 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
3977 /* Finish writing to a dump file.
3978 Returns TRUE on success, FALSE on failure. */
3979 static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err)
3983 /* Flush any hostname resolution info we may have */
3984 pcapng_write_name_resolution_block(wdh, err);
3986 for (i = 0; i < wdh->interface_data->len; i++) {
3988 /* Get the interface description */
3989 wtap_optionblock_t int_data;
3990 wtapng_if_descr_mandatory_t *int_data_mand;
3992 int_data = g_array_index(wdh->interface_data, wtap_optionblock_t, i);
3993 int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
3995 for (j = 0; j < int_data_mand->num_stat_entries; j++) {
3996 wtap_optionblock_t if_stats;
3998 if_stats = g_array_index(int_data_mand->interface_statistics, wtap_optionblock_t, j);
3999 pcapng_debug("pcapng_dump_finish: write ISB for interface %u", ((wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats))->interface_id);
4000 if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) {
4006 pcapng_debug("pcapng_dump_finish");
4011 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
4014 pcapng_dump_open(wtap_dumper *wdh, int *err)
4018 pcapng_debug("pcapng_dump_open");
4019 /* This is a pcapng file */
4020 wdh->subtype_write = pcapng_dump;
4021 wdh->subtype_finish = pcapng_dump_finish;
4023 if (wdh->interface_data->len == 0) {
4024 pcapng_debug("There are no interfaces. Can't handle that...");
4025 *err = WTAP_ERR_INTERNAL;
4029 /* write the section header block */
4030 if (!pcapng_write_section_header_block(wdh, err)) {
4033 pcapng_debug("pcapng_dump_open: wrote section header block.");
4035 /* Write the Interface description blocks */
4036 pcapng_debug("pcapng_dump_open: Number of IDB:s to write (number of interfaces) %u",
4037 wdh->interface_data->len);
4039 for (i = 0; i < wdh->interface_data->len; i++) {
4041 /* Get the interface description */
4042 wtap_optionblock_t idb;
4044 idb = g_array_index(wdh->interface_data, wtap_optionblock_t, i);
4046 if (!pcapng_write_if_descr_block(wdh, idb, err)) {
4056 /* Returns 0 if we could write the specified encapsulation type,
4057 an error indication otherwise. */
4058 int pcapng_dump_can_write_encap(int wtap_encap)
4060 pcapng_debug("pcapng_dump_can_write_encap: encap = %d (%s)",
4062 wtap_encap_string(wtap_encap));
4064 /* Per-packet encapsulation is supported. */
4065 if (wtap_encap == WTAP_ENCAP_PER_PACKET)
4068 /* Make sure we can figure out this DLT type */
4069 if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
4070 return WTAP_ERR_UNWRITABLE_ENCAP;
4076 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4081 * indent-tabs-mode: nil
4084 * vi: set shiftwidth=4 tabstop=8 expandtab:
4085 * :indentSize=4:tabSize=8:noTabs=true: