Fix with-pcap build by disabling HAVE_LIBPCAP guard for now, for some reason it isn...
[obnox/wireshark/wip.git] / pcapio.c
1 /* TODO: why isn't this defined??? */
2 /* #ifdef HAVE_LIBPCAP */
3
4 /* pcapio.c
5  * Our own private code for writing libpcap files when capturing.
6  *
7  * We have these because we want a way to open a stream for output given
8  * only a file descriptor.  libpcap 0.9[.x] has "pcap_dump_fopen()", which
9  * provides that, but
10  *
11  *      1) earlier versions of libpcap doesn't have it
12  *
13  * and
14  *
15  *      2) WinPcap doesn't have it, because a file descriptor opened
16  *         by code built for one version of the MSVC++ C library
17  *         can't be used by library routines built for another version
18  *         (e.g., threaded vs. unthreaded).
19  *
20  * Libpcap's pcap_dump() also doesn't return any error indications.
21  *
22  * $Id$
23  *
24  * Wireshark - Network traffic analyzer
25  * By Gerald Combs <gerald@wireshark.org>
26  * Copyright 1998 Gerald Combs
27  *
28  * Derived from code in the Wiretap Library
29  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
30  *
31  * This program is free software; you can redistribute it and/or
32  * modify it under the terms of the GNU General Public License
33  * as published by the Free Software Foundation; either version 2
34  * of the License, or (at your option) any later version.
35  *
36  * This program is distributed in the hope that it will be useful,
37  * but WITHOUT ANY WARRANTY; without even the implied warranty of
38  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
39  * GNU General Public License for more details.
40  *
41  * You should have received a copy of the GNU General Public License
42  * along with this program; if not, write to the Free Software
43  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
44  */
45
46 #ifdef HAVE_CONFIG_H
47 #include "config.h"
48 #endif
49
50 #include <stdlib.h>
51 #include <stdio.h>
52 #include <errno.h>
53
54 #include <pcap.h>
55
56 #include <glib.h>
57
58 #include "pcapio.h"
59
60 /* Magic numbers in "libpcap" files.
61
62    "libpcap" file records are written in the byte order of the host that
63    writes them, and the reader is expected to fix this up.
64
65    PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC
66    is a byte-swapped version of that.
67
68    PCAP_NSEC_MAGIC is for Ulf Lamping's modified "libpcap" format,
69    which uses the same common file format as PCAP_MAGIC, but the 
70    timestamps are saved in nanosecond resolution instead of microseconds.
71    PCAP_SWAPPED_NSEC_MAGIC is a byte-swapped version of that. */
72 #define PCAP_MAGIC                      0xa1b2c3d4
73 #define PCAP_SWAPPED_MAGIC              0xd4c3b2a1
74 #define PCAP_NSEC_MAGIC                 0xa1b23c4d
75 #define PCAP_SWAPPED_NSEC_MAGIC         0x4d3cb2a1
76
77 /* "libpcap" file header. */
78 struct pcap_hdr {
79         guint32 magic;          /* magic number */
80         guint16 version_major;  /* major version number */
81         guint16 version_minor;  /* minor version number */
82         gint32  thiszone;       /* GMT to local correction */
83         guint32 sigfigs;        /* accuracy of timestamps */
84         guint32 snaplen;        /* max length of captured packets, in octets */
85         guint32 network;        /* data link type */
86 };
87
88 /* "libpcap" record header. */
89 struct pcaprec_hdr {
90         guint32 ts_sec;         /* timestamp seconds */
91         guint32 ts_usec;        /* timestamp microseconds (nsecs for PCAP_NSEC_MAGIC) */
92         guint32 incl_len;       /* number of octets of packet saved in file */
93         guint32 orig_len;       /* actual length of packet */
94 };
95
96 /* Returns a FILE * to write to on success, NULL on failure; sets "*err" to
97    an error code, or 0 for a short write, on failure */
98 FILE *
99 libpcap_fdopen(int fd, int linktype, int snaplen, long *bytes_written,
100     int *err)
101 {
102         FILE *fp;
103         struct pcap_hdr file_hdr;
104         size_t nwritten;
105
106         fp = fdopen(fd, "wb");
107         if (fp == NULL) {
108                 *err = errno;
109                 return NULL;
110         }
111
112         file_hdr.magic = PCAP_MAGIC;
113         /* current "libpcap" format is 2.4 */
114         file_hdr.version_major = 2;
115         file_hdr.version_minor = 4;
116         file_hdr.thiszone = 0;  /* XXX - current offset? */
117         file_hdr.sigfigs = 0;   /* unknown, but also apparently unused */
118         file_hdr.snaplen = snaplen;
119         file_hdr.network = linktype;
120         nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, fp);
121         if (nwritten != sizeof file_hdr) {
122                 if (nwritten == 0 && ferror(fp))
123                         *err = errno;
124                 else
125                         *err = 0;       /* short write */
126                 fclose(fp);
127                 return NULL;
128         }
129         *bytes_written = sizeof file_hdr;
130
131         return fp;
132 }
133
134 /* Write a record for a packet to a dump file.
135    Returns TRUE on success, FALSE on failure. */
136 gboolean
137 libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
138     long *bytes_written, int *err)
139 {
140         struct pcaprec_hdr rec_hdr;
141         size_t nwritten;
142
143         rec_hdr.ts_sec = phdr->ts.tv_sec;
144         rec_hdr.ts_usec = phdr->ts.tv_usec;
145         rec_hdr.incl_len = phdr->caplen;
146         rec_hdr.orig_len = phdr->len;
147         nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, fp);
148         if (nwritten != sizeof rec_hdr) {
149                 if (nwritten == 0 && ferror(fp))
150                         *err = errno;
151                 else
152                         *err = 0;       /* short write */
153                 return FALSE;
154         }
155         *bytes_written += sizeof rec_hdr;
156
157         nwritten = fwrite(pd, 1, phdr->caplen, fp);
158         if (nwritten != phdr->caplen) {
159                 if (nwritten == 0 && ferror(fp))
160                         *err = errno;
161                 else
162                         *err = 0;       /* short write */
163                 return FALSE;
164         }
165         *bytes_written += phdr->caplen;
166         return TRUE;
167 }
168
169 gboolean
170 libpcap_dump_flush(FILE *pd, int *err)
171 {
172         if (fflush(pd) == EOF) {
173                 if (err != NULL)
174                         *err = errno;
175                 return FALSE;
176         }
177         return TRUE;
178 }
179
180 gboolean
181 libpcap_dump_close(FILE *pd, int *err)
182 {
183         if (fclose(pd) == EOF) {
184                 if (err != NULL)
185                         *err = errno;
186                 return FALSE;
187         }
188         return TRUE;
189 }
190
191 /*#endif */ /* HAVE_LIBPCAP */