1 /* $NetBSD: sf-pcap-ng.c,v 1.6 2015/03/31 21:39:42 christos Exp $ */
4 * Copyright (c) 1993, 1994, 1995, 1996, 1997
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * sf-pcap-ng.c - pcap-ng-file-format-specific code from savefile.c
27 static const char rcsid
[] _U_
=
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: sf-pcap-ng.c,v 1.6 2015/03/31 21:39:42 christos Exp $");
39 #include <pcap-stdinc.h>
46 #ifdef HAVE_SYS_BITYPES_H
47 #include <sys/bitypes.h>
49 #include <sys/types.h>
60 #include "pcap-common.h"
62 #ifdef HAVE_OS_PROTO_H
66 #include "sf-pcap-ng.h"
73 * Common part at the beginning of all blocks.
76 bpf_u_int32 block_type
;
77 bpf_u_int32 total_length
;
81 * Common trailer at the end of all blocks.
83 struct block_trailer
{
84 bpf_u_int32 total_length
;
90 #define OPT_ENDOFOPT 0 /* end of options */
91 #define OPT_COMMENT 1 /* comment string */
96 struct option_header
{
98 u_short option_length
;
102 * Structures for the part of each block type following the common
107 * Section Header Block.
109 #define BT_SHB 0x0A0D0D0A
111 struct section_header_block
{
112 bpf_u_int32 byte_order_magic
;
113 u_short major_version
;
114 u_short minor_version
;
115 u_int64_t section_length
;
116 /* followed by options and trailer */
120 * Byte-order magic value.
122 #define BYTE_ORDER_MAGIC 0x1A2B3C4D
125 * Current version number. If major_version isn't PCAP_NG_VERSION_MAJOR,
126 * that means that this code can't read the file.
128 #define PCAP_NG_VERSION_MAJOR 1
131 * Interface Description Block.
133 #define BT_IDB 0x00000001
135 struct interface_description_block
{
139 /* followed by options and trailer */
143 * Options in the IDB.
145 #define IF_NAME 2 /* interface name string */
146 #define IF_DESCRIPTION 3 /* interface description string */
147 #define IF_IPV4ADDR 4 /* interface's IPv4 address and netmask */
148 #define IF_IPV6ADDR 5 /* interface's IPv6 address and prefix length */
149 #define IF_MACADDR 6 /* interface's MAC address */
150 #define IF_EUIADDR 7 /* interface's EUI address */
151 #define IF_SPEED 8 /* interface's speed, in bits/s */
152 #define IF_TSRESOL 9 /* interface's time stamp resolution */
153 #define IF_TZONE 10 /* interface's time zone */
154 #define IF_FILTER 11 /* filter used when capturing on interface */
155 #define IF_OS 12 /* string OS on which capture on this interface was done */
156 #define IF_FCSLEN 13 /* FCS length for this interface */
157 #define IF_TSOFFSET 14 /* time stamp offset for this interface */
160 * Enhanced Packet Block.
162 #define BT_EPB 0x00000006
164 struct enhanced_packet_block
{
165 bpf_u_int32 interface_id
;
166 bpf_u_int32 timestamp_high
;
167 bpf_u_int32 timestamp_low
;
170 /* followed by packet data, options, and trailer */
174 * Simple Packet Block.
176 #define BT_SPB 0x00000003
178 struct simple_packet_block
{
180 /* followed by packet data and trailer */
186 #define BT_PB 0x00000002
188 struct packet_block
{
189 u_short interface_id
;
191 bpf_u_int32 timestamp_high
;
192 bpf_u_int32 timestamp_low
;
195 /* followed by packet data, options, and trailer */
199 * Block cursor - used when processing the contents of a block.
200 * Contains a pointer into the data being processed and a count
201 * of bytes remaining in the block.
203 struct block_cursor
{
205 size_t data_remaining
;
206 bpf_u_int32 block_type
;
213 } tstamp_scale_type_t
;
216 * Per-interface information.
219 u_int tsresol
; /* time stamp resolution */
220 u_int64_t tsoffset
; /* time stamp offset */
221 tstamp_scale_type_t scale_type
; /* how to scale */
225 u_int user_tsresol
; /* time stamp resolution requested by the user */
226 bpf_u_int32 ifcount
; /* number of interfaces seen in this capture */
227 bpf_u_int32 ifaces_size
; /* size of arrary below */
228 struct pcap_ng_if
*ifaces
; /* array of interface information */
231 static void pcap_ng_cleanup(pcap_t
*p
);
232 static int pcap_ng_next_packet(pcap_t
*p
, struct pcap_pkthdr
*hdr
,
236 read_bytes(FILE *fp
, void *buf
, size_t bytes_to_read
, int fail_on_eof
,
241 amt_read
= fread(buf
, 1, bytes_to_read
, fp
);
242 if (amt_read
!= bytes_to_read
) {
244 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
245 "error reading dump file: %s",
246 pcap_strerror(errno
));
248 if (amt_read
== 0 && !fail_on_eof
)
249 return (0); /* EOF */
250 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
251 "truncated dump file; tried to read %lu bytes, only got %lu",
252 (unsigned long)bytes_to_read
,
253 (unsigned long)amt_read
);
261 read_block(FILE *fp
, pcap_t
*p
, struct block_cursor
*cursor
, char *errbuf
)
264 struct block_header bhdr
;
266 status
= read_bytes(fp
, &bhdr
, sizeof(bhdr
), 0, errbuf
);
268 return (status
); /* error or EOF */
271 bhdr
.block_type
= SWAPLONG(bhdr
.block_type
);
272 bhdr
.total_length
= SWAPLONG(bhdr
.total_length
);
276 * Is this block "too big"?
278 * We choose 16MB as "too big", for now, so that we handle
279 * "reasonably" large buffers but don't chew up all the
280 * memory if we read a malformed file.
282 if (bhdr
.total_length
> 16*1024*1024) {
283 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
284 "pcap-ng block size %u > maximum %u",
285 bhdr
.total_length
, 16*1024*1024);
290 * Is this block "too small" - i.e., is it shorter than a block
291 * header plus a block trailer?
293 if (bhdr
.total_length
< sizeof(struct block_header
) +
294 sizeof(struct block_trailer
)) {
295 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
296 "block in pcap-ng dump file has a length of %u < %lu",
298 (unsigned long)(sizeof(struct block_header
) + sizeof(struct block_trailer
)));
303 * Is the buffer big enough?
305 if (p
->bufsize
< (int)bhdr
.total_length
) {
307 * No - make it big enough.
309 p
->buffer
= realloc(p
->buffer
, bhdr
.total_length
);
310 if (p
->buffer
== NULL
) {
311 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "out of memory");
317 * Copy the stuff we've read to the buffer, and read the rest
320 memcpy(p
->buffer
, &bhdr
, sizeof(bhdr
));
321 if (read_bytes(fp
, p
->buffer
+ sizeof(bhdr
),
322 bhdr
.total_length
- sizeof(bhdr
), 1, errbuf
) == -1)
326 * Initialize the cursor.
328 cursor
->data
= p
->buffer
+ sizeof(bhdr
);
329 cursor
->data_remaining
= bhdr
.total_length
- sizeof(bhdr
) -
330 sizeof(struct block_trailer
);
331 cursor
->block_type
= bhdr
.block_type
;
336 get_from_block_data(struct block_cursor
*cursor
, size_t chunk_size
,
342 * Make sure we have the specified amount of data remaining in
345 if (cursor
->data_remaining
< chunk_size
) {
346 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
347 "block of type %u in pcap-ng dump file is too short",
353 * Return the current pointer, and skip past the chunk.
356 cursor
->data
+= chunk_size
;
357 cursor
->data_remaining
-= chunk_size
;
361 static struct option_header
*
362 get_opthdr_from_block_data(pcap_t
*p
, struct block_cursor
*cursor
, char *errbuf
)
364 struct option_header
*opthdr
;
366 opthdr
= get_from_block_data(cursor
, sizeof(*opthdr
), errbuf
);
367 if (opthdr
== NULL
) {
369 * Option header is cut short.
375 * Byte-swap it if necessary.
378 opthdr
->option_code
= SWAPSHORT(opthdr
->option_code
);
379 opthdr
->option_length
= SWAPSHORT((uint32_t)opthdr
->option_length
);
386 get_optvalue_from_block_data(struct block_cursor
*cursor
,
387 struct option_header
*opthdr
, char *errbuf
)
389 size_t padded_option_len
;
392 /* Pad option length to 4-byte boundary */
393 padded_option_len
= opthdr
->option_length
;
394 padded_option_len
= ((padded_option_len
+ 3)/4)*4;
396 optvalue
= get_from_block_data(cursor
, padded_option_len
, errbuf
);
397 if (optvalue
== NULL
) {
399 * Option value is cut short.
408 process_idb_options(pcap_t
*p
, struct block_cursor
*cursor
, u_int
*tsresol
,
409 u_int64_t
*tsoffset
, char *errbuf
)
411 struct option_header
*opthdr
;
413 int saw_tsresol
, saw_tsoffset
;
419 while (cursor
->data_remaining
!= 0) {
421 * Get the option header.
423 opthdr
= get_opthdr_from_block_data(p
, cursor
, errbuf
);
424 if (opthdr
== NULL
) {
426 * Option header is cut short.
434 optvalue
= get_optvalue_from_block_data(cursor
, opthdr
,
436 if (optvalue
== NULL
) {
438 * Option value is cut short.
443 switch (opthdr
->option_code
) {
446 if (opthdr
->option_length
!= 0) {
447 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
448 "Interface Description Block has opt_endofopt option with length %u != 0",
449 opthdr
->option_length
);
455 if (opthdr
->option_length
!= 1) {
456 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
457 "Interface Description Block has if_tsresol option with length %u != 1",
458 opthdr
->option_length
);
462 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
463 "Interface Description Block has more than one if_tsresol option");
467 memcpy(&tsresol_opt
, optvalue
, sizeof(tsresol_opt
));
468 if (tsresol_opt
& 0x80) {
470 * Resolution is negative power of 2.
472 *tsresol
= 1 << (tsresol_opt
& 0x7F);
475 * Resolution is negative power of 10.
478 for (i
= 0; i
< tsresol_opt
; i
++)
483 * Resolution is too high.
485 if (tsresol_opt
& 0x80) {
486 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
487 "Interface Description Block if_tsresol option resolution 2^-%u is too high",
490 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
491 "Interface Description Block if_tsresol option resolution 10^-%u is too high",
499 if (opthdr
->option_length
!= 8) {
500 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
501 "Interface Description Block has if_tsoffset option with length %u != 8",
502 opthdr
->option_length
);
506 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
507 "Interface Description Block has more than one if_tsoffset option");
511 memcpy(tsoffset
, optvalue
, sizeof(*tsoffset
));
513 *tsoffset
= (uint64_t)SWAPLL(*tsoffset
);
526 add_interface(pcap_t
*p
, struct block_cursor
*cursor
, char *errbuf
)
528 struct pcap_ng_sf
*ps
;
535 * Count this interface.
540 * Grow the array of per-interface information as necessary.
542 if (ps
->ifcount
> ps
->ifaces_size
) {
544 * We need to grow the array.
546 if (ps
->ifaces
== NULL
) {
548 * It's currently empty.
551 ps
->ifaces
= malloc(sizeof (struct pcap_ng_if
));
554 * It's not currently empty; double its size.
555 * (Perhaps overkill once we have a lot of interfaces.)
557 ps
->ifaces_size
*= 2;
558 ps
->ifaces
= realloc(ps
->ifaces
, ps
->ifaces_size
* sizeof (struct pcap_ng_if
));
560 if (ps
->ifaces
== NULL
) {
562 * We ran out of memory.
565 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
566 "out of memory for per-interface information (%u interfaces)",
573 * Set the default time stamp resolution and offset.
575 tsresol
= 1000000; /* microsecond resolution */
576 tsoffset
= 0; /* absolute timestamps */
579 * Now look for various time stamp options, so we know
580 * how to interpret the time stamps for this interface.
582 if (process_idb_options(p
, cursor
, &tsresol
, &tsoffset
, errbuf
) == -1)
585 ps
->ifaces
[ps
->ifcount
- 1].tsresol
= tsresol
;
586 ps
->ifaces
[ps
->ifcount
- 1].tsoffset
= tsoffset
;
589 * Determine whether we're scaling up or down or not
590 * at all for this interface.
592 switch (p
->opt
.tstamp_precision
) {
594 case PCAP_TSTAMP_PRECISION_MICRO
:
595 if (tsresol
== 1000000) {
597 * The resolution is 1 microsecond,
598 * so we don't have to do scaling.
600 ps
->ifaces
[ps
->ifcount
- 1].scale_type
= PASS_THROUGH
;
601 } else if (tsresol
> 1000000) {
603 * The resolution is greater than
604 * 1 microsecond, so we have to
605 * scale the timestamps down.
607 ps
->ifaces
[ps
->ifcount
- 1].scale_type
= SCALE_DOWN
;
610 * The resolution is less than 1
611 * microsecond, so we have to scale
614 ps
->ifaces
[ps
->ifcount
- 1].scale_type
= SCALE_UP
;
618 case PCAP_TSTAMP_PRECISION_NANO
:
619 if (tsresol
== 1000000000) {
621 * The resolution is 1 nanosecond,
622 * so we don't have to do scaling.
624 ps
->ifaces
[ps
->ifcount
- 1].scale_type
= PASS_THROUGH
;
625 } else if (tsresol
> 1000000000) {
627 * The resolution is greater than
628 * 1 nanosecond, so we have to
629 * scale the timestamps down.
631 ps
->ifaces
[ps
->ifcount
- 1].scale_type
= SCALE_DOWN
;
634 * The resolution is less than 1
635 * nanosecond, so we have to scale
638 ps
->ifaces
[ps
->ifcount
- 1].scale_type
= SCALE_UP
;
646 * Check whether this is a pcap-ng savefile and, if it is, extract the
647 * relevant information from the header.
650 pcap_ng_check_header(bpf_u_int32 magic
, FILE *fp
, u_int precision
, char *errbuf
,
654 bpf_u_int32 total_length
;
655 bpf_u_int32 byte_order_magic
;
656 struct block_header
*bhdrp
;
657 struct section_header_block
*shbp
;
660 struct pcap_ng_sf
*ps
;
662 struct block_cursor cursor
;
663 struct interface_description_block
*idbp
;
666 * Assume no read errors.
671 * Check whether the first 4 bytes of the file are the block
672 * type for a pcap-ng savefile.
674 if (magic
!= BT_SHB
) {
676 * XXX - check whether this looks like what the block
677 * type would be after being munged by mapping between
678 * UN*X and DOS/Windows text file format and, if it
679 * does, look for the byte-order magic number in
680 * the appropriate place and, if we find it, report
681 * this as possibly being a pcap-ng file transferred
682 * between UN*X and Windows in text file format?
684 return (NULL
); /* nope */
688 * OK, they are. However, that's just \n\r\r\n, so it could,
689 * conceivably, be an ordinary text file.
691 * It could not, however, conceivably be any other type of
692 * capture file, so we can read the rest of the putative
693 * Section Header Block; put the block type in the common
694 * header, read the rest of the common header and the
695 * fixed-length portion of the SHB, and look for the byte-order
698 amt_read
= fread(&total_length
, 1, sizeof(total_length
), fp
);
699 if (amt_read
< sizeof(total_length
)) {
701 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
702 "error reading dump file: %s",
703 pcap_strerror(errno
));
705 return (NULL
); /* fail */
709 * Possibly a weird short text file, so just say
714 amt_read
= fread(&byte_order_magic
, 1, sizeof(byte_order_magic
), fp
);
715 if (amt_read
< sizeof(byte_order_magic
)) {
717 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
718 "error reading dump file: %s",
719 pcap_strerror(errno
));
721 return (NULL
); /* fail */
725 * Possibly a weird short text file, so just say
730 if (byte_order_magic
!= BYTE_ORDER_MAGIC
) {
731 byte_order_magic
= SWAPLONG(byte_order_magic
);
732 if (byte_order_magic
!= BYTE_ORDER_MAGIC
) {
734 * Not a pcap-ng file.
739 total_length
= SWAPLONG(total_length
);
743 * Check the sanity of the total length.
745 if (total_length
< sizeof(*bhdrp
) + sizeof(*shbp
) + sizeof(struct block_trailer
)) {
746 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
747 "Section Header Block in pcap-ng dump file has a length of %u < %lu",
749 (unsigned long)(sizeof(*bhdrp
) + sizeof(*shbp
) + sizeof(struct block_trailer
)));
755 * OK, this is a good pcap-ng file.
756 * Allocate a pcap_t for it.
758 p
= pcap_open_offline_common(errbuf
, sizeof (struct pcap_ng_sf
));
760 /* Allocation failed. */
764 p
->swapped
= swapped
;
768 * What precision does the user want?
772 case PCAP_TSTAMP_PRECISION_MICRO
:
773 ps
->user_tsresol
= 1000000;
776 case PCAP_TSTAMP_PRECISION_NANO
:
777 ps
->user_tsresol
= 1000000000;
781 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
782 "unknown time stamp resolution %u", precision
);
788 p
->opt
.tstamp_precision
= precision
;
791 * Allocate a buffer into which to read blocks. We default to
794 * the total length of the SHB for which we read the header;
796 * 2K, which should be more than large enough for an Enhanced
797 * Packet Block containing a full-size Ethernet frame, and
798 * leaving room for some options.
800 * If we find a bigger block, we reallocate the buffer.
803 if (p
->bufsize
< (int)total_length
)
804 p
->bufsize
= total_length
;
805 p
->buffer
= malloc(p
->bufsize
);
806 if (p
->buffer
== NULL
) {
807 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "out of memory");
814 * Copy the stuff we've read to the buffer, and read the rest
817 bhdrp
= (struct block_header
*)(void *)p
->buffer
;
818 shbp
= (struct section_header_block
*)(void *)(p
->buffer
+ sizeof(struct block_header
));
819 bhdrp
->block_type
= magic
;
820 bhdrp
->total_length
= total_length
;
821 shbp
->byte_order_magic
= byte_order_magic
;
823 p
->buffer
+ (sizeof(magic
) + sizeof(total_length
) + sizeof(byte_order_magic
)),
824 total_length
- (sizeof(magic
) + sizeof(total_length
) + sizeof(byte_order_magic
)),
830 * Byte-swap the fields we've read.
832 shbp
->major_version
= SWAPSHORT((uint32_t)shbp
->major_version
);
833 shbp
->minor_version
= SWAPSHORT((uint32_t)shbp
->minor_version
);
836 * XXX - we don't care about the section length.
839 if (shbp
->major_version
!= PCAP_NG_VERSION_MAJOR
) {
840 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
841 "unknown pcap-ng savefile major version number %u",
842 shbp
->major_version
);
845 p
->version_major
= shbp
->major_version
;
846 p
->version_minor
= shbp
->minor_version
;
849 * Save the time stamp resolution the user requested.
851 p
->opt
.tstamp_precision
= precision
;
854 * Now start looking for an Interface Description Block.
858 * Read the next block.
860 status
= read_block(fp
, p
, &cursor
, errbuf
);
862 /* EOF - no IDB in this file */
863 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
864 "the capture file has no Interface Description Blocks");
868 goto fail
; /* error */
869 switch (cursor
.block_type
) {
873 * Get a pointer to the fixed-length portion of the
876 idbp
= get_from_block_data(&cursor
, sizeof(*idbp
),
879 goto fail
; /* error */
882 * Byte-swap it if necessary.
885 idbp
->linktype
= SWAPSHORT((uint16_t)idbp
->linktype
);
886 idbp
->snaplen
= SWAPLONG(idbp
->snaplen
);
890 * Try to add this interface.
892 if (!add_interface(p
, &cursor
, errbuf
))
900 * Saw a packet before we saw any IDBs. That's
901 * not valid, as we don't know what link-layer
902 * encapsulation the packet has.
904 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
905 "the capture file has a packet block before any Interface Description Blocks");
917 p
->tzoff
= 0; /* XXX - not used in pcap */
918 p
->snapshot
= idbp
->snaplen
;
919 p
->linktype
= linktype_to_dlt(idbp
->linktype
);
922 p
->next_packet_op
= pcap_ng_next_packet
;
923 p
->cleanup_op
= pcap_ng_cleanup
;
936 pcap_ng_cleanup(pcap_t
*p
)
938 struct pcap_ng_sf
*ps
= p
->priv
;
945 * Read and return the next packet from the savefile. Return the header
946 * in hdr and a pointer to the contents in data. Return 0 on success, 1
947 * if there were no more packets, and -1 on an error.
950 pcap_ng_next_packet(pcap_t
*p
, struct pcap_pkthdr
*hdr
, u_char
**data
)
952 struct pcap_ng_sf
*ps
= p
->priv
;
953 struct block_cursor cursor
;
955 struct enhanced_packet_block
*epbp
;
956 struct simple_packet_block
*spbp
;
957 struct packet_block
*pbp
;
958 bpf_u_int32 interface_id
= 0xFFFFFFFF;
959 struct interface_description_block
*idbp
;
960 struct section_header_block
*shbp
;
962 u_int64_t t
, sec
, frac
;
965 * Look for an Enhanced Packet Block, a Simple Packet Block,
970 * Read the block type and length; those are common
973 status
= read_block(fp
, p
, &cursor
, p
->errbuf
);
975 return (1); /* EOF */
977 return (-1); /* error */
978 switch (cursor
.block_type
) {
982 * Get a pointer to the fixed-length portion of the
985 epbp
= get_from_block_data(&cursor
, sizeof(*epbp
),
988 return (-1); /* error */
991 * Byte-swap it if necessary.
994 /* these were written in opposite byte order */
995 interface_id
= SWAPLONG(epbp
->interface_id
);
996 hdr
->caplen
= SWAPLONG(epbp
->caplen
);
997 hdr
->len
= SWAPLONG(epbp
->len
);
998 t
= ((u_int64_t
)SWAPLONG(epbp
->timestamp_high
)) << 32 |
999 SWAPLONG(epbp
->timestamp_low
);
1001 interface_id
= epbp
->interface_id
;
1002 hdr
->caplen
= epbp
->caplen
;
1003 hdr
->len
= epbp
->len
;
1004 t
= ((u_int64_t
)epbp
->timestamp_high
) << 32 |
1005 epbp
->timestamp_low
;
1011 * Get a pointer to the fixed-length portion of the
1014 spbp
= get_from_block_data(&cursor
, sizeof(*spbp
),
1017 return (-1); /* error */
1020 * SPB packets are assumed to have arrived on
1021 * the first interface.
1026 * Byte-swap it if necessary.
1029 /* these were written in opposite byte order */
1030 hdr
->len
= SWAPLONG(spbp
->len
);
1032 hdr
->len
= spbp
->len
;
1035 * The SPB doesn't give the captured length;
1036 * it's the minimum of the snapshot length
1037 * and the packet length.
1039 hdr
->caplen
= hdr
->len
;
1040 if ((int)hdr
->caplen
> p
->snapshot
)
1041 hdr
->caplen
= p
->snapshot
;
1042 t
= 0; /* no time stamps */
1047 * Get a pointer to the fixed-length portion of the
1050 pbp
= get_from_block_data(&cursor
, sizeof(*pbp
),
1053 return (-1); /* error */
1056 * Byte-swap it if necessary.
1059 /* these were written in opposite byte order */
1060 interface_id
= SWAPSHORT((uint32_t)pbp
->interface_id
);
1061 hdr
->caplen
= SWAPLONG(pbp
->caplen
);
1062 hdr
->len
= SWAPLONG(pbp
->len
);
1063 t
= ((u_int64_t
)SWAPLONG(pbp
->timestamp_high
)) << 32 |
1064 SWAPLONG(pbp
->timestamp_low
);
1066 interface_id
= pbp
->interface_id
;
1067 hdr
->caplen
= pbp
->caplen
;
1068 hdr
->len
= pbp
->len
;
1069 t
= ((u_int64_t
)pbp
->timestamp_high
) << 32 |
1076 * Interface Description Block. Get a pointer
1077 * to its fixed-length portion.
1079 idbp
= get_from_block_data(&cursor
, sizeof(*idbp
),
1082 return (-1); /* error */
1085 * Byte-swap it if necessary.
1088 idbp
->linktype
= SWAPSHORT((uint32_t)idbp
->linktype
);
1089 idbp
->snaplen
= SWAPLONG(idbp
->snaplen
);
1093 * If the link-layer type or snapshot length
1094 * differ from the ones for the first IDB we
1097 * XXX - just discard packets from those
1100 if (p
->linktype
!= idbp
->linktype
) {
1101 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1102 "an interface has a type %u different from the type of the first interface",
1106 if (p
->snapshot
!= (int)idbp
->snaplen
) {
1107 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1108 "an interface has a snapshot length %u different from the type of the first interface",
1114 * Try to add this interface.
1116 if (!add_interface(p
, &cursor
, p
->errbuf
))
1122 * Section Header Block. Get a pointer
1123 * to its fixed-length portion.
1125 shbp
= get_from_block_data(&cursor
, sizeof(*shbp
),
1128 return (-1); /* error */
1131 * Assume the byte order of this section is
1132 * the same as that of the previous section.
1133 * We'll check for that later.
1136 shbp
->byte_order_magic
=
1137 SWAPLONG(shbp
->byte_order_magic
);
1138 shbp
->major_version
=
1139 SWAPSHORT((uint32_t)shbp
->major_version
);
1143 * Make sure the byte order doesn't change;
1144 * pcap_is_swapped() shouldn't change its
1145 * return value in the middle of reading a capture.
1147 switch (shbp
->byte_order_magic
) {
1149 case BYTE_ORDER_MAGIC
:
1155 case SWAPLONG(BYTE_ORDER_MAGIC
):
1157 * Byte order changes.
1159 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1160 "the file has sections with different byte orders");
1167 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1168 "the file has a section with a bad byte order magic field");
1173 * Make sure the major version is the version
1176 if (shbp
->major_version
!= PCAP_NG_VERSION_MAJOR
) {
1177 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1178 "unknown pcap-ng savefile major version number %u",
1179 shbp
->major_version
);
1184 * Reset the interface count; this section should
1185 * have its own set of IDBs. If any of them
1186 * don't have the same interface type, snapshot
1187 * length, or resolution as the first interface
1188 * we saw, we'll fail. (And if we don't see
1189 * any IDBs, we'll fail when we see a packet
1197 * Not a packet block, IDB, or SHB; ignore it.
1205 * Is the interface ID an interface we know?
1207 if (interface_id
>= ps
->ifcount
) {
1211 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1212 "a packet arrived on interface %u, but there's no Interface Description Block for that interface",
1218 * Convert the time stamp to seconds and fractions of a second,
1219 * with the fractions being in units of the file-supplied resolution.
1221 sec
= t
/ ps
->ifaces
[interface_id
].tsresol
+ ps
->ifaces
[interface_id
].tsoffset
;
1222 frac
= t
% ps
->ifaces
[interface_id
].tsresol
;
1225 * Convert the fractions from units of the file-supplied resolution
1226 * to units of the user-requested resolution.
1228 switch (ps
->ifaces
[interface_id
].scale_type
) {
1232 * The interface resolution is what the user wants,
1240 * The interface resolution is different from what the
1241 * user wants; convert the fractions to units of the
1242 * resolution the user requested by multiplying by the
1243 * quotient of the user-requested resolution and the
1244 * file-supplied resolution. We do that by multiplying
1245 * by the user-requested resolution and dividing by the
1246 * file-supplied resolution, as the quotient might not
1247 * fit in an integer.
1249 * XXX - if ps->ifaces[interface_id].tsresol is a power
1250 * of 10, we could just multiply by the quotient of
1251 * ps->user_tsresol and ps->ifaces[interface_id].tsresol
1252 * in the scale-up case, and divide by the quotient of
1253 * ps->ifaces[interface_id].tsresol and ps->user_tsresol
1254 * in the scale-down case, as we know those will be integers.
1255 * That would involve fewer arithmetic operations, and
1256 * would run less risk of overflow.
1258 * Is there something clever we could do if
1259 * ps->ifaces[interface_id].tsresol is a power of 2?
1261 frac
*= ps
->user_tsresol
;
1262 frac
/= ps
->ifaces
[interface_id
].tsresol
;
1265 hdr
->ts
.tv_sec
= sec
;
1266 hdr
->ts
.tv_usec
= (suseconds_t
)frac
;
1269 * Get a pointer to the packet data.
1271 *data
= get_from_block_data(&cursor
, hdr
->caplen
, p
->errbuf
);
1276 swap_pseudo_headers(p
->linktype
, hdr
, *data
);