00001 /* 00002 * Copyright (c) 1993, 1994, 1995, 1996, 1997 00003 * The Regents of the University of California. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that: (1) source code distributions 00007 * retain the above copyright notice and this paragraph in its entirety, (2) 00008 * distributions including binary code include the above copyright notice and 00009 * this paragraph in its entirety in the documentation or other materials 00010 * provided with the distribution, and (3) all advertising materials mentioning 00011 * features or use of this software display the following acknowledgement: 00012 * ``This product includes software developed by the University of California, 00013 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 00014 * the University nor the names of its contributors may be used to endorse 00015 * or promote products derived from this software without specific prior 00016 * written permission. 00017 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 00018 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 00019 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00020 * 00021 * savefile.c - supports offline use of tcpdump 00022 * Extraction/creation by Jeffrey Mogul, DECWRL 00023 * Modified by Steve McCanne, LBL. 00024 * 00025 * Used to save the received packet headers, after filtering, to 00026 * a file, and then read them later. 00027 * The first record in the file contains saved values for the machine 00028 * dependent values so we can print the dump file on any architecture. 00029 */ 00030 00031 #ifndef lint 00032 static const char rcsid[] = 00033 "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.75 2003/01/23 07:24:53 guy Exp $ (LBL)"; 00034 #endif 00035 00036 #ifdef HAVE_CONFIG_H 00037 #include "config.h" 00038 #endif 00039 00040 #include <errno.h> 00041 #include <memory.h> 00042 #include <stdio.h> 00043 #include <stdlib.h> 00044 #include <string.h> 00045 00046 #include "pcap-int.h" 00047 00048 #ifdef HAVE_OS_PROTO_H 00049 #include "os-proto.h" 00050 #endif 00051 00052 #define TCPDUMP_MAGIC 0xa1b2c3d4 00053 #define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34 00054 00055 /* 00056 * We use the "receiver-makes-right" approach to byte order, 00057 * because time is at a premium when we are writing the file. 00058 * In other words, the pcap_file_header and pcap_pkthdr, 00059 * records are written in host byte order. 00060 * Note that the packets are always written in network byte order. 00061 * 00062 * ntoh[ls] aren't sufficient because we might need to swap on a big-endian 00063 * machine (if the file was written in little-end order). 00064 */ 00065 #define SWAPLONG(y) \ 00066 ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) 00067 #define SWAPSHORT(y) \ 00068 ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) ) 00069 00070 #define SFERR_TRUNC 1 00071 #define SFERR_BADVERSION 2 00072 #define SFERR_BADF 3 00073 #define SFERR_EOF 4 /* not really an error, just a status */ 00074 00075 /* 00076 * We don't write DLT_* values to the capture file header, because 00077 * they're not the same on all platforms. 00078 * 00079 * Unfortunately, the various flavors of BSD have not always used the same 00080 * numerical values for the same data types, and various patches to 00081 * libpcap for non-BSD OSes have added their own DLT_* codes for link 00082 * layer encapsulation types seen on those OSes, and those codes have had, 00083 * in some cases, values that were also used, on other platforms, for other 00084 * link layer encapsulation types. 00085 * 00086 * This means that capture files of a type whose numerical DLT_* code 00087 * means different things on different BSDs, or with different versions 00088 * of libpcap, can't always be read on systems other than those like 00089 * the one running on the machine on which the capture was made. 00090 * 00091 * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes 00092 * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_* 00093 * codes to DLT_* codes when reading a savefile header. 00094 * 00095 * For those DLT_* codes that have, as far as we know, the same values on 00096 * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as 00097 * DLT_xxx; that way, captures of those types can still be read by 00098 * versions of libpcap that map LINKTYPE_* values to DLT_* values, and 00099 * captures of those types written by versions of libpcap that map DLT_ 00100 * values to LINKTYPE_ values can still be read by older versions 00101 * of libpcap. 00102 * 00103 * The other LINKTYPE_* codes are given values starting at 100, in the 00104 * hopes that no DLT_* code will be given one of those values. 00105 * 00106 * In order to ensure that a given LINKTYPE_* code's value will refer to 00107 * the same encapsulation type on all platforms, you should not allocate 00108 * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org". 00109 * The tcpdump developers will allocate a value for you, and will not 00110 * subsequently allocate it to anybody else; that value will be added to 00111 * the "pcap.h" in the tcpdump.org CVS repository, so that a future 00112 * libpcap release will include it. 00113 * 00114 * You should, if possible, also contribute patches to libpcap and tcpdump 00115 * to handle the new encapsulation type, so that they can also be checked 00116 * into the tcpdump.org CVS repository and so that they will appear in 00117 * future libpcap and tcpdump releases. 00118 */ 00119 #define LINKTYPE_NULL DLT_NULL 00120 #define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */ 00121 #define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */ 00122 #define LINKTYPE_AX25 DLT_AX25 00123 #define LINKTYPE_PRONET DLT_PRONET 00124 #define LINKTYPE_CHAOS DLT_CHAOS 00125 #define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */ 00126 #define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */ 00127 #define LINKTYPE_SLIP DLT_SLIP 00128 #define LINKTYPE_PPP DLT_PPP 00129 #define LINKTYPE_FDDI DLT_FDDI 00130 00131 /* 00132 * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662 00133 * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol 00134 * field) at the beginning of the packet. 00135 * 00136 * This is for use when there is always such a header; the address field 00137 * might be 0xff, for regular PPP, or it might be an address field for Cisco 00138 * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco 00139 * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL. 00140 * 00141 * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that 00142 * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL 00143 * captures will be written out with a link type that NetBSD's tcpdump 00144 * can read. 00145 */ 00146 #define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */ 00147 00148 #define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */ 00149 00150 #define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */ 00151 #define LINKTYPE_RAW 101 /* raw IP */ 00152 #define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */ 00153 #define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */ 00154 #define LINKTYPE_C_HDLC 104 /* Cisco HDLC */ 00155 #define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */ 00156 #define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */ 00157 #define LINKTYPE_FRELAY 107 /* Frame Relay */ 00158 #define LINKTYPE_LOOP 108 /* OpenBSD loopback */ 00159 00160 #define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */ 00161 #define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */ 00162 #define LINKTYPE_ECONET 115 /* Acorn Econet */ 00163 00164 #define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */ 00165 #define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */ 00166 #define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */ 00167 #define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ 00168 #define LINKTYPE_SUNATM 123 /* Solaris+SunATM */ 00169 00170 #define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */ 00171 00172 #define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */ 00173 00174 #define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */ 00175 00176 /* 00177 * These types are reserved for future use. 00178 */ 00179 #define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */ 00180 #define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */ 00181 #define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */ 00182 #define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */ 00183 #define LINKTYPE_IPFILTER 116 /* IP Filter capture files */ 00184 #define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */ 00185 #define LINKTYPE_HHDLC 121 /* Siemens HiPath HDLC */ 00186 #define LINKTYPE_RIO 124 /* RapidIO */ 00187 #define LINKTYPE_PCI_EXP 125 /* PCI Express */ 00188 #define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */ 00189 00190 static struct linktype_map { 00191 int dlt; 00192 int linktype; 00193 } map[] = { 00194 /* 00195 * These DLT_* codes have LINKTYPE_* codes with values identical 00196 * to the values of the corresponding DLT_* code. 00197 */ 00198 { DLT_NULL, LINKTYPE_NULL }, 00199 { DLT_EN10MB, LINKTYPE_ETHERNET }, 00200 { DLT_EN3MB, LINKTYPE_EXP_ETHERNET }, 00201 { DLT_AX25, LINKTYPE_AX25 }, 00202 { DLT_PRONET, LINKTYPE_PRONET }, 00203 { DLT_CHAOS, LINKTYPE_CHAOS }, 00204 { DLT_IEEE802, LINKTYPE_TOKEN_RING }, 00205 { DLT_ARCNET, LINKTYPE_ARCNET }, 00206 { DLT_SLIP, LINKTYPE_SLIP }, 00207 { DLT_PPP, LINKTYPE_PPP }, 00208 { DLT_FDDI, LINKTYPE_FDDI }, 00209 00210 /* 00211 * These DLT_* codes have different values on different 00212 * platforms; we map them to LINKTYPE_* codes that 00213 * have values that should never be equal to any DLT_* 00214 * code. 00215 */ 00216 #ifdef DLT_FR 00217 /* BSD/OS Frame Relay */ 00218 { DLT_FR, LINKTYPE_FRELAY }, 00219 #endif 00220 { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 }, 00221 { DLT_RAW, LINKTYPE_RAW }, 00222 { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS }, 00223 { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS }, 00224 00225 /* BSD/OS Cisco HDLC */ 00226 { DLT_C_HDLC, LINKTYPE_C_HDLC }, 00227 00228 /* 00229 * These DLT_* codes are not on all platforms, but, so far, 00230 * there don't appear to be any platforms that define 00231 * other codes with those values; we map them to 00232 * different LINKTYPE_* values anyway, just in case. 00233 */ 00234 00235 /* Linux ATM Classical IP */ 00236 { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP }, 00237 00238 /* NetBSD sync/async serial PPP (or Cisco HDLC) */ 00239 { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC }, 00240 00241 /* NetBSD PPP over Ethernet */ 00242 { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER }, 00243 00244 /* IEEE 802.11 wireless */ 00245 { DLT_IEEE802_11, LINKTYPE_IEEE802_11 }, 00246 00247 /* Frame Relay */ 00248 { DLT_FRELAY, LINKTYPE_FRELAY }, 00249 00250 /* OpenBSD loopback */ 00251 { DLT_LOOP, LINKTYPE_LOOP }, 00252 00253 /* Linux cooked socket capture */ 00254 { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL }, 00255 00256 /* Apple LocalTalk hardware */ 00257 { DLT_LTALK, LINKTYPE_LTALK }, 00258 00259 /* Acorn Econet */ 00260 { DLT_ECONET, LINKTYPE_ECONET }, 00261 00262 /* For Cisco-internal use */ 00263 { DLT_CISCO_IOS, LINKTYPE_CISCO_IOS }, 00264 00265 /* Prism II monitor-mode header plus 802.11 header */ 00266 { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER }, 00267 00268 /* FreeBSD Aironet driver stuff */ 00269 { DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER }, 00270 00271 /* Siemens HiPath HDLC */ 00272 { DLT_HHDLC, LINKTYPE_HHDLC }, 00273 00274 /* RFC 2625 IP-over-Fibre Channel */ 00275 { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC }, 00276 00277 /* Solaris+SunATM */ 00278 { DLT_SUNATM, LINKTYPE_SUNATM }, 00279 00280 /* RapidIO */ 00281 { DLT_RIO, LINKTYPE_RIO }, 00282 00283 /* PCI Express */ 00284 { DLT_PCI_EXP, LINKTYPE_PCI_EXP }, 00285 00286 /* Xilinx Aurora link layer */ 00287 { DLT_AURORA, LINKTYPE_AURORA }, 00288 00289 /* 802.11 plus WLAN header */ 00290 { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO }, 00291 00292 /* Tazmen Sniffer Protocol */ 00293 { DLT_TZSP, LINKTYPE_TZSP }, 00294 00295 /* Arcnet with Linux-style link-layer headers */ 00296 { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX }, 00297 00298 /* 00299 * Any platform that defines additional DLT_* codes should: 00300 * 00301 * request a LINKTYPE_* code and value from tcpdump.org, 00302 * as per the above; 00303 * 00304 * add, in their version of libpcap, an entry to map 00305 * those DLT_* codes to the corresponding LINKTYPE_* 00306 * code; 00307 * 00308 * redefine, in their "net/bpf.h", any DLT_* values 00309 * that collide with the values used by their additional 00310 * DLT_* codes, to remove those collisions (but without 00311 * making them collide with any of the LINKTYPE_* 00312 * values equal to 50 or above; they should also avoid 00313 * defining DLT_* values that collide with those 00314 * LINKTYPE_* values, either). 00315 */ 00316 { -1, -1 } 00317 }; 00318 00319 static int 00320 dlt_to_linktype(int dlt) 00321 { 00322 int i; 00323 00324 for (i = 0; map[i].dlt != -1; i++) { 00325 if (map[i].dlt == dlt) 00326 return (map[i].linktype); 00327 } 00328 00329 /* 00330 * If we don't have a mapping for this DLT_ code, return an 00331 * error; that means that the table above needs to have an 00332 * entry added. 00333 */ 00334 return (-1); 00335 } 00336 00337 static int 00338 linktype_to_dlt(int linktype) 00339 { 00340 int i; 00341 00342 for (i = 0; map[i].linktype != -1; i++) { 00343 if (map[i].linktype == linktype) 00344 return (map[i].dlt); 00345 } 00346 00347 /* 00348 * If we don't have an entry for this link type, return 00349 * the link type value; it may be a DLT_ value from an 00350 * older version of libpcap. 00351 */ 00352 return linktype; 00353 } 00354 00355 static int 00356 sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) 00357 { 00358 struct pcap_file_header hdr; 00359 00360 hdr.magic = TCPDUMP_MAGIC; 00361 hdr.version_major = PCAP_VERSION_MAJOR; 00362 hdr.version_minor = PCAP_VERSION_MINOR; 00363 00364 hdr.thiszone = thiszone; 00365 hdr.snaplen = snaplen; 00366 hdr.sigfigs = 0; 00367 hdr.linktype = linktype; 00368 00369 if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) 00370 return (-1); 00371 00372 return (0); 00373 } 00374 00375 static void 00376 swap_hdr(struct pcap_file_header *hp) 00377 { 00378 hp->version_major = SWAPSHORT(hp->version_major); 00379 hp->version_minor = SWAPSHORT(hp->version_minor); 00380 hp->thiszone = SWAPLONG(hp->thiszone); 00381 hp->sigfigs = SWAPLONG(hp->sigfigs); 00382 hp->snaplen = SWAPLONG(hp->snaplen); 00383 hp->linktype = SWAPLONG(hp->linktype); 00384 } 00385 00386 pcap_t * 00387 pcap_open_offline(const char *fname, char *errbuf) 00388 { 00389 register pcap_t *p; 00390 register FILE *fp; 00391 struct pcap_file_header hdr; 00392 bpf_u_int32 magic; 00393 int linklen; 00394 00395 p = (pcap_t *)malloc(sizeof(*p)); 00396 if (p == NULL) { 00397 strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 00398 return (NULL); 00399 } 00400 00401 memset((char *)p, 0, sizeof(*p)); 00402 /* 00403 * Set this field so we don't close stdin in pcap_close! 00404 */ 00405 #ifndef WIN32 00406 p->fd = -1; 00407 #else 00408 p->adapter = NULL; 00409 #endif 00410 00411 if (fname[0] == '-' && fname[1] == '\0') 00412 fp = stdin; 00413 else { 00414 #ifndef WIN32 00415 fp = fopen(fname, "r"); 00416 #else 00417 fp = fopen(fname, "rb"); 00418 #endif 00419 if (fp == NULL) { 00420 snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, 00421 pcap_strerror(errno)); 00422 goto bad; 00423 } 00424 } 00425 if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) { 00426 snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s", 00427 pcap_strerror(errno)); 00428 goto bad; 00429 } 00430 magic = hdr.magic; 00431 if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { 00432 magic = SWAPLONG(magic); 00433 if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { 00434 snprintf(errbuf, PCAP_ERRBUF_SIZE, 00435 "bad dump file format"); 00436 goto bad; 00437 } 00438 p->sf.swapped = 1; 00439 swap_hdr(&hdr); 00440 } 00441 if (magic == PATCHED_TCPDUMP_MAGIC) { 00442 /* 00443 * XXX - the patch that's in some versions of libpcap 00444 * changes the packet header but not the magic number; 00445 * we'd have to use some hacks^H^H^H^H^Hheuristics to 00446 * detect that. 00447 */ 00448 p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr); 00449 } else 00450 p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr); 00451 if (hdr.version_major < PCAP_VERSION_MAJOR) { 00452 snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format"); 00453 goto bad; 00454 } 00455 p->tzoff = hdr.thiszone; 00456 p->snapshot = hdr.snaplen; 00457 p->linktype = linktype_to_dlt(hdr.linktype); 00458 p->sf.rfile = fp; 00459 #ifndef WIN32 00460 p->bufsize = hdr.snaplen; 00461 #else 00462 /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */ 00463 p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr); 00464 #endif 00465 00466 /* Align link header as required for proper data alignment */ 00467 /* XXX should handle all types */ 00468 switch (p->linktype) { 00469 00470 case DLT_EN10MB: 00471 linklen = 14; 00472 break; 00473 00474 case DLT_FDDI: 00475 linklen = 13 + 8; /* fddi_header + llc */ 00476 break; 00477 00478 case DLT_NULL: 00479 default: 00480 linklen = 0; 00481 break; 00482 } 00483 00484 if (p->bufsize < 0) 00485 p->bufsize = BPF_MAXBUFSIZE; 00486 p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); 00487 if (p->sf.base == NULL) { 00488 strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 00489 goto bad; 00490 } 00491 p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); 00492 p->sf.version_major = hdr.version_major; 00493 p->sf.version_minor = hdr.version_minor; 00494 #ifdef PCAP_FDDIPAD 00495 /* XXX padding only needed for kernel fcode */ 00496 pcap_fddipad = 0; 00497 #endif 00498 00499 return (p); 00500 bad: 00501 if(fp) 00502 fclose(fp); 00503 free(p); 00504 return (NULL); 00505 } 00506 00507 /* 00508 * Read sf_readfile and return the next packet. Return the header in hdr 00509 * and the contents in buf. Return 0 on success, SFERR_EOF if there were 00510 * no more packets, and SFERR_TRUNC if a partial packet was encountered. 00511 */ 00512 #if (defined(HAVE_PCAPREADEX) || defined(WIN32) ) 00513 int 00514 #else 00515 static int 00516 #endif 00517 sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) 00518 { 00519 struct pcap_sf_patched_pkthdr sf_hdr; 00520 FILE *fp = p->sf.rfile; 00521 00522 /* 00523 * Read the packet header; the structure we use as a buffer 00524 * is the longer structure for files generated by the patched 00525 * libpcap, but if the file has the magic number for an 00526 * unpatched libpcap we only read as many bytes as the regular 00527 * header has. 00528 */ 00529 if (fread(&sf_hdr, p->sf.hdrsize, 1, fp) != 1) { 00530 /* probably an EOF, though could be a truncated packet */ 00531 return (1); 00532 } 00533 00534 if (p->sf.swapped) { 00535 /* these were written in opposite byte order */ 00536 hdr->caplen = SWAPLONG(sf_hdr.caplen); 00537 hdr->len = SWAPLONG(sf_hdr.len); 00538 hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); 00539 hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); 00540 } else { 00541 hdr->caplen = sf_hdr.caplen; 00542 hdr->len = sf_hdr.len; 00543 hdr->ts.tv_sec = sf_hdr.ts.tv_sec; 00544 hdr->ts.tv_usec = sf_hdr.ts.tv_usec; 00545 } 00546 /* 00547 * We interchanged the caplen and len fields at version 2.3, 00548 * in order to match the bpf header layout. But unfortunately 00549 * some files were written with version 2.3 in their headers 00550 * but without the interchanged fields. 00551 */ 00552 if (p->sf.version_minor < 3 || 00553 (p->sf.version_minor == 3 && hdr->caplen > hdr->len)) { 00554 int t = hdr->caplen; 00555 hdr->caplen = hdr->len; 00556 hdr->len = t; 00557 } 00558 00559 if (hdr->caplen > buflen) { 00560 /* 00561 * This can happen due to Solaris 2.3 systems tripping 00562 * over the BUFMOD problem and not setting the snapshot 00563 * correctly in the savefile header. If the caplen isn't 00564 * grossly wrong, try to salvage. 00565 */ 00566 static u_char *tp = NULL; 00567 static int tsize = 0; 00568 00569 if (hdr->caplen > 65535) { 00570 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00571 "bogus savefile header"); 00572 return (-1); 00573 } 00574 00575 if (tsize < hdr->caplen) { 00576 tsize = ((hdr->caplen + 1023) / 1024) * 1024; 00577 if (tp != NULL) 00578 free((u_char *)tp); 00579 tp = (u_char *)malloc(tsize); 00580 if (tp == NULL) { 00581 tsize = 0; 00582 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00583 "BUFMOD hack malloc"); 00584 return (-1); 00585 } 00586 } 00587 if (fread((char *)tp, hdr->caplen, 1, fp) != 1) { 00588 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00589 "truncated dump file"); 00590 return (-1); 00591 } 00592 /* 00593 * We can only keep up to buflen bytes. Since caplen > buflen 00594 * is exactly how we got here, we know we can only keep the 00595 * first buflen bytes and must drop the remainder. Adjust 00596 * caplen accordingly, so we don't get confused later as 00597 * to how many bytes we have to play with. 00598 */ 00599 hdr->caplen = buflen; 00600 memcpy((char *)buf, (char *)tp, buflen); 00601 00602 } else { 00603 /* read the packet itself */ 00604 00605 if (fread((char *)buf, hdr->caplen, 1, fp) != 1) { 00606 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00607 "truncated dump file"); 00608 return (-1); 00609 } 00610 } 00611 return (0); 00612 } 00613 00614 /* 00615 * Print out packets stored in the file initialized by sf_read_init(). 00616 * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. 00617 */ 00618 int 00619 pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 00620 { 00621 struct bpf_insn *fcode = p->fcode.bf_insns; 00622 int status = 0; 00623 int n = 0; 00624 00625 while (status == 0) { 00626 struct pcap_pkthdr h; 00627 00628 status = sf_next_packet(p, &h, p->buffer, p->bufsize); 00629 if (status) { 00630 if (status == 1) 00631 return (0); 00632 return (status); 00633 } 00634 00635 if (fcode == NULL || 00636 bpf_filter(fcode, p->buffer, h.len, h.caplen)) { 00637 (*callback)(user, &h, p->buffer); 00638 if (++n >= cnt && cnt > 0) 00639 break; 00640 } 00641 } 00642 /*XXX this breaks semantics tcpslice expects */ 00643 return (n); 00644 } 00645 00646 /* 00647 * Output a packet to the initialized dump file. 00648 */ 00649 void 00650 pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 00651 { 00652 register FILE *f; 00653 struct pcap_sf_pkthdr sf_hdr; 00654 00655 f = (FILE *)user; 00656 sf_hdr.ts.tv_sec = h->ts.tv_sec; 00657 sf_hdr.ts.tv_usec = h->ts.tv_usec; 00658 sf_hdr.caplen = h->caplen; 00659 sf_hdr.len = h->len; 00660 /* XXX we should check the return status */ 00661 (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); 00662 (void)fwrite((char *)sp, h->caplen, 1, f); 00663 } 00664 00665 /* 00666 * Initialize so that sf_write() will output to the file named 'fname'. 00667 */ 00668 pcap_dumper_t * 00669 pcap_dump_open(pcap_t *p, const char *fname) 00670 { 00671 FILE *f; 00672 int linktype; 00673 00674 linktype = dlt_to_linktype(p->linktype); 00675 if (linktype == -1) { 00676 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00677 "%s: link-layer type %d isn't supported in savefiles", 00678 fname, linktype); 00679 return (NULL); 00680 } 00681 00682 if (fname[0] == '-' && fname[1] == '\0') { 00683 f = stdout; 00684 #ifdef WIN32 00685 _setmode(_fileno(f), _O_BINARY); 00686 #endif 00687 } else { 00688 #ifndef WIN32 00689 f = fopen(fname, "w"); 00690 #else 00691 f = fopen(fname, "wb"); 00692 setbuf(f, NULL); /* XXX - why? */ 00693 #endif 00694 if (f == NULL) { 00695 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", 00696 fname, pcap_strerror(errno)); 00697 return (NULL); 00698 } 00699 } 00700 (void)sf_write_header(f, linktype, p->tzoff, p->snapshot); 00701 return ((pcap_dumper_t *)f); 00702 } 00703 00704 int 00705 pcap_dump_flush(pcap_dumper_t *p) 00706 { 00707 00708 if (fflush((FILE *)p) == EOF) 00709 return (-1); 00710 else 00711 return (0); 00712 } 00713 00714 void 00715 pcap_dump_close(pcap_dumper_t *p) 00716 { 00717 00718 #ifdef notyet 00719 if (ferror((FILE *)p)) 00720 return-an-error; 00721 /* XXX should check return from fclose() too */ 00722 #endif 00723 (void)fclose((FILE *)p); 00724 }
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.