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