diff options
-rw-r--r-- | capture_opts.c | 6 | ||||
-rw-r--r-- | capture_opts.h | 3 | ||||
-rw-r--r-- | doc/dumpcap.pod | 4 | ||||
-rw-r--r-- | dumpcap.c | 12 | ||||
-rw-r--r-- | ringbuffer.c | 50 | ||||
-rw-r--r-- | ringbuffer.h | 1 |
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. @@ -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 */ |