138032Speter/* 2261363Sgshapiro * Copyright (c) 1993, 1994, 1995, 1996, 1997 364565Sgshapiro * The Regents of the University of California. All rights reserved. 438032Speter * 538032Speter * Redistribution and use in source and binary forms, with or without 638032Speter * modification, are permitted provided that: (1) source code distributions 738032Speter * retain the above copyright notice and this paragraph in its entirety, (2) 838032Speter * distributions including binary code include the above copyright notice and 938032Speter * this paragraph in its entirety in the documentation or other materials 1038032Speter * provided with the distribution, and (3) all advertising materials mentioning 1138032Speter * features or use of this software display the following acknowledgement: 1238032Speter * ``This product includes software developed by the University of California, 1338032Speter * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1464565Sgshapiro * the University nor the names of its contributors may be used to endorse 1564565Sgshapiro * or promote products derived from this software without specific prior 16266692Sgshapiro * written permission. 1764565Sgshapiro * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1864565Sgshapiro * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1964565Sgshapiro * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2064565Sgshapiro * 2164565Sgshapiro * sf-pcapng.c - pcapng-file-format-specific code from savefile.c 2238032Speter */ 2338032Speter 2464565Sgshapiro#ifdef HAVE_CONFIG_H 2564565Sgshapiro#include <config.h> 2664565Sgshapiro#endif 2764565Sgshapiro 2864565Sgshapiro#include <pcap/pcap-inttypes.h> 2990795Sgshapiro 3064565Sgshapiro#include <errno.h> 3138032Speter#include <memory.h> 3238032Speter#include <stdio.h> 3338032Speter#include <stdlib.h> 3438032Speter#include <string.h> 3538032Speter 3638032Speter#include "pcap-int.h" 3738032Speter#include "pcap-util.h" 3838032Speter 3938032Speter#include "pcap-common.h" 4038032Speter 4138032Speter#ifdef HAVE_OS_PROTO_H 4238032Speter#include "os-proto.h" 4338032Speter#endif 4438032Speter 4538032Speter#include "sf-pcapng.h" 4638032Speter 4738032Speter/* 4838032Speter * Block types. 4938032Speter */ 50157006Sgshapiro 51157006Sgshapiro/* 52157006Sgshapiro * Common part at the beginning of all blocks. 5338032Speter */ 5438032Speterstruct block_header { 5538032Speter bpf_u_int32 block_type; 5638032Speter bpf_u_int32 total_length; 5738032Speter}; 5838032Speter 5938032Speter/* 6064565Sgshapiro * Common trailer at the end of all blocks. 6138032Speter */ 6290795Sgshapirostruct block_trailer { 6338032Speter bpf_u_int32 total_length; 6438032Speter}; 6538032Speter 6638032Speter/* 6738032Speter * Common options. 6838032Speter */ 6938032Speter#define OPT_ENDOFOPT 0 /* end of options */ 7038032Speter#define OPT_COMMENT 1 /* comment string */ 7138032Speter 7238032Speter/* 7338032Speter * Option header. 7438032Speter */ 7538032Speterstruct option_header { 7638032Speter u_short option_code; 7738032Speter u_short option_length; 7838032Speter}; 7938032Speter 8038032Speter/* 8138032Speter * Structures for the part of each block type following the common 8238032Speter * part. 8338032Speter */ 8438032Speter 8538032Speter/* 8638032Speter * Section Header Block. 8738032Speter */ 8838032Speter#define BT_SHB 0x0A0D0D0A 8938032Speter#define BT_SHB_INSANE_MAX 1024U*1024U*1U /* 1MB should be enough */ 9038032Speterstruct section_header_block { 9138032Speter bpf_u_int32 byte_order_magic; 9238032Speter u_short major_version; 9338032Speter u_short minor_version; 9438032Speter uint64_t section_length; 9538032Speter /* followed by options and trailer */ 9638032Speter}; 9738032Speter 9838032Speter/* 9938032Speter * Byte-order magic value. 10038032Speter */ 10190795Sgshapiro#define BYTE_ORDER_MAGIC 0x1A2B3C4D 10238032Speter 10338032Speter/* 10490795Sgshapiro * Current version number. If major_version isn't PCAP_NG_VERSION_MAJOR, 10590795Sgshapiro * or if minor_version isn't PCAP_NG_VERSION_MINOR or 2, that means that 10638032Speter * this code can't read the file. 10738032Speter */ 10864565Sgshapiro#define PCAP_NG_VERSION_MAJOR 1 10990795Sgshapiro#define PCAP_NG_VERSION_MINOR 0 11090795Sgshapiro 11138032Speter/* 11238032Speter * Interface Description Block. 11338032Speter */ 11438032Speter#define BT_IDB 0x00000001 11590795Sgshapiro 11638032Speterstruct interface_description_block { 11738032Speter u_short linktype; 11838032Speter u_short reserved; 11938032Speter bpf_u_int32 snaplen; 12038032Speter /* followed by options and trailer */ 12138032Speter}; 12238032Speter 12338032Speter/* 12438032Speter * Options in the IDB. 12538032Speter */ 12638032Speter#define IF_NAME 2 /* interface name string */ 12738032Speter#define IF_DESCRIPTION 3 /* interface description string */ 12838032Speter#define IF_IPV4ADDR 4 /* interface's IPv4 address and netmask */ 12938032Speter#define IF_IPV6ADDR 5 /* interface's IPv6 address and prefix length */ 13038032Speter#define IF_MACADDR 6 /* interface's MAC address */ 13138032Speter#define IF_EUIADDR 7 /* interface's EUI address */ 13238032Speter#define IF_SPEED 8 /* interface's speed, in bits/s */ 13338032Speter#define IF_TSRESOL 9 /* interface's time stamp resolution */ 13438032Speter#define IF_TZONE 10 /* interface's time zone */ 13538032Speter#define IF_FILTER 11 /* filter used when capturing on interface */ 13638032Speter#define IF_OS 12 /* string OS on which capture on this interface was done */ 13738032Speter#define IF_FCSLEN 13 /* FCS length for this interface */ 13838032Speter#define IF_TSOFFSET 14 /* time stamp offset for this interface */ 13938032Speter 14038032Speter/* 14138032Speter * Enhanced Packet Block. 14238032Speter */ 143168520Sgshapiro#define BT_EPB 0x00000006 144168520Sgshapiro 14564565Sgshapirostruct enhanced_packet_block { 14638032Speter bpf_u_int32 interface_id; 14738032Speter bpf_u_int32 timestamp_high; 14838032Speter bpf_u_int32 timestamp_low; 14938032Speter bpf_u_int32 caplen; 15038032Speter bpf_u_int32 len; 15138032Speter /* followed by packet data, options, and trailer */ 15238032Speter}; 15338032Speter 15438032Speter/* 15538032Speter * Simple Packet Block. 15638032Speter */ 15738032Speter#define BT_SPB 0x00000003 15894337Sgshapiro 15964565Sgshapirostruct simple_packet_block { 16064565Sgshapiro bpf_u_int32 len; 16164565Sgshapiro /* followed by packet data and trailer */ 16264565Sgshapiro}; 16338032Speter 16464565Sgshapiro/* 16538032Speter * Packet Block. 16664565Sgshapiro */ 16764565Sgshapiro#define BT_PB 0x00000002 16890795Sgshapiro 16938032Speterstruct packet_block { 17038032Speter u_short interface_id; 17138032Speter u_short drops_count; 17238032Speter bpf_u_int32 timestamp_high; 17338032Speter bpf_u_int32 timestamp_low; 17438032Speter bpf_u_int32 caplen; 17538032Speter bpf_u_int32 len; 17638032Speter /* followed by packet data, options, and trailer */ 17738032Speter}; 17890795Sgshapiro 17938032Speter/* 18038032Speter * Block cursor - used when processing the contents of a block. 18138032Speter * Contains a pointer into the data being processed and a count 18238032Speter * of bytes remaining in the block. 18338032Speter */ 18438032Speterstruct block_cursor { 18590795Sgshapiro u_char *data; 18690795Sgshapiro size_t data_remaining; 18738032Speter bpf_u_int32 block_type; 18838032Speter}; 18938032Speter 19038032Spetertypedef enum { 19138032Speter PASS_THROUGH, 19238032Speter SCALE_UP_DEC, 19364565Sgshapiro SCALE_DOWN_DEC, 19438032Speter SCALE_UP_BIN, 19538032Speter SCALE_DOWN_BIN 19638032Speter} tstamp_scale_type_t; 19738032Speter 19838032Speter/* 19938032Speter * Per-interface information. 20038032Speter */ 20138032Speterstruct pcap_ng_if { 20238032Speter uint32_t snaplen; /* snapshot length */ 20338032Speter uint64_t tsresol; /* time stamp resolution */ 20438032Speter tstamp_scale_type_t scale_type; /* how to scale */ 20538032Speter uint64_t scale_factor; /* time stamp scale factor for power-of-10 tsresol */ 20638032Speter uint64_t tsoffset; /* time stamp offset */ 20738032Speter}; 20838032Speter 20938032Speter/* 21038032Speter * Per-pcap_t private data. 21190795Sgshapiro * 21290795Sgshapiro * max_blocksize is the maximum size of a block that we'll accept. We 21390795Sgshapiro * reject blocks bigger than this, so we don't consume too much memory 21438032Speter * with a truly huge block. It can change as we see IDBs with different 21538032Speter * link-layer header types. (Currently, we don't support IDBs with 21664565Sgshapiro * different link-layer header types, but we will support it in the 21790795Sgshapiro * future, when we offer file-reading APIs that support it.) 21890795Sgshapiro * 21938032Speter * XXX - that's an issue on ILP32 platforms, where the maximum block 22064565Sgshapiro * size of 2^31-1 would eat all but one byte of the entire address space. 22138032Speter * It's less of an issue on ILP64/LLP64 platforms, but the actual size 22238032Speter * of the address space may be limited by 1) the number of *significant* 22338032Speter * address bits (currently, x86-64 only supports 48 bits of address), 2) 22438032Speter * any limitations imposed by the operating system; 3) any limitations 22538032Speter * imposed by the amount of available backing store for anonymous pages, 22638032Speter * so we impose a limit regardless of the size of a pointer. 22738032Speter */ 22838032Speterstruct pcap_ng_sf { 22938032Speter uint64_t user_tsresol; /* time stamp resolution requested by the user */ 23090795Sgshapiro u_int max_blocksize; /* don't grow buffer size past this */ 23138032Speter bpf_u_int32 ifcount; /* number of interfaces seen in this capture */ 23290795Sgshapiro bpf_u_int32 ifaces_size; /* size of array below */ 23338032Speter struct pcap_ng_if *ifaces; /* array of interface information */ 23438032Speter}; 23538032Speter 23638032Speter/* 23790795Sgshapiro * The maximum block size we start with; we use an arbitrary value of 23838032Speter * 16 MiB. 23990795Sgshapiro */ 24038032Speter#define INITIAL_MAX_BLOCKSIZE (16*1024*1024) 24138032Speter 24238032Speter/* 24338032Speter * Maximum block size for a given maximum snapshot length; we define it 24438032Speter * as the size of an EPB with a max_snaplen-sized packet and 128KB of 24590795Sgshapiro * options. 24690795Sgshapiro */ 24790795Sgshapiro#define MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen) \ 24890795Sgshapiro (sizeof (struct block_header) + \ 24990795Sgshapiro sizeof (struct enhanced_packet_block) + \ 25090795Sgshapiro (max_snaplen) + 131072 + \ 25138032Speter sizeof (struct block_trailer)) 25290795Sgshapiro 25390795Sgshapirostatic void pcap_ng_cleanup(pcap_t *p); 25490795Sgshapirostatic int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, 25590795Sgshapiro u_char **data); 25690795Sgshapiro 25790795Sgshapirostatic int 25890795Sgshapiroread_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof, 25990795Sgshapiro char *errbuf) 26090795Sgshapiro{ 26190795Sgshapiro size_t amt_read; 26238032Speter 26390795Sgshapiro amt_read = fread(buf, 1, bytes_to_read, fp); 26438032Speter if (amt_read != bytes_to_read) { 26538032Speter if (ferror(fp)) { 26638032Speter pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 26790795Sgshapiro errno, "error reading dump file"); 26890795Sgshapiro } else { 26938032Speter if (amt_read == 0 && !fail_on_eof) 27038032Speter return (0); /* EOF */ 27138032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 27238032Speter "truncated pcapng dump file; tried to read %zu bytes, only got %zu", 27338032Speter bytes_to_read, amt_read); 27438032Speter } 27538032Speter return (-1); 27638032Speter } 27738032Speter return (1); 27838032Speter} 27938032Speter 28038032Speterstatic int 28138032Speterread_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf) 28238032Speter{ 28338032Speter struct pcap_ng_sf *ps; 28438032Speter int status; 28538032Speter struct block_header bhdr; 28671348Sgshapiro struct block_trailer *btrlr; 28738032Speter u_char *bdata; 28838032Speter size_t data_remaining; 28971348Sgshapiro 29038032Speter ps = p->priv; 291223067Sgshapiro 29290795Sgshapiro status = read_bytes(fp, &bhdr, sizeof(bhdr), 0, errbuf); 293223067Sgshapiro if (status <= 0) 294223067Sgshapiro return (status); /* error or EOF */ 295223067Sgshapiro 296223067Sgshapiro if (p->swapped) { 297223067Sgshapiro bhdr.block_type = SWAPLONG(bhdr.block_type); 298223067Sgshapiro bhdr.total_length = SWAPLONG(bhdr.total_length); 299223067Sgshapiro } 300223067Sgshapiro 301223067Sgshapiro /* 302223067Sgshapiro * Is this block "too small" - i.e., is it shorter than a block 303223067Sgshapiro * header plus a block trailer? 304223067Sgshapiro */ 305223067Sgshapiro if (bhdr.total_length < sizeof(struct block_header) + 306223067Sgshapiro sizeof(struct block_trailer)) { 307223067Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, 308223067Sgshapiro "block in pcapng dump file has a length of %u < %zu", 309223067Sgshapiro bhdr.total_length, 310223067Sgshapiro sizeof(struct block_header) + sizeof(struct block_trailer)); 311223067Sgshapiro return (-1); 312223067Sgshapiro } 313223067Sgshapiro 314223067Sgshapiro /* 315223067Sgshapiro * Is the block total length a multiple of 4? 316223067Sgshapiro */ 317223067Sgshapiro if ((bhdr.total_length % 4) != 0) { 31838032Speter /* 31990795Sgshapiro * No. Report that as an error. 32090795Sgshapiro */ 32190795Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, 32290795Sgshapiro "block in pcapng dump file has a length of %u that is not a multiple of 4", 32390795Sgshapiro bhdr.total_length); 32490795Sgshapiro return (-1); 32590795Sgshapiro } 32638032Speter 32738032Speter /* 32838032Speter * Is the buffer big enough? 32938032Speter */ 33038032Speter if (p->bufsize < bhdr.total_length) { 33138032Speter /* 33238032Speter * No - make it big enough, unless it's too big, in 33338032Speter * which case we fail. 33438032Speter */ 33538032Speter void *bigger_buffer; 33638032Speter 33738032Speter if (bhdr.total_length > ps->max_blocksize) { 338168520Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, "pcapng block size %u > maximum %u", bhdr.total_length, 33938032Speter ps->max_blocksize); 34038032Speter return (-1); 34138032Speter } 34238032Speter bigger_buffer = realloc(p->buffer, bhdr.total_length); 34338032Speter if (bigger_buffer == NULL) { 34471348Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); 34564565Sgshapiro return (-1); 34638032Speter } 34738032Speter p->buffer = bigger_buffer; 34838032Speter } 34990795Sgshapiro 35090795Sgshapiro /* 35190795Sgshapiro * Copy the stuff we've read to the buffer, and read the rest 35290795Sgshapiro * of the block. 35390795Sgshapiro */ 35490795Sgshapiro memcpy(p->buffer, &bhdr, sizeof(bhdr)); 355285303Sgshapiro bdata = (u_char *)p->buffer + sizeof(bhdr); 35690795Sgshapiro data_remaining = bhdr.total_length - sizeof(bhdr); 35790795Sgshapiro if (read_bytes(fp, bdata, data_remaining, 1, errbuf) == -1) 35890795Sgshapiro return (-1); 35990795Sgshapiro 36090795Sgshapiro /* 36190795Sgshapiro * Get the block size from the trailer. 36290795Sgshapiro */ 36364565Sgshapiro btrlr = (struct block_trailer *)(bdata + data_remaining - sizeof (struct block_trailer)); 36490795Sgshapiro if (p->swapped) 36564565Sgshapiro btrlr->total_length = SWAPLONG(btrlr->total_length); 36664565Sgshapiro 36764565Sgshapiro /* 36864565Sgshapiro * Is the total length from the trailer the same as the total 36964565Sgshapiro * length from the header? 37064565Sgshapiro */ 37138032Speter if (bhdr.total_length != btrlr->total_length) { 37238032Speter /* 37390795Sgshapiro * No. 37464565Sgshapiro */ 37538032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 37638032Speter "block total length in header and trailer don't match"); 37738032Speter return (-1); 37838032Speter } 37938032Speter 38038032Speter /* 38138032Speter * Initialize the cursor. 38238032Speter */ 38390795Sgshapiro cursor->data = bdata; 38438032Speter cursor->data_remaining = data_remaining - sizeof(struct block_trailer); 38538032Speter cursor->block_type = bhdr.block_type; 38638032Speter return (1); 38738032Speter} 38838032Speter 38938032Speterstatic void * 39038032Speterget_from_block_data(struct block_cursor *cursor, size_t chunk_size, 39138032Speter char *errbuf) 39238032Speter{ 39338032Speter void *data; 39438032Speter 39538032Speter /* 39638032Speter * Make sure we have the specified amount of data remaining in 39738032Speter * the block data. 39838032Speter */ 39938032Speter if (cursor->data_remaining < chunk_size) { 40038032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 40138032Speter "block of type %u in pcapng dump file is too short", 40290795Sgshapiro cursor->block_type); 40338032Speter return (NULL); 404168520Sgshapiro } 40538032Speter 40690795Sgshapiro /* 40790795Sgshapiro * Return the current pointer, and skip past the chunk. 40838032Speter */ 40938032Speter data = cursor->data; 41038032Speter cursor->data += chunk_size; 41138032Speter cursor->data_remaining -= chunk_size; 41238032Speter return (data); 41338032Speter} 41438032Speter 41538032Speterstatic struct option_header * 41694337Sgshapiroget_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf) 41738032Speter{ 41838032Speter struct option_header *opthdr; 41938032Speter 42038032Speter opthdr = get_from_block_data(cursor, sizeof(*opthdr), errbuf); 42138032Speter if (opthdr == NULL) { 42238032Speter /* 42338032Speter * Option header is cut short. 42438032Speter */ 42538032Speter return (NULL); 426141887Sgshapiro } 42790795Sgshapiro 428141887Sgshapiro /* 429141887Sgshapiro * Byte-swap it if necessary. 430141887Sgshapiro */ 431141887Sgshapiro if (p->swapped) { 432141887Sgshapiro opthdr->option_code = SWAPSHORT(opthdr->option_code); 433141887Sgshapiro opthdr->option_length = SWAPSHORT(opthdr->option_length); 434141887Sgshapiro } 435141887Sgshapiro 436141887Sgshapiro return (opthdr); 437141887Sgshapiro} 438141887Sgshapiro 439141887Sgshapirostatic void * 440141887Sgshapiroget_optvalue_from_block_data(struct block_cursor *cursor, 441141887Sgshapiro struct option_header *opthdr, char *errbuf) 442141887Sgshapiro{ 443141887Sgshapiro size_t padded_option_len; 444141887Sgshapiro void *optvalue; 445141887Sgshapiro 446141887Sgshapiro /* Pad option length to 4-byte boundary */ 447141887Sgshapiro padded_option_len = opthdr->option_length; 448141887Sgshapiro padded_option_len = ((padded_option_len + 3)/4)*4; 449141887Sgshapiro 450141887Sgshapiro optvalue = get_from_block_data(cursor, padded_option_len, errbuf); 451141887Sgshapiro if (optvalue == NULL) { 452141887Sgshapiro /* 453141887Sgshapiro * Option value is cut short. 454141887Sgshapiro */ 455141887Sgshapiro return (NULL); 456141887Sgshapiro } 457141887Sgshapiro 458141887Sgshapiro return (optvalue); 459141887Sgshapiro} 460141887Sgshapiro 461141887Sgshapirostatic int 462141887Sgshapiroprocess_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, 463141887Sgshapiro uint64_t *tsoffset, int *is_binary, char *errbuf) 464141887Sgshapiro{ 465141887Sgshapiro struct option_header *opthdr; 466141887Sgshapiro void *optvalue; 467141887Sgshapiro int saw_tsresol, saw_tsoffset; 468141887Sgshapiro uint8_t tsresol_opt; 469141887Sgshapiro u_int i; 470141887Sgshapiro 471141887Sgshapiro saw_tsresol = 0; 472141887Sgshapiro saw_tsoffset = 0; 473141887Sgshapiro while (cursor->data_remaining != 0) { 474141887Sgshapiro /* 475141887Sgshapiro * Get the option header. 476141887Sgshapiro */ 477141887Sgshapiro opthdr = get_opthdr_from_block_data(p, cursor, errbuf); 47890795Sgshapiro if (opthdr == NULL) { 47990795Sgshapiro /* 48090795Sgshapiro * Option header is cut short. 48190795Sgshapiro */ 48290795Sgshapiro return (-1); 48390795Sgshapiro } 48490795Sgshapiro 48590795Sgshapiro /* 48690795Sgshapiro * Get option value. 48790795Sgshapiro */ 48890795Sgshapiro optvalue = get_optvalue_from_block_data(cursor, opthdr, 48990795Sgshapiro errbuf); 49090795Sgshapiro if (optvalue == NULL) { 49190795Sgshapiro /* 49290795Sgshapiro * Option value is cut short. 49390795Sgshapiro */ 494168520Sgshapiro return (-1); 49590795Sgshapiro } 496168520Sgshapiro 497168520Sgshapiro switch (opthdr->option_code) { 49890795Sgshapiro 49990795Sgshapiro case OPT_ENDOFOPT: 50090795Sgshapiro if (opthdr->option_length != 0) { 50190795Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, 50290795Sgshapiro "Interface Description Block has opt_endofopt option with length %u != 0", 50364565Sgshapiro opthdr->option_length); 50490795Sgshapiro return (-1); 50590795Sgshapiro } 50690795Sgshapiro goto done; 50790795Sgshapiro 50890795Sgshapiro case IF_TSRESOL: 50990795Sgshapiro if (opthdr->option_length != 1) { 51090795Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, 51164565Sgshapiro "Interface Description Block has if_tsresol option with length %u != 1", 51264565Sgshapiro opthdr->option_length); 51364565Sgshapiro return (-1); 51464565Sgshapiro } 51564565Sgshapiro if (saw_tsresol) { 51664565Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, 51764565Sgshapiro "Interface Description Block has more than one if_tsresol option"); 51864565Sgshapiro return (-1); 51964565Sgshapiro } 52064565Sgshapiro saw_tsresol = 1; 52171348Sgshapiro memcpy(&tsresol_opt, optvalue, sizeof(tsresol_opt)); 52290795Sgshapiro if (tsresol_opt & 0x80) { 52364565Sgshapiro /* 52464565Sgshapiro * Resolution is negative power of 2. 52590795Sgshapiro */ 52664565Sgshapiro uint8_t tsresol_shift = (tsresol_opt & 0x7F); 52764565Sgshapiro 52890795Sgshapiro if (tsresol_shift > 63) { 52964565Sgshapiro /* 53090795Sgshapiro * Resolution is too high; 2^-{res} 53138032Speter * won't fit in a 64-bit value. 53238032Speter */ 53338032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 53438032Speter "Interface Description Block if_tsresol option resolution 2^-%u is too high", 53538032Speter tsresol_shift); 53638032Speter return (-1); 53738032Speter } 53838032Speter *is_binary = 1; 53938032Speter *tsresol = ((uint64_t)1) << tsresol_shift; 54038032Speter } else { 54138032Speter /* 54238032Speter * Resolution is negative power of 10. 54338032Speter */ 54438032Speter if (tsresol_opt > 19) { 54538032Speter /* 54638032Speter * Resolution is too high; 2^-{res} 54738032Speter * won't fit in a 64-bit value (the 54838032Speter * largest power of 10 that fits 54938032Speter * in a 64-bit value is 10^19, as 55038032Speter * the largest 64-bit unsigned 55138032Speter * value is ~1.8*10^19). 55238032Speter */ 55338032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 55490795Sgshapiro "Interface Description Block if_tsresol option resolution 10^-%u is too high", 55590795Sgshapiro tsresol_opt); 55690795Sgshapiro return (-1); 55790795Sgshapiro } 55890795Sgshapiro *is_binary = 0; 55938032Speter *tsresol = 1; 56090795Sgshapiro for (i = 0; i < tsresol_opt; i++) 56138032Speter *tsresol *= 10; 56290795Sgshapiro } 56338032Speter break; 56438032Speter 56538032Speter case IF_TSOFFSET: 566132946Sgshapiro if (opthdr->option_length != 8) { 56738032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 56838032Speter "Interface Description Block has if_tsoffset option with length %u != 8", 56938032Speter opthdr->option_length); 57038032Speter return (-1); 57138032Speter } 57238032Speter if (saw_tsoffset) { 57338032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 57438032Speter "Interface Description Block has more than one if_tsoffset option"); 57538032Speter return (-1); 57638032Speter } 57738032Speter saw_tsoffset = 1; 57838032Speter memcpy(tsoffset, optvalue, sizeof(*tsoffset)); 57938032Speter if (p->swapped) 58038032Speter *tsoffset = SWAPLL(*tsoffset); 58164565Sgshapiro break; 58238032Speter 58338032Speter default: 58438032Speter break; 58538032Speter } 58638032Speter } 58738032Speter 58838032Speterdone: 58938032Speter return (0); 59038032Speter} 59138032Speter 59238032Speterstatic int 59338032Speteradd_interface(pcap_t *p, struct interface_description_block *idbp, 59438032Speter struct block_cursor *cursor, char *errbuf) 59538032Speter{ 59690795Sgshapiro struct pcap_ng_sf *ps; 597223067Sgshapiro uint64_t tsresol; 59890795Sgshapiro uint64_t tsoffset; 59990795Sgshapiro int is_binary; 60090795Sgshapiro 60190795Sgshapiro ps = p->priv; 60290795Sgshapiro 60390795Sgshapiro /* 60490795Sgshapiro * Count this interface. 60590795Sgshapiro */ 60671348Sgshapiro ps->ifcount++; 60738032Speter 60838032Speter /* 60938032Speter * Grow the array of per-interface information as necessary. 610132946Sgshapiro */ 611132946Sgshapiro if (ps->ifcount > ps->ifaces_size) { 61238032Speter /* 61338032Speter * We need to grow the array. 61438032Speter */ 61538032Speter bpf_u_int32 new_ifaces_size; 61638032Speter struct pcap_ng_if *new_ifaces; 61738032Speter 61838032Speter if (ps->ifaces_size == 0) { 61938032Speter /* 62038032Speter * It's currently empty. 62190795Sgshapiro * 62238032Speter * (The Clang static analyzer doesn't do enough, 62338032Speter * err, umm, dataflow *analysis* to realize that 62438032Speter * ps->ifaces_size == 0 if ps->ifaces == NULL, 62590795Sgshapiro * and so complains about a possible zero argument 62638032Speter * to realloc(), so we check for the former 62738032Speter * condition to shut it up. 62890795Sgshapiro * 62938032Speter * However, it doesn't complain that one of the 630120259Sgshapiro * multiplications below could overflow, which is 631120259Sgshapiro * a real, albeit extremely unlikely, problem (you'd 632120259Sgshapiro * need a pcapng file with tens of millions of 633120259Sgshapiro * interfaces).) 634120259Sgshapiro */ 635120259Sgshapiro new_ifaces_size = 1; 636120259Sgshapiro new_ifaces = malloc(sizeof (struct pcap_ng_if)); 637120259Sgshapiro } else { 638120259Sgshapiro /* 639120259Sgshapiro * It's not currently empty; double its size. 64038032Speter * (Perhaps overkill once we have a lot of interfaces.) 64138032Speter * 64238032Speter * Check for overflow if we double it. 64338032Speter */ 644120259Sgshapiro if (ps->ifaces_size * 2 < ps->ifaces_size) { 64538032Speter /* 64638032Speter * The maximum number of interfaces before 64738032Speter * ps->ifaces_size overflows is the largest 64838032Speter * possible 32-bit power of 2, as we do 64990795Sgshapiro * size doubling. 65090795Sgshapiro */ 65138032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 65238032Speter "more than %u interfaces in the file", 65338032Speter 0x80000000U); 65438032Speter return (0); 65590795Sgshapiro } 65690795Sgshapiro 65790795Sgshapiro /* 65838032Speter * ps->ifaces_size * 2 doesn't overflow, so it's 65938032Speter * safe to multiply. 66064565Sgshapiro */ 66138032Speter new_ifaces_size = ps->ifaces_size * 2; 66290795Sgshapiro 66338032Speter /* 66490795Sgshapiro * Now make sure that's not so big that it overflows 66538032Speter * if we multiply by sizeof (struct pcap_ng_if). 66638032Speter * 66738032Speter * That can happen on 32-bit platforms, with a 32-bit 66890795Sgshapiro * size_t; it shouldn't happen on 64-bit platforms, 66938032Speter * with a 64-bit size_t, as new_ifaces_size is 67090795Sgshapiro * 32 bits. 67138032Speter */ 67290795Sgshapiro if (new_ifaces_size * sizeof (struct pcap_ng_if) < new_ifaces_size) { 67338032Speter /* 67490795Sgshapiro * As this fails only with 32-bit size_t, 67538032Speter * the multiplication was 32x32->32, and 67638032Speter * the largest 32-bit value that can safely 67738032Speter * be multiplied by sizeof (struct pcap_ng_if) 67838032Speter * without overflow is the largest 32-bit 679132946Sgshapiro * (unsigned) value divided by 68038032Speter * sizeof (struct pcap_ng_if). 68190795Sgshapiro */ 68238032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 68338032Speter "more than %u interfaces in the file", 68438032Speter 0xFFFFFFFFU / ((u_int)sizeof (struct pcap_ng_if))); 685132946Sgshapiro return (0); 68638032Speter } 68738032Speter new_ifaces = realloc(ps->ifaces, new_ifaces_size * sizeof (struct pcap_ng_if)); 68838032Speter } 68938032Speter if (new_ifaces == NULL) { 69038032Speter /* 69138032Speter * We ran out of memory. 69238032Speter * Give up. 69338032Speter */ 694132946Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, 695132946Sgshapiro "out of memory for per-interface information (%u interfaces)", 69638032Speter ps->ifcount); 69738032Speter return (0); 69838032Speter } 69938032Speter ps->ifaces_size = new_ifaces_size; 70038032Speter ps->ifaces = new_ifaces; 70138032Speter } 70238032Speter 70338032Speter ps->ifaces[ps->ifcount - 1].snaplen = idbp->snaplen; 704132946Sgshapiro 70538032Speter /* 70690795Sgshapiro * Set the default time stamp resolution and offset. 70742580Speter */ 70838032Speter tsresol = 1000000; /* microsecond resolution */ 70938032Speter is_binary = 0; /* which is a power of 10 */ 71038032Speter tsoffset = 0; /* absolute timestamps */ 71138032Speter 71238032Speter /* 71338032Speter * Now look for various time stamp options, so we know 71490795Sgshapiro * how to interpret the time stamps for this interface. 71538032Speter */ 71638032Speter if (process_idb_options(p, cursor, &tsresol, &tsoffset, &is_binary, 71738032Speter errbuf) == -1) 71838032Speter return (0); 71938032Speter 72038032Speter ps->ifaces[ps->ifcount - 1].tsresol = tsresol; 72164565Sgshapiro ps->ifaces[ps->ifcount - 1].tsoffset = tsoffset; 72238032Speter 72338032Speter /* 72438032Speter * Determine whether we're scaling up or down or not 72538032Speter * at all for this interface. 72638032Speter */ 72738032Speter if (tsresol == ps->user_tsresol) { 72838032Speter /* 72938032Speter * The resolution is the resolution the user wants, 73038032Speter * so we don't have to do scaling. 73138032Speter */ 73290795Sgshapiro ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH; 73338032Speter } else if (tsresol > ps->user_tsresol) { 73438032Speter /* 73538032Speter * The resolution is greater than what the user wants, 73638032Speter * so we have to scale the timestamps down. 73738032Speter */ 73838032Speter if (is_binary) 73938032Speter ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN_BIN; 74038032Speter else { 74138032Speter /* 74264565Sgshapiro * Calculate the scale factor. 74338032Speter */ 74438032Speter ps->ifaces[ps->ifcount - 1].scale_factor = tsresol/ps->user_tsresol; 74538032Speter ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN_DEC; 74664565Sgshapiro } 74738032Speter } else { 74898125Sgshapiro /* 74938032Speter * The resolution is less than what the user wants, 75038032Speter * so we have to scale the timestamps up. 75138032Speter */ 75238032Speter if (is_binary) 75338032Speter ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP_BIN; 75490795Sgshapiro else { 75590795Sgshapiro /* 75638032Speter * Calculate the scale factor. 757168520Sgshapiro */ 75890795Sgshapiro ps->ifaces[ps->ifcount - 1].scale_factor = ps->user_tsresol/tsresol; 75938032Speter ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP_DEC; 76038032Speter } 76138032Speter } 76290795Sgshapiro return (1); 76390795Sgshapiro} 76438032Speter 76538032Speter/* 76638032Speter * Check whether this is a pcapng savefile and, if it is, extract the 76738032Speter * relevant information from the header. 76838032Speter */ 76938032Speterpcap_t * 77064565Sgshapiropcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, 77138032Speter char *errbuf, int *err) 77238032Speter{ 77338032Speter bpf_u_int32 magic_int; 77490795Sgshapiro size_t amt_read; 77538032Speter bpf_u_int32 total_length; 77638032Speter bpf_u_int32 byte_order_magic; 77738032Speter struct block_header *bhdrp; 77890795Sgshapiro struct section_header_block *shbp; 77990795Sgshapiro pcap_t *p; 78038032Speter int swapped = 0; 78138032Speter struct pcap_ng_sf *ps; 78290795Sgshapiro int status; 78364565Sgshapiro struct block_cursor cursor; 78490795Sgshapiro struct interface_description_block *idbp; 78538032Speter 78638032Speter /* 78738032Speter * Assume no read errors. 78838032Speter */ 78938032Speter *err = 0; 79038032Speter 79190795Sgshapiro /* 79238032Speter * Check whether the first 4 bytes of the file are the block 79338032Speter * type for a pcapng savefile. 79464565Sgshapiro */ 79538032Speter memcpy(&magic_int, magic, sizeof(magic_int)); 79638032Speter if (magic_int != BT_SHB) { 79790795Sgshapiro /* 79838032Speter * XXX - check whether this looks like what the block 79938032Speter * type would be after being munged by mapping between 80038032Speter * UN*X and DOS/Windows text file format and, if it 80138032Speter * does, look for the byte-order magic number in 80238032Speter * the appropriate place and, if we find it, report 80338032Speter * this as possibly being a pcapng file transferred 80438032Speter * between UN*X and Windows in text file format? 80538032Speter */ 80638032Speter return (NULL); /* nope */ 80738032Speter } 80838032Speter 80938032Speter /* 81038032Speter * OK, they are. However, that's just \n\r\r\n, so it could, 81138032Speter * conceivably, be an ordinary text file. 81238032Speter * 81338032Speter * It could not, however, conceivably be any other type of 81464565Sgshapiro * capture file, so we can read the rest of the putative 81538032Speter * Section Header Block; put the block type in the common 81638032Speter * header, read the rest of the common header and the 81738032Speter * fixed-length portion of the SHB, and look for the byte-order 81838032Speter * magic value. 81990795Sgshapiro */ 82038032Speter amt_read = fread(&total_length, 1, sizeof(total_length), fp); 82138032Speter if (amt_read < sizeof(total_length)) { 82238032Speter if (ferror(fp)) { 82338032Speter pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 82438032Speter errno, "error reading dump file"); 82538032Speter *err = 1; 82638032Speter return (NULL); /* fail */ 82738032Speter } 82838032Speter 82990795Sgshapiro /* 83038032Speter * Possibly a weird short text file, so just say 83138032Speter * "not pcapng". 83238032Speter */ 83338032Speter return (NULL); 83490795Sgshapiro } 83538032Speter amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp); 83638032Speter if (amt_read < sizeof(byte_order_magic)) { 83738032Speter if (ferror(fp)) { 83838032Speter pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 83938032Speter errno, "error reading dump file"); 84090795Sgshapiro *err = 1; 84138032Speter return (NULL); /* fail */ 84238032Speter } 84338032Speter 84464565Sgshapiro /* 84538032Speter * Possibly a weird short text file, so just say 84690795Sgshapiro * "not pcapng". 84742580Speter */ 84838032Speter return (NULL); 84938032Speter } 85038032Speter if (byte_order_magic != BYTE_ORDER_MAGIC) { 85138032Speter byte_order_magic = SWAPLONG(byte_order_magic); 85238032Speter if (byte_order_magic != BYTE_ORDER_MAGIC) { 85390795Sgshapiro /* 85438032Speter * Not a pcapng file. 85538032Speter */ 85690795Sgshapiro return (NULL); 85790795Sgshapiro } 85838032Speter swapped = 1; 85938032Speter total_length = SWAPLONG(total_length); 86064565Sgshapiro } 86138032Speter 86238032Speter /* 86338032Speter * Check the sanity of the total length. 86464565Sgshapiro */ 86590795Sgshapiro if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer) || 86690795Sgshapiro (total_length > BT_SHB_INSANE_MAX)) { 86798125Sgshapiro snprintf(errbuf, PCAP_ERRBUF_SIZE, 86838032Speter "Section Header Block in pcapng dump file has invalid length %zu < _%u_ < %u (BT_SHB_INSANE_MAX)", 86938032Speter sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer), 87038032Speter total_length, 87138032Speter BT_SHB_INSANE_MAX); 87290795Sgshapiro 87390795Sgshapiro *err = 1; 87438032Speter return (NULL); 87538032Speter } 87638032Speter 87790795Sgshapiro /* 87864565Sgshapiro * OK, this is a good pcapng file. 87938032Speter * Allocate a pcap_t for it. 88038032Speter */ 88190795Sgshapiro p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_ng_sf); 88238032Speter if (p == NULL) { 88338032Speter /* Allocation failed. */ 88490795Sgshapiro *err = 1; 88590795Sgshapiro return (NULL); 88664565Sgshapiro } 887168520Sgshapiro p->swapped = swapped; 88890795Sgshapiro ps = p->priv; 88938032Speter 89038032Speter /* 89138032Speter * What precision does the user want? 89290795Sgshapiro */ 89338032Speter switch (precision) { 89438032Speter 89538032Speter case PCAP_TSTAMP_PRECISION_MICRO: 89638032Speter ps->user_tsresol = 1000000; 89738032Speter break; 89838032Speter 89938032Speter case PCAP_TSTAMP_PRECISION_NANO: 90038032Speter ps->user_tsresol = 1000000000; 90138032Speter break; 90290795Sgshapiro 90390795Sgshapiro default: 90438032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 90538032Speter "unknown time stamp resolution %u", precision); 90638032Speter free(p); 90738032Speter *err = 1; 90890795Sgshapiro return (NULL); 90990795Sgshapiro } 91064565Sgshapiro 91164565Sgshapiro p->opt.tstamp_precision = precision; 91264565Sgshapiro 91390795Sgshapiro /* 91490795Sgshapiro * Allocate a buffer into which to read blocks. We default to 91564565Sgshapiro * the maximum of: 91638032Speter * 91790795Sgshapiro * the total length of the SHB for which we read the header; 91838032Speter * 91938032Speter * 2K, which should be more than large enough for an Enhanced 92064565Sgshapiro * Packet Block containing a full-size Ethernet frame, and 92138032Speter * leaving room for some options. 92238032Speter * 92390795Sgshapiro * If we find a bigger block, we reallocate the buffer, up to 92438032Speter * the maximum size. We start out with a maximum size of 92538032Speter * INITIAL_MAX_BLOCKSIZE; if we see any link-layer header types 92638032Speter * with a maximum snapshot that results in a larger maximum 92738032Speter * block length, we boost the maximum. 92838032Speter */ 92938032Speter p->bufsize = 2048; 93038032Speter if (p->bufsize < total_length) 93138032Speter p->bufsize = total_length; 93238032Speter p->buffer = malloc(p->bufsize); 93338032Speter if (p->buffer == NULL) { 93438032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); 93538032Speter free(p); 93638032Speter *err = 1; 93738032Speter return (NULL); 93838032Speter } 93938032Speter ps->max_blocksize = INITIAL_MAX_BLOCKSIZE; 94038032Speter 94138032Speter /* 94264565Sgshapiro * Copy the stuff we've read to the buffer, and read the rest 94338032Speter * of the SHB. 94490795Sgshapiro */ 94538032Speter bhdrp = (struct block_header *)p->buffer; 94638032Speter shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header)); 94738032Speter bhdrp->block_type = magic_int; 94838032Speter bhdrp->total_length = total_length; 94938032Speter shbp->byte_order_magic = byte_order_magic; 95038032Speter if (read_bytes(fp, 95138032Speter (u_char *)p->buffer + (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)), 95238032Speter total_length - (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)), 953159613Sgshapiro 1, errbuf) == -1) 95438032Speter goto fail; 955159613Sgshapiro 956159613Sgshapiro if (p->swapped) { 957159613Sgshapiro /* 95838032Speter * Byte-swap the fields we've read. 959159613Sgshapiro */ 96038032Speter shbp->major_version = SWAPSHORT(shbp->major_version); 961159613Sgshapiro shbp->minor_version = SWAPSHORT(shbp->minor_version); 962159613Sgshapiro 963159613Sgshapiro /* 96438032Speter * XXX - we don't care about the section length. 96538032Speter */ 96690795Sgshapiro } 96790795Sgshapiro /* Currently only SHB versions 1.0 and 1.2 are supported; 96838032Speter version 1.2 is treated as being the same as version 1.0. 96938032Speter See the current version of the pcapng specification. 97090795Sgshapiro 97190795Sgshapiro Version 1.2 is written by some programs that write additional 97238032Speter block types (which can be read by any code that handles them, 97390795Sgshapiro regardless of whether the minor version if 0 or 2, so that's 97438032Speter not a reason to change the minor version number). 97538032Speter 976249729Sgshapiro XXX - the pcapng specification says that readers should 97738032Speter just ignore sections with an unsupported version number; 97838032Speter presumably they can also report an error if they skip 97938032Speter all the way to the end of the file without finding 98038032Speter any versions that they support. */ 98138032Speter if (! (shbp->major_version == PCAP_NG_VERSION_MAJOR && 98238032Speter (shbp->minor_version == PCAP_NG_VERSION_MINOR || 98338032Speter shbp->minor_version == 2))) { 98438032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 98538032Speter "unsupported pcapng savefile version %u.%u", 98638032Speter shbp->major_version, shbp->minor_version); 98738032Speter goto fail; 98838032Speter } 98938032Speter p->version_major = shbp->major_version; 99038032Speter p->version_minor = shbp->minor_version; 99138032Speter 99238032Speter /* 99338032Speter * Save the time stamp resolution the user requested. 99438032Speter */ 99538032Speter p->opt.tstamp_precision = precision; 99638032Speter 99738032Speter /* 99838032Speter * Now start looking for an Interface Description Block. 99938032Speter */ 100038032Speter for (;;) { 100138032Speter /* 100238032Speter * Read the next block. 100338032Speter */ 100438032Speter status = read_block(fp, p, &cursor, errbuf); 100538032Speter if (status == 0) { 100638032Speter /* EOF - no IDB in this file */ 100738032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 100838032Speter "the capture file has no Interface Description Blocks"); 100938032Speter goto fail; 101038032Speter } 101138032Speter if (status == -1) 101238032Speter goto fail; /* error */ 101338032Speter switch (cursor.block_type) { 101438032Speter 101538032Speter case BT_IDB: 101690795Sgshapiro /* 1017132946Sgshapiro * Get a pointer to the fixed-length portion of the 101838032Speter * IDB. 101938032Speter */ 102038032Speter idbp = get_from_block_data(&cursor, sizeof(*idbp), 102138032Speter errbuf); 102238032Speter if (idbp == NULL) 102338032Speter goto fail; /* error */ 102438032Speter 102538032Speter /* 102638032Speter * Byte-swap it if necessary. 102738032Speter */ 102838032Speter if (p->swapped) { 102938032Speter idbp->linktype = SWAPSHORT(idbp->linktype); 103090795Sgshapiro idbp->snaplen = SWAPLONG(idbp->snaplen); 103190795Sgshapiro } 103238032Speter 103338032Speter /* 103438032Speter * Try to add this interface. 103538032Speter */ 103690795Sgshapiro if (!add_interface(p, idbp, &cursor, errbuf)) 103738032Speter goto fail; 103838032Speter 103938032Speter goto done; 104038032Speter 104138032Speter case BT_EPB: 104238032Speter case BT_SPB: 104338032Speter case BT_PB: 104438032Speter /* 104538032Speter * Saw a packet before we saw any IDBs. That's 104638032Speter * not valid, as we don't know what link-layer 104738032Speter * encapsulation the packet has. 104838032Speter */ 104938032Speter snprintf(errbuf, PCAP_ERRBUF_SIZE, 105038032Speter "the capture file has a packet block before any Interface Description Blocks"); 105138032Speter goto fail; 105238032Speter 105364565Sgshapiro default: 105438032Speter /* 105538032Speter * Just ignore it. 105638032Speter */ 105738032Speter break; 105890795Sgshapiro } 105938032Speter } 106038032Speter 106138032Speterdone: 106238032Speter p->linktype = linktype_to_dlt(idbp->linktype); 106338032Speter p->snapshot = pcap_adjust_snapshot(p->linktype, idbp->snaplen); 106438032Speter p->linktype_ext = 0; 106538032Speter 106690795Sgshapiro /* 106790795Sgshapiro * If the maximum block size for a packet with the maximum 106838032Speter * snapshot length for this DLT_ is bigger than the current 106938032Speter * maximum block size, increase the maximum. 107038032Speter */ 107138032Speter if (MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype)) > ps->max_blocksize) 107290795Sgshapiro ps->max_blocksize = MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype)); 107338032Speter 107438032Speter p->next_packet_op = pcap_ng_next_packet; 107538032Speter p->cleanup_op = pcap_ng_cleanup; 107690795Sgshapiro 107738032Speter return (p); 107890795Sgshapiro 107990795Sgshapirofail: 108064565Sgshapiro free(ps->ifaces); 108138032Speter free(p->buffer); 108290795Sgshapiro free(p); 108390795Sgshapiro *err = 1; 108490795Sgshapiro return (NULL); 108590795Sgshapiro} 108690795Sgshapiro 108790795Sgshapirostatic void 108890795Sgshapiropcap_ng_cleanup(pcap_t *p) 108938032Speter{ 109090795Sgshapiro struct pcap_ng_sf *ps = p->priv; 109190795Sgshapiro 109290795Sgshapiro free(ps->ifaces); 109338032Speter sf_cleanup(p); 109490795Sgshapiro} 109590795Sgshapiro 109690795Sgshapiro/* 109790795Sgshapiro * Read and return the next packet from the savefile. Return the header 109890795Sgshapiro * in hdr and a pointer to the contents in data. Return 1 on success, 0 109990795Sgshapiro * if there were no more packets, and -1 on an error. 110038032Speter */ 110190795Sgshapirostatic int 110238032Speterpcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) 110364565Sgshapiro{ 110438032Speter struct pcap_ng_sf *ps = p->priv; 110538032Speter struct block_cursor cursor; 110690795Sgshapiro int status; 110738032Speter struct enhanced_packet_block *epbp; 110838032Speter struct simple_packet_block *spbp; 110938032Speter struct packet_block *pbp; 111038032Speter bpf_u_int32 interface_id = 0xFFFFFFFF; 111138032Speter struct interface_description_block *idbp; 111238032Speter struct section_header_block *shbp; 111338032Speter FILE *fp = p->rfile; 111438032Speter uint64_t t, sec, frac; 111538032Speter 111638032Speter /* 111738032Speter * Look for an Enhanced Packet Block, a Simple Packet Block, 111838032Speter * or a Packet Block. 111938032Speter */ 112038032Speter for (;;) { 112138032Speter /* 112238032Speter * Read the block type and length; those are common 112338032Speter * to all blocks. 112438032Speter */ 112538032Speter status = read_block(fp, p, &cursor, p->errbuf); 112638032Speter if (status == 0) 112738032Speter return (0); /* EOF */ 112864565Sgshapiro if (status == -1) 112938032Speter return (-1); /* error */ 113038032Speter switch (cursor.block_type) { 113138032Speter 113238032Speter case BT_EPB: 1133141862Sgshapiro /* 113438032Speter * Get a pointer to the fixed-length portion of the 113538032Speter * EPB. 113638032Speter */ 113738032Speter epbp = get_from_block_data(&cursor, sizeof(*epbp), 113838032Speter p->errbuf); 113938032Speter if (epbp == NULL) 114038032Speter return (-1); /* error */ 114138032Speter 114238032Speter /* 114338032Speter * Byte-swap it if necessary. 114438032Speter */ 114538032Speter if (p->swapped) { 114690795Sgshapiro /* these were written in opposite byte order */ 114738032Speter interface_id = SWAPLONG(epbp->interface_id); 114838032Speter hdr->caplen = SWAPLONG(epbp->caplen); 114938032Speter hdr->len = SWAPLONG(epbp->len); 115038032Speter t = ((uint64_t)SWAPLONG(epbp->timestamp_high)) << 32 | 115138032Speter SWAPLONG(epbp->timestamp_low); 115290795Sgshapiro } else { 115390795Sgshapiro interface_id = epbp->interface_id; 115438032Speter hdr->caplen = epbp->caplen; 115538032Speter hdr->len = epbp->len; 115638032Speter t = ((uint64_t)epbp->timestamp_high) << 32 | 115738032Speter epbp->timestamp_low; 115890795Sgshapiro } 115990795Sgshapiro goto found; 116090795Sgshapiro 116138032Speter case BT_SPB: 116298125Sgshapiro /* 1163157006Sgshapiro * Get a pointer to the fixed-length portion of the 1164157006Sgshapiro * SPB. 1165157006Sgshapiro */ 116638032Speter spbp = get_from_block_data(&cursor, sizeof(*spbp), 116738032Speter p->errbuf); 116838032Speter if (spbp == NULL) 116938032Speter return (-1); /* error */ 117090795Sgshapiro 117190795Sgshapiro /* 117238032Speter * SPB packets are assumed to have arrived on 117338032Speter * the first interface. 1174182352Sgshapiro */ 1175182352Sgshapiro interface_id = 0; 1176182352Sgshapiro 1177182352Sgshapiro /* 1178182352Sgshapiro * Byte-swap it if necessary. 1179182352Sgshapiro */ 1180182352Sgshapiro if (p->swapped) { 118190795Sgshapiro /* these were written in opposite byte order */ 118238032Speter hdr->len = SWAPLONG(spbp->len); 1183182352Sgshapiro } else 1184182352Sgshapiro hdr->len = spbp->len; 118538032Speter 118690795Sgshapiro /* 118738032Speter * The SPB doesn't give the captured length; 1188182352Sgshapiro * it's the minimum of the snapshot length 1189182352Sgshapiro * and the packet length. 119038032Speter */ 119138032Speter hdr->caplen = hdr->len; 119238032Speter if (hdr->caplen > (bpf_u_int32)p->snapshot) 119338032Speter hdr->caplen = p->snapshot; 1194182352Sgshapiro t = 0; /* no time stamps */ 119538032Speter goto found; 119664565Sgshapiro 119764565Sgshapiro case BT_PB: 119864565Sgshapiro /* 119964565Sgshapiro * Get a pointer to the fixed-length portion of the 120064565Sgshapiro * PB. 120164565Sgshapiro */ 120290795Sgshapiro pbp = get_from_block_data(&cursor, sizeof(*pbp), 120364565Sgshapiro p->errbuf); 120438032Speter if (pbp == NULL) 120590795Sgshapiro return (-1); /* error */ 120664565Sgshapiro 120764565Sgshapiro /* 120864565Sgshapiro * Byte-swap it if necessary. 120964565Sgshapiro */ 121038032Speter if (p->swapped) { 1211182352Sgshapiro /* these were written in opposite byte order */ 1212182352Sgshapiro interface_id = SWAPSHORT(pbp->interface_id); 1213182352Sgshapiro hdr->caplen = SWAPLONG(pbp->caplen); 1214182352Sgshapiro hdr->len = SWAPLONG(pbp->len); 1215182352Sgshapiro t = ((uint64_t)SWAPLONG(pbp->timestamp_high)) << 32 | 1216182352Sgshapiro SWAPLONG(pbp->timestamp_low); 1217182352Sgshapiro } else { 1218182352Sgshapiro interface_id = pbp->interface_id; 1219182352Sgshapiro hdr->caplen = pbp->caplen; 1220182352Sgshapiro hdr->len = pbp->len; 1221182352Sgshapiro t = ((uint64_t)pbp->timestamp_high) << 32 | 122238032Speter pbp->timestamp_low; 122377352Sgshapiro } 122477352Sgshapiro goto found; 122564565Sgshapiro 122664565Sgshapiro case BT_IDB: 122764565Sgshapiro /* 122864565Sgshapiro * Interface Description Block. Get a pointer 122990795Sgshapiro * to its fixed-length portion. 123064565Sgshapiro */ 123164565Sgshapiro idbp = get_from_block_data(&cursor, sizeof(*idbp), 123290795Sgshapiro p->errbuf); 123364565Sgshapiro if (idbp == NULL) 123438032Speter return (-1); /* error */ 123538032Speter 123690795Sgshapiro /* 123738032Speter * Byte-swap it if necessary. 123838032Speter */ 123938032Speter if (p->swapped) { 124038032Speter idbp->linktype = SWAPSHORT(idbp->linktype); 124138032Speter idbp->snaplen = SWAPLONG(idbp->snaplen); 124290795Sgshapiro } 124364565Sgshapiro 124438032Speter /* 124564565Sgshapiro * If the link-layer type or snapshot length 124690795Sgshapiro * differ from the ones for the first IDB we 124764565Sgshapiro * saw, quit. 124864565Sgshapiro * 124938032Speter * XXX - just discard packets from those 125038032Speter * interfaces? 125164565Sgshapiro */ 125264565Sgshapiro if (p->linktype != idbp->linktype) { 125364565Sgshapiro snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 125464565Sgshapiro "an interface has a type %u different from the type of the first interface", 125564565Sgshapiro idbp->linktype); 125664565Sgshapiro return (-1); 125738032Speter } 125838032Speter 125938032Speter /* 126038032Speter * Check against the *adjusted* value of this IDB's 126138032Speter * snapshot length. 126238032Speter */ 126338032Speter if ((bpf_u_int32)p->snapshot != 126438032Speter pcap_adjust_snapshot(p->linktype, idbp->snaplen)) { 126564565Sgshapiro snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 126638032Speter "an interface has a snapshot length %u different from the snapshot length of the first interface", 126738032Speter idbp->snaplen); 126838032Speter return (-1); 126938032Speter } 127038032Speter 127138032Speter /* 127238032Speter * Try to add this interface. 127338032Speter */ 127438032Speter if (!add_interface(p, idbp, &cursor, p->errbuf)) 127538032Speter return (-1); 1276120259Sgshapiro break; 127738032Speter 127838032Speter case BT_SHB: 127938032Speter /* 128038032Speter * Section Header Block. Get a pointer 128138032Speter * to its fixed-length portion. 128238032Speter */ 128338032Speter shbp = get_from_block_data(&cursor, sizeof(*shbp), 128438032Speter p->errbuf); 128538032Speter if (shbp == NULL) 1286120259Sgshapiro return (-1); /* error */ 128738032Speter 128838032Speter /* 128938032Speter * Assume the byte order of this section is 129038032Speter * the same as that of the previous section. 129142580Speter * We'll check for that later. 129242580Speter */ 129338032Speter if (p->swapped) { 129490795Sgshapiro shbp->byte_order_magic = 129538032Speter SWAPLONG(shbp->byte_order_magic); 129638032Speter shbp->major_version = 129738032Speter SWAPSHORT(shbp->major_version); 129838032Speter } 129938032Speter 130090795Sgshapiro /* 130164565Sgshapiro * Make sure the byte order doesn't change; 130238032Speter * pcap_is_swapped() shouldn't change its 130338032Speter * return value in the middle of reading a capture. 130438032Speter */ 130538032Speter switch (shbp->byte_order_magic) { 130638032Speter 130738032Speter case BYTE_ORDER_MAGIC: 130838032Speter /* 130938032Speter * OK. 131038032Speter */ 131138032Speter break; 131238032Speter 131338032Speter case SWAPLONG(BYTE_ORDER_MAGIC): 131438032Speter /* 131538032Speter * Byte order changes. 131638032Speter */ 131738032Speter snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 131890795Sgshapiro "the file has sections with different byte orders"); 131990795Sgshapiro return (-1); 132038032Speter 132138032Speter default: 132238032Speter /* 132338032Speter * Not a valid SHB. 132438032Speter */ 132538032Speter snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 132638032Speter "the file has a section with a bad byte order magic field"); 132738032Speter return (-1); 132877352Sgshapiro } 132977352Sgshapiro 133077352Sgshapiro /* 133138032Speter * Make sure the major version is the version 133238032Speter * we handle. 133390795Sgshapiro */ 133490795Sgshapiro if (shbp->major_version != PCAP_NG_VERSION_MAJOR) { 133590795Sgshapiro snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 133638032Speter "unknown pcapng savefile major version number %u", 133738032Speter shbp->major_version); 133890795Sgshapiro return (-1); 133938032Speter } 134038032Speter 134138032Speter /* 134238032Speter * Reset the interface count; this section should 134338032Speter * have its own set of IDBs. If any of them 134490795Sgshapiro * don't have the same interface type, snapshot 134590795Sgshapiro * length, or resolution as the first interface 134638032Speter * we saw, we'll fail. (And if we don't see 134738032Speter * any IDBs, we'll fail when we see a packet 134838032Speter * block.) 134938032Speter */ 1350168520Sgshapiro ps->ifcount = 0; 135138032Speter break; 135238032Speter 135338032Speter default: 135490795Sgshapiro /* 135538032Speter * Not a packet block, IDB, or SHB; ignore it. 135638032Speter */ 135738032Speter break; 135838032Speter } 135990795Sgshapiro } 136090795Sgshapiro 136190795Sgshapirofound: 136238032Speter /* 136338032Speter * Is the interface ID an interface we know? 136490795Sgshapiro */ 136590795Sgshapiro if (interface_id >= ps->ifcount) { 136690795Sgshapiro /* 136738032Speter * Yes. Fail. 136890795Sgshapiro */ 136990795Sgshapiro snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 137038032Speter "a packet arrived on interface %u, but there's no Interface Description Block for that interface", 137190795Sgshapiro interface_id); 137290795Sgshapiro return (-1); 137390795Sgshapiro } 137438032Speter 137538032Speter if (hdr->caplen > (bpf_u_int32)p->snapshot) { 137690795Sgshapiro snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 137738032Speter "invalid packet capture length %u, bigger than " 137890795Sgshapiro "snaplen of %d", hdr->caplen, p->snapshot); 137938032Speter return (-1); 138038032Speter } 138138032Speter 1382168520Sgshapiro /* 138390795Sgshapiro * Convert the time stamp to seconds and fractions of a second, 138438032Speter * with the fractions being in units of the file-supplied resolution. 138590795Sgshapiro */ 138690795Sgshapiro sec = t / ps->ifaces[interface_id].tsresol + ps->ifaces[interface_id].tsoffset; 138738032Speter frac = t % ps->ifaces[interface_id].tsresol; 138838032Speter 138990795Sgshapiro /* 139090795Sgshapiro * Convert the fractions from units of the file-supplied resolution 139138032Speter * to units of the user-requested resolution. 139238032Speter */ 139390795Sgshapiro switch (ps->ifaces[interface_id].scale_type) { 139438032Speter 139590795Sgshapiro case PASS_THROUGH: 139690795Sgshapiro /* 139738032Speter * The interface resolution is what the user wants, 139838032Speter * so we're done. 139938032Speter */ 140090795Sgshapiro break; 140138032Speter 140238032Speter case SCALE_UP_DEC: 140338032Speter /* 140438032Speter * The interface resolution is less than what the user 140538032Speter * wants; scale the fractional part up to the units of 140638032Speter * the resolution the user requested by multiplying by 140738032Speter * the quotient of the user-requested resolution and the 140838032Speter * file-supplied resolution. 140964565Sgshapiro * 141064565Sgshapiro * Those resolutions are both powers of 10, and the user- 141164565Sgshapiro * requested resolution is greater than the file-supplied 141238032Speter * resolution, so the quotient in question is an integer. 141338032Speter * We've calculated that quotient already, so we just 141438032Speter * multiply by it. 141538032Speter */ 141638032Speter frac *= ps->ifaces[interface_id].scale_factor; 141738032Speter break; 141838032Speter 141964565Sgshapiro case SCALE_UP_BIN: 142038032Speter /* 142164565Sgshapiro * The interface resolution is less than what the user 142238032Speter * wants; scale the fractional part up to the units of 142338032Speter * the resolution the user requested by multiplying by 142490795Sgshapiro * the quotient of the user-requested resolution and the 142538032Speter * file-supplied resolution. 142664565Sgshapiro * 142764565Sgshapiro * The file-supplied resolution is a power of 2, so the 142864565Sgshapiro * quotient is not an integer, so, in order to do this 142964565Sgshapiro * entirely with integer arithmetic, we multiply by the 143090795Sgshapiro * user-requested resolution and divide by the file- 143190795Sgshapiro * supplied resolution. 143264565Sgshapiro * 143364565Sgshapiro * XXX - Is there something clever we could do here, 143494337Sgshapiro * given that we know that the file-supplied resolution 143564565Sgshapiro * is a power of 2? Doing a multiplication followed by 143638032Speter * a division runs the risk of overflowing, and involves 143738032Speter * two non-simple arithmetic operations. 143838032Speter */ 143990795Sgshapiro frac *= ps->user_tsresol; 144090795Sgshapiro frac /= ps->ifaces[interface_id].tsresol; 144138032Speter break; 144290795Sgshapiro 144390795Sgshapiro case SCALE_DOWN_DEC: 144490795Sgshapiro /* 144590795Sgshapiro * The interface resolution is greater than what the user 144638032Speter * wants; scale the fractional part up to the units of 144790795Sgshapiro * the resolution the user requested by multiplying by 144890795Sgshapiro * the quotient of the user-requested resolution and the 144990795Sgshapiro * file-supplied resolution. 145038032Speter * 145138032Speter * Those resolutions are both powers of 10, and the user- 145238032Speter * requested resolution is less than the file-supplied 145338032Speter * resolution, so the quotient in question isn't an 145438032Speter * integer, but its reciprocal is, and we can just divide 145538032Speter * by the reciprocal of the quotient. We've calculated 145664565Sgshapiro * the reciprocal of that quotient already, so we must 145738032Speter * divide by it. 145838032Speter */ 145990795Sgshapiro frac /= ps->ifaces[interface_id].scale_factor; 146038032Speter break; 146190795Sgshapiro 146290795Sgshapiro 146338032Speter case SCALE_DOWN_BIN: 146438032Speter /* 146590795Sgshapiro * The interface resolution is greater than what the user 146690795Sgshapiro * wants; convert the fractional part to units of the 146790795Sgshapiro * resolution the user requested by multiplying by the 146838032Speter * quotient of the user-requested resolution and the 146938032Speter * file-supplied resolution. We do that by multiplying 147038032Speter * by the user-requested resolution and dividing by the 147138032Speter * file-supplied resolution, as the quotient might not 147238032Speter * fit in an integer. 147390795Sgshapiro * 147442580Speter * The file-supplied resolution is a power of 2, so the 147538032Speter * quotient is not an integer, and neither is its 1476120259Sgshapiro * reciprocal, so, in order to do this entirely with 147738032Speter * integer arithmetic, we multiply by the user-requested 147838032Speter * resolution and divide by the file-supplied resolution. 147938032Speter * 148038032Speter * XXX - Is there something clever we could do here, 148138032Speter * given that we know that the file-supplied resolution 148238032Speter * is a power of 2? Doing a multiplication followed by 148338032Speter * a division runs the risk of overflowing, and involves 148438032Speter * two non-simple arithmetic operations. 148538032Speter */ 148638032Speter frac *= ps->user_tsresol; 148738032Speter frac /= ps->ifaces[interface_id].tsresol; 148838032Speter break; 148938032Speter } 149038032Speter#ifdef _WIN32 149138032Speter /* 149264565Sgshapiro * tv_sec and tv_used in the Windows struct timeval are both 149338032Speter * longs. 149438032Speter */ 149538032Speter hdr->ts.tv_sec = (long)sec; 149638032Speter hdr->ts.tv_usec = (long)frac; 149738032Speter#else 149838032Speter /* 149938032Speter * tv_sec in the UN*X struct timeval is a time_t; tv_usec is 150038032Speter * suseconds_t in UN*Xes that work the way the current Single 150138032Speter * UNIX Standard specify - but not all older UN*Xes necessarily 150238032Speter * support that type, so just cast to int. 150364565Sgshapiro */ 150464565Sgshapiro hdr->ts.tv_sec = (time_t)sec; 150564565Sgshapiro hdr->ts.tv_usec = (int)frac; 150638032Speter#endif 150738032Speter 150838032Speter /* 150938032Speter * Get a pointer to the packet data. 151038032Speter */ 151138032Speter *data = get_from_block_data(&cursor, hdr->caplen, p->errbuf); 151238032Speter if (*data == NULL) 151338032Speter return (-1); 151438032Speter 151538032Speter pcap_post_process(p->linktype, p->swapped, hdr, *data); 151638032Speter 151738032Speter return (1); 151838032Speter} 151938032Speter