1511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
2511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copyright (c) 1993, 1994, 1995, 1996, 1997
3511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *	The Regents of the University of California.  All rights reserved.
4511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
5511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Redistribution and use in source and binary forms, with or without
6511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * modification, are permitted provided that: (1) source code distributions
7511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * retain the above copyright notice and this paragraph in its entirety, (2)
8511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * distributions including binary code include the above copyright notice and
9511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * this paragraph in its entirety in the documentation or other materials
10511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * provided with the distribution, and (3) all advertising materials mentioning
11511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * features or use of this software display the following acknowledgement:
12511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * ``This product includes software developed by the University of California,
13511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the University nor the names of its contributors may be used to endorse
15511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or promote products derived from this software without specific prior
16511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * written permission.
17511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
21511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * sf-pcap-ng.c - pcap-ng-file-format-specific code from savefile.c
22511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
23511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
24511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef lint
25511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char rcsid[] _U_ =
26511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    "@(#) $Header$ (LBL)";
27511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
28511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
29511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_CONFIG_H
30511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "config.h"
31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef WIN32
34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <pcap-stdinc.h>
35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else /* WIN32 */
36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if HAVE_INTTYPES_H
37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <inttypes.h>
38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#elif HAVE_STDINT_H
39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdint.h>
40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BITYPES_H
42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/bitypes.h>
43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/types.h>
45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* WIN32 */
46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <errno.h>
48511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <memory.h>
49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdio.h>
50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdlib.h>
51511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <string.h>
52511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
53511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap-int.h"
54511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
55511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap-common.h"
56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
57511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_OS_PROTO_H
58511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "os-proto.h"
59511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "sf-pcap-ng.h"
62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Block types.
65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Common part at the beginning of all blocks.
69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block_header {
71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	block_type;
72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	total_length;
73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Common trailer at the end of all blocks.
77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block_trailer {
79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	total_length;
80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Common options.
84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define OPT_ENDOFOPT	0	/* end of options */
86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define OPT_COMMENT	1	/* comment string */
87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Option header.
90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct option_header {
92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_short		option_code;
93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_short		option_length;
94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Structures for the part of each block type following the common
98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * part.
99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Section Header Block.
103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define BT_SHB			0x0A0D0D0A
105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct section_header_block {
107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	byte_order_magic;
108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_short		major_version;
109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_short		minor_version;
110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int64_t	section_length;
111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* followed by options and trailer */
112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Byte-order magic value.
116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define BYTE_ORDER_MAGIC	0x1A2B3C4D
118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Current version number.  If major_version isn't PCAP_NG_VERSION_MAJOR,
121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that means that this code can't read the file.
122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define PCAP_NG_VERSION_MAJOR	1
124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Interface Description Block.
127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define BT_IDB			0x00000001
129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct interface_description_block {
131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_short		linktype;
132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_short		reserved;
133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	snaplen;
134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* followed by options and trailer */
135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Options in the IDB.
139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_NAME		2	/* interface name string */
141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_DESCRIPTION	3	/* interface description string */
142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_IPV4ADDR	4	/* interface's IPv4 address and netmask */
143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_IPV6ADDR	5	/* interface's IPv6 address and prefix length */
144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_MACADDR	6	/* interface's MAC address */
145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_EUIADDR	7	/* interface's EUI address */
146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_SPEED	8	/* interface's speed, in bits/s */
147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_TSRESOL	9	/* interface's time stamp resolution */
148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_TZONE	10	/* interface's time zone */
149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_FILTER	11	/* filter used when capturing on interface */
150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_OS		12	/* string OS on which capture on this interface was done */
151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_FCSLEN	13	/* FCS length for this interface */
152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define IF_TSOFFSET	14	/* time stamp offset for this interface */
153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Enhanced Packet Block.
156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define BT_EPB			0x00000006
158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct enhanced_packet_block {
160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	interface_id;
161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	timestamp_high;
162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	timestamp_low;
163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	caplen;
164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	len;
165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* followed by packet data, options, and trailer */
166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Simple Packet Block.
170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define BT_SPB			0x00000003
172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct simple_packet_block {
174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	len;
175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* followed by packet data and trailer */
176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Packet Block.
180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define BT_PB			0x00000002
182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct packet_block {
184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_short		interface_id;
185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_short		drops_count;
186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	timestamp_high;
187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	timestamp_low;
188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	caplen;
189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	len;
190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* followed by packet data, options, and trailer */
191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Block cursor - used when processing the contents of a block.
195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Contains a pointer into the data being processed and a count
196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of bytes remaining in the block.
197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct block_cursor {
199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_char		*data;
200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	size_t		data_remaining;
201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32	block_type;
202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralltypedef enum {
205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	PASS_THROUGH,
206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	SCALE_UP,
207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	SCALE_DOWN
208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} tstamp_scale_type_t;
209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Per-interface information.
212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct pcap_ng_if {
214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int tsresol;			/* time stamp resolution */
215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int64_t tsoffset;		/* time stamp offset */
216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	tstamp_scale_type_t scale_type;	/* how to scale */
217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct pcap_ng_sf {
220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int user_tsresol;		/* time stamp resolution requested by the user */
221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32 ifcount;		/* number of interfaces seen in this capture */
222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32 ifaces_size;	/* size of arrary below */
223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_ng_if *ifaces;	/* array of interface information */
224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void pcap_ng_cleanup(pcap_t *p);
227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    u_char **data);
229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallread_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof,
232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    char *errbuf)
233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	size_t amt_read;
235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	amt_read = fread(buf, 1, bytes_to_read, fp);
237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (amt_read != bytes_to_read) {
238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (ferror(fp)) {
239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(errbuf, PCAP_ERRBUF_SIZE,
240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    "error reading dump file: %s",
241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    pcap_strerror(errno));
242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		} else {
243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (amt_read == 0 && !fail_on_eof)
244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (0);	/* EOF */
245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(errbuf, PCAP_ERRBUF_SIZE,
246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    "truncated dump file; tried to read %lu bytes, only got %lu",
247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    (unsigned long)bytes_to_read,
248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    (unsigned long)amt_read);
249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (-1);
251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (1);
253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallread_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int status;
259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block_header bhdr;
260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	status = read_bytes(fp, &bhdr, sizeof(bhdr), 0, errbuf);
262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (status <= 0)
263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (status);	/* error or EOF */
264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p->swapped) {
266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bhdr.block_type = SWAPLONG(bhdr.block_type);
267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		bhdr.total_length = SWAPLONG(bhdr.total_length);
268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Is this block "too big"?
272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * We choose 16MB as "too big", for now, so that we handle
274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * "reasonably" large buffers but don't chew up all the
275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * memory if we read a malformed file.
276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (bhdr.total_length > 16*1024*1024) {
278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(errbuf, PCAP_ERRBUF_SIZE,
279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    "pcap-ng block size %u > maximum %u",
280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    bhdr.total_length, 16*1024*1024);
281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    return (-1);
282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Is this block "too small" - i.e., is it shorter than a block
286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * header plus a block trailer?
287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (bhdr.total_length < sizeof(struct block_header) +
289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    sizeof(struct block_trailer)) {
290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(errbuf, PCAP_ERRBUF_SIZE,
291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    "block in pcap-ng dump file has a length of %u < %lu",
292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    bhdr.total_length,
293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (unsigned long)(sizeof(struct block_header) + sizeof(struct block_trailer)));
294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (-1);
295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Is the buffer big enough?
299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p->bufsize < bhdr.total_length) {
301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * No - make it big enough.
303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		p->buffer = realloc(p->buffer, bhdr.total_length);
305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (p->buffer == NULL) {
306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (-1);
308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Copy the stuff we've read to the buffer, and read the rest
313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * of the block.
314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	memcpy(p->buffer, &bhdr, sizeof(bhdr));
316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (read_bytes(fp, p->buffer + sizeof(bhdr),
317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    bhdr.total_length - sizeof(bhdr), 1, errbuf) == -1)
318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (-1);
319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Initialize the cursor.
322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	cursor->data = p->buffer + sizeof(bhdr);
324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	cursor->data_remaining = bhdr.total_length - sizeof(bhdr) -
325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    sizeof(struct block_trailer);
326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	cursor->block_type = bhdr.block_type;
327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (1);
328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
329511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void *
331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallget_from_block_data(struct block_cursor *cursor, size_t chunk_size,
332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    char *errbuf)
333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	void *data;
335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Make sure we have the specified amount of data remaining in
338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * the block data.
339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (cursor->data_remaining < chunk_size) {
341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(errbuf, PCAP_ERRBUF_SIZE,
342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    "block of type %u in pcap-ng dump file is too short",
343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    cursor->block_type);
344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Return the current pointer, and skip past the chunk.
349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	data = cursor->data;
351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	cursor->data += chunk_size;
352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	cursor->data_remaining -= chunk_size;
353511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (data);
354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct option_header *
357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallget_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf)
358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct option_header *opthdr;
360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	opthdr = get_from_block_data(cursor, sizeof(*opthdr), errbuf);
362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (opthdr == NULL) {
363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Option header is cut short.
365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Byte-swap it if necessary.
371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p->swapped) {
373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		opthdr->option_code = SWAPSHORT(opthdr->option_code);
374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		opthdr->option_length = SWAPSHORT(opthdr->option_length);
375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (opthdr);
378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void *
381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallget_optvalue_from_block_data(struct block_cursor *cursor,
382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    struct option_header *opthdr, char *errbuf)
383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	size_t padded_option_len;
385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	void *optvalue;
386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* Pad option length to 4-byte boundary */
388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	padded_option_len = opthdr->option_length;
389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	padded_option_len = ((padded_option_len + 3)/4)*4;
390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	optvalue = get_from_block_data(cursor, padded_option_len, errbuf);
392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (optvalue == NULL) {
393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Option value is cut short.
395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (optvalue);
400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallprocess_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    u_int64_t *tsoffset, char *errbuf)
405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct option_header *opthdr;
407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	void *optvalue;
408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int saw_tsresol, saw_tsoffset;
409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_char tsresol_opt;
410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int i;
411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	saw_tsresol = 0;
413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	saw_tsoffset = 0;
414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	while (cursor->data_remaining != 0) {
415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
416511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Get the option header.
417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		opthdr = get_opthdr_from_block_data(p, cursor, errbuf);
419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (opthdr == NULL) {
420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Option header is cut short.
422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (-1);
424511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
425511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
427511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Get option value.
428511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		optvalue = get_optvalue_from_block_data(cursor, opthdr,
430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    errbuf);
431511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (optvalue == NULL) {
432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
433511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Option value is cut short.
434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (-1);
436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (opthdr->option_code) {
439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case OPT_ENDOFOPT:
441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (opthdr->option_length != 0) {
442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(errbuf, PCAP_ERRBUF_SIZE,
443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "Interface Description Block has opt_endofopt option with length %u != 0",
444511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    opthdr->option_length);
445511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto done;
448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case IF_TSRESOL:
450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (opthdr->option_length != 1) {
451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(errbuf, PCAP_ERRBUF_SIZE,
452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "Interface Description Block has if_tsresol option with length %u != 1",
453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    opthdr->option_length);
454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (saw_tsresol) {
457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(errbuf, PCAP_ERRBUF_SIZE,
458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "Interface Description Block has more than one if_tsresol option");
459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			saw_tsresol = 1;
462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			tsresol_opt = *(u_int *)optvalue;
463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (tsresol_opt & 0x80) {
464511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
465511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Resolution is negative power of 2.
466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				*tsresol = 1 << (tsresol_opt & 0x7F);
468511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			} else {
469511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Resolution is negative power of 10.
471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				*tsresol = 1;
473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				for (i = 0; i < tsresol_opt; i++)
474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					*tsresol *= 10;
475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (*tsresol == 0) {
477511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
478511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Resolution is too high.
479511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
480511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				if (tsresol_opt & 0x80) {
481511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					snprintf(errbuf, PCAP_ERRBUF_SIZE,
482511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					    "Interface Description Block if_tsresol option resolution 2^-%u is too high",
483511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					    tsresol_opt & 0x7F);
484511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				} else {
485511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					snprintf(errbuf, PCAP_ERRBUF_SIZE,
486511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					    "Interface Description Block if_tsresol option resolution 10^-%u is too high",
487511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					    tsresol_opt);
488511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				}
489511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
491511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
492511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
493511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case IF_TSOFFSET:
494511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (opthdr->option_length != 8) {
495511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(errbuf, PCAP_ERRBUF_SIZE,
496511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "Interface Description Block has if_tsoffset option with length %u != 8",
497511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    opthdr->option_length);
498511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
499511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
500511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (saw_tsoffset) {
501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(errbuf, PCAP_ERRBUF_SIZE,
502511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "Interface Description Block has more than one if_tsoffset option");
503511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
504511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
505511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			saw_tsoffset = 1;
506511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			memcpy(tsoffset, optvalue, sizeof(*tsoffset));
507511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->swapped)
508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				*tsoffset = SWAPLL(*tsoffset);
509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
513511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
515511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
516511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldone:
517511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (0);
518511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
520511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
521511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralladd_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
522511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
523511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_ng_sf *ps;
524511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int tsresol;
525511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int64_t tsoffset;
526511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
527511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	ps = p->priv;
528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
530511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Count this interface.
531511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	ps->ifcount++;
533511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
535511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Grow the array of per-interface information as necessary.
536511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (ps->ifcount > ps->ifaces_size) {
538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * We need to grow the array.
540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
541511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (ps->ifaces == NULL) {
542511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
543511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * It's currently empty.
544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
545511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces_size = 1;
546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces = malloc(sizeof (struct pcap_ng_if));
547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		} else {
548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
549511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * It's not currently empty; double its size.
550511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * (Perhaps overkill once we have a lot of interfaces.)
551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces_size *= 2;
553511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces = realloc(ps->ifaces, ps->ifaces_size * sizeof (struct pcap_ng_if));
554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (ps->ifaces == NULL) {
556511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
557511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * We ran out of memory.
558511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Give up.
559511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
560511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(errbuf, PCAP_ERRBUF_SIZE,
561511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    "out of memory for per-interface information (%u interfaces)",
562511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    ps->ifcount);
563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (0);
564511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
565511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
566511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
567511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
568511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Set the default time stamp resolution and offset.
569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
570511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	tsresol = 1000000;	/* microsecond resolution */
571511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	tsoffset = 0;		/* absolute timestamps */
572511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
573511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
574511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Now look for various time stamp options, so we know
575511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * how to interpret the time stamps for this interface.
576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
577511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (process_idb_options(p, cursor, &tsresol, &tsoffset, errbuf) == -1)
578511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (0);
579511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
580511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	ps->ifaces[ps->ifcount - 1].tsresol = tsresol;
581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	ps->ifaces[ps->ifcount - 1].tsoffset = tsoffset;
582511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
583511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
584511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Determine whether we're scaling up or down or not
585511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * at all for this interface.
586511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (p->opt.tstamp_precision) {
588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
589511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case PCAP_TSTAMP_PRECISION_MICRO:
590511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (tsresol == 1000000) {
591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * The resolution is 1 microsecond,
593511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * so we don't have to do scaling.
594511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
595511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH;
596511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		} else if (tsresol > 1000000) {
597511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
598511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * The resolution is greater than
599511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * 1 microsecond, so we have to
600511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * scale the timestamps down.
601511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
602511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN;
603511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		} else {
604511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
605511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * The resolution is less than 1
606511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * microsecond, so we have to scale
607511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * the timestamps up.
608511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
609511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP;
610511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
611511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
613511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case PCAP_TSTAMP_PRECISION_NANO:
614511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (tsresol == 1000000000) {
615511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
616511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * The resolution is 1 nanosecond,
617511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * so we don't have to do scaling.
618511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
619511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH;
620511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		} else if (tsresol > 1000000000) {
621511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
622511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * The resolution is greater than
623511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * 1 nanosecond, so we have to
624511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * scale the timestamps down.
625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
626511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN;
627511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		} else {
628511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
629511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * The resolution is less than 1
630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * nanosecond, so we have to scale
631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * the timestamps up.
632511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP;
634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
635511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
637511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (1);
638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
639511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
641511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Check whether this is a pcap-ng savefile and, if it is, extract the
642511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * relevant information from the header.
643511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
644511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_t *
645511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
646511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    int *err)
647511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
648511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	size_t amt_read;
649511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32 total_length;
650511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32 byte_order_magic;
651511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block_header *bhdrp;
652511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct section_header_block *shbp;
653511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pcap_t *p;
654511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int swapped = 0;
655511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_ng_sf *ps;
656511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int status;
657511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block_cursor cursor;
658511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct interface_description_block *idbp;
659511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
660511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
661511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Assume no read errors.
662511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
663511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	*err = 0;
664511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
665511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
666511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Check whether the first 4 bytes of the file are the block
667511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * type for a pcap-ng savefile.
668511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
669511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (magic != BT_SHB) {
670511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
671511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * XXX - check whether this looks like what the block
672511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * type would be after being munged by mapping between
673511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * UN*X and DOS/Windows text file format and, if it
674511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * does, look for the byte-order magic number in
675511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * the appropriate place and, if we find it, report
676511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * this as possibly being a pcap-ng file transferred
677511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * between UN*X and Windows in text file format?
678511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
679511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);	/* nope */
680511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
681511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
682511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
683511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * OK, they are.  However, that's just \n\r\r\n, so it could,
684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * conceivably, be an ordinary text file.
685511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
686511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * It could not, however, conceivably be any other type of
687511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * capture file, so we can read the rest of the putative
688511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Section Header Block; put the block type in the common
689511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * header, read the rest of the common header and the
690511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * fixed-length portion of the SHB, and look for the byte-order
691511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * magic value.
692511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
693511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	amt_read = fread(&total_length, 1, sizeof(total_length), fp);
694511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (amt_read < sizeof(total_length)) {
695511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (ferror(fp)) {
696511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(errbuf, PCAP_ERRBUF_SIZE,
697511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    "error reading dump file: %s",
698511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    pcap_strerror(errno));
699511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			*err = 1;
700511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (NULL);	/* fail */
701511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
702511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
703511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
704511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Possibly a weird short text file, so just say
705511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * "not pcap-ng".
706511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
707511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
708511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
709511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp);
710511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (amt_read < sizeof(byte_order_magic)) {
711511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (ferror(fp)) {
712511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(errbuf, PCAP_ERRBUF_SIZE,
713511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    "error reading dump file: %s",
714511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    pcap_strerror(errno));
715511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			*err = 1;
716511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (NULL);	/* fail */
717511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
718511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
719511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
720511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Possibly a weird short text file, so just say
721511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * "not pcap-ng".
722511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
723511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
724511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
725511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (byte_order_magic != BYTE_ORDER_MAGIC) {
726511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		byte_order_magic = SWAPLONG(byte_order_magic);
727511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (byte_order_magic != BYTE_ORDER_MAGIC) {
728511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
729511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Not a pcap-ng file.
730511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
731511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (NULL);
732511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
733511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		swapped = 1;
734511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		total_length = SWAPLONG(total_length);
735511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
736511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
737511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Check the sanity of the total length.
739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)) {
741511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(errbuf, PCAP_ERRBUF_SIZE,
742511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    "Section Header Block in pcap-ng dump file has a length of %u < %lu",
743511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    total_length,
744511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
745511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		*err = 1;
746511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
747511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
748511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
749511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
750511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * OK, this is a good pcap-ng file.
751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Allocate a pcap_t for it.
752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
753511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf));
754511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p == NULL) {
755511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* Allocation failed. */
756511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		*err = 1;
757511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
758511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
759511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->swapped = swapped;
760511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	ps = p->priv;
761511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
762511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * What precision does the user want?
764511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (precision) {
766511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
767511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case PCAP_TSTAMP_PRECISION_MICRO:
768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		ps->user_tsresol = 1000000;
769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case PCAP_TSTAMP_PRECISION_NANO:
772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		ps->user_tsresol = 1000000000;
773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
774511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
775511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	default:
776511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(errbuf, PCAP_ERRBUF_SIZE,
777511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    "unknown time stamp resolution %u", precision);
778511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		free(p);
779511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		*err = 1;
780511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
781511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
782511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->opt.tstamp_precision = precision;
784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
786511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Allocate a buffer into which to read blocks.  We default to
787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * the maximum of:
788511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *	the total length of the SHB for which we read the header;
790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *	2K, which should be more than large enough for an Enhanced
792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *	Packet Block containing a full-size Ethernet frame, and
793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *	leaving room for some options.
794511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 *
795511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * If we find a bigger block, we reallocate the buffer.
796511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
797511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->bufsize = 2048;
798511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p->bufsize < total_length)
799511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		p->bufsize = total_length;
800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->buffer = malloc(p->bufsize);
801511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p->buffer == NULL) {
802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
803511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		free(p);
804511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		*err = 1;
805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
806511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
807511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
808511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
809511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Copy the stuff we've read to the buffer, and read the rest
810511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * of the SHB.
811511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
812511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bhdrp = (struct block_header *)p->buffer;
813511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	shbp = (struct section_header_block *)(p->buffer + sizeof(struct block_header));
814511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bhdrp->block_type = magic;
815511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bhdrp->total_length = total_length;
816511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	shbp->byte_order_magic = byte_order_magic;
817511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (read_bytes(fp,
818511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
819511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
820511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    1, errbuf) == -1)
821511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		goto fail;
822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p->swapped) {
824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Byte-swap the fields we've read.
826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		shbp->major_version = SWAPSHORT(shbp->major_version);
828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		shbp->minor_version = SWAPSHORT(shbp->minor_version);
829511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
830511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
831511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * XXX - we don't care about the section length.
832511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
833511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
834511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
835511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(errbuf, PCAP_ERRBUF_SIZE,
836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    "unknown pcap-ng savefile major version number %u",
837511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    shbp->major_version);
838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		goto fail;
839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
840511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->version_major = shbp->major_version;
841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->version_minor = shbp->minor_version;
842511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Save the time stamp resolution the user requested.
845511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
846511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->opt.tstamp_precision = precision;
847511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
848511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Now start looking for an Interface Description Block.
850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	for (;;) {
852511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Read the next block.
854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		status = read_block(fp, p, &cursor, errbuf);
856511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (status == 0) {
857511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* EOF - no IDB in this file */
858511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(errbuf, PCAP_ERRBUF_SIZE,
859511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    "the capture file has no Interface Description Blocks");
860511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto fail;
861511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
862511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (status == -1)
863511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto fail;	/* error */
864511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (cursor.block_type) {
865511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
866511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_IDB:
867511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
868511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Get a pointer to the fixed-length portion of the
869511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * IDB.
870511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
871511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			idbp = get_from_block_data(&cursor, sizeof(*idbp),
872511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    errbuf);
873511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (idbp == NULL)
874511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				goto fail;	/* error */
875511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
876511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
877511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Byte-swap it if necessary.
878511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
879511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->swapped) {
880511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				idbp->linktype = SWAPSHORT(idbp->linktype);
881511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				idbp->snaplen = SWAPLONG(idbp->snaplen);
882511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
883511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
884511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
885511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Try to add this interface.
886511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
887511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (!add_interface(p, &cursor, errbuf))
888511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				goto fail;
889511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto done;
890511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
891511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_EPB:
892511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_SPB:
893511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_PB:
894511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
895511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Saw a packet before we saw any IDBs.  That's
896511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * not valid, as we don't know what link-layer
897511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * encapsulation the packet has.
898511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
899511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(errbuf, PCAP_ERRBUF_SIZE,
900511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    "the capture file has a packet block before any Interface Description Blocks");
901511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto fail;
902511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
903511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
904511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
905511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Just ignore it.
906511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
907511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
908511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
909511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
910511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
911511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldone:
912511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->tzoff = 0;	/* XXX - not used in pcap */
913511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->snapshot = idbp->snaplen;
914511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->linktype = linktype_to_dlt(idbp->linktype);
915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->linktype_ext = 0;
916511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
917511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->next_packet_op = pcap_ng_next_packet;
918511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->cleanup_op = pcap_ng_cleanup;
919511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (p);
921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallfail:
923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	free(ps->ifaces);
924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	free(p->buffer);
925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	free(p);
926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	*err = 1;
927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (NULL);
928511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
931511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_ng_cleanup(pcap_t *p)
932511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
933511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_ng_sf *ps = p->priv;
934511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
935511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	free(ps->ifaces);
936511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sf_cleanup(p);
937511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
938511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
939511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
940511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Read and return the next packet from the savefile.  Return the header
941511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in hdr and a pointer to the contents in data.  Return 0 on success, 1
942511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if there were no more packets, and -1 on an error.
943511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
944511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
945511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
946511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
947511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_ng_sf *ps = p->priv;
948511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct block_cursor cursor;
949511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int status;
950511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct enhanced_packet_block *epbp;
951511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct simple_packet_block *spbp;
952511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct packet_block *pbp;
953511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32 interface_id = 0xFFFFFFFF;
954511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct interface_description_block *idbp;
955511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct section_header_block *shbp;
956511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	FILE *fp = p->rfile;
957511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int64_t t, sec, frac;
958511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
959511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
960511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Look for an Enhanced Packet Block, a Simple Packet Block,
961511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * or a Packet Block.
962511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
963511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	for (;;) {
964511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
965511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Read the block type and length; those are common
966511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * to all blocks.
967511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
968511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		status = read_block(fp, p, &cursor, p->errbuf);
969511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (status == 0)
970511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (1);	/* EOF */
971511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (status == -1)
972511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return (-1);	/* error */
973511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (cursor.block_type) {
974511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
975511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_EPB:
976511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
977511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Get a pointer to the fixed-length portion of the
978511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * EPB.
979511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
980511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			epbp = get_from_block_data(&cursor, sizeof(*epbp),
981511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    p->errbuf);
982511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (epbp == NULL)
983511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);	/* error */
984511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
985511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
986511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Byte-swap it if necessary.
987511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
988511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->swapped) {
989511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/* these were written in opposite byte order */
990511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				interface_id = SWAPLONG(epbp->interface_id);
991511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->caplen = SWAPLONG(epbp->caplen);
992511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->len = SWAPLONG(epbp->len);
993511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				t = ((u_int64_t)SWAPLONG(epbp->timestamp_high)) << 32 |
994511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    SWAPLONG(epbp->timestamp_low);
995511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			} else {
996511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				interface_id = epbp->interface_id;
997511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->caplen = epbp->caplen;
998511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->len = epbp->len;
999511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				t = ((u_int64_t)epbp->timestamp_high) << 32 |
1000511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    epbp->timestamp_low;
1001511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1002511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto found;
1003511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1004511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_SPB:
1005511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1006511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Get a pointer to the fixed-length portion of the
1007511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * SPB.
1008511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1009511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			spbp = get_from_block_data(&cursor, sizeof(*spbp),
1010511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    p->errbuf);
1011511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (spbp == NULL)
1012511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);	/* error */
1013511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1014511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1015511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * SPB packets are assumed to have arrived on
1016511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * the first interface.
1017511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1018511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			interface_id = 0;
1019511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1020511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1021511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Byte-swap it if necessary.
1022511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1023511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->swapped) {
1024511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/* these were written in opposite byte order */
1025511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->len = SWAPLONG(spbp->len);
1026511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			} else
1027511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->len = spbp->len;
1028511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1029511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1030511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * The SPB doesn't give the captured length;
1031511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * it's the minimum of the snapshot length
1032511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * and the packet length.
1033511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1034511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			hdr->caplen = hdr->len;
1035511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (hdr->caplen > p->snapshot)
1036511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->caplen = p->snapshot;
1037511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			t = 0;	/* no time stamps */
1038511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto found;
1039511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1040511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_PB:
1041511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1042511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Get a pointer to the fixed-length portion of the
1043511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * PB.
1044511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1045511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			pbp = get_from_block_data(&cursor, sizeof(*pbp),
1046511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    p->errbuf);
1047511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (pbp == NULL)
1048511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);	/* error */
1049511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1050511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1051511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Byte-swap it if necessary.
1052511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1053511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->swapped) {
1054511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/* these were written in opposite byte order */
1055511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				interface_id = SWAPSHORT(pbp->interface_id);
1056511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->caplen = SWAPLONG(pbp->caplen);
1057511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->len = SWAPLONG(pbp->len);
1058511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				t = ((u_int64_t)SWAPLONG(pbp->timestamp_high)) << 32 |
1059511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    SWAPLONG(pbp->timestamp_low);
1060511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			} else {
1061511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				interface_id = pbp->interface_id;
1062511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->caplen = pbp->caplen;
1063511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				hdr->len = pbp->len;
1064511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				t = ((u_int64_t)pbp->timestamp_high) << 32 |
1065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    pbp->timestamp_low;
1066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1067511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto found;
1068511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1069511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_IDB:
1070511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1071511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Interface Description Block.  Get a pointer
1072511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * to its fixed-length portion.
1073511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1074511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			idbp = get_from_block_data(&cursor, sizeof(*idbp),
1075511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    p->errbuf);
1076511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (idbp == NULL)
1077511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);	/* error */
1078511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1079511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1080511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Byte-swap it if necessary.
1081511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1082511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->swapped) {
1083511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				idbp->linktype = SWAPSHORT(idbp->linktype);
1084511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				idbp->snaplen = SWAPLONG(idbp->snaplen);
1085511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1086511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1087511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1088511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * If the link-layer type or snapshot length
1089511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * differ from the ones for the first IDB we
1090511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * saw, quit.
1091511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 *
1092511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * XXX - just discard packets from those
1093511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * interfaces?
1094511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1095511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->linktype != idbp->linktype) {
1096511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1097511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "an interface has a type %u different from the type of the first interface",
1098511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    idbp->linktype);
1099511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
1100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->snapshot != idbp->snaplen) {
1102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "an interface has a snapshot length %u different from the type of the first interface",
1104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    idbp->snaplen);
1105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
1106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Try to add this interface.
1110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (!add_interface(p, &cursor, p->errbuf))
1112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
1113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
1114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case BT_SHB:
1116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Section Header Block.  Get a pointer
1118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * to its fixed-length portion.
1119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			shbp = get_from_block_data(&cursor, sizeof(*shbp),
1121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    p->errbuf);
1122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (shbp == NULL)
1123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);	/* error */
1124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Assume the byte order of this section is
1127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * the same as that of the previous section.
1128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * We'll check for that later.
1129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (p->swapped) {
1131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				shbp->byte_order_magic =
1132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    SWAPLONG(shbp->byte_order_magic);
1133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				shbp->major_version =
1134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    SWAPSHORT(shbp->major_version);
1135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Make sure the byte order doesn't change;
1139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * pcap_is_swapped() shouldn't change its
1140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * return value in the middle of reading a capture.
1141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			switch (shbp->byte_order_magic) {
1143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			case BYTE_ORDER_MAGIC:
1145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
1146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * OK.
1147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
1148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				break;
1149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			case SWAPLONG(BYTE_ORDER_MAGIC):
1151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
1152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Byte order changes.
1153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
1154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "the file has sections with different byte orders");
1156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
1157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			default:
1159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				/*
1160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 * Not a valid SHB.
1161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				 */
1162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "the file has a section with a bad byte order magic field");
1164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
1165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Make sure the major version is the version
1169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * we handle.
1170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
1172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    "unknown pcap-ng savefile major version number %u",
1174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    shbp->major_version);
1175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return (-1);
1176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Reset the interface count; this section should
1180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * have its own set of IDBs.  If any of them
1181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * don't have the same interface type, snapshot
1182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * length, or resolution as the first interface
1183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * we saw, we'll fail.  (And if we don't see
1184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * any IDBs, we'll fail when we see a packet
1185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * block.)
1186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			ps->ifcount = 0;
1188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
1189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
1191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/*
1192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 * Not a packet block, IDB, or SHB; ignore it.
1193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			 */
1194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
1195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
1196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
1197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallfound:
1199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
1200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Is the interface ID an interface we know?
1201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
1202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (interface_id >= ps->ifcount) {
1203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
1204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Yes.  Fail.
1205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
1206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    "a packet arrived on interface %u, but there's no Interface Description Block for that interface",
1208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    interface_id);
1209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (-1);
1210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
1211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
1213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Convert the time stamp to a struct timeval.
1214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
1215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	sec = t / ps->ifaces[interface_id].tsresol + ps->ifaces[interface_id].tsoffset;
1216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	frac = t % ps->ifaces[interface_id].tsresol;
1217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	switch (ps->ifaces[interface_id].scale_type) {
1218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case PASS_THROUGH:
1220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
1221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The interface resolution is what the user wants,
1222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * so we're done.
1223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
1224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
1225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case SCALE_UP:
1227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
1228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The interface resolution is less than what the user
1229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * wants; scale up to that resolution.
1230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
1231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * XXX - if ps->ifaces[interface_id].tsresol is a power
1232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * of 10, we could just multiply by the quotient of
1233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * ps->ifaces[interface_id].tsresol and ps->user_tsresol,
1234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * as we know that's an integer.  That runs less risk of
1235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * overflow.
1236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
1237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Is there something clever we could do if
1238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * ps->ifaces[interface_id].tsresol is a power of 2?
1239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
1240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		frac *= ps->ifaces[interface_id].tsresol;
1241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		frac /= ps->user_tsresol;
1242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
1243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	case SCALE_DOWN:
1245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
1246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * The interface resolution is greater than what the user
1247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * wants; scale down to that resolution.
1248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
1249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * XXX - if ps->ifaces[interface_id].tsresol is a power
1250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * of 10, we could just divide by the quotient of
1251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * ps->user_tsresol and ps->ifaces[interface_id].tsresol,
1252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * as we know that's an integer.  That runs less risk of
1253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * overflow.
1254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 *
1255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Is there something clever we could do if
1256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * ps->ifaces[interface_id].tsresol is a power of 2?
1257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
1258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		frac *= ps->user_tsresol;
1259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		frac /= ps->ifaces[interface_id].tsresol;
1260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		break;
1261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
1262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	hdr->ts.tv_sec = sec;
1263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	hdr->ts.tv_usec = frac;
1264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/*
1266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 * Get a pointer to the packet data.
1267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 */
1268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	*data = get_from_block_data(&cursor, hdr->caplen, p->errbuf);
1269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (*data == NULL)
1270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (-1);
1271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p->swapped)
1273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		swap_pseudo_headers(p->linktype, hdr, *data);
1274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (0);
1276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
1277