2 * Reports capture file information including # of packets, duration, others
4 * Copyright 2004 Ian Schorr
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
16 * New capinfos features
18 * Continue processing additional files after
19 * a wiretap open failure. The new -C option
20 * reverts to capinfos' original behavior which
21 * is to cancel any further file processing at
22 * first file open failure.
24 * Change the behavior of how the default display
25 * of all infos is initiated. This gets rid of a
26 * special post getopt() argument count test.
28 * Add new table output format (with related options)
29 * This feature allows outputting the various infos
30 * into a tab delimited text file, or to a comma
31 * separated variables file (*.csv) instead of the
32 * original "long" format.
35 * behaviour changed: Upon exit capinfos will return
36 * an error status if an error occurred at any
37 * point during "continuous" file processing.
38 * (Previously a success status was always
39 * returned if the -C option was not used).
45 #define WS_LOG_DOMAIN LOG_DOMAIN_MAIN
53 #include <ws_exit_codes.h>
54 #include <wsutil/ws_getopt.h>
58 #include <wiretap/wtap.h>
60 #include <wsutil/cmdarg_err.h>
61 #include <wsutil/filesystem.h>
62 #include <wsutil/privileges.h>
64 #include <wsutil/version_info.h>
65 #include <wiretap/wtap_opttypes.h>
68 #include <wsutil/plugins.h>
71 #include <wsutil/str_util.h>
72 #include <wsutil/to_str.h>
73 #include <wsutil/file_util.h>
74 #include <wsutil/ws_assert.h>
75 #include <wsutil/wslog.h>
79 #include "ui/failure_message.h"
82 * By default capinfos now continues processing
83 * the next filename if and when wiretap detects
84 * a problem opening or reading a file.
85 * Use the '-C' option to revert back to original
86 * capinfos behavior which is to abort any
87 * additional file processing at the first file
88 * open or read failure.
91 static bool stop_after_failure
;
94 * table report variables
97 static bool long_report
= true; /* By default generate long report */
98 static bool table_report_header
= true; /* Generate column header by default */
99 static char field_separator
= '\t'; /* Use TAB as field separator by default */
100 static char quote_char
= '\0'; /* Do NOT quote fields by default */
101 static bool machine_readable
; /* Display machine-readable numbers */
104 * capinfos has the ability to report on a number of
105 * various characteristics ("infos") for each input file.
107 * By default reporting of all info fields is enabled.
109 * Optionally the reporting of any specific info field
110 * or combination of info fields can be enabled with
111 * individual options.
114 static bool report_all_infos
= true; /* Report all infos */
116 static bool cap_file_type
= true; /* Report capture type */
117 static bool cap_file_encap
= true; /* Report encapsulation */
118 static bool cap_snaplen
= true; /* Packet size limit (snaplen)*/
119 static bool cap_packet_count
= true; /* Report packet count */
120 static bool cap_file_size
= true; /* Report file size */
121 static bool cap_comment
= true; /* Display the capture comment */
122 static bool cap_file_more_info
= true; /* Report more file info */
123 static bool cap_file_idb
= true; /* Report Interface info */
124 static bool cap_file_nrb
= true; /* Report Name Resolution Block info */
125 static bool cap_file_dsb
= true; /* Report Decryption Secrets Block info */
127 static bool cap_data_size
= true; /* Report packet byte size */
128 static bool cap_duration
= true; /* Report capture duration */
129 static bool cap_earliest_packet_time
= true; /* Report timestamp of earliest packet */
130 static bool cap_latest_packet_time
= true; /* Report timestamp of latest packet */
131 static bool time_as_secs
; /* Report time values as raw seconds */
133 static bool cap_data_rate_byte
= true; /* Report data rate bytes/sec */
134 static bool cap_data_rate_bit
= true; /* Report data rate bites/sec */
135 static bool cap_packet_size
= true; /* Report average packet size */
136 static bool cap_packet_rate
= true; /* Report average packet rate */
137 static bool cap_order
= true; /* Report if packets are in chronological order (True/False) */
138 static bool pkt_comments
= true; /* Report individual packet comments */
140 static bool cap_file_hashes
= true; /* Calculate file hashes */
142 // Strongest to weakest
143 #define HASH_SIZE_SHA256 32
144 #define HASH_SIZE_SHA1 20
146 #define HASH_STR_SIZE (65) /* Max hash size * 2 + '\0' */
147 #define HASH_BUF_SIZE (1024 * 1024)
150 static char file_sha256
[HASH_STR_SIZE
];
151 static char file_sha1
[HASH_STR_SIZE
];
153 static char *hash_buf
;
154 static gcry_md_hd_t hd
;
156 static unsigned int num_ipv4_addresses
;
157 static unsigned int num_ipv6_addresses
;
158 static unsigned int num_decryption_secrets
;
161 * If we have at least two packets with time stamps, and they're not in
162 * order - i.e., the later packet has a time stamp older than the earlier
163 * packet - the time stamps are known not to be in order.
165 * If every packet has a time stamp, and they're all in order, the time
166 * stamp is known to be in order.
168 * Otherwise, we have no idea.
176 typedef struct _pkt_cmt
{
179 struct _pkt_cmt
*next
;
182 typedef struct _capture_info
{
183 const char *filename
;
185 wtap_compression_type compression_type
;
190 uint64_t packet_bytes
;
192 nstime_t earliest_packet_time
;
193 int earliest_packet_time_tsprec
;
194 nstime_t latest_packet_time
;
195 int latest_packet_time_tsprec
;
196 uint32_t packet_count
;
197 bool snap_set
; /* If set in capture file header */
198 uint32_t snaplen
; /* value from the capture file header */
199 uint32_t snaplen_min_inferred
; /* If caplen < len for 1 or more rcds */
200 uint32_t snaplen_max_inferred
; /* ... */
208 double data_rate
; /* in bytes/s */
212 int *encap_counts
; /* array of per_packet encap counts; array has one entry per wtap_encap type */
213 pkt_cmt
*pkt_cmts
; /* list of packet comments */
215 unsigned int num_interfaces
; /* number of IDBs, and thus size of interface_packet_counts array */
216 GArray
*interface_packet_counts
; /* array of per_packet interface_id counts; one entry per file IDB */
217 uint32_t pkt_interface_id_unknown
; /* counts if packet interface_id didn't match a known one */
218 GArray
*idb_info_strings
; /* array of IDB info strings */
221 static char *decimal_point
;
224 enable_all_infos(void)
226 report_all_infos
= true;
228 cap_file_type
= true;
229 cap_file_encap
= true;
231 cap_packet_count
= true;
232 cap_file_size
= true;
235 cap_file_more_info
= true;
240 cap_data_size
= true;
242 cap_earliest_packet_time
= true;
243 cap_latest_packet_time
= true;
246 cap_data_rate_byte
= true;
247 cap_data_rate_bit
= true;
248 cap_packet_size
= true;
249 cap_packet_rate
= true;
251 cap_file_hashes
= true;
255 disable_all_infos(void)
257 report_all_infos
= false;
259 cap_file_type
= false;
260 cap_file_encap
= false;
262 cap_packet_count
= false;
263 cap_file_size
= false;
265 pkt_comments
= false;
266 cap_file_more_info
= false;
267 cap_file_idb
= false;
268 cap_file_nrb
= false;
269 cap_file_dsb
= false;
271 cap_data_size
= false;
272 cap_duration
= false;
273 cap_earliest_packet_time
= false;
274 cap_latest_packet_time
= false;
277 cap_data_rate_byte
= false;
278 cap_data_rate_bit
= false;
279 cap_packet_size
= false;
280 cap_packet_rate
= false;
282 cap_file_hashes
= false;
286 order_string(order_t order
)
300 return "???"; /* "cannot happen" (the next step is "Profit!") */
305 absolute_time_string(nstime_t
*timer
, int tsprecision
, capture_info
*cf_info
)
308 * https://web.archive.org/web/20120513133703/http://www.idrbt.ac.in/publications/workingpapers/Working%20Paper%20No.%209.pdf
312 * A 64-bit Unix time would be safe for the indefinite future, as
313 * this variable would not overflow until 2**63 or
314 * 9,223,372,036,854,775,808 (over nine quintillion) seconds
315 * after the beginning of the Unix epoch - corresponding to
316 * GMT 15:30:08, Sunday, 4th December, 292,277,026,596.
318 * So, if we're displaying the time as YYYY-MM-DD HH:MM:SS.SSSSSSSSS,
319 * we'll have the buffer be large enough for a date of the format
320 * 292277026596-MM-DD HH:MM:SS.SSSSSSSSS, which is the biggest value
321 * you'll get with a 64-bit time_t and a nanosecond-resolution
322 * fraction-of-a-second.
324 * That's 12+1+2+1+2+1+2+1+2+2+2+1+9+1, including the terminating
327 * If we're displaying the time as epoch time, and the time is
328 * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
329 * to be big enough for 18446744073709551615.999999999. That's
330 * 20+1+9+1, including the terminating '\0', or 31. If it's
331 * signed, 2^63 is 9223372036854775808, so the buffer has to
332 * be big enough for -9223372036854775808.999999999, which is
333 * again 20+1+9+1, or 31.
337 static char time_string_buf
[39];
339 if (cf_info
->times_known
&& cf_info
->packet_count
> 0) {
341 display_epoch_time(time_string_buf
, sizeof time_string_buf
, timer
, tsprecision
);
343 format_nstime_as_iso8601(time_string_buf
, sizeof time_string_buf
, timer
, decimal_point
, true, tsprecision
);
346 snprintf(time_string_buf
, sizeof time_string_buf
, "n/a");
348 return time_string_buf
;
352 relative_time_string(nstime_t
*timer
, int tsprecision
, capture_info
*cf_info
, bool want_seconds
)
354 const char *second
= want_seconds
? " second" : "";
355 const char *plural
= want_seconds
? "s" : "";
357 * If we're displaying the time as epoch time, and the time is
358 * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
359 * to be big enough for "18446744073709551615.999999999 seconds".
360 * That's 20+1+9+1+7+1, including the terminating '\0', or 39.
361 * If it'ssigned, 2^63 is 9223372036854775808, so the buffer has to
362 * be big enough for "-9223372036854775808.999999999 seconds",
363 * which is again 20+1+9+1+7+1, or 39.
365 static char time_string_buf
[39];
367 if (cf_info
->times_known
&& cf_info
->packet_count
> 0) {
372 ptr
= time_string_buf
;
373 remaining
= sizeof time_string_buf
;
374 num_bytes
= snprintf(ptr
, remaining
,
376 (int64_t)timer
->secs
);
380 * Not much else we can do.
382 snprintf(ptr
, remaining
, "snprintf() failed");
383 return time_string_buf
;
385 if ((unsigned int)num_bytes
>= remaining
) {
387 * That filled up or would have overflowed the buffer.
388 * Nothing more we can do.
390 return time_string_buf
;
393 remaining
-= num_bytes
;
395 if (tsprecision
!= 0) {
397 * Append the fractional part.
399 num_bytes
= format_fractional_part_nsecs(ptr
, remaining
, timer
->nsecs
, decimal_point
, tsprecision
);
400 if ((unsigned int)num_bytes
>= remaining
) {
402 * That filled up or would have overflowed the buffer.
403 * Nothing more we can do.
405 return time_string_buf
;
408 remaining
-= num_bytes
;
414 snprintf(ptr
, remaining
, "%s%s",
416 timer
->secs
== 1 ? "" : plural
);
418 return time_string_buf
;
421 snprintf(time_string_buf
, sizeof time_string_buf
, "n/a");
422 return time_string_buf
;
425 static void print_value(const char *text_p1
, int width
, const char *text_p2
, double value
)
428 printf("%s%.*f%s\n", text_p1
, width
, value
, text_p2
);
430 printf("%sn/a\n", text_p1
);
433 /* multi-line comments would conflict with the formatting that capinfos uses
434 we replace linefeeds with spaces */
436 string_replace_newlines(char *str
)
453 show_option_string(const char *prefix
, const char *option_str
)
457 if (option_str
!= NULL
&& option_str
[0] != '\0') {
458 str
= g_strdup(option_str
);
459 string_replace_newlines(str
);
460 printf("%s%s\n", prefix
, str
);
466 print_stats(const char *filename
, capture_info
*cf_info
)
468 const char *file_type_string
, *file_encap_string
;
472 /* Build printable strings for various stats */
473 if (machine_readable
) {
474 file_type_string
= wtap_file_type_subtype_name(cf_info
->file_type
);
475 file_encap_string
= wtap_encap_name(cf_info
->file_encap
);
478 file_type_string
= wtap_file_type_subtype_description(cf_info
->file_type
);
479 file_encap_string
= wtap_encap_description(cf_info
->file_encap
);
482 if (filename
) printf ("File name: %s\n", filename
);
484 const char *compression_type_description
;
485 compression_type_description
= wtap_compression_type_description(cf_info
->compression_type
);
486 if (compression_type_description
== NULL
)
487 printf ("File type: %s\n",
490 printf ("File type: %s (%s)\n",
491 file_type_string
, compression_type_description
);
493 if (cap_file_encap
) {
494 printf ("File encapsulation: %s\n", file_encap_string
);
495 if (cf_info
->file_encap
== WTAP_ENCAP_PER_PACKET
) {
497 printf ("Encapsulation in use by packets (# of pkts):\n");
498 for (i
=0; i
<WTAP_NUM_ENCAP_TYPES
; i
++) {
499 if (cf_info
->encap_counts
[i
] > 0)
501 wtap_encap_description(i
), cf_info
->encap_counts
[i
]);
505 if (cap_file_more_info
) {
506 printf ("File timestamp precision: %s (%d)\n",
507 wtap_tsprec_string(cf_info
->file_tsprec
), cf_info
->file_tsprec
);
510 if (cap_snaplen
&& cf_info
->snap_set
)
511 printf ("Packet size limit: file hdr: %u bytes\n", cf_info
->snaplen
);
512 else if (cap_snaplen
&& !cf_info
->snap_set
)
513 printf ("Packet size limit: file hdr: (not set)\n");
514 if (cf_info
->snaplen_max_inferred
> 0) {
515 if (cf_info
->snaplen_min_inferred
== cf_info
->snaplen_max_inferred
)
516 printf ("Packet size limit: inferred: %u bytes\n", cf_info
->snaplen_min_inferred
);
518 printf ("Packet size limit: inferred: %u bytes - %u bytes (range)\n",
519 cf_info
->snaplen_min_inferred
, cf_info
->snaplen_max_inferred
);
521 if (cap_packet_count
) {
522 printf ("Number of packets: ");
523 if (machine_readable
) {
524 printf ("%u\n", cf_info
->packet_count
);
526 size_string
= format_size(cf_info
->packet_count
, FORMAT_SIZE_UNIT_NONE
, 0);
527 printf ("%s\n", size_string
);
532 printf ("File size: ");
533 if (machine_readable
) {
534 printf ("%" PRId64
" bytes\n", cf_info
->filesize
);
536 size_string
= format_size(cf_info
->filesize
, FORMAT_SIZE_UNIT_BYTES
, 0);
537 printf ("%s\n", size_string
);
542 printf ("Data size: ");
543 if (machine_readable
) {
544 printf ("%" PRIu64
" bytes\n", cf_info
->packet_bytes
);
546 size_string
= format_size(cf_info
->packet_bytes
, FORMAT_SIZE_UNIT_BYTES
, 0);
547 printf ("%s\n", size_string
);
551 if (cf_info
->times_known
) {
552 if (cap_duration
) /* XXX - shorten to hh:mm:ss */
553 printf("Capture duration: %s\n", relative_time_string(&cf_info
->duration
, cf_info
->duration_tsprec
, cf_info
, true));
554 if (cap_earliest_packet_time
)
555 printf("Earliest packet time: %s\n", absolute_time_string(&cf_info
->earliest_packet_time
, cf_info
->earliest_packet_time_tsprec
, cf_info
));
556 if (cap_latest_packet_time
)
557 printf("Latest packet time: %s\n", absolute_time_string(&cf_info
->latest_packet_time
, cf_info
->latest_packet_time_tsprec
, cf_info
));
558 if (cap_data_rate_byte
) {
559 printf("Data byte rate: ");
560 if (machine_readable
) {
561 print_value("", 2, " bytes/sec", cf_info
->data_rate
);
563 size_string
= format_size((int64_t)cf_info
->data_rate
, FORMAT_SIZE_UNIT_BYTES_S
, 0);
564 printf ("%s\n", size_string
);
568 if (cap_data_rate_bit
) {
569 printf("Data bit rate: ");
570 if (machine_readable
) {
571 print_value("", 2, " bits/sec", cf_info
->data_rate
*8);
573 size_string
= format_size((int64_t)(cf_info
->data_rate
*8), FORMAT_SIZE_UNIT_BITS_S
, 0);
574 printf ("%s\n", size_string
);
579 if (cap_packet_size
) printf("Average packet size: %.2f bytes\n", cf_info
->packet_size
);
580 if (cf_info
->times_known
) {
581 if (cap_packet_rate
) {
582 printf("Average packet rate: ");
583 if (machine_readable
) {
584 print_value("", 2, " packets/sec", cf_info
->packet_rate
);
586 size_string
= format_size((int64_t)cf_info
->packet_rate
, FORMAT_SIZE_UNIT_PACKETS_S
, 0);
587 printf ("%s\n", size_string
);
592 if (cap_file_hashes
) {
593 printf ("SHA256: %s\n", file_sha256
);
594 printf ("SHA1: %s\n", file_sha1
);
596 if (cap_order
) printf ("Strict time order: %s\n", order_string(cf_info
->order
));
598 bool has_multiple_sections
= (wtap_file_get_num_shbs(cf_info
->wth
) > 1);
600 for (unsigned int section_number
= 0;
601 section_number
< wtap_file_get_num_shbs(cf_info
->wth
);
605 // If we have more than one section, add headers for each section.
606 if (has_multiple_sections
)
607 printf("Section %u:\n\n", section_number
);
609 shb
= wtap_file_get_shb(cf_info
->wth
, section_number
);
611 if (cap_file_more_info
) {
614 if (wtap_block_get_string_option_value(shb
, OPT_SHB_HARDWARE
, &str
) == WTAP_OPTTYPE_SUCCESS
)
615 show_option_string("Capture hardware: ", str
);
616 if (wtap_block_get_string_option_value(shb
, OPT_SHB_OS
, &str
) == WTAP_OPTTYPE_SUCCESS
)
617 show_option_string("Capture oper-sys: ", str
);
618 if (wtap_block_get_string_option_value(shb
, OPT_SHB_USERAPPL
, &str
) == WTAP_OPTTYPE_SUCCESS
)
619 show_option_string("Capture application: ", str
);
625 for (i
= 0; wtap_block_get_nth_string_option_value(shb
, OPT_COMMENT
, i
, &str
) == WTAP_OPTTYPE_SUCCESS
; i
++) {
626 show_option_string("Capture comment: ", str
);
632 if (pkt_comments
&& cf_info
->pkt_cmts
!= NULL
) {
633 for (p
= cf_info
->pkt_cmts
; p
!= NULL
; prev
= p
, p
= p
->next
, g_free(prev
)) {
634 if (machine_readable
){
635 printf("Packet %d Comment: %s\n", p
->recno
, g_strescape(p
->cmt
, NULL
));
637 printf("Packet %d Comment: %s\n", p
->recno
, p
->cmt
);
643 if (cap_file_idb
&& cf_info
->num_interfaces
!= 0) {
645 ws_assert(cf_info
->num_interfaces
== cf_info
->idb_info_strings
->len
);
646 printf ("Number of interfaces in file: %u\n", cf_info
->num_interfaces
);
647 for (i
= 0; i
< cf_info
->idb_info_strings
->len
; i
++) {
648 char *s
= g_array_index(cf_info
->idb_info_strings
, char*, i
);
649 uint32_t packet_count
= 0;
650 if (i
< cf_info
->interface_packet_counts
->len
)
651 packet_count
= g_array_index(cf_info
->interface_packet_counts
, uint32_t, i
);
652 printf ("Interface #%u info:\n", i
);
654 printf (" Number of packets = %u\n", packet_count
);
659 if (num_ipv4_addresses
!= 0)
660 printf ("Number of resolved IPv4 addresses in file: %u\n", num_ipv4_addresses
);
661 if (num_ipv6_addresses
!= 0)
662 printf ("Number of resolved IPv6 addresses in file: %u\n", num_ipv6_addresses
);
665 if (num_decryption_secrets
!= 0)
666 printf ("Number of decryption secrets in file: %u\n", num_decryption_secrets
);
673 if (field_separator
) putchar(field_separator
);
679 if (quote_char
) putchar(quote_char
);
683 print_stats_table_header_label(const char *label
)
692 print_stats_table_header(capture_info
*cf_info
)
702 if (cap_file_type
) print_stats_table_header_label("File type");
703 if (cap_file_encap
) print_stats_table_header_label("File encapsulation");
704 if (cap_file_more_info
) print_stats_table_header_label("File time precision");
706 print_stats_table_header_label("Packet size limit");
707 print_stats_table_header_label("Packet size limit min (inferred)");
708 print_stats_table_header_label("Packet size limit max (inferred)");
710 if (cap_packet_count
) print_stats_table_header_label("Number of packets");
711 if (cap_file_size
) print_stats_table_header_label("File size (bytes)");
712 if (cap_data_size
) print_stats_table_header_label("Data size (bytes)");
713 if (cap_duration
) print_stats_table_header_label("Capture duration (seconds)");
714 if (cap_earliest_packet_time
) print_stats_table_header_label("Start time");
715 if (cap_latest_packet_time
) print_stats_table_header_label("End time");
716 if (cap_data_rate_byte
) print_stats_table_header_label("Data byte rate (bytes/sec)");
717 if (cap_data_rate_bit
) print_stats_table_header_label("Data bit rate (bits/sec)");
718 if (cap_packet_size
) print_stats_table_header_label("Average packet size (bytes)");
719 if (cap_packet_rate
) print_stats_table_header_label("Average packet rate (packets/sec)");
720 if (cap_file_hashes
) {
721 print_stats_table_header_label("SHA256");
722 print_stats_table_header_label("SHA1");
724 if (cap_order
) print_stats_table_header_label("Strict time order");
725 if (cap_file_more_info
) {
726 print_stats_table_header_label("Capture hardware");
727 print_stats_table_header_label("Capture oper-sys");
728 print_stats_table_header_label("Capture application");
730 if (cap_comment
) print_stats_table_header_label("Capture comment");
732 if (pkt_comments
&& cf_info
->pkt_cmts
!= NULL
) {
733 /* Packet 2^64 Comment" + NULL */
734 buf_len
= strlen("Packet 18446744073709551616 Comment") + 1;
735 buf
= (char *)g_malloc0(buf_len
);
737 for (p
= cf_info
->pkt_cmts
; p
!= NULL
; p
= p
->next
) {
738 snprintf(buf
, buf_len
, "Packet %d Comment", p
->recno
);
739 print_stats_table_header_label(buf
);
747 print_stats_table(const char *filename
, capture_info
*cf_info
)
749 const char *file_type_string
, *file_encap_string
;
752 /* Build printable strings for various stats */
753 file_type_string
= wtap_file_type_subtype_name(cf_info
->file_type
);
754 file_encap_string
= wtap_encap_name(cf_info
->file_encap
);
758 printf("%s", filename
);
765 printf("%s", file_type_string
);
769 /* ToDo: If WTAP_ENCAP_PER_PACKET, show the list of encapsulations encountered;
770 * Output a line for each different encap with all fields repeated except
771 * the encapsulation field which has "Per Packet: ..." for each
772 * encapsulation type seen ?
774 if (cap_file_encap
) {
777 printf("%s", file_encap_string
);
781 if (cap_file_more_info
) {
784 printf("%s", wtap_tsprec_string(cf_info
->file_tsprec
));
791 if (cf_info
->snap_set
)
792 printf("%u", cf_info
->snaplen
);
796 if (cf_info
->snaplen_max_inferred
> 0) {
799 printf("%u", cf_info
->snaplen_min_inferred
);
803 printf("%u", cf_info
->snaplen_max_inferred
);
818 if (cap_packet_count
) {
821 printf("%u", cf_info
->packet_count
);
828 printf("%" PRId64
, cf_info
->filesize
);
835 printf("%" PRIu64
, cf_info
->packet_bytes
);
842 printf("%s", relative_time_string(&cf_info
->duration
, cf_info
->duration_tsprec
, cf_info
, false));
846 if (cap_earliest_packet_time
) {
849 printf("%s", absolute_time_string(&cf_info
->earliest_packet_time
, cf_info
->earliest_packet_time_tsprec
, cf_info
));
853 if (cap_latest_packet_time
) {
856 printf("%s", absolute_time_string(&cf_info
->latest_packet_time
, cf_info
->latest_packet_time_tsprec
, cf_info
));
860 if (cap_data_rate_byte
) {
863 if (cf_info
->times_known
)
864 printf("%.2f", cf_info
->data_rate
);
870 if (cap_data_rate_bit
) {
873 if (cf_info
->times_known
)
874 printf("%.2f", cf_info
->data_rate
*8);
880 if (cap_packet_size
) {
883 printf("%.2f", cf_info
->packet_size
);
887 if (cap_packet_rate
) {
890 if (cf_info
->times_known
)
891 printf("%.2f", cf_info
->packet_rate
);
897 if (cap_file_hashes
) {
900 printf("%s", file_sha256
);
905 printf("%s", file_sha1
);
912 printf("%s", order_string(cf_info
->order
));
916 for (unsigned section_number
= 0;
917 section_number
< wtap_file_get_num_shbs(cf_info
->wth
);
921 shb
= wtap_file_get_shb(cf_info
->wth
, section_number
);
922 if (cap_file_more_info
) {
927 if (wtap_block_get_string_option_value(shb
, OPT_SHB_HARDWARE
, &str
) == WTAP_OPTTYPE_SUCCESS
) {
934 if (wtap_block_get_string_option_value(shb
, OPT_SHB_OS
, &str
) == WTAP_OPTTYPE_SUCCESS
) {
941 if (wtap_block_get_string_option_value(shb
, OPT_SHB_USERAPPL
, &str
) == WTAP_OPTTYPE_SUCCESS
) {
948 * One might argue that the following is silly to put into a table format,
949 * but oh well note that there may be *more than one* of each of these types
950 * of options. To mitigate some of the potential silliness the if(cap_comment)
951 * block is moved AFTER the if(cap_file_more_info) block. This will make any
952 * comments the last item(s) in each row. We now have a new -K option to
953 * disable cap_comment to more easily manage the potential silliness.
954 * Potential silliness includes multiple comments (therefore resulting in
955 * more than one additional column and/or comments with embedded newlines
956 * and/or possible delimiters).
958 * To mitigate embedded newlines and other special characters, use -M
963 bool have_cap
= false;
965 for (i
= 0; wtap_block_get_nth_string_option_value(shb
, OPT_COMMENT
, i
, &opt_comment
) == WTAP_OPTTYPE_SUCCESS
; i
++) {
969 if (machine_readable
){
970 printf("%s", g_strescape(opt_comment
, NULL
));
972 printf("%s", opt_comment
);
977 /* Maintain column alignment when we have no OPT_COMMENT */
986 if (pkt_comments
&& cf_info
->pkt_cmts
!= NULL
) {
987 for(p
= cf_info
->pkt_cmts
; p
!= NULL
; prev
= p
, p
= p
->next
, g_free(prev
)) {
990 if (machine_readable
) {
991 printf("%s", g_strescape(p
->cmt
, NULL
));
993 printf("%s", p
->cmt
);
1004 cleanup_capture_info(capture_info
*cf_info
)
1007 ws_assert(cf_info
!= NULL
);
1009 g_free(cf_info
->encap_counts
);
1010 cf_info
->encap_counts
= NULL
;
1012 g_array_free(cf_info
->interface_packet_counts
, true);
1013 cf_info
->interface_packet_counts
= NULL
;
1015 if (cf_info
->idb_info_strings
) {
1016 for (i
= 0; i
< cf_info
->idb_info_strings
->len
; i
++) {
1017 char *s
= g_array_index(cf_info
->idb_info_strings
, char*, i
);
1020 g_array_free(cf_info
->idb_info_strings
, true);
1022 cf_info
->idb_info_strings
= NULL
;
1026 count_ipv4_address(const unsigned int addr _U_
, const char *name _U_
, const bool static_entry _U_
)
1028 num_ipv4_addresses
++;
1032 count_ipv6_address(const void *addrp _U_
, const char *name _U_
, const bool static_entry _U_
)
1034 num_ipv6_addresses
++;
1038 count_decryption_secret(uint32_t secrets_type _U_
, const void *secrets _U_
, unsigned int size _U_
)
1040 /* XXX - count them based on the secrets type (which is an opaque code,
1041 not a small integer)? */
1042 num_decryption_secrets
++;
1046 hash_to_str(const unsigned char *hash
, size_t length
, char *str
)
1050 for (i
= 0; i
< (int) length
; i
++) {
1051 snprintf(str
+(i
*2), 3, "%02x", hash
[i
]);
1056 calculate_hashes(const char *filename
)
1061 (void) g_strlcpy(file_sha256
, "<unknown>", HASH_STR_SIZE
);
1062 (void) g_strlcpy(file_sha1
, "<unknown>", HASH_STR_SIZE
);
1064 if (cap_file_hashes
) {
1065 fh
= ws_fopen(filename
, "rb");
1067 while((hash_bytes
= fread(hash_buf
, 1, HASH_BUF_SIZE
, fh
)) > 0) {
1068 gcry_md_write(hd
, hash_buf
, hash_bytes
);
1071 hash_to_str(gcry_md_read(hd
, GCRY_MD_SHA256
), HASH_SIZE_SHA256
, file_sha256
);
1072 hash_to_str(gcry_md_read(hd
, GCRY_MD_SHA1
), HASH_SIZE_SHA1
, file_sha1
);
1075 if (hd
) gcry_md_reset(hd
);
1080 process_cap_file(const char *filename
, bool need_separator
)
1086 int64_t data_offset
;
1088 uint32_t packet
= 0;
1090 uint32_t snaplen_min_inferred
= 0xffffffff;
1091 uint32_t snaplen_max_inferred
= 0;
1094 capture_info cf_info
;
1095 bool have_times
= true;
1096 nstime_t earliest_packet_time
;
1097 int earliest_packet_time_tsprec
;
1098 nstime_t latest_packet_time
;
1099 int latest_packet_time_tsprec
;
1102 bool know_order
= false;
1103 order_t order
= IN_ORDER
;
1105 wtapng_iface_descriptions_t
*idb_info
;
1107 pkt_cmt
*pc
= NULL
, *prev
= NULL
;
1109 cf_info
.wth
= wtap_open_offline(filename
, WTAP_TYPE_AUTO
, &err
, &err_info
, false);
1111 cfile_open_failure_message(filename
, err
, err_info
);
1116 * Calculate the checksums. Do this after wtap_open_offline, so we don't
1117 * bother calculating them for files that are not known capture types
1118 * where we wouldn't print them anyway.
1120 calculate_hashes(filename
);
1122 if (need_separator
&& long_report
) {
1126 nstime_set_zero(&earliest_packet_time
);
1127 earliest_packet_time_tsprec
= WTAP_TSPREC_UNKNOWN
;
1128 nstime_set_zero(&latest_packet_time
);
1129 latest_packet_time_tsprec
= WTAP_TSPREC_UNKNOWN
;
1130 nstime_set_zero(&cur_time
);
1131 nstime_set_zero(&prev_time
);
1133 cf_info
.encap_counts
= g_new0(int,WTAP_NUM_ENCAP_TYPES
);
1135 idb_info
= wtap_file_get_idb_info(cf_info
.wth
);
1137 ws_assert(idb_info
->interface_data
!= NULL
);
1139 cf_info
.pkt_cmts
= NULL
;
1140 cf_info
.num_interfaces
= idb_info
->interface_data
->len
;
1141 cf_info
.interface_packet_counts
= g_array_sized_new(false, true, sizeof(uint32_t), cf_info
.num_interfaces
);
1142 g_array_set_size(cf_info
.interface_packet_counts
, cf_info
.num_interfaces
);
1143 cf_info
.pkt_interface_id_unknown
= 0;
1148 /* Zero out the counters for the callbacks. */
1149 num_ipv4_addresses
= 0;
1150 num_ipv6_addresses
= 0;
1151 num_decryption_secrets
= 0;
1153 /* Register callbacks for new name<->address maps from the file and
1154 decryption secrets from the file. */
1155 wtap_set_cb_new_ipv4(cf_info
.wth
, count_ipv4_address
);
1156 wtap_set_cb_new_ipv6(cf_info
.wth
, count_ipv6_address
);
1157 wtap_set_cb_new_secrets(cf_info
.wth
, count_decryption_secret
);
1159 /* Tally up data that we need to parse through the file to find */
1160 wtap_rec_init(&rec
);
1161 ws_buffer_init(&buf
, 1514);
1162 while (wtap_read(cf_info
.wth
, &rec
, &buf
, &err
, &err_info
, &data_offset
)) {
1163 if (rec
.presence_flags
& WTAP_HAS_TS
) {
1164 prev_time
= cur_time
;
1167 earliest_packet_time
= rec
.ts
;
1168 earliest_packet_time_tsprec
= rec
.tsprec
;
1169 latest_packet_time
= rec
.ts
;
1170 latest_packet_time_tsprec
= rec
.tsprec
;
1173 if (nstime_cmp(&cur_time
, &prev_time
) < 0) {
1174 order
= NOT_IN_ORDER
;
1176 if (nstime_cmp(&cur_time
, &earliest_packet_time
) < 0) {
1177 earliest_packet_time
= cur_time
;
1178 earliest_packet_time_tsprec
= rec
.tsprec
;
1180 if (nstime_cmp(&cur_time
, &latest_packet_time
) > 0) {
1181 latest_packet_time
= cur_time
;
1182 latest_packet_time_tsprec
= rec
.tsprec
;
1185 have_times
= false; /* at least one packet has no time stamp */
1186 if (order
!= NOT_IN_ORDER
)
1187 order
= ORDER_UNKNOWN
;
1190 if (rec
.rec_type
== REC_TYPE_PACKET
) {
1191 bytes
+= rec
.rec_header
.packet_header
.len
;
1193 /* packet comments */
1194 if (pkt_comments
&& wtap_block_count_option(rec
.block
, OPT_COMMENT
) > 0) {
1196 for (i
= 0; wtap_block_get_nth_string_option_value(rec
.block
, OPT_COMMENT
, i
, &cmt_buff
) == WTAP_OPTTYPE_SUCCESS
; i
++) {
1197 pc
= g_new0(pkt_cmt
, 1);
1200 pc
->cmt
= g_strdup(cmt_buff
);
1204 cf_info
.pkt_cmts
= pc
;
1212 /* If caplen < len for a rcd, then presumably */
1213 /* 'Limit packet capture length' was done for this rcd. */
1214 /* Keep track as to the min/max actual snapshot lengths */
1215 /* seen for this file. */
1216 if (rec
.rec_header
.packet_header
.caplen
< rec
.rec_header
.packet_header
.len
) {
1217 if (rec
.rec_header
.packet_header
.caplen
< snaplen_min_inferred
)
1218 snaplen_min_inferred
= rec
.rec_header
.packet_header
.caplen
;
1219 if (rec
.rec_header
.packet_header
.caplen
> snaplen_max_inferred
)
1220 snaplen_max_inferred
= rec
.rec_header
.packet_header
.caplen
;
1223 if ((rec
.rec_header
.packet_header
.pkt_encap
> 0) &&
1224 (rec
.rec_header
.packet_header
.pkt_encap
< WTAP_NUM_ENCAP_TYPES
)) {
1225 cf_info
.encap_counts
[rec
.rec_header
.packet_header
.pkt_encap
] += 1;
1227 fprintf(stderr
, "capinfos: Unknown packet encapsulation %d in frame %u of file \"%s\"\n",
1228 rec
.rec_header
.packet_header
.pkt_encap
, packet
, filename
);
1231 /* Packet interface_id info */
1232 if (rec
.presence_flags
& WTAP_HAS_INTERFACE_ID
) {
1233 /* cf_info.num_interfaces is size, not index, so it's one more than max index */
1234 if (rec
.rec_header
.packet_header
.interface_id
>= cf_info
.num_interfaces
) {
1236 * OK, re-fetch the number of interfaces, as there might have
1237 * been an interface that was in the middle of packets, and
1238 * grow the array to be big enough for the new number of
1241 idb_info
= wtap_file_get_idb_info(cf_info
.wth
);
1243 cf_info
.num_interfaces
= idb_info
->interface_data
->len
;
1244 g_array_set_size(cf_info
.interface_packet_counts
, cf_info
.num_interfaces
);
1249 if (rec
.rec_header
.packet_header
.interface_id
< cf_info
.num_interfaces
) {
1250 g_array_index(cf_info
.interface_packet_counts
, uint32_t,
1251 rec
.rec_header
.packet_header
.interface_id
) += 1;
1254 cf_info
.pkt_interface_id_unknown
+= 1;
1258 /* it's for interface_id 0 */
1259 if (cf_info
.num_interfaces
!= 0) {
1260 g_array_index(cf_info
.interface_packet_counts
, uint32_t, 0) += 1;
1263 cf_info
.pkt_interface_id_unknown
+= 1;
1268 wtap_rec_reset(&rec
);
1270 wtap_rec_cleanup(&rec
);
1271 ws_buffer_free(&buf
);
1274 * Get IDB info strings.
1275 * We do this at the end, so we can get information for all IDBs in
1276 * the file, even those that come after packet records, and so that
1277 * we get, for example, a count of the number of statistics entries
1278 * for each interface as of the *end* of the file.
1280 idb_info
= wtap_file_get_idb_info(cf_info
.wth
);
1282 cf_info
.idb_info_strings
= g_array_sized_new(false, false, sizeof(char*), cf_info
.num_interfaces
);
1283 cf_info
.num_interfaces
= idb_info
->interface_data
->len
;
1284 for (i
= 0; i
< cf_info
.num_interfaces
; i
++) {
1285 const wtap_block_t if_descr
= g_array_index(idb_info
->interface_data
, wtap_block_t
, i
);
1286 char *s
= wtap_get_debug_if_descr(if_descr
, 21, "\n");
1287 g_array_append_val(cf_info
.idb_info_strings
, s
);
1295 "capinfos: An error occurred after reading %u packets from \"%s\".\n",
1297 cfile_read_failure_message(filename
, err
, err_info
);
1298 if (err
== WTAP_ERR_SHORT_READ
) {
1299 /* Don't give up completely with this one. */
1302 " (will continue anyway, checksums might be incorrect)\n");
1304 cleanup_capture_info(&cf_info
);
1305 wtap_close(cf_info
.wth
);
1311 size
= wtap_file_size(cf_info
.wth
, &err
);
1314 "capinfos: Can't get size of \"%s\": %s.\n",
1315 filename
, g_strerror(err
));
1316 cleanup_capture_info(&cf_info
);
1317 wtap_close(cf_info
.wth
);
1321 cf_info
.filesize
= size
;
1324 cf_info
.file_type
= wtap_file_type_subtype(cf_info
.wth
);
1325 cf_info
.compression_type
= wtap_get_compression_type(cf_info
.wth
);
1327 /* File Encapsulation */
1328 cf_info
.file_encap
= wtap_file_encap(cf_info
.wth
);
1330 cf_info
.file_tsprec
= wtap_file_tsprec(cf_info
.wth
);
1332 /* Packet size limit (snaplen) */
1333 cf_info
.snaplen
= wtap_snapshot_length(cf_info
.wth
);
1334 if (cf_info
.snaplen
> 0)
1335 cf_info
.snap_set
= true;
1337 cf_info
.snap_set
= false;
1339 cf_info
.snaplen_min_inferred
= snaplen_min_inferred
;
1340 cf_info
.snaplen_max_inferred
= snaplen_max_inferred
;
1343 cf_info
.packet_count
= packet
;
1346 cf_info
.times_known
= have_times
;
1347 cf_info
.earliest_packet_time
= earliest_packet_time
;
1348 cf_info
.earliest_packet_time_tsprec
= earliest_packet_time_tsprec
;
1349 cf_info
.latest_packet_time
= latest_packet_time
;
1350 cf_info
.latest_packet_time_tsprec
= latest_packet_time_tsprec
;
1351 nstime_delta(&cf_info
.duration
, &latest_packet_time
, &earliest_packet_time
);
1352 /* Duration precision is the higher of the earliest and latest packet timestamp precisions. */
1353 if (cf_info
.latest_packet_time_tsprec
> cf_info
.earliest_packet_time_tsprec
)
1354 cf_info
.duration_tsprec
= cf_info
.latest_packet_time_tsprec
;
1356 cf_info
.duration_tsprec
= cf_info
.earliest_packet_time_tsprec
;
1357 cf_info
.know_order
= know_order
;
1358 cf_info
.order
= order
;
1360 /* Number of packet bytes */
1361 cf_info
.packet_bytes
= bytes
;
1363 cf_info
.data_rate
= 0.0;
1364 cf_info
.packet_rate
= 0.0;
1365 cf_info
.packet_size
= 0.0;
1368 double delta_time
= nstime_to_sec(&latest_packet_time
) - nstime_to_sec(&earliest_packet_time
);
1369 if (delta_time
> 0.0) {
1370 cf_info
.data_rate
= (double)bytes
/ delta_time
; /* Data rate per second */
1371 cf_info
.packet_rate
= (double)packet
/ delta_time
; /* packet rate per second */
1373 cf_info
.packet_size
= (double)bytes
/ packet
; /* Avg packet size */
1376 if (!long_report
&& table_report_header
) {
1377 print_stats_table_header(&cf_info
);
1381 print_stats(filename
, &cf_info
);
1383 print_stats_table(filename
, &cf_info
);
1386 cleanup_capture_info(&cf_info
);
1387 wtap_close(cf_info
.wth
);
1393 print_usage(FILE *output
)
1395 fprintf(output
, "\n");
1396 fprintf(output
, "Usage: capinfos [options] <infile> ...\n");
1397 fprintf(output
, "\n");
1398 fprintf(output
, "General infos:\n");
1399 fprintf(output
, " -t display the capture file type\n");
1400 fprintf(output
, " -E display the capture file encapsulation\n");
1401 fprintf(output
, " -I display the capture file interface information\n");
1402 fprintf(output
, " -F display additional capture file information\n");
1403 fprintf(output
, " -H display the SHA256 and SHA1 hashes of the file\n");
1404 fprintf(output
, " -k display the capture comment\n");
1405 fprintf(output
, " -p display individual packet comments\n");
1406 fprintf(output
, "\n");
1407 fprintf(output
, "Size infos:\n");
1408 fprintf(output
, " -c display the number of packets\n");
1409 fprintf(output
, " -s display the size of the file (in bytes)\n");
1410 fprintf(output
, " -d display the total length of all packets (in bytes)\n");
1411 fprintf(output
, " -l display the packet size limit (snapshot length)\n");
1412 fprintf(output
, "\n");
1413 fprintf(output
, "Time infos:\n");
1414 fprintf(output
, " -u display the capture duration (in seconds)\n");
1415 fprintf(output
, " -a display the timestamp of the earliest packet\n");
1416 fprintf(output
, " -e display the timestamp of the latest packet\n");
1417 fprintf(output
, " -o display the capture file chronological status (True/False)\n");
1418 fprintf(output
, " -S display earliest and latest packet timestamps as seconds\n");
1419 fprintf(output
, "\n");
1420 fprintf(output
, "Statistic infos:\n");
1421 fprintf(output
, " -y display average data rate (in bytes/sec)\n");
1422 fprintf(output
, " -i display average data rate (in bits/sec)\n");
1423 fprintf(output
, " -z display average packet size (in bytes)\n");
1424 fprintf(output
, " -x display average packet rate (in packets/sec)\n");
1425 fprintf(output
, "\n");
1426 fprintf(output
, "Metadata infos:\n");
1427 fprintf(output
, " -n display number of resolved IPv4 and IPv6 addresses\n");
1428 fprintf(output
, " -D display number of decryption secrets\n");
1429 fprintf(output
, "\n");
1430 fprintf(output
, "Output format:\n");
1431 fprintf(output
, " -L generate long report (default)\n");
1432 fprintf(output
, " -T generate table report\n");
1433 fprintf(output
, " -M display machine-readable values in long reports\n");
1434 fprintf(output
, "\n");
1435 fprintf(output
, "Table report options:\n");
1436 fprintf(output
, " -R generate header record (default)\n");
1437 fprintf(output
, " -r do not generate header record\n");
1438 fprintf(output
, "\n");
1439 fprintf(output
, " -B separate infos with TAB character (default)\n");
1440 fprintf(output
, " -m separate infos with comma (,) character\n");
1441 fprintf(output
, " -b separate infos with SPACE character\n");
1442 fprintf(output
, "\n");
1443 fprintf(output
, " -N do not quote infos (default)\n");
1444 fprintf(output
, " -q quote infos with single quotes (')\n");
1445 fprintf(output
, " -Q quote infos with double quotes (\")\n");
1446 fprintf(output
, "\n");
1447 fprintf(output
, "Miscellaneous:\n");
1448 fprintf(output
, " -h, --help display this help and exit\n");
1449 fprintf(output
, " -v, --version display version info and exit\n");
1450 fprintf(output
, " -C cancel processing if file open fails (default is to continue)\n");
1451 fprintf(output
, " -A generate all infos (default)\n");
1452 fprintf(output
, " -K disable displaying the capture comment\n");
1453 fprintf(output
, " -P disable displaying individual packet comments\n");
1454 fprintf(output
, "\n");
1455 fprintf(output
, "Options are processed from left to right order with later options superseding\n");
1456 fprintf(output
, "or adding to earlier options.\n");
1457 fprintf(output
, "\n");
1458 fprintf(output
, "If no options are given the default is to display all infos in long report\n");
1459 fprintf(output
, "output format.\n");
1463 * Report an error in command-line arguments.
1466 capinfos_cmdarg_err(const char *msg_format
, va_list ap
)
1468 fprintf(stderr
, "capinfos: ");
1469 vfprintf(stderr
, msg_format
, ap
);
1470 fprintf(stderr
, "\n");
1474 * Report additional information for an error in command-line arguments.
1477 capinfos_cmdarg_err_cont(const char *msg_format
, va_list ap
)
1479 vfprintf(stderr
, msg_format
, ap
);
1480 fprintf(stderr
, "\n");
1484 main(int argc
, char *argv
[])
1486 char *configuration_init_error
;
1487 bool need_separator
= false;
1489 int overall_error_status
= EXIT_SUCCESS
;
1490 static const struct ws_option long_options
[] = {
1491 {"help", ws_no_argument
, NULL
, 'h'},
1492 {"version", ws_no_argument
, NULL
, 'v'},
1499 * Set the C-language locale to the native environment and set the
1500 * code page to UTF-8 on Windows.
1503 setlocale(LC_ALL
, ".UTF-8");
1505 setlocale(LC_ALL
, "");
1508 cmdarg_err_init(capinfos_cmdarg_err
, capinfos_cmdarg_err_cont
);
1510 /* Initialize log handler early so we can have proper logging during startup. */
1511 ws_log_init("capinfos", vcmdarg_err
);
1513 /* Early logging command-line initialization. */
1514 ws_log_parse_args(&argc
, argv
, vcmdarg_err
, WS_EXIT_INVALID_OPTION
);
1516 ws_noisy("Finished log init and parsing command line log arguments");
1518 /* Get the decimal point. */
1519 decimal_point
= g_strdup(localeconv()->decimal_point
);
1521 /* Initialize the version information. */
1522 ws_init_version_info("Capinfos", NULL
, NULL
);
1525 create_app_running_mutex();
1529 * Get credential information for later use.
1531 init_process_policies();
1534 * Attempt to get the pathname of the directory containing the
1537 configuration_init_error
= configuration_init(argv
[0], NULL
);
1538 if (configuration_init_error
!= NULL
) {
1540 "capinfos: Can't get pathname of directory containing the capinfos program: %s.\n",
1541 configuration_init_error
);
1542 g_free(configuration_init_error
);
1545 init_report_failure_message("capinfos");
1549 /* Process the options */
1550 while ((opt
= ws_getopt_long(argc
, argv
, "abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST", long_options
, NULL
)) !=-1) {
1555 if (report_all_infos
) disable_all_infos();
1556 cap_file_type
= true;
1560 if (report_all_infos
) disable_all_infos();
1561 cap_file_encap
= true;
1565 if (report_all_infos
) disable_all_infos();
1570 if (report_all_infos
) disable_all_infos();
1571 cap_packet_count
= true;
1575 if (report_all_infos
) disable_all_infos();
1576 cap_file_size
= true;
1580 if (report_all_infos
) disable_all_infos();
1581 cap_data_size
= true;
1585 if (report_all_infos
) disable_all_infos();
1586 cap_duration
= true;
1590 if (report_all_infos
) disable_all_infos();
1591 cap_earliest_packet_time
= true;
1595 if (report_all_infos
) disable_all_infos();
1596 cap_latest_packet_time
= true;
1600 time_as_secs
= true;
1604 if (report_all_infos
) disable_all_infos();
1605 cap_data_rate_byte
= true;
1609 if (report_all_infos
) disable_all_infos();
1610 cap_data_rate_bit
= true;
1614 if (report_all_infos
) disable_all_infos();
1615 cap_packet_size
= true;
1619 if (report_all_infos
) disable_all_infos();
1620 cap_packet_rate
= true;
1624 if (report_all_infos
) disable_all_infos();
1625 cap_file_hashes
= true;
1629 if (report_all_infos
) disable_all_infos();
1634 if (report_all_infos
) disable_all_infos();
1639 if (report_all_infos
) disable_all_infos();
1640 pkt_comments
= true;
1644 cap_comment
= false;
1648 pkt_comments
= false;
1652 if (report_all_infos
) disable_all_infos();
1653 cap_file_more_info
= true;
1657 if (report_all_infos
) disable_all_infos();
1658 cap_file_idb
= true;
1662 if (report_all_infos
) disable_all_infos();
1663 cap_file_nrb
= true;
1667 if (report_all_infos
) disable_all_infos();
1668 cap_file_dsb
= true;
1672 stop_after_failure
= true;
1684 long_report
= false;
1688 machine_readable
= true;
1692 table_report_header
= true;
1696 table_report_header
= false;
1712 field_separator
= '\t';
1716 field_separator
= ',';
1720 field_separator
= ' ';
1724 show_help_header("Print various information (infos) about capture files.");
1725 print_usage(stdout
);
1734 case '?': /* Bad flag - print usage message */
1735 print_usage(stderr
);
1736 overall_error_status
= WS_EXIT_INVALID_OPTION
;
1742 if ((argc
- ws_optind
) < 1) {
1743 print_usage(stderr
);
1744 overall_error_status
= WS_EXIT_INVALID_OPTION
;
1748 if (cap_file_hashes
) {
1749 gcry_check_version(NULL
);
1750 gcry_md_open(&hd
, GCRY_MD_SHA256
, 0);
1752 gcry_md_enable(hd
, GCRY_MD_SHA1
);
1754 hash_buf
= (char *)g_malloc(HASH_BUF_SIZE
);
1757 overall_error_status
= 0;
1759 for (opt
= ws_optind
; opt
< argc
; opt
++) {
1761 status
= process_cap_file(argv
[opt
], need_separator
);
1763 /* Something failed. It's been reported; remember that processing
1764 one file failed and, if -C was specified, stop. */
1765 overall_error_status
= status
;
1766 if (stop_after_failure
)
1770 /* Either it succeeded or it got a "short read" but printed
1771 information anyway. Note that we need a blank line before
1772 the next file's information, to separate it from the
1774 need_separator
= true;
1783 return overall_error_status
;