6 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
8 * File format support for pcap-ng file format
9 * Copyright (c) 2007 by Ulf Lamping <ulf.lamping@web.de>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 /* File format reference:
27 * http://www.winpcap.org/ntar/draft/PCAP-DumpFileFormat.html
29 * http://wiki.wireshark.org/Development/PcapNg
40 /* Needed for addrinfo */
41 #ifdef HAVE_SYS_TYPES_H
42 # include <sys/types.h>
45 #ifdef HAVE_SYS_SOCKET_H
46 #include <sys/socket.h>
49 #ifdef HAVE_NETINET_IN_H
50 # include <netinet/in.h>
57 #ifdef HAVE_WINSOCK2_H
58 # include <winsock2.h>
61 #if defined(_WIN32) && defined(INET6)
62 # include <ws2tcpip.h>
66 #include "file_wrappers.h"
69 #include "pcap-common.h"
70 #include "pcap-encap.h"
74 #define pcapng_debug0(str) g_warning(str)
75 #define pcapng_debug1(str,p1) g_warning(str,p1)
76 #define pcapng_debug2(str,p1,p2) g_warning(str,p1,p2)
77 #define pcapng_debug3(str,p1,p2,p3) g_warning(str,p1,p2,p3)
79 #define pcapng_debug0(str)
80 #define pcapng_debug1(str,p1)
81 #define pcapng_debug2(str,p1,p2)
82 #define pcapng_debug3(str,p1,p2,p3)
86 pcapng_read(wtap *wth, int *err, gchar **err_info,
89 pcapng_seek_read(wtap *wth, gint64 seek_off,
90 union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
91 int *err, gchar **err_info);
93 pcapng_close(wtap *wth);
96 /* pcapng: common block header for every block type */
97 typedef struct pcapng_block_header_s {
99 guint32 block_total_length;
100 /* x bytes block_body */
101 /* guint32 block_total_length */
102 } pcapng_block_header_t;
104 /* pcapng: section header block */
105 typedef struct pcapng_section_header_block_s {
106 /* pcapng_block_header_t */
108 guint16 version_major;
109 guint16 version_minor;
110 guint64 section_length; /* might be -1 for unknown */
111 /* ... Options ... */
112 } pcapng_section_header_block_t;
114 /* pcapng: interface description block */
115 typedef struct pcapng_interface_description_block_s {
119 /* ... Options ... */
120 } pcapng_interface_description_block_t;
122 /* pcapng: packet block (obsolete) */
123 typedef struct pcapng_packet_block_s {
124 guint16 interface_id;
126 guint32 timestamp_high;
127 guint32 timestamp_low;
128 guint32 captured_len;
130 /* ... Packet Data ... */
131 /* ... Padding ... */
132 /* ... Options ... */
133 } pcapng_packet_block_t;
135 /* pcapng: enhanced packet block */
136 typedef struct pcapng_enhanced_packet_block_s {
137 guint32 interface_id;
138 guint32 timestamp_high;
139 guint32 timestamp_low;
140 guint32 captured_len;
142 /* ... Packet Data ... */
143 /* ... Padding ... */
144 /* ... Options ... */
145 } pcapng_enhanced_packet_block_t;
147 /* pcapng: simple packet block */
148 typedef struct pcapng_simple_packet_block_s {
150 /* ... Packet Data ... */
151 /* ... Padding ... */
152 } pcapng_simple_packet_block_t;
154 /* pcapng: simple packet block */
155 typedef struct pcapng_name_resolution_block_s {
159 } pcapng_name_resolution_block_t;
161 /* pcapng: interface statistics block */
162 typedef struct pcapng_interface_statistics_block_s {
163 guint32 interface_id;
164 guint32 timestamp_high;
165 guint32 timestamp_low;
166 /* ... Options ... */
167 } pcapng_interface_statistics_block_t;
169 /* pcapng: common option header for every option type */
170 typedef struct pcapng_option_header_s {
172 guint16 option_length;
173 /* ... x bytes Option Body ... */
174 /* ... Padding ... */
175 } pcapng_option_header_t;
178 #define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */
179 #define BLOCK_TYPE_PB 0x00000002 /* Packet Block (obsolete) */
180 #define BLOCK_TYPE_SPB 0x00000003 /* Simple Packet Block */
181 #define BLOCK_TYPE_NRB 0x00000004 /* Name Resolution Block */
182 #define BLOCK_TYPE_ISB 0x00000005 /* Interface Statistics Block */
183 #define BLOCK_TYPE_EPB 0x00000006 /* Enhanced Packet Block */
184 #define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */
188 /* Capture section */
189 typedef struct wtapng_section_s {
191 guint64 section_length;
193 gchar *opt_comment; /* NULL if not available */
194 gchar *shb_hardware; /* NULL if not available */
195 gchar *shb_os; /* NULL if not available */
196 gchar *shb_user_appl; /* NULL if not available */
199 /* Interface Description */
200 typedef struct wtapng_if_descr_s {
205 gchar *opt_comment; /* NULL if not available */
206 gchar *if_name; /* NULL if not available */
207 gchar *if_description;/* NULL if not available */
208 /* XXX: if_IPv4addr */
209 /* XXX: if_IPv6addr */
210 /* XXX: if_MACaddr */
211 /* XXX: if_EUIaddr */
212 guint64 if_speed; /* 0xFFFFFFFF if unknown */
213 guint8 if_tsresol; /* default is 6 for microsecond resolution */
214 gchar *if_filter; /* NULL if not available */
215 gchar *if_os; /* NULL if not available */
216 gint8 if_fcslen; /* -1 if unknown or changes between packets */
217 /* XXX: guint64 if_tsoffset; */
221 typedef struct wtapng_packet_s {
223 guint32 ts_high; /* seconds since 1.1.1970 */
224 guint32 ts_low; /* fraction of seconds, depends on if_tsresol */
225 guint32 cap_len; /* data length in the file */
226 guint32 packet_len; /* data length on the wire */
227 guint32 interface_id; /* identifier of the interface. */
228 guint16 drops_count; /* drops count, only valid for packet block */
229 /* 0xffff if information no available */
231 gchar *opt_comment; /* NULL if not available */
233 guint32 pack_flags; /* XXX - 0 for now (any value for "we don't have it"?) */
236 guint32 pseudo_header_len;
238 /* XXX - put the packet data / pseudo_header here as well? */
242 typedef struct wtapng_simple_packet_s {
244 guint32 cap_len; /* data length in the file */
245 guint32 packet_len; /* data length on the wire */
246 guint32 pseudo_header_len;
248 /* XXX - put the packet data / pseudo_header here as well? */
249 } wtapng_simple_packet_t;
251 /* Name Resolution */
252 typedef struct wtapng_name_res_s {
254 gchar *opt_comment; /* NULL if not available */
258 /* Interface Statistics */
259 typedef struct wtapng_if_stats_s {
261 guint64 interface_id;
265 gchar *opt_comment; /* NULL if not available */
267 /*guint32 isb_starttime_high;*/
268 /*guint32 isb_starttime_low;*/
269 /*guint32 isb_endtime_high;*/
270 /*guint32 isb_endtime_low;*/
273 /*guint64 isb_filteraccept;*/
274 /*guint64 isb_osdrop;*/
275 /*guint64 isb_usrdeliv;*/
279 typedef struct wtapng_block_s {
280 guint32 type; /* block_type as defined by pcapng */
282 wtapng_section_t section;
283 wtapng_if_descr_t if_descr;
284 wtapng_packet_t packet;
285 wtapng_simple_packet_t simple_packet;
286 wtapng_name_res_t name_res;
287 wtapng_if_stats_t if_stats;
291 * XXX - currently don't know how to handle these!
293 * For one thing, when we're reading a block, they must be
294 * writable, i.e. not const, so that we can read into them,
295 * but, when we're writing a block, they can be const, and,
296 * in fact, they sometimes point to const values.
298 const union wtap_pseudo_header *pseudo_header;
299 struct wtap_pkthdr *packet_header;
300 const guint8 *frame_buffer;
304 typedef struct interface_data_s {
306 guint64 time_units_per_second;
311 gboolean byte_swapped;
312 guint16 version_major;
313 guint16 version_minor;
315 GArray *interface_data;
316 guint number_of_interfaces;
317 wtap_new_ipv4_callback_t add_new_ipv4;
318 wtap_new_ipv6_callback_t add_new_ipv6;
322 pcapng_get_encap(gint id, pcapng_t *pn)
324 interface_data_t int_data;
326 if ((id >= 0) && ((guint)id < pn->number_of_interfaces)) {
327 int_data = g_array_index(pn->interface_data, interface_data_t, id);
328 return int_data.wtap_encap;
330 return WTAP_ERR_UNSUPPORTED_ENCAP;
336 pcapng_read_option(FILE_T fh, pcapng_t *pn, pcapng_option_header_t *oh,
337 char *content, int len, int *err, gchar **err_info)
341 guint64 file_offset64;
344 /* read option header */
345 errno = WTAP_ERR_CANT_READ;
346 bytes_read = file_read(oh, sizeof (*oh), fh);
347 if (bytes_read != sizeof (*oh)) {
348 pcapng_debug0("pcapng_read_option: failed to read option");
349 *err = file_error(fh, err_info);
354 block_read = sizeof (*oh);
355 if(pn->byte_swapped) {
356 oh->option_code = BSWAP16(oh->option_code);
357 oh->option_length = BSWAP16(oh->option_length);
360 /* sanity check: option length */
361 if (oh->option_length > len) {
362 pcapng_debug2("pcapng_read_option: option_length %u larger than buffer (%u)",
363 oh->option_length, len);
367 /* read option content */
368 errno = WTAP_ERR_CANT_READ;
369 bytes_read = file_read(content, oh->option_length, fh);
370 if (bytes_read != oh->option_length) {
371 pcapng_debug1("pcapng_read_option: failed to read content of option %u", oh->option_code);
372 *err = file_error(fh, err_info);
377 block_read += oh->option_length;
379 /* jump over potential padding bytes at end of option */
380 if( (oh->option_length % 4) != 0) {
381 file_offset64 = file_seek(fh, 4 - (oh->option_length % 4), SEEK_CUR, err);
382 if (file_offset64 <= 0) {
387 block_read += 4 - (oh->option_length % 4);
395 pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
396 pcapng_block_header_t *bh, pcapng_t *pn,
397 wtapng_block_t *wblock, int *err,
403 pcapng_section_header_block_t shb;
404 pcapng_option_header_t oh;
405 char option_content[100]; /* XXX - size might need to be increased, if we see longer options */
408 /* read block content */
409 errno = WTAP_ERR_CANT_READ;
410 bytes_read = file_read(&shb, sizeof shb, fh);
411 if (bytes_read != sizeof shb) {
412 *err = file_error(fh, err_info);
416 * We're reading this as part of an open,
417 * and this block is too short to be
418 * an SHB, so the file is too short
419 * to be a pcap-ng file.
425 * Otherwise, just report this as an error.
427 *err = WTAP_ERR_SHORT_READ;
431 block_read = bytes_read;
433 /* is the magic number one we expect? */
436 /* this seems pcapng with correct byte order */
437 pn->byte_swapped = FALSE;
438 pn->version_major = shb.version_major;
439 pn->version_minor = shb.version_minor;
441 pcapng_debug3("pcapng_read_section_header_block: SHB (little endian) V%u.%u, len %u",
442 pn->version_major, pn->version_minor, bh->block_total_length);
445 /* this seems pcapng with swapped byte order */
446 pn->byte_swapped = TRUE;
447 pn->version_major = BSWAP16(shb.version_major);
448 pn->version_minor = BSWAP16(shb.version_minor);
450 /* tweak the block length to meet current swapping that we know now */
451 bh->block_total_length = BSWAP32(bh->block_total_length);
453 pcapng_debug3("pcapng_read_section_header_block: SHB (big endian) V%u.%u, len %u",
454 pn->version_major, pn->version_minor, bh->block_total_length);
457 /* Not a "pcapng" magic number we know about. */
459 /* Not a pcap-ng file. */
464 *err = WTAP_ERR_BAD_RECORD;
465 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown byte-order magic number 0x%08x", shb.magic);
469 /* OK, at this point we assume it's a pcap-ng file. */
471 /* we currently only understand SHB V1.0 */
472 if (pn->version_major != 1 || pn->version_minor > 0) {
473 *err = WTAP_ERR_UNSUPPORTED;
474 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown SHB version %u.%u",
475 pn->version_major, pn->version_minor);
479 /* 64bit section_length (currently unused) */
480 if (pn->byte_swapped) {
481 wblock->data.section.section_length = BSWAP64(shb.section_length);
483 wblock->data.section.section_length = shb.section_length;
486 /* Option defaults */
487 wblock->data.section.opt_comment = NULL;
488 wblock->data.section.shb_hardware = NULL;
489 wblock->data.section.shb_os = NULL;
490 wblock->data.section.shb_user_appl = NULL;
493 errno = WTAP_ERR_CANT_READ;
494 to_read = bh->block_total_length
495 - (int)sizeof(pcapng_block_header_t)
496 - (int)sizeof (pcapng_section_header_block_t)
497 - (int)sizeof(bh->block_total_length);
500 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
501 if (bytes_read <= 0) {
502 pcapng_debug0("pcapng_read_section_header_block: failed to read option");
505 block_read += bytes_read;
506 to_read -= bytes_read;
508 /* handle option content */
509 switch(oh.option_code) {
510 case(0): /* opt_endofopt */
512 pcapng_debug1("pcapng_read_section_header_block: %u bytes after opt_endofopt", to_read);
514 /* padding should be ok here, just get out of this */
517 case(1): /* opt_comment */
518 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
519 wblock->data.section.opt_comment = g_strndup(option_content, sizeof(option_content));
520 pcapng_debug1("pcapng_read_section_header_block: opt_comment %s", wblock->data.section.opt_comment);
522 pcapng_debug1("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
525 case(2): /* shb_hardware */
526 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
527 wblock->data.section.shb_hardware = g_strndup(option_content, sizeof(option_content));
528 pcapng_debug1("pcapng_read_section_header_block: shb_hardware %s", wblock->data.section.shb_hardware);
530 pcapng_debug1("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
533 case(3): /* shb_os */
534 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
535 wblock->data.section.shb_os = g_strndup(option_content, sizeof(option_content));
536 pcapng_debug1("pcapng_read_section_header_block: shb_os %s", wblock->data.section.shb_os);
538 pcapng_debug1("pcapng_read_section_header_block: shb_os length %u seems strange", oh.option_length);
541 case(4): /* shb_userappl */
542 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
543 wblock->data.section.shb_user_appl = g_strndup(option_content, sizeof(option_content));
544 pcapng_debug1("pcapng_read_section_header_block: shb_userappl %s", wblock->data.section.shb_user_appl);
546 pcapng_debug1("pcapng_read_section_header_block: shb_userappl length %u seems strange", oh.option_length);
550 pcapng_debug2("pcapng_read_section_header_block: unknown option %u - ignoring %u bytes",
551 oh.option_code, oh.option_length);
555 if (pn->interface_data != NULL) {
556 g_array_free(pn->interface_data, TRUE);
557 pn->interface_data = NULL;
558 *err = WTAP_ERR_BAD_RECORD;
559 *err_info = g_strdup_printf("pcapng: multiple section header blocks not supported.");
562 pn->interface_data = g_array_new(FALSE, FALSE, sizeof(interface_data_t));
563 pn->number_of_interfaces = 0;
569 /* "Interface Description Block" */
571 pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn,
572 wtapng_block_t *wblock, int *err, gchar **err_info)
574 guint64 time_units_per_second;
578 pcapng_interface_description_block_t idb;
579 pcapng_option_header_t oh;
580 interface_data_t int_data;
582 char option_content[100]; /* XXX - size might need to be increased, if we see longer options */
585 time_units_per_second = 1000000; /* default */
586 /* read block content */
587 errno = WTAP_ERR_CANT_READ;
588 bytes_read = file_read(&idb, sizeof idb, fh);
589 if (bytes_read != sizeof idb) {
590 pcapng_debug0("pcapng_read_if_descr_block: failed to read IDB");
591 *err = file_error(fh, err_info);
596 block_read = bytes_read;
598 /* mandatory values */
599 if (pn->byte_swapped) {
600 wblock->data.if_descr.link_type = BSWAP16(idb.linktype);
601 wblock->data.if_descr.snap_len = BSWAP32(idb.snaplen);
603 wblock->data.if_descr.link_type = idb.linktype;
604 wblock->data.if_descr.snap_len = idb.snaplen;
607 pcapng_debug3("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u",
608 wblock->data.if_descr.link_type,
609 wtap_encap_string(wtap_pcap_encap_to_wtap_encap(wblock->data.if_descr.link_type)),
610 wblock->data.if_descr.snap_len);
612 if (wblock->data.if_descr.snap_len > WTAP_MAX_PACKET_SIZE) {
613 /* This is unrealisitic, but text2pcap currently uses 102400.
614 * We do not use this value, maybe we should check the
615 * snap_len of the packets against it. For now, only warn.
617 pcapng_debug1("pcapng_read_if_descr_block: snapshot length %u unrealistic.",
618 wblock->data.if_descr.snap_len);
619 /*wblock->data.if_descr.snap_len = WTAP_MAX_PACKET_SIZE;*/
622 /* Option defaults */
623 wblock->data.if_descr.opt_comment = NULL;
624 wblock->data.if_descr.if_name = NULL;
625 wblock->data.if_descr.if_description = NULL;
626 /* XXX: if_IPv4addr */
627 /* XXX: if_IPv6addr */
628 /* XXX: if_MACaddr */
629 /* XXX: if_EUIaddr */
630 wblock->data.if_descr.if_speed = 0xFFFFFFFF; /* "unknown" */
631 wblock->data.if_descr.if_tsresol = 6; /* default is 6 for microsecond resolution */
632 wblock->data.if_descr.if_filter = NULL;
633 wblock->data.if_descr.if_os = NULL;
634 wblock->data.if_descr.if_fcslen = -1; /* unknown or changes between packets */
635 /* XXX: guint64 if_tsoffset; */
639 errno = WTAP_ERR_CANT_READ;
640 to_read = bh->block_total_length
641 - (int)sizeof(pcapng_block_header_t)
642 - (int)sizeof (pcapng_interface_description_block_t)
643 - (int)sizeof(bh->block_total_length);
644 while (to_read > 0) {
646 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
647 if (bytes_read <= 0) {
648 pcapng_debug0("pcapng_read_if_descr_block: failed to read option");
651 block_read += bytes_read;
652 to_read -= bytes_read;
654 /* handle option content */
655 switch(oh.option_code) {
656 case(0): /* opt_endofopt */
658 pcapng_debug1("pcapng_read_if_descr_block: %u bytes after opt_endofopt", to_read);
660 /* padding should be ok here, just get out of this */
663 case(1): /* opt_comment */
664 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
665 wblock->data.if_descr.opt_comment = g_strndup(option_content, sizeof(option_content));
666 pcapng_debug1("pcapng_read_if_descr_block: opt_comment %s", wblock->data.if_descr.opt_comment);
668 pcapng_debug1("pcapng_read_if_descr_block: opt_comment length %u seems strange", oh.option_length);
671 case(2): /* if_name */
672 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
673 wblock->data.if_descr.if_name = g_strndup(option_content, sizeof(option_content));
674 pcapng_debug1("pcapng_read_if_descr_block: if_name %s", wblock->data.if_descr.if_name);
676 pcapng_debug1("pcapng_read_if_descr_block: if_name length %u seems strange", oh.option_length);
679 case(3): /* if_description */
680 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
681 wblock->data.if_descr.if_description = g_strndup(option_content, sizeof(option_content));
682 pcapng_debug1("pcapng_read_if_descr_block: if_description %s", wblock->data.if_descr.if_description);
684 pcapng_debug1("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
687 case(8): /* if_speed */
688 if(oh.option_length == 8) {
689 /* Don't cast a char[] into a guint64--the
690 * char[] may not be aligned correctly.
692 memcpy(&wblock->data.if_descr.if_speed, option_content, sizeof(guint64));
694 wblock->data.if_descr.if_speed = BSWAP64(wblock->data.if_descr.if_speed);
695 pcapng_debug1("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", wblock->data.if_descr.if_speed);
697 pcapng_debug1("pcapng_read_if_descr_block: if_speed length %u not 8 as expected", oh.option_length);
700 case(9): /* if_tsresol */
701 if (oh.option_length == 1) {
706 wblock->data.if_descr.if_tsresol = option_content[0];
707 if (wblock->data.if_descr.if_tsresol & 0x80) {
712 exponent = (guint8)(wblock->data.if_descr.if_tsresol & 0x7f);
713 if (((base == 2) && (exponent < 64)) || ((base == 10) && (exponent < 20))) {
715 for (i = 0; i < exponent; i++) {
718 time_units_per_second = result;
720 time_units_per_second = G_MAXUINT64;
722 if (time_units_per_second > (((guint64)1) << 32)) {
723 pcapng_debug0("pcapng_open: time conversion might be inaccurate");
725 pcapng_debug1("pcapng_read_if_descr_block: if_tsresol %u", wblock->data.if_descr.if_tsresol);
727 pcapng_debug1("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length);
730 case(11): /* if_filter */
731 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
732 wblock->data.if_descr.if_filter = g_strndup(option_content, sizeof(option_content));
733 pcapng_debug1("pcapng_read_if_descr_block: if_filter %s", wblock->data.if_descr.if_filter);
735 pcapng_debug1("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
738 case(13): /* if_fcslen */
739 if(oh.option_length == 1) {
740 wblock->data.if_descr.if_fcslen = option_content[0];
741 pn->if_fcslen = wblock->data.if_descr.if_fcslen;
742 pcapng_debug1("pcapng_read_if_descr_block: if_fcslen %u", wblock->data.if_descr.if_fcslen);
743 /* XXX - add sanity check */
745 pcapng_debug1("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
749 pcapng_debug2("pcapng_read_if_descr_block: unknown option %u - ignoring %u bytes",
750 oh.option_code, oh.option_length);
754 encap = wtap_pcap_encap_to_wtap_encap(wblock->data.if_descr.link_type);
755 if (*wblock->file_encap == WTAP_ENCAP_UNKNOWN) {
756 *wblock->file_encap = encap;
758 if (*wblock->file_encap != encap) {
759 *wblock->file_encap = WTAP_ENCAP_PER_PACKET;
763 int_data.wtap_encap = encap;
764 int_data.time_units_per_second = time_units_per_second;
765 g_array_append_val(pn->interface_data, int_data);
766 pn->number_of_interfaces++;
772 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)
777 guint64 file_offset64;
778 pcapng_enhanced_packet_block_t epb;
779 pcapng_packet_block_t pb;
780 guint32 block_total_length;
781 pcapng_option_header_t oh;
783 int pseudo_header_len;
784 char option_content[100]; /* XXX - size might need to be increased, if we see longer options */
787 /* "(Enhanced) Packet Block" read fixed part */
788 errno = WTAP_ERR_CANT_READ;
790 bytes_read = file_read(&epb, sizeof epb, fh);
791 if (bytes_read != sizeof epb) {
792 pcapng_debug0("pcapng_read_packet_block: failed to read packet data");
793 *err = file_error(fh, err_info);
796 block_read = bytes_read;
798 if (pn->byte_swapped) {
799 wblock->data.packet.interface_id = BSWAP32(epb.interface_id);
800 wblock->data.packet.drops_count = -1; /* invalid */
801 wblock->data.packet.ts_high = BSWAP32(epb.timestamp_high);
802 wblock->data.packet.ts_low = BSWAP32(epb.timestamp_low);
803 wblock->data.packet.cap_len = BSWAP32(epb.captured_len);
804 wblock->data.packet.packet_len = BSWAP32(epb.packet_len);
806 wblock->data.packet.interface_id = epb.interface_id;
807 wblock->data.packet.drops_count = -1; /* invalid */
808 wblock->data.packet.ts_high = epb.timestamp_high;
809 wblock->data.packet.ts_low = epb.timestamp_low;
810 wblock->data.packet.cap_len = epb.captured_len;
811 wblock->data.packet.packet_len = epb.packet_len;
814 bytes_read = file_read(&pb, sizeof pb, fh);
815 if (bytes_read != sizeof pb) {
816 pcapng_debug0("pcapng_read_packet_block: failed to read packet data");
817 *err = file_error(fh, err_info);
820 block_read = bytes_read;
822 if (pn->byte_swapped) {
823 wblock->data.packet.interface_id = BSWAP16(pb.interface_id);
824 wblock->data.packet.drops_count = BSWAP16(pb.drops_count);
825 wblock->data.packet.ts_high = BSWAP32(pb.timestamp_high);
826 wblock->data.packet.ts_low = BSWAP32(pb.timestamp_low);
827 wblock->data.packet.cap_len = BSWAP32(pb.captured_len);
828 wblock->data.packet.packet_len = BSWAP32(pb.packet_len);
830 wblock->data.packet.interface_id = pb.interface_id;
831 wblock->data.packet.drops_count = pb.drops_count;
832 wblock->data.packet.ts_high = pb.timestamp_high;
833 wblock->data.packet.ts_low = pb.timestamp_low;
834 wblock->data.packet.cap_len = pb.captured_len;
835 wblock->data.packet.packet_len = pb.packet_len;
839 if (wblock->data.packet.cap_len > wblock->data.packet.packet_len) {
840 *err = WTAP_ERR_BAD_RECORD;
841 *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than packet_len %u.",
842 wblock->data.packet.cap_len, wblock->data.packet.packet_len);
845 if (wblock->data.packet.cap_len > WTAP_MAX_PACKET_SIZE) {
846 *err = WTAP_ERR_BAD_RECORD;
847 *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u.",
848 wblock->data.packet.cap_len, WTAP_MAX_PACKET_SIZE);
851 pcapng_debug3("pcapng_read_packet_block: packet data: packet_len %u captured_len %u interface_id %u",
852 wblock->data.packet.packet_len,
853 wblock->data.packet.cap_len,
854 wblock->data.packet.interface_id);
855 if (wblock->data.packet.packet_len > WTAP_MAX_PACKET_SIZE) {
856 *err = WTAP_ERR_BAD_RECORD;
857 *err_info = g_strdup_printf("pcapng_read_packet_block: packet_len %u is larger than WTAP_MAX_PACKET_SIZE %u.",
858 wblock->data.packet.packet_len, WTAP_MAX_PACKET_SIZE);
862 wtap_encap = pcapng_get_encap(wblock->data.packet.interface_id, pn);
863 pcapng_debug3("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.",
865 wtap_encap_string(wtap_encap),
866 pcap_get_phdr_size(wtap_encap, wblock->pseudo_header));
868 memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header));
869 pseudo_header_len = pcap_process_pseudo_header(fh,
872 wblock->data.packet.cap_len,
874 wblock->packet_header,
875 (union wtap_pseudo_header *)wblock->pseudo_header,
878 if (pseudo_header_len < 0) {
881 wblock->data.packet.pseudo_header_len = (guint32)pseudo_header_len;
882 block_read += pseudo_header_len;
883 if (pseudo_header_len != pcap_get_phdr_size(wtap_encap, wblock->pseudo_header)) {
884 pcapng_debug1("pcapng_read_packet_block: Could only read %d bytes for pseudo header.",
888 /* "(Enhanced) Packet Block" read capture data */
889 errno = WTAP_ERR_CANT_READ;
890 bytes_read = file_read((guint8 *) (wblock->frame_buffer), wblock->data.packet.cap_len - pseudo_header_len, fh);
891 if (bytes_read != (int) (wblock->data.packet.cap_len - pseudo_header_len)) {
892 *err = file_error(fh, err_info);
893 pcapng_debug1("pcapng_read_packet_block: couldn't read %u bytes of captured data",
894 wblock->data.packet.cap_len - pseudo_header_len);
896 *err = WTAP_ERR_SHORT_READ;
899 block_read += bytes_read;
901 /* jump over potential padding bytes at end of the packet data */
902 if( (wblock->data.packet.cap_len % 4) != 0) {
903 file_offset64 = file_seek(fh, 4 - (wblock->data.packet.cap_len % 4), SEEK_CUR, err);
904 if (file_offset64 <= 0) {
909 block_read += 4 - (wblock->data.packet.cap_len % 4);
912 /* add padding bytes to "block total length" */
913 /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
914 if (bh->block_total_length % 4) {
915 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
917 block_total_length = bh->block_total_length;
920 /* Option defaults */
921 wblock->data.packet.opt_comment = NULL;
922 wblock->data.packet.drop_count = -1;
923 wblock->data.packet.pack_flags = 0; /* XXX - is 0 ok to signal "not used"? */
925 /* FCS length default */
926 fcslen = pn->if_fcslen;
929 errno = WTAP_ERR_CANT_READ;
930 to_read = block_total_length
931 - (int)sizeof(pcapng_block_header_t)
932 - block_read /* fixed and variable part, including padding */
933 - (int)sizeof(bh->block_total_length);
936 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
937 if (bytes_read <= 0) {
938 pcapng_debug0("pcapng_read_packet_block: failed to read option");
941 block_read += bytes_read;
942 to_read -= bytes_read;
944 /* handle option content */
945 switch(oh.option_code) {
946 case(0): /* opt_endofopt */
948 pcapng_debug1("pcapng_read_packet_block: %u bytes after opt_endofopt", to_read);
950 /* padding should be ok here, just get out of this */
953 case(1): /* opt_comment */
954 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
955 wblock->data.packet.opt_comment = g_strndup(option_content, sizeof(option_content));
956 pcapng_debug1("pcapng_read_packet_block: opt_comment %s", wblock->data.packet.opt_comment);
958 pcapng_debug1("pcapng_read_packet_block: opt_comment length %u seems strange", oh.option_length);
961 case(2): /* pack_flags / epb_flags */
962 if(oh.option_length == 4) {
963 /* Don't cast a char[] into a guint32--the
964 * char[] may not be aligned correctly.
966 memcpy(&wblock->data.packet.pack_flags, option_content, sizeof(guint32));
968 wblock->data.packet.pack_flags = BSWAP32(wblock->data.packet.pack_flags);
969 if (wblock->data.packet.pack_flags & 0x000001E0) {
970 /* The FCS length is present */
971 fcslen = (wblock->data.packet.pack_flags & 0x000001E0) >> 5;
973 pcapng_debug1("pcapng_read_if_descr_block: pack_flags %u (ignored)", wblock->data.packet.pack_flags);
975 pcapng_debug1("pcapng_read_if_descr_block: pack_flags length %u not 4 as expected", oh.option_length);
979 pcapng_debug2("pcapng_read_packet_block: unknown option %u - ignoring %u bytes",
980 oh.option_code, oh.option_length);
984 pcap_read_post_process(WTAP_FILE_PCAPNG, wtap_encap,
985 (union wtap_pseudo_header *)wblock->pseudo_header,
986 (guint8 *) (wblock->frame_buffer),
987 (int) (wblock->data.packet.cap_len - pseudo_header_len),
988 pn->byte_swapped, fcslen);
994 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)
998 guint64 file_offset64;
1000 int pseudo_header_len;
1001 pcapng_simple_packet_block_t spb;
1004 /* "Simple Packet Block" read fixed part */
1005 errno = WTAP_ERR_CANT_READ;
1006 bytes_read = file_read(&spb, sizeof spb, fh);
1007 if (bytes_read != sizeof spb) {
1008 pcapng_debug0("pcapng_read_simple_packet_block: failed to read packet data");
1009 *err = file_error(fh, err_info);
1012 block_read = bytes_read;
1014 if (pn->byte_swapped) {
1015 wblock->data.simple_packet.packet_len = BSWAP32(spb.packet_len);
1017 wblock->data.simple_packet.packet_len = spb.packet_len;
1020 wblock->data.simple_packet.cap_len = bh->block_total_length
1021 - (guint32)sizeof(pcapng_simple_packet_block_t)
1022 - (guint32)sizeof(bh->block_total_length);
1024 if (wblock->data.simple_packet.cap_len > WTAP_MAX_PACKET_SIZE) {
1025 *err = WTAP_ERR_BAD_RECORD;
1026 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u.",
1027 wblock->data.simple_packet.cap_len, WTAP_MAX_PACKET_SIZE);
1030 pcapng_debug1("pcapng_read_simple_packet_block: packet data: packet_len %u",
1031 wblock->data.simple_packet.packet_len);
1032 if (wblock->data.simple_packet.packet_len > WTAP_MAX_PACKET_SIZE) {
1033 *err = WTAP_ERR_BAD_RECORD;
1034 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: packet_len %u is larger than WTAP_MAX_PACKET_SIZE %u.",
1035 wblock->data.simple_packet.packet_len, WTAP_MAX_PACKET_SIZE);
1039 encap = pcapng_get_encap(0, pn);
1040 pcapng_debug1("pcapng_read_simple_packet_block: Need to read pseudo header of size %d",
1041 pcap_get_phdr_size(encap, wblock->pseudo_header));
1043 memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1044 pseudo_header_len = pcap_process_pseudo_header(fh,
1047 wblock->data.simple_packet.cap_len,
1049 wblock->packet_header,
1050 (union wtap_pseudo_header *)wblock->pseudo_header,
1053 if (pseudo_header_len < 0) {
1056 wblock->data.simple_packet.pseudo_header_len = (guint32)pseudo_header_len;
1057 block_read += pseudo_header_len;
1058 if (pseudo_header_len != pcap_get_phdr_size(encap, wblock->pseudo_header)) {
1059 pcapng_debug1("pcapng_read_simple_packet_block: Could only read %d bytes for pseudo header.",
1063 memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1065 /* "Simple Packet Block" read capture data */
1066 errno = WTAP_ERR_CANT_READ;
1067 bytes_read = file_read((guint8 *) (wblock->frame_buffer), wblock->data.simple_packet.cap_len, fh);
1068 if (bytes_read != (int) wblock->data.simple_packet.cap_len) {
1069 *err = file_error(fh, err_info);
1070 pcapng_debug1("pcapng_read_simple_packet_block: couldn't read %u bytes of captured data",
1071 wblock->data.simple_packet.cap_len);
1073 *err = WTAP_ERR_SHORT_READ;
1076 block_read += bytes_read;
1078 /* jump over potential padding bytes at end of the packet data */
1079 if ((wblock->data.simple_packet.cap_len % 4) != 0) {
1080 file_offset64 = file_seek(fh, 4 - (wblock->data.simple_packet.cap_len % 4), SEEK_CUR, err);
1081 if (file_offset64 <= 0) {
1086 block_read += 4 - (wblock->data.simple_packet.cap_len % 4);
1089 pcap_read_post_process(WTAP_FILE_PCAPNG, encap,
1090 (union wtap_pseudo_header *)wblock->pseudo_header,
1091 (guint8 *) (wblock->frame_buffer),
1092 (int) wblock->data.simple_packet.cap_len,
1093 pn->byte_swapped, pn->if_fcslen);
1097 #define NRES_ENDOFRECORD 0
1098 #define NRES_IP4RECORD 1
1099 #define NRES_IP6RECORD 2
1100 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
1101 /* IPv6 + MAXNAMELEN */
1102 #define MAX_NRB_REC_SIZE (16 + 64)
1104 pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock _U_,int *err, gchar **err_info)
1109 guint64 file_offset64;
1110 pcapng_name_resolution_block_t nrb;
1111 guint8 nrb_rec[MAX_NRB_REC_SIZE];
1114 errno = WTAP_ERR_CANT_READ;
1115 to_read = bh->block_total_length
1116 - sizeof(pcapng_block_header_t)
1117 - sizeof(bh->block_total_length);
1119 while (block_read < to_read) {
1120 bytes_read = file_read(&nrb, sizeof nrb, fh);
1121 if (bytes_read != sizeof nrb) {
1122 pcapng_debug0("pcapng_read_name_resolution_block: failed to read record header");
1123 *err = file_error(fh, err_info);
1126 block_read += bytes_read;
1128 if (pn->byte_swapped) {
1129 nrb.record_type = BSWAP16(nrb.record_type);
1130 nrb.record_len = BSWAP16(nrb.record_len);
1133 switch(nrb.record_type) {
1134 case NRES_ENDOFRECORD:
1135 /* There shouldn't be any more data */
1138 case NRES_IP4RECORD:
1139 if (nrb.record_len < 6 || nrb.record_len > MAX_NRB_REC_SIZE || to_read < nrb.record_len) {
1140 pcapng_debug0("pcapng_read_name_resolution_block: bad length or insufficient data for IPv4 record");
1143 bytes_read = file_read(nrb_rec, nrb.record_len, fh);
1144 if (bytes_read != nrb.record_len) {
1145 pcapng_debug0("pcapng_read_name_resolution_block: failed to read IPv4 record data");
1146 *err = file_error(fh, err_info);
1149 block_read += bytes_read;
1151 if (pn->add_new_ipv4) {
1152 memcpy(&v4_addr, nrb_rec, 4);
1153 if (pn->byte_swapped)
1154 v4_addr = BSWAP32(v4_addr);
1155 pn->add_new_ipv4(v4_addr, nrb_rec + 4);
1158 file_offset64 = file_seek(fh, PADDING4(nrb.record_len), SEEK_CUR, err);
1159 if (file_offset64 <= 0) {
1164 block_read += PADDING4(nrb.record_len);
1166 case NRES_IP6RECORD:
1167 if (nrb.record_len < 18 || nrb.record_len > MAX_NRB_REC_SIZE || to_read < nrb.record_len) {
1168 pcapng_debug0("pcapng_read_name_resolution_block: bad length or insufficient data for IPv6 record");
1171 bytes_read = file_read(nrb_rec, nrb.record_len, fh);
1172 if (bytes_read != nrb.record_len) {
1173 pcapng_debug0("pcapng_read_name_resolution_block: failed to read IPv6 record data");
1174 *err = file_error(fh, err_info);
1177 block_read += bytes_read;
1179 if (pn->add_new_ipv6) {
1180 pn->add_new_ipv6(nrb_rec, nrb_rec + 16);
1183 file_offset64 = file_seek(fh, PADDING4(nrb.record_len), SEEK_CUR, err);
1184 if (file_offset64 <= 0) {
1189 block_read += PADDING4(nrb.record_len);
1192 pcapng_debug1("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
1193 file_offset64 = file_seek(fh, nrb.record_len + PADDING4(nrb.record_len), SEEK_CUR, err);
1194 if (file_offset64 <= 0) {
1199 block_read += nrb.record_len + PADDING4(nrb.record_len);
1208 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)
1213 pcapng_interface_statistics_block_t isb;
1214 pcapng_option_header_t oh;
1215 char option_content[100]; /* XXX - size might need to be increased, if we see longer options */
1218 /* "Interface Statistics Block" read fixed part */
1219 errno = WTAP_ERR_CANT_READ;
1220 bytes_read = file_read(&isb, sizeof isb, fh);
1221 if (bytes_read != sizeof isb) {
1222 pcapng_debug0("pcapng_read_interface_statistics_block: failed to read packet data");
1223 *err = file_error(fh, err_info);
1226 block_read = bytes_read;
1228 if(pn->byte_swapped) {
1229 wblock->data.if_stats.interface_id = BSWAP64(isb.interface_id);
1230 wblock->data.if_stats.ts_high = BSWAP32(isb.timestamp_high);
1231 wblock->data.if_stats.ts_low = BSWAP32(isb.timestamp_low);
1233 wblock->data.if_stats.interface_id = isb.interface_id;
1234 wblock->data.if_stats.ts_high = isb.timestamp_high;
1235 wblock->data.if_stats.ts_low = isb.timestamp_low;
1237 pcapng_debug1("pcapng_read_interface_statistics_block: interface_id %" G_GINT64_MODIFIER "u", wblock->data.if_stats.interface_id);
1239 /* Option defaults */
1240 wblock->data.if_stats.opt_comment = NULL;
1241 wblock->data.if_stats.isb_ifrecv = -1;
1242 wblock->data.if_stats.isb_ifdrop = -1;
1245 errno = WTAP_ERR_CANT_READ;
1246 to_read = bh->block_total_length
1247 - sizeof(pcapng_block_header_t)
1248 - block_read /* fixed and variable part, including padding */
1249 - sizeof(bh->block_total_length);
1250 while(to_read > 0) {
1252 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
1253 if (bytes_read <= 0) {
1254 pcapng_debug0("pcapng_read_interface_statistics_block: failed to read option");
1257 block_read += bytes_read;
1258 to_read -= bytes_read;
1260 /* handle option content */
1261 switch(oh.option_code) {
1262 case(0): /* opt_endofopt */
1264 pcapng_debug1("pcapng_read_interface_statistics_block: %u bytes after opt_endofopt", to_read);
1266 /* padding should be ok here, just get out of this */
1269 case(1): /* opt_comment */
1270 if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
1271 wblock->data.if_stats.opt_comment = g_strndup(option_content, sizeof(option_content));
1272 pcapng_debug1("pcapng_read_interface_statistics_block: opt_comment %s", wblock->data.if_stats.opt_comment);
1274 pcapng_debug1("pcapng_read_interface_statistics_block: opt_comment length %u seems strange", oh.option_length);
1277 case(4): /* isb_ifrecv */
1278 if(oh.option_length == 8) {
1279 /* Don't cast a char[] into a guint32--the
1280 * char[] may not be aligned correctly.
1282 memcpy(&wblock->data.if_stats.isb_ifrecv, option_content, sizeof(guint64));
1283 if(pn->byte_swapped)
1284 wblock->data.if_stats.isb_ifrecv = BSWAP64(wblock->data.if_stats.isb_ifrecv);
1285 pcapng_debug1("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_ifrecv);
1287 pcapng_debug1("pcapng_read_interface_statistics_block: isb_ifrecv length %u not 8 as expected", oh.option_length);
1290 case(5): /* isb_ifdrop */
1291 if(oh.option_length == 8) {
1292 /* Don't cast a char[] into a guint32--the
1293 * char[] may not be aligned correctly.
1295 memcpy(&wblock->data.if_stats.isb_ifdrop, option_content, sizeof(guint64));
1296 if(pn->byte_swapped)
1297 wblock->data.if_stats.isb_ifdrop = BSWAP64(wblock->data.if_stats.isb_ifdrop);
1298 pcapng_debug1("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_ifdrop);
1300 pcapng_debug1("pcapng_read_interface_statistics_block: isb_ifdrop length %u not 8 as expected", oh.option_length);
1304 pcapng_debug2("pcapng_read_interface_statistics_block: unknown option %u - ignoring %u bytes",
1305 oh.option_code, oh.option_length);
1314 pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_, wtapng_block_t *wblock _U_,int *err, gchar **err_info _U_)
1317 guint64 file_offset64;
1318 guint32 block_total_length;
1321 /* add padding bytes to "block total length" */
1322 /* (the "block total length" of some example files don't contain any padding bytes!) */
1323 if (bh->block_total_length % 4) {
1324 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1326 block_total_length = bh->block_total_length;
1329 block_read = block_total_length - (guint32)sizeof(pcapng_block_header_t) - (guint32)sizeof(bh->block_total_length);
1331 /* jump over this unknown block */
1332 file_offset64 = file_seek(fh, block_read, SEEK_CUR, err);
1333 if (file_offset64 <= 0) {
1344 pcapng_read_block(FILE_T fh, gboolean first_block, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
1348 pcapng_block_header_t bh;
1349 guint32 block_total_length;
1352 /* Try to read the (next) block header */
1353 errno = WTAP_ERR_CANT_READ;
1354 bytes_read = file_read(&bh, sizeof bh, fh);
1355 if (bytes_read != sizeof bh) {
1356 *err = file_error(fh, err_info);
1357 pcapng_debug3("pcapng_read_block: file_read() returned %d instead of %u, err = %d.", bytes_read, (unsigned int)sizeof bh, *err);
1363 block_read = bytes_read;
1364 if (pn->byte_swapped) {
1365 bh.block_type = BSWAP32(bh.block_type);
1366 bh.block_total_length = BSWAP32(bh.block_total_length);
1369 wblock->type = bh.block_type;
1371 pcapng_debug1("pcapng_read_block: block_type 0x%x", bh.block_type);
1375 * This is being read in by pcapng_open(), so this block
1376 * must be an SHB. If it's not, this is not a pcap-ng
1379 * XXX - check for various forms of Windows <-> UN*X
1380 * mangling, and suggest that the file might be a
1381 * pcap-ng file that was damaged in transit?
1383 if (bh.block_type != BLOCK_TYPE_SHB)
1384 return 0; /* not a pcap-ng file */
1387 switch(bh.block_type) {
1388 case(BLOCK_TYPE_SHB):
1389 bytes_read = pcapng_read_section_header_block(fh, first_block, &bh, pn, wblock, err, err_info);
1391 case(BLOCK_TYPE_IDB):
1392 bytes_read = pcapng_read_if_descr_block(fh, &bh, pn, wblock, err, err_info);
1394 case(BLOCK_TYPE_PB):
1395 bytes_read = pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE);
1397 case(BLOCK_TYPE_SPB):
1398 bytes_read = pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info);
1400 case(BLOCK_TYPE_EPB):
1401 bytes_read = pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE);
1403 case(BLOCK_TYPE_NRB):
1404 bytes_read = pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info);
1406 case(BLOCK_TYPE_ISB):
1407 bytes_read = pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info);
1410 pcapng_debug2("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
1411 bytes_read = pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info);
1414 if (bytes_read <= 0) {
1417 block_read += bytes_read;
1419 /* sanity check: first and second block lengths must match */
1420 errno = WTAP_ERR_CANT_READ;
1421 bytes_read = file_read(&block_total_length, sizeof block_total_length, fh);
1422 if (bytes_read != sizeof block_total_length) {
1423 pcapng_debug0("pcapng_read_block: couldn't read second block length");
1424 *err = file_error(fh, err_info);
1426 *err = WTAP_ERR_SHORT_READ;
1429 block_read += bytes_read;
1431 if (pn->byte_swapped)
1432 block_total_length = BSWAP32(block_total_length);
1434 if (!(block_total_length == bh.block_total_length)) {
1435 *err = WTAP_ERR_BAD_RECORD;
1436 *err_info = g_strdup_printf("pcapng_read_block: total block lengths (first %u and second %u) don't match",
1437 bh.block_total_length, block_total_length);
1445 /* classic wtap: open capture file */
1447 pcapng_open(wtap *wth, int *err, gchar **err_info)
1451 wtapng_block_t wblock;
1454 /* we don't know the byte swapping of the file yet */
1455 pn.byte_swapped = FALSE;
1457 pn.version_major = -1;
1458 pn.version_minor = -1;
1459 pn.interface_data = NULL;
1460 pn.number_of_interfaces = 0;
1462 /* we don't expect any packet blocks yet */
1463 wblock.frame_buffer = NULL;
1464 wblock.pseudo_header = NULL;
1465 wblock.packet_header = NULL;
1466 wblock.file_encap = &wth->file_encap;
1468 pcapng_debug0("pcapng_open: opening file");
1469 /* read first block */
1470 bytes_read = pcapng_read_block(wth->fh, TRUE, &pn, &wblock, err, err_info);
1471 if (bytes_read <= 0) {
1472 pcapng_debug0("pcapng_open: couldn't read first SHB");
1473 *err = file_error(wth->fh, err_info);
1478 wth->data_offset += bytes_read;
1480 /* first block must be a "Section Header Block" */
1481 if (wblock.type != BLOCK_TYPE_SHB) {
1483 * XXX - check for damage from transferring a file
1484 * between Windows and UN*X as text rather than
1487 pcapng_debug1("pcapng_open: first block type %u not SHB", wblock.type);
1491 wth->file_encap = WTAP_ENCAP_UNKNOWN;
1492 wth->snapshot_length = 0;
1493 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
1494 pcapng = (pcapng_t *)g_malloc(sizeof(pcapng_t));
1495 wth->priv = (void *)pcapng;
1497 wth->subtype_read = pcapng_read;
1498 wth->subtype_seek_read = pcapng_seek_read;
1499 wth->subtype_close = pcapng_close;
1500 wth->file_type = WTAP_FILE_PCAPNG;
1506 /* classic wtap: read packet */
1508 pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1510 pcapng_t *pcapng = (pcapng_t *)wth->priv;
1513 wtapng_block_t wblock;
1515 pcapng_debug1("pcapng_read: wth->data_offset is initially %" G_GINT64_MODIFIER "u", wth->data_offset);
1516 *data_offset = wth->data_offset;
1517 pcapng_debug1("pcapng_read: *data_offset is initially set to %" G_GINT64_MODIFIER "u", *data_offset);
1519 /* XXX - This should be done in the packet block reading function and
1520 * should make use of the caplen of the packet.
1522 if (wth->snapshot_length > 0) {
1523 buffer_assure_space(wth->frame_buffer, wth->snapshot_length);
1525 buffer_assure_space(wth->frame_buffer, WTAP_MAX_PACKET_SIZE);
1528 wblock.frame_buffer = buffer_start_ptr(wth->frame_buffer);
1529 wblock.pseudo_header = &wth->pseudo_header;
1530 wblock.packet_header = &wth->phdr;
1531 wblock.file_encap = &wth->file_encap;
1533 pcapng->add_new_ipv4 = wth->add_new_ipv4;
1534 pcapng->add_new_ipv6 = wth->add_new_ipv6;
1536 /* read next block */
1538 bytes_read = pcapng_read_block(wth->fh, FALSE, pcapng, &wblock, err, err_info);
1539 if (bytes_read <= 0) {
1540 wth->data_offset = *data_offset;
1541 pcapng_debug1("pcapng_read: wth->data_offset is finally %" G_GINT64_MODIFIER "u", wth->data_offset);
1542 pcapng_debug0("pcapng_read: couldn't read packet block");
1546 /* block must be a "Packet Block" or an "Enhanced Packet Block" -> otherwise continue */
1547 if (wblock.type == BLOCK_TYPE_PB || wblock.type == BLOCK_TYPE_EPB) {
1551 /* XXX - improve handling of "unknown" blocks */
1552 pcapng_debug1("pcapng_read: block type 0x%x not PB/EPB", wblock.type);
1553 *data_offset += bytes_read;
1554 pcapng_debug1("pcapng_read: *data_offset is updated to %" G_GINT64_MODIFIER "u", *data_offset);
1557 /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
1558 ts = (((guint64)wblock.data.packet.ts_high) << 32) | ((guint64)wblock.data.packet.ts_low);
1560 wth->phdr.caplen = wblock.data.packet.cap_len - wblock.data.packet.pseudo_header_len;
1561 wth->phdr.len = wblock.data.packet.packet_len - wblock.data.packet.pseudo_header_len;
1562 if (wblock.data.packet.interface_id < pcapng->number_of_interfaces) {
1563 interface_data_t int_data;
1564 guint64 time_units_per_second;
1567 id = (gint)wblock.data.packet.interface_id;
1568 int_data = g_array_index(pcapng->interface_data, interface_data_t, id);
1569 time_units_per_second = int_data.time_units_per_second;
1570 wth->phdr.pkt_encap = int_data.wtap_encap;
1571 wth->phdr.ts.secs = (time_t)(ts / time_units_per_second);
1572 wth->phdr.ts.nsecs = (int)(((ts % time_units_per_second) * 1000000000) / time_units_per_second);
1574 wth->phdr.pkt_encap = WTAP_ENCAP_UNKNOWN;
1575 *err = WTAP_ERR_BAD_RECORD;
1576 *err_info = g_strdup_printf("pcapng: interface index %u is not less than interface count %u.",
1577 wblock.data.packet.interface_id, pcapng->number_of_interfaces);
1578 wth->data_offset = *data_offset + bytes_read;
1579 pcapng_debug1("pcapng_read: wth->data_offset is finally %" G_GINT64_MODIFIER "u", wth->data_offset);
1583 /*pcapng_debug2("Read length: %u Packet length: %u", bytes_read, wth->phdr.caplen);*/
1584 wth->data_offset = *data_offset + bytes_read;
1585 pcapng_debug1("pcapng_read: wth->data_offset is finally %" G_GINT64_MODIFIER "u", wth->data_offset);
1591 /* classic wtap: seek to file position and read packet */
1593 pcapng_seek_read(wtap *wth, gint64 seek_off,
1594 union wtap_pseudo_header *pseudo_header, guint8 *pd, int length _U_,
1595 int *err, gchar **err_info)
1597 pcapng_t *pcapng = (pcapng_t *)wth->priv;
1598 guint64 bytes_read64;
1600 wtapng_block_t wblock;
1603 /* seek to the right file position */
1604 bytes_read64 = file_seek(wth->random_fh, seek_off, SEEK_SET, err);
1605 if (bytes_read64 <= 0) {
1606 return FALSE; /* Seek error */
1608 pcapng_debug1("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
1610 wblock.frame_buffer = pd;
1611 wblock.pseudo_header = pseudo_header;
1612 wblock.packet_header = &wth->phdr;
1613 wblock.file_encap = &wth->file_encap;
1615 /* read the block */
1616 bytes_read = pcapng_read_block(wth->random_fh, FALSE, pcapng, &wblock, err, err_info);
1617 if (bytes_read <= 0) {
1618 *err = file_error(wth->random_fh, err_info);
1619 pcapng_debug3("pcapng_seek_read: couldn't read packet block (err=%d, errno=%d, bytes_read=%d).",
1620 *err, errno, bytes_read);
1624 /* block must be a "Packet Block" or an "Enhanced Packet Block" */
1625 if (wblock.type != BLOCK_TYPE_PB && wblock.type != BLOCK_TYPE_EPB) {
1626 pcapng_debug1("pcapng_seek_read: block type %u not PB/EPB", wblock.type);
1634 /* classic wtap: close capture file */
1636 pcapng_close(wtap *wth)
1638 pcapng_t *pcapng = (pcapng_t *)wth->priv;
1640 pcapng_debug0("pcapng_close: closing file");
1641 if (pcapng->interface_data != NULL) {
1642 g_array_free(pcapng->interface_data, TRUE);
1649 GArray *interface_data;
1650 guint number_of_interfaces;
1651 struct addrinfo *addrinfo_list_last;
1655 pcapng_write_section_header_block(wtap_dumper *wdh, wtapng_block_t *wblock, int *err)
1657 pcapng_block_header_t bh;
1658 pcapng_section_header_block_t shb;
1661 /* write block header */
1662 bh.block_type = wblock->type;
1663 bh.block_total_length = sizeof(bh) + sizeof(shb) /* + options */ + 4;
1665 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
1667 wdh->bytes_dumped += sizeof bh;
1669 /* write block fixed content */
1670 /* XXX - get these values from wblock? */
1671 shb.magic = 0x1A2B3C4D;
1672 shb.version_major = 1;
1673 shb.version_minor = 0;
1674 shb.section_length = -1;
1676 if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
1678 wdh->bytes_dumped += sizeof shb;
1680 /* XXX - write (optional) block options */
1682 /* write block footer */
1683 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
1684 sizeof bh.block_total_length, err))
1686 wdh->bytes_dumped += sizeof bh.block_total_length;
1694 pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_block_t *wblock, int *err)
1696 pcapng_block_header_t bh;
1697 pcapng_interface_description_block_t idb;
1700 pcapng_debug3("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d",
1701 wblock->data.if_descr.link_type,
1702 wtap_encap_string(wtap_pcap_encap_to_wtap_encap(wblock->data.if_descr.link_type)),
1703 wblock->data.if_descr.snap_len);
1705 if (wblock->data.if_descr.link_type == (guint16)-1) {
1706 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
1710 /* write block header */
1711 bh.block_type = wblock->type;
1712 bh.block_total_length = sizeof(bh) + sizeof(idb) /* + options */ + 4;
1714 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
1716 wdh->bytes_dumped += sizeof bh;
1718 /* write block fixed content */
1719 idb.linktype = wblock->data.if_descr.link_type;
1721 idb.snaplen = wblock->data.if_descr.snap_len;
1723 if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
1725 wdh->bytes_dumped += sizeof idb;
1727 /* XXX - write (optional) block options */
1729 /* write block footer */
1730 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
1731 sizeof bh.block_total_length, err))
1733 wdh->bytes_dumped += sizeof bh.block_total_length;
1740 pcapng_write_packet_block(wtap_dumper *wdh, wtapng_block_t *wblock, int *err)
1742 pcapng_block_header_t bh;
1743 pcapng_enhanced_packet_block_t epb;
1744 const guint32 zero_pad = 0;
1748 phdr_len = (guint32)pcap_get_phdr_size(wblock->data.packet.wtap_encap, wblock->pseudo_header);
1749 if ((phdr_len + wblock->data.packet.cap_len) % 4) {
1750 pad_len = 4 - ((phdr_len + wblock->data.packet.cap_len) % 4);
1755 /* write (enhanced) packet block header */
1756 bh.block_type = wblock->type;
1757 bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + wblock->data.packet.cap_len + pad_len /* + options */ + 4;
1759 if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
1761 wdh->bytes_dumped += sizeof bh;
1763 /* write block fixed content */
1764 epb.interface_id = wblock->data.packet.interface_id;
1765 epb.timestamp_high = wblock->data.packet.ts_high;
1766 epb.timestamp_low = wblock->data.packet.ts_low;
1767 epb.captured_len = wblock->data.packet.cap_len + phdr_len;
1768 epb.packet_len = wblock->data.packet.packet_len + phdr_len;
1770 if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
1772 wdh->bytes_dumped += sizeof epb;
1774 /* write pseudo header */
1775 if (!pcap_write_phdr(wdh, wblock->data.packet.wtap_encap, wblock->pseudo_header, err)) {
1778 wdh->bytes_dumped += phdr_len;
1780 /* write packet data */
1781 if (!wtap_dump_file_write(wdh, wblock->frame_buffer,
1782 wblock->data.packet.cap_len, err))
1784 wdh->bytes_dumped += wblock->data.packet.cap_len;
1786 /* write padding (if any) */
1788 if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
1790 wdh->bytes_dumped += pad_len;
1793 /* XXX - write (optional) block options */
1795 /* write block footer */
1796 if (!wtap_dump_file_write(wdh, &bh.block_total_length,
1797 sizeof bh.block_total_length, err))
1799 wdh->bytes_dumped += sizeof bh.block_total_length;
1805 #define NRES_REC_MAX_SIZE ((WTAP_MAX_PACKET_SIZE * 4) + 16)
1807 pcapng_write_name_resolution_block(wtap_dumper *wdh, pcapng_dump_t *pcapng, int *err)
1809 pcapng_block_header_t bh;
1810 pcapng_name_resolution_block_t nrb;
1811 struct addrinfo *ai;
1812 struct sockaddr_in *sa4;
1813 struct sockaddr_in6 *sa6;
1815 gint rec_off, namelen, tot_rec_len;
1817 if (! pcapng->addrinfo_list_last || ! pcapng->addrinfo_list_last->ai_next) {
1821 rec_off = 8; /* block type + block total length */
1822 bh.block_type = BLOCK_TYPE_NRB;
1823 bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
1824 rec_data = g_malloc(NRES_REC_MAX_SIZE);
1826 for (; pcapng->addrinfo_list_last && pcapng->addrinfo_list_last->ai_next; pcapng->addrinfo_list_last = pcapng->addrinfo_list_last->ai_next ) {
1827 ai = pcapng->addrinfo_list_last->ai_next; /* Skips over the first (dummy) entry */
1828 namelen = (gint)strlen(ai->ai_canonname) + 1;
1829 if (ai->ai_family == AF_INET) {
1830 nrb.record_type = NRES_IP4RECORD;
1831 nrb.record_len = 4 + namelen;
1832 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
1833 bh.block_total_length += tot_rec_len;
1835 if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE)
1839 * The joys of BSD sockaddrs. In practice, this
1840 * cast is alignment-safe.
1842 sa4 = (struct sockaddr_in *)(void *)ai->ai_addr;
1843 memcpy(rec_data + rec_off, &nrb, sizeof(nrb));
1846 memcpy(rec_data + rec_off, &(sa4->sin_addr.s_addr), 4);
1849 memcpy(rec_data + rec_off, ai->ai_canonname, namelen);
1852 memset(rec_data + rec_off, 0, PADDING4(namelen));
1853 rec_off += PADDING4(namelen);
1854 pcapng_debug1("NRB: added IPv4 record for %s", ai->ai_canonname);
1855 } else if (ai->ai_family == AF_INET6) {
1856 nrb.record_type = NRES_IP6RECORD;
1857 nrb.record_len = 16 + namelen;
1858 tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
1859 bh.block_total_length += tot_rec_len;
1861 if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE)
1865 * The joys of BSD sockaddrs. In practice, this
1866 * cast is alignment-safe.
1868 sa6 = (struct sockaddr_in6 *)(void *)ai->ai_addr;
1869 memcpy(rec_data + rec_off, &nrb, sizeof(nrb));
1872 memcpy(rec_data + rec_off, sa6->sin6_addr.s6_addr, 16);
1875 memcpy(rec_data + rec_off, ai->ai_canonname, namelen);
1878 memset(rec_data + rec_off, 0, PADDING4(namelen));
1879 rec_off += PADDING4(namelen);
1880 pcapng_debug1("NRB: added IPv6 record for %s", ai->ai_canonname);
1884 /* We know the total length now; copy the block header. */
1885 memcpy(rec_data, &bh, sizeof(bh));
1888 memset(rec_data + rec_off, 0, 4);
1891 memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
1893 if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
1899 wdh->bytes_dumped += bh.block_total_length;
1905 pcapng_write_block(wtap_dumper *wdh, /*pcapng_t *pn, */wtapng_block_t *wblock, int *err)
1907 switch(wblock->type) {
1908 case(BLOCK_TYPE_SHB):
1909 return pcapng_write_section_header_block(wdh, wblock, err);
1910 case(BLOCK_TYPE_IDB):
1911 return pcapng_write_if_descr_block(wdh, wblock, err);
1912 case(BLOCK_TYPE_PB):
1913 /* Packet Block is obsolete */
1915 case(BLOCK_TYPE_EPB):
1916 return pcapng_write_packet_block(wdh, wblock, err);
1918 pcapng_debug1("Unknown block_type: 0x%x", wblock->type);
1925 pcapng_lookup_interface_id_by_encap(int wtap_encap, wtap_dumper *wdh)
1928 interface_data_t int_data;
1929 pcapng_dump_t *pcapng = (pcapng_dump_t *)wdh->priv;
1931 for(i = 0; i < (gint)pcapng->number_of_interfaces; i++) {
1932 int_data = g_array_index(pcapng->interface_data, interface_data_t, i);
1933 if (wtap_encap == int_data.wtap_encap) {
1941 static gboolean pcapng_dump(wtap_dumper *wdh,
1942 const struct wtap_pkthdr *phdr,
1943 const union wtap_pseudo_header *pseudo_header,
1944 const guint8 *pd, int *err)
1946 wtapng_block_t wblock;
1947 interface_data_t int_data;
1948 guint32 interface_id;
1950 pcapng_dump_t *pcapng = (pcapng_dump_t *)wdh->priv;
1952 pcapng_debug2("pcapng_dump: encap = %d (%s)",
1954 wtap_encap_string(phdr->pkt_encap));
1956 if (!pcapng->addrinfo_list_last)
1957 pcapng->addrinfo_list_last = wdh->addrinfo_list;
1959 interface_id = pcapng_lookup_interface_id_by_encap(phdr->pkt_encap, wdh);
1960 if (interface_id == G_MAXUINT32) {
1961 /* write the interface description block */
1962 wblock.frame_buffer = NULL;
1963 wblock.pseudo_header = NULL;
1964 wblock.packet_header = NULL;
1965 wblock.file_encap = NULL;
1966 wblock.type = BLOCK_TYPE_IDB;
1967 wblock.data.if_descr.link_type = wtap_wtap_encap_to_pcap_encap(phdr->pkt_encap);
1968 wblock.data.if_descr.snap_len = (wdh->snaplen != 0) ? wdh->snaplen :
1969 WTAP_MAX_PACKET_SIZE; /* XXX */
1971 /* XXX - options unused */
1972 wblock.data.if_descr.if_speed = -1;
1973 wblock.data.if_descr.if_tsresol = 6; /* default: usec */
1974 wblock.data.if_descr.if_os = NULL;
1975 wblock.data.if_descr.if_fcslen = -1;
1977 if (!pcapng_write_block(wdh, &wblock, err)) {
1981 interface_id = pcapng->number_of_interfaces;
1982 int_data.wtap_encap = phdr->pkt_encap;
1983 int_data.time_units_per_second = 0;
1984 g_array_append_val(pcapng->interface_data, int_data);
1985 pcapng->number_of_interfaces++;
1987 pcapng_debug3("pcapng_dump: added interface description block with index %u for encap = %d (%s).",
1990 wtap_encap_string(phdr->pkt_encap));
1993 /* Flush any hostname resolution info we may have */
1994 while (pcapng->addrinfo_list_last && pcapng->addrinfo_list_last->ai_next) {
1995 pcapng_write_name_resolution_block(wdh, pcapng, err);
1998 wblock.frame_buffer = pd;
1999 wblock.pseudo_header = pseudo_header;
2000 wblock.packet_header = NULL;
2001 wblock.file_encap = NULL;
2003 /* write the (enhanced) packet block */
2004 wblock.type = BLOCK_TYPE_EPB;
2006 /* default is to write out in microsecond resolution */
2007 ts = (((guint64)phdr->ts.secs) * 1000000) + (phdr->ts.nsecs / 1000);
2009 /* Split the 64-bit timestamp into two 32-bit pieces */
2010 wblock.data.packet.ts_high = (guint32)(ts >> 32);
2011 wblock.data.packet.ts_low = (guint32)ts;
2013 wblock.data.packet.cap_len = phdr->caplen;
2014 wblock.data.packet.packet_len = phdr->len;
2015 wblock.data.packet.interface_id = interface_id;
2016 wblock.data.packet.wtap_encap = phdr->pkt_encap;
2018 /* currently unused */
2019 wblock.data.packet.drop_count = -1;
2020 wblock.data.packet.opt_comment = NULL;
2022 if (!pcapng_write_block(wdh, &wblock, err)) {
2030 /* Finish writing to a dump file.
2031 Returns TRUE on success, FALSE on failure. */
2032 static gboolean pcapng_dump_close(wtap_dumper *wdh, int *err _U_)
2034 pcapng_dump_t *pcapng = (pcapng_dump_t *)wdh->priv;
2036 pcapng_debug0("pcapng_dump_close");
2037 g_array_free(pcapng->interface_data, TRUE);
2038 pcapng->number_of_interfaces = 0;
2043 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
2046 pcapng_dump_open(wtap_dumper *wdh, int *err)
2048 wtapng_block_t wblock;
2049 pcapng_dump_t *pcapng;
2051 wblock.frame_buffer = NULL;
2052 wblock.pseudo_header = NULL;
2053 wblock.packet_header = NULL;
2054 wblock.file_encap = NULL;
2056 pcapng_debug0("pcapng_dump_open");
2057 /* This is a pcapng file */
2058 wdh->subtype_write = pcapng_dump;
2059 wdh->subtype_close = pcapng_dump_close;
2060 pcapng = (pcapng_dump_t *)g_malloc0(sizeof(pcapng_dump_t));
2061 wdh->priv = (void *)pcapng;
2062 pcapng->interface_data = g_array_new(FALSE, FALSE, sizeof(interface_data_t));
2064 /* write the section header block */
2065 wblock.type = BLOCK_TYPE_SHB;
2066 wblock.data.section.section_length = -1;
2068 /* XXX - options unused */
2069 wblock.data.section.opt_comment = NULL;
2070 wblock.data.section.shb_hardware = NULL;
2071 wblock.data.section.shb_os = NULL;
2072 wblock.data.section.shb_user_appl = NULL;
2074 if (!pcapng_write_block(wdh, &wblock, err)) {
2077 pcapng_debug0("pcapng_dump_open: wrote section header block.");
2083 /* Returns 0 if we could write the specified encapsulation type,
2084 an error indication otherwise. */
2085 int pcapng_dump_can_write_encap(int wtap_encap)
2087 pcapng_debug2("pcapng_dump_can_write_encap: encap = %d (%s)",
2089 wtap_encap_string(wtap_encap));
2091 /* Per-packet encapsulations is supported. */
2092 if (wtap_encap == WTAP_ENCAP_PER_PACKET)
2095 /* Make sure we can figure out this DLT type */
2096 if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
2097 return WTAP_ERR_UNSUPPORTED_ENCAP;