summaryrefslogtreecommitdiff
path: root/capinfos.c
diff options
context:
space:
mode:
authorJaap Keuter <jaap.keuter@xs4all.nl>2009-11-13 21:43:57 +0000
committerJaap Keuter <jaap.keuter@xs4all.nl>2009-11-13 21:43:57 +0000
commit25470e56630323b84ba54a10eb61eefdf0927cb1 (patch)
treef6f2ade728c5aca7a8e8737f30cfd8960c4561a1 /capinfos.c
parenteeb2d89d9232730d1c572ee852cd6ef75e76779d (diff)
downloadwireshark-25470e56630323b84ba54a10eb61eefdf0927cb1.tar.gz
From Jim Young:
The ability to continue processing additional files if and when wtap_open_offline() should fail. A new -C option reverts to capinfos' original behavior which is to cancel 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. svn path=/trunk/; revision=30956
Diffstat (limited to 'capinfos.c')
-rw-r--r--capinfos.c439
1 files changed, 392 insertions, 47 deletions
diff --git a/capinfos.c b/capinfos.c
index 8c774f527f..00ed9dc38b 100644
--- a/capinfos.c
+++ b/capinfos.c
@@ -24,6 +24,29 @@
* 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
@@ -57,20 +80,54 @@
#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;
@@ -92,6 +149,69 @@ typedef struct _capture_info {
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)
{
@@ -106,7 +226,7 @@ static void print_value(gchar *text_p1, gint width, gchar *text_p2, double value
}
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;
@@ -118,6 +238,7 @@ print_stats(capture_info *cf_info)
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);
@@ -132,6 +253,156 @@ print_stats(capture_info *cf_info)
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)
{
@@ -222,8 +493,11 @@ 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;
}
@@ -246,35 +520,57 @@ usage(gboolean is_error)
" (" 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
@@ -322,58 +618,118 @@ main(int argc, char *argv[])
/* 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);
@@ -386,29 +742,15 @@ main(int argc, char *argv[])
}
}
- 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);
@@ -425,16 +767,19 @@ main(int argc, char *argv[])
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;
}