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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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
160 #define SHB_HARDWARE 2 /* currently not used */
162 #define SHB_USERAPPL 4
164 #define IDB_DESCRIPTION 3
165 #define IDB_IF_SPEED 8
166 #define IDB_TSRESOL 9
167 #define IDB_FILTER 11
169 #define ISB_STARTTIME 2
170 #define ISB_ENDTIME 3
173 #define ISB_FILTERACCEPT 6
175 #define ISB_USRDELIV 8
176 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
178 #define WRITE_DATA(file_pointer, data_pointer, data_length, written_length, error_pointer) \
183 nwritten = fwrite(data_pointer, 1, data_length, file_pointer); \
184 if (nwritten != data_length) { \
185 if (nwritten == 0 && ferror(file_pointer)) { \
186 *error_pointer = errno; \
188 *error_pointer = 0; \
192 written_length += (long)nwritten; \
196 /* Returns a FILE * to write to on success, NULL on failure */
198 libpcap_fdopen(int fd, int *err)
202 fp = fdopen(fd, "wb");
209 /* Write the file header to a dump file.
210 Returns TRUE on success, FALSE on failure.
211 Sets "*err" to an error code, or 0 for a short write, on failure*/
213 libpcap_write_file_header(FILE *fp, int linktype, int snaplen, gboolean ts_nsecs, long *bytes_written, int *err)
215 struct pcap_hdr file_hdr;
218 file_hdr.magic = ts_nsecs ? PCAP_NSEC_MAGIC : PCAP_MAGIC;
219 /* current "libpcap" format is 2.4 */
220 file_hdr.version_major = 2;
221 file_hdr.version_minor = 4;
222 file_hdr.thiszone = 0; /* XXX - current offset? */
223 file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
224 file_hdr.snaplen = snaplen;
225 file_hdr.network = linktype;
226 nwritten = fwrite(&file_hdr, 1, sizeof(file_hdr), fp);
227 if (nwritten != sizeof(file_hdr)) {
228 if (nwritten == 0 && ferror(fp))
231 *err = 0; /* short write */
234 *bytes_written += sizeof(file_hdr);
239 /* Write a record for a packet to a dump file.
240 Returns TRUE on success, FALSE on failure. */
242 libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
243 long *bytes_written, int *err)
245 struct pcaprec_hdr rec_hdr;
248 rec_hdr.ts_sec = phdr->ts.tv_sec;
249 rec_hdr.ts_usec = phdr->ts.tv_usec;
250 rec_hdr.incl_len = phdr->caplen;
251 rec_hdr.orig_len = phdr->len;
252 nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, fp);
253 if (nwritten != sizeof rec_hdr) {
254 if (nwritten == 0 && ferror(fp))
257 *err = 0; /* short write */
260 *bytes_written += sizeof rec_hdr;
262 nwritten = fwrite(pd, 1, phdr->caplen, fp);
263 if (nwritten != phdr->caplen) {
264 if (nwritten == 0 && ferror(fp))
267 *err = 0; /* short write */
270 *bytes_written += phdr->caplen;
275 libpcap_write_session_header_block(FILE *fp,
280 guint64 section_length,
285 struct option option;
286 guint32 block_total_length;
287 const guint32 padding = 0;
288 gboolean have_options = FALSE;
290 /* Size of base header */
291 block_total_length = sizeof(struct shb) +
293 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
294 block_total_length += sizeof(struct option) +
295 (guint16)ADD_PADDING(strlen(comment));
298 if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
299 block_total_length += sizeof(struct option) +
300 (guint16)ADD_PADDING(strlen(hw));
303 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
304 block_total_length += sizeof(struct option) +
305 (guint16)ADD_PADDING(strlen(os));
308 if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
309 block_total_length += sizeof(struct option) +
310 (guint16)ADD_PADDING(strlen(appname));
313 /* If we have options add size of end-of-options */
315 block_total_length += sizeof(struct option);
317 /* write shb header */
318 shb.block_type = SECTION_HEADER_BLOCK_TYPE;
319 shb.block_total_length = block_total_length;
320 shb.byte_order_magic = PCAPNG_MAGIC;
321 shb.major_version = PCAPNG_MAJOR_VERSION;
322 shb.minor_version = PCAPNG_MINOR_VERSION;
323 shb.section_length = section_length;
324 WRITE_DATA(fp, &shb, sizeof(struct shb), *bytes_written, err);
326 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
327 /* write opt_comment options */
328 option.type = OPT_COMMENT;
329 option.value_length = (guint16)strlen(comment);
330 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
331 WRITE_DATA(fp, comment, strlen(comment), *bytes_written, err);
332 if (strlen(comment) % 4) {
333 WRITE_DATA(fp, &padding, 4 - strlen(comment) % 4, *bytes_written, err);
336 if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
337 /* write shb_hardware options */
338 option.type = SHB_HARDWARE;
339 option.value_length = (guint16)strlen(hw);
340 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
341 WRITE_DATA(fp, hw, strlen(hw), *bytes_written, err);
342 if ((strlen(hw) + 1) % 4) {
343 WRITE_DATA(fp, &padding, 4 - strlen(hw) % 4, *bytes_written, err);
346 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
347 /* write shb_os options */
348 option.type = SHB_OS;
349 option.value_length = (guint16)strlen(os);
350 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
351 WRITE_DATA(fp, os, strlen(os), *bytes_written, err);
352 if (strlen(os) % 4) {
353 WRITE_DATA(fp, &padding, 4 - strlen(os) % 4, *bytes_written, err);
356 if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
357 /* write shb_userappl options */
358 option.type = SHB_USERAPPL;
359 option.value_length = (guint16)strlen(appname);
360 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
361 WRITE_DATA(fp, appname, strlen(appname), *bytes_written, err);
362 if (strlen(appname) % 4) {
363 WRITE_DATA(fp, &padding, 4 - strlen(appname) % 4, *bytes_written, err);
367 /* write end of options */
368 option.type = OPT_ENDOFOPT;
369 option.value_length = 0;
370 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
373 /* write the trailing block total length */
374 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
379 libpcap_write_interface_description_block(FILE *fp,
380 const char *comment, /* OPT_COMMENT 1 */
381 const char *name, /* IDB_NAME 2 */
382 const char *descr, /* IDB_DESCRIPTION 3 */
383 const char *filter, /* IDB_FILTER 11 */
384 const char *os, /* IDB_OS 12 */
388 guint64 if_speed, /* IDB_IF_SPEED 8 */
389 guint8 tsresol, /* IDB_TSRESOL 9 */
393 struct option option;
394 guint32 block_total_length;
395 const guint32 padding = 0;
396 gboolean have_options = FALSE;
398 block_total_length = sizeof(struct idb) + sizeof(guint32);
399 /* 01 - OPT_COMMENT */
400 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
401 block_total_length += sizeof(struct option) +
402 (guint16)ADD_PADDING(strlen(comment));
407 if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
408 block_total_length += sizeof(struct option) +
409 (guint16)ADD_PADDING(strlen(name));
413 /* 03 - IDB_DESCRIPTION */
414 if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) {
415 block_total_length += sizeof(struct option) +
416 (guint16)ADD_PADDING(strlen(descr));
420 /* 08 - IDB_IF_SPEED */
422 block_total_length += sizeof(struct option) + sizeof(guint64);
426 /* 09 - IDB_TSRESOL */
428 block_total_length += sizeof(struct option) + sizeof(struct option);
432 /* 11 - IDB_FILTER */
433 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
434 block_total_length += sizeof(struct option) +
435 (guint16)(ADD_PADDING(strlen(filter)+ 1));
440 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
441 block_total_length += sizeof(struct option) +
442 (guint16)ADD_PADDING(strlen(os));
446 /* If we have options add size of end-of-options */
448 block_total_length += sizeof(struct option);
451 /* write block header */
452 idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE;
453 idb.block_total_length = block_total_length;
454 idb.link_type = link_type;
456 idb.snap_len = snap_len;
457 WRITE_DATA(fp, &idb, sizeof(struct idb), *bytes_written, err);
459 /* 01 - OPT_COMMENT - write comment string if applicable */
460 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
461 option.type = OPT_COMMENT;
462 option.value_length = (guint16)strlen(comment);
463 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
464 WRITE_DATA(fp, comment, strlen(comment), *bytes_written, err);
465 if (strlen(comment) % 4) {
466 WRITE_DATA(fp, &padding, 4 - strlen(comment) % 4 , *bytes_written, err);
470 /* 02 - IDB_NAME - write interface name string if applicable */
471 if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
472 option.type = IDB_NAME;
473 option.value_length = (guint16)strlen(name);
474 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
475 WRITE_DATA(fp, name, strlen(name), *bytes_written, err);
476 if (strlen(name) % 4) {
477 WRITE_DATA(fp, &padding, 4 - strlen(name) % 4 , *bytes_written, err);
481 /* 03 - IDB_DESCRIPTION */
482 /* write interface description string if applicable */
483 if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) {
484 option.type = IDB_DESCRIPTION;
485 option.value_length = (guint16)strlen(descr);
486 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
487 WRITE_DATA(fp, descr, strlen(descr), *bytes_written, err);
488 if (strlen(descr) % 4) {
489 WRITE_DATA(fp, &padding, 4 - strlen(descr) % 4 , *bytes_written, err);
493 /* 08 - IDB_IF_SPEED */
495 option.type = IDB_IF_SPEED;
496 option.value_length = sizeof(guint64);
497 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
498 WRITE_DATA(fp, &if_speed, sizeof(guint64), *bytes_written, err);
501 /* 09 - IDB_TSRESOL */
503 option.type = IDB_TSRESOL;
504 option.value_length = sizeof(guint8);
505 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
506 WRITE_DATA(fp, &tsresol, sizeof(guint8), *bytes_written, err);
507 WRITE_DATA(fp, &padding, 3 , *bytes_written, err);
510 /* 11 - IDB_FILTER - write filter string if applicable
511 * We only write version 1 of the filter, libpcap string
513 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
514 option.type = IDB_FILTER;
515 option.value_length = (guint16)(strlen(filter) + 1 );
516 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
518 /* The first byte of the Option Data keeps a code of the filter used, 0 = lipbpcap filter string */
519 WRITE_DATA(fp, &padding, 1, *bytes_written, err);
520 WRITE_DATA(fp, filter, strlen(filter), *bytes_written, err);
521 if ((strlen(filter) + 1) % 4) {
522 WRITE_DATA(fp, &padding, 4 - (strlen(filter) + 1) % 4 , *bytes_written, err);
526 /* 12 - IDB_OS - write os string if applicable */
527 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
528 option.type = IDB_OS;
529 option.value_length = (guint16)strlen(os);
530 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
531 WRITE_DATA(fp, os, strlen(os), *bytes_written, err);
532 if (strlen(os) % 4) {
533 WRITE_DATA(fp, &padding, 4 - strlen(os) % 4 , *bytes_written, err);
538 /* write end of options */
539 option.type = OPT_ENDOFOPT;
540 option.value_length = 0;
541 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
544 /* write the trailing Block Total Length */
545 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
549 /* Write a record for a packet to a dump file.
550 Returns TRUE on success, FALSE on failure. */
552 libpcap_write_enhanced_packet_block(FILE *fp,
553 const struct pcap_pkthdr *phdr,
554 guint32 interface_id,
561 guint32 block_total_length;
563 const guint32 padding = 0;
565 block_total_length = sizeof(struct epb) +
566 ADD_PADDING(phdr->caplen) +
568 timestamp = (guint64)(phdr->ts.tv_sec) * ts_mul +
569 (guint64)(phdr->ts.tv_usec);
570 epb.block_type = ENHANCED_PACKET_BLOCK_TYPE;
571 epb.block_total_length = block_total_length;
572 epb.interface_id = interface_id;
573 epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
574 epb.timestamp_low = (guint32)(timestamp & 0xffffffff);
575 epb.captured_len = phdr->caplen;
576 epb.packet_len = phdr->len;
577 WRITE_DATA(fp, &epb, sizeof(struct epb), *bytes_written, err);
578 WRITE_DATA(fp, pd, phdr->caplen, *bytes_written, err);
579 if (phdr->caplen % 4) {
580 WRITE_DATA(fp, &padding, 4 - phdr->caplen % 4, *bytes_written, err);
582 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
587 libpcap_write_interface_statistics_block(FILE *fp,
588 guint32 interface_id,
590 const char *comment, /* OPT_COMMENT 1 */
591 guint64 isb_starttime, /* ISB_STARTTIME 2 */
592 guint64 isb_endtime, /* ISB_ENDTIME 3 */
593 guint64 isb_ifrecv, /* ISB_IFRECV 4 */
594 guint64 isb_ifdrop, /* ISB_IFDROP 5 */
603 struct option option;
604 guint32 block_total_length;
606 gboolean have_options = FALSE;
607 const guint32 padding = 0;
610 * Current time, represented as 100-nanosecond intervals since
611 * January 1, 1601, 00:00:00 UTC.
613 * I think DWORD might be signed, so cast both parts of "now"
614 * to guint32 so that the sign bit doesn't get treated specially.
616 * Windows 8 provides GetSystemTimePreciseAsFileTime which we
617 * might want to use instead.
619 GetSystemTimeAsFileTime(&now);
620 timestamp = (((guint64)(guint32)now.dwHighDateTime) << 32) +
621 (guint32)now.dwLowDateTime;
624 * Convert to same thing but as 1-microsecond, i.e. 1000-nanosecond,
630 * Subtract difference, in microseconds, between January 1, 1601
631 * 00:00:00 UTC and January 1, 1970, 00:00:00 UTC.
633 timestamp -= G_GINT64_CONSTANT(11644473600000000U);
636 * Current time, represented as seconds and microseconds since
637 * January 1, 1970, 00:00:00 UTC.
639 gettimeofday(&now, NULL);
642 * Convert to delta in microseconds.
644 timestamp = (guint64)(now.tv_sec) * 1000000 +
645 (guint64)(now.tv_usec);
647 block_total_length = sizeof(struct isb) + sizeof(guint32);
648 if (isb_ifrecv != G_MAXUINT64) {
649 block_total_length += sizeof(struct option) + sizeof(guint64);
652 if (isb_ifdrop != G_MAXUINT64) {
653 block_total_length += sizeof(struct option) + sizeof(guint64);
657 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
658 block_total_length += sizeof(struct option) +
659 (guint16)ADD_PADDING(strlen(comment));
662 if (isb_starttime !=0) {
663 block_total_length += sizeof(struct option) + sizeof(guint64); /* ISB_STARTTIME */
666 if (isb_endtime !=0) {
667 block_total_length += sizeof(struct option) + sizeof(guint64); /* ISB_ENDTIME */
670 /* If we have options add size of end-of-options */
672 block_total_length += sizeof(struct option);
675 isb.block_type = INTERFACE_STATISTICS_BLOCK_TYPE;
676 isb.block_total_length = block_total_length;
677 isb.interface_id = interface_id;
678 isb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
679 isb.timestamp_low = (guint32)(timestamp & 0xffffffff);
680 WRITE_DATA(fp, &isb, sizeof(struct isb), *bytes_written, err);
682 /* write comment string if applicable */
683 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
684 option.type = OPT_COMMENT;
685 option.value_length = (guint16)strlen(comment);
686 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
687 WRITE_DATA(fp, comment, strlen(comment), *bytes_written, err);
688 if (strlen(comment) % 4) {
689 WRITE_DATA(fp, &padding, 4 - strlen(comment) % 4 , *bytes_written, err);
693 if (isb_starttime !=0) {
696 option.type = ISB_STARTTIME;
697 option.value_length = sizeof(guint64);
698 high = (guint32)((isb_starttime>>32) & 0xffffffff);
699 low = (guint32)(isb_starttime & 0xffffffff);
700 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
701 WRITE_DATA(fp, &high, sizeof(guint32), *bytes_written, err);
702 WRITE_DATA(fp, &low, sizeof(guint32), *bytes_written, err);
704 if (isb_endtime !=0) {
707 option.type = ISB_ENDTIME;
708 option.value_length = sizeof(guint64);
709 high = (guint32)((isb_endtime>>32) & 0xffffffff);
710 low = (guint32)(isb_endtime & 0xffffffff);
711 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
712 WRITE_DATA(fp, &high, sizeof(guint32), *bytes_written, err);
713 WRITE_DATA(fp, &low, sizeof(guint32), *bytes_written, err);
715 if (isb_ifrecv != G_MAXUINT64) {
716 option.type = ISB_IFRECV;
717 option.value_length = sizeof(guint64);
718 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
719 WRITE_DATA(fp, &isb_ifrecv, sizeof(guint64), *bytes_written, err);
721 if (isb_ifdrop != G_MAXUINT64) {
722 option.type = ISB_IFDROP;
723 option.value_length = sizeof(guint64);
724 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
725 WRITE_DATA(fp, &isb_ifdrop, sizeof(guint64), *bytes_written, err);
728 /* write end of options */
729 option.type = OPT_ENDOFOPT;
730 option.value_length = 0;
731 WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
734 WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
740 libpcap_dump_flush(FILE *pd, int *err)
742 if (fflush(pd) == EOF) {
751 libpcap_dump_close(FILE *pd, int *err)
753 if (fclose(pd) == EOF) {
761 #endif /* HAVE_LIBPCAP */
764 * Editor modelines - http://www.wireshark.org/tools/modelines.html
769 * indent-tabs-mode: nil
772 * vi: set shiftwidth=4 tabstop=8 expandtab:
773 * :indentSize=4:tabSize=8:noTabs=true: