aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--capture_opts.c6
-rw-r--r--capture_opts.h3
-rw-r--r--doc/dumpcap.pod4
-rw-r--r--dumpcap.c12
-rw-r--r--ringbuffer.c50
-rw-r--r--ringbuffer.h1
6 files changed, 76 insertions, 0 deletions
diff --git a/capture_opts.c b/capture_opts.c
index 5d4ed86355..05a8e67897 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -116,6 +116,8 @@ capture_opts_init(capture_options *capture_opts)
capture_opts->output_to_pipe = FALSE;
capture_opts->capture_child = FALSE;
+ capture_opts->print_file_names = FALSE;
+ capture_opts->print_name_to = NULL;
}
void
@@ -248,6 +250,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
g_log(log_domain, log_level, "FileInterval (%u) : %u", capture_opts->has_file_interval, capture_opts->file_interval);
g_log(log_domain, log_level, "FilePackets (%u) : %u", capture_opts->has_file_packets, capture_opts->file_packets);
g_log(log_domain, log_level, "RingNumFiles (%u) : %u", capture_opts->has_ring_num_files, capture_opts->ring_num_files);
+ g_log(log_domain, log_level, "RingPrintFiles (%u) : %s", capture_opts->print_file_names, (capture_opts->print_file_names ? capture_opts->print_name_to : ""));
g_log(log_domain, log_level, "AutostopFiles (%u) : %u", capture_opts->has_autostop_files, capture_opts->autostop_files);
g_log(log_domain, log_level, "AutostopPackets (%u) : %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
@@ -411,6 +414,9 @@ get_ring_arguments(capture_options *capture_opts, const char *arg)
} else if (strcmp(arg,"packets") == 0) {
capture_opts->has_file_packets = TRUE;
capture_opts->file_packets = get_positive_int(p, "ring buffer packet count");
+ } else if (strcmp(arg,"printname") == 0) {
+ capture_opts->print_file_names = TRUE;
+ capture_opts->print_name_to = g_strdup(p);
}
*colonp = ':'; /* put the colon back */
diff --git a/capture_opts.h b/capture_opts.h
index e81aa72d40..82029b8eea 100644
--- a/capture_opts.h
+++ b/capture_opts.h
@@ -310,6 +310,9 @@ typedef struct capture_options_tag {
gchar *capture_comment; /** capture comment to write to the
output file */
+ gboolean print_file_names; /**< TRUE if printing names of completed
+ files as we close them */
+ gchar *print_name_to; /**< output file name */
/* internally used (don't touch from outside) */
gboolean output_to_pipe; /**< save_file is a pipe (named or stdout) */
diff --git a/doc/dumpcap.pod b/doc/dumpcap.pod
index ff8ea76c67..4dbf25f786 100644
--- a/doc/dumpcap.pod
+++ b/doc/dumpcap.pod
@@ -129,6 +129,10 @@ every hour on the hour.
B<packets>:I<value> switch to the next file after it contains I<value>
packets.
+B<printname>:I<filename> print the name of the most recently written file
+to I<filename> after the file is closed. I<filename> can be C<stdout> or C<->
+for standard output, or C<stderr> for standard error.
+
Example: B<-b filesize:1000 -b files:5> results in a ring buffer of five files
of size one megabyte each.
diff --git a/dumpcap.c b/dumpcap.c
index 2d4e0195d3..7d3a88013f 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -420,6 +420,8 @@ print_usage(FILE *output)
fprintf(output, " packets:NUM - ringbuffer: replace after NUM packets\n");
fprintf(output, " interval:NUM - switch to next file when the time is\n");
fprintf(output, " an exact multiple of NUM secs\n");
+ fprintf(output, " printname:FILE - print filename to FILE when written\n");
+ fprintf(output, " (can use 'stdout' or 'stderr')\n");
fprintf(output, " -n use pcapng format instead of pcap (default)\n");
fprintf(output, " -P use libpcap format instead of pcapng\n");
fprintf(output, " --capture-comment <comment>\n");
@@ -3400,6 +3402,16 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
g_free(capfile_name);
capfile_name = NULL;
}
+ if (capture_opts->print_file_names) {
+ if (!ringbuf_set_print_name(capture_opts->print_name_to, NULL)) {
+ g_snprintf(errmsg, errmsg_len, "Could not write filenames to %s: %s.\n",
+ capture_opts->print_name_to,
+ g_strerror(errno));
+ g_free(capfile_name);
+ ringbuf_error_cleanup();
+ return FALSE;
+ }
+ }
} else {
/* Try to open/create the specified file for use as a capture buffer. */
*save_file_fd = ws_open(capfile_name, O_WRONLY|O_BINARY|O_TRUNC|O_CREAT,
diff --git a/ringbuffer.c b/ringbuffer.c
index 2069f4de98..f674643635 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -63,6 +63,7 @@ typedef struct _ringbuf_data {
FILE *pdh;
char *io_buffer; /**< The IO buffer used to write to the file */
gboolean group_read_access; /**< TRUE if files need to be opened with group read access */
+ FILE *name_h; /**< write names of completed files to this handle */
} ringbuf_data;
static ringbuf_data rb_data;
@@ -135,6 +136,7 @@ ringbuf_init(const char *capfile_name, guint num_files, gboolean group_read_acce
rb_data.pdh = NULL;
rb_data.io_buffer = NULL;
rb_data.group_read_access = group_read_access;
+ rb_data.name_h = NULL;
/* just to be sure ... */
if (num_files <= RINGBUFFER_MAX_NUM_FILES) {
@@ -204,6 +206,34 @@ ringbuf_init(const char *capfile_name, guint num_files, gboolean group_read_acce
return rb_data.fd;
}
+/*
+ * Set name of file to which to print ringbuffer file names.
+ */
+gboolean
+ringbuf_set_print_name(gchar *name, int *err)
+{
+ if (rb_data.name_h != NULL) {
+ if (EOF == fclose(rb_data.name_h)) {
+ if (err != NULL) {
+ *err = errno;
+ }
+ return FALSE;
+ }
+ }
+ if (!strcmp(name, "-") || !strcmp(name, "stdout")) {
+ rb_data.name_h = stdout;
+ } else if (!strcmp(name, "stderr")) {
+ rb_data.name_h = stderr;
+ } else {
+ if (NULL == (rb_data.name_h = ws_fopen(name, "wt"))) {
+ if (err != NULL) {
+ *err = errno;
+ }
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
/*
* Whether the ringbuf filenames are ready.
@@ -276,6 +306,11 @@ ringbuf_switch_file(FILE **pdh, gchar **save_file, int *save_file_fd, int *err)
rb_data.pdh = NULL;
rb_data.fd = -1;
+ if (rb_data.name_h != NULL) {
+ fprintf(rb_data.name_h, "%s\n", ringbuf_current_filename());
+ fflush(rb_data.name_h);
+ }
+
/* get the next file number and open it */
rb_data.curr_file_num++ /* = next_file_num*/;
@@ -322,6 +357,15 @@ ringbuf_libpcap_dump_close(gchar **save_file, int *err)
}
+ if (rb_data.name_h != NULL) {
+ fprintf(rb_data.name_h, "%s\n", ringbuf_current_filename());
+ fflush(rb_data.name_h);
+
+ if (EOF == fclose(rb_data.name_h)) {
+ /* Can't really do much about this, can we? */
+ }
+ }
+
/* set the save file name to the current file */
*save_file = rb_data.files[rb_data.curr_file_num % rb_data.num_files].name;
return ret_val;
@@ -387,6 +431,12 @@ ringbuf_error_cleanup(void)
g_free(rb_data.io_buffer);
rb_data.io_buffer = NULL;
+ if (rb_data.name_h != NULL) {
+ if (EOF == fclose(rb_data.name_h)) {
+ /* Can't really do much about this, can we? */
+ }
+ }
+
/* free the memory */
ringbuf_free();
}
diff --git a/ringbuffer.h b/ringbuffer.h
index 4c1a3baaa9..d95dff2636 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -32,6 +32,7 @@ gboolean ringbuf_switch_file(FILE **pdh, gchar **save_file, int *save_file_fd,
gboolean ringbuf_libpcap_dump_close(gchar **save_file, int *err);
void ringbuf_free(void);
void ringbuf_error_cleanup(void);
+gboolean ringbuf_set_print_name(gchar *name, int *err);
#endif /* ringbuffer.h */