* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+/*
+ * 2009-09-19: jyoung
+ *
+ * New capinfos features
+ *
+ * Continue processing additional files after
+ * a wiretap open failure. The new -C option
+ * reverts to capinfos' original behavior which
+ * is to cancels any further file processing at
+ * first file open failure.
+ *
+ * Change the behavior of how the default display
+ * of all infos is initiated. This gets rid of a
+ * special post getopt() argument count test.
+ *
+ * Add new table output format (with related options)
+ * This feature allows outputting the various infos
+ * into a tab delimited text file, or to a comma
+ * separated variables file (*.csv) instead of the
+ * original "long" format.
+ */
+
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "wsgetopt.h"
#endif
-static gboolean cap_file_type = FALSE; /* Do not report capture type */
-static gboolean cap_file_encap = FALSE; /* Do not report encapsulation */
-static gboolean cap_packet_count = FALSE; /* Do not produce packet count */
-static gboolean cap_file_size = FALSE; /* Do not report file size */
-static gboolean cap_data_size = FALSE; /* Do not report packet byte size */
-static gboolean cap_duration = FALSE; /* Do not report capture duration */
-static gboolean cap_start_time = FALSE;
-static gboolean cap_end_time = FALSE;
+/*
+ * By default capinfos now continues processing
+ * the next filename if and when wiretap detects
+ * a problem opening a file.
+ * Use the '-C' option to revert back to original
+ * capinfos behavior which is to abort any
+ * additional file processing at first open file
+ * failure.
+ */
+
+static gboolean continue_after_wtap_open_offline_failure = TRUE;
+
+/*
+ * table report variables
+ */
-static gboolean cap_data_rate_byte = FALSE;
-static gboolean cap_data_rate_bit = FALSE;
-static gboolean cap_packet_size = FALSE;
-static gboolean cap_packet_rate = FALSE;
+static gboolean long_report = TRUE; /* By default generate long report */
+static gchar table_report_header = TRUE; /* Generate column header by default */
+static gchar field_separator = '\t'; /* Use TAB as field separator by default */
+static gchar quote_char = '\0'; /* Do NOT quote fields by default */
+/*
+ * capinfos has the ability to report on a number of
+ * various characteristics ("infos") for each input file.
+ *
+ * By default reporting of all info fields is enabled.
+ *
+ * Optionally the reporting of any specific info field
+ * or combination of info fields can be enabled with
+ * individual options.
+ */
+
+static gboolean report_all_infos = TRUE; /* Report all infos */
+
+static gboolean cap_file_type = TRUE; /* Report capture type */
+static gboolean cap_file_encap = TRUE; /* Report encapsulation */
+static gboolean cap_packet_count = TRUE; /* Report packet count */
+static gboolean cap_file_size = TRUE; /* Report file size */
+
+static gboolean cap_data_size = TRUE; /* Report packet byte size */
+static gboolean cap_duration = TRUE; /* Report capture duration */
+static gboolean cap_start_time = TRUE; /* Report capture start time */
+static gboolean cap_end_time = TRUE; /* Report capture end time */
+
+static gboolean cap_data_rate_byte = TRUE; /* Report data rate bytes/sec */
+static gboolean cap_data_rate_bit = TRUE; /* Report data rate bites/sec */
+static gboolean cap_packet_size = TRUE; /* Report average packet size */
+static gboolean cap_packet_rate = TRUE; /* Report average packet rate */
typedef struct _capture_info {
const char *filename;
double data_rate; /* in bytes */
} capture_info;
+static void
+enable_all_infos(void)
+{
+ report_all_infos = TRUE;
+
+ cap_file_type = TRUE;
+ cap_file_encap = TRUE;
+ cap_packet_count = TRUE;
+ cap_file_size = TRUE;
+
+ cap_data_size = TRUE;
+ cap_duration = TRUE;
+ cap_start_time = TRUE;
+ cap_end_time = TRUE;
+
+ cap_data_rate_byte = TRUE;
+ cap_data_rate_bit = TRUE;
+ cap_packet_size = TRUE;
+ cap_packet_rate = TRUE;
+}
+
+static void
+disable_all_infos(void)
+{
+ report_all_infos = FALSE;
+
+ cap_file_type = FALSE;
+ cap_file_encap = FALSE;
+ cap_packet_count = FALSE;
+ cap_file_size = FALSE;
+
+ cap_data_size = FALSE;
+ cap_duration = FALSE;
+ cap_start_time = FALSE;
+ cap_end_time = FALSE;
+
+ cap_data_rate_byte = FALSE;
+ cap_data_rate_bit = FALSE;
+ cap_packet_size = FALSE;
+ cap_packet_rate = FALSE;
+}
+
+/*
+ * ctime_no_lf()
+ *
+ * This function simply truncates the string returned
+ * from the ctime() function to remove the trailing
+ * '\n' character.
+ *
+ * The ctime() function returns a string formatted as:
+ * "Www Mmm dd hh:mm:ss yyyy\n"
+ * The unwanted '\n' is the 24th character.
+ */
+
+static gchar *
+ctime_no_lf(const time_t* timer)
+{
+ gchar *time_string;
+ time_string = ctime(timer);
+ time_string[24] = '\0';
+ return(time_string);
+}
+
static double
secs_nsecs(const struct wtap_nstime * nstime)
{
}
static void
-print_stats(capture_info *cf_info)
+print_stats(const gchar *filename, capture_info *cf_info)
{
const gchar *file_type_string, *file_encap_string;
time_t start_time_t;
start_time_t = (time_t)cf_info->start_time;
stop_time_t = (time_t)cf_info->stop_time;
+ if (filename) printf ("File name: %s\n", filename);
if (cap_file_type) printf ("File type: %s\n", file_type_string);
if (cap_file_encap) printf ("File encapsulation: %s\n", file_encap_string);
if (cap_packet_count) printf ("Number of packets: %u\n", cf_info->packet_count);
if (cap_packet_rate) print_value("Average packet rate: ", 2, " packets/sec", cf_info->packet_rate);
}
+static void
+putsep(void)
+{
+ if (field_separator) putchar(field_separator);
+}
+
+static void
+putquote(void)
+{
+ if (quote_char) putchar(quote_char);
+}
+
+static void
+print_stats_table_header_label(gchar *label)
+{
+ putsep();
+ putquote();
+ printf("%s", label);
+ putquote();
+}
+
+static void
+print_stats_table_header(void)
+{
+ putquote();
+ printf("File name");
+ putquote();
+
+ if (cap_file_type) print_stats_table_header_label("File type");
+ if (cap_file_encap) print_stats_table_header_label("File encapsulation");
+ if (cap_packet_count) print_stats_table_header_label("Number of packets");
+ if (cap_file_size) print_stats_table_header_label("File size (bytes)");
+ if (cap_data_size) print_stats_table_header_label("Data size (bytes)");
+ if (cap_duration) print_stats_table_header_label("Capture duration (seconds)");
+ if (cap_start_time) print_stats_table_header_label("Start time");
+ if (cap_end_time) print_stats_table_header_label("End time");
+ if (cap_data_rate_byte) print_stats_table_header_label("Data byte rate (bytes/sec)");
+ if (cap_data_rate_bit) print_stats_table_header_label("Data bit rate (bits/sec)");
+ if (cap_packet_size) print_stats_table_header_label("Average packet size (bytes)");
+ if (cap_packet_rate) print_stats_table_header_label("Average packet rate (packets/sec)");
+
+ printf("\n");
+}
+
+static void
+print_stats_table(const gchar *filename, capture_info *cf_info)
+{
+ const gchar *file_type_string, *file_encap_string;
+ time_t start_time_t;
+ time_t stop_time_t;
+
+ /* Build printable strings for various stats */
+ file_type_string = wtap_file_type_string(cf_info->file_type);
+ file_encap_string = wtap_encap_string(cf_info->file_encap);
+ start_time_t = (time_t)cf_info->start_time;
+ stop_time_t = (time_t)cf_info->stop_time;
+
+ if (filename) {
+ putquote();
+ printf("%s", filename);
+ putquote();
+ }
+
+ if (cap_file_type) {
+ putsep();
+ putquote();
+ printf("%s", file_type_string);
+ putquote();
+ }
+
+ if (cap_file_encap) {
+ putsep();
+ putquote();
+ printf("%s", file_encap_string);
+ putquote();
+ }
+
+ if (cap_packet_count) {
+ putsep();
+ putquote();
+ printf("%u", cf_info->packet_count);
+ putquote();
+ }
+
+ if (cap_file_size) {
+ putsep();
+ putquote();
+ printf("%" G_GINT64_MODIFIER "d", cf_info->filesize);
+ putquote();
+ }
+
+ if (cap_data_size) {
+ putsep();
+ putquote();
+ printf("%" G_GINT64_MODIFIER "u", cf_info->packet_bytes);
+ putquote();
+ }
+
+ if (cap_duration) {
+ putsep();
+ putquote();
+ printf("%f", cf_info->duration);
+ putquote();
+ }
+
+ if (cap_start_time) {
+ putsep();
+ putquote();
+ printf("%s", (cf_info->packet_count>0) ? ctime_no_lf (&start_time_t) : "n/a");
+ putquote();
+ }
+
+ if (cap_end_time) {
+ putsep();
+ putquote();
+ printf("%s", (cf_info->packet_count>0) ? ctime_no_lf (&stop_time_t) : "n/a");
+ putquote();
+ }
+
+ if (cap_data_rate_byte) {
+ putsep();
+ putquote();
+ printf("%.2f", cf_info->data_rate);
+ putquote();
+ }
+
+ if (cap_data_rate_bit) {
+ putsep();
+ putquote();
+ printf("%.2f", cf_info->data_rate*8);
+ putquote();
+ }
+
+ if (cap_packet_size) {
+ putsep();
+ putquote();
+ printf("%.2f", cf_info->packet_size);
+ putquote();
+ }
+
+ if (cap_packet_rate) {
+ putsep();
+ putquote();
+ printf("%.2f", cf_info->packet_rate);
+ putquote();
+ }
+
+ printf("\n");
+}
+
static int
process_cap_file(wtap *wth, const char *filename)
{
cf_info.packet_size = (double)bytes / packet; /* Avg packet size */
}
- printf("File name: %s\n", filename);
- print_stats(&cf_info);
+ if(long_report) {
+ print_stats(filename, &cf_info);
+ } else {
+ print_stats_table(filename, &cf_info);
+ }
return 0;
}
" (" SVNVERSION " from " SVNPATH ")"
#endif
"\n", VERSION);
- fprintf(output, "Prints information about capture files.\n");
+ fprintf(output, "Prints various information (infos) about capture files.\n");
fprintf(output, "See http://www.wireshark.org for more information.\n");
fprintf(output, "\n");
fprintf(output, "Usage: capinfos [options] <infile> ...\n");
fprintf(output, "\n");
- fprintf(output, "General:\n");
+ fprintf(output, "General infos:\n");
fprintf(output, " -t display the capture file type\n");
fprintf(output, " -E display the capture file encapsulation\n");
fprintf(output, "\n");
- fprintf(output, "Size:\n");
+ fprintf(output, "Size infos:\n");
fprintf(output, " -c display the number of packets\n");
fprintf(output, " -s display the size of the file (in bytes)\n");
fprintf(output, " -d display the total length of all packets (in bytes)\n");
fprintf(output, "\n");
- fprintf(output, "Time:\n");
+ fprintf(output, "Time infos:\n");
fprintf(output, " -u display the capture duration (in seconds)\n");
fprintf(output, " -a display the capture start time\n");
fprintf(output, " -e display the capture end time\n");
fprintf(output, "\n");
- fprintf(output, "Statistic:\n");
+ fprintf(output, "Statistic infos:\n");
fprintf(output, " -y display average data rate (in bytes/sec)\n");
fprintf(output, " -i display average data rate (in bits/sec)\n");
fprintf(output, " -z display average packet size (in bytes)\n");
fprintf(output, " -x display average packet rate (in packets/sec)\n");
fprintf(output, "\n");
+ fprintf(output, "Output format:\n");
+ fprintf(output, " -L generate long report (default)\n");
+ fprintf(output, " -T generate table report\n");
+ fprintf(output, "\n");
+ fprintf(output, "Table report options:\n");
+ fprintf(output, " -R generate header record (default)\n");
+ fprintf(output, " -r do not generate header record\n");
+ fprintf(output, "\n");
+ fprintf(output, " -B separate infos with TAB character (default)\n");
+ fprintf(output, " -m separate infos with comma (,) character\n");
+ fprintf(output, " -b separate infos with SPACE character\n");
+ fprintf(output, "\n");
+ fprintf(output, " -N do not quote infos (default)\n");
+ fprintf(output, " -q quote infos with single quotes (')\n");
+ fprintf(output, " -Q quote infos with double quotes (\")\n");
+ fprintf(output, "\n");
fprintf(output, "Miscellaneous:\n");
fprintf(output, " -h display this help and exit\n");
+ fprintf(output, " -C cancel processing if file open fails (default is to continue)\n");
+ fprintf(output, " -A generate all infos (default)\n");
+ fprintf(output, "\n");
+ fprintf(output, "Options are processed from left to right order with later options superceeding\n");
+ fprintf(output, "or adding to earlier options.\n");
fprintf(output, "\n");
- fprintf(output, "If no options are given the default is to display all infos\n");
+ fprintf(output, "If no options are given the default is to display all infos in long report\n");
+ fprintf(output, "output format.\n");
}
#ifdef HAVE_PLUGINS
/* Process the options */
- while ((opt = getopt(argc, argv, "tEcsduaeyizvhx")) !=-1) {
+ while ((opt = getopt(argc, argv, "tEcsduaeyizvhxCALTRrNqQBmb")) !=-1) {
switch (opt) {
case 't':
+ if (report_all_infos) disable_all_infos();
cap_file_type = TRUE;
break;
case 'E':
+ if (report_all_infos) disable_all_infos();
cap_file_encap = TRUE;
break;
case 'c':
+ if (report_all_infos) disable_all_infos();
cap_packet_count = TRUE;
break;
case 's':
+ if (report_all_infos) disable_all_infos();
cap_file_size = TRUE;
break;
case 'd':
+ if (report_all_infos) disable_all_infos();
cap_data_size = TRUE;
break;
case 'u':
+ if (report_all_infos) disable_all_infos();
cap_duration = TRUE;
break;
case 'a':
+ if (report_all_infos) disable_all_infos();
cap_start_time = TRUE;
break;
case 'e':
+ if (report_all_infos) disable_all_infos();
cap_end_time = TRUE;
break;
case 'y':
+ if (report_all_infos) disable_all_infos();
cap_data_rate_byte = TRUE;
break;
case 'i':
+ if (report_all_infos) disable_all_infos();
cap_data_rate_bit = TRUE;
break;
case 'z':
+ if (report_all_infos) disable_all_infos();
cap_packet_size = TRUE;
break;
case 'x':
+ if (report_all_infos) disable_all_infos();
cap_packet_rate = TRUE;
break;
+ case 'C':
+ continue_after_wtap_open_offline_failure = FALSE;
+ break;
+
+ case 'A':
+ enable_all_infos();
+ break;
+
+ case 'L':
+ long_report = TRUE;
+ break;
+
+ case 'T':
+ long_report = FALSE;
+ break;
+
+ case 'R':
+ table_report_header = TRUE;
+ break;
+
+ case 'r':
+ table_report_header = FALSE;
+ break;
+
+ case 'N':
+ quote_char = '\0';
+ break;
+
+ case 'q':
+ quote_char = '\'';
+ break;
+
+ case 'Q':
+ quote_char = '"';
+ break;
+
+ case 'B':
+ field_separator = '\t';
+ break;
+
+ case 'm':
+ field_separator = ',';
+ break;
+
+ case 'b':
+ field_separator = ' ';
+ break;
+
case 'h':
usage(FALSE);
exit(1);
}
}
- if (optind < 2) {
-
- /* If no arguments were given, by default display all statistics */
- cap_file_type = TRUE;
- cap_file_encap = TRUE;
- cap_packet_count = TRUE;
- cap_file_size = TRUE;
- cap_data_size = TRUE;
- cap_duration = TRUE;
- cap_start_time = TRUE;
- cap_end_time = TRUE;
-
- cap_data_rate_byte = TRUE;
- cap_data_rate_bit = TRUE;
- cap_packet_size = TRUE;
- cap_packet_rate = TRUE;
- }
-
if ((argc - optind) < 1) {
usage(TRUE);
exit(1);
}
+ if(!long_report && table_report_header) {
+ print_stats_table_header();
+ }
+
for (opt = optind; opt < argc; opt++) {
wth = wtap_open_offline(argv[opt], &err, &err_info, FALSE);
g_free(err_info);
break;
}
- exit(1);
+ if(!continue_after_wtap_open_offline_failure)
+ exit(1);
}
- if (opt > optind)
- printf("\n");
- status = process_cap_file(wth, argv[opt]);
+ if(wth) {
+ if ((opt > optind) && (long_report))
+ printf("\n");
+ status = process_cap_file(wth, argv[opt]);
- wtap_close(wth);
- if (status)
- exit(status);
+ wtap_close(wth);
+ if (status)
+ exit(status);
+ }
}
return 0;
}
S<[ B<-y> ]>
S<[ B<-i> ]>
S<[ B<-z> ]>
-S<[ B<-x> ]>
+S<[ B<-L> ]>
+S<[ B<-T> ]>
+S<[ B<-R> ]>
+S<[ B<-r> ]>
+S<[ B<-B> ]>
+S<[ B<-m> ]>
+S<[ B<-b> ]>
+S<[ B<-N> ]>
+S<[ B<-q> ]>
+S<[ B<-Q> ]>
S<[ B<-h> ]>
+S<[ B<-C> ]>
+S<[ B<-A> ]>
E<lt>I<infile>E<gt>
I<...>
=head1 DESCRIPTION
B<Capinfos> is a program that reads one or more capture files and
-returns some or all available statistics of each E<lt>I<infile>E<gt>.
+returns some or all available statistics (infos) of each E<lt>I<infile>E<gt>
+in one of two types of output formats: long or table.
-The user specifies which statistics to report by specifying flags
-corresponding to the statistic. If no flags are specified, B<Capinfos>
-will report all statistics available.
+The long output is suitable for a human to read. The table output
+is useful for generating a report that can be easily imported into
+a spreadsheet or database.
+
+The user specifies what type of output (long or table) and which
+statistics to display by specifying flags (options) that corresponding
+to the report type and desired infos. If no options are specified,
+B<Capinfos> will report all statistics available in "long" format.
+
+Options are processed from left to right order with later options
+superceeding or adding to earlier options.
B<Capinfos> is able to detect and read the same capture files that are
supported by B<Wireshark>.
=item -c
-Counts the number of packets in the capture file.
+Displays the number of packets in the capture file.
=item -s
displays the average packet rate, in packets/sec
+=item -L
+
+Generate long report. Capinfos can generate two
+different styles of reports. The "long" report is
+the default style of output and is suitable for a
+human to use.
+
+=item -T
+
+Generate a table report. A table report is a text file
+that is suitable for importing into a spreadsheet or
+database. Capinfos can build a tab delimited text file
+(the default) or several variations on Comma-separated
+values (CSV) files.
+
+=item -R
+
+Generate header record. This option is only useful
+when generating a table style report (-T). A header
+is generated by default. A header record (if generated)
+is the first line of data reported and includes labels
+for all the columns included within the table report.
+
+
+=item -r
+
+Do not generate header record. This option is only
+useful when generating a table style report (-T).
+If this option is specified then B<no> header record will be
+generated within the table report.
+
+
+=item -B
+
+Separate the infos with ASCII TAB characters.
+This option is only useful when generating a table
+style report (-T). The various info values will be
+separated (delimited) from one another with a single
+ASCII TAB character. The TAB character is the default
+delimiter when -T style report is enabled.
+
+=item -m
+
+Separate the infos with comma (,) characters. This option
+is only useful when generating a table style report (-T).
+The various info values will be separated (delimited)
+from one another with a single comma "," character.
+
+=item -b
+
+Separate infos with ASCII SPACE (0x20) characters.
+This option is only useful when generating a table
+style report (-T). The various info values will be
+separated (delimited) from one another with a single
+ASCII SPACE character.
+
+NOTE: Since some of the header labels as well as some
+of the value fields contain SPACE characters. This
+option is of limited value unless one of the quoting
+options (-q or -Q) is also specified.
+
+=item -N
+
+Do not quote the infos. This option is only useful
+when generating a table style report (-T). Excluding
+any quoting characters around the various values and
+using a TAB delimiter produces a very "clean" table
+report that is easily parsed with CLI tools. By
+default infos are B<NOT> quoted.
+
+
+=item -q
+
+Quote infos with single quotes ('). This option is
+only useful when generating a table style report (-T).
+When this option is enabled, each value will be
+encapsulated within a pair of single quote (')
+characters. This option (when used with the -m
+option) is useful for generating one type of CSV
+style file report.
+
+=item -Q
+
+Quote infos with double quotes ("). This option is
+only useful when generating a table style report (-T).
+When this option is enabled, each value will be
+encapsulated within a pair of double quote (")
+characters. This option (when used with the -m
+option) is useful for generating the most common
+type of CSV style file report.
+
=item -h
Prints the help listing and exits.
+=item -C
+
+Cancel processing any additional files if and
+when capinfos should fail to open an input file.
+By default capinfos will attempt to open each and
+every file name argument.
+
+Note: An error message will be written to stderr
+whenever capinfos fails to open a file regardless
+of whether the -C option is specified or not.
+
+=item -A
+
+Generate all infos. By default capinfos will display
+all infos values for each input file, but enabling
+any of the individual display infos options will
+disable the generate all option.
+
+
=back
+=head1 EXAMPLES
+
+To see a description of the capinfos options use:
+
+ capinfos -h
+
+To generate a long form report for the capture file
+mycapture.pcap use:
+
+ capinfos mycapture.pcap
+
+To generate a TAB delimited table form report for the capture
+file mycapture.pcap use:
+
+ capinfos -T mycapture.pcap
+
+To generate a CSV style table form report for the capture
+file mycapture.pcap use:
+
+ capinfos -T -m -Q mycapture.pcap
+
+or
+
+ capinfos -TmQ mycapture.pcap
+
+
+To generate a TAB delimited table style report with just the
+filenames, capture type, capture encapsulation type and packet
+count for all the pcap files in the current directory use:
+
+ capinfos -T -t -E -c *.pcap
+
+or
+
+ capinfos -TtEs *.pcap
+
+Note: The ability to use of filename globbing characters are
+a feature of *nix style command shells.
+
+To generate a CSV delimited table style report of all infos
+for all pcap files in the current directory and write it to
+a text file called mycaptures.csv use:
+
+ capinfos -TmQ *.pcap >mycaptures.csv
+
+The resulting mycaptures.csv file can be easily imported
+into spreadsheet applications.
+
=head1 SEE ALSO
tcpdump(8), pcap(3), wireshark(1), mergecap(1), editcap(1), tshark(1),
Contributors
------------
Gerald Combs <gerald[AT]wireshark.org>
+ Jim Young <jyoung[AT]gsu.edu>