Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 605 lines (542 sloc) 17.946 kb
b11ddf8 Initial revision
mcr authored
1 /*
2 * Copyright (c) 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * savefile.c - supports offline use of tcpdump
22 * Extraction/creation by Jeffrey Mogul, DECWRL
23 * Modified by Steve McCanne, LBL.
24 *
25 * Used to save the received packet headers, after filtering, to
26 * a file, and then read them later.
27 * The first record in the file contains saved values for the machine
28 * dependent values so we can print the dump file on any architecture.
29 */
30
31 #ifndef lint
32 static const char rcsid[] =
ef0a3b3 @yuguy Add a DLT_IEEE802_11 for use by any platform that provides raw 802.11
yuguy authored
33 "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.46 2000-11-15 05:36:48 guy Exp $ (LBL)";
0e2f8c8 add config.h, remove gnuc.h. remove __dead
assar authored
34 #endif
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
b11ddf8 Initial revision
mcr authored
38 #endif
39
40 #include <sys/types.h>
41 #include <sys/time.h>
42
43 #include <errno.h>
44 #include <memory.h>
45 #include <stdio.h>
46 #include <stdlib.h>
fd7f1bf @yuguy Include <string.h> to declare various string-manipulating routines.
yuguy authored
47 #include <string.h>
b11ddf8 Initial revision
mcr authored
48 #include <unistd.h>
49
50 #include "pcap-int.h"
51
52 #ifdef HAVE_OS_PROTO_H
53 #include "os-proto.h"
54 #endif
55
56 #define TCPDUMP_MAGIC 0xa1b2c3d4
884ed98 @yuguy Add support for reading capture files from programs using Alexey
yuguy authored
57 #define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34
b11ddf8 Initial revision
mcr authored
58
59 /*
60 * We use the "receiver-makes-right" approach to byte order,
61 * because time is at a premium when we are writing the file.
62 * In other words, the pcap_file_header and pcap_pkthdr,
63 * records are written in host byte order.
64 * Note that the packets are always written in network byte order.
65 *
66 * ntoh[ls] aren't sufficient because we might need to swap on a big-endian
67 * machine (if the file was written in little-end order).
68 */
69 #define SWAPLONG(y) \
70 ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
71 #define SWAPSHORT(y) \
72 ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
73
74 #define SFERR_TRUNC 1
75 #define SFERR_BADVERSION 2
76 #define SFERR_BADF 3
77 #define SFERR_EOF 4 /* not really an error, just a status */
78
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
79 /*
80 * We don't write DLT_* values to the capture file header, because
81 * they're not the same on all platforms.
82 *
83 * Unfortunately, the various flavors of BSD have not always used the same
84 * numerical values for the same data types, and various patches to
85 * libpcap for non-BSD OSes have added their own DLT_* codes for link
86 * layer encapsulation types seen on those OSes, and those codes have had,
87 * in some cases, values that were also used, on other platforms, for other
88 * link layer encapsulation types.
89 *
90 * This means that capture files of a type whose numerical DLT_* code
91 * means different things on different BSDs, or with different versions
92 * of libpcap, can't always be read on systems other than those like
93 * the one running on the machine on which the capture was made.
94 *
95 * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes
96 * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_*
97 * codes to DLT_* codes when reading a savefile header.
98 *
99 * For those DLT_* codes that have, as far as we know, the same values on
100 * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as
101 * DLT_xxx; that way, captures of those types can still be read by
102 * versions of libpcap that map LINKTYPE_* values to DLT_* values, and
103 * captures of those types written by versions of libpcap that map DLT_
104 * values to LINKTYPE_ values can still be read by older versions
105 * of libpcap.
106 *
107 * The other LINKTYPE_* codes are given values starting at 100, in the
108 * hopes that no DLT_* code will be given one of those values.
109 *
110 * In order to ensure that a given LINKTYPE_* code's value will refer to
111 * the same encapsulation type on all platforms, you should not allocate
112 * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org".
113 * The tcpdump developers will allocate a value for you, and will not
114 * subsequently allocate it to anybody else; that value will be added to
115 * the "pcap.h" in the tcpdump.org CVS repository, so that a future
116 * libpcap release will include it.
117 *
118 * You should, if possible, also contribute patches to libpcap and tcpdump
119 * to handle the new encapsulation type, so that they can also be checked
120 * into the tcpdump.org CVS repository and so that they will appear in
121 * future libpcap and tcpdump releases.
122 */
123 #define LINKTYPE_NULL DLT_NULL
124 #define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */
125 #define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */
126 #define LINKTYPE_AX25 DLT_AX25
127 #define LINKTYPE_PRONET DLT_PRONET
128 #define LINKTYPE_CHAOS DLT_CHAOS
129 #define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */
130 #define LINKTYPE_ARCNET DLT_ARCNET
131 #define LINKTYPE_SLIP DLT_SLIP
132 #define LINKTYPE_PPP DLT_PPP
133 #define LINKTYPE_FDDI DLT_FDDI
134
135 #define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */
136 #define LINKTYPE_RAW 101 /* raw IP */
137 #define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */
138 #define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */
139 #define LINKTYPE_C_HDLC 104 /* Cisco HDLC */
140 #define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */
141
142 /*
143 * Reserved for future use.
144 */
145 #define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */
146 #define LINKTYPE_FR 107 /* BSD/OS Frame Relay */
147 #define LINKTYPE_LOOP 108 /* OpenBSD loopback */
148 #define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
149 #define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
150 #define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
151 #define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
152
153 /*
154 * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662
155 * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol
156 * field) at the beginning of the packet.
157 *
158 * This is for use when there is always such a header; the address field
159 * might be 0xff, for regular PPP, or it might be an address field for Cisco
160 * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco
161 * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL.
162 */
e9c3298 @yuguy Oops! I gave LINKTYPE_PPP_HDLC the same value as LINKTYPE_FR, which is
yuguy authored
163 #define LINKTYPE_PPP_HDLC 113 /* PPP in HDLC-like framing */
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
164
165 static struct linktype_map {
166 int dlt;
167 int linktype;
168 } map[] = {
169 /*
170 * These DLT_* codes have LINKTYPE_* codes with values identical
171 * to the values of the corresponding DLT_* code.
172 */
173 { DLT_NULL, LINKTYPE_NULL },
174 { DLT_EN10MB, LINKTYPE_ETHERNET },
175 { DLT_EN3MB, LINKTYPE_EXP_ETHERNET },
176 { DLT_AX25, LINKTYPE_AX25 },
177 { DLT_PRONET, LINKTYPE_PRONET },
178 { DLT_CHAOS, LINKTYPE_CHAOS },
179 { DLT_IEEE802, LINKTYPE_TOKEN_RING },
180 { DLT_ARCNET, LINKTYPE_ARCNET },
181 { DLT_SLIP, LINKTYPE_SLIP },
182 { DLT_PPP, LINKTYPE_PPP },
183 { DLT_FDDI, LINKTYPE_FDDI },
184
185 /*
186 * These DLT_* codes have different values on different
187 * platforms; we map them to LINKTYPE_* codes that
188 * have values that should never be equal to any DLT_*
189 * code.
190 */
191 { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
192 { DLT_RAW, LINKTYPE_RAW },
193 { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
194 { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS },
195
196 /* BSD/OS Cisco HDLC */
197 { DLT_C_HDLC, LINKTYPE_C_HDLC },
198
199 /*
200 * These DLT_* codes are not on all platforms, but, so far,
201 * there don't appear to be any platforms that define
202 * other codes with those values; we map them to
203 * different LINKTYPE_* values anyway, just in case.
204 */
205
206 /* Linux ATM Classical IP */
207 { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP },
208
209 /* NetBSD sync/async serial PPP (or Cisco HDLC) */
210 { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC },
211
ef0a3b3 @yuguy Add a DLT_IEEE802_11 for use by any platform that provides raw 802.11
yuguy authored
212 /* IEEE 802.11 wireless */
213 { DLT_IEEE802_11, LINKTYPE_IEEE802_11 },
214
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
215 /*
216 * Any platform that defines additional DLT_* codes should:
217 *
218 * request a LINKTYPE_* code and value from tcpdump.org,
219 * as per the above;
220 *
221 * add, in their version of libpcap, an entry to map
222 * those DLT_* codes to the corresponding LINKTYPE_*
223 * code;
224 *
225 * redefine, in their "net/bpf.h", any DLT_* values
226 * that collide with the values used by their additional
227 * DLT_* codes, to remove those collisions (but without
228 * making them collide with any of the LINKTYPE_*
229 * values equal to 50 or above; they should also avoid
230 * defining DLT_* values that collide with those
231 * LINKTYPE_* values, either).
232 */
233 { -1, -1 }
234 };
235
236 static int
237 dlt_to_linktype(int dlt)
238 {
239 int i;
240
241 for (i = 0; map[i].dlt != -1; i++) {
242 if (map[i].dlt == dlt)
243 return (map[i].linktype);
244 }
245
246 /*
247 * If we don't have a mapping for this DLT_ code, return an
248 * error; that means that the table above needs to have an
249 * entry added.
250 */
251 return (-1);
252 }
253
254 static int
255 linktype_to_dlt(int linktype)
256 {
257 int i;
258
259 for (i = 0; map[i].linktype != -1; i++) {
260 if (map[i].linktype == linktype)
261 return (map[i].dlt);
262 }
263
264 /*
265 * If we don't have an entry for this link type, return
266 * the link type value; it may be a DLT_ value from an
267 * older version of libpcap.
268 */
269 return linktype;
270 }
271
b11ddf8 Initial revision
mcr authored
272 static int
273 sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
274 {
275 struct pcap_file_header hdr;
276
277 hdr.magic = TCPDUMP_MAGIC;
278 hdr.version_major = PCAP_VERSION_MAJOR;
279 hdr.version_minor = PCAP_VERSION_MINOR;
280
281 hdr.thiszone = thiszone;
282 hdr.snaplen = snaplen;
283 hdr.sigfigs = 0;
284 hdr.linktype = linktype;
285
286 if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
287 return (-1);
288
289 return (0);
290 }
291
292 static void
293 swap_hdr(struct pcap_file_header *hp)
294 {
295 hp->version_major = SWAPSHORT(hp->version_major);
296 hp->version_minor = SWAPSHORT(hp->version_minor);
297 hp->thiszone = SWAPLONG(hp->thiszone);
298 hp->sigfigs = SWAPLONG(hp->sigfigs);
299 hp->snaplen = SWAPLONG(hp->snaplen);
300 hp->linktype = SWAPLONG(hp->linktype);
301 }
302
303 pcap_t *
304 pcap_open_offline(const char *fname, char *errbuf)
305 {
306 register pcap_t *p;
307 register FILE *fp;
308 struct pcap_file_header hdr;
884ed98 @yuguy Add support for reading capture files from programs using Alexey
yuguy authored
309 bpf_u_int32 magic;
b11ddf8 Initial revision
mcr authored
310 int linklen;
311
312 p = (pcap_t *)malloc(sizeof(*p));
313 if (p == NULL) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
314 strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
b11ddf8 Initial revision
mcr authored
315 return (NULL);
316 }
317
318 memset((char *)p, 0, sizeof(*p));
319 /*
320 * Set this field so we don't close stdin in pcap_close!
321 */
322 p->fd = -1;
323
324 if (fname[0] == '-' && fname[1] == '\0')
325 fp = stdin;
326 else {
327 fp = fopen(fname, "r");
328 if (fp == NULL) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
329 snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
330 pcap_strerror(errno));
b11ddf8 Initial revision
mcr authored
331 goto bad;
332 }
333 }
334 if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
335 snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s",
336 pcap_strerror(errno));
b11ddf8 Initial revision
mcr authored
337 goto bad;
338 }
884ed98 @yuguy Add support for reading capture files from programs using Alexey
yuguy authored
339 magic = hdr.magic;
340 if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
341 magic = SWAPLONG(magic);
342 if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
343 snprintf(errbuf, PCAP_ERRBUF_SIZE,
344 "bad dump file format");
b11ddf8 Initial revision
mcr authored
345 goto bad;
346 }
347 p->sf.swapped = 1;
348 swap_hdr(&hdr);
349 }
884ed98 @yuguy Add support for reading capture files from programs using Alexey
yuguy authored
350 if (magic == PATCHED_TCPDUMP_MAGIC) {
351 /*
352 * XXX - the patch that's in some versions of libpcap
353 * changes the packet header but not the magic number;
354 * we'd have to use some hacks^H^H^H^H^Hheuristics to
355 * detect that.
356 */
357 p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
358 } else
359 p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
b11ddf8 Initial revision
mcr authored
360 if (hdr.version_major < PCAP_VERSION_MAJOR) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
361 snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format");
b11ddf8 Initial revision
mcr authored
362 goto bad;
363 }
364 p->tzoff = hdr.thiszone;
365 p->snapshot = hdr.snaplen;
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
366 p->linktype = linktype_to_dlt(hdr.linktype);
b11ddf8 Initial revision
mcr authored
367 p->sf.rfile = fp;
368 p->bufsize = hdr.snaplen;
369
370 /* Align link header as required for proper data alignment */
371 /* XXX should handle all types */
372 switch (p->linktype) {
373
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
374 case DLT_EN10MB:
b11ddf8 Initial revision
mcr authored
375 linklen = 14;
376 break;
377
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
378 case DLT_FDDI:
b11ddf8 Initial revision
mcr authored
379 linklen = 13 + 8; /* fddi_header + llc */
380 break;
381
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
382 case DLT_NULL:
b11ddf8 Initial revision
mcr authored
383 default:
384 linklen = 0;
385 break;
386 }
387
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
388 if (p->bufsize < 0)
389 p->bufsize = BPF_MAXBUFSIZE;
b11ddf8 Initial revision
mcr authored
390 p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
391 if (p->sf.base == NULL) {
392 strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
393 goto bad;
394 }
b11ddf8 Initial revision
mcr authored
395 p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT);
396 p->sf.version_major = hdr.version_major;
397 p->sf.version_minor = hdr.version_minor;
398 #ifdef PCAP_FDDIPAD
399 /* XXX padding only needed for kernel fcode */
400 pcap_fddipad = 0;
401 #endif
402
403 return (p);
404 bad:
405 free(p);
406 return (NULL);
407 }
408
409 /*
410 * Read sf_readfile and return the next packet. Return the header in hdr
411 * and the contents in buf. Return 0 on success, SFERR_EOF if there were
412 * no more packets, and SFERR_TRUNC if a partial packet was encountered.
413 */
414 static int
415 sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
416 {
884ed98 @yuguy Add support for reading capture files from programs using Alexey
yuguy authored
417 struct pcap_sf_patched_pkthdr sf_hdr;
b11ddf8 Initial revision
mcr authored
418 FILE *fp = p->sf.rfile;
419
884ed98 @yuguy Add support for reading capture files from programs using Alexey
yuguy authored
420 /*
421 * Read the packet header; the structure we use as a buffer
422 * is the longer structure for files generated by the patched
423 * libpcap, but if the file has the magic number for an
424 * unpatched libpcap we only read as many bytes as the regular
425 * header has.
426 */
427 if (fread(&sf_hdr, p->sf.hdrsize, 1, fp) != 1) {
b11ddf8 Initial revision
mcr authored
428 /* probably an EOF, though could be a truncated packet */
429 return (1);
430 }
431
432 if (p->sf.swapped) {
433 /* these were written in opposite byte order */
56c33c0 (sf_next_packet, pcap_dump): convert between `pcap_pkthdr' and
assar authored
434 hdr->caplen = SWAPLONG(sf_hdr.caplen);
435 hdr->len = SWAPLONG(sf_hdr.len);
436 hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
437 hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
438 } else {
439 hdr->caplen = sf_hdr.caplen;
440 hdr->len = sf_hdr.len;
441 hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
442 hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
b11ddf8 Initial revision
mcr authored
443 }
444 /*
445 * We interchanged the caplen and len fields at version 2.3,
446 * in order to match the bpf header layout. But unfortunately
447 * some files were written with version 2.3 in their headers
448 * but without the interchanged fields.
449 */
450 if (p->sf.version_minor < 3 ||
451 (p->sf.version_minor == 3 && hdr->caplen > hdr->len)) {
452 int t = hdr->caplen;
453 hdr->caplen = hdr->len;
454 hdr->len = t;
455 }
456
457 if (hdr->caplen > buflen) {
458 /*
459 * This can happen due to Solaris 2.3 systems tripping
460 * over the BUFMOD problem and not setting the snapshot
461 * correctly in the savefile header. If the caplen isn't
462 * grossly wrong, try to salvage.
463 */
464 static u_char *tp = NULL;
465 static int tsize = 0;
466
467 if (hdr->caplen > 65535) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
468 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
469 "bogus savefile header");
b11ddf8 Initial revision
mcr authored
470 return (-1);
471 }
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
472
b11ddf8 Initial revision
mcr authored
473 if (tsize < hdr->caplen) {
474 tsize = ((hdr->caplen + 1023) / 1024) * 1024;
475 if (tp != NULL)
476 free((u_char *)tp);
477 tp = (u_char *)malloc(tsize);
478 if (tp == NULL) {
479 tsize = 0;
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
480 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
481 "BUFMOD hack malloc");
b11ddf8 Initial revision
mcr authored
482 return (-1);
483 }
484 }
485 if (fread((char *)tp, hdr->caplen, 1, fp) != 1) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
486 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
487 "truncated dump file");
b11ddf8 Initial revision
mcr authored
488 return (-1);
489 }
490 /*
491 * We can only keep up to buflen bytes. Since caplen > buflen
492 * is exactly how we got here, we know we can only keep the
493 * first buflen bytes and must drop the remainder. Adjust
494 * caplen accordingly, so we don't get confused later as
495 * to how many bytes we have to play with.
496 */
497 hdr->caplen = buflen;
498 memcpy((char *)buf, (char *)tp, buflen);
499
500 } else {
501 /* read the packet itself */
502
503 if (fread((char *)buf, hdr->caplen, 1, fp) != 1) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
504 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
505 "truncated dump file");
b11ddf8 Initial revision
mcr authored
506 return (-1);
507 }
508 }
509 return (0);
510 }
511
512 /*
513 * Print out packets stored in the file initialized by sf_read_init().
514 * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
515 */
516 int
517 pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
518 {
519 struct bpf_insn *fcode = p->fcode.bf_insns;
520 int status = 0;
521 int n = 0;
522
523 while (status == 0) {
524 struct pcap_pkthdr h;
525
526 status = sf_next_packet(p, &h, p->buffer, p->bufsize);
527 if (status) {
528 if (status == 1)
529 return (0);
530 return (status);
531 }
532
533 if (fcode == NULL ||
534 bpf_filter(fcode, p->buffer, h.len, h.caplen)) {
535 (*callback)(user, &h, p->buffer);
536 if (++n >= cnt && cnt > 0)
537 break;
538 }
539 }
540 /*XXX this breaks semantics tcpslice expects */
541 return (n);
542 }
543
544 /*
545 * Output a packet to the initialized dump file.
546 */
547 void
548 pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
549 {
550 register FILE *f;
56c33c0 (sf_next_packet, pcap_dump): convert between `pcap_pkthdr' and
assar authored
551 struct pcap_sf_pkthdr sf_hdr;
b11ddf8 Initial revision
mcr authored
552
553 f = (FILE *)user;
56c33c0 (sf_next_packet, pcap_dump): convert between `pcap_pkthdr' and
assar authored
554 sf_hdr.ts.tv_sec = h->ts.tv_sec;
555 sf_hdr.ts.tv_usec = h->ts.tv_usec;
556 sf_hdr.caplen = h->caplen;
557 sf_hdr.len = h->len;
b11ddf8 Initial revision
mcr authored
558 /* XXX we should check the return status */
56c33c0 (sf_next_packet, pcap_dump): convert between `pcap_pkthdr' and
assar authored
559 (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f);
b11ddf8 Initial revision
mcr authored
560 (void)fwrite((char *)sp, h->caplen, 1, f);
561 }
562
563 /*
564 * Initialize so that sf_write() will output to the file named 'fname'.
565 */
566 pcap_dumper_t *
567 pcap_dump_open(pcap_t *p, const char *fname)
568 {
569 FILE *f;
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
570 int linktype;
571
572 linktype = dlt_to_linktype(p->linktype);
573 if (linktype == -1) {
574 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
575 "%s: link-layer type %d isn't supported in savefiles",
576 fname, linktype);
577 return (NULL);
578 }
579
b11ddf8 Initial revision
mcr authored
580 if (fname[0] == '-' && fname[1] == '\0')
581 f = stdout;
582 else {
583 f = fopen(fname, "w");
584 if (f == NULL) {
20d9e08 do not use sprintf(). always use snprintf().
itojun authored
585 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
b11ddf8 Initial revision
mcr authored
586 fname, pcap_strerror(errno));
587 return (NULL);
588 }
589 }
2c961ff @yuguy Get rid of the PCAP_ENCAP_ values - if an application uses them, that
yuguy authored
590 (void)sf_write_header(f, linktype, p->tzoff, p->snapshot);
b11ddf8 Initial revision
mcr authored
591 return ((pcap_dumper_t *)f);
592 }
593
594 void
595 pcap_dump_close(pcap_dumper_t *p)
596 {
597
598 #ifdef notyet
599 if (ferror((FILE *)p))
600 return-an-error;
601 /* XXX should check return from fclose() too */
602 #endif
603 (void)fclose((FILE *)p);
604 }
Something went wrong with that request. Please try again.