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 * Wireshark - Network traffic analyzer
22 * By Gerald Combs <gerald@wireshark.org>
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.
60 /* Magic numbers in "libpcap" files.
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.
65 PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC
66 is a byte-swapped version of that.
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
77 /* "libpcap" file header. */
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 */
88 /* "libpcap" record header. */
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 */
96 /* Magic numbers in ".pcapng" files.
98 * .pcapng file records are written in the byte order of the host that
99 * writes them, and the reader is expected to fix this up.
100 * PCAPNG_MAGIC is the magic number, in host byte order;
101 * PCAPNG_SWAPPED_MAGIC is a byte-swapped version of that.
103 #define PCAPNG_MAGIC 0x1A2B3C4D
104 #define PCAPNG_SWAPPED_MAGIC 0xD4C3B2A1
106 /* Currently we are only supporting the initial version of
108 #define PCAPNG_MAJOR_VERSION 1
109 #define PCAPNG_MINOR_VERSION 0
111 /* Section Header Block without options and trailing Block Total Length */
114 guint32 block_total_length;
115 guint32 byte_order_magic;
116 guint16 major_version;
117 guint16 minor_version;
118 guint64 section_length;
120 #define SECTION_HEADER_BLOCK_TYPE 0x0A0D0D0A
122 /* Interface Decription Block without options and trailing Block Total Length */
125 guint32 block_total_length;
130 #define INTERFACE_DESCRIPTION_BLOCK_TYPE 0x00000001
132 /* Interface Statistics Block without actual packet, options, and trailing
133 Block Total Length */
136 guint32 block_total_length;
137 guint32 interface_id;
138 guint32 timestamp_high;
139 guint32 timestamp_low;
141 #define INTERFACE_STATISTICS_BLOCK_TYPE 0x00000005
143 /* Enhanced Packet Block without actual packet, options, and trailing
144 Block Total Length */
147 guint32 block_total_length;
148 guint32 interface_id;
149 guint32 timestamp_high;
150 guint32 timestamp_low;
151 guint32 captured_len;
154 #define ENHANCED_PACKET_BLOCK_TYPE 0x00000006
158 guint16 value_length;
160 #define OPT_ENDOFOPT 0
161 #define OPT_COMMENT 1 /* currently not used */
162 #define SHB_HARDWARE 2 /* currently not used */
164 #define SHB_USERAPPL 4
166 #define IDB_FILTER 11
169 #define ISB_FILTERACCEPT 6
171 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
173 #define WRITE_DATA(file_pointer, data_pointer, data_length, written_length, error_pointer) \
178 nwritten = fwrite(data_pointer, 1, data_length, file_pointer); \
179 if (nwritten != data_length) { \
180 if (nwritten == 0 && ferror(file_pointer)) { \
181 *error_pointer = errno; \
183 *error_pointer = 0; \
187 written_length += (long)nwritten; \
191 /* Returns a FILE * to write to on success, NULL on failure */
193 libpcap_fdopen(int fd, int *err)
197 fp = fdopen(fd, "wb");
204 /* Write the file header to a dump file.
205 Returns TRUE on success, FALSE on failure.
206 Sets "*err" to an error code, or 0 for a short write, on failure*/
208 libpcap_write_file_header(FILE *fp, int linktype, int snaplen, long *bytes_written, int *err)
210 struct pcap_hdr file_hdr;
213 file_hdr.magic = PCAP_MAGIC;
214 /* current "libpcap" format is 2.4 */
215 file_hdr.version_major = 2;
216 file_hdr.version_minor = 4;
217 file_hdr.thiszone = 0; /* XXX - current offset? */
218 file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
219 file_hdr.snaplen = snaplen;
220 file_hdr.network = linktype;
221 nwritten = fwrite(&file_hdr, 1, sizeof(file_hdr), fp);
222 if (nwritten != sizeof(file_hdr)) {
223 if (nwritten == 0 && ferror(fp))
226 *err = 0; /* short write */
229 *bytes_written += sizeof(file_hdr);
234 /* Write a record for a packet to a dump file.
235 Returns TRUE on success, FALSE on failure. */
237 libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
238 long *bytes_written, int *err)
240 struct pcaprec_hdr rec_hdr;
243 rec_hdr.ts_sec = phdr->ts.tv_sec;
244 rec_hdr.ts_usec = phdr->ts.tv_usec;
245 rec_hdr.incl_len = phdr->caplen;
246 rec_hdr.orig_len = phdr->len;
247 nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, fp);
248 if (nwritten != sizeof rec_hdr) {
249 if (nwritten == 0 && ferror(fp))
252 *err = 0; /* short write */
255 *bytes_written += sizeof rec_hdr;
257 nwritten = fwrite(pd, 1, phdr->caplen, fp);
258 if (nwritten != phdr->caplen) {
259 if (nwritten == 0 && ferror(fp))
262 *err = 0; /* short write */
265 *bytes_written += phdr->caplen;
270 libpcap_write_session_header_block(FILE *fp,
275 guint64 section_length,
280 struct option option;
281 guint32 block_total_length;
282 const guint32 padding = 0;
283 gboolean have_options = FALSE;
285 /* Size of base header */
286 block_total_length = sizeof(struct shb) +
288 if ((comment)&&(strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
289 block_total_length += sizeof(struct option) +
290 (guint16)(ADD_PADDING(strlen(comment) + 1));
293 if ((hw)&&(strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
294 block_total_length += sizeof(struct option) +
295 (guint16)(ADD_PADDING(strlen(hw) + 1));
298 if ((os)&&(strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
299 block_total_length += sizeof(struct option) +
300 (guint16)(ADD_PADDING(strlen(os) + 1));
303 if ((appname)&&(strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
304 block_total_length += sizeof(struct option) +
305 (guint16)(ADD_PADDING(strlen(appname) + 1));
308 /* If we have options add size of end-of-options */
310 block_total_length += sizeof(struct option);
312 /* write shb header */
313 shb.block_type = SECTION_HEADER_BLOCK_TYPE;
314 shb.block_total_length = block_total_length;
315 shb.byte_order_magic = PCAPNG_MAGIC;
316 shb.major_version = PCAPNG_MAJOR_VERSION;
317 shb.minor_version = PCAPNG_MINOR_VERSION;
318 shb.section_length = section_length;
319 WRITE_DATA(fp, &shb, sizeof(struct shb), *bytes_written, err);
321 if ((comment)&&(strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
322 /* write opt_comment options */
323 option.type = OPT_COMMENT;
324 option.value_length = (guint16)(strlen(comment) + 1);
325 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
326 WRITE_DATA(fp, comment, strlen(comment) + 1, *bytes_written, err);
327 if ((strlen(comment) + 1) % 4) {
328 WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
331 if ((hw)&&(strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
332 /* write shb_hardware options */
333 option.type = SHB_HARDWARE;
334 option.value_length = (guint16)(strlen(hw) + 1);
335 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
336 WRITE_DATA(fp, hw, strlen(hw) + 1, *bytes_written, err);
337 if ((strlen(hw) + 1) % 4) {
338 WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
341 if ((os)&&(strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
342 /* write shb_os options */
343 option.type = SHB_OS;
344 option.value_length = (guint16)(strlen(os) + 1);
345 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
346 WRITE_DATA(fp, os, strlen(os) + 1, *bytes_written, err);
347 if ((strlen(os) + 1) % 4) {
348 WRITE_DATA(fp, &padding, 4 - (strlen(os) + 1) % 4, *bytes_written, err);
351 if ((appname)&&(strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
352 /* write shb_userappl options */
353 option.type = SHB_USERAPPL;
354 option.value_length = (guint16)(strlen(appname) + 1);
355 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
356 WRITE_DATA(fp, appname, strlen(appname) + 1, *bytes_written, err);
357 if ((strlen(appname) + 1) % 4) {
358 WRITE_DATA(fp, &padding, 4 - (strlen(appname) + 1) % 4, *bytes_written, err);
362 /* write end of options */
363 option.type = OPT_ENDOFOPT;
364 option.value_length = 0;
365 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
368 /* write the trailing block total length */
369 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
374 libpcap_write_interface_description_block(FILE *fp,
383 struct option option;
384 guint32 block_total_length;
385 const guint32 padding = 0;
387 block_total_length = sizeof(struct idb) + sizeof(guint32);
388 if ((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
389 block_total_length += sizeof(struct option) +
390 (guint16)(ADD_PADDING(strlen(name) + 1));
392 if ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
393 block_total_length += sizeof(struct option) +
394 (guint16)(ADD_PADDING(strlen(filter) + 1));
396 if (((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) ||
397 ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16))) {
398 block_total_length += sizeof(struct option);
400 /* write block header */
401 idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE;
402 idb.block_total_length = block_total_length;
403 idb.link_type = link_type;
405 idb.snap_len = snap_len;
406 WRITE_DATA(fp, &idb, sizeof(struct idb), *bytes_written, err);
407 /* write interface name string if applicable */
408 if ((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
409 option.type = IDB_NAME;
410 option.value_length = (guint16)(strlen(name) + 1);
411 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
412 WRITE_DATA(fp, name, strlen(name) + 1, *bytes_written, err);
413 if ((strlen(name) + 1) % 4) {
414 WRITE_DATA(fp, &padding, 4 - (strlen(name) + 1) % 4 , *bytes_written, err);
417 /* write filter string if applicable */
418 if ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
419 option.type = IDB_FILTER;
420 option.value_length = (guint16)(strlen(filter) + 1);
421 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
422 WRITE_DATA(fp, filter, strlen(filter) + 1, *bytes_written, err);
423 if ((strlen(filter) + 1) % 4) {
424 WRITE_DATA(fp, &padding, 4 - (strlen(filter) + 1) % 4 , *bytes_written, err);
427 /* write endofopt option if there were any options */
428 if (((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) ||
429 ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16))) {
430 option.type = OPT_ENDOFOPT;
431 option.value_length = 0;
432 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
434 /* write the trailing Block Total Length */
435 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
439 /* Write a record for a packet to a dump file.
440 Returns TRUE on success, FALSE on failure. */
442 libpcap_write_enhanced_packet_block(FILE *fp,
443 const struct pcap_pkthdr *phdr,
444 guint32 interface_id,
450 guint32 block_total_length;
452 const guint32 padding = 0;
454 block_total_length = sizeof(struct epb) +
455 ADD_PADDING(phdr->caplen) +
457 timestamp = (guint64)(phdr->ts.tv_sec) * 1000000 +
458 (guint64)(phdr->ts.tv_usec);
459 epb.block_type = ENHANCED_PACKET_BLOCK_TYPE;
460 epb.block_total_length = block_total_length;
461 epb.interface_id = interface_id;
462 epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
463 epb.timestamp_low = (guint32)(timestamp & 0xffffffff);
464 epb.captured_len = phdr->caplen;
465 epb.packet_len = phdr->len;
466 WRITE_DATA(fp, &epb, sizeof(struct epb), *bytes_written, err);
467 WRITE_DATA(fp, pd, phdr->caplen, *bytes_written, err);
468 if (phdr->caplen % 4) {
469 WRITE_DATA(fp, &padding, 4 - phdr->caplen % 4, *bytes_written, err);
471 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
476 libpcap_write_interface_statistics_block(FILE *fp,
477 guint32 interface_id,
488 struct option option;
489 struct pcap_stat stats;
490 guint32 block_total_length;
493 gboolean stats_retrieved;
497 * Current time, represented as 100-nanosecond intervals since
498 * January 1, 1601, 00:00:00 UTC.
500 * I think DWORD might be signed, so cast both parts of "now"
501 * to guint32 so that the sign bit doesn't get treated specially.
503 GetSystemTimeAsFileTime(&now);
504 timestamp = (((guint64)(guint32)now.dwHighDateTime) << 32) +
505 (guint32)now.dwLowDateTime;
508 * Convert to same thing but as 1-microsecond, i.e. 1000-nanosecond,
514 * Subtract difference, in microseconds, between January 1, 1601
515 * 00:00:00 UTC and January 1, 1970, 00:00:00 UTC.
517 timestamp -= G_GINT64_CONSTANT(11644473600000000U);
520 * Current time, represented as seconds and microseconds since
521 * January 1, 1970, 00:00:00 UTC.
523 gettimeofday(&now, NULL);
526 * Convert to delta in microseconds.
528 timestamp = (guint64)(now.tv_sec) * 1000000 +
529 (guint64)(now.tv_usec);
531 if (pcap_stats(pd, &stats) < 0) {
532 stats_retrieved = FALSE;
533 g_warning("pcap_stats() failed.");
535 stats_retrieved = TRUE;
537 block_total_length = sizeof(struct isb) +
539 if (stats_retrieved) {
540 block_total_length += 3 * sizeof(struct option) + 2 * sizeof(guint64);
542 isb.block_type = INTERFACE_STATISTICS_BLOCK_TYPE;
543 isb.block_total_length = block_total_length;
544 isb.interface_id = interface_id;
545 isb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
546 isb.timestamp_low = (guint32)(timestamp & 0xffffffff);
547 WRITE_DATA(fp, &isb, sizeof(struct isb), *bytes_written, err);
548 if (stats_retrieved) {
550 option.type = ISB_IFRECV;
551 option.value_length = sizeof(guint64);
552 counter = stats.ps_recv;
553 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
554 WRITE_DATA(fp, &counter, sizeof(guint64), *bytes_written, err);
556 option.type = ISB_IFDROP;
557 option.value_length = sizeof(guint64);
558 counter = stats.ps_drop;
559 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
560 WRITE_DATA(fp, &counter, sizeof(guint64), *bytes_written, err);
562 option.type = OPT_ENDOFOPT;
563 option.value_length = 0;
564 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
566 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
572 libpcap_dump_flush(FILE *pd, int *err)
574 if (fflush(pd) == EOF) {
583 libpcap_dump_close(FILE *pd, int *err)
585 if (fclose(pd) == EOF) {
593 #endif /* HAVE_LIBPCAP */