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
171 #define ISB_STARTTIME 2
172 #define ISB_ENDTIME 3
175 #define ISB_FILTERACCEPT 6
177 #define ISB_USRDELIV 8
178 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
180 #define WRITE_DATA(file_pointer, data_pointer, data_length, written_length, error_pointer) \
185 nwritten = fwrite(data_pointer, 1, data_length, file_pointer); \
186 if (nwritten != data_length) { \
187 if (nwritten == 0 && ferror(file_pointer)) { \
188 *error_pointer = errno; \
190 *error_pointer = 0; \
194 written_length += (long)nwritten; \
198 /* Returns a FILE * to write to on success, NULL on failure */
200 libpcap_fdopen(int fd, int *err)
204 fp = fdopen(fd, "wb");
211 /* Write the file header to a dump file.
212 Returns TRUE on success, FALSE on failure.
213 Sets "*err" to an error code, or 0 for a short write, on failure*/
215 libpcap_write_file_header(FILE *fp, int linktype, int snaplen, gboolean ts_nsecs, long *bytes_written, int *err)
217 struct pcap_hdr file_hdr;
220 file_hdr.magic = ts_nsecs ? PCAP_NSEC_MAGIC : PCAP_MAGIC;
221 /* current "libpcap" format is 2.4 */
222 file_hdr.version_major = 2;
223 file_hdr.version_minor = 4;
224 file_hdr.thiszone = 0; /* XXX - current offset? */
225 file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
226 file_hdr.snaplen = snaplen;
227 file_hdr.network = linktype;
228 nwritten = fwrite(&file_hdr, 1, sizeof(file_hdr), fp);
229 if (nwritten != sizeof(file_hdr)) {
230 if (nwritten == 0 && ferror(fp))
233 *err = 0; /* short write */
236 *bytes_written += sizeof(file_hdr);
241 /* Write a record for a packet to a dump file.
242 Returns TRUE on success, FALSE on failure. */
244 libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
245 long *bytes_written, int *err)
247 struct pcaprec_hdr rec_hdr;
250 rec_hdr.ts_sec = phdr->ts.tv_sec;
251 rec_hdr.ts_usec = phdr->ts.tv_usec;
252 rec_hdr.incl_len = phdr->caplen;
253 rec_hdr.orig_len = phdr->len;
254 nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, fp);
255 if (nwritten != sizeof rec_hdr) {
256 if (nwritten == 0 && ferror(fp))
259 *err = 0; /* short write */
262 *bytes_written += sizeof rec_hdr;
264 nwritten = fwrite(pd, 1, phdr->caplen, fp);
265 if (nwritten != phdr->caplen) {
266 if (nwritten == 0 && ferror(fp))
269 *err = 0; /* short write */
272 *bytes_written += phdr->caplen;
277 libpcap_write_session_header_block(FILE *fp,
282 guint64 section_length,
287 struct option option;
288 guint32 block_total_length;
289 const guint32 padding = 0;
290 gboolean have_options = FALSE;
292 /* Size of base header */
293 block_total_length = sizeof(struct shb) +
295 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
296 block_total_length += sizeof(struct option) +
297 (guint16)ADD_PADDING(strlen(comment));
300 if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
301 block_total_length += sizeof(struct option) +
302 (guint16)ADD_PADDING(strlen(hw));
305 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
306 block_total_length += sizeof(struct option) +
307 (guint16)ADD_PADDING(strlen(os));
310 if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
311 block_total_length += sizeof(struct option) +
312 (guint16)ADD_PADDING(strlen(appname));
315 /* If we have options add size of end-of-options */
317 block_total_length += sizeof(struct option);
319 /* write shb header */
320 shb.block_type = SECTION_HEADER_BLOCK_TYPE;
321 shb.block_total_length = block_total_length;
322 shb.byte_order_magic = PCAPNG_MAGIC;
323 shb.major_version = PCAPNG_MAJOR_VERSION;
324 shb.minor_version = PCAPNG_MINOR_VERSION;
325 shb.section_length = section_length;
326 WRITE_DATA(fp, &shb, sizeof(struct shb), *bytes_written, err);
328 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
329 /* write opt_comment options */
330 option.type = OPT_COMMENT;
331 option.value_length = (guint16)strlen(comment);
332 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
333 WRITE_DATA(fp, comment, strlen(comment), *bytes_written, err);
334 if (strlen(comment) % 4) {
335 WRITE_DATA(fp, &padding, 4 - strlen(comment) % 4, *bytes_written, err);
338 if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
339 /* write shb_hardware options */
340 option.type = SHB_HARDWARE;
341 option.value_length = (guint16)strlen(hw);
342 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
343 WRITE_DATA(fp, hw, strlen(hw), *bytes_written, err);
344 if ((strlen(hw) + 1) % 4) {
345 WRITE_DATA(fp, &padding, 4 - strlen(hw) % 4, *bytes_written, err);
348 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
349 /* write shb_os options */
350 option.type = SHB_OS;
351 option.value_length = (guint16)strlen(os);
352 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
353 WRITE_DATA(fp, os, strlen(os), *bytes_written, err);
354 if (strlen(os) % 4) {
355 WRITE_DATA(fp, &padding, 4 - strlen(os) % 4, *bytes_written, err);
358 if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
359 /* write shb_userappl options */
360 option.type = SHB_USERAPPL;
361 option.value_length = (guint16)strlen(appname);
362 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
363 WRITE_DATA(fp, appname, strlen(appname), *bytes_written, err);
364 if (strlen(appname) % 4) {
365 WRITE_DATA(fp, &padding, 4 - strlen(appname) % 4, *bytes_written, err);
369 /* write end of options */
370 option.type = OPT_ENDOFOPT;
371 option.value_length = 0;
372 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
375 /* write the trailing block total length */
376 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
381 libpcap_write_interface_description_block(FILE *fp,
382 const char *comment, /* OPT_COMMENT 1 */
383 const char *name, /* IDB_NAME 2 */
384 const char *descr, /* IDB_DESCRIPTION 3 */
385 const char *filter, /* IDB_FILTER 11 */
386 const char *os, /* IDB_OS 12 */
390 guint64 if_speed, /* IDB_IF_SPEED 8 */
391 guint8 tsresol, /* IDB_TSRESOL 9 */
395 struct option option;
396 guint32 block_total_length;
397 const guint32 padding = 0;
398 gboolean have_options = FALSE;
400 block_total_length = sizeof(struct idb) + sizeof(guint32);
401 /* 01 - OPT_COMMENT */
402 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
403 block_total_length += sizeof(struct option) +
404 (guint16)ADD_PADDING(strlen(comment));
409 if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
410 block_total_length += sizeof(struct option) +
411 (guint16)ADD_PADDING(strlen(name));
415 /* 03 - IDB_DESCRIPTION */
416 if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) {
417 block_total_length += sizeof(struct option) +
418 (guint16)ADD_PADDING(strlen(descr));
422 /* 08 - IDB_IF_SPEED */
424 block_total_length += sizeof(struct option) + sizeof(guint64);
428 /* 09 - IDB_TSRESOL */
430 block_total_length += sizeof(struct option) + sizeof(struct option);
434 /* 11 - IDB_FILTER */
435 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
436 block_total_length += sizeof(struct option) +
437 (guint16)(ADD_PADDING(strlen(filter)+ 1));
442 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
443 block_total_length += sizeof(struct option) +
444 (guint16)ADD_PADDING(strlen(os));
448 /* If we have options add size of end-of-options */
450 block_total_length += sizeof(struct option);
453 /* write block header */
454 idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE;
455 idb.block_total_length = block_total_length;
456 idb.link_type = link_type;
458 idb.snap_len = snap_len;
459 WRITE_DATA(fp, &idb, sizeof(struct idb), *bytes_written, err);
461 /* 01 - OPT_COMMENT - write comment string if applicable */
462 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
463 option.type = OPT_COMMENT;
464 option.value_length = (guint16)strlen(comment);
465 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
466 WRITE_DATA(fp, comment, strlen(comment), *bytes_written, err);
467 if (strlen(comment) % 4) {
468 WRITE_DATA(fp, &padding, 4 - strlen(comment) % 4 , *bytes_written, err);
472 /* 02 - IDB_NAME - write interface name string if applicable */
473 if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
474 option.type = IDB_NAME;
475 option.value_length = (guint16)strlen(name);
476 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
477 WRITE_DATA(fp, name, strlen(name), *bytes_written, err);
478 if (strlen(name) % 4) {
479 WRITE_DATA(fp, &padding, 4 - strlen(name) % 4 , *bytes_written, err);
483 /* 03 - IDB_DESCRIPTION */
484 /* write interface description string if applicable */
485 if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) {
486 option.type = IDB_DESCRIPTION;
487 option.value_length = (guint16)strlen(descr);
488 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
489 WRITE_DATA(fp, descr, strlen(descr), *bytes_written, err);
490 if (strlen(descr) % 4) {
491 WRITE_DATA(fp, &padding, 4 - strlen(descr) % 4 , *bytes_written, err);
495 /* 08 - IDB_IF_SPEED */
497 option.type = IDB_IF_SPEED;
498 option.value_length = sizeof(guint64);
499 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
500 WRITE_DATA(fp, &if_speed, sizeof(guint64), *bytes_written, err);
503 /* 09 - IDB_TSRESOL */
505 option.type = IDB_TSRESOL;
506 option.value_length = sizeof(guint8);
507 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
508 WRITE_DATA(fp, &tsresol, sizeof(guint8), *bytes_written, err);
509 WRITE_DATA(fp, &padding, 3 , *bytes_written, err);
512 /* 11 - IDB_FILTER - write filter string if applicable
513 * We only write version 1 of the filter, libpcap string
515 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
516 option.type = IDB_FILTER;
517 option.value_length = (guint16)(strlen(filter) + 1 );
518 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
520 /* The first byte of the Option Data keeps a code of the filter used, 0 = lipbpcap filter string */
521 WRITE_DATA(fp, &padding, 1, *bytes_written, err);
522 WRITE_DATA(fp, filter, strlen(filter), *bytes_written, err);
523 if ((strlen(filter) + 1) % 4) {
524 WRITE_DATA(fp, &padding, 4 - (strlen(filter) + 1) % 4 , *bytes_written, err);
528 /* 12 - IDB_OS - write os string if applicable */
529 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
530 option.type = IDB_OS;
531 option.value_length = (guint16)strlen(os);
532 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
533 WRITE_DATA(fp, os, strlen(os), *bytes_written, err);
534 if (strlen(os) % 4) {
535 WRITE_DATA(fp, &padding, 4 - strlen(os) % 4 , *bytes_written, err);
540 /* write end of options */
541 option.type = OPT_ENDOFOPT;
542 option.value_length = 0;
543 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
546 /* write the trailing Block Total Length */
547 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
551 /* Write a record for a packet to a dump file.
552 Returns TRUE on success, FALSE on failure. */
554 libpcap_write_enhanced_packet_block(FILE *fp,
555 const struct pcap_pkthdr *phdr,
556 guint32 interface_id,
563 guint32 block_total_length;
565 const guint32 padding = 0;
567 block_total_length = sizeof(struct epb) +
568 ADD_PADDING(phdr->caplen) +
570 timestamp = (guint64)(phdr->ts.tv_sec) * ts_mul +
571 (guint64)(phdr->ts.tv_usec);
572 epb.block_type = ENHANCED_PACKET_BLOCK_TYPE;
573 epb.block_total_length = block_total_length;
574 epb.interface_id = interface_id;
575 epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
576 epb.timestamp_low = (guint32)(timestamp & 0xffffffff);
577 epb.captured_len = phdr->caplen;
578 epb.packet_len = phdr->len;
579 WRITE_DATA(fp, &epb, sizeof(struct epb), *bytes_written, err);
580 WRITE_DATA(fp, pd, phdr->caplen, *bytes_written, err);
581 if (phdr->caplen % 4) {
582 WRITE_DATA(fp, &padding, 4 - phdr->caplen % 4, *bytes_written, err);
584 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
589 libpcap_write_interface_statistics_block(FILE *fp,
590 guint32 interface_id,
592 const char *comment, /* OPT_COMMENT 1 */
593 guint64 isb_starttime, /* ISB_STARTTIME 2 */
594 guint64 isb_endtime, /* ISB_ENDTIME 3 */
595 guint64 isb_ifrecv, /* ISB_IFRECV 4 */
596 guint64 isb_ifdrop, /* ISB_IFDROP 5 */
605 struct option option;
606 guint32 block_total_length;
608 gboolean have_options = FALSE;
609 const guint32 padding = 0;
612 * Current time, represented as 100-nanosecond intervals since
613 * January 1, 1601, 00:00:00 UTC.
615 * I think DWORD might be signed, so cast both parts of "now"
616 * to guint32 so that the sign bit doesn't get treated specially.
618 * Windows 8 provides GetSystemTimePreciseAsFileTime which we
619 * might want to use instead.
621 GetSystemTimeAsFileTime(&now);
622 timestamp = (((guint64)(guint32)now.dwHighDateTime) << 32) +
623 (guint32)now.dwLowDateTime;
626 * Convert to same thing but as 1-microsecond, i.e. 1000-nanosecond,
632 * Subtract difference, in microseconds, between January 1, 1601
633 * 00:00:00 UTC and January 1, 1970, 00:00:00 UTC.
635 timestamp -= G_GINT64_CONSTANT(11644473600000000U);
638 * Current time, represented as seconds and microseconds since
639 * January 1, 1970, 00:00:00 UTC.
641 gettimeofday(&now, NULL);
644 * Convert to delta in microseconds.
646 timestamp = (guint64)(now.tv_sec) * 1000000 +
647 (guint64)(now.tv_usec);
649 block_total_length = sizeof(struct isb) + sizeof(guint32);
650 if (isb_ifrecv != G_MAXUINT64) {
651 block_total_length += sizeof(struct option) + sizeof(guint64);
654 if (isb_ifdrop != G_MAXUINT64) {
655 block_total_length += sizeof(struct option) + sizeof(guint64);
659 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
660 block_total_length += sizeof(struct option) +
661 (guint16)ADD_PADDING(strlen(comment));
664 if (isb_starttime !=0) {
665 block_total_length += sizeof(struct option) + sizeof(guint64); /* ISB_STARTTIME */
668 if (isb_endtime !=0) {
669 block_total_length += sizeof(struct option) + sizeof(guint64); /* ISB_ENDTIME */
672 /* If we have options add size of end-of-options */
674 block_total_length += sizeof(struct option);
677 isb.block_type = INTERFACE_STATISTICS_BLOCK_TYPE;
678 isb.block_total_length = block_total_length;
679 isb.interface_id = interface_id;
680 isb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
681 isb.timestamp_low = (guint32)(timestamp & 0xffffffff);
682 WRITE_DATA(fp, &isb, sizeof(struct isb), *bytes_written, err);
684 /* write comment string if applicable */
685 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
686 option.type = OPT_COMMENT;
687 option.value_length = (guint16)strlen(comment);
688 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
689 WRITE_DATA(fp, comment, strlen(comment), *bytes_written, err);
690 if (strlen(comment) % 4) {
691 WRITE_DATA(fp, &padding, 4 - strlen(comment) % 4 , *bytes_written, err);
695 if (isb_starttime !=0) {
698 option.type = ISB_STARTTIME;
699 option.value_length = sizeof(guint64);
700 high = (guint32)((isb_starttime>>32) & 0xffffffff);
701 low = (guint32)(isb_starttime & 0xffffffff);
702 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
703 WRITE_DATA(fp, &high, sizeof(guint32), *bytes_written, err);
704 WRITE_DATA(fp, &low, sizeof(guint32), *bytes_written, err);
706 if (isb_endtime !=0) {
709 option.type = ISB_ENDTIME;
710 option.value_length = sizeof(guint64);
711 high = (guint32)((isb_endtime>>32) & 0xffffffff);
712 low = (guint32)(isb_endtime & 0xffffffff);
713 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
714 WRITE_DATA(fp, &high, sizeof(guint32), *bytes_written, err);
715 WRITE_DATA(fp, &low, sizeof(guint32), *bytes_written, err);
717 if (isb_ifrecv != G_MAXUINT64) {
718 option.type = ISB_IFRECV;
719 option.value_length = sizeof(guint64);
720 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
721 WRITE_DATA(fp, &isb_ifrecv, sizeof(guint64), *bytes_written, err);
723 if (isb_ifdrop != G_MAXUINT64) {
724 option.type = ISB_IFDROP;
725 option.value_length = sizeof(guint64);
726 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
727 WRITE_DATA(fp, &isb_ifdrop, sizeof(guint64), *bytes_written, err);
730 /* write end of options */
731 option.type = OPT_ENDOFOPT;
732 option.value_length = 0;
733 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
736 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
742 libpcap_dump_flush(FILE *pd, int *err)
744 if (fflush(pd) == EOF) {
753 libpcap_dump_close(FILE *pd, int *err)
755 if (fclose(pd) == EOF) {
763 #endif /* HAVE_LIBPCAP */
766 * Editor modelines - http://www.wireshark.org/tools/modelines.html
771 * indent-tabs-mode: nil
774 * vi: set shiftwidth=4 tabstop=8 expandtab:
775 * :indentSize=4:tabSize=8:noTabs=true: