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.
49 #ifdef HAVE_SYS_TIME_H
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
163 #define SHB_HARDWARE 2 /* currently not used */
165 #define SHB_USERAPPL 4
167 #define IDB_DESCRIPTION 3
168 #define IDB_IF_SPEED 8
169 #define IDB_TSRESOL 9
170 #define IDB_FILTER 11
172 #define ISB_STARTTIME 2
173 #define ISB_ENDTIME 3
176 #define ISB_FILTERACCEPT 6
178 #define ISB_USRDELIV 8
179 #define ADD_PADDING(x) ((((x) + 3) >> 2) << 2)
181 /* Write to capture file */
183 libpcap_write_to_file(FILE* pfile,
186 guint64 *bytes_written,
191 nwritten = fwrite(data, data_length, 1, pfile);
201 (*bytes_written) += data_length;
205 /* Write the file header to a dump file.
206 Returns TRUE on success, FALSE on failure.
207 Sets "*err" to an error code, or 0 for a short write, on failure*/
209 libpcap_write_file_header(FILE* pfile, int linktype, int snaplen, gboolean ts_nsecs, guint64 *bytes_written, int *err)
211 struct pcap_hdr file_hdr;
213 file_hdr.magic = ts_nsecs ? PCAP_NSEC_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;
222 return libpcap_write_to_file(pfile, (const guint8*)&file_hdr, sizeof(file_hdr), bytes_written, err);
225 /* Write a record for a packet to a dump file.
226 Returns TRUE on success, FALSE on failure. */
228 libpcap_write_packet(FILE* pfile,
229 time_t sec, guint32 usec,
230 guint32 caplen, guint32 len,
232 guint64 *bytes_written, int *err)
234 struct pcaprec_hdr rec_hdr;
236 rec_hdr.ts_sec = (guint32)sec; /* Y2.038K issue in pcap format.... */
237 rec_hdr.ts_usec = usec;
238 rec_hdr.incl_len = caplen;
239 rec_hdr.orig_len = len;
240 if (!libpcap_write_to_file(pfile, (const guint8*)&rec_hdr, sizeof(rec_hdr), bytes_written, err))
243 return libpcap_write_to_file(pfile, pd, caplen, bytes_written, err);
247 write_string_option(FILE* pfile,
248 guint16 option_type, const char *option_value,
249 guint64 *bytes_written, int *err)
251 size_t option_value_length;
252 struct option option;
253 const guint32 padding = 0;
255 if (option_value == NULL)
256 return TRUE; /* nothing to write */
257 option_value_length = strlen(option_value);
258 if ((option_value_length > 0) && (option_value_length < G_MAXUINT16)) {
259 /* something to write */
260 option.type = option_type;
261 option.value_length = (guint16)option_value_length;
263 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
266 if (!libpcap_write_to_file(pfile, (const guint8*)option_value, (int) option_value_length, bytes_written, err))
269 if (option_value_length % 4) {
270 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - option_value_length % 4, bytes_written, err))
278 libpcap_write_session_header_block(FILE* pfile,
283 guint64 section_length,
284 guint64 *bytes_written,
288 struct option option;
289 guint32 block_total_length;
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 += (guint32)(sizeof(struct option) +
297 (guint16)ADD_PADDING(strlen(comment)));
300 if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
301 block_total_length += (guint32)(sizeof(struct option) +
302 (guint16)ADD_PADDING(strlen(hw)));
305 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
306 block_total_length += (guint32)(sizeof(struct option) +
307 (guint16)ADD_PADDING(strlen(os)));
310 if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
311 block_total_length += (guint32)(sizeof(struct option) +
312 (guint16)ADD_PADDING(strlen(appname)));
315 /* If we have options add size of end-of-options */
317 block_total_length += (guint32)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;
327 if (!libpcap_write_to_file(pfile, (const guint8*)&shb, sizeof(struct shb), bytes_written, err))
330 if (!write_string_option(pfile, OPT_COMMENT, comment,
333 if (!write_string_option(pfile, SHB_HARDWARE, hw,
336 if (!write_string_option(pfile, SHB_OS, os,
339 if (!write_string_option(pfile, SHB_USERAPPL, appname,
343 /* write end of options */
344 option.type = OPT_ENDOFOPT;
345 option.value_length = 0;
346 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
350 /* write the trailing block total length */
351 return libpcap_write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err);
355 libpcap_write_interface_description_block(FILE* pfile,
356 const char *comment, /* OPT_COMMENT 1 */
357 const char *name, /* IDB_NAME 2 */
358 const char *descr, /* IDB_DESCRIPTION 3 */
359 const char *filter, /* IDB_FILTER 11 */
360 const char *os, /* IDB_OS 12 */
363 guint64 *bytes_written,
364 guint64 if_speed, /* IDB_IF_SPEED 8 */
365 guint8 tsresol, /* IDB_TSRESOL 9 */
369 struct option option;
370 guint32 block_total_length;
371 const guint32 padding = 0;
372 gboolean have_options = FALSE;
374 block_total_length = (guint32)(sizeof(struct idb) + sizeof(guint32));
375 /* 01 - OPT_COMMENT */
376 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
377 block_total_length += (guint32)(sizeof(struct option) +
378 (guint16)ADD_PADDING(strlen(comment)));
383 if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
384 block_total_length += (guint32)(sizeof(struct option) +
385 (guint16)ADD_PADDING(strlen(name)));
389 /* 03 - IDB_DESCRIPTION */
390 if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) {
391 block_total_length += (guint32)(sizeof(struct option) +
392 (guint16)ADD_PADDING(strlen(descr)));
396 /* 08 - IDB_IF_SPEED */
398 block_total_length += (guint32)(sizeof(struct option) +
403 /* 09 - IDB_TSRESOL */
405 block_total_length += (guint32)(sizeof(struct option) +
406 sizeof(struct option));
410 /* 11 - IDB_FILTER */
411 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
412 block_total_length += (guint32)(sizeof(struct option) +
413 (guint16)(ADD_PADDING(strlen(filter)+ 1)));
418 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
419 block_total_length += (guint32)(sizeof(struct option) +
420 (guint16)ADD_PADDING(strlen(os)));
424 /* If we have options add size of end-of-options */
426 block_total_length += (guint32)sizeof(struct option);
429 /* write block header */
430 idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE;
431 idb.block_total_length = block_total_length;
432 idb.link_type = link_type;
434 idb.snap_len = snap_len;
435 if (!libpcap_write_to_file(pfile, (const guint8*)&idb, sizeof(struct idb), bytes_written, err))
438 /* 01 - OPT_COMMENT - write comment string if applicable */
439 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
440 option.type = OPT_COMMENT;
441 option.value_length = (guint16)strlen(comment);
443 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
446 if (!libpcap_write_to_file(pfile, (const guint8*)comment, (int) strlen(comment), bytes_written, err))
449 if (strlen(comment) % 4) {
450 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - strlen(comment) % 4, bytes_written, err))
455 /* 02 - IDB_NAME - write interface name string if applicable */
456 if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) {
457 option.type = IDB_NAME;
458 option.value_length = (guint16)strlen(name);
460 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
463 if (!libpcap_write_to_file(pfile, (const guint8*)name, (int) strlen(name), bytes_written, err))
466 if (strlen(name) % 4) {
467 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - strlen(name) % 4, bytes_written, err))
472 /* 03 - IDB_DESCRIPTION */
473 /* write interface description string if applicable */
474 if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) {
475 option.type = IDB_DESCRIPTION;
476 option.value_length = (guint16)strlen(descr);
478 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
481 if (!libpcap_write_to_file(pfile, (const guint8*)descr, (int) strlen(descr), bytes_written, err))
484 if (strlen(descr) % 4) {
485 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - strlen(descr) % 4, bytes_written, err))
490 /* 08 - IDB_IF_SPEED */
492 option.type = IDB_IF_SPEED;
493 option.value_length = sizeof(guint64);
495 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
498 if (!libpcap_write_to_file(pfile, (const guint8*)&if_speed, sizeof(guint64), bytes_written, err))
502 /* 09 - IDB_TSRESOL */
504 option.type = IDB_TSRESOL;
505 option.value_length = sizeof(guint8);
507 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
510 if (!libpcap_write_to_file(pfile, (const guint8*)&tsresol, sizeof(guint8), bytes_written, err))
513 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 3, bytes_written, err))
517 /* 11 - IDB_FILTER - write filter string if applicable
518 * We only write version 1 of the filter, libpcap string
520 if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) {
521 option.type = IDB_FILTER;
522 option.value_length = (guint16)(strlen(filter) + 1 );
523 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
526 /* The first byte of the Option Data keeps a code of the filter used, 0 = lipbpcap filter string */
527 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 1, bytes_written, err))
529 if (!libpcap_write_to_file(pfile, (const guint8*)filter, (int) strlen(filter), bytes_written, err))
531 if ((strlen(filter) + 1) % 4) {
532 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - (strlen(filter) + 1) % 4, bytes_written, err))
537 /* 12 - IDB_OS - write os string if applicable */
538 if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
539 option.type = IDB_OS;
540 option.value_length = (guint16)strlen(os);
541 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
543 if (!libpcap_write_to_file(pfile, (const guint8*)os, (int) strlen(os), bytes_written, err))
545 if (strlen(os) % 4) {
546 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - strlen(os) % 4, bytes_written, err))
552 /* write end of options */
553 option.type = OPT_ENDOFOPT;
554 option.value_length = 0;
555 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
559 /* write the trailing Block Total Length */
560 return libpcap_write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err);
563 /* Write a record for a packet to a dump file.
564 Returns TRUE on success, FALSE on failure. */
566 libpcap_write_enhanced_packet_block(FILE* pfile,
568 time_t sec, guint32 usec,
569 guint32 caplen, guint32 len,
570 guint32 interface_id,
574 guint64 *bytes_written,
578 struct option option;
579 guint32 block_total_length;
581 gboolean have_options = FALSE;
582 const guint32 padding = 0;
584 block_total_length = (guint32)(sizeof(struct epb) +
585 ADD_PADDING(caplen) +
587 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
588 block_total_length += (guint32)(sizeof(struct option) +
589 (guint16)ADD_PADDING(strlen(comment)));
593 block_total_length += (guint32)(sizeof(struct option) +
597 /* If we have options add size of end-of-options */
599 block_total_length += (guint32)sizeof(struct option);
601 timestamp = (guint64)sec * ts_mul + (guint64)usec;
602 epb.block_type = ENHANCED_PACKET_BLOCK_TYPE;
603 epb.block_total_length = block_total_length;
604 epb.interface_id = interface_id;
605 epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
606 epb.timestamp_low = (guint32)(timestamp & 0xffffffff);
607 epb.captured_len = caplen;
608 epb.packet_len = len;
609 if (!libpcap_write_to_file(pfile, (const guint8*)&epb, sizeof(struct epb), bytes_written, err))
611 if (!libpcap_write_to_file(pfile, pd, caplen, bytes_written, err))
614 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - caplen % 4, bytes_written, err))
617 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
618 option.type = OPT_COMMENT;
619 option.value_length = (guint16)strlen(comment);
621 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
624 if (!libpcap_write_to_file(pfile, (const guint8*)comment, (int) strlen(comment), bytes_written, err))
627 if (strlen(comment) % 4) {
628 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - strlen(comment) % 4, bytes_written, err))
633 option.type = EPB_FLAGS;
634 option.value_length = sizeof(guint32);
635 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
637 if (!libpcap_write_to_file(pfile, (const guint8*)&flags, sizeof(guint32), bytes_written, err))
639 option.type = OPT_ENDOFOPT;
640 option.value_length = 0;
641 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
645 return libpcap_write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err);
649 libpcap_write_interface_statistics_block(FILE* pfile,
650 guint32 interface_id,
651 guint64 *bytes_written,
652 const char *comment, /* OPT_COMMENT 1 */
653 guint64 isb_starttime, /* ISB_STARTTIME 2 */
654 guint64 isb_endtime, /* ISB_ENDTIME 3 */
655 guint64 isb_ifrecv, /* ISB_IFRECV 4 */
656 guint64 isb_ifdrop, /* ISB_IFDROP 5 */
665 struct option option;
666 guint32 block_total_length;
668 gboolean have_options = FALSE;
669 const guint32 padding = 0;
672 * Current time, represented as 100-nanosecond intervals since
673 * January 1, 1601, 00:00:00 UTC.
675 * I think DWORD might be signed, so cast both parts of "now"
676 * to guint32 so that the sign bit doesn't get treated specially.
678 * Windows 8 provides GetSystemTimePreciseAsFileTime which we
679 * might want to use instead.
681 GetSystemTimeAsFileTime(&now);
682 timestamp = (((guint64)(guint32)now.dwHighDateTime) << 32) +
683 (guint32)now.dwLowDateTime;
686 * Convert to same thing but as 1-microsecond, i.e. 1000-nanosecond,
692 * Subtract difference, in microseconds, between January 1, 1601
693 * 00:00:00 UTC and January 1, 1970, 00:00:00 UTC.
695 timestamp -= G_GINT64_CONSTANT(11644473600000000U);
698 * Current time, represented as seconds and microseconds since
699 * January 1, 1970, 00:00:00 UTC.
701 gettimeofday(&now, NULL);
704 * Convert to delta in microseconds.
706 timestamp = (guint64)(now.tv_sec) * 1000000 +
707 (guint64)(now.tv_usec);
709 block_total_length = (guint32)(sizeof(struct isb) + sizeof(guint32));
710 if (isb_ifrecv != G_MAXUINT64) {
711 block_total_length += (guint32)(sizeof(struct option) +
715 if (isb_ifdrop != G_MAXUINT64) {
716 block_total_length += (guint32)(sizeof(struct option) +
721 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
722 block_total_length += (guint32)(sizeof(struct option) +
723 (guint16)ADD_PADDING(strlen(comment)));
726 if (isb_starttime !=0) {
727 block_total_length += (guint32)(sizeof(struct option) +
728 sizeof(guint64)); /* ISB_STARTTIME */
731 if (isb_endtime !=0) {
732 block_total_length += (guint32)(sizeof(struct option) +
733 sizeof(guint64)); /* ISB_ENDTIME */
736 /* If we have options add size of end-of-options */
738 block_total_length += (guint32)sizeof(struct option);
741 isb.block_type = INTERFACE_STATISTICS_BLOCK_TYPE;
742 isb.block_total_length = block_total_length;
743 isb.interface_id = interface_id;
744 isb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff);
745 isb.timestamp_low = (guint32)(timestamp & 0xffffffff);
746 if (!libpcap_write_to_file(pfile, (const guint8*)&isb, sizeof(struct isb), bytes_written, err))
749 /* write comment string if applicable */
750 if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
751 option.type = OPT_COMMENT;
752 option.value_length = (guint16)strlen(comment);
753 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
756 if (!libpcap_write_to_file(pfile, (const guint8*)comment, (int) strlen(comment), bytes_written, err))
759 if (strlen(comment) % 4) {
760 if (!libpcap_write_to_file(pfile, (const guint8*)&padding, 4 - strlen(comment) % 4, bytes_written, err))
765 if (isb_starttime !=0) {
768 option.type = ISB_STARTTIME;
769 option.value_length = sizeof(guint64);
770 high = (guint32)((isb_starttime>>32) & 0xffffffff);
771 low = (guint32)(isb_starttime & 0xffffffff);
772 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
775 if (!libpcap_write_to_file(pfile, (const guint8*)&high, sizeof(guint32), bytes_written, err))
778 if (!libpcap_write_to_file(pfile, (const guint8*)&low, sizeof(guint32), bytes_written, err))
781 if (isb_endtime !=0) {
784 option.type = ISB_ENDTIME;
785 option.value_length = sizeof(guint64);
786 high = (guint32)((isb_endtime>>32) & 0xffffffff);
787 low = (guint32)(isb_endtime & 0xffffffff);
788 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
791 if (!libpcap_write_to_file(pfile, (const guint8*)&high, sizeof(guint32), bytes_written, err))
794 if (!libpcap_write_to_file(pfile, (const guint8*)&low, sizeof(guint32), bytes_written, err))
797 if (isb_ifrecv != G_MAXUINT64) {
798 option.type = ISB_IFRECV;
799 option.value_length = sizeof(guint64);
800 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
803 if (!libpcap_write_to_file(pfile, (const guint8*)&isb_ifrecv, sizeof(guint64), bytes_written, err))
806 if (isb_ifdrop != G_MAXUINT64) {
807 option.type = ISB_IFDROP;
808 option.value_length = sizeof(guint64);
809 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
812 if (!libpcap_write_to_file(pfile, (const guint8*)&isb_ifdrop, sizeof(guint64), bytes_written, err))
816 /* write end of options */
817 option.type = OPT_ENDOFOPT;
818 option.value_length = 0;
819 if (!libpcap_write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err))
823 return libpcap_write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err);
827 * Editor modelines - http://www.wireshark.org/tools/modelines.html
832 * indent-tabs-mode: nil
835 * vi: set shiftwidth=4 tabstop=8 expandtab:
836 * :indentSize=4:tabSize=8:noTabs=true: