#ifdef HAVE_LIBPCAP
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "capture-wpcap.h"
#endif
#include "ui_util.h"
+#include "log.h"
/* close the currently loaded capture file */
cf_close(capture_opts->cf);
+ g_assert(capture_opts->state == CAPTURE_STOPPED);
+ capture_opts->state = CAPTURE_PREPARING;
+
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start ...");
+
/* try to start the capture child process */
- ret = sync_pipe_start(capture_opts, capture_opts->save_file == NULL);
+ ret = sync_pipe_start(capture_opts);
if(!ret) {
if(capture_opts->save_file != NULL) {
g_free(capture_opts->save_file);
capture_opts->save_file = NULL;
}
+
+ capture_opts->state = CAPTURE_STOPPED;
+ } else {
+ /* the capture child might not respond shortly after bringing it up */
+ /* (especially it will block, if no input coming from an input capture pipe (e.g. mkfifo) is coming in) */
+
+ /* to prevent problems, bring the main GUI into "capture mode" right after successfully */
+ /* spawn/exec the capture child, without waiting for any response from it */
+ cf_callback_invoke(cf_cb_live_capture_prepared, capture_opts);
}
return ret;
void
capture_stop(capture_options *capture_opts)
{
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Stop ...");
+
/* stop the capture child gracefully */
sync_pipe_stop(capture_opts);
}
+
+void
+capture_restart(capture_options *capture_opts)
+{
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Restart");
+
+ capture_opts->restart = TRUE;
+ capture_stop(capture_opts);
+}
+
+
void
capture_kill_child(capture_options *capture_opts)
{
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "Capture Kill");
+
/* kill the capture child */
sync_pipe_kill(capture_opts);
}
}
/* if we didn't captured even a single packet, close the file again */
- if(cf_packet_count(capture_opts->cf) == 0) {
+ if(cf_packet_count(capture_opts->cf) == 0 && !capture_opts->restart) {
simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
"%sNo packets captured!%s\n\n"
"As no data was captured, closing the %scapture file!",
int err;
- /*g_warning("New capture file: %s", new_file);*/
+ if(capture_opts->state == CAPTURE_PREPARING) {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture started!");
+ }
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "File: \"%s\"", new_file);
+
+ g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
/* free the old filename */
if(capture_opts->save_file != NULL) {
cf_callback_invoke(cf_cb_live_capture_fixed_started, capture_opts);
}
+ capture_opts->state = CAPTURE_RUNNING;
return TRUE;
}
int err;
+ g_assert(capture_opts->save_file);
+
if(capture_opts->real_time_mode) {
/* Read from the capture file the number of records the child told us
it added.
file.
XXX - abort on a read error? */
+ cf_callback_invoke(cf_cb_live_capture_update_continue, capture_opts->cf);
+ main_window_update();
break;
case CF_READ_ABORTED:
int err;
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!");
+ g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
+
+ /* if we didn't started the capture (happens if an error occured), do a fake start */
+ if(capture_opts->state == CAPTURE_PREPARING) {
+ if(capture_opts->real_time_mode) {
+ cf_callback_invoke(cf_cb_live_capture_update_started, capture_opts);
+ } else {
+ cf_callback_invoke(cf_cb_live_capture_fixed_started, capture_opts);
+ }
+ }
+
if(capture_opts->real_time_mode) {
/* first of all, we are not doing a capture any more */
cf_callback_invoke(cf_cb_live_capture_update_finished, capture_opts->cf);
switch (cf_finish_tail(capture_opts->cf, &err)) {
case CF_READ_OK:
- if(cf_packet_count(capture_opts->cf) == 0) {
+ if(cf_packet_count(capture_opts->cf) == 0 && !capture_opts->restart) {
simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
"%sNo packets captured!%s\n\n"
"As no data was captured, closing the %scapture file!",
/* first of all, we are not doing a capture any more */
cf_callback_invoke(cf_cb_live_capture_fixed_finished, capture_opts->cf);
- /* this is a normal mode capture, read in the capture file data */
- capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf),
- cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
+ /* this is a normal mode capture and if no error happened, read in the capture file data */
+ if(capture_opts->save_file != NULL) {
+ capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf),
+ cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
+ }
+ }
+
+ capture_opts->state = CAPTURE_STOPPED;
+
+ /* if we couldn't open a capture file, there's nothing more for us to do */
+ if(capture_opts->save_file == NULL) {
+ cf_close(capture_opts->cf);
+ return;
}
- /* We're not doing a capture any more, so we don't have a save file. */
- if(capture_opts->save_file) {
+ /* does the user wants to restart the current capture? */
+ if(capture_opts->restart) {
+ capture_opts->restart = FALSE;
+
+ unlink(capture_opts->save_file);
+
+ /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */
+ if(cf_is_tempfile(capture_opts->cf)) {
+ g_free(capture_opts->save_file);
+ capture_opts->save_file = NULL;
+ }
+
+ /* ... and start the capture again */
+ capture_start(capture_opts);
+ } else {
+ /* We're not doing a capture any more, so we don't have a save file. */
g_free(capture_opts->save_file);
capture_opts->save_file = NULL;
}