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.
19 * Wireshark - Network traffic analyzer
20 * By Gerald Combs <gerald@wireshark.org>
21 * Copyright 1998 Gerald Combs
23 * Derived from code in the Wiretap Library
24 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
26 * This program is free software; you can redistribute it and/or
27 * modify it under the terms of the GNU General Public License
28 * as published by the Free Software Foundation; either version 2
29 * of the License, or (at your option) any later version.
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public License
37 * along with this program; if not, write to the Free Software
38 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
47 #ifdef HAVE_SYS_TIME_H
58 /* Magic numbers in "libpcap" files.
60 "libpcap" file records are written in the byte order of the host that
61 writes them, and the reader is expected to fix this up.
63 PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC
64 is a byte-swapped version of that.
66 PCAP_NSEC_MAGIC is for Ulf Lamping's modified "libpcap" format,
67 which uses the same common file format as PCAP_MAGIC, but the
68 timestamps are saved in nanosecond resolution instead of microseconds.
69 PCAP_SWAPPED_NSEC_MAGIC is a byte-swapped version of that. */
70 #define PCAP_MAGIC 0xa1b2c3d4
71 #define PCAP_SWAPPED_MAGIC 0xd4c3b2a1
72 #define PCAP_NSEC_MAGIC 0xa1b23c4d
73 #define PCAP_SWAPPED_NSEC_MAGIC 0x4d3cb2a1
75 /* "libpcap" file header. */
77 guint32 magic; /* magic number */
78 guint16 version_major; /* major version number */
79 guint16 version_minor; /* minor version number */
80 gint32 thiszone; /* GMT to local correction */
81 guint32 sigfigs; /* accuracy of timestamps */
82 guint32 snaplen; /* max length of captured packets, in octets */
83 guint32 network; /* data link type */
86 /* "libpcap" record header. */
88 guint32 ts_sec; /* timestamp seconds */
89 guint32 ts_usec; /* timestamp microseconds (nsecs for PCAP_NSEC_MAGIC) */
90 guint32 incl_len; /* number of octets of packet saved in file */
91 guint32 orig_len; /* actual length of packet */
94 /* Magic numbers in ".pcapng" files.
96 * .pcapng file records are written in the byte order of the host that
97 * writes them, and the reader is expected to fix this up.
98 * PCAPNG_MAGIC is the magic number, in host byte order;
99 * PCAPNG_SWAPPED_MAGIC is a byte-swapped version of that.
101 #define PCAPNG_MAGIC 0x1A2B3C4D
102 #define PCAPNG_SWAPPED_MAGIC 0xD4C3B2A1
104 /* Currently we are only supporting the initial version of
106 #define PCAPNG_MAJOR_VERSION 1
107 #define PCAPNG_MINOR_VERSION 0
109 /* Section Header Block without options and trailing Block Total Length */
112 guint32 block_total_length;
113 guint32 byte_order_magic;
114 guint16 major_version;
115 guint16 minor_version;
116 guint64 section_length;
118 #define SECTION_HEADER_BLOCK_TYPE 0x0A0D0D0A
120 /* Interface Decription Block without options and trailing Block Total Length */
123 guint32 block_total_length;
128 #define INTERFACE_DESCRIPTION_BLOCK_TYPE 0x00000001
130 /* Interface Statistics Block without actual packet, options, and trailing
131 Block Total Length */
134 guint32 block_total_length;
135 guint32 interface_id;
136 guint32 timestamp_high;
137 guint32 timestamp_low;
139 #define INTERFACE_STATISTICS_BLOCK_TYPE 0x00000005
141 /* Enhanced Packet Block without actual packet, options, and trailing
142 Block Total Length */
145 guint32 block_total_length;
146 guint32 interface_id;
147 guint32 timestamp_high;
148 guint32 timestamp_low;
149 guint32 captured_len;
152 #define ENHANCED_PACKET_BLOCK_TYPE 0x00000006
156 guint16 value_length;
158 #define OPT_ENDOFOPT 0
159 #define OPT_COMMENT 1
161 #define SHB_HARDWARE 2 /* currently not used */
163 #define SHB_USERAPPL 4
165 #define IDB_DESCRIPTION 3
166 #define IDB_IF_SPEED 8
167 #define IDB_TSRESOL 9
168 #define IDB_FILTER 11
170 #define ISB_STARTTIME 2
171 #define ISB_ENDTIME 3
174 #define ISB_FILTERACCEPT 6
176 #define ISB_USRDELIV 8
177 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
179 /* Write to capture file */
181 write_to_file(FILE* pfile, const guint8* data, size_t data_length,
182 guint64 *bytes_written, int *err)
186 nwritten = fwrite(data, data_length, 1, pfile);
196 (*bytes_written) += data_length;
200 /* Writing pcap files */
202 /* Write the file header to a dump file.
203 Returns TRUE on success, FALSE on failure.
204 Sets "*err" to an error code, or 0 for a short write, on failure*/
206 libpcap_write_file_header(FILE* pfile, int linktype, int snaplen, gboolean ts_nsecs, guint64 *bytes_written, int *err)
208 struct pcap_hdr file_hdr;
210 file_hdr.magic = ts_nsecs ? PCAP_NSEC_MAGIC : PCAP_MAGIC;
211 /* current "libpcap" format is 2.4 */
212 file_hdr.version_major = 2;
213 file_hdr.version_minor = 4;
214 file_hdr.thiszone = 0; /* XXX - current offset? */
215 file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
216 file_hdr.snaplen = snaplen;
217 file_hdr.network = linktype;
219 return write_to_file(pfile, (const guint8*)&file_hdr, sizeof(file_hdr), bytes_written, err);
222 /* Write a record for a packet to a dump file.
223 Returns TRUE on success, FALSE on failure. */
225 libpcap_write_packet(FILE* pfile,
226 time_t sec, guint32 usec,
227 guint32 caplen, guint32 len,
229 guint64 *bytes_written, int *err)
231 struct pcaprec_hdr rec_hdr;
233 rec_hdr.ts_sec = (guint32)sec; /* Y2.038K issue in pcap format.... */
234 rec_hdr.ts_usec = usec;
235 rec_hdr.incl_len = caplen;
236 rec_hdr.orig_len = len;
237 if (!write_to_file(pfile, (const guint8*)&rec_hdr, sizeof(rec_hdr), bytes_written, err))
240 return write_to_file(pfile, pd, caplen, bytes_written, err);
243 /* Writing pcap-ng files */
246 pcapng_count_string_option(const char *option_value)
248 if ((option_value != NULL) && (strlen(option_value) > 0) && (strlen(option_value) < G_MAXUINT16)) {
249 /* There's a value to write; get its length */
250 return (guint32)(sizeof(struct option) +
251 (guint16)ADD_PADDING(strlen(option_value)));
253 return 0; /* nothing to write */
257 pcapng_write_string_option(FILE* pfile,
258 guint16 option_type, const char *option_value,
259 guint64 *bytes_written, int *err)
261 size_t option_value_length;
262 struct option option;
263 const guint32 padding = 0;
265 if (option_value == NULL)
266 return TRUE; /* nothing to write */
267 option_value_length = strlen(option_value);
268 if ((option_value_length > 0) && (option_value_length < G_MAXUINT16)) {
269 /* something to write */
270 option.type = option_type;
271 option.value_length = (guint16)option_value_length;
273 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
276 if (!write_to_file(pfile, (const guint8*)option_value, (int) option_value_length, bytes_written, err))
279 if (option_value_length % 4) {
280 if (!write_to_file(pfile, (const guint8*)&padding, 4 - option_value_length % 4, bytes_written, err))
288 pcapng_write_session_header_block(FILE* pfile,
293 guint64 section_length,
294 guint64 *bytes_written,
298 struct option option;
299 guint32 block_total_length;
300 guint32 options_length;
302 /* Size of base header */
303 block_total_length = sizeof(struct shb) +
306 options_length += pcapng_count_string_option(comment);
307 options_length += pcapng_count_string_option(hw);
308 options_length += pcapng_count_string_option(os);
309 options_length += pcapng_count_string_option(appname);
310 /* If we have options add size of end-of-options */
311 if (options_length != 0) {
312 options_length += (guint32)sizeof(struct option);
314 block_total_length += options_length;
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;
324 if (!write_to_file(pfile, (const guint8*)&shb, sizeof(struct shb), bytes_written, err))
327 if (!pcapng_write_string_option(pfile, OPT_COMMENT, comment,
330 if (!pcapng_write_string_option(pfile, SHB_HARDWARE, hw,
333 if (!pcapng_write_string_option(pfile, SHB_OS, os,
336 if (!pcapng_write_string_option(pfile, SHB_USERAPPL, appname,
339 if (options_length != 0) {
340 /* write end of options */
341 option.type = OPT_ENDOFOPT;
342 option.value_length = 0;
343 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
347 /* write the trailing block total length */
348 return write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err);
352 pcapng_write_interface_description_block(FILE* pfile,
353 const char *comment, /* OPT_COMMENT 1 */
354 const char *name, /* IDB_NAME 2 */
355 const char *descr, /* IDB_DESCRIPTION 3 */
356 const char *filter, /* IDB_FILTER 11 */
357 const char *os, /* IDB_OS 12 */
360 guint64 *bytes_written,
361 guint64 if_speed, /* IDB_IF_SPEED 8 */
362 guint8 tsresol, /* IDB_TSRESOL 9 */
366 struct option option;
367 guint32 block_total_length;
368 guint32 options_length;
369 const guint32 padding = 0;
371 block_total_length = (guint32)(sizeof(struct idb) + sizeof(guint32));
373 /* 01 - OPT_COMMENT */
374 options_length += pcapng_count_string_option(comment);
377 options_length += pcapng_count_string_option(name);
379 /* 03 - IDB_DESCRIPTION */
380 options_length += pcapng_count_string_option(descr);
382 /* 08 - IDB_IF_SPEED */
384 options_length += (guint32)(sizeof(struct option) +
388 /* 09 - IDB_TSRESOL */
390 options_length += (guint32)(sizeof(struct option) +
391 sizeof(struct option));
394 /* 11 - IDB_FILTER */
395 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
396 /* No, this isn't a string, it has an extra type byte */
397 options_length += (guint32)(sizeof(struct option) +
398 (guint16)(ADD_PADDING(strlen(filter)+ 1)));
402 options_length += pcapng_count_string_option(os);
404 /* If we have options add size of end-of-options */
405 if (options_length != 0) {
406 options_length += (guint32)sizeof(struct option);
408 block_total_length += options_length;
410 /* write block header */
411 idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE;
412 idb.block_total_length = block_total_length;
413 idb.link_type = link_type;
415 idb.snap_len = snap_len;
416 if (!write_to_file(pfile, (const guint8*)&idb, sizeof(struct idb), bytes_written, err))
419 /* 01 - OPT_COMMENT - write comment string if applicable */
420 if (!pcapng_write_string_option(pfile, OPT_COMMENT, comment,
424 /* 02 - IDB_NAME - write interface name string if applicable */
425 if (!pcapng_write_string_option(pfile, IDB_NAME, name,
429 /* 03 - IDB_DESCRIPTION */
430 /* write interface description string if applicable */
431 if (!pcapng_write_string_option(pfile, IDB_DESCRIPTION, descr,
435 /* 08 - IDB_IF_SPEED */
437 option.type = IDB_IF_SPEED;
438 option.value_length = sizeof(guint64);
440 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
443 if (!write_to_file(pfile, (const guint8*)&if_speed, sizeof(guint64), bytes_written, err))
447 /* 09 - IDB_TSRESOL */
449 option.type = IDB_TSRESOL;
450 option.value_length = sizeof(guint8);
452 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
455 if (!write_to_file(pfile, (const guint8*)&tsresol, sizeof(guint8), bytes_written, err))
458 if (!write_to_file(pfile, (const guint8*)&padding, 3, bytes_written, err))
462 /* 11 - IDB_FILTER - write filter string if applicable
463 * We only write version 1 of the filter, pcapng string
465 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16 - 1)) {
466 option.type = IDB_FILTER;
467 option.value_length = (guint16)(strlen(filter) + 1 );
468 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
471 /* The first byte of the Option Data keeps a code of the filter used, 0 = lipbpcap filter string */
472 if (!write_to_file(pfile, (const guint8*)&padding, 1, bytes_written, err))
474 if (!write_to_file(pfile, (const guint8*)filter, (int) strlen(filter), bytes_written, err))
476 if ((strlen(filter) + 1) % 4) {
477 if (!write_to_file(pfile, (const guint8*)&padding, 4 - (strlen(filter) + 1) % 4, bytes_written, err))
482 /* 12 - IDB_OS - write os string if applicable */
483 if (!pcapng_write_string_option(pfile, IDB_OS, os,
487 if (options_length != 0) {
488 /* write end of options */
489 option.type = OPT_ENDOFOPT;
490 option.value_length = 0;
491 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
495 /* write the trailing Block Total Length */
496 return write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err);
499 /* Write a record for a packet to a dump file.
500 Returns TRUE on success, FALSE on failure. */
502 pcapng_write_enhanced_packet_block(FILE* pfile,
504 time_t sec, guint32 usec,
505 guint32 caplen, guint32 len,
506 guint32 interface_id,
510 guint64 *bytes_written,
514 struct option option;
515 guint32 block_total_length;
517 guint32 options_length;
518 const guint32 padding = 0;
520 block_total_length = (guint32)(sizeof(struct epb) +
521 ADD_PADDING(caplen) +
524 options_length += pcapng_count_string_option(comment);
526 options_length += (guint32)(sizeof(struct option) +
529 /* If we have options add size of end-of-options */
530 if (options_length != 0) {
531 options_length += (guint32)sizeof(struct option);
533 block_total_length += options_length;
534 timestamp = (guint64)sec * ts_mul + (guint64)usec;
535 epb.block_type = ENHANCED_PACKET_BLOCK_TYPE;
536 epb.block_total_length = block_total_length;
537 epb.interface_id = interface_id;
538 epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
539 epb.timestamp_low = (guint32)(timestamp & 0xffffffff);
540 epb.captured_len = caplen;
541 epb.packet_len = len;
542 if (!write_to_file(pfile, (const guint8*)&epb, sizeof(struct epb), bytes_written, err))
544 if (!write_to_file(pfile, pd, caplen, bytes_written, err))
547 if (!write_to_file(pfile, (const guint8*)&padding, 4 - caplen % 4, bytes_written, err))
550 if (!pcapng_write_string_option(pfile, OPT_COMMENT, comment,
554 option.type = EPB_FLAGS;
555 option.value_length = sizeof(guint32);
556 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
558 if (!write_to_file(pfile, (const guint8*)&flags, sizeof(guint32), bytes_written, err))
561 if (options_length != 0) {
562 /* write end of options */
563 option.type = OPT_ENDOFOPT;
564 option.value_length = 0;
565 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
569 return write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err);
573 pcapng_write_interface_statistics_block(FILE* pfile,
574 guint32 interface_id,
575 guint64 *bytes_written,
576 const char *comment, /* OPT_COMMENT 1 */
577 guint64 isb_starttime, /* ISB_STARTTIME 2 */
578 guint64 isb_endtime, /* ISB_ENDTIME 3 */
579 guint64 isb_ifrecv, /* ISB_IFRECV 4 */
580 guint64 isb_ifdrop, /* ISB_IFDROP 5 */
589 struct option option;
590 guint32 block_total_length;
591 guint32 options_length;
596 * Current time, represented as 100-nanosecond intervals since
597 * January 1, 1601, 00:00:00 UTC.
599 * I think DWORD might be signed, so cast both parts of "now"
600 * to guint32 so that the sign bit doesn't get treated specially.
602 * Windows 8 provides GetSystemTimePreciseAsFileTime which we
603 * might want to use instead.
605 GetSystemTimeAsFileTime(&now);
606 timestamp = (((guint64)(guint32)now.dwHighDateTime) << 32) +
607 (guint32)now.dwLowDateTime;
610 * Convert to same thing but as 1-microsecond, i.e. 1000-nanosecond,
616 * Subtract difference, in microseconds, between January 1, 1601
617 * 00:00:00 UTC and January 1, 1970, 00:00:00 UTC.
619 timestamp -= G_GUINT64_CONSTANT(11644473600000000);
622 * Current time, represented as seconds and microseconds since
623 * January 1, 1970, 00:00:00 UTC.
625 gettimeofday(&now, NULL);
628 * Convert to delta in microseconds.
630 timestamp = (guint64)(now.tv_sec) * 1000000 +
631 (guint64)(now.tv_usec);
633 block_total_length = (guint32)(sizeof(struct isb) + sizeof(guint32));
635 if (isb_ifrecv != G_MAXUINT64) {
636 options_length += (guint32)(sizeof(struct option) +
639 if (isb_ifdrop != G_MAXUINT64) {
640 options_length += (guint32)(sizeof(struct option) +
644 options_length += pcapng_count_string_option(comment);
645 if (isb_starttime !=0) {
646 options_length += (guint32)(sizeof(struct option) +
647 sizeof(guint64)); /* ISB_STARTTIME */
649 if (isb_endtime !=0) {
650 options_length += (guint32)(sizeof(struct option) +
651 sizeof(guint64)); /* ISB_ENDTIME */
653 /* If we have options add size of end-of-options */
654 if (options_length != 0) {
655 options_length += (guint32)sizeof(struct option);
657 block_total_length += options_length;
659 isb.block_type = INTERFACE_STATISTICS_BLOCK_TYPE;
660 isb.block_total_length = block_total_length;
661 isb.interface_id = interface_id;
662 isb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
663 isb.timestamp_low = (guint32)(timestamp & 0xffffffff);
664 if (!write_to_file(pfile, (const guint8*)&isb, sizeof(struct isb), bytes_written, err))
667 /* write comment string if applicable */
668 if (!pcapng_write_string_option(pfile, OPT_COMMENT, comment,
672 if (isb_starttime !=0) {
675 option.type = ISB_STARTTIME;
676 option.value_length = sizeof(guint64);
677 high = (guint32)((isb_starttime>>32) & 0xffffffff);
678 low = (guint32)(isb_starttime & 0xffffffff);
679 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
682 if (!write_to_file(pfile, (const guint8*)&high, sizeof(guint32), bytes_written, err))
685 if (!write_to_file(pfile, (const guint8*)&low, sizeof(guint32), bytes_written, err))
688 if (isb_endtime !=0) {
691 option.type = ISB_ENDTIME;
692 option.value_length = sizeof(guint64);
693 high = (guint32)((isb_endtime>>32) & 0xffffffff);
694 low = (guint32)(isb_endtime & 0xffffffff);
695 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
698 if (!write_to_file(pfile, (const guint8*)&high, sizeof(guint32), bytes_written, err))
701 if (!write_to_file(pfile, (const guint8*)&low, sizeof(guint32), bytes_written, err))
704 if (isb_ifrecv != G_MAXUINT64) {
705 option.type = ISB_IFRECV;
706 option.value_length = sizeof(guint64);
707 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
710 if (!write_to_file(pfile, (const guint8*)&isb_ifrecv, sizeof(guint64), bytes_written, err))
713 if (isb_ifdrop != G_MAXUINT64) {
714 option.type = ISB_IFDROP;
715 option.value_length = sizeof(guint64);
716 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
719 if (!write_to_file(pfile, (const guint8*)&isb_ifdrop, sizeof(guint64), bytes_written, err))
722 if (options_length != 0) {
723 /* write end of options */
724 option.type = OPT_ENDOFOPT;
725 option.value_length = 0;
726 if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
730 return write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err);
734 * Editor modelines - http://www.wireshark.org/tools/modelines.html
739 * indent-tabs-mode: nil
742 * vi: set shiftwidth=8 tabstop=8 expandtab:
743 * :indentSize=8:tabSize=8:noTabs=true: