diff options
-rw-r--r-- | capture.c | 84 | ||||
-rw-r--r-- | capture.h | 19 | ||||
-rw-r--r-- | capture_loop.c | 67 | ||||
-rw-r--r-- | capture_sync.c | 100 | ||||
-rw-r--r-- | capture_sync.h | 3 | ||||
-rw-r--r-- | gtk/capture_dlg.c | 147 | ||||
-rw-r--r-- | gtk/capture_if_dlg.c | 7 | ||||
-rw-r--r-- | gtk/capture_info_dlg.c | 3 | ||||
-rw-r--r-- | gtk/main.c | 131 | ||||
-rw-r--r-- | gtk/main.h | 3 |
10 files changed, 298 insertions, 266 deletions
@@ -72,7 +72,6 @@ /* * Capture options. */ -capture_options capture_opts; gboolean capture_child; /* if this is the child for "-S" */ @@ -81,19 +80,17 @@ gboolean capture_child; /* if this is the child for "-S" */ #define O_BINARY 0 #endif -static gboolean normal_do_capture(gboolean is_tempfile); +static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tempfile); static void stop_capture_signal_handler(int signo); -/* Open a specified file, or create a temporary file, and start a capture - to the file in question. Returns TRUE if the capture starts - successfully, FALSE otherwise. */ -gboolean -do_capture(const char *save_file) -{ + +/* open the output file (temporary/specified name/ringbuffer) and close the old one */ +/* Returns TRUE if the file opened successfully, FALSE otherwise. */ +static gboolean +capture_open_output(capture_options *capture_opts, const char *save_file, gboolean *is_tempfile) { char tmpname[128+1]; - gboolean is_tempfile; gchar *capfile_name; - gboolean ret; + if (save_file != NULL) { /* If the Sync option is set, we return to the caller while the capture @@ -101,29 +98,31 @@ do_capture(const char *save_file) * case the caller destroys it after we return. */ capfile_name = g_strdup(save_file); - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { /* ringbuffer is enabled */ cfile.save_file_fd = ringbuf_init(capfile_name, - (capture_opts.has_ring_num_files) ? capture_opts.ring_num_files : 0); + (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0); } else { /* Try to open/create the specified file for use as a capture buffer. */ cfile.save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, 0600); } - is_tempfile = FALSE; + *is_tempfile = FALSE; } else { - /* Choose a random name for the capture buffer */ + /* Choose a random name for the temporary capture buffer */ cfile.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether"); capfile_name = g_strdup(tmpname); - is_tempfile = TRUE; + *is_tempfile = TRUE; } + + /* did we fail to open the output file? */ if (cfile.save_file_fd == -1) { if (is_tempfile) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The temporary file to which the capture would be saved (\"%s\")" "could not be opened: %s.", capfile_name, strerror(errno)); } else { - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { ringbuf_error_cleanup(); } open_failure_alert_box(capfile_name, errno, TRUE); @@ -131,21 +130,42 @@ do_capture(const char *save_file) g_free(capfile_name); return FALSE; } + + /* close the old file */ cf_close(&cfile); g_assert(cfile.save_file == NULL); cfile.save_file = capfile_name; - /* cfile.save_file is "g_free"ed below, which is equivalent to + /* cfile.save_file is "g_free"ed later, which is equivalent to "g_free(capfile_name)". */ - if (capture_opts.sync_mode) { + return TRUE; +} + + +/* Open a specified file, or create a temporary file, and start a capture + to the file in question. */ +/* Returns TRUE if the capture starts successfully, FALSE otherwise. */ +gboolean +do_capture(capture_options *capture_opts, const char *save_file) +{ + gboolean is_tempfile; + gboolean ret; + + + /* open the output file (temporary/specified name/ringbuffer) and close the old one */ + if(!capture_open_output(capture_opts, save_file, &is_tempfile)) { + return FALSE; + } + + if (capture_opts->sync_mode) { /* sync mode: do the capture in a child process */ - ret = sync_pipe_do_capture(is_tempfile); + ret = sync_pipe_do_capture(capture_opts, is_tempfile); /* capture is still running */ set_main_window_name("(Live Capture in Progress) - Ethereal"); } else { /* normal mode: do the capture synchronously */ set_main_window_name("(Live Capture in Progress) - Ethereal"); - ret = normal_do_capture(is_tempfile); + ret = normal_do_capture(capture_opts, is_tempfile); /* capture is finished here */ } @@ -155,7 +175,7 @@ do_capture(const char *save_file) /* start a normal capture session */ static gboolean -normal_do_capture(gboolean is_tempfile) +normal_do_capture(capture_options *capture_opts, gboolean is_tempfile) { int capture_succeeded; gboolean stats_known; @@ -163,15 +183,15 @@ normal_do_capture(gboolean is_tempfile) int err; /* Not sync mode. */ - capture_succeeded = capture_start(&stats_known, &stats); - if (capture_opts.quit_after_cap) { + capture_succeeded = capture_start(capture_opts, &stats_known, &stats); + if (capture_opts->quit_after_cap) { /* DON'T unlink the save file. Presumably someone wants it. */ main_window_exit(); } if (!capture_succeeded) { /* We didn't succeed in doing the capture, so we don't have a save file. */ - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { ringbuf_free(); } else { g_free(cfile.save_file); @@ -183,7 +203,7 @@ normal_do_capture(gboolean is_tempfile) if ((err = cf_open(cfile.save_file, is_tempfile, &cfile)) != 0) { /* We're not doing a capture any more, so we don't have a save file. */ - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { ringbuf_free(); } else { g_free(cfile.save_file); @@ -244,7 +264,7 @@ normal_do_capture(gboolean is_tempfile) /* We're not doing a capture any more, so we don't have a save file. */ - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { ringbuf_free(); } else { g_free(cfile.save_file); @@ -272,7 +292,7 @@ stop_capture_signal_handler(int signo _U_) int -capture_start(gboolean *stats_known, struct pcap_stat *stats) +capture_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats) { #ifndef _WIN32 /* @@ -283,14 +303,14 @@ capture_start(gboolean *stats_known, struct pcap_stat *stats) signal(SIGUSR1, stop_capture_signal_handler); #endif - return capture_loop_start(stats_known, stats); + return capture_loop_start(capture_opts, stats_known, stats); } void -capture_stop(void) +capture_stop(gboolean sync_mode) { - if (capture_opts.sync_mode) { + if (sync_mode) { sync_pipe_stop(); } @@ -298,9 +318,9 @@ capture_stop(void) } void -kill_capture_child(void) +kill_capture_child(gboolean sync_mode) { - if (capture_opts.sync_mode) { + if (sync_mode) { sync_pipe_kill(); } } @@ -35,7 +35,7 @@ #ifdef HAVE_LIBPCAP /** Capture options coming from user interface */ -typedef struct { +typedef struct capture_options_tag { /* general */ #ifdef _WIN32 int buffer_size; /**< the capture buffer size (MB) */ @@ -43,12 +43,12 @@ typedef struct { gboolean has_snaplen; /**< TRUE if maximum capture packet length is specified */ int snaplen; /**< Maximum captured packet length */ - int promisc_mode; /**< Capture in promiscuous mode */ + gboolean promisc_mode; /**< Capture in promiscuous mode */ int linktype; /**< Data link type to use, or -1 for "use default" */ /* GUI related */ - int sync_mode; /**< Fork a child to do the capture, + gboolean sync_mode; /**< Fork a child to do the capture, and sync between them */ gboolean show_info; /**< show the info dialog */ gboolean quit_after_cap; /** Makes a "capture only mode". Implies -k */ @@ -77,9 +77,6 @@ typedef struct { gint32 autostop_duration; /**< Maximum capture duration */ } capture_options; -/** Global capture options. */ -extern capture_options capture_opts; - /** True if this is the child for "-S" */ extern gboolean capture_child; @@ -88,19 +85,19 @@ extern gboolean capture_child; * to the file in question. * * @return TRUE if the capture starts successfully, FALSE otherwise. */ -extern gboolean do_capture(const char *save_file); +extern gboolean do_capture(capture_options *capture_opts, const char *save_file); /** Do the low-level work of a capture (start the capture child). */ -extern int capture_start(gboolean *stats_known, struct pcap_stat *stats); +extern int capture_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats); /** Stop a capture from a menu item. */ -extern void capture_stop(void); +extern void capture_stop(gboolean sync_mode); /** Terminate the capture child cleanly when exiting. */ -extern void kill_capture_child(void); +extern void kill_capture_child(gboolean sync_mode); /** Do the low-level work of a capture. */ -extern int capture_loop_start(gboolean *stats_known, struct pcap_stat *stats); +extern int capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats); /** Stop a low-level capture. */ extern void capture_loop_stop(void); diff --git a/capture_loop.c b/capture_loop.c index 3f9989c408..b086dda127 100644 --- a/capture_loop.c +++ b/capture_loop.c @@ -496,7 +496,7 @@ cap_pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr, /* open the capture input file (pcap or capture pipe) */ -static int capture_loop_open_input(loop_data *ld, char *errmsg, int errmsg_len) { +static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld, char *errmsg, int errmsg_len) { gchar open_err_str[PCAP_ERRBUF_SIZE]; const char *set_linktype_err_str; #ifdef _WIN32 @@ -559,16 +559,16 @@ static int capture_loop_open_input(loop_data *ld, char *errmsg, int errmsg_len) the error buffer, and check if it's still a null string. */ open_err_str[0] = '\0'; ld->pcap_h = pcap_open_live(cfile.iface, - capture_opts.has_snaplen ? capture_opts.snaplen : + capture_opts->has_snaplen ? capture_opts->snaplen : WTAP_MAX_PACKET_SIZE, - capture_opts.promisc_mode, CAP_READ_TIMEOUT, + capture_opts->promisc_mode, CAP_READ_TIMEOUT, open_err_str); if (ld->pcap_h != NULL) { /* we've opened "cfile.iface" as a network device */ #ifdef _WIN32 /* try to set the capture buffer size */ - if (pcap_setbuff(ld->pcap_h, capture_opts.buffer_size * 1024 * 1024) != 0) { + if (pcap_setbuff(ld->pcap_h, capture_opts->buffer_size * 1024 * 1024) != 0) { simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "%sCouldn't set the capture buffer size!%s\n" "\n" @@ -576,14 +576,14 @@ static int capture_loop_open_input(loop_data *ld, char *errmsg, int errmsg_len) "the default of 1MB will be used.\n" "\n" "Nonetheless, the capture is started.\n", - simple_dialog_primary_start(), simple_dialog_primary_end(), capture_opts.buffer_size); + simple_dialog_primary_start(), simple_dialog_primary_end(), capture_opts->buffer_size); } #endif /* setting the data link type only works on real interfaces */ - if (capture_opts.linktype != -1) { + if (capture_opts->linktype != -1) { set_linktype_err_str = set_pcap_linktype(ld->pcap_h, cfile.iface, - capture_opts.linktype); + capture_opts->linktype); if (set_linktype_err_str != NULL) { g_snprintf(errmsg, errmsg_len, "Unable to set data link type (%s).", set_linktype_err_str); @@ -767,14 +767,14 @@ static int capture_loop_init_filter(loop_data *ld, char *errmsg, int errmsg_len) } -/* open the capture output file (wiretap) */ -static int capture_loop_open_output(loop_data *ld, char *errmsg, int errmsg_len) { +/* open the wiretap part of the capture output file */ +static int capture_loop_open_wiretap_output(capture_options *capture_opts, loop_data *ld, char *errmsg, int errmsg_len) { int pcap_encap; int file_snaplen; int err; - /* Set up to write to the capture file. */ + /* get packet encapsulation type and snaplen */ #ifndef _WIN32 if (ld->from_cap_pipe) { pcap_encap = ld->cap_pipe_hdr.network; @@ -786,6 +786,7 @@ static int capture_loop_open_output(loop_data *ld, char *errmsg, int errmsg_len) file_snaplen = pcap_snapshot(ld->pcap_h); } + /* Set up to write to the capture file. */ ld->wtap_linktype = wtap_pcap_encap_to_wtap_encap(pcap_encap); if (ld->wtap_linktype == WTAP_ENCAP_UNKNOWN) { g_snprintf(errmsg, errmsg_len, @@ -793,7 +794,7 @@ static int capture_loop_open_output(loop_data *ld, char *errmsg, int errmsg_len) " that Ethereal doesn't support (data link type %d).", pcap_encap); return FALSE; } - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { ld->wtap_pdh = ringbuf_init_wtap_dump_fdopen(WTAP_FILE_PCAP, ld->wtap_linktype, file_snaplen, &err); } else { @@ -836,8 +837,8 @@ static int capture_loop_open_output(loop_data *ld, char *errmsg, int errmsg_len) return TRUE; } -static gboolean capture_loop_close_output(loop_data *ld, int *err_close) { - if (capture_opts.multi_files_on) { +static gboolean capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close) { + if (capture_opts->multi_files_on) { return ringbuf_wtap_dump_close(&cfile, err_close); } else { return wtap_dump_close(ld->wtap_pdh, err_close); @@ -963,7 +964,7 @@ static loop_data ld; /* Do the low-level work of a capture. Returns TRUE if it succeeds, FALSE otherwise. */ int -capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) +capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats) { time_t upd_time, cur_time; time_t start_time; @@ -978,13 +979,13 @@ capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) capture_info capture_ui; char errmsg[4096+1]; - gboolean show_info = capture_opts.show_info || !capture_opts.sync_mode; + gboolean show_info = capture_opts->show_info || !capture_opts->sync_mode; /* init the loop data */ ld.go = TRUE; - if (capture_opts.has_autostop_packets) - ld.packets_max = capture_opts.autostop_packets; + if (capture_opts->has_autostop_packets) + ld.packets_max = capture_opts->autostop_packets; else ld.packets_max = 0; /* no limit */ ld.err = 0; /* no error seen yet */ @@ -1017,7 +1018,7 @@ capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) /* open the "input file" from network interface or capture pipe */ - if (!capture_loop_open_input(&ld, errmsg, sizeof(errmsg))) { + if (!capture_loop_open_input(capture_opts, &ld, errmsg, sizeof(errmsg))) { goto error; } @@ -1026,8 +1027,8 @@ capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) goto error; } - /* open the (wiretap) output file */ - if (!capture_loop_open_output(&ld, errmsg, sizeof(errmsg))) { + /* open the wiretap part of the output file (the output file is already open) */ + if (!capture_loop_open_wiretap_output(capture_opts, &ld, errmsg, sizeof(errmsg))) { goto error; } @@ -1053,21 +1054,21 @@ capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) /* initialize capture stop (and alike) conditions */ init_capture_stop_conditions(); /* create stop conditions */ - if (capture_opts.has_autostop_filesize) + if (capture_opts->has_autostop_filesize) cnd_autostop_size = - cnd_new(CND_CLASS_CAPTURESIZE,(long)capture_opts.autostop_filesize); - if (capture_opts.has_autostop_duration) + cnd_new(CND_CLASS_CAPTURESIZE,(long)capture_opts->autostop_filesize); + if (capture_opts->has_autostop_duration) cnd_autostop_duration = - cnd_new(CND_CLASS_TIMEOUT,(gint32)capture_opts.autostop_duration); + cnd_new(CND_CLASS_TIMEOUT,(gint32)capture_opts->autostop_duration); - if (capture_opts.multi_files_on) { - if (capture_opts.has_file_duration) + if (capture_opts->multi_files_on) { + if (capture_opts->has_file_duration) cnd_file_duration = - cnd_new(CND_CLASS_TIMEOUT, capture_opts.file_duration); + cnd_new(CND_CLASS_TIMEOUT, capture_opts->file_duration); - if (capture_opts.has_autostop_files) + if (capture_opts->has_autostop_files) cnd_autostop_files = - cnd_new(CND_CLASS_CAPTURESIZE, capture_opts.autostop_files); + cnd_new(CND_CLASS_CAPTURESIZE, capture_opts->autostop_files); } /* start capture info dialog */ @@ -1096,7 +1097,7 @@ capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) if (cnd_autostop_size != NULL && cnd_eval(cnd_autostop_size, (guint32)wtap_get_bytes_dumped(ld.wtap_pdh))){ /* Capture size limit reached, do we have another file? */ - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { if (cnd_autostop_files != NULL && cnd_eval(cnd_autostop_files, ++autostop_files)) { /* no files left: stop here */ ld.go = FALSE; @@ -1165,7 +1166,7 @@ capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) /* check capture file duration condition */ if (cnd_file_duration != NULL && cnd_eval(cnd_file_duration)) { /* duration limit reached, do we have another file? */ - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { if (cnd_autostop_files != NULL && cnd_eval(cnd_autostop_files, ++autostop_files)) { /* no files left: stop here */ ld.go = FALSE; @@ -1230,7 +1231,7 @@ capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) } /* close the wiretap (output) file */ - close_ok = capture_loop_close_output(&ld, &err_close); + close_ok = capture_loop_close_output(capture_opts, &ld, &err_close); /* If we've displayed a message about a write error, there's no point in displaying another message about an error on close. */ @@ -1275,7 +1276,7 @@ capture_loop_start(gboolean *stats_known, struct pcap_stat *stats) return write_ok && close_ok; error: - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { /* cleanup ringbuffer */ ringbuf_error_cleanup(); } else { diff --git a/capture_sync.c b/capture_sync.c index e1affe02ac..c37555ff03 100644 --- a/capture_sync.c +++ b/capture_sync.c @@ -129,6 +129,42 @@ static void sync_pipe_wait_for_child(gboolean always_report); +void +sync_pipe_capstart_to_parent(void) +{ + static const char capstart_msg = SP_CAPSTART; + + write(1, &capstart_msg, 1); +} + +void +sync_pipe_packet_count_to_parent(int packet_count) +{ + char tmp[SP_DECISIZE+1+1]; + sprintf(tmp, "%d%c", packet_count, SP_PACKET_COUNT); + write(1, tmp, strlen(tmp)); +} + +void +sync_pipe_errmsg_to_parent(const char *errmsg) +{ + int msglen = strlen(errmsg); + char lenbuf[SP_DECISIZE+1+1]; + + sprintf(lenbuf, "%u%c", msglen, SP_ERROR_MSG); + write(1, lenbuf, strlen(lenbuf)); + write(1, errmsg, msglen); +} + +void +sync_pipe_drops_to_parent(int drops) +{ + char tmp[SP_DECISIZE+1+1]; + sprintf(tmp, "%d%c", drops, SP_DROPS); + write(1, tmp, strlen(tmp)); +} + + /* Add a string pointer to a NULL-terminated array of string pointers. */ static char ** sync_pipe_add_arg(char **args, int *argc, char *arg) @@ -171,7 +207,7 @@ sync_pipe_quote_encapsulate(const char *string) gboolean -sync_pipe_do_capture(gboolean is_tempfile) { +sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) { guint byte_count; int i; guchar c; @@ -218,22 +254,22 @@ sync_pipe_do_capture(gboolean is_tempfile) { sprintf(save_file_fd,"%d",cfile.save_file_fd); /* in lieu of itoa */ argv = sync_pipe_add_arg(argv, &argc, save_file_fd); - if (capture_opts.has_autostop_packets) { + if (capture_opts->has_autostop_packets) { argv = sync_pipe_add_arg(argv, &argc, "-c"); - sprintf(scount,"%d",capture_opts.autostop_packets); + sprintf(scount,"%d",capture_opts->autostop_packets); argv = sync_pipe_add_arg(argv, &argc, scount); } - if (capture_opts.has_snaplen) { + if (capture_opts->has_snaplen) { argv = sync_pipe_add_arg(argv, &argc, "-s"); - sprintf(ssnap,"%d",capture_opts.snaplen); + sprintf(ssnap,"%d",capture_opts->snaplen); argv = sync_pipe_add_arg(argv, &argc, ssnap); } - if (capture_opts.linktype != -1) { + if (capture_opts->linktype != -1) { argv = sync_pipe_add_arg(argv, &argc, "-y"); #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME - sprintf(ssnap,"%s",pcap_datalink_val_to_name(capture_opts.linktype)); + sprintf(ssnap,"%s",pcap_datalink_val_to_name(capture_opts->linktype)); #else /* XXX - just treat it as a number */ sprintf(ssnap,"%d",capture_opts.linktype); @@ -241,23 +277,23 @@ sync_pipe_do_capture(gboolean is_tempfile) { argv = sync_pipe_add_arg(argv, &argc, ssnap); } - if (capture_opts.has_autostop_filesize) { + if (capture_opts->has_autostop_filesize) { argv = sync_pipe_add_arg(argv, &argc, "-a"); - sprintf(sautostop_filesize,"filesize:%d",capture_opts.autostop_filesize); + sprintf(sautostop_filesize,"filesize:%d",capture_opts->autostop_filesize); argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize); } - if (capture_opts.has_autostop_duration) { + if (capture_opts->has_autostop_duration) { argv = sync_pipe_add_arg(argv, &argc, "-a"); - sprintf(sautostop_duration,"duration:%d",capture_opts.autostop_duration); + sprintf(sautostop_duration,"duration:%d",capture_opts->autostop_duration); argv = sync_pipe_add_arg(argv, &argc, sautostop_duration); } - if (!capture_opts.show_info) { + if (!capture_opts->show_info) { argv = sync_pipe_add_arg(argv, &argc, "-H"); } - if (!capture_opts.promisc_mode) + if (!capture_opts->promisc_mode) argv = sync_pipe_add_arg(argv, &argc, "-p"); #ifdef _WIN32 @@ -600,13 +636,15 @@ sync_pipe_input_cb(gint source, gpointer user_data) case READ_ABORTED: /* Kill the child capture process; the user wants to exit, and we shouldn't just leave it running. */ - kill_capture_child(); + kill_capture_child(TRUE /* sync_mode */); break; } return TRUE; } + +/* the child process is going down, wait until it's completely terminated */ static void sync_pipe_wait_for_child(gboolean always_report) { @@ -654,40 +692,6 @@ sync_pipe_wait_for_child(gboolean always_report) #endif } -void -sync_pipe_errmsg_to_parent(const char *errmsg) -{ - int msglen = strlen(errmsg); - char lenbuf[SP_DECISIZE+1+1]; - - sprintf(lenbuf, "%u%c", msglen, SP_ERROR_MSG); - write(1, lenbuf, strlen(lenbuf)); - write(1, errmsg, msglen); -} - -void -sync_pipe_drops_to_parent(int drops) -{ - char tmp[SP_DECISIZE+1+1]; - sprintf(tmp, "%d%c", drops, SP_DROPS); - write(1, tmp, strlen(tmp)); -} - -void -sync_pipe_packet_count_to_parent(int packet_count) -{ - char tmp[SP_DECISIZE+1+1]; - sprintf(tmp, "%d%c", packet_count, SP_PACKET_COUNT); - write(1, tmp, strlen(tmp)); -} - -void -sync_pipe_capstart_to_parent(void) -{ - static const char capstart_msg = SP_CAPSTART; - - write(1, &capstart_msg, 1); -} #ifndef _WIN32 static char * diff --git a/capture_sync.h b/capture_sync.h index b82fcd4b4b..2daed7bc5c 100644 --- a/capture_sync.h +++ b/capture_sync.h @@ -41,11 +41,12 @@ * * Most of the parameters are passed through the global capture_opts. * + * @param capture_opts the options (formerly global) * @param is_tempfile TRUE if the current cfile is a tempfile * @return TRUE if a capture could be started, FALSE if not */ extern gboolean -sync_pipe_do_capture(gboolean is_tempfile); +sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile); /** User wants to stop capturing, gracefully close the capture child */ extern void diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c index fd9f3734c7..7633ff0e61 100644 --- a/gtk/capture_dlg.c +++ b/gtk/capture_dlg.c @@ -38,6 +38,7 @@ #include <epan/addr_resolv.h> #include "main.h" #include "ui_util.h" +#include "capture.h" #include "capture_dlg.h" #include "filter_dlg.h" #include "simple_dialog.h" @@ -122,7 +123,7 @@ capture_prep_interface_changed_cb(GtkWidget *entry, gpointer parent_w); void capture_stop_cb(GtkWidget *w _U_, gpointer d _U_) { - capture_stop(); + capture_stop(capture_opts->sync_mode); } /* @@ -669,10 +670,10 @@ capture_prep(void) buffer_size_lb = gtk_label_new("Buffer size:"); gtk_box_pack_start (GTK_BOX(linktype_hb), buffer_size_lb, FALSE, FALSE, 0); - buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.buffer_size, + buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts->buffer_size, 1, 65535, 1.0, 10.0, 0.0); buffer_size_sb = gtk_spin_button_new (buffer_size_adj, 0, 0); - gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) capture_opts.buffer_size); + gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) capture_opts->buffer_size); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (buffer_size_sb), TRUE); WIDGET_SET_SIZE(buffer_size_sb, 80, -1); gtk_tooltips_set_tip(tooltips, buffer_size_sb, @@ -687,7 +688,7 @@ capture_prep(void) promisc_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC( "Capture packets in _promiscuous mode", accel_group); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb), - capture_opts.promisc_mode); + capture_opts->promisc_mode); gtk_tooltips_set_tip(tooltips, promisc_cb, "Usually a network card will only capture the traffic sent to its own network address. " "If you want to capture all traffic that the network card can \"see\", mark this option. " @@ -700,14 +701,14 @@ capture_prep(void) snap_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC("_Limit each packet to", accel_group); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb), - capture_opts.has_snaplen); + capture_opts->has_snaplen); SIGNAL_CONNECT(snap_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, snap_cb, "Limit the maximum number of bytes to be captured from each packet. This size includes the " "link-layer header and all subsequent headers. ", NULL); gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0); - snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.snaplen, + snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts->snaplen, MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0); snap_sb = gtk_spin_button_new (snap_adj, 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE); @@ -807,7 +808,7 @@ capture_prep(void) /* multiple files row */ multi_files_on_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC("Use _multiple files", accel_group); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(multi_files_on_cb), - capture_opts.multi_files_on); + capture_opts->multi_files_on); SIGNAL_CONNECT(multi_files_on_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, multi_files_on_cb, @@ -819,7 +820,7 @@ capture_prep(void) /* Ring buffer filesize row */ ring_filesize_cb = gtk_check_button_new_with_label("Next file every"); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ring_filesize_cb), - capture_opts.has_autostop_filesize); + capture_opts->has_autostop_filesize); SIGNAL_CONNECT(ring_filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, ring_filesize_cb, "If the selected file size is exceeded, capturing switches to the next file.", @@ -833,10 +834,10 @@ capture_prep(void) WIDGET_SET_SIZE(ring_filesize_sb, 80, -1); gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_sb, 1, 2, row, row+1); - ring_filesize_om = size_unit_option_menu_new(capture_opts.autostop_filesize); + ring_filesize_om = size_unit_option_menu_new(capture_opts->autostop_filesize); gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_om, 2, 3, row, row+1); - value = size_unit_option_menu_set_value(capture_opts.autostop_filesize); + value = size_unit_option_menu_set_value(capture_opts->autostop_filesize); gtk_adjustment_set_value(ring_filesize_adj, (gfloat) value); row++; @@ -844,7 +845,7 @@ capture_prep(void) /* Ring buffer duration row */ file_duration_cb = gtk_check_button_new_with_label("Next file every"); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(file_duration_cb), - capture_opts.has_file_duration); + capture_opts->has_file_duration); SIGNAL_CONNECT(file_duration_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, file_duration_cb, @@ -859,17 +860,17 @@ capture_prep(void) WIDGET_SET_SIZE(file_duration_sb, 80, -1); gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_sb, 1, 2, row, row+1); - file_duration_om = time_unit_option_menu_new(capture_opts.file_duration); + file_duration_om = time_unit_option_menu_new(capture_opts->file_duration); gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_om, 2, 3, row, row+1); - value = time_unit_option_menu_convert_value(capture_opts.file_duration); + value = time_unit_option_menu_convert_value(capture_opts->file_duration); gtk_adjustment_set_value(file_duration_adj, (gfloat) value); row++; /* Ring buffer files row */ ringbuffer_nbf_cb = gtk_check_button_new_with_label("Ring buffer with"); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb), - capture_opts.has_ring_num_files); + capture_opts->has_ring_num_files); SIGNAL_CONNECT(ringbuffer_nbf_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, ringbuffer_nbf_cb, "After capturing has switched to the next file and the given number of files has exceeded, " @@ -877,7 +878,7 @@ capture_prep(void) NULL); gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_cb, 0, 1, row, row+1); - ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.ring_num_files, + ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts->ring_num_files, 2/*RINGBUFFER_MIN_NUM_FILES*/, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0); ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE); @@ -893,13 +894,13 @@ capture_prep(void) /* Files row */ stop_files_cb = gtk_check_button_new_with_label("Stop capture after"); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_files_cb), - capture_opts.has_autostop_files); + capture_opts->has_autostop_files); SIGNAL_CONNECT(stop_files_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, stop_files_cb, "Stop capturing after the given number of \"file switches\" have been done.", NULL); gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_cb, 0, 1, row, row+1); - stop_files_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_files, + stop_files_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts->autostop_files, 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0); stop_files_sb = gtk_spin_button_new (stop_files_adj, 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_files_sb), TRUE); @@ -929,13 +930,13 @@ capture_prep(void) /* Packet count row */ stop_packets_cb = gtk_check_button_new_with_label("... after"); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_packets_cb), - capture_opts.has_autostop_packets); + capture_opts->has_autostop_packets); SIGNAL_CONNECT(stop_packets_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, stop_packets_cb, "Stop capturing after the given number of packets have been captured.", NULL); gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_cb, 0, 1, row, row+1); - stop_packets_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_packets, + stop_packets_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts->autostop_packets, 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0); stop_packets_sb = gtk_spin_button_new (stop_packets_adj, 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_packets_sb), TRUE); @@ -950,7 +951,7 @@ capture_prep(void) /* Filesize row */ stop_filesize_cb = gtk_check_button_new_with_label("... after"); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_filesize_cb), - capture_opts.has_autostop_filesize); + capture_opts->has_autostop_filesize); SIGNAL_CONNECT(stop_filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, stop_filesize_cb, "Stop capturing after the given amount of capture data has been captured.", NULL); @@ -963,10 +964,10 @@ capture_prep(void) WIDGET_SET_SIZE(stop_filesize_sb, 80, -1); gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_sb, 1, 2, row, row+1); - stop_filesize_om = size_unit_option_menu_new(capture_opts.autostop_filesize); + stop_filesize_om = size_unit_option_menu_new(capture_opts->autostop_filesize); gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_om, 2, 3, row, row+1); - value = size_unit_option_menu_set_value(capture_opts.autostop_filesize); + value = size_unit_option_menu_set_value(capture_opts->autostop_filesize); gtk_adjustment_set_value(stop_filesize_adj, (gfloat) value); row++; @@ -974,7 +975,7 @@ capture_prep(void) /* Duration row */ stop_duration_cb = gtk_check_button_new_with_label("... after"); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_duration_cb), - capture_opts.has_autostop_duration); + capture_opts->has_autostop_duration); SIGNAL_CONNECT(stop_duration_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, stop_duration_cb, "Stop capturing after the given time is exceeded.", NULL); @@ -987,10 +988,10 @@ capture_prep(void) WIDGET_SET_SIZE(stop_duration_sb, 80, -1); gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_sb, 1, 2, row, row+1); - stop_duration_om = time_unit_option_menu_new(capture_opts.autostop_duration); + stop_duration_om = time_unit_option_menu_new(capture_opts->autostop_duration); gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_om, 2, 3, row, row+1); - value = time_unit_option_menu_convert_value(capture_opts.autostop_duration); + value = time_unit_option_menu_convert_value(capture_opts->autostop_duration); gtk_adjustment_set_value(stop_duration_adj, (gfloat) value); row++; @@ -1006,7 +1007,7 @@ capture_prep(void) sync_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC( "_Update list of packets in real time", accel_group); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb), - capture_opts.sync_mode); + capture_opts->sync_mode); SIGNAL_CONNECT(sync_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w); gtk_tooltips_set_tip(tooltips, sync_cb, "Using this option will show the captured packets immediately on the main screen. " @@ -1025,7 +1026,7 @@ capture_prep(void) /* "Hide capture info" row */ hide_info_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC( "_Hide capture info dialog", accel_group); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(hide_info_cb), !capture_opts.show_info); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(hide_info_cb), !capture_opts->show_info); gtk_tooltips_set_tip(tooltips, hide_info_cb, "Hide the capture info dialog while capturing.", NULL); gtk_container_add(GTK_CONTAINER(display_vb), hide_info_cb); @@ -1302,26 +1303,26 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { cfile.iface = g_strdup(if_name); g_free(entry_text); - capture_opts.linktype = + capture_opts->linktype = GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY)); #ifdef _WIN32 - capture_opts.buffer_size = + capture_opts->buffer_size = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb)); #endif - capture_opts.has_snaplen = + capture_opts->has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)); - if (capture_opts.has_snaplen) { - capture_opts.snaplen = + if (capture_opts->has_snaplen) { + capture_opts->snaplen = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb)); - if (capture_opts.snaplen < 1) - capture_opts.snaplen = WTAP_MAX_PACKET_SIZE; - else if (capture_opts.snaplen < MIN_PACKET_SIZE) - capture_opts.snaplen = MIN_PACKET_SIZE; + if (capture_opts->snaplen < 1) + capture_opts->snaplen = WTAP_MAX_PACKET_SIZE; + else if (capture_opts->snaplen < MIN_PACKET_SIZE) + capture_opts->snaplen = MIN_PACKET_SIZE; } - capture_opts.promisc_mode = + capture_opts->promisc_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb)); /* XXX - don't try to get clever and set "cfile.filter" to NULL if the @@ -1352,28 +1353,28 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { save_file = NULL; } - capture_opts.has_autostop_packets = + capture_opts->has_autostop_packets = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)); - if (capture_opts.has_autostop_packets) - capture_opts.autostop_packets = + if (capture_opts->has_autostop_packets) + capture_opts->autostop_packets = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_packets_sb)); - capture_opts.has_autostop_duration = + capture_opts->has_autostop_duration = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)); - if (capture_opts.has_autostop_duration) { - capture_opts.autostop_duration = + if (capture_opts->has_autostop_duration) { + capture_opts->autostop_duration = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_duration_sb)); - capture_opts.autostop_duration = - time_unit_option_menu_get_value(stop_duration_om, capture_opts.autostop_duration); + capture_opts->autostop_duration = + time_unit_option_menu_get_value(stop_duration_om, capture_opts->autostop_duration); } - capture_opts.sync_mode = + capture_opts->sync_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb)); auto_scroll_live = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb)); - capture_opts.show_info = + capture_opts->show_info = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hide_info_cb)); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb))) @@ -1389,32 +1390,32 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { else g_resolv_flags &= ~RESOLV_TRANSPORT; - capture_opts.has_ring_num_files = + capture_opts->has_ring_num_files = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)); - capture_opts.ring_num_files = + capture_opts->ring_num_files = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb)); - if (capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES) - capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES; + if (capture_opts->ring_num_files > RINGBUFFER_MAX_NUM_FILES) + capture_opts->ring_num_files = RINGBUFFER_MAX_NUM_FILES; #if RINGBUFFER_MIN_NUM_FILES > 0 - else if (capture_opts.ring_num_files < RINGBUFFER_MIN_NUM_FILES) - capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES; + else if (capture_opts->ring_num_files < RINGBUFFER_MIN_NUM_FILES) + capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES; #endif - capture_opts.multi_files_on = + capture_opts->multi_files_on = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb)); - if(capture_opts.sync_mode) - capture_opts.multi_files_on = FALSE; + if(capture_opts->sync_mode) + capture_opts->multi_files_on = FALSE; - if (capture_opts.multi_files_on) { - capture_opts.has_autostop_filesize = + if (capture_opts->multi_files_on) { + capture_opts->has_autostop_filesize = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)); - if (capture_opts.has_autostop_filesize) { + if (capture_opts->has_autostop_filesize) { tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_filesize_sb)); tmp = size_unit_option_menu_convert_value(ring_filesize_om, tmp); if(tmp != 0) { - capture_opts.autostop_filesize = tmp; + capture_opts->autostop_filesize = tmp; } else { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, PRIMARY_TEXT_START "Multiple files: Requested filesize too large!\n\n" PRIMARY_TEXT_END @@ -1429,7 +1430,7 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { PRIMARY_TEXT_START "Multiple files: No capture file name given!\n\n" PRIMARY_TEXT_END "You must specify a filename if you want to use multiple files."); return; - } else if (!capture_opts.has_autostop_filesize) { + } else if (!capture_opts->has_autostop_filesize) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, PRIMARY_TEXT_START "Multiple files: No file limit given!\n\n" PRIMARY_TEXT_END "You must specify a file size at which is switched to the next capture file\n" @@ -1438,13 +1439,13 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { return; } } else { - capture_opts.has_autostop_filesize = + capture_opts->has_autostop_filesize = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)); - if (capture_opts.has_autostop_filesize) { + if (capture_opts->has_autostop_filesize) { tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_filesize_sb)); tmp = size_unit_option_menu_convert_value(stop_filesize_om, tmp); if(tmp != 0) { - capture_opts.autostop_filesize = tmp; + capture_opts->autostop_filesize = tmp; } else { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, PRIMARY_TEXT_START "Stop Capture: Requested filesize too large!\n\n" PRIMARY_TEXT_END @@ -1454,24 +1455,24 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { } } - capture_opts.has_file_duration = + capture_opts->has_file_duration = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)); - if (capture_opts.has_file_duration) { - capture_opts.file_duration = + if (capture_opts->has_file_duration) { + capture_opts->file_duration = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(file_duration_sb)); - capture_opts.file_duration = - time_unit_option_menu_get_value(file_duration_om, capture_opts.file_duration); + capture_opts->file_duration = + time_unit_option_menu_get_value(file_duration_om, capture_opts->file_duration); } - capture_opts.has_autostop_files = + capture_opts->has_autostop_files = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)); - if (capture_opts.has_autostop_files) - capture_opts.autostop_files = + if (capture_opts->has_autostop_files) + capture_opts->autostop_files = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_files_sb)); window_destroy(GTK_WIDGET(parent_w)); - if (do_capture(save_file)) { + if (do_capture(capture_opts, save_file)) { /* The capture succeeded, which means the capture filter syntax is valid; add this capture filter to the recent capture filter list. */ cfilter_combo_add_recent(cfile.cfilter); diff --git a/gtk/capture_if_dlg.c b/gtk/capture_if_dlg.c index 287bb14397..d90a76150e 100644 --- a/gtk/capture_if_dlg.c +++ b/gtk/capture_if_dlg.c @@ -54,13 +54,14 @@ #include "compat_macros.h" #include "simple_dialog.h" +#include "capture.h" #include "capture_dlg.h" #include "ui_util.h" #include "dlg_utils.h" #include "wtap.h" -#include "capture.h" +#include "main.h" extern gboolean is_capture_in_progress(void); @@ -115,7 +116,7 @@ capture_do_cb(GtkWidget *capture_bt _U_, gpointer if_data) cfile.iface = g_strdup(if_dlg_data->device); - do_capture(NULL /* save_file */); + do_capture(capture_opts, NULL /* save_file */); } @@ -160,7 +161,7 @@ open_if(gchar *name, if_dlg_data_t *if_dlg_data) */ if_dlg_data->pch = pcap_open_live(name, MIN_PACKET_SIZE, - capture_opts.promisc_mode, CAP_READ_TIMEOUT, + capture_opts->promisc_mode, CAP_READ_TIMEOUT, open_err_str); if (if_dlg_data->pch != NULL) { diff --git a/gtk/capture_info_dlg.c b/gtk/capture_info_dlg.c index dd7385a63e..8738c5b9a5 100644 --- a/gtk/capture_info_dlg.c +++ b/gtk/capture_info_dlg.c @@ -40,6 +40,7 @@ #include "capture_combo_utils.h" #include "dlg_utils.h" #include "ui_util.h" +#include "main.h" /* a single capture counter value (with title, pointer to value and GtkWidgets) */ /* as the packet_counts is a struct, not an array, keep a pointer to the */ @@ -71,7 +72,7 @@ pct(gint num, gint denom) { static void capture_info_delete_cb(GtkWidget *w _U_, GdkEvent *event _U_, gpointer data _U_) { - capture_stop(); + capture_stop(capture_opts->sync_mode); } diff --git a/gtk/main.c b/gtk/main.c index 9637869dfa..0b334bce81 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -177,8 +177,11 @@ static void console_log_handler(const char *log_domain, #ifdef HAVE_LIBPCAP static gboolean list_link_layer_types; +capture_options global_capture_opts; +capture_options *capture_opts = &global_capture_opts; #endif + static void create_main_window(gint, gint, gint, e_prefs*); static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_); static void main_save_window_geometry(GtkWidget *widget); @@ -782,7 +785,7 @@ main_do_quit(void) #ifdef HAVE_LIBPCAP /* Nuke any child capture in progress. */ - kill_capture_child(); + kill_capture_child(capture_opts->sync_mode); #endif /* Are we in the middle of reading a capture? */ @@ -1083,11 +1086,11 @@ set_autostop_criterion(const char *autostoparg) return FALSE; } if (strcmp(autostoparg,"duration") == 0) { - capture_opts.has_autostop_duration = TRUE; - capture_opts.autostop_duration = get_positive_int(p,"autostop duration"); + capture_opts->has_autostop_duration = TRUE; + capture_opts->autostop_duration = get_positive_int(p,"autostop duration"); } else if (strcmp(autostoparg,"filesize") == 0) { - capture_opts.has_autostop_filesize = TRUE; - capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize"); + capture_opts->has_autostop_filesize = TRUE; + capture_opts->autostop_filesize = get_positive_int(p,"autostop filesize"); } else { return FALSE; } @@ -1113,7 +1116,7 @@ get_ring_arguments(const char *arg) *p++ = '\0'; } - capture_opts.ring_num_files = + capture_opts->ring_num_files = get_natural_int(arg, "number of ring buffer files"); if (colonp == NULL) @@ -1136,8 +1139,8 @@ get_ring_arguments(const char *arg) return FALSE; } - capture_opts.has_file_duration = TRUE; - capture_opts.file_duration = get_positive_int(p, + capture_opts->has_file_duration = TRUE; + capture_opts->file_duration = get_positive_int(p, "ring buffer duration"); *colonp = ':'; /* put the colon back */ @@ -1750,28 +1753,28 @@ main(int argc, char *argv[]) #endif #ifdef HAVE_LIBPCAP - capture_opts.has_snaplen = FALSE; - capture_opts.snaplen = MIN_PACKET_SIZE; - capture_opts.linktype = -1; + capture_opts->has_snaplen = FALSE; + capture_opts->snaplen = MIN_PACKET_SIZE; + capture_opts->linktype = -1; #ifdef _WIN32 - capture_opts.buffer_size = 1; + capture_opts->buffer_size = 1; #endif - capture_opts.quit_after_cap = FALSE; + capture_opts->quit_after_cap = FALSE; - capture_opts.has_autostop_packets = FALSE; - capture_opts.autostop_packets = 1; - capture_opts.has_autostop_duration = FALSE; - capture_opts.autostop_duration = 60 /* 1 min */; - capture_opts.has_autostop_filesize = FALSE; - capture_opts.autostop_filesize = 1024 * 1024 /* 1 MB */; - capture_opts.has_autostop_files = FALSE; - capture_opts.autostop_files = 1; + capture_opts->has_autostop_packets = FALSE; + capture_opts->autostop_packets = 1; + capture_opts->has_autostop_duration = FALSE; + capture_opts->autostop_duration = 60 /* 1 min */; + capture_opts->has_autostop_filesize = FALSE; + capture_opts->autostop_filesize = 1024 * 1024 /* 1 MB */; + capture_opts->has_autostop_files = FALSE; + capture_opts->autostop_files = 1; - capture_opts.multi_files_on = FALSE; - capture_opts.has_ring_num_files = TRUE; - capture_opts.ring_num_files = 2; - capture_opts.has_file_duration = FALSE; - capture_opts.file_duration = 60 /* 1 min */; + capture_opts->multi_files_on = FALSE; + capture_opts->has_ring_num_files = TRUE; + capture_opts->ring_num_files = 2; + capture_opts->has_file_duration = FALSE; + capture_opts->file_duration = 60 /* 1 min */; /* If this is a capture child process, it should pay no attention to the "prefs.capture_prom_mode" setting in the preferences file; @@ -1782,15 +1785,15 @@ main(int argc, char *argv[]) Otherwise, set promiscuous mode from the preferences setting. */ /* the same applies to other preferences settings as well. */ if (capture_child) { - capture_opts.promisc_mode = TRUE; /* maybe changed by command line below */ - capture_opts.show_info = TRUE; /* maybe changed by command line below */ - capture_opts.sync_mode = TRUE; /* always true in child process */ + capture_opts->promisc_mode = TRUE; /* maybe changed by command line below */ + capture_opts->show_info = TRUE; /* maybe changed by command line below */ + capture_opts->sync_mode = TRUE; /* always true in child process */ auto_scroll_live = FALSE; /* doesn't matter in child process */ } else { - capture_opts.promisc_mode = prefs->capture_prom_mode; - capture_opts.show_info = prefs->capture_show_info; - capture_opts.sync_mode = prefs->capture_real_time; + capture_opts->promisc_mode = prefs->capture_prom_mode; + capture_opts->show_info = prefs->capture_show_info; + capture_opts->sync_mode = prefs->capture_real_time; auto_scroll_live = prefs->capture_auto_scroll; } @@ -1891,8 +1894,8 @@ main(int argc, char *argv[]) break; case 'b': /* Ringbuffer option */ #ifdef HAVE_LIBPCAP - capture_opts.multi_files_on = TRUE; - capture_opts.has_ring_num_files = TRUE; + capture_opts->multi_files_on = TRUE; + capture_opts->has_ring_num_files = TRUE; if (get_ring_arguments(optarg) == FALSE) { fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg); exit(1); @@ -1907,8 +1910,8 @@ main(int argc, char *argv[]) break; case 'c': /* Capture xxx packets */ #ifdef HAVE_LIBPCAP - capture_opts.has_autostop_packets = TRUE; - capture_opts.autostop_packets = get_positive_int(optarg, "packet count"); + capture_opts->has_autostop_packets = TRUE; + capture_opts->autostop_packets = get_positive_int(optarg, "packet count"); #else capture_option_specified = TRUE; arg_error = TRUE; @@ -1954,7 +1957,7 @@ main(int argc, char *argv[]) break; case 'H': /* Hide capture info dialog box */ #ifdef HAVE_LIBPCAP - capture_opts.show_info = FALSE; + capture_opts->show_info = FALSE; #else capture_option_specified = TRUE; arg_error = TRUE; @@ -2004,7 +2007,7 @@ main(int argc, char *argv[]) break; case 'p': /* Don't capture in promiscuous mode */ #ifdef HAVE_LIBPCAP - capture_opts.promisc_mode = FALSE; + capture_opts->promisc_mode = FALSE; #else capture_option_specified = TRUE; arg_error = TRUE; @@ -2015,7 +2018,7 @@ main(int argc, char *argv[]) break; case 'Q': /* Quit after capture (just capture to file) */ #ifdef HAVE_LIBPCAP - capture_opts.quit_after_cap = TRUE; + capture_opts->quit_after_cap = TRUE; start_capture = TRUE; /*** -Q implies -k !! ***/ #else capture_option_specified = TRUE; @@ -2033,8 +2036,8 @@ main(int argc, char *argv[]) break; case 's': /* Set the snapshot (capture) length */ #ifdef HAVE_LIBPCAP - capture_opts.has_snaplen = TRUE; - capture_opts.snaplen = get_positive_int(optarg, "snapshot length"); + capture_opts->has_snaplen = TRUE; + capture_opts->snaplen = get_positive_int(optarg, "snapshot length"); #else capture_option_specified = TRUE; arg_error = TRUE; @@ -2042,7 +2045,7 @@ main(int argc, char *argv[]) break; case 'S': /* "Sync" mode: used for following file ala tail -f */ #ifdef HAVE_LIBPCAP - capture_opts.sync_mode = TRUE; + capture_opts->sync_mode = TRUE; #else capture_option_specified = TRUE; arg_error = TRUE; @@ -2086,15 +2089,15 @@ main(int argc, char *argv[]) case 'y': /* Set the pcap data link type */ #ifdef HAVE_LIBPCAP #ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL - capture_opts.linktype = pcap_datalink_name_to_val(optarg); - if (capture_opts.linktype == -1) { + capture_opts->linktype = pcap_datalink_name_to_val(optarg); + if (capture_opts->linktype == -1) { fprintf(stderr, "ethereal: The specified data link type \"%s\" isn't valid\n", optarg); exit(1); } #else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */ /* XXX - just treat it as a number */ - capture_opts.linktype = get_natural_int(optarg, "data link type"); + capture_opts->linktype = get_natural_int(optarg, "data link type"); #endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */ #else /* HAVE_LIBPCAP */ capture_option_specified = TRUE; @@ -2205,7 +2208,7 @@ main(int argc, char *argv[]) exit(1); } /* No - did they specify a ring buffer option? */ - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { fprintf(stderr, "ethereal: Ring buffer requested, but a capture isn't being done.\n"); exit(1); } @@ -2220,24 +2223,24 @@ main(int argc, char *argv[]) /* No - was the ring buffer option specified and, if so, does it make sense? */ - if (capture_opts.multi_files_on) { + if (capture_opts->multi_files_on) { /* Ring buffer works only under certain conditions: a) ring buffer does not work with temporary files; - b) sync_mode and capture_opts.ringbuffer_on are mutually exclusive - + b) sync_mode and capture_opts->ringbuffer_on are mutually exclusive - sync_mode takes precedence; c) it makes no sense to enable the ring buffer if the maximum file size is set to "infinite". */ if (save_file == NULL) { fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n"); - capture_opts.multi_files_on = FALSE; + 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; + capture_opts->multi_files_on = FALSE; } - if (!capture_opts.has_autostop_filesize) { + if (!capture_opts->has_autostop_filesize) { fprintf(stderr, "ethereal: Ring buffer requested, but no maximum capture file size was specified.\n"); - capture_opts.multi_files_on = FALSE; + capture_opts->multi_files_on = FALSE; } } } @@ -2354,19 +2357,19 @@ main(int argc, char *argv[]) } #ifdef HAVE_LIBPCAP - if (capture_opts.has_snaplen) { - if (capture_opts.snaplen < 1) - capture_opts.snaplen = WTAP_MAX_PACKET_SIZE; - else if (capture_opts.snaplen < MIN_PACKET_SIZE) - capture_opts.snaplen = MIN_PACKET_SIZE; + if (capture_opts->has_snaplen) { + if (capture_opts->snaplen < 1) + capture_opts->snaplen = WTAP_MAX_PACKET_SIZE; + else if (capture_opts->snaplen < MIN_PACKET_SIZE) + capture_opts->snaplen = MIN_PACKET_SIZE; } /* Check the value range of the ringbuffer_num_files parameter */ - if (capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES) - capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES; + if (capture_opts->ring_num_files > RINGBUFFER_MAX_NUM_FILES) + capture_opts->ring_num_files = RINGBUFFER_MAX_NUM_FILES; #if RINGBUFFER_MIN_NUM_FILES > 0 - else if (capture_opts.num_files < RINGBUFFER_MIN_NUM_FILES) - capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES; + else if (capture_opts->num_files < RINGBUFFER_MIN_NUM_FILES) + capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES; #endif #endif @@ -2508,7 +2511,7 @@ main(int argc, char *argv[]) #ifdef HAVE_LIBPCAP if (start_capture) { /* "-k" was specified; start a capture. */ - if (do_capture(save_file)) { + if (do_capture(capture_opts, save_file)) { /* The capture started. Open tap windows; we do so after creating the main window, to avoid GTK warnings, and after starting the capture, so we know we have something to tap. */ @@ -2538,7 +2541,7 @@ main(int argc, char *argv[]) display_queued_messages(); /* XXX - hand these stats to the parent process */ - capture_start(&stats_known, &stats); + capture_start(capture_opts, &stats_known, &stats); /* The capture is done; there's nothing more for us to do. */ gtk_exit(0); diff --git a/gtk/main.h b/gtk/main.h index a84ea22e8d..f77da78c6b 100644 --- a/gtk/main.h +++ b/gtk/main.h @@ -57,6 +57,9 @@ * @ingroup windows_group */ +/** Global capture options. */ +typedef struct capture_options_tag * p_capture_options_t; +extern p_capture_options_t capture_opts; /** User requested "Zoom In" by menu or toolbar. * |