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
162 #define SHB_HARDWARE 2 /* currently not used */
164 #define SHB_USERAPPL 4
166 #define IDB_DESCRIPTION 3
167 #define IDB_IF_SPEED 8
168 #define IDB_TSRESOL 9
169 #define IDB_FILTER 11
173 #define ISB_FILTERACCEPT 6
175 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
177 #define WRITE_DATA(file_pointer, data_pointer, data_length, written_length, error_pointer) \
182 nwritten = fwrite(data_pointer, 1, data_length, file_pointer); \
183 if (nwritten != data_length) { \
184 if (nwritten == 0 && ferror(file_pointer)) { \
185 *error_pointer = errno; \
187 *error_pointer = 0; \
191 written_length += (long)nwritten; \
195 /* Returns a FILE * to write to on success, NULL on failure */
197 libpcap_fdopen(int fd, int *err)
201 fp = fdopen(fd, "wb");
208 /* Write the file header to a dump file.
209 Returns TRUE on success, FALSE on failure.
210 Sets "*err" to an error code, or 0 for a short write, on failure*/
212 libpcap_write_file_header(FILE *fp, int linktype, int snaplen, long *bytes_written, int *err)
214 struct pcap_hdr file_hdr;
217 file_hdr.magic = PCAP_MAGIC;
218 /* current "libpcap" format is 2.4 */
219 file_hdr.version_major = 2;
220 file_hdr.version_minor = 4;
221 file_hdr.thiszone = 0; /* XXX - current offset? */
222 file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
223 file_hdr.snaplen = snaplen;
224 file_hdr.network = linktype;
225 nwritten = fwrite(&file_hdr, 1, sizeof(file_hdr), fp);
226 if (nwritten != sizeof(file_hdr)) {
227 if (nwritten == 0 && ferror(fp))
230 *err = 0; /* short write */
233 *bytes_written += sizeof(file_hdr);
238 /* Write a record for a packet to a dump file.
239 Returns TRUE on success, FALSE on failure. */
241 libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
242 long *bytes_written, int *err)
244 struct pcaprec_hdr rec_hdr;
247 rec_hdr.ts_sec = phdr->ts.tv_sec;
248 rec_hdr.ts_usec = phdr->ts.tv_usec;
249 rec_hdr.incl_len = phdr->caplen;
250 rec_hdr.orig_len = phdr->len;
251 nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, fp);
252 if (nwritten != sizeof rec_hdr) {
253 if (nwritten == 0 && ferror(fp))
256 *err = 0; /* short write */
259 *bytes_written += sizeof rec_hdr;
261 nwritten = fwrite(pd, 1, phdr->caplen, fp);
262 if (nwritten != phdr->caplen) {
263 if (nwritten == 0 && ferror(fp))
266 *err = 0; /* short write */
269 *bytes_written += phdr->caplen;
274 libpcap_write_session_header_block(FILE *fp,
279 guint64 section_length,
284 struct option option;
285 guint32 block_total_length;
286 const guint32 padding = 0;
287 gboolean have_options = FALSE;
289 /* Size of base header */
290 block_total_length = sizeof(struct shb) +
292 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
293 block_total_length += sizeof(struct option) +
294 (guint16)(ADD_PADDING(strlen(comment) + 1));
297 if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
298 block_total_length += sizeof(struct option) +
299 (guint16)(ADD_PADDING(strlen(hw) + 1));
302 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
303 block_total_length += sizeof(struct option) +
304 (guint16)(ADD_PADDING(strlen(os) + 1));
307 if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
308 block_total_length += sizeof(struct option) +
309 (guint16)(ADD_PADDING(strlen(appname) + 1));
312 /* If we have options add size of end-of-options */
314 block_total_length += sizeof(struct option);
316 /* write shb header */
317 shb.block_type = SECTION_HEADER_BLOCK_TYPE;
318 shb.block_total_length = block_total_length;
319 shb.byte_order_magic = PCAPNG_MAGIC;
320 shb.major_version = PCAPNG_MAJOR_VERSION;
321 shb.minor_version = PCAPNG_MINOR_VERSION;
322 shb.section_length = section_length;
323 WRITE_DATA(fp, &shb, sizeof(struct shb), *bytes_written, err);
325 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
326 /* write opt_comment options */
327 option.type = OPT_COMMENT;
328 option.value_length = (guint16)(strlen(comment) + 1);
329 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
330 WRITE_DATA(fp, comment, strlen(comment) + 1, *bytes_written, err);
331 if ((strlen(comment) + 1) % 4) {
332 WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
335 if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
336 /* write shb_hardware options */
337 option.type = SHB_HARDWARE;
338 option.value_length = (guint16)(strlen(hw) + 1);
339 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
340 WRITE_DATA(fp, hw, strlen(hw) + 1, *bytes_written, err);
341 if ((strlen(hw) + 1) % 4) {
342 WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
345 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
346 /* write shb_os options */
347 option.type = SHB_OS;
348 option.value_length = (guint16)(strlen(os) + 1);
349 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
350 WRITE_DATA(fp, os, strlen(os) + 1, *bytes_written, err);
351 if ((strlen(os) + 1) % 4) {
352 WRITE_DATA(fp, &padding, 4 - (strlen(os) + 1) % 4, *bytes_written, err);
355 if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
356 /* write shb_userappl options */
357 option.type = SHB_USERAPPL;
358 option.value_length = (guint16)(strlen(appname) + 1);
359 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
360 WRITE_DATA(fp, appname, strlen(appname) + 1, *bytes_written, err);
361 if ((strlen(appname) + 1) % 4) {
362 WRITE_DATA(fp, &padding, 4 - (strlen(appname) + 1) % 4, *bytes_written, err);
366 /* write end of options */
367 option.type = OPT_ENDOFOPT;
368 option.value_length = 0;
369 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
372 /* write the trailing block total length */
373 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
378 libpcap_write_interface_description_block(FILE *fp,
379 const char *comment, /* OPT_COMMENT 1 */
380 const char *name, /* IDB_NAME 2 */
381 const char *descr, /* IDB_DESCRIPTION 3 */
382 const char *filter, /* IDB_FILTER 11 */
383 const char *os, /* IDB_OS 12 */
387 guint64 if_speed, /* IDB_IF_SPEED 8 */
388 guint8 tsresol, /* IDB_TSRESOL 9 */
392 struct option option;
393 guint32 block_total_length;
394 const guint32 padding = 0;
395 gboolean have_options = FALSE;
397 block_total_length = sizeof(struct idb) + sizeof(guint32);
399 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
400 block_total_length += sizeof(struct option) +
401 (guint16)(ADD_PADDING(strlen(comment) + 1));
405 /* IDB_DESCRIPTION */
406 if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) {
407 block_total_length += sizeof(struct option) +
408 (guint16)(ADD_PADDING(strlen(descr) + 1));
413 if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
414 block_total_length += sizeof(struct option) +
415 (guint16)(ADD_PADDING(strlen(name) + 1));
420 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
421 block_total_length += sizeof(struct option) +
422 (guint16)(ADD_PADDING(strlen(filter) + 1));
427 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
428 block_total_length += sizeof(struct option) +
429 (guint16)(ADD_PADDING(strlen(os) + 1));
435 block_total_length += sizeof(struct option) + sizeof(guint64);
441 block_total_length += sizeof(struct option) + sizeof(struct option);
445 /* If we have options add size of end-of-options */
447 block_total_length += sizeof(struct option);
450 /* write block header */
451 idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE;
452 idb.block_total_length = block_total_length;
453 idb.link_type = link_type;
455 idb.snap_len = snap_len;
456 WRITE_DATA(fp, &idb, sizeof(struct idb), *bytes_written, err);
458 /* write comment string if applicable */
459 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
460 option.type = OPT_COMMENT;
461 option.value_length = (guint16)(strlen(comment) + 1);
462 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
463 WRITE_DATA(fp, comment, strlen(comment) + 1, *bytes_written, err);
464 if ((strlen(comment) + 1) % 4) {
465 WRITE_DATA(fp, &padding, 4 - (strlen(comment) + 1) % 4 , *bytes_written, err);
469 /* write interface name string if applicable */
470 if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
471 option.type = IDB_NAME;
472 option.value_length = (guint16)(strlen(name) + 1);
473 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
474 WRITE_DATA(fp, name, strlen(name) + 1, *bytes_written, err);
475 if ((strlen(name) + 1) % 4) {
476 WRITE_DATA(fp, &padding, 4 - (strlen(name) + 1) % 4 , *bytes_written, err);
480 /* write interface description string if applicable */
481 if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) {
482 option.type = IDB_DESCRIPTION;
483 option.value_length = (guint16)(strlen(descr) + 1);
484 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
485 WRITE_DATA(fp, name, strlen(descr) + 1, *bytes_written, err);
486 if ((strlen(descr) + 1) % 4) {
487 WRITE_DATA(fp, &padding, 4 - (strlen(descr) + 1) % 4 , *bytes_written, err);
491 /* write filter string if applicable */
492 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
493 option.type = IDB_FILTER;
494 option.value_length = (guint16)(strlen(filter) + 1);
495 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
496 WRITE_DATA(fp, filter, strlen(filter) + 1, *bytes_written, err);
497 if ((strlen(filter) + 1) % 4) {
498 WRITE_DATA(fp, &padding, 4 - (strlen(filter) + 1) % 4 , *bytes_written, err);
502 /* write os string if applicable */
503 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
504 option.type = IDB_OS;
505 option.value_length = (guint16)(strlen(os) + 1);
506 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
507 WRITE_DATA(fp, os, strlen(os) + 1, *bytes_written, err);
508 if ((strlen(os) + 1) % 4) {
509 WRITE_DATA(fp, &padding, 4 - (strlen(os) + 1) % 4 , *bytes_written, err);
515 option.type = IDB_IF_SPEED;
516 option.value_length = sizeof(guint64);
517 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
518 WRITE_DATA(fp, &if_speed, sizeof(guint64), *bytes_written, err);
523 option.type = IDB_TSRESOL;
524 option.value_length = sizeof(guint8);
525 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
526 WRITE_DATA(fp, &if_speed, sizeof(guint8), *bytes_written, err);
527 WRITE_DATA(fp, &padding, 3 , *bytes_written, err);
531 /* write end of options */
532 option.type = OPT_ENDOFOPT;
533 option.value_length = 0;
534 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
537 /* write the trailing Block Total Length */
538 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
542 /* Write a record for a packet to a dump file.
543 Returns TRUE on success, FALSE on failure. */
545 libpcap_write_enhanced_packet_block(FILE *fp,
546 const struct pcap_pkthdr *phdr,
547 guint32 interface_id,
553 guint32 block_total_length;
555 const guint32 padding = 0;
557 block_total_length = sizeof(struct epb) +
558 ADD_PADDING(phdr->caplen) +
560 timestamp = (guint64)(phdr->ts.tv_sec) * 1000000 +
561 (guint64)(phdr->ts.tv_usec);
562 epb.block_type = ENHANCED_PACKET_BLOCK_TYPE;
563 epb.block_total_length = block_total_length;
564 epb.interface_id = interface_id;
565 epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
566 epb.timestamp_low = (guint32)(timestamp & 0xffffffff);
567 epb.captured_len = phdr->caplen;
568 epb.packet_len = phdr->len;
569 WRITE_DATA(fp, &epb, sizeof(struct epb), *bytes_written, err);
570 WRITE_DATA(fp, pd, phdr->caplen, *bytes_written, err);
571 if (phdr->caplen % 4) {
572 WRITE_DATA(fp, &padding, 4 - phdr->caplen % 4, *bytes_written, err);
574 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
579 libpcap_write_interface_statistics_block(FILE *fp,
580 guint32 interface_id,
591 struct option option;
592 struct pcap_stat stats;
593 guint32 block_total_length;
596 gboolean stats_retrieved;
600 * Current time, represented as 100-nanosecond intervals since
601 * January 1, 1601, 00:00:00 UTC.
603 * I think DWORD might be signed, so cast both parts of "now"
604 * to guint32 so that the sign bit doesn't get treated specially.
606 GetSystemTimeAsFileTime(&now);
607 timestamp = (((guint64)(guint32)now.dwHighDateTime) << 32) +
608 (guint32)now.dwLowDateTime;
611 * Convert to same thing but as 1-microsecond, i.e. 1000-nanosecond,
617 * Subtract difference, in microseconds, between January 1, 1601
618 * 00:00:00 UTC and January 1, 1970, 00:00:00 UTC.
620 timestamp -= G_GINT64_CONSTANT(11644473600000000U);
623 * Current time, represented as seconds and microseconds since
624 * January 1, 1970, 00:00:00 UTC.
626 gettimeofday(&now, NULL);
629 * Convert to delta in microseconds.
631 timestamp = (guint64)(now.tv_sec) * 1000000 +
632 (guint64)(now.tv_usec);
634 if (pcap_stats(pd, &stats) < 0) {
635 stats_retrieved = FALSE;
636 g_warning("pcap_stats() failed.");
638 stats_retrieved = TRUE;
640 block_total_length = sizeof(struct isb) +
642 if (stats_retrieved) {
643 block_total_length += 3 * sizeof(struct option) + 2 * sizeof(guint64);
645 isb.block_type = INTERFACE_STATISTICS_BLOCK_TYPE;
646 isb.block_total_length = block_total_length;
647 isb.interface_id = interface_id;
648 isb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
649 isb.timestamp_low = (guint32)(timestamp & 0xffffffff);
650 WRITE_DATA(fp, &isb, sizeof(struct isb), *bytes_written, err);
651 if (stats_retrieved) {
653 option.type = ISB_IFRECV;
654 option.value_length = sizeof(guint64);
655 counter = stats.ps_recv;
656 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
657 WRITE_DATA(fp, &counter, sizeof(guint64), *bytes_written, err);
659 option.type = ISB_IFDROP;
660 option.value_length = sizeof(guint64);
661 counter = stats.ps_drop;
662 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
663 WRITE_DATA(fp, &counter, sizeof(guint64), *bytes_written, err);
665 option.type = OPT_ENDOFOPT;
666 option.value_length = 0;
667 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
669 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
675 libpcap_dump_flush(FILE *pd, int *err)
677 if (fflush(pd) == EOF) {
686 libpcap_dump_close(FILE *pd, int *err)
688 if (fclose(pd) == EOF) {
696 #endif /* HAVE_LIBPCAP */