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.66 2002/08/06 06:27:49 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 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_SUNATM 123 /* Solaris+SunATM */ 00168 00169 /* 00170 * These types are reserved for future use. 00171 */ 00172 #define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */ 00173 #define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */ 00174 #define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */ 00175 #define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */ 00176 #define LINKTYPE_IPFILTER 116 /* IP Filter capture files */ 00177 #define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */ 00178 #define LINKTYPE_HHDLC 121 /* Siemens HiPath HDLC */ 00179 #define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ 00180 00181 static struct linktype_map { 00182 int dlt; 00183 int linktype; 00184 } map[] = { 00185 /* 00186 * These DLT_* codes have LINKTYPE_* codes with values identical 00187 * to the values of the corresponding DLT_* code. 00188 */ 00189 { DLT_NULL, LINKTYPE_NULL }, 00190 { DLT_EN10MB, LINKTYPE_ETHERNET }, 00191 { DLT_EN3MB, LINKTYPE_EXP_ETHERNET }, 00192 { DLT_AX25, LINKTYPE_AX25 }, 00193 { DLT_PRONET, LINKTYPE_PRONET }, 00194 { DLT_CHAOS, LINKTYPE_CHAOS }, 00195 { DLT_IEEE802, LINKTYPE_TOKEN_RING }, 00196 { DLT_ARCNET, LINKTYPE_ARCNET }, 00197 { DLT_SLIP, LINKTYPE_SLIP }, 00198 { DLT_PPP, LINKTYPE_PPP }, 00199 { DLT_FDDI, LINKTYPE_FDDI }, 00200 00201 /* 00202 * These DLT_* codes have different values on different 00203 * platforms; we map them to LINKTYPE_* codes that 00204 * have values that should never be equal to any DLT_* 00205 * code. 00206 */ 00207 #ifdef DLT_FR 00208 /* BSD/OS Frame Relay */ 00209 { DLT_FR, LINKTYPE_FRELAY }, 00210 #endif 00211 { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 }, 00212 { DLT_RAW, LINKTYPE_RAW }, 00213 { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS }, 00214 { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS }, 00215 00216 /* BSD/OS Cisco HDLC */ 00217 { DLT_C_HDLC, LINKTYPE_C_HDLC }, 00218 00219 /* 00220 * These DLT_* codes are not on all platforms, but, so far, 00221 * there don't appear to be any platforms that define 00222 * other codes with those values; we map them to 00223 * different LINKTYPE_* values anyway, just in case. 00224 */ 00225 00226 /* Linux ATM Classical IP */ 00227 { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP }, 00228 00229 /* NetBSD sync/async serial PPP (or Cisco HDLC) */ 00230 { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC }, 00231 00232 /* NetBSD PPP over Ethernet */ 00233 { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER }, 00234 00235 /* IEEE 802.11 wireless */ 00236 { DLT_IEEE802_11, LINKTYPE_IEEE802_11 }, 00237 00238 /* Frame Relay */ 00239 { DLT_FRELAY, LINKTYPE_FRELAY }, 00240 00241 /* OpenBSD loopback */ 00242 { DLT_LOOP, LINKTYPE_LOOP }, 00243 00244 /* Linux cooked socket capture */ 00245 { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL }, 00246 00247 /* Apple LocalTalk hardware */ 00248 { DLT_LTALK, LINKTYPE_LTALK }, 00249 00250 /* Acorn Econet */ 00251 { DLT_ECONET, LINKTYPE_ECONET }, 00252 00253 /* For Cisco-internal use */ 00254 { DLT_CISCO_IOS, LINKTYPE_CISCO_IOS }, 00255 00256 /* Prism II monitor-mode header plus 802.11 header */ 00257 { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER }, 00258 00259 /* FreeBSD Aironet driver stuff */ 00260 { DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER }, 00261 00262 /* Siemens HiPath HDLC */ 00263 { DLT_HHDLC, LINKTYPE_HHDLC }, 00264 00265 /* RFC 2625 IP-over-Fibre Channel */ 00266 { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC }, 00267 00268 /* Solaris+SunATM */ 00269 { DLT_SUNATM, LINKTYPE_SUNATM }, 00270 00271 /* 00272 * Any platform that defines additional DLT_* codes should: 00273 * 00274 * request a LINKTYPE_* code and value from tcpdump.org, 00275 * as per the above; 00276 * 00277 * add, in their version of libpcap, an entry to map 00278 * those DLT_* codes to the corresponding LINKTYPE_* 00279 * code; 00280 * 00281 * redefine, in their "net/bpf.h", any DLT_* values 00282 * that collide with the values used by their additional 00283 * DLT_* codes, to remove those collisions (but without 00284 * making them collide with any of the LINKTYPE_* 00285 * values equal to 50 or above; they should also avoid 00286 * defining DLT_* values that collide with those 00287 * LINKTYPE_* values, either). 00288 */ 00289 { -1, -1 } 00290 }; 00291 00292 static int 00293 dlt_to_linktype(int dlt) 00294 { 00295 int i; 00296 00297 for (i = 0; map[i].dlt != -1; i++) { 00298 if (map[i].dlt == dlt) 00299 return (map[i].linktype); 00300 } 00301 00302 /* 00303 * If we don't have a mapping for this DLT_ code, return an 00304 * error; that means that the table above needs to have an 00305 * entry added. 00306 */ 00307 return (-1); 00308 } 00309 00310 static int 00311 linktype_to_dlt(int linktype) 00312 { 00313 int i; 00314 00315 for (i = 0; map[i].linktype != -1; i++) { 00316 if (map[i].linktype == linktype) 00317 return (map[i].dlt); 00318 } 00319 00320 /* 00321 * If we don't have an entry for this link type, return 00322 * the link type value; it may be a DLT_ value from an 00323 * older version of libpcap. 00324 */ 00325 return linktype; 00326 } 00327 00328 static int 00329 sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) 00330 { 00331 struct pcap_file_header hdr; 00332 00333 hdr.magic = TCPDUMP_MAGIC; 00334 hdr.version_major = PCAP_VERSION_MAJOR; 00335 hdr.version_minor = PCAP_VERSION_MINOR; 00336 00337 hdr.thiszone = thiszone; 00338 hdr.snaplen = snaplen; 00339 hdr.sigfigs = 0; 00340 hdr.linktype = linktype; 00341 00342 if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) 00343 return (-1); 00344 00345 return (0); 00346 } 00347 00348 static void 00349 swap_hdr(struct pcap_file_header *hp) 00350 { 00351 hp->version_major = SWAPSHORT(hp->version_major); 00352 hp->version_minor = SWAPSHORT(hp->version_minor); 00353 hp->thiszone = SWAPLONG(hp->thiszone); 00354 hp->sigfigs = SWAPLONG(hp->sigfigs); 00355 hp->snaplen = SWAPLONG(hp->snaplen); 00356 hp->linktype = SWAPLONG(hp->linktype); 00357 } 00358 00359 pcap_t * 00360 pcap_open_offline(const char *fname, char *errbuf) 00361 { 00362 register pcap_t *p; 00363 register FILE *fp; 00364 struct pcap_file_header hdr; 00365 bpf_u_int32 magic; 00366 int linklen; 00367 00368 p = (pcap_t *)malloc(sizeof(*p)); 00369 if (p == NULL) { 00370 strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 00371 return (NULL); 00372 } 00373 00374 memset((char *)p, 0, sizeof(*p)); 00375 /* 00376 * Set this field so we don't close stdin in pcap_close! 00377 */ 00378 #ifndef WIN32 00379 p->fd = -1; 00380 #else 00381 p->adapter = NULL; 00382 #endif 00383 00384 if (fname[0] == '-' && fname[1] == '\0') 00385 fp = stdin; 00386 else { 00387 #ifndef WIN32 00388 fp = fopen(fname, "r"); 00389 #else 00390 fp = fopen(fname, "rb"); 00391 #endif 00392 if (fp == NULL) { 00393 snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, 00394 pcap_strerror(errno)); 00395 goto bad; 00396 } 00397 } 00398 if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) { 00399 snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s", 00400 pcap_strerror(errno)); 00401 goto bad; 00402 } 00403 magic = hdr.magic; 00404 if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { 00405 magic = SWAPLONG(magic); 00406 if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { 00407 snprintf(errbuf, PCAP_ERRBUF_SIZE, 00408 "bad dump file format"); 00409 goto bad; 00410 } 00411 p->sf.swapped = 1; 00412 swap_hdr(&hdr); 00413 } 00414 if (magic == PATCHED_TCPDUMP_MAGIC) { 00415 /* 00416 * XXX - the patch that's in some versions of libpcap 00417 * changes the packet header but not the magic number; 00418 * we'd have to use some hacks^H^H^H^H^Hheuristics to 00419 * detect that. 00420 */ 00421 p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr); 00422 } else 00423 p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr); 00424 if (hdr.version_major < PCAP_VERSION_MAJOR) { 00425 snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format"); 00426 goto bad; 00427 } 00428 p->tzoff = hdr.thiszone; 00429 p->snapshot = hdr.snaplen; 00430 p->linktype = linktype_to_dlt(hdr.linktype); 00431 p->sf.rfile = fp; 00432 #ifndef WIN32 00433 p->bufsize = hdr.snaplen; 00434 #else 00435 /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */ 00436 p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr); 00437 #endif 00438 00439 /* Align link header as required for proper data alignment */ 00440 /* XXX should handle all types */ 00441 switch (p->linktype) { 00442 00443 case DLT_EN10MB: 00444 linklen = 14; 00445 break; 00446 00447 case DLT_FDDI: 00448 linklen = 13 + 8; /* fddi_header + llc */ 00449 break; 00450 00451 case DLT_NULL: 00452 default: 00453 linklen = 0; 00454 break; 00455 } 00456 00457 if (p->bufsize < 0) 00458 p->bufsize = BPF_MAXBUFSIZE; 00459 p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); 00460 if (p->sf.base == NULL) { 00461 strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 00462 goto bad; 00463 } 00464 p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); 00465 p->sf.version_major = hdr.version_major; 00466 p->sf.version_minor = hdr.version_minor; 00467 #ifdef PCAP_FDDIPAD 00468 /* XXX padding only needed for kernel fcode */ 00469 pcap_fddipad = 0; 00470 #endif 00471 00472 return (p); 00473 bad: 00474 free(p); 00475 return (NULL); 00476 } 00477 00478 /* 00479 * Read sf_readfile and return the next packet. Return the header in hdr 00480 * and the contents in buf. Return 0 on success, SFERR_EOF if there were 00481 * no more packets, and SFERR_TRUNC if a partial packet was encountered. 00482 */ 00483 #ifdef WIN32 00484 int 00485 #else 00486 static int 00487 #endif 00488 sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) 00489 { 00490 struct pcap_sf_patched_pkthdr sf_hdr; 00491 FILE *fp = p->sf.rfile; 00492 00493 /* 00494 * Read the packet header; the structure we use as a buffer 00495 * is the longer structure for files generated by the patched 00496 * libpcap, but if the file has the magic number for an 00497 * unpatched libpcap we only read as many bytes as the regular 00498 * header has. 00499 */ 00500 if (fread(&sf_hdr, p->sf.hdrsize, 1, fp) != 1) { 00501 /* probably an EOF, though could be a truncated packet */ 00502 return (1); 00503 } 00504 00505 if (p->sf.swapped) { 00506 /* these were written in opposite byte order */ 00507 hdr->caplen = SWAPLONG(sf_hdr.caplen); 00508 hdr->len = SWAPLONG(sf_hdr.len); 00509 hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); 00510 hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); 00511 } else { 00512 hdr->caplen = sf_hdr.caplen; 00513 hdr->len = sf_hdr.len; 00514 hdr->ts.tv_sec = sf_hdr.ts.tv_sec; 00515 hdr->ts.tv_usec = sf_hdr.ts.tv_usec; 00516 } 00517 /* 00518 * We interchanged the caplen and len fields at version 2.3, 00519 * in order to match the bpf header layout. But unfortunately 00520 * some files were written with version 2.3 in their headers 00521 * but without the interchanged fields. 00522 */ 00523 if (p->sf.version_minor < 3 || 00524 (p->sf.version_minor == 3 && hdr->caplen > hdr->len)) { 00525 int t = hdr->caplen; 00526 hdr->caplen = hdr->len; 00527 hdr->len = t; 00528 } 00529 00530 if (hdr->caplen > buflen) { 00531 /* 00532 * This can happen due to Solaris 2.3 systems tripping 00533 * over the BUFMOD problem and not setting the snapshot 00534 * correctly in the savefile header. If the caplen isn't 00535 * grossly wrong, try to salvage. 00536 */ 00537 static u_char *tp = NULL; 00538 static int tsize = 0; 00539 00540 if (hdr->caplen > 65535) { 00541 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00542 "bogus savefile header"); 00543 return (-1); 00544 } 00545 00546 if (tsize < hdr->caplen) { 00547 tsize = ((hdr->caplen + 1023) / 1024) * 1024; 00548 if (tp != NULL) 00549 free((u_char *)tp); 00550 tp = (u_char *)malloc(tsize); 00551 if (tp == NULL) { 00552 tsize = 0; 00553 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00554 "BUFMOD hack malloc"); 00555 return (-1); 00556 } 00557 } 00558 if (fread((char *)tp, hdr->caplen, 1, fp) != 1) { 00559 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00560 "truncated dump file"); 00561 return (-1); 00562 } 00563 /* 00564 * We can only keep up to buflen bytes. Since caplen > buflen 00565 * is exactly how we got here, we know we can only keep the 00566 * first buflen bytes and must drop the remainder. Adjust 00567 * caplen accordingly, so we don't get confused later as 00568 * to how many bytes we have to play with. 00569 */ 00570 hdr->caplen = buflen; 00571 memcpy((char *)buf, (char *)tp, buflen); 00572 00573 } else { 00574 /* read the packet itself */ 00575 00576 if (fread((char *)buf, hdr->caplen, 1, fp) != 1) { 00577 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00578 "truncated dump file"); 00579 return (-1); 00580 } 00581 } 00582 return (0); 00583 } 00584 00585 /* 00586 * Print out packets stored in the file initialized by sf_read_init(). 00587 * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. 00588 */ 00589 int 00590 pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 00591 { 00592 struct bpf_insn *fcode = p->fcode.bf_insns; 00593 int status = 0; 00594 int n = 0; 00595 00596 while (status == 0) { 00597 struct pcap_pkthdr h; 00598 00599 status = sf_next_packet(p, &h, p->buffer, p->bufsize); 00600 if (status) { 00601 if (status == 1) 00602 return (0); 00603 return (status); 00604 } 00605 00606 if (fcode == NULL || 00607 bpf_filter(fcode, p->buffer, h.len, h.caplen)) { 00608 (*callback)(user, &h, p->buffer); 00609 if (++n >= cnt && cnt > 0) 00610 break; 00611 } 00612 } 00613 /*XXX this breaks semantics tcpslice expects */ 00614 return (n); 00615 } 00616 00617 /* 00618 * Output a packet to the initialized dump file. 00619 */ 00620 void 00621 pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 00622 { 00623 register FILE *f; 00624 struct pcap_sf_pkthdr sf_hdr; 00625 00626 f = (FILE *)user; 00627 sf_hdr.ts.tv_sec = h->ts.tv_sec; 00628 sf_hdr.ts.tv_usec = h->ts.tv_usec; 00629 sf_hdr.caplen = h->caplen; 00630 sf_hdr.len = h->len; 00631 /* XXX we should check the return status */ 00632 (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); 00633 (void)fwrite((char *)sp, h->caplen, 1, f); 00634 } 00635 00636 /* 00637 * Initialize so that sf_write() will output to the file named 'fname'. 00638 */ 00639 pcap_dumper_t * 00640 pcap_dump_open(pcap_t *p, const char *fname) 00641 { 00642 FILE *f; 00643 int linktype; 00644 00645 linktype = dlt_to_linktype(p->linktype); 00646 if (linktype == -1) { 00647 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00648 "%s: link-layer type %d isn't supported in savefiles", 00649 fname, linktype); 00650 return (NULL); 00651 } 00652 00653 if (fname[0] == '-' && fname[1] == '\0') { 00654 f = stdout; 00655 #ifdef WIN32 00656 _setmode(_fileno(f), _O_BINARY); 00657 #endif 00658 } else { 00659 #ifndef WIN32 00660 f = fopen(fname, "w"); 00661 #else 00662 f = fopen(fname, "wb"); 00663 setbuf(f, NULL); /* XXX - why? */ 00664 #endif 00665 if (f == NULL) { 00666 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", 00667 fname, pcap_strerror(errno)); 00668 return (NULL); 00669 } 00670 } 00671 (void)sf_write_header(f, linktype, p->tzoff, p->snapshot); 00672 return ((pcap_dumper_t *)f); 00673 } 00674 00675 void 00676 pcap_dump_close(pcap_dumper_t *p) 00677 { 00678 00679 #ifdef notyet 00680 if (ferror((FILE *)p)) 00681 return-an-error; 00682 /* XXX should check return from fclose() too */ 00683 #endif 00684 (void)fclose((FILE *)p); 00685 }
documentation. Copyright (c) 2002 Politecnico di Torino. All rights reserved.