2 * Our own private code for writing libpcap files when capturing.
4 * We have these because we want a way to open a stream for output given
5 * only a file descriptor. libpcap 0.9[.x] has "pcap_dump_fopen()", which
8 * 1) earlier versions of libpcap doesn't have it
12 * 2) WinPcap doesn't have it, because a file descriptor opened
13 * by code built for one version of the MSVC++ C library
14 * can't be used by library routines built for another version
15 * (e.g., threaded vs. unthreaded).
17 * Libpcap's pcap_dump() also doesn't return any error indications.
21 * Ethereal - Network traffic analyzer
22 * By Gerald Combs <gerald@ethereal.com>
23 * Copyright 1998 Gerald Combs
25 * Derived from code in the Wiretap Library
26 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
28 * This program is free software; you can redistribute it and/or
29 * modify it under the terms of the GNU General Public License
30 * as published by the Free Software Foundation; either version 2
31 * of the License, or (at your option) any later version.
33 * This program is distributed in the hope that it will be useful,
34 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 * GNU General Public License for more details.
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
57 /* Magic numbers in "libpcap" files.
59 "libpcap" file records are written in the byte order of the host that
60 writes them, and the reader is expected to fix this up.
62 PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC
63 is a byte-swapped version of that.
65 PCAP_NSEC_MAGIC is for Ulf Lamping's modified "libpcap" format,
66 which uses the same common file format as PCAP_MAGIC, but the
67 timestamps are saved in nanosecond resolution instead of microseconds.
68 PCAP_SWAPPED_NSEC_MAGIC is a byte-swapped version of that. */
69 #define PCAP_MAGIC 0xa1b2c3d4
70 #define PCAP_SWAPPED_MAGIC 0xd4c3b2a1
71 #define PCAP_NSEC_MAGIC 0xa1b23c4d
72 #define PCAP_SWAPPED_NSEC_MAGIC 0x4d3cb2a1
74 /* "libpcap" file header. */
76 guint32 magic; /* magic number */
77 guint16 version_major; /* major version number */
78 guint16 version_minor; /* minor version number */
79 gint32 thiszone; /* GMT to local correction */
80 guint32 sigfigs; /* accuracy of timestamps */
81 guint32 snaplen; /* max length of captured packets, in octets */
82 guint32 network; /* data link type */
85 /* "libpcap" record header. */
87 guint32 ts_sec; /* timestamp seconds */
88 guint32 ts_usec; /* timestamp microseconds (nsecs for PCAP_NSEC_MAGIC) */
89 guint32 incl_len; /* number of octets of packet saved in file */
90 guint32 orig_len; /* actual length of packet */
93 /* Returns a FILE * to write to on success, NULL on failure; sets "*err" to
94 an error code, or 0 for a short write, on failure */
96 libpcap_fdopen(int fd, int linktype, int snaplen, long *bytes_written,
100 struct pcap_hdr file_hdr;
103 fp = fdopen(fd, "wb");
109 file_hdr.magic = PCAP_MAGIC;
110 /* current "libpcap" format is 2.4 */
111 file_hdr.version_major = 2;
112 file_hdr.version_minor = 4;
113 file_hdr.thiszone = 0; /* XXX - current offset? */
114 file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
115 file_hdr.snaplen = snaplen;
116 file_hdr.network = linktype;
117 nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, fp);
118 if (nwritten != sizeof file_hdr) {
119 if (nwritten == 0 && ferror(fp))
122 *err = 0; /* short write */
126 *bytes_written = sizeof file_hdr;
131 /* Write a record for a packet to a dump file.
132 Returns TRUE on success, FALSE on failure. */
134 libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
135 long *bytes_written, int *err)
137 struct pcaprec_hdr rec_hdr;
140 rec_hdr.ts_sec = phdr->ts.tv_sec;
141 rec_hdr.ts_usec = phdr->ts.tv_usec;
142 rec_hdr.incl_len = phdr->caplen;
143 rec_hdr.orig_len = phdr->len;
144 nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, fp);
145 if (nwritten != sizeof rec_hdr) {
146 if (nwritten == 0 && ferror(fp))
149 *err = 0; /* short write */
152 *bytes_written += sizeof rec_hdr;
154 nwritten = fwrite(pd, 1, phdr->caplen, fp);
155 if (nwritten != phdr->caplen) {
156 if (nwritten == 0 && ferror(fp))
159 *err = 0; /* short write */
162 *bytes_written += phdr->caplen;
167 libpcap_dump_flush(FILE *pd, int *err)
169 if (fflush(pd) == EOF) {
178 libpcap_dump_close(FILE *pd, int *err)
180 if (fclose(pd) == EOF) {