1*3a289941SAaron LI /* 2*3a289941SAaron LI * Copyright (c) 1993, 1994, 1995, 1996, 1997 3*3a289941SAaron LI * The Regents of the University of California. All rights reserved. 4*3a289941SAaron LI * 5*3a289941SAaron LI * Redistribution and use in source and binary forms, with or without 6*3a289941SAaron LI * modification, are permitted provided that: (1) source code distributions 7*3a289941SAaron LI * retain the above copyright notice and this paragraph in its entirety, (2) 8*3a289941SAaron LI * distributions including binary code include the above copyright notice and 9*3a289941SAaron LI * this paragraph in its entirety in the documentation or other materials 10*3a289941SAaron LI * provided with the distribution, and (3) all advertising materials mentioning 11*3a289941SAaron LI * features or use of this software display the following acknowledgement: 12*3a289941SAaron LI * ``This product includes software developed by the University of California, 13*3a289941SAaron LI * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14*3a289941SAaron LI * the University nor the names of its contributors may be used to endorse 15*3a289941SAaron LI * or promote products derived from this software without specific prior 16*3a289941SAaron LI * written permission. 17*3a289941SAaron LI * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18*3a289941SAaron LI * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19*3a289941SAaron LI * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20*3a289941SAaron LI * 21*3a289941SAaron LI * sf-pcapng.c - pcapng-file-format-specific code from savefile.c 22*3a289941SAaron LI */ 23*3a289941SAaron LI 24*3a289941SAaron LI #ifdef HAVE_CONFIG_H 25*3a289941SAaron LI #include <config.h> 26*3a289941SAaron LI #endif 27*3a289941SAaron LI 28*3a289941SAaron LI #include <pcap/pcap-inttypes.h> 29*3a289941SAaron LI 30*3a289941SAaron LI #include <errno.h> 31*3a289941SAaron LI #include <memory.h> 32*3a289941SAaron LI #include <stdio.h> 33*3a289941SAaron LI #include <stdlib.h> 34*3a289941SAaron LI #include <string.h> 35*3a289941SAaron LI 36*3a289941SAaron LI #include "pcap-int.h" 37*3a289941SAaron LI 38*3a289941SAaron LI #include "pcap-common.h" 39*3a289941SAaron LI 40*3a289941SAaron LI #ifdef HAVE_OS_PROTO_H 41*3a289941SAaron LI #include "os-proto.h" 42*3a289941SAaron LI #endif 43*3a289941SAaron LI 44*3a289941SAaron LI #include "sf-pcapng.h" 45*3a289941SAaron LI 46*3a289941SAaron LI /* 47*3a289941SAaron LI * Block types. 48*3a289941SAaron LI */ 49*3a289941SAaron LI 50*3a289941SAaron LI /* 51*3a289941SAaron LI * Common part at the beginning of all blocks. 52*3a289941SAaron LI */ 53*3a289941SAaron LI struct block_header { 54*3a289941SAaron LI bpf_u_int32 block_type; 55*3a289941SAaron LI bpf_u_int32 total_length; 56*3a289941SAaron LI }; 57*3a289941SAaron LI 58*3a289941SAaron LI /* 59*3a289941SAaron LI * Common trailer at the end of all blocks. 60*3a289941SAaron LI */ 61*3a289941SAaron LI struct block_trailer { 62*3a289941SAaron LI bpf_u_int32 total_length; 63*3a289941SAaron LI }; 64*3a289941SAaron LI 65*3a289941SAaron LI /* 66*3a289941SAaron LI * Common options. 67*3a289941SAaron LI */ 68*3a289941SAaron LI #define OPT_ENDOFOPT 0 /* end of options */ 69*3a289941SAaron LI #define OPT_COMMENT 1 /* comment string */ 70*3a289941SAaron LI 71*3a289941SAaron LI /* 72*3a289941SAaron LI * Option header. 73*3a289941SAaron LI */ 74*3a289941SAaron LI struct option_header { 75*3a289941SAaron LI u_short option_code; 76*3a289941SAaron LI u_short option_length; 77*3a289941SAaron LI }; 78*3a289941SAaron LI 79*3a289941SAaron LI /* 80*3a289941SAaron LI * Structures for the part of each block type following the common 81*3a289941SAaron LI * part. 82*3a289941SAaron LI */ 83*3a289941SAaron LI 84*3a289941SAaron LI /* 85*3a289941SAaron LI * Section Header Block. 86*3a289941SAaron LI */ 87*3a289941SAaron LI #define BT_SHB 0x0A0D0D0A 88*3a289941SAaron LI #define BT_SHB_INSANE_MAX 1024U*1024U*1U /* 1MB should be enough */ 89*3a289941SAaron LI struct section_header_block { 90*3a289941SAaron LI bpf_u_int32 byte_order_magic; 91*3a289941SAaron LI u_short major_version; 92*3a289941SAaron LI u_short minor_version; 93*3a289941SAaron LI uint64_t section_length; 94*3a289941SAaron LI /* followed by options and trailer */ 95*3a289941SAaron LI }; 96*3a289941SAaron LI 97*3a289941SAaron LI /* 98*3a289941SAaron LI * Byte-order magic value. 99*3a289941SAaron LI */ 100*3a289941SAaron LI #define BYTE_ORDER_MAGIC 0x1A2B3C4D 101*3a289941SAaron LI 102*3a289941SAaron LI /* 103*3a289941SAaron LI * Current version number. If major_version isn't PCAP_NG_VERSION_MAJOR, 104*3a289941SAaron LI * that means that this code can't read the file. 105*3a289941SAaron LI */ 106*3a289941SAaron LI #define PCAP_NG_VERSION_MAJOR 1 107*3a289941SAaron LI #define PCAP_NG_VERSION_MINOR 0 108*3a289941SAaron LI 109*3a289941SAaron LI /* 110*3a289941SAaron LI * Interface Description Block. 111*3a289941SAaron LI */ 112*3a289941SAaron LI #define BT_IDB 0x00000001 113*3a289941SAaron LI 114*3a289941SAaron LI struct interface_description_block { 115*3a289941SAaron LI u_short linktype; 116*3a289941SAaron LI u_short reserved; 117*3a289941SAaron LI bpf_u_int32 snaplen; 118*3a289941SAaron LI /* followed by options and trailer */ 119*3a289941SAaron LI }; 120*3a289941SAaron LI 121*3a289941SAaron LI /* 122*3a289941SAaron LI * Options in the IDB. 123*3a289941SAaron LI */ 124*3a289941SAaron LI #define IF_NAME 2 /* interface name string */ 125*3a289941SAaron LI #define IF_DESCRIPTION 3 /* interface description string */ 126*3a289941SAaron LI #define IF_IPV4ADDR 4 /* interface's IPv4 address and netmask */ 127*3a289941SAaron LI #define IF_IPV6ADDR 5 /* interface's IPv6 address and prefix length */ 128*3a289941SAaron LI #define IF_MACADDR 6 /* interface's MAC address */ 129*3a289941SAaron LI #define IF_EUIADDR 7 /* interface's EUI address */ 130*3a289941SAaron LI #define IF_SPEED 8 /* interface's speed, in bits/s */ 131*3a289941SAaron LI #define IF_TSRESOL 9 /* interface's time stamp resolution */ 132*3a289941SAaron LI #define IF_TZONE 10 /* interface's time zone */ 133*3a289941SAaron LI #define IF_FILTER 11 /* filter used when capturing on interface */ 134*3a289941SAaron LI #define IF_OS 12 /* string OS on which capture on this interface was done */ 135*3a289941SAaron LI #define IF_FCSLEN 13 /* FCS length for this interface */ 136*3a289941SAaron LI #define IF_TSOFFSET 14 /* time stamp offset for this interface */ 137*3a289941SAaron LI 138*3a289941SAaron LI /* 139*3a289941SAaron LI * Enhanced Packet Block. 140*3a289941SAaron LI */ 141*3a289941SAaron LI #define BT_EPB 0x00000006 142*3a289941SAaron LI 143*3a289941SAaron LI struct enhanced_packet_block { 144*3a289941SAaron LI bpf_u_int32 interface_id; 145*3a289941SAaron LI bpf_u_int32 timestamp_high; 146*3a289941SAaron LI bpf_u_int32 timestamp_low; 147*3a289941SAaron LI bpf_u_int32 caplen; 148*3a289941SAaron LI bpf_u_int32 len; 149*3a289941SAaron LI /* followed by packet data, options, and trailer */ 150*3a289941SAaron LI }; 151*3a289941SAaron LI 152*3a289941SAaron LI /* 153*3a289941SAaron LI * Simple Packet Block. 154*3a289941SAaron LI */ 155*3a289941SAaron LI #define BT_SPB 0x00000003 156*3a289941SAaron LI 157*3a289941SAaron LI struct simple_packet_block { 158*3a289941SAaron LI bpf_u_int32 len; 159*3a289941SAaron LI /* followed by packet data and trailer */ 160*3a289941SAaron LI }; 161*3a289941SAaron LI 162*3a289941SAaron LI /* 163*3a289941SAaron LI * Packet Block. 164*3a289941SAaron LI */ 165*3a289941SAaron LI #define BT_PB 0x00000002 166*3a289941SAaron LI 167*3a289941SAaron LI struct packet_block { 168*3a289941SAaron LI u_short interface_id; 169*3a289941SAaron LI u_short drops_count; 170*3a289941SAaron LI bpf_u_int32 timestamp_high; 171*3a289941SAaron LI bpf_u_int32 timestamp_low; 172*3a289941SAaron LI bpf_u_int32 caplen; 173*3a289941SAaron LI bpf_u_int32 len; 174*3a289941SAaron LI /* followed by packet data, options, and trailer */ 175*3a289941SAaron LI }; 176*3a289941SAaron LI 177*3a289941SAaron LI /* 178*3a289941SAaron LI * Block cursor - used when processing the contents of a block. 179*3a289941SAaron LI * Contains a pointer into the data being processed and a count 180*3a289941SAaron LI * of bytes remaining in the block. 181*3a289941SAaron LI */ 182*3a289941SAaron LI struct block_cursor { 183*3a289941SAaron LI u_char *data; 184*3a289941SAaron LI size_t data_remaining; 185*3a289941SAaron LI bpf_u_int32 block_type; 186*3a289941SAaron LI }; 187*3a289941SAaron LI 188*3a289941SAaron LI typedef enum { 189*3a289941SAaron LI PASS_THROUGH, 190*3a289941SAaron LI SCALE_UP_DEC, 191*3a289941SAaron LI SCALE_DOWN_DEC, 192*3a289941SAaron LI SCALE_UP_BIN, 193*3a289941SAaron LI SCALE_DOWN_BIN 194*3a289941SAaron LI } tstamp_scale_type_t; 195*3a289941SAaron LI 196*3a289941SAaron LI /* 197*3a289941SAaron LI * Per-interface information. 198*3a289941SAaron LI */ 199*3a289941SAaron LI struct pcap_ng_if { 200*3a289941SAaron LI uint64_t tsresol; /* time stamp resolution */ 201*3a289941SAaron LI tstamp_scale_type_t scale_type; /* how to scale */ 202*3a289941SAaron LI uint64_t scale_factor; /* time stamp scale factor for power-of-10 tsresol */ 203*3a289941SAaron LI uint64_t tsoffset; /* time stamp offset */ 204*3a289941SAaron LI }; 205*3a289941SAaron LI 206*3a289941SAaron LI /* 207*3a289941SAaron LI * Per-pcap_t private data. 208*3a289941SAaron LI * 209*3a289941SAaron LI * max_blocksize is the maximum size of a block that we'll accept. We 210*3a289941SAaron LI * reject blocks bigger than this, so we don't consume too much memory 211*3a289941SAaron LI * with a truly huge block. It can change as we see IDBs with different 212*3a289941SAaron LI * link-layer header types. (Currently, we don't support IDBs with 213*3a289941SAaron LI * different link-layer header types, but we will support it in the 214*3a289941SAaron LI * future, when we offer file-reading APIs that support it.) 215*3a289941SAaron LI * 216*3a289941SAaron LI * XXX - that's an issue on ILP32 platforms, where the maximum block 217*3a289941SAaron LI * size of 2^31-1 would eat all but one byte of the entire address space. 218*3a289941SAaron LI * It's less of an issue on ILP64/LLP64 platforms, but the actual size 219*3a289941SAaron LI * of the address space may be limited by 1) the number of *significant* 220*3a289941SAaron LI * address bits (currently, x86-64 only supports 48 bits of address), 2) 221*3a289941SAaron LI * any limitations imposed by the operating system; 3) any limitations 222*3a289941SAaron LI * imposed by the amount of available backing store for anonymous pages, 223*3a289941SAaron LI * so we impose a limit regardless of the size of a pointer. 224*3a289941SAaron LI */ 225*3a289941SAaron LI struct pcap_ng_sf { 226*3a289941SAaron LI uint64_t user_tsresol; /* time stamp resolution requested by the user */ 227*3a289941SAaron LI u_int max_blocksize; /* don't grow buffer size past this */ 228*3a289941SAaron LI bpf_u_int32 ifcount; /* number of interfaces seen in this capture */ 229*3a289941SAaron LI bpf_u_int32 ifaces_size; /* size of array below */ 230*3a289941SAaron LI struct pcap_ng_if *ifaces; /* array of interface information */ 231*3a289941SAaron LI }; 232*3a289941SAaron LI 233*3a289941SAaron LI /* 234*3a289941SAaron LI * The maximum block size we start with; we use an arbitrary value of 235*3a289941SAaron LI * 16 MiB. 236*3a289941SAaron LI */ 237*3a289941SAaron LI #define INITIAL_MAX_BLOCKSIZE (16*1024*1024) 238*3a289941SAaron LI 239*3a289941SAaron LI /* 240*3a289941SAaron LI * Maximum block size for a given maximum snapshot length; we define it 241*3a289941SAaron LI * as the size of an EPB with a max_snaplen-sized packet and 128KB of 242*3a289941SAaron LI * options. 243*3a289941SAaron LI */ 244*3a289941SAaron LI #define MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen) \ 245*3a289941SAaron LI (sizeof (struct block_header) + \ 246*3a289941SAaron LI sizeof (struct enhanced_packet_block) + \ 247*3a289941SAaron LI (max_snaplen) + 131072 + \ 248*3a289941SAaron LI sizeof (struct block_trailer)) 249*3a289941SAaron LI 250*3a289941SAaron LI static void pcap_ng_cleanup(pcap_t *p); 251*3a289941SAaron LI static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, 252*3a289941SAaron LI u_char **data); 253*3a289941SAaron LI 254*3a289941SAaron LI static int 255*3a289941SAaron LI read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof, 256*3a289941SAaron LI char *errbuf) 257*3a289941SAaron LI { 258*3a289941SAaron LI size_t amt_read; 259*3a289941SAaron LI 260*3a289941SAaron LI amt_read = fread(buf, 1, bytes_to_read, fp); 261*3a289941SAaron LI if (amt_read != bytes_to_read) { 262*3a289941SAaron LI if (ferror(fp)) { 263*3a289941SAaron LI pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 264*3a289941SAaron LI errno, "error reading dump file"); 265*3a289941SAaron LI } else { 266*3a289941SAaron LI if (amt_read == 0 && !fail_on_eof) 267*3a289941SAaron LI return (0); /* EOF */ 268*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 269*3a289941SAaron LI "truncated pcapng dump file; tried to read %" PRIsize " bytes, only got %" PRIsize, 270*3a289941SAaron LI bytes_to_read, amt_read); 271*3a289941SAaron LI } 272*3a289941SAaron LI return (-1); 273*3a289941SAaron LI } 274*3a289941SAaron LI return (1); 275*3a289941SAaron LI } 276*3a289941SAaron LI 277*3a289941SAaron LI static int 278*3a289941SAaron LI read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf) 279*3a289941SAaron LI { 280*3a289941SAaron LI struct pcap_ng_sf *ps; 281*3a289941SAaron LI int status; 282*3a289941SAaron LI struct block_header bhdr; 283*3a289941SAaron LI struct block_trailer *btrlr; 284*3a289941SAaron LI u_char *bdata; 285*3a289941SAaron LI size_t data_remaining; 286*3a289941SAaron LI 287*3a289941SAaron LI ps = p->priv; 288*3a289941SAaron LI 289*3a289941SAaron LI status = read_bytes(fp, &bhdr, sizeof(bhdr), 0, errbuf); 290*3a289941SAaron LI if (status <= 0) 291*3a289941SAaron LI return (status); /* error or EOF */ 292*3a289941SAaron LI 293*3a289941SAaron LI if (p->swapped) { 294*3a289941SAaron LI bhdr.block_type = SWAPLONG(bhdr.block_type); 295*3a289941SAaron LI bhdr.total_length = SWAPLONG(bhdr.total_length); 296*3a289941SAaron LI } 297*3a289941SAaron LI 298*3a289941SAaron LI /* 299*3a289941SAaron LI * Is this block "too small" - i.e., is it shorter than a block 300*3a289941SAaron LI * header plus a block trailer? 301*3a289941SAaron LI */ 302*3a289941SAaron LI if (bhdr.total_length < sizeof(struct block_header) + 303*3a289941SAaron LI sizeof(struct block_trailer)) { 304*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 305*3a289941SAaron LI "block in pcapng dump file has a length of %u < %" PRIsize, 306*3a289941SAaron LI bhdr.total_length, 307*3a289941SAaron LI sizeof(struct block_header) + sizeof(struct block_trailer)); 308*3a289941SAaron LI return (-1); 309*3a289941SAaron LI } 310*3a289941SAaron LI 311*3a289941SAaron LI /* 312*3a289941SAaron LI * Is the block total length a multiple of 4? 313*3a289941SAaron LI */ 314*3a289941SAaron LI if ((bhdr.total_length % 4) != 0) { 315*3a289941SAaron LI /* 316*3a289941SAaron LI * No. Report that as an error. 317*3a289941SAaron LI */ 318*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 319*3a289941SAaron LI "block in pcapng dump file has a length of %u that is not a multiple of 4" PRIsize, 320*3a289941SAaron LI bhdr.total_length); 321*3a289941SAaron LI return (-1); 322*3a289941SAaron LI } 323*3a289941SAaron LI 324*3a289941SAaron LI /* 325*3a289941SAaron LI * Is the buffer big enough? 326*3a289941SAaron LI */ 327*3a289941SAaron LI if (p->bufsize < bhdr.total_length) { 328*3a289941SAaron LI /* 329*3a289941SAaron LI * No - make it big enough, unless it's too big, in 330*3a289941SAaron LI * which case we fail. 331*3a289941SAaron LI */ 332*3a289941SAaron LI void *bigger_buffer; 333*3a289941SAaron LI 334*3a289941SAaron LI if (bhdr.total_length > ps->max_blocksize) { 335*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "pcapng block size %u > maximum %u", bhdr.total_length, 336*3a289941SAaron LI ps->max_blocksize); 337*3a289941SAaron LI return (-1); 338*3a289941SAaron LI } 339*3a289941SAaron LI bigger_buffer = realloc(p->buffer, bhdr.total_length); 340*3a289941SAaron LI if (bigger_buffer == NULL) { 341*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); 342*3a289941SAaron LI return (-1); 343*3a289941SAaron LI } 344*3a289941SAaron LI p->buffer = bigger_buffer; 345*3a289941SAaron LI } 346*3a289941SAaron LI 347*3a289941SAaron LI /* 348*3a289941SAaron LI * Copy the stuff we've read to the buffer, and read the rest 349*3a289941SAaron LI * of the block. 350*3a289941SAaron LI */ 351*3a289941SAaron LI memcpy(p->buffer, &bhdr, sizeof(bhdr)); 352*3a289941SAaron LI bdata = (u_char *)p->buffer + sizeof(bhdr); 353*3a289941SAaron LI data_remaining = bhdr.total_length - sizeof(bhdr); 354*3a289941SAaron LI if (read_bytes(fp, bdata, data_remaining, 1, errbuf) == -1) 355*3a289941SAaron LI return (-1); 356*3a289941SAaron LI 357*3a289941SAaron LI /* 358*3a289941SAaron LI * Get the block size from the trailer. 359*3a289941SAaron LI */ 360*3a289941SAaron LI btrlr = (struct block_trailer *)(bdata + data_remaining - sizeof (struct block_trailer)); 361*3a289941SAaron LI if (p->swapped) 362*3a289941SAaron LI btrlr->total_length = SWAPLONG(btrlr->total_length); 363*3a289941SAaron LI 364*3a289941SAaron LI /* 365*3a289941SAaron LI * Is the total length from the trailer the same as the total 366*3a289941SAaron LI * length from the header? 367*3a289941SAaron LI */ 368*3a289941SAaron LI if (bhdr.total_length != btrlr->total_length) { 369*3a289941SAaron LI /* 370*3a289941SAaron LI * No. 371*3a289941SAaron LI */ 372*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 373*3a289941SAaron LI "block total length in header and trailer don't match"); 374*3a289941SAaron LI return (-1); 375*3a289941SAaron LI } 376*3a289941SAaron LI 377*3a289941SAaron LI /* 378*3a289941SAaron LI * Initialize the cursor. 379*3a289941SAaron LI */ 380*3a289941SAaron LI cursor->data = bdata; 381*3a289941SAaron LI cursor->data_remaining = data_remaining - sizeof(struct block_trailer); 382*3a289941SAaron LI cursor->block_type = bhdr.block_type; 383*3a289941SAaron LI return (1); 384*3a289941SAaron LI } 385*3a289941SAaron LI 386*3a289941SAaron LI static void * 387*3a289941SAaron LI get_from_block_data(struct block_cursor *cursor, size_t chunk_size, 388*3a289941SAaron LI char *errbuf) 389*3a289941SAaron LI { 390*3a289941SAaron LI void *data; 391*3a289941SAaron LI 392*3a289941SAaron LI /* 393*3a289941SAaron LI * Make sure we have the specified amount of data remaining in 394*3a289941SAaron LI * the block data. 395*3a289941SAaron LI */ 396*3a289941SAaron LI if (cursor->data_remaining < chunk_size) { 397*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 398*3a289941SAaron LI "block of type %u in pcapng dump file is too short", 399*3a289941SAaron LI cursor->block_type); 400*3a289941SAaron LI return (NULL); 401*3a289941SAaron LI } 402*3a289941SAaron LI 403*3a289941SAaron LI /* 404*3a289941SAaron LI * Return the current pointer, and skip past the chunk. 405*3a289941SAaron LI */ 406*3a289941SAaron LI data = cursor->data; 407*3a289941SAaron LI cursor->data += chunk_size; 408*3a289941SAaron LI cursor->data_remaining -= chunk_size; 409*3a289941SAaron LI return (data); 410*3a289941SAaron LI } 411*3a289941SAaron LI 412*3a289941SAaron LI static struct option_header * 413*3a289941SAaron LI get_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf) 414*3a289941SAaron LI { 415*3a289941SAaron LI struct option_header *opthdr; 416*3a289941SAaron LI 417*3a289941SAaron LI opthdr = get_from_block_data(cursor, sizeof(*opthdr), errbuf); 418*3a289941SAaron LI if (opthdr == NULL) { 419*3a289941SAaron LI /* 420*3a289941SAaron LI * Option header is cut short. 421*3a289941SAaron LI */ 422*3a289941SAaron LI return (NULL); 423*3a289941SAaron LI } 424*3a289941SAaron LI 425*3a289941SAaron LI /* 426*3a289941SAaron LI * Byte-swap it if necessary. 427*3a289941SAaron LI */ 428*3a289941SAaron LI if (p->swapped) { 429*3a289941SAaron LI opthdr->option_code = SWAPSHORT(opthdr->option_code); 430*3a289941SAaron LI opthdr->option_length = SWAPSHORT(opthdr->option_length); 431*3a289941SAaron LI } 432*3a289941SAaron LI 433*3a289941SAaron LI return (opthdr); 434*3a289941SAaron LI } 435*3a289941SAaron LI 436*3a289941SAaron LI static void * 437*3a289941SAaron LI get_optvalue_from_block_data(struct block_cursor *cursor, 438*3a289941SAaron LI struct option_header *opthdr, char *errbuf) 439*3a289941SAaron LI { 440*3a289941SAaron LI size_t padded_option_len; 441*3a289941SAaron LI void *optvalue; 442*3a289941SAaron LI 443*3a289941SAaron LI /* Pad option length to 4-byte boundary */ 444*3a289941SAaron LI padded_option_len = opthdr->option_length; 445*3a289941SAaron LI padded_option_len = ((padded_option_len + 3)/4)*4; 446*3a289941SAaron LI 447*3a289941SAaron LI optvalue = get_from_block_data(cursor, padded_option_len, errbuf); 448*3a289941SAaron LI if (optvalue == NULL) { 449*3a289941SAaron LI /* 450*3a289941SAaron LI * Option value is cut short. 451*3a289941SAaron LI */ 452*3a289941SAaron LI return (NULL); 453*3a289941SAaron LI } 454*3a289941SAaron LI 455*3a289941SAaron LI return (optvalue); 456*3a289941SAaron LI } 457*3a289941SAaron LI 458*3a289941SAaron LI static int 459*3a289941SAaron LI process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, 460*3a289941SAaron LI uint64_t *tsoffset, int *is_binary, char *errbuf) 461*3a289941SAaron LI { 462*3a289941SAaron LI struct option_header *opthdr; 463*3a289941SAaron LI void *optvalue; 464*3a289941SAaron LI int saw_tsresol, saw_tsoffset; 465*3a289941SAaron LI uint8_t tsresol_opt; 466*3a289941SAaron LI u_int i; 467*3a289941SAaron LI 468*3a289941SAaron LI saw_tsresol = 0; 469*3a289941SAaron LI saw_tsoffset = 0; 470*3a289941SAaron LI while (cursor->data_remaining != 0) { 471*3a289941SAaron LI /* 472*3a289941SAaron LI * Get the option header. 473*3a289941SAaron LI */ 474*3a289941SAaron LI opthdr = get_opthdr_from_block_data(p, cursor, errbuf); 475*3a289941SAaron LI if (opthdr == NULL) { 476*3a289941SAaron LI /* 477*3a289941SAaron LI * Option header is cut short. 478*3a289941SAaron LI */ 479*3a289941SAaron LI return (-1); 480*3a289941SAaron LI } 481*3a289941SAaron LI 482*3a289941SAaron LI /* 483*3a289941SAaron LI * Get option value. 484*3a289941SAaron LI */ 485*3a289941SAaron LI optvalue = get_optvalue_from_block_data(cursor, opthdr, 486*3a289941SAaron LI errbuf); 487*3a289941SAaron LI if (optvalue == NULL) { 488*3a289941SAaron LI /* 489*3a289941SAaron LI * Option value is cut short. 490*3a289941SAaron LI */ 491*3a289941SAaron LI return (-1); 492*3a289941SAaron LI } 493*3a289941SAaron LI 494*3a289941SAaron LI switch (opthdr->option_code) { 495*3a289941SAaron LI 496*3a289941SAaron LI case OPT_ENDOFOPT: 497*3a289941SAaron LI if (opthdr->option_length != 0) { 498*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 499*3a289941SAaron LI "Interface Description Block has opt_endofopt option with length %u != 0", 500*3a289941SAaron LI opthdr->option_length); 501*3a289941SAaron LI return (-1); 502*3a289941SAaron LI } 503*3a289941SAaron LI goto done; 504*3a289941SAaron LI 505*3a289941SAaron LI case IF_TSRESOL: 506*3a289941SAaron LI if (opthdr->option_length != 1) { 507*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 508*3a289941SAaron LI "Interface Description Block has if_tsresol option with length %u != 1", 509*3a289941SAaron LI opthdr->option_length); 510*3a289941SAaron LI return (-1); 511*3a289941SAaron LI } 512*3a289941SAaron LI if (saw_tsresol) { 513*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 514*3a289941SAaron LI "Interface Description Block has more than one if_tsresol option"); 515*3a289941SAaron LI return (-1); 516*3a289941SAaron LI } 517*3a289941SAaron LI saw_tsresol = 1; 518*3a289941SAaron LI memcpy(&tsresol_opt, optvalue, sizeof(tsresol_opt)); 519*3a289941SAaron LI if (tsresol_opt & 0x80) { 520*3a289941SAaron LI /* 521*3a289941SAaron LI * Resolution is negative power of 2. 522*3a289941SAaron LI */ 523*3a289941SAaron LI uint8_t tsresol_shift = (tsresol_opt & 0x7F); 524*3a289941SAaron LI 525*3a289941SAaron LI if (tsresol_shift > 63) { 526*3a289941SAaron LI /* 527*3a289941SAaron LI * Resolution is too high; 2^-{res} 528*3a289941SAaron LI * won't fit in a 64-bit value. 529*3a289941SAaron LI */ 530*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 531*3a289941SAaron LI "Interface Description Block if_tsresol option resolution 2^-%u is too high", 532*3a289941SAaron LI tsresol_shift); 533*3a289941SAaron LI return (-1); 534*3a289941SAaron LI } 535*3a289941SAaron LI *is_binary = 1; 536*3a289941SAaron LI *tsresol = ((uint64_t)1) << tsresol_shift; 537*3a289941SAaron LI } else { 538*3a289941SAaron LI /* 539*3a289941SAaron LI * Resolution is negative power of 10. 540*3a289941SAaron LI */ 541*3a289941SAaron LI if (tsresol_opt > 19) { 542*3a289941SAaron LI /* 543*3a289941SAaron LI * Resolution is too high; 2^-{res} 544*3a289941SAaron LI * won't fit in a 64-bit value (the 545*3a289941SAaron LI * largest power of 10 that fits 546*3a289941SAaron LI * in a 64-bit value is 10^19, as 547*3a289941SAaron LI * the largest 64-bit unsigned 548*3a289941SAaron LI * value is ~1.8*10^19). 549*3a289941SAaron LI */ 550*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 551*3a289941SAaron LI "Interface Description Block if_tsresol option resolution 10^-%u is too high", 552*3a289941SAaron LI tsresol_opt); 553*3a289941SAaron LI return (-1); 554*3a289941SAaron LI } 555*3a289941SAaron LI *is_binary = 0; 556*3a289941SAaron LI *tsresol = 1; 557*3a289941SAaron LI for (i = 0; i < tsresol_opt; i++) 558*3a289941SAaron LI *tsresol *= 10; 559*3a289941SAaron LI } 560*3a289941SAaron LI break; 561*3a289941SAaron LI 562*3a289941SAaron LI case IF_TSOFFSET: 563*3a289941SAaron LI if (opthdr->option_length != 8) { 564*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 565*3a289941SAaron LI "Interface Description Block has if_tsoffset option with length %u != 8", 566*3a289941SAaron LI opthdr->option_length); 567*3a289941SAaron LI return (-1); 568*3a289941SAaron LI } 569*3a289941SAaron LI if (saw_tsoffset) { 570*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 571*3a289941SAaron LI "Interface Description Block has more than one if_tsoffset option"); 572*3a289941SAaron LI return (-1); 573*3a289941SAaron LI } 574*3a289941SAaron LI saw_tsoffset = 1; 575*3a289941SAaron LI memcpy(tsoffset, optvalue, sizeof(*tsoffset)); 576*3a289941SAaron LI if (p->swapped) 577*3a289941SAaron LI *tsoffset = SWAPLL(*tsoffset); 578*3a289941SAaron LI break; 579*3a289941SAaron LI 580*3a289941SAaron LI default: 581*3a289941SAaron LI break; 582*3a289941SAaron LI } 583*3a289941SAaron LI } 584*3a289941SAaron LI 585*3a289941SAaron LI done: 586*3a289941SAaron LI return (0); 587*3a289941SAaron LI } 588*3a289941SAaron LI 589*3a289941SAaron LI static int 590*3a289941SAaron LI add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf) 591*3a289941SAaron LI { 592*3a289941SAaron LI struct pcap_ng_sf *ps; 593*3a289941SAaron LI uint64_t tsresol; 594*3a289941SAaron LI uint64_t tsoffset; 595*3a289941SAaron LI int is_binary; 596*3a289941SAaron LI 597*3a289941SAaron LI ps = p->priv; 598*3a289941SAaron LI 599*3a289941SAaron LI /* 600*3a289941SAaron LI * Count this interface. 601*3a289941SAaron LI */ 602*3a289941SAaron LI ps->ifcount++; 603*3a289941SAaron LI 604*3a289941SAaron LI /* 605*3a289941SAaron LI * Grow the array of per-interface information as necessary. 606*3a289941SAaron LI */ 607*3a289941SAaron LI if (ps->ifcount > ps->ifaces_size) { 608*3a289941SAaron LI /* 609*3a289941SAaron LI * We need to grow the array. 610*3a289941SAaron LI */ 611*3a289941SAaron LI bpf_u_int32 new_ifaces_size; 612*3a289941SAaron LI struct pcap_ng_if *new_ifaces; 613*3a289941SAaron LI 614*3a289941SAaron LI if (ps->ifaces_size == 0) { 615*3a289941SAaron LI /* 616*3a289941SAaron LI * It's currently empty. 617*3a289941SAaron LI * 618*3a289941SAaron LI * (The Clang static analyzer doesn't do enough, 619*3a289941SAaron LI * err, umm, dataflow *analysis* to realize that 620*3a289941SAaron LI * ps->ifaces_size == 0 if ps->ifaces == NULL, 621*3a289941SAaron LI * and so complains about a possible zero argument 622*3a289941SAaron LI * to realloc(), so we check for the former 623*3a289941SAaron LI * condition to shut it up. 624*3a289941SAaron LI * 625*3a289941SAaron LI * However, it doesn't complain that one of the 626*3a289941SAaron LI * multiplications below could overflow, which is 627*3a289941SAaron LI * a real, albeit extremely unlikely, problem (you'd 628*3a289941SAaron LI * need a pcapng file with tens of millions of 629*3a289941SAaron LI * interfaces).) 630*3a289941SAaron LI */ 631*3a289941SAaron LI new_ifaces_size = 1; 632*3a289941SAaron LI new_ifaces = malloc(sizeof (struct pcap_ng_if)); 633*3a289941SAaron LI } else { 634*3a289941SAaron LI /* 635*3a289941SAaron LI * It's not currently empty; double its size. 636*3a289941SAaron LI * (Perhaps overkill once we have a lot of interfaces.) 637*3a289941SAaron LI * 638*3a289941SAaron LI * Check for overflow if we double it. 639*3a289941SAaron LI */ 640*3a289941SAaron LI if (ps->ifaces_size * 2 < ps->ifaces_size) { 641*3a289941SAaron LI /* 642*3a289941SAaron LI * The maximum number of interfaces before 643*3a289941SAaron LI * ps->ifaces_size overflows is the largest 644*3a289941SAaron LI * possible 32-bit power of 2, as we do 645*3a289941SAaron LI * size doubling. 646*3a289941SAaron LI */ 647*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 648*3a289941SAaron LI "more than %u interfaces in the file", 649*3a289941SAaron LI 0x80000000U); 650*3a289941SAaron LI return (0); 651*3a289941SAaron LI } 652*3a289941SAaron LI 653*3a289941SAaron LI /* 654*3a289941SAaron LI * ps->ifaces_size * 2 doesn't overflow, so it's 655*3a289941SAaron LI * safe to multiply. 656*3a289941SAaron LI */ 657*3a289941SAaron LI new_ifaces_size = ps->ifaces_size * 2; 658*3a289941SAaron LI 659*3a289941SAaron LI /* 660*3a289941SAaron LI * Now make sure that's not so big that it overflows 661*3a289941SAaron LI * if we multiply by sizeof (struct pcap_ng_if). 662*3a289941SAaron LI * 663*3a289941SAaron LI * That can happen on 32-bit platforms, with a 32-bit 664*3a289941SAaron LI * size_t; it shouldn't happen on 64-bit platforms, 665*3a289941SAaron LI * with a 64-bit size_t, as new_ifaces_size is 666*3a289941SAaron LI * 32 bits. 667*3a289941SAaron LI */ 668*3a289941SAaron LI if (new_ifaces_size * sizeof (struct pcap_ng_if) < new_ifaces_size) { 669*3a289941SAaron LI /* 670*3a289941SAaron LI * As this fails only with 32-bit size_t, 671*3a289941SAaron LI * the multiplication was 32x32->32, and 672*3a289941SAaron LI * the largest 32-bit value that can safely 673*3a289941SAaron LI * be multiplied by sizeof (struct pcap_ng_if) 674*3a289941SAaron LI * without overflow is the largest 32-bit 675*3a289941SAaron LI * (unsigned) value divided by 676*3a289941SAaron LI * sizeof (struct pcap_ng_if). 677*3a289941SAaron LI */ 678*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 679*3a289941SAaron LI "more than %u interfaces in the file", 680*3a289941SAaron LI 0xFFFFFFFFU / ((u_int)sizeof (struct pcap_ng_if))); 681*3a289941SAaron LI return (0); 682*3a289941SAaron LI } 683*3a289941SAaron LI new_ifaces = realloc(ps->ifaces, new_ifaces_size * sizeof (struct pcap_ng_if)); 684*3a289941SAaron LI } 685*3a289941SAaron LI if (new_ifaces == NULL) { 686*3a289941SAaron LI /* 687*3a289941SAaron LI * We ran out of memory. 688*3a289941SAaron LI * Give up. 689*3a289941SAaron LI */ 690*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 691*3a289941SAaron LI "out of memory for per-interface information (%u interfaces)", 692*3a289941SAaron LI ps->ifcount); 693*3a289941SAaron LI return (0); 694*3a289941SAaron LI } 695*3a289941SAaron LI ps->ifaces_size = new_ifaces_size; 696*3a289941SAaron LI ps->ifaces = new_ifaces; 697*3a289941SAaron LI } 698*3a289941SAaron LI 699*3a289941SAaron LI /* 700*3a289941SAaron LI * Set the default time stamp resolution and offset. 701*3a289941SAaron LI */ 702*3a289941SAaron LI tsresol = 1000000; /* microsecond resolution */ 703*3a289941SAaron LI is_binary = 0; /* which is a power of 10 */ 704*3a289941SAaron LI tsoffset = 0; /* absolute timestamps */ 705*3a289941SAaron LI 706*3a289941SAaron LI /* 707*3a289941SAaron LI * Now look for various time stamp options, so we know 708*3a289941SAaron LI * how to interpret the time stamps for this interface. 709*3a289941SAaron LI */ 710*3a289941SAaron LI if (process_idb_options(p, cursor, &tsresol, &tsoffset, &is_binary, 711*3a289941SAaron LI errbuf) == -1) 712*3a289941SAaron LI return (0); 713*3a289941SAaron LI 714*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].tsresol = tsresol; 715*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].tsoffset = tsoffset; 716*3a289941SAaron LI 717*3a289941SAaron LI /* 718*3a289941SAaron LI * Determine whether we're scaling up or down or not 719*3a289941SAaron LI * at all for this interface. 720*3a289941SAaron LI */ 721*3a289941SAaron LI if (tsresol == ps->user_tsresol) { 722*3a289941SAaron LI /* 723*3a289941SAaron LI * The resolution is the resolution the user wants, 724*3a289941SAaron LI * so we don't have to do scaling. 725*3a289941SAaron LI */ 726*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH; 727*3a289941SAaron LI } else if (tsresol > ps->user_tsresol) { 728*3a289941SAaron LI /* 729*3a289941SAaron LI * The resolution is greater than what the user wants, 730*3a289941SAaron LI * so we have to scale the timestamps down. 731*3a289941SAaron LI */ 732*3a289941SAaron LI if (is_binary) 733*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN_BIN; 734*3a289941SAaron LI else { 735*3a289941SAaron LI /* 736*3a289941SAaron LI * Calculate the scale factor. 737*3a289941SAaron LI */ 738*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].scale_factor = tsresol/ps->user_tsresol; 739*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN_DEC; 740*3a289941SAaron LI } 741*3a289941SAaron LI } else { 742*3a289941SAaron LI /* 743*3a289941SAaron LI * The resolution is less than what the user wants, 744*3a289941SAaron LI * so we have to scale the timestamps up. 745*3a289941SAaron LI */ 746*3a289941SAaron LI if (is_binary) 747*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP_BIN; 748*3a289941SAaron LI else { 749*3a289941SAaron LI /* 750*3a289941SAaron LI * Calculate the scale factor. 751*3a289941SAaron LI */ 752*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].scale_factor = ps->user_tsresol/tsresol; 753*3a289941SAaron LI ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP_DEC; 754*3a289941SAaron LI } 755*3a289941SAaron LI } 756*3a289941SAaron LI return (1); 757*3a289941SAaron LI } 758*3a289941SAaron LI 759*3a289941SAaron LI /* 760*3a289941SAaron LI * Check whether this is a pcapng savefile and, if it is, extract the 761*3a289941SAaron LI * relevant information from the header. 762*3a289941SAaron LI */ 763*3a289941SAaron LI pcap_t * 764*3a289941SAaron LI pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, 765*3a289941SAaron LI char *errbuf, int *err) 766*3a289941SAaron LI { 767*3a289941SAaron LI bpf_u_int32 magic_int; 768*3a289941SAaron LI size_t amt_read; 769*3a289941SAaron LI bpf_u_int32 total_length; 770*3a289941SAaron LI bpf_u_int32 byte_order_magic; 771*3a289941SAaron LI struct block_header *bhdrp; 772*3a289941SAaron LI struct section_header_block *shbp; 773*3a289941SAaron LI pcap_t *p; 774*3a289941SAaron LI int swapped = 0; 775*3a289941SAaron LI struct pcap_ng_sf *ps; 776*3a289941SAaron LI int status; 777*3a289941SAaron LI struct block_cursor cursor; 778*3a289941SAaron LI struct interface_description_block *idbp; 779*3a289941SAaron LI 780*3a289941SAaron LI /* 781*3a289941SAaron LI * Assume no read errors. 782*3a289941SAaron LI */ 783*3a289941SAaron LI *err = 0; 784*3a289941SAaron LI 785*3a289941SAaron LI /* 786*3a289941SAaron LI * Check whether the first 4 bytes of the file are the block 787*3a289941SAaron LI * type for a pcapng savefile. 788*3a289941SAaron LI */ 789*3a289941SAaron LI memcpy(&magic_int, magic, sizeof(magic_int)); 790*3a289941SAaron LI if (magic_int != BT_SHB) { 791*3a289941SAaron LI /* 792*3a289941SAaron LI * XXX - check whether this looks like what the block 793*3a289941SAaron LI * type would be after being munged by mapping between 794*3a289941SAaron LI * UN*X and DOS/Windows text file format and, if it 795*3a289941SAaron LI * does, look for the byte-order magic number in 796*3a289941SAaron LI * the appropriate place and, if we find it, report 797*3a289941SAaron LI * this as possibly being a pcapng file transferred 798*3a289941SAaron LI * between UN*X and Windows in text file format? 799*3a289941SAaron LI */ 800*3a289941SAaron LI return (NULL); /* nope */ 801*3a289941SAaron LI } 802*3a289941SAaron LI 803*3a289941SAaron LI /* 804*3a289941SAaron LI * OK, they are. However, that's just \n\r\r\n, so it could, 805*3a289941SAaron LI * conceivably, be an ordinary text file. 806*3a289941SAaron LI * 807*3a289941SAaron LI * It could not, however, conceivably be any other type of 808*3a289941SAaron LI * capture file, so we can read the rest of the putative 809*3a289941SAaron LI * Section Header Block; put the block type in the common 810*3a289941SAaron LI * header, read the rest of the common header and the 811*3a289941SAaron LI * fixed-length portion of the SHB, and look for the byte-order 812*3a289941SAaron LI * magic value. 813*3a289941SAaron LI */ 814*3a289941SAaron LI amt_read = fread(&total_length, 1, sizeof(total_length), fp); 815*3a289941SAaron LI if (amt_read < sizeof(total_length)) { 816*3a289941SAaron LI if (ferror(fp)) { 817*3a289941SAaron LI pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 818*3a289941SAaron LI errno, "error reading dump file"); 819*3a289941SAaron LI *err = 1; 820*3a289941SAaron LI return (NULL); /* fail */ 821*3a289941SAaron LI } 822*3a289941SAaron LI 823*3a289941SAaron LI /* 824*3a289941SAaron LI * Possibly a weird short text file, so just say 825*3a289941SAaron LI * "not pcapng". 826*3a289941SAaron LI */ 827*3a289941SAaron LI return (NULL); 828*3a289941SAaron LI } 829*3a289941SAaron LI amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp); 830*3a289941SAaron LI if (amt_read < sizeof(byte_order_magic)) { 831*3a289941SAaron LI if (ferror(fp)) { 832*3a289941SAaron LI pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 833*3a289941SAaron LI errno, "error reading dump file"); 834*3a289941SAaron LI *err = 1; 835*3a289941SAaron LI return (NULL); /* fail */ 836*3a289941SAaron LI } 837*3a289941SAaron LI 838*3a289941SAaron LI /* 839*3a289941SAaron LI * Possibly a weird short text file, so just say 840*3a289941SAaron LI * "not pcapng". 841*3a289941SAaron LI */ 842*3a289941SAaron LI return (NULL); 843*3a289941SAaron LI } 844*3a289941SAaron LI if (byte_order_magic != BYTE_ORDER_MAGIC) { 845*3a289941SAaron LI byte_order_magic = SWAPLONG(byte_order_magic); 846*3a289941SAaron LI if (byte_order_magic != BYTE_ORDER_MAGIC) { 847*3a289941SAaron LI /* 848*3a289941SAaron LI * Not a pcapng file. 849*3a289941SAaron LI */ 850*3a289941SAaron LI return (NULL); 851*3a289941SAaron LI } 852*3a289941SAaron LI swapped = 1; 853*3a289941SAaron LI total_length = SWAPLONG(total_length); 854*3a289941SAaron LI } 855*3a289941SAaron LI 856*3a289941SAaron LI /* 857*3a289941SAaron LI * Check the sanity of the total length. 858*3a289941SAaron LI */ 859*3a289941SAaron LI if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer) || 860*3a289941SAaron LI (total_length > BT_SHB_INSANE_MAX)) { 861*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 862*3a289941SAaron LI "Section Header Block in pcapng dump file has invalid length %" PRIsize " < _%u_ < %u (BT_SHB_INSANE_MAX)", 863*3a289941SAaron LI sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer), 864*3a289941SAaron LI total_length, 865*3a289941SAaron LI BT_SHB_INSANE_MAX); 866*3a289941SAaron LI 867*3a289941SAaron LI *err = 1; 868*3a289941SAaron LI return (NULL); 869*3a289941SAaron LI } 870*3a289941SAaron LI 871*3a289941SAaron LI /* 872*3a289941SAaron LI * OK, this is a good pcapng file. 873*3a289941SAaron LI * Allocate a pcap_t for it. 874*3a289941SAaron LI */ 875*3a289941SAaron LI p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf)); 876*3a289941SAaron LI if (p == NULL) { 877*3a289941SAaron LI /* Allocation failed. */ 878*3a289941SAaron LI *err = 1; 879*3a289941SAaron LI return (NULL); 880*3a289941SAaron LI } 881*3a289941SAaron LI p->swapped = swapped; 882*3a289941SAaron LI ps = p->priv; 883*3a289941SAaron LI 884*3a289941SAaron LI /* 885*3a289941SAaron LI * What precision does the user want? 886*3a289941SAaron LI */ 887*3a289941SAaron LI switch (precision) { 888*3a289941SAaron LI 889*3a289941SAaron LI case PCAP_TSTAMP_PRECISION_MICRO: 890*3a289941SAaron LI ps->user_tsresol = 1000000; 891*3a289941SAaron LI break; 892*3a289941SAaron LI 893*3a289941SAaron LI case PCAP_TSTAMP_PRECISION_NANO: 894*3a289941SAaron LI ps->user_tsresol = 1000000000; 895*3a289941SAaron LI break; 896*3a289941SAaron LI 897*3a289941SAaron LI default: 898*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 899*3a289941SAaron LI "unknown time stamp resolution %u", precision); 900*3a289941SAaron LI free(p); 901*3a289941SAaron LI *err = 1; 902*3a289941SAaron LI return (NULL); 903*3a289941SAaron LI } 904*3a289941SAaron LI 905*3a289941SAaron LI p->opt.tstamp_precision = precision; 906*3a289941SAaron LI 907*3a289941SAaron LI /* 908*3a289941SAaron LI * Allocate a buffer into which to read blocks. We default to 909*3a289941SAaron LI * the maximum of: 910*3a289941SAaron LI * 911*3a289941SAaron LI * the total length of the SHB for which we read the header; 912*3a289941SAaron LI * 913*3a289941SAaron LI * 2K, which should be more than large enough for an Enhanced 914*3a289941SAaron LI * Packet Block containing a full-size Ethernet frame, and 915*3a289941SAaron LI * leaving room for some options. 916*3a289941SAaron LI * 917*3a289941SAaron LI * If we find a bigger block, we reallocate the buffer, up to 918*3a289941SAaron LI * the maximum size. We start out with a maximum size of 919*3a289941SAaron LI * INITIAL_MAX_BLOCKSIZE; if we see any link-layer header types 920*3a289941SAaron LI * with a maximum snapshot that results in a larger maximum 921*3a289941SAaron LI * block length, we boost the maximum. 922*3a289941SAaron LI */ 923*3a289941SAaron LI p->bufsize = 2048; 924*3a289941SAaron LI if (p->bufsize < total_length) 925*3a289941SAaron LI p->bufsize = total_length; 926*3a289941SAaron LI p->buffer = malloc(p->bufsize); 927*3a289941SAaron LI if (p->buffer == NULL) { 928*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); 929*3a289941SAaron LI free(p); 930*3a289941SAaron LI *err = 1; 931*3a289941SAaron LI return (NULL); 932*3a289941SAaron LI } 933*3a289941SAaron LI ps->max_blocksize = INITIAL_MAX_BLOCKSIZE; 934*3a289941SAaron LI 935*3a289941SAaron LI /* 936*3a289941SAaron LI * Copy the stuff we've read to the buffer, and read the rest 937*3a289941SAaron LI * of the SHB. 938*3a289941SAaron LI */ 939*3a289941SAaron LI bhdrp = (struct block_header *)p->buffer; 940*3a289941SAaron LI shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header)); 941*3a289941SAaron LI bhdrp->block_type = magic_int; 942*3a289941SAaron LI bhdrp->total_length = total_length; 943*3a289941SAaron LI shbp->byte_order_magic = byte_order_magic; 944*3a289941SAaron LI if (read_bytes(fp, 945*3a289941SAaron LI (u_char *)p->buffer + (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)), 946*3a289941SAaron LI total_length - (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)), 947*3a289941SAaron LI 1, errbuf) == -1) 948*3a289941SAaron LI goto fail; 949*3a289941SAaron LI 950*3a289941SAaron LI if (p->swapped) { 951*3a289941SAaron LI /* 952*3a289941SAaron LI * Byte-swap the fields we've read. 953*3a289941SAaron LI */ 954*3a289941SAaron LI shbp->major_version = SWAPSHORT(shbp->major_version); 955*3a289941SAaron LI shbp->minor_version = SWAPSHORT(shbp->minor_version); 956*3a289941SAaron LI 957*3a289941SAaron LI /* 958*3a289941SAaron LI * XXX - we don't care about the section length. 959*3a289941SAaron LI */ 960*3a289941SAaron LI } 961*3a289941SAaron LI /* currently only SHB version 1.0 is supported */ 962*3a289941SAaron LI if (! (shbp->major_version == PCAP_NG_VERSION_MAJOR && 963*3a289941SAaron LI shbp->minor_version == PCAP_NG_VERSION_MINOR)) { 964*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 965*3a289941SAaron LI "unsupported pcapng savefile version %u.%u", 966*3a289941SAaron LI shbp->major_version, shbp->minor_version); 967*3a289941SAaron LI goto fail; 968*3a289941SAaron LI } 969*3a289941SAaron LI p->version_major = shbp->major_version; 970*3a289941SAaron LI p->version_minor = shbp->minor_version; 971*3a289941SAaron LI 972*3a289941SAaron LI /* 973*3a289941SAaron LI * Save the time stamp resolution the user requested. 974*3a289941SAaron LI */ 975*3a289941SAaron LI p->opt.tstamp_precision = precision; 976*3a289941SAaron LI 977*3a289941SAaron LI /* 978*3a289941SAaron LI * Now start looking for an Interface Description Block. 979*3a289941SAaron LI */ 980*3a289941SAaron LI for (;;) { 981*3a289941SAaron LI /* 982*3a289941SAaron LI * Read the next block. 983*3a289941SAaron LI */ 984*3a289941SAaron LI status = read_block(fp, p, &cursor, errbuf); 985*3a289941SAaron LI if (status == 0) { 986*3a289941SAaron LI /* EOF - no IDB in this file */ 987*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 988*3a289941SAaron LI "the capture file has no Interface Description Blocks"); 989*3a289941SAaron LI goto fail; 990*3a289941SAaron LI } 991*3a289941SAaron LI if (status == -1) 992*3a289941SAaron LI goto fail; /* error */ 993*3a289941SAaron LI switch (cursor.block_type) { 994*3a289941SAaron LI 995*3a289941SAaron LI case BT_IDB: 996*3a289941SAaron LI /* 997*3a289941SAaron LI * Get a pointer to the fixed-length portion of the 998*3a289941SAaron LI * IDB. 999*3a289941SAaron LI */ 1000*3a289941SAaron LI idbp = get_from_block_data(&cursor, sizeof(*idbp), 1001*3a289941SAaron LI errbuf); 1002*3a289941SAaron LI if (idbp == NULL) 1003*3a289941SAaron LI goto fail; /* error */ 1004*3a289941SAaron LI 1005*3a289941SAaron LI /* 1006*3a289941SAaron LI * Byte-swap it if necessary. 1007*3a289941SAaron LI */ 1008*3a289941SAaron LI if (p->swapped) { 1009*3a289941SAaron LI idbp->linktype = SWAPSHORT(idbp->linktype); 1010*3a289941SAaron LI idbp->snaplen = SWAPLONG(idbp->snaplen); 1011*3a289941SAaron LI } 1012*3a289941SAaron LI 1013*3a289941SAaron LI /* 1014*3a289941SAaron LI * Try to add this interface. 1015*3a289941SAaron LI */ 1016*3a289941SAaron LI if (!add_interface(p, &cursor, errbuf)) 1017*3a289941SAaron LI goto fail; 1018*3a289941SAaron LI 1019*3a289941SAaron LI goto done; 1020*3a289941SAaron LI 1021*3a289941SAaron LI case BT_EPB: 1022*3a289941SAaron LI case BT_SPB: 1023*3a289941SAaron LI case BT_PB: 1024*3a289941SAaron LI /* 1025*3a289941SAaron LI * Saw a packet before we saw any IDBs. That's 1026*3a289941SAaron LI * not valid, as we don't know what link-layer 1027*3a289941SAaron LI * encapsulation the packet has. 1028*3a289941SAaron LI */ 1029*3a289941SAaron LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1030*3a289941SAaron LI "the capture file has a packet block before any Interface Description Blocks"); 1031*3a289941SAaron LI goto fail; 1032*3a289941SAaron LI 1033*3a289941SAaron LI default: 1034*3a289941SAaron LI /* 1035*3a289941SAaron LI * Just ignore it. 1036*3a289941SAaron LI */ 1037*3a289941SAaron LI break; 1038*3a289941SAaron LI } 1039*3a289941SAaron LI } 1040*3a289941SAaron LI 1041*3a289941SAaron LI done: 1042*3a289941SAaron LI p->tzoff = 0; /* XXX - not used in pcap */ 1043*3a289941SAaron LI p->linktype = linktype_to_dlt(idbp->linktype); 1044*3a289941SAaron LI p->snapshot = pcap_adjust_snapshot(p->linktype, idbp->snaplen); 1045*3a289941SAaron LI p->linktype_ext = 0; 1046*3a289941SAaron LI 1047*3a289941SAaron LI /* 1048*3a289941SAaron LI * If the maximum block size for a packet with the maximum 1049*3a289941SAaron LI * snapshot length for this DLT_ is bigger than the current 1050*3a289941SAaron LI * maximum block size, increase the maximum. 1051*3a289941SAaron LI */ 1052*3a289941SAaron LI if (MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype)) > ps->max_blocksize) 1053*3a289941SAaron LI ps->max_blocksize = MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype)); 1054*3a289941SAaron LI 1055*3a289941SAaron LI p->next_packet_op = pcap_ng_next_packet; 1056*3a289941SAaron LI p->cleanup_op = pcap_ng_cleanup; 1057*3a289941SAaron LI 1058*3a289941SAaron LI return (p); 1059*3a289941SAaron LI 1060*3a289941SAaron LI fail: 1061*3a289941SAaron LI free(ps->ifaces); 1062*3a289941SAaron LI free(p->buffer); 1063*3a289941SAaron LI free(p); 1064*3a289941SAaron LI *err = 1; 1065*3a289941SAaron LI return (NULL); 1066*3a289941SAaron LI } 1067*3a289941SAaron LI 1068*3a289941SAaron LI static void 1069*3a289941SAaron LI pcap_ng_cleanup(pcap_t *p) 1070*3a289941SAaron LI { 1071*3a289941SAaron LI struct pcap_ng_sf *ps = p->priv; 1072*3a289941SAaron LI 1073*3a289941SAaron LI free(ps->ifaces); 1074*3a289941SAaron LI sf_cleanup(p); 1075*3a289941SAaron LI } 1076*3a289941SAaron LI 1077*3a289941SAaron LI /* 1078*3a289941SAaron LI * Read and return the next packet from the savefile. Return the header 1079*3a289941SAaron LI * in hdr and a pointer to the contents in data. Return 0 on success, 1 1080*3a289941SAaron LI * if there were no more packets, and -1 on an error. 1081*3a289941SAaron LI */ 1082*3a289941SAaron LI static int 1083*3a289941SAaron LI pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) 1084*3a289941SAaron LI { 1085*3a289941SAaron LI struct pcap_ng_sf *ps = p->priv; 1086*3a289941SAaron LI struct block_cursor cursor; 1087*3a289941SAaron LI int status; 1088*3a289941SAaron LI struct enhanced_packet_block *epbp; 1089*3a289941SAaron LI struct simple_packet_block *spbp; 1090*3a289941SAaron LI struct packet_block *pbp; 1091*3a289941SAaron LI bpf_u_int32 interface_id = 0xFFFFFFFF; 1092*3a289941SAaron LI struct interface_description_block *idbp; 1093*3a289941SAaron LI struct section_header_block *shbp; 1094*3a289941SAaron LI FILE *fp = p->rfile; 1095*3a289941SAaron LI uint64_t t, sec, frac; 1096*3a289941SAaron LI 1097*3a289941SAaron LI /* 1098*3a289941SAaron LI * Look for an Enhanced Packet Block, a Simple Packet Block, 1099*3a289941SAaron LI * or a Packet Block. 1100*3a289941SAaron LI */ 1101*3a289941SAaron LI for (;;) { 1102*3a289941SAaron LI /* 1103*3a289941SAaron LI * Read the block type and length; those are common 1104*3a289941SAaron LI * to all blocks. 1105*3a289941SAaron LI */ 1106*3a289941SAaron LI status = read_block(fp, p, &cursor, p->errbuf); 1107*3a289941SAaron LI if (status == 0) 1108*3a289941SAaron LI return (1); /* EOF */ 1109*3a289941SAaron LI if (status == -1) 1110*3a289941SAaron LI return (-1); /* error */ 1111*3a289941SAaron LI switch (cursor.block_type) { 1112*3a289941SAaron LI 1113*3a289941SAaron LI case BT_EPB: 1114*3a289941SAaron LI /* 1115*3a289941SAaron LI * Get a pointer to the fixed-length portion of the 1116*3a289941SAaron LI * EPB. 1117*3a289941SAaron LI */ 1118*3a289941SAaron LI epbp = get_from_block_data(&cursor, sizeof(*epbp), 1119*3a289941SAaron LI p->errbuf); 1120*3a289941SAaron LI if (epbp == NULL) 1121*3a289941SAaron LI return (-1); /* error */ 1122*3a289941SAaron LI 1123*3a289941SAaron LI /* 1124*3a289941SAaron LI * Byte-swap it if necessary. 1125*3a289941SAaron LI */ 1126*3a289941SAaron LI if (p->swapped) { 1127*3a289941SAaron LI /* these were written in opposite byte order */ 1128*3a289941SAaron LI interface_id = SWAPLONG(epbp->interface_id); 1129*3a289941SAaron LI hdr->caplen = SWAPLONG(epbp->caplen); 1130*3a289941SAaron LI hdr->len = SWAPLONG(epbp->len); 1131*3a289941SAaron LI t = ((uint64_t)SWAPLONG(epbp->timestamp_high)) << 32 | 1132*3a289941SAaron LI SWAPLONG(epbp->timestamp_low); 1133*3a289941SAaron LI } else { 1134*3a289941SAaron LI interface_id = epbp->interface_id; 1135*3a289941SAaron LI hdr->caplen = epbp->caplen; 1136*3a289941SAaron LI hdr->len = epbp->len; 1137*3a289941SAaron LI t = ((uint64_t)epbp->timestamp_high) << 32 | 1138*3a289941SAaron LI epbp->timestamp_low; 1139*3a289941SAaron LI } 1140*3a289941SAaron LI goto found; 1141*3a289941SAaron LI 1142*3a289941SAaron LI case BT_SPB: 1143*3a289941SAaron LI /* 1144*3a289941SAaron LI * Get a pointer to the fixed-length portion of the 1145*3a289941SAaron LI * SPB. 1146*3a289941SAaron LI */ 1147*3a289941SAaron LI spbp = get_from_block_data(&cursor, sizeof(*spbp), 1148*3a289941SAaron LI p->errbuf); 1149*3a289941SAaron LI if (spbp == NULL) 1150*3a289941SAaron LI return (-1); /* error */ 1151*3a289941SAaron LI 1152*3a289941SAaron LI /* 1153*3a289941SAaron LI * SPB packets are assumed to have arrived on 1154*3a289941SAaron LI * the first interface. 1155*3a289941SAaron LI */ 1156*3a289941SAaron LI interface_id = 0; 1157*3a289941SAaron LI 1158*3a289941SAaron LI /* 1159*3a289941SAaron LI * Byte-swap it if necessary. 1160*3a289941SAaron LI */ 1161*3a289941SAaron LI if (p->swapped) { 1162*3a289941SAaron LI /* these were written in opposite byte order */ 1163*3a289941SAaron LI hdr->len = SWAPLONG(spbp->len); 1164*3a289941SAaron LI } else 1165*3a289941SAaron LI hdr->len = spbp->len; 1166*3a289941SAaron LI 1167*3a289941SAaron LI /* 1168*3a289941SAaron LI * The SPB doesn't give the captured length; 1169*3a289941SAaron LI * it's the minimum of the snapshot length 1170*3a289941SAaron LI * and the packet length. 1171*3a289941SAaron LI */ 1172*3a289941SAaron LI hdr->caplen = hdr->len; 1173*3a289941SAaron LI if (hdr->caplen > (bpf_u_int32)p->snapshot) 1174*3a289941SAaron LI hdr->caplen = p->snapshot; 1175*3a289941SAaron LI t = 0; /* no time stamps */ 1176*3a289941SAaron LI goto found; 1177*3a289941SAaron LI 1178*3a289941SAaron LI case BT_PB: 1179*3a289941SAaron LI /* 1180*3a289941SAaron LI * Get a pointer to the fixed-length portion of the 1181*3a289941SAaron LI * PB. 1182*3a289941SAaron LI */ 1183*3a289941SAaron LI pbp = get_from_block_data(&cursor, sizeof(*pbp), 1184*3a289941SAaron LI p->errbuf); 1185*3a289941SAaron LI if (pbp == NULL) 1186*3a289941SAaron LI return (-1); /* error */ 1187*3a289941SAaron LI 1188*3a289941SAaron LI /* 1189*3a289941SAaron LI * Byte-swap it if necessary. 1190*3a289941SAaron LI */ 1191*3a289941SAaron LI if (p->swapped) { 1192*3a289941SAaron LI /* these were written in opposite byte order */ 1193*3a289941SAaron LI interface_id = SWAPSHORT(pbp->interface_id); 1194*3a289941SAaron LI hdr->caplen = SWAPLONG(pbp->caplen); 1195*3a289941SAaron LI hdr->len = SWAPLONG(pbp->len); 1196*3a289941SAaron LI t = ((uint64_t)SWAPLONG(pbp->timestamp_high)) << 32 | 1197*3a289941SAaron LI SWAPLONG(pbp->timestamp_low); 1198*3a289941SAaron LI } else { 1199*3a289941SAaron LI interface_id = pbp->interface_id; 1200*3a289941SAaron LI hdr->caplen = pbp->caplen; 1201*3a289941SAaron LI hdr->len = pbp->len; 1202*3a289941SAaron LI t = ((uint64_t)pbp->timestamp_high) << 32 | 1203*3a289941SAaron LI pbp->timestamp_low; 1204*3a289941SAaron LI } 1205*3a289941SAaron LI goto found; 1206*3a289941SAaron LI 1207*3a289941SAaron LI case BT_IDB: 1208*3a289941SAaron LI /* 1209*3a289941SAaron LI * Interface Description Block. Get a pointer 1210*3a289941SAaron LI * to its fixed-length portion. 1211*3a289941SAaron LI */ 1212*3a289941SAaron LI idbp = get_from_block_data(&cursor, sizeof(*idbp), 1213*3a289941SAaron LI p->errbuf); 1214*3a289941SAaron LI if (idbp == NULL) 1215*3a289941SAaron LI return (-1); /* error */ 1216*3a289941SAaron LI 1217*3a289941SAaron LI /* 1218*3a289941SAaron LI * Byte-swap it if necessary. 1219*3a289941SAaron LI */ 1220*3a289941SAaron LI if (p->swapped) { 1221*3a289941SAaron LI idbp->linktype = SWAPSHORT(idbp->linktype); 1222*3a289941SAaron LI idbp->snaplen = SWAPLONG(idbp->snaplen); 1223*3a289941SAaron LI } 1224*3a289941SAaron LI 1225*3a289941SAaron LI /* 1226*3a289941SAaron LI * If the link-layer type or snapshot length 1227*3a289941SAaron LI * differ from the ones for the first IDB we 1228*3a289941SAaron LI * saw, quit. 1229*3a289941SAaron LI * 1230*3a289941SAaron LI * XXX - just discard packets from those 1231*3a289941SAaron LI * interfaces? 1232*3a289941SAaron LI */ 1233*3a289941SAaron LI if (p->linktype != idbp->linktype) { 1234*3a289941SAaron LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1235*3a289941SAaron LI "an interface has a type %u different from the type of the first interface", 1236*3a289941SAaron LI idbp->linktype); 1237*3a289941SAaron LI return (-1); 1238*3a289941SAaron LI } 1239*3a289941SAaron LI 1240*3a289941SAaron LI /* 1241*3a289941SAaron LI * Check against the *adjusted* value of this IDB's 1242*3a289941SAaron LI * snapshot length. 1243*3a289941SAaron LI */ 1244*3a289941SAaron LI if ((bpf_u_int32)p->snapshot != 1245*3a289941SAaron LI pcap_adjust_snapshot(p->linktype, idbp->snaplen)) { 1246*3a289941SAaron LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1247*3a289941SAaron LI "an interface has a snapshot length %u different from the type of the first interface", 1248*3a289941SAaron LI idbp->snaplen); 1249*3a289941SAaron LI return (-1); 1250*3a289941SAaron LI } 1251*3a289941SAaron LI 1252*3a289941SAaron LI /* 1253*3a289941SAaron LI * Try to add this interface. 1254*3a289941SAaron LI */ 1255*3a289941SAaron LI if (!add_interface(p, &cursor, p->errbuf)) 1256*3a289941SAaron LI return (-1); 1257*3a289941SAaron LI break; 1258*3a289941SAaron LI 1259*3a289941SAaron LI case BT_SHB: 1260*3a289941SAaron LI /* 1261*3a289941SAaron LI * Section Header Block. Get a pointer 1262*3a289941SAaron LI * to its fixed-length portion. 1263*3a289941SAaron LI */ 1264*3a289941SAaron LI shbp = get_from_block_data(&cursor, sizeof(*shbp), 1265*3a289941SAaron LI p->errbuf); 1266*3a289941SAaron LI if (shbp == NULL) 1267*3a289941SAaron LI return (-1); /* error */ 1268*3a289941SAaron LI 1269*3a289941SAaron LI /* 1270*3a289941SAaron LI * Assume the byte order of this section is 1271*3a289941SAaron LI * the same as that of the previous section. 1272*3a289941SAaron LI * We'll check for that later. 1273*3a289941SAaron LI */ 1274*3a289941SAaron LI if (p->swapped) { 1275*3a289941SAaron LI shbp->byte_order_magic = 1276*3a289941SAaron LI SWAPLONG(shbp->byte_order_magic); 1277*3a289941SAaron LI shbp->major_version = 1278*3a289941SAaron LI SWAPSHORT(shbp->major_version); 1279*3a289941SAaron LI } 1280*3a289941SAaron LI 1281*3a289941SAaron LI /* 1282*3a289941SAaron LI * Make sure the byte order doesn't change; 1283*3a289941SAaron LI * pcap_is_swapped() shouldn't change its 1284*3a289941SAaron LI * return value in the middle of reading a capture. 1285*3a289941SAaron LI */ 1286*3a289941SAaron LI switch (shbp->byte_order_magic) { 1287*3a289941SAaron LI 1288*3a289941SAaron LI case BYTE_ORDER_MAGIC: 1289*3a289941SAaron LI /* 1290*3a289941SAaron LI * OK. 1291*3a289941SAaron LI */ 1292*3a289941SAaron LI break; 1293*3a289941SAaron LI 1294*3a289941SAaron LI case SWAPLONG(BYTE_ORDER_MAGIC): 1295*3a289941SAaron LI /* 1296*3a289941SAaron LI * Byte order changes. 1297*3a289941SAaron LI */ 1298*3a289941SAaron LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1299*3a289941SAaron LI "the file has sections with different byte orders"); 1300*3a289941SAaron LI return (-1); 1301*3a289941SAaron LI 1302*3a289941SAaron LI default: 1303*3a289941SAaron LI /* 1304*3a289941SAaron LI * Not a valid SHB. 1305*3a289941SAaron LI */ 1306*3a289941SAaron LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1307*3a289941SAaron LI "the file has a section with a bad byte order magic field"); 1308*3a289941SAaron LI return (-1); 1309*3a289941SAaron LI } 1310*3a289941SAaron LI 1311*3a289941SAaron LI /* 1312*3a289941SAaron LI * Make sure the major version is the version 1313*3a289941SAaron LI * we handle. 1314*3a289941SAaron LI */ 1315*3a289941SAaron LI if (shbp->major_version != PCAP_NG_VERSION_MAJOR) { 1316*3a289941SAaron LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1317*3a289941SAaron LI "unknown pcapng savefile major version number %u", 1318*3a289941SAaron LI shbp->major_version); 1319*3a289941SAaron LI return (-1); 1320*3a289941SAaron LI } 1321*3a289941SAaron LI 1322*3a289941SAaron LI /* 1323*3a289941SAaron LI * Reset the interface count; this section should 1324*3a289941SAaron LI * have its own set of IDBs. If any of them 1325*3a289941SAaron LI * don't have the same interface type, snapshot 1326*3a289941SAaron LI * length, or resolution as the first interface 1327*3a289941SAaron LI * we saw, we'll fail. (And if we don't see 1328*3a289941SAaron LI * any IDBs, we'll fail when we see a packet 1329*3a289941SAaron LI * block.) 1330*3a289941SAaron LI */ 1331*3a289941SAaron LI ps->ifcount = 0; 1332*3a289941SAaron LI break; 1333*3a289941SAaron LI 1334*3a289941SAaron LI default: 1335*3a289941SAaron LI /* 1336*3a289941SAaron LI * Not a packet block, IDB, or SHB; ignore it. 1337*3a289941SAaron LI */ 1338*3a289941SAaron LI break; 1339*3a289941SAaron LI } 1340*3a289941SAaron LI } 1341*3a289941SAaron LI 1342*3a289941SAaron LI found: 1343*3a289941SAaron LI /* 1344*3a289941SAaron LI * Is the interface ID an interface we know? 1345*3a289941SAaron LI */ 1346*3a289941SAaron LI if (interface_id >= ps->ifcount) { 1347*3a289941SAaron LI /* 1348*3a289941SAaron LI * Yes. Fail. 1349*3a289941SAaron LI */ 1350*3a289941SAaron LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1351*3a289941SAaron LI "a packet arrived on interface %u, but there's no Interface Description Block for that interface", 1352*3a289941SAaron LI interface_id); 1353*3a289941SAaron LI return (-1); 1354*3a289941SAaron LI } 1355*3a289941SAaron LI 1356*3a289941SAaron LI if (hdr->caplen > (bpf_u_int32)p->snapshot) { 1357*3a289941SAaron LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1358*3a289941SAaron LI "invalid packet capture length %u, bigger than " 1359*3a289941SAaron LI "snaplen of %d", hdr->caplen, p->snapshot); 1360*3a289941SAaron LI return (-1); 1361*3a289941SAaron LI } 1362*3a289941SAaron LI 1363*3a289941SAaron LI /* 1364*3a289941SAaron LI * Convert the time stamp to seconds and fractions of a second, 1365*3a289941SAaron LI * with the fractions being in units of the file-supplied resolution. 1366*3a289941SAaron LI */ 1367*3a289941SAaron LI sec = t / ps->ifaces[interface_id].tsresol + ps->ifaces[interface_id].tsoffset; 1368*3a289941SAaron LI frac = t % ps->ifaces[interface_id].tsresol; 1369*3a289941SAaron LI 1370*3a289941SAaron LI /* 1371*3a289941SAaron LI * Convert the fractions from units of the file-supplied resolution 1372*3a289941SAaron LI * to units of the user-requested resolution. 1373*3a289941SAaron LI */ 1374*3a289941SAaron LI switch (ps->ifaces[interface_id].scale_type) { 1375*3a289941SAaron LI 1376*3a289941SAaron LI case PASS_THROUGH: 1377*3a289941SAaron LI /* 1378*3a289941SAaron LI * The interface resolution is what the user wants, 1379*3a289941SAaron LI * so we're done. 1380*3a289941SAaron LI */ 1381*3a289941SAaron LI break; 1382*3a289941SAaron LI 1383*3a289941SAaron LI case SCALE_UP_DEC: 1384*3a289941SAaron LI /* 1385*3a289941SAaron LI * The interface resolution is less than what the user 1386*3a289941SAaron LI * wants; scale the fractional part up to the units of 1387*3a289941SAaron LI * the resolution the user requested by multiplying by 1388*3a289941SAaron LI * the quotient of the user-requested resolution and the 1389*3a289941SAaron LI * file-supplied resolution. 1390*3a289941SAaron LI * 1391*3a289941SAaron LI * Those resolutions are both powers of 10, and the user- 1392*3a289941SAaron LI * requested resolution is greater than the file-supplied 1393*3a289941SAaron LI * resolution, so the quotient in question is an integer. 1394*3a289941SAaron LI * We've calculated that quotient already, so we just 1395*3a289941SAaron LI * multiply by it. 1396*3a289941SAaron LI */ 1397*3a289941SAaron LI frac *= ps->ifaces[interface_id].scale_factor; 1398*3a289941SAaron LI break; 1399*3a289941SAaron LI 1400*3a289941SAaron LI case SCALE_UP_BIN: 1401*3a289941SAaron LI /* 1402*3a289941SAaron LI * The interface resolution is less than what the user 1403*3a289941SAaron LI * wants; scale the fractional part up to the units of 1404*3a289941SAaron LI * the resolution the user requested by multiplying by 1405*3a289941SAaron LI * the quotient of the user-requested resolution and the 1406*3a289941SAaron LI * file-supplied resolution. 1407*3a289941SAaron LI * 1408*3a289941SAaron LI * The file-supplied resolution is a power of 2, so the 1409*3a289941SAaron LI * quotient is not an integer, so, in order to do this 1410*3a289941SAaron LI * entirely with integer arithmetic, we multiply by the 1411*3a289941SAaron LI * user-requested resolution and divide by the file- 1412*3a289941SAaron LI * supplied resolution. 1413*3a289941SAaron LI * 1414*3a289941SAaron LI * XXX - Is there something clever we could do here, 1415*3a289941SAaron LI * given that we know that the file-supplied resolution 1416*3a289941SAaron LI * is a power of 2? Doing a multiplication followed by 1417*3a289941SAaron LI * a division runs the risk of overflowing, and involves 1418*3a289941SAaron LI * two non-simple arithmetic operations. 1419*3a289941SAaron LI */ 1420*3a289941SAaron LI frac *= ps->user_tsresol; 1421*3a289941SAaron LI frac /= ps->ifaces[interface_id].tsresol; 1422*3a289941SAaron LI break; 1423*3a289941SAaron LI 1424*3a289941SAaron LI case SCALE_DOWN_DEC: 1425*3a289941SAaron LI /* 1426*3a289941SAaron LI * The interface resolution is greater than what the user 1427*3a289941SAaron LI * wants; scale the fractional part up to the units of 1428*3a289941SAaron LI * the resolution the user requested by multiplying by 1429*3a289941SAaron LI * the quotient of the user-requested resolution and the 1430*3a289941SAaron LI * file-supplied resolution. 1431*3a289941SAaron LI * 1432*3a289941SAaron LI * Those resolutions are both powers of 10, and the user- 1433*3a289941SAaron LI * requested resolution is less than the file-supplied 1434*3a289941SAaron LI * resolution, so the quotient in question isn't an 1435*3a289941SAaron LI * integer, but its reciprocal is, and we can just divide 1436*3a289941SAaron LI * by the reciprocal of the quotient. We've calculated 1437*3a289941SAaron LI * the reciprocal of that quotient already, so we must 1438*3a289941SAaron LI * divide by it. 1439*3a289941SAaron LI */ 1440*3a289941SAaron LI frac /= ps->ifaces[interface_id].scale_factor; 1441*3a289941SAaron LI break; 1442*3a289941SAaron LI 1443*3a289941SAaron LI 1444*3a289941SAaron LI case SCALE_DOWN_BIN: 1445*3a289941SAaron LI /* 1446*3a289941SAaron LI * The interface resolution is greater than what the user 1447*3a289941SAaron LI * wants; convert the fractional part to units of the 1448*3a289941SAaron LI * resolution the user requested by multiplying by the 1449*3a289941SAaron LI * quotient of the user-requested resolution and the 1450*3a289941SAaron LI * file-supplied resolution. We do that by multiplying 1451*3a289941SAaron LI * by the user-requested resolution and dividing by the 1452*3a289941SAaron LI * file-supplied resolution, as the quotient might not 1453*3a289941SAaron LI * fit in an integer. 1454*3a289941SAaron LI * 1455*3a289941SAaron LI * The file-supplied resolution is a power of 2, so the 1456*3a289941SAaron LI * quotient is not an integer, and neither is its 1457*3a289941SAaron LI * reciprocal, so, in order to do this entirely with 1458*3a289941SAaron LI * integer arithmetic, we multiply by the user-requested 1459*3a289941SAaron LI * resolution and divide by the file-supplied resolution. 1460*3a289941SAaron LI * 1461*3a289941SAaron LI * XXX - Is there something clever we could do here, 1462*3a289941SAaron LI * given that we know that the file-supplied resolution 1463*3a289941SAaron LI * is a power of 2? Doing a multiplication followed by 1464*3a289941SAaron LI * a division runs the risk of overflowing, and involves 1465*3a289941SAaron LI * two non-simple arithmetic operations. 1466*3a289941SAaron LI */ 1467*3a289941SAaron LI frac *= ps->user_tsresol; 1468*3a289941SAaron LI frac /= ps->ifaces[interface_id].tsresol; 1469*3a289941SAaron LI break; 1470*3a289941SAaron LI } 1471*3a289941SAaron LI #ifdef _WIN32 1472*3a289941SAaron LI /* 1473*3a289941SAaron LI * tv_sec and tv_used in the Windows struct timeval are both 1474*3a289941SAaron LI * longs. 1475*3a289941SAaron LI */ 1476*3a289941SAaron LI hdr->ts.tv_sec = (long)sec; 1477*3a289941SAaron LI hdr->ts.tv_usec = (long)frac; 1478*3a289941SAaron LI #else 1479*3a289941SAaron LI /* 1480*3a289941SAaron LI * tv_sec in the UN*X struct timeval is a time_t; tv_usec is 1481*3a289941SAaron LI * suseconds_t in UN*Xes that work the way the current Single 1482*3a289941SAaron LI * UNIX Standard specify - but not all older UN*Xes necessarily 1483*3a289941SAaron LI * support that type, so just cast to int. 1484*3a289941SAaron LI */ 1485*3a289941SAaron LI hdr->ts.tv_sec = (time_t)sec; 1486*3a289941SAaron LI hdr->ts.tv_usec = (int)frac; 1487*3a289941SAaron LI #endif 1488*3a289941SAaron LI 1489*3a289941SAaron LI /* 1490*3a289941SAaron LI * Get a pointer to the packet data. 1491*3a289941SAaron LI */ 1492*3a289941SAaron LI *data = get_from_block_data(&cursor, hdr->caplen, p->errbuf); 1493*3a289941SAaron LI if (*data == NULL) 1494*3a289941SAaron LI return (-1); 1495*3a289941SAaron LI 1496*3a289941SAaron LI if (p->swapped) 1497*3a289941SAaron LI swap_pseudo_headers(p->linktype, hdr, *data); 1498*3a289941SAaron LI 1499*3a289941SAaron LI return (0); 1500*3a289941SAaron LI } 1501