aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Lamping <ulf.lamping@web.de>2005-03-28 00:19:02 +0000
committerUlf Lamping <ulf.lamping@web.de>2005-03-28 00:19:02 +0000
commit7e78ef354ebd4f0dba19230f9095f146dcbf2978 (patch)
tree90a04c9ab245c6b9b41edef1b1924368de92d42e
parentcb859703ca66ba83e8f9cc0005a784f9aad07e90 (diff)
major capture engine rework: use two task model for EVERY capture mode
rework of the -b command line parameter (for Ethereal and Tethereal) svn path=/trunk/; revision=13949
-rw-r--r--capture.c30
-rw-r--r--capture_loop.c26
-rw-r--r--capture_opts.c59
-rw-r--r--capture_sync.c65
-rw-r--r--gtk/main.c8
-rw-r--r--ringbuffer.c6
-rw-r--r--ringbuffer.h1
7 files changed, 154 insertions, 41 deletions
diff --git a/capture.c b/capture.c
index dfee5f82b7..c29447b4fc 100644
--- a/capture.c
+++ b/capture.c
@@ -72,7 +72,7 @@
#define O_BINARY 0
#endif
-static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tempfile);
+/*static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tempfile);*/
static void stop_capture_signal_handler(int signo);
@@ -92,8 +92,16 @@ capture_open_output(capture_options *capture_opts, gboolean *is_tempfile) {
capfile_name = g_strdup(capture_opts->save_file);
if (capture_opts->multi_files_on) {
/* ringbuffer is enabled */
- capture_opts->save_file_fd = ringbuf_init(capfile_name,
- (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0);
+/* capture_opts->save_file_fd = ringbuf_init(capfile_name,
+ (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0);*/
+ /* XXX - this is a hack, we need to find a way to move this whole function to capture_loop.c */
+ capture_opts->save_file_fd = -1;
+ if(capture_opts->save_file != NULL) {
+ g_free(capture_opts->save_file);
+ }
+ capture_opts->save_file = capfile_name;
+ *is_tempfile = FALSE;
+ return TRUE;
} else {
/* Try to open/create the specified file for use as a capture buffer. */
capture_opts->save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT,
@@ -115,7 +123,7 @@ capture_open_output(capture_options *capture_opts, gboolean *is_tempfile) {
"could not be opened: %s.", capfile_name, strerror(errno));
} else {
if (capture_opts->multi_files_on) {
- ringbuf_error_cleanup();
+/* ringbuf_error_cleanup();*/
}
open_failure_alert_box(capfile_name, errno, TRUE);
}
@@ -134,17 +142,19 @@ capture_open_output(capture_options *capture_opts, gboolean *is_tempfile) {
}
+#if 0
/* close the output file (NOT the capture file) */
static void
capture_close_output(capture_options *capture_opts)
{
if (capture_opts->multi_files_on) {
- ringbuf_free();
+/* ringbuf_free();*/
} else {
g_free(capture_opts->save_file);
}
capture_opts->save_file = NULL;
}
+#endif
/* Open a specified file, or create a temporary file, and start a capture
@@ -173,17 +183,19 @@ do_capture(capture_options *capture_opts)
* If this is fixed, we could always use the sync mode, throwing away the
* normal mode completely and doing some more cleanup. */
/* if (TRUE) {*/
- if (capture_opts->sync_mode) {
+/* if (capture_opts->sync_mode) {*/
/* sync mode: do the capture in a child process */
ret = sync_pipe_do_capture(capture_opts, is_tempfile);
/* capture is still running */
cf_callback_invoke(cf_cb_live_capture_prepare, capture_opts);
+#if 0
} else {
/* normal mode: do the capture synchronously */
cf_callback_invoke(cf_cb_live_capture_prepare, capture_opts);
ret = normal_do_capture(capture_opts, is_tempfile);
/* capture is finished here */
}
+#endif
return ret;
}
@@ -268,6 +280,7 @@ guint32 drops)
}
+#if 0
/* start a normal capture session */
static gboolean
normal_do_capture(capture_options *capture_opts, gboolean is_tempfile)
@@ -292,6 +305,7 @@ normal_do_capture(capture_options *capture_opts, gboolean is_tempfile)
capture_close_output(capture_opts);
return succeeded;
}
+#endif
static void
@@ -304,7 +318,7 @@ stop_capture_signal_handler(int signo _U_)
int
capture_child_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats)
{
- gchar *err_msg;
+/* gchar *err_msg;*/
g_assert(capture_opts->capture_child);
@@ -316,6 +330,7 @@ capture_child_start(capture_options *capture_opts, gboolean *stats_known, struct
signal(SIGUSR1, stop_capture_signal_handler);
#endif
+#if 0
/* parent must have send us a file descriptor for the opened output file */
if (capture_opts->save_file_fd == -1) {
/* send this to the standard output as something our parent
@@ -325,6 +340,7 @@ capture_child_start(capture_options *capture_opts, gboolean *stats_known, struct
g_free(err_msg);
return FALSE;
}
+#endif
return capture_loop_start(capture_opts, stats_known, stats);
}
diff --git a/capture_loop.c b/capture_loop.c
index 1f947fa6f1..32771d5c04 100644
--- a/capture_loop.c
+++ b/capture_loop.c
@@ -1027,6 +1027,26 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
/* We haven't yet gotten the capture statistics. */
*stats_known = FALSE;
+ /*g_warning("capture_loop_start");
+ capture_opts_info(capture_opts);*/
+
+ /*_asm {int 3};*/
+
+ if (capture_opts->multi_files_on) {
+ /* ringbuffer is enabled */
+ capture_opts->save_file_fd = ringbuf_init(capture_opts->save_file,
+ (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0);
+ if (capture_opts->save_file_fd == -1) {
+ ringbuf_error_cleanup();
+ goto error;
+ }
+
+ /* replace save_file by current ringbuffer filename */
+ if(capture_opts->save_file) {
+ g_free(capture_opts->save_file);
+ }
+ capture_opts->save_file = g_strdup(ringbuf_current_filename());
+ }
/* open the "input file" from network interface or capture pipe */
if (!capture_loop_open_input(capture_opts, &ld, errmsg, sizeof(errmsg))) {
@@ -1123,6 +1143,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
if (cnd_file_duration) {
cnd_reset(cnd_file_duration);
}
+ if (capture_opts->capture_child) {
+ sync_pipe_filename_to_parent(capture_opts->save_file);
+ }
} else {
/* File switch failed: stop here */
ld.go = FALSE;
@@ -1191,6 +1214,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
cnd_reset(cnd_file_duration);
if(cnd_autostop_size)
cnd_reset(cnd_autostop_size);
+ if (capture_opts->capture_child) {
+ sync_pipe_filename_to_parent(capture_opts->save_file);
+ }
} else {
/* File switch failed: stop here */
ld.go = FALSE;
diff --git a/capture_opts.c b/capture_opts.c
index f2bdc06900..ccf73f62bb 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -85,6 +85,39 @@ capture_opts_init(capture_options *capture_opts, void *cfile)
capture_opts->fork_child = -1; /* invalid process handle */
}
+
+/* debug only: print content of capture_opts to console */
+void
+capture_opts_info(capture_options *capture_opts) {
+ g_warning("CAPTURE OPTIONS :");
+ g_warning("File : %s", capture_opts->cf);
+ g_warning("Filter : %s", capture_opts->cfilter);
+ g_warning("Interface : %s", capture_opts->iface);
+#ifdef _WIN32
+ g_warning("BufferSize : %u (MB)", capture_opts->buffer_size);
+#endif
+ g_warning("SnapLen (%u): %u", capture_opts->has_snaplen, capture_opts->snaplen);
+ g_warning("Promisc : %u", capture_opts->promisc_mode);
+ g_warning("LinkType : %d", capture_opts->linktype);
+ g_warning("Child : %u", capture_opts->capture_child);
+ g_warning("SaveFile : %s", capture_opts->save_file);
+ g_warning("SaveFileFd : %d", capture_opts->save_file_fd);
+ g_warning("SyncMode : %u", capture_opts->sync_mode);
+ g_warning("ShowInfo : %u", capture_opts->show_info);
+ g_warning("QuitAfterCap : %u", capture_opts->quit_after_cap);
+
+ g_warning("MultiFilesOn : %u", capture_opts->multi_files_on);
+ g_warning("FileDuration (%u): %u", capture_opts->has_file_duration, capture_opts->file_duration);
+ g_warning("RingNumFiles (%u): %u", capture_opts->has_ring_num_files, capture_opts->ring_num_files);
+
+ g_warning("AutostopFiles (%u): %u", capture_opts->has_autostop_files, capture_opts->autostop_files);
+ g_warning("AutostopPackets (%u): %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
+ g_warning("AutostopFilesize(%u): %u", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
+ g_warning("AutostopDuration(%u): %u", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
+
+ g_warning("ForkChild : %d", capture_opts->fork_child);
+}
+
/*
* Given a string of the form "<autostop criterion>:<value>", as might appear
* as an argument to a "-a" option, parse it and set the criterion in
@@ -148,18 +181,12 @@ get_ring_arguments(capture_options *capture_opts, const char *appname, const cha
gchar *p = NULL, *colonp;
colonp = strchr(arg, ':');
-
- if (colonp != NULL) {
- p = colonp;
- *p++ = '\0';
- }
-
- capture_opts->ring_num_files =
- get_natural_int(appname, arg, "number of ring buffer files");
-
if (colonp == NULL)
return TRUE;
+ p = colonp;
+ *p++ = '\0';
+
/*
* Skip over any white space (there probably won't be any, but
* as we allow it in the preferences file, we might as well
@@ -177,9 +204,16 @@ get_ring_arguments(capture_options *capture_opts, const char *appname, const cha
return FALSE;
}
- capture_opts->has_file_duration = TRUE;
- capture_opts->file_duration = get_positive_int(appname, p,
- "ring buffer duration");
+ if (strcmp(arg,"files") == 0) {
+ capture_opts->has_ring_num_files = TRUE;
+ capture_opts->ring_num_files = get_natural_int(appname, p, "number of ring buffer files");
+ } else if (strcmp(arg,"filesize") == 0) {
+ capture_opts->has_autostop_filesize = TRUE;
+ capture_opts->autostop_filesize = get_positive_int(appname, p, "ring buffer filesize");
+ } else if (strcmp(arg,"duration") == 0) {
+ capture_opts->has_file_duration = TRUE;
+ capture_opts->file_duration = get_positive_int(appname, p, "ring buffer duration");
+ }
*colonp = ':'; /* put the colon back */
return TRUE;
@@ -202,7 +236,6 @@ capture_opts_add_opt(capture_options *capture_opts, const char *appname, int opt
break;
case 'b': /* Ringbuffer option */
capture_opts->multi_files_on = TRUE;
- capture_opts->has_ring_num_files = TRUE;
if (get_ring_arguments(capture_opts, appname, optarg) == FALSE) {
fprintf(stderr, "%s: Invalid or unknown -b arg \"%s\"\n", appname, optarg);
exit(1);
diff --git a/capture_sync.c b/capture_sync.c
index 092cce08d5..9cb7a12e4f 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -221,7 +221,11 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
char *msg;
int err;
char ssnap[24];
- char scount[24]; /* need a constant for len of numbers */
+ char scount[24]; /* need a constant for len of numbers */
+ char sfilesize[24]; /* need a constant for len of numbers */
+ char sfile_duration[24]; /* need a constant for len of numbers */
+ char sring_num_files[24]; /* need a constant for len of numbers */
+ char sautostop_files[24]; /* need a constant for len of numbers */
char sautostop_filesize[24]; /* need a constant for len of numbers */
char sautostop_duration[24]; /* need a constant for len of numbers */
char save_file_fd_str[24];
@@ -239,6 +243,10 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
int sync_pipe[2]; /* pipes used to sync between instances */
+
+ /*g_warning("sync_pipe_do_capture");
+ capture_opts_info(capture_opts);*/
+
capture_opts->fork_child = -1;
/* Allocate the string pointer array with enough space for the
@@ -260,12 +268,6 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
sprintf(save_file_fd_str,"%d",capture_opts->save_file_fd); /* in lieu of itoa */
argv = sync_pipe_add_arg(argv, &argc, save_file_fd_str);
- if (capture_opts->has_autostop_packets) {
- argv = sync_pipe_add_arg(argv, &argc, "-c");
- sprintf(scount,"%d",capture_opts->autostop_packets);
- argv = sync_pipe_add_arg(argv, &argc, scount);
- }
-
if (capture_opts->has_snaplen) {
argv = sync_pipe_add_arg(argv, &argc, "-s");
sprintf(ssnap,"%d",capture_opts->snaplen);
@@ -283,10 +285,42 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
argv = sync_pipe_add_arg(argv, &argc, ssnap);
}
- if (capture_opts->has_autostop_filesize) {
- argv = sync_pipe_add_arg(argv, &argc, "-a");
- sprintf(sautostop_filesize,"filesize:%d",capture_opts->autostop_filesize);
- argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
+ if(capture_opts->multi_files_on) {
+ if (capture_opts->has_autostop_filesize) {
+ argv = sync_pipe_add_arg(argv, &argc, "-b");
+ sprintf(sfilesize,"filesize:%d",capture_opts->autostop_filesize);
+ argv = sync_pipe_add_arg(argv, &argc, sfilesize);
+ }
+
+ if (capture_opts->has_file_duration) {
+ argv = sync_pipe_add_arg(argv, &argc, "-b");
+ sprintf(sfile_duration,"duration:%d",capture_opts->file_duration);
+ argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
+ }
+
+ if (capture_opts->has_ring_num_files) {
+ argv = sync_pipe_add_arg(argv, &argc, "-b");
+ sprintf(sring_num_files,"files:%d",capture_opts->ring_num_files);
+ argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
+ }
+
+ if (capture_opts->has_autostop_files) {
+ argv = sync_pipe_add_arg(argv, &argc, "-a");
+ sprintf(sautostop_files,"files:%d",capture_opts->autostop_files);
+ argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
+ }
+ } else {
+ if (capture_opts->has_autostop_filesize) {
+ argv = sync_pipe_add_arg(argv, &argc, "-a");
+ sprintf(sautostop_filesize,"filesize:%d",capture_opts->autostop_filesize);
+ argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
+ }
+ }
+
+ if (capture_opts->has_autostop_packets) {
+ argv = sync_pipe_add_arg(argv, &argc, "-c");
+ sprintf(scount,"%d",capture_opts->autostop_packets);
+ argv = sync_pipe_add_arg(argv, &argc, scount);
}
if (capture_opts->has_autostop_duration) {
@@ -304,7 +338,6 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
#ifdef _WIN32
/* Create a pipe for the child process */
-
if(_pipe(sync_pipe, 512, O_BINARY) < 0) {
/* Couldn't create the pipe between parent and child. */
error = errno;
@@ -402,7 +435,9 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
/* Close the save file FD, as we won't be using it - we'll be opening
it and reading the save file through Wiretap. */
- close(capture_opts->save_file_fd);
+ if(capture_opts->save_file_fd != -1) {
+ close(capture_opts->save_file_fd);
+ }
if (capture_opts->fork_child == -1) {
/* We couldn't even create the child process. */
@@ -676,10 +711,6 @@ sync_pipe_input_cb(gint source, gpointer user_data)
}
*r = '\0';
- /* currently, both filenames must be equal */
- /* (this will change, when multiple files together with sync_mode are captured) */
- g_assert(strcmp(capture_opts->save_file, msg) == 0);
-
/* save the new filename */
if(capture_opts->save_file != NULL) {
g_free(capture_opts->save_file);
diff --git a/gtk/main.c b/gtk/main.c
index 327f257a21..a269d867d0 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -2070,12 +2070,12 @@ main(int argc, char *argv[])
fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n");
capture_opts->multi_files_on = FALSE;
}
- if (capture_opts->sync_mode) {
+/* if (capture_opts->sync_mode) {
fprintf(stderr, "ethereal: Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.\n");
capture_opts->multi_files_on = FALSE;
- }
- if (!capture_opts->has_autostop_filesize) {
- fprintf(stderr, "ethereal: Ring buffer requested, but no maximum capture file size was specified.\n");
+ }*/
+ if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
+ fprintf(stderr, "ethereal: Ring buffer requested, but no maximum capture file size or duration were specified.\n");
capture_opts->multi_files_on = FALSE;
}
}
diff --git a/ringbuffer.c b/ringbuffer.c
index 1a89e6d4bb..4cfc637a3c 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -232,6 +232,12 @@ ringbuf_init(const char *capfile_name, guint num_files)
return rb_data.fd;
}
+
+const gchar *ringbuf_current_filename(void)
+{
+ return rb_data.files[rb_data.curr_file_num % rb_data.num_files].name;
+}
+
/*
* Calls wtap_dump_fdopen() for the current ringbuffer file
*/
diff --git a/ringbuffer.h b/ringbuffer.h
index b5904053e3..8962cf1dac 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -38,6 +38,7 @@
#define RINGBUFFER_MAX_NUM_FILES 1024
int ringbuf_init(const char *capture_name, guint num_files);
+const gchar *ringbuf_current_filename(void);
wtap_dumper* ringbuf_init_wtap_dump_fdopen(int filetype, int linktype,
int snaplen, int *err);
gboolean ringbuf_switch_file(wtap_dumper **pdh, gchar **save_file, int *save_file_fd, int *err);