1998-09-16 02:39:15 +00:00
|
|
|
/* capture.c
|
|
|
|
* Routines for packet capture windows
|
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
1998-09-16 03:22:19 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* Ethereal - Network traffic analyzer
|
2001-10-25 06:41:48 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
1998-09-16 02:39:15 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2004-05-09 10:03:41 +00:00
|
|
|
/* With MSVC and a libethereal.dll this file needs to import some variables
|
|
|
|
in a special way. Therefore _NEED_VAR_IMPORT_ is defined. */
|
|
|
|
#define _NEED_VAR_IMPORT_
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
1999-07-09 04:18:36 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
|
1998-12-17 05:42:33 +00:00
|
|
|
#include <stdlib.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <string.h>
|
2000-08-11 13:37:21 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_FCNTL_H
|
1999-10-02 06:26:53 +00:00
|
|
|
#include <fcntl.h>
|
2000-08-11 13:37:21 +00:00
|
|
|
#endif
|
1999-08-03 20:51:41 +00:00
|
|
|
|
2004-10-30 23:26:47 +00:00
|
|
|
#ifdef HAVE_IO_H
|
|
|
|
# include <io.h>
|
1999-08-03 20:51:41 +00:00
|
|
|
#endif
|
|
|
|
|
1999-05-11 18:51:10 +00:00
|
|
|
#include <signal.h>
|
|
|
|
#include <errno.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2004-10-30 23:26:47 +00:00
|
|
|
#include <pcap.h>
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
2003-10-11 21:49:56 +00:00
|
|
|
#include <epan/dfilter/dfilter.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "file.h"
|
|
|
|
#include "capture.h"
|
2004-10-30 11:44:06 +00:00
|
|
|
#include "capture_sync.h"
|
2005-01-16 02:56:28 +00:00
|
|
|
#include "capture_ui_utils.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "util.h"
|
2001-11-09 07:44:51 +00:00
|
|
|
#include "pcap-util.h"
|
2004-02-11 01:23:25 +00:00
|
|
|
#include "alert_box.h"
|
2000-01-03 06:59:25 +00:00
|
|
|
#include "simple_dialog.h"
|
2004-09-27 22:55:15 +00:00
|
|
|
#include <epan/prefs.h>
|
1999-09-09 03:32:03 +00:00
|
|
|
#include "globals.h"
|
2001-12-04 07:32:05 +00:00
|
|
|
#include "conditions.h"
|
2001-12-04 08:26:00 +00:00
|
|
|
#include "ringbuffer.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2002-12-31 21:12:55 +00:00
|
|
|
#ifdef _WIN32
|
2001-11-09 07:44:51 +00:00
|
|
|
#include "capture-wpcap.h"
|
|
|
|
#endif
|
2004-01-22 18:13:57 +00:00
|
|
|
#include "ui_util.h"
|
2001-11-09 07:44:51 +00:00
|
|
|
|
2000-06-15 08:02:43 +00:00
|
|
|
|
2004-06-30 06:58:59 +00:00
|
|
|
/* Win32 needs the O_BINARY flag for open() */
|
|
|
|
#ifndef O_BINARY
|
|
|
|
#define O_BINARY 0
|
|
|
|
#endif
|
2000-09-15 05:32:49 +00:00
|
|
|
|
2004-12-29 09:09:35 +00:00
|
|
|
static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tempfile);
|
2004-02-21 14:04:17 +00:00
|
|
|
static void stop_capture_signal_handler(int signo);
|
|
|
|
|
2004-12-29 09:09:35 +00:00
|
|
|
|
|
|
|
/* 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) {
|
Move the toolkit-independent code to create a temporary capture file,
and to fork off and run a separate copy of "ethereal" for "-S" and "-F"
captures or just call "capture()" otherwise, out of "gtk/capture_dlg.c"
and into a routine in "capture.c".
If the attempt to create said temporary capture file fails, pop up a
dialog box and don't do the capture.
Have the child capture process send a message upstream after it either
successfully starts the capture and syncs out the header of the capture
file, or fails to start the capture; the message indicates whether it
succeeded or failed, and, if it failed, includes a failure message.
This:
avoids the use of a signal, and thus means we don't have to
worry about whether to capture the signal, or whether to start
or stop capturing depending on whether this particular capture
is in sync mode or not;
lets us pop up the message box for the error in the parent
process if we're in sync mode, rather than doing it in the
child, which didn't work well.
Add a check button to the Capture/Start dialog box, so that we can
control, for each capture, whether it's to be done in sync mode or not.
svn path=/trunk/; revision=708
1999-09-23 06:27:27 +00:00
|
|
|
char tmpname[128+1];
|
2002-09-09 20:39:01 +00:00
|
|
|
gchar *capfile_name;
|
2004-12-29 09:09:35 +00:00
|
|
|
|
2002-09-09 20:39:01 +00:00
|
|
|
|
|
|
|
if (save_file != NULL) {
|
|
|
|
/* If the Sync option is set, we return to the caller while the capture
|
|
|
|
* is in progress. Therefore we need to take a copy of save_file in
|
|
|
|
* case the caller destroys it after we return.
|
|
|
|
*/
|
|
|
|
capfile_name = g_strdup(save_file);
|
2004-12-29 09:09:35 +00:00
|
|
|
if (capture_opts->multi_files_on) {
|
2001-12-04 08:26:00 +00:00
|
|
|
/* ringbuffer is enabled */
|
2002-02-24 09:25:36 +00:00
|
|
|
cfile.save_file_fd = ringbuf_init(capfile_name,
|
2004-12-29 09:09:35 +00:00
|
|
|
(capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0);
|
2001-12-04 08:26:00 +00:00
|
|
|
} else {
|
|
|
|
/* Try to open/create the specified file for use as a capture buffer. */
|
2002-02-24 09:25:36 +00:00
|
|
|
cfile.save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT,
|
|
|
|
0600);
|
2001-12-04 08:26:00 +00:00
|
|
|
}
|
2004-12-29 09:09:35 +00:00
|
|
|
*is_tempfile = FALSE;
|
1999-10-02 06:26:53 +00:00
|
|
|
} else {
|
2004-12-29 09:09:35 +00:00
|
|
|
/* Choose a random name for the temporary capture buffer */
|
2000-06-27 04:36:03 +00:00
|
|
|
cfile.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
|
1999-10-02 06:26:53 +00:00
|
|
|
capfile_name = g_strdup(tmpname);
|
2004-12-29 09:09:35 +00:00
|
|
|
*is_tempfile = TRUE;
|
1999-10-02 06:26:53 +00:00
|
|
|
}
|
2004-12-29 09:09:35 +00:00
|
|
|
|
|
|
|
/* did we fail to open the output file? */
|
2000-06-27 04:36:03 +00:00
|
|
|
if (cfile.save_file_fd == -1) {
|
2000-07-20 05:10:02 +00:00
|
|
|
if (is_tempfile) {
|
2004-01-31 03:22:42 +00:00
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
2000-07-20 05:10:02 +00:00
|
|
|
"The temporary file to which the capture would be saved (\"%s\")"
|
1999-11-28 09:44:53 +00:00
|
|
|
"could not be opened: %s.", capfile_name, strerror(errno));
|
2000-07-20 05:10:02 +00:00
|
|
|
} else {
|
2004-12-29 09:09:35 +00:00
|
|
|
if (capture_opts->multi_files_on) {
|
2001-12-04 08:26:00 +00:00
|
|
|
ringbuf_error_cleanup();
|
|
|
|
}
|
2004-02-11 01:23:25 +00:00
|
|
|
open_failure_alert_box(capfile_name, errno, TRUE);
|
2000-07-20 05:10:02 +00:00
|
|
|
}
|
2002-09-09 20:39:01 +00:00
|
|
|
g_free(capfile_name);
|
2003-09-15 23:15:32 +00:00
|
|
|
return FALSE;
|
Move the toolkit-independent code to create a temporary capture file,
and to fork off and run a separate copy of "ethereal" for "-S" and "-F"
captures or just call "capture()" otherwise, out of "gtk/capture_dlg.c"
and into a routine in "capture.c".
If the attempt to create said temporary capture file fails, pop up a
dialog box and don't do the capture.
Have the child capture process send a message upstream after it either
successfully starts the capture and syncs out the header of the capture
file, or fails to start the capture; the message indicates whether it
succeeded or failed, and, if it failed, includes a failure message.
This:
avoids the use of a signal, and thus means we don't have to
worry about whether to capture the signal, or whether to start
or stop capturing depending on whether this particular capture
is in sync mode or not;
lets us pop up the message box for the error in the parent
process if we're in sync mode, rather than doing it in the
child, which didn't work well.
Add a check button to the Capture/Start dialog box, so that we can
control, for each capture, whether it's to be done in sync mode or not.
svn path=/trunk/; revision=708
1999-09-23 06:27:27 +00:00
|
|
|
}
|
2004-12-29 09:09:35 +00:00
|
|
|
|
|
|
|
/* close the old file */
|
2003-09-15 22:48:42 +00:00
|
|
|
cf_close(&cfile);
|
2000-06-27 04:36:03 +00:00
|
|
|
g_assert(cfile.save_file == NULL);
|
|
|
|
cfile.save_file = capfile_name;
|
2004-12-29 09:09:35 +00:00
|
|
|
/* cfile.save_file is "g_free"ed later, which is equivalent to
|
2002-09-09 20:39:01 +00:00
|
|
|
"g_free(capfile_name)". */
|
Add a new global flag "capture_child", which is TRUE if we're a child
process for a sync mode or fork mode capture.
Have that flag control whether we do things that *only* the parent or
*only* the child should do, rather than basing it solely on the setting
of "sync_mode" or "fork_mode" (or, in the case of stuff done in the
child process either in sync mode or fork mode, rather than basing it on
the setting of those flags at all).
Split "do_capture()" into a "run_capture()" routine that starts a
capture (possibly by forking off and execing a child process, if we're
supposed to do sync mode or fork mode captures), and that assumes the
file to which the capture is to write has already been opened and that
"cf.save_file_fd" is the file descriptor for that file, and a
"do_capture()" routine that creates a temporary file, getting an FD for
it, and calls "run_capture()".
Use "run_capture()", rather than "capture()", for "-k" captures, so that
it'll do the capture in a child process if "-S" or "-F" was specified
("do_capture()" won't do because "-k" captures should write to the file
specified by the "-w" flag, not some random temporary file).
For child process captures, however, just use "capture()" - the child
process shouldn't itself fork off a child if we're in sync or fork mode,
and should just write to the file whose file descriptor was specified by
the "-W" flag on the command line.
All this allows you to do "ethereal -S -w <file> -i <interface> -k" to
start a sync mode capture from the command line.
svn path=/trunk/; revision=740
1999-09-30 06:50:01 +00:00
|
|
|
|
2004-12-29 09:09:35 +00:00
|
|
|
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;
|
2005-01-16 02:48:41 +00:00
|
|
|
gchar *title;
|
2004-12-29 09:09:35 +00:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2005-01-16 02:48:41 +00:00
|
|
|
title = g_strdup_printf("%s: Capturing - Ethereal",
|
|
|
|
get_interface_descriptive_name(cfile.iface));
|
2004-12-29 09:09:35 +00:00
|
|
|
if (capture_opts->sync_mode) {
|
2004-02-21 12:58:42 +00:00
|
|
|
/* sync mode: do the capture in a child process */
|
2004-12-29 09:09:35 +00:00
|
|
|
ret = sync_pipe_do_capture(capture_opts, is_tempfile);
|
2004-02-21 12:58:42 +00:00
|
|
|
/* capture is still running */
|
2005-01-16 02:48:41 +00:00
|
|
|
set_main_window_name(title);
|
2004-02-21 12:58:42 +00:00
|
|
|
} else {
|
|
|
|
/* normal mode: do the capture synchronously */
|
2005-01-16 02:48:41 +00:00
|
|
|
set_main_window_name(title);
|
2004-12-29 09:09:35 +00:00
|
|
|
ret = normal_do_capture(capture_opts, is_tempfile);
|
2004-02-21 12:58:42 +00:00
|
|
|
/* capture is finished here */
|
|
|
|
}
|
2005-01-16 02:48:41 +00:00
|
|
|
g_free(title);
|
2004-06-20 13:39:44 +00:00
|
|
|
|
|
|
|
return ret;
|
2004-02-21 12:58:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-30 11:44:06 +00:00
|
|
|
/* start a normal capture session */
|
2004-02-21 12:58:42 +00:00
|
|
|
static gboolean
|
2004-12-29 09:09:35 +00:00
|
|
|
normal_do_capture(capture_options *capture_opts, gboolean is_tempfile)
|
2004-02-21 12:58:42 +00:00
|
|
|
{
|
|
|
|
int capture_succeeded;
|
|
|
|
gboolean stats_known;
|
|
|
|
struct pcap_stat stats;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
/* Not sync mode. */
|
2004-12-29 09:09:35 +00:00
|
|
|
capture_succeeded = capture_start(capture_opts, &stats_known, &stats);
|
|
|
|
if (capture_opts->quit_after_cap) {
|
2004-02-21 12:58:42 +00:00
|
|
|
/* 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. */
|
2004-12-29 09:09:35 +00:00
|
|
|
if (capture_opts->multi_files_on) {
|
2004-02-21 12:58:42 +00:00
|
|
|
ringbuf_free();
|
|
|
|
} else {
|
|
|
|
g_free(cfile.save_file);
|
|
|
|
}
|
|
|
|
cfile.save_file = NULL;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
/* Capture succeeded; attempt to read in the capture file. */
|
|
|
|
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. */
|
2004-12-29 09:09:35 +00:00
|
|
|
if (capture_opts->multi_files_on) {
|
2004-02-21 12:58:42 +00:00
|
|
|
ringbuf_free();
|
|
|
|
} else {
|
|
|
|
g_free(cfile.save_file);
|
|
|
|
}
|
|
|
|
cfile.save_file = NULL;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the read filter to NULL. */
|
|
|
|
cfile.rfcode = NULL;
|
|
|
|
|
|
|
|
/* Get the packet-drop statistics.
|
|
|
|
|
|
|
|
XXX - there are currently no packet-drop statistics stored
|
|
|
|
in libpcap captures, and that's what we're reading.
|
|
|
|
|
|
|
|
At some point, we will add support in Wiretap to return
|
|
|
|
packet-drop statistics for capture file formats that store it,
|
|
|
|
and will make "cf_read()" get those statistics from Wiretap.
|
|
|
|
We clear the statistics (marking them as "not known") in
|
|
|
|
"cf_open()", and "cf_read()" will only fetch them and mark
|
|
|
|
them as known if Wiretap supplies them, so if we get the
|
|
|
|
statistics now, after calling "cf_open()" but before calling
|
|
|
|
"cf_read()", the values we store will be used by "cf_read()".
|
|
|
|
|
|
|
|
If a future libpcap capture file format stores the statistics,
|
|
|
|
we'll put them into the capture file that we write, and will
|
|
|
|
thus not have to set them here - "cf_read()" will get them from
|
|
|
|
the file and use them. */
|
|
|
|
if (stats_known) {
|
|
|
|
cfile.drops_known = TRUE;
|
|
|
|
|
|
|
|
/* XXX - on some systems, libpcap doesn't bother filling in
|
|
|
|
"ps_ifdrop" - it doesn't even set it to zero - so we don't
|
|
|
|
bother looking at it.
|
|
|
|
|
|
|
|
Ideally, libpcap would have an interface that gave us
|
|
|
|
several statistics - perhaps including various interface
|
|
|
|
error statistics - and would tell us which of them it
|
|
|
|
supplies, allowing us to display only the ones it does. */
|
|
|
|
cfile.drops = stats.ps_drop;
|
|
|
|
}
|
|
|
|
switch (cf_read(&cfile)) {
|
|
|
|
|
|
|
|
case READ_SUCCESS:
|
|
|
|
case READ_ERROR:
|
|
|
|
/* Just because we got an error, that doesn't mean we were unable
|
|
|
|
to read any of the file; we handle what we could get from the
|
|
|
|
file. */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case READ_ABORTED:
|
|
|
|
/* Exit by leaving the main loop, so that any quit functions
|
|
|
|
we registered get called. */
|
|
|
|
main_window_nested_quit();
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We're not doing a capture any more, so we don't have a save
|
|
|
|
file. */
|
2004-12-29 09:09:35 +00:00
|
|
|
if (capture_opts->multi_files_on) {
|
2004-02-21 12:58:42 +00:00
|
|
|
ringbuf_free();
|
|
|
|
} else {
|
|
|
|
g_free(cfile.save_file);
|
|
|
|
}
|
|
|
|
cfile.save_file = NULL;
|
|
|
|
|
|
|
|
/* if we didn't captured even a single packet, close the file again */
|
|
|
|
if(cfile.count == 0) {
|
|
|
|
simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
|
|
|
|
"%sNo packets captured!%s\n\n"
|
|
|
|
"As no data was captured, closing the %scapture file!",
|
|
|
|
simple_dialog_primary_start(), simple_dialog_primary_end(),
|
|
|
|
(cfile.is_tempfile) ? "temporary " : "");
|
|
|
|
cf_close(&cfile);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Enough is enough. Requiring anybody who uses Ethereal on Linux to
update their libpcap probably isn't going to scale - the increasing
frequency with which "Ethereal hangs when I try to capture packets"
shows up on "ethereal-dev" suggests that, unless and until a libpcap
with the "select()" in it becomes ubiquitous on Linux, that'll be the
source of a constant support burden - so we'll just put the "select()"
in Ethereal if it's being built for Linux.
(Putting it in for platforms where the read timeout argument to
"pcap_open_live()" works adds an extra useless system call at best and,
at worst, could make Ethereal not work - "select()" doesn't work on
"/dev/bpf" devices on FreeBSD 3.3, at least, unless you're in "immediate
mode", and, whilst "immediate mode" would make Ethereal respond more
quickly when packets arrive, it might cause Ethereal to respond too
quickly, doing reads for every new packet rather than waiting for
multiple packets to arrive and reading them all with one "read()", which
appears to be at least part of the intent of the read timeout on
"/dev/bpf" devices in BSD.)
svn path=/trunk/; revision=1451
2000-01-12 06:56:32 +00:00
|
|
|
|
2000-07-30 16:54:12 +00:00
|
|
|
static void
|
2004-10-30 17:50:51 +00:00
|
|
|
stop_capture_signal_handler(int signo _U_)
|
2000-07-30 16:54:12 +00:00
|
|
|
{
|
2004-10-30 17:50:51 +00:00
|
|
|
capture_loop_stop();
|
2000-07-30 16:54:12 +00:00
|
|
|
}
|
|
|
|
|
2000-10-11 06:01:16 +00:00
|
|
|
|
2004-10-30 17:50:51 +00:00
|
|
|
int
|
2004-12-29 09:09:35 +00:00
|
|
|
capture_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats)
|
Move the toolkit-independent code to create a temporary capture file,
and to fork off and run a separate copy of "ethereal" for "-S" and "-F"
captures or just call "capture()" otherwise, out of "gtk/capture_dlg.c"
and into a routine in "capture.c".
If the attempt to create said temporary capture file fails, pop up a
dialog box and don't do the capture.
Have the child capture process send a message upstream after it either
successfully starts the capture and syncs out the header of the capture
file, or fails to start the capture; the message indicates whether it
succeeded or failed, and, if it failed, includes a failure message.
This:
avoids the use of a signal, and thus means we don't have to
worry about whether to capture the signal, or whether to start
or stop capturing depending on whether this particular capture
is in sync mode or not;
lets us pop up the message box for the error in the parent
process if we're in sync mode, rather than doing it in the
child, which didn't work well.
Add a check button to the Capture/Start dialog box, so that we can
control, for each capture, whether it's to be done in sync mode or not.
svn path=/trunk/; revision=708
1999-09-23 06:27:27 +00:00
|
|
|
{
|
2000-10-11 06:01:16 +00:00
|
|
|
#ifndef _WIN32
|
|
|
|
/*
|
|
|
|
* Catch SIGUSR1, so that we exit cleanly if the parent process
|
|
|
|
* kills us with it due to the user selecting "Capture->Stop".
|
|
|
|
*/
|
2004-12-29 12:37:06 +00:00
|
|
|
if (capture_opts->capture_child)
|
2004-02-21 12:58:42 +00:00
|
|
|
signal(SIGUSR1, stop_capture_signal_handler);
|
2000-10-11 06:01:16 +00:00
|
|
|
#endif
|
2004-03-04 19:31:21 +00:00
|
|
|
|
2004-12-29 09:09:35 +00:00
|
|
|
return capture_loop_start(capture_opts, stats_known, stats);
|
2002-06-04 11:19:59 +00:00
|
|
|
}
|
|
|
|
|
2000-10-11 06:01:16 +00:00
|
|
|
void
|
2004-12-29 09:09:35 +00:00
|
|
|
capture_stop(gboolean sync_mode)
|
2000-10-11 06:01:16 +00:00
|
|
|
{
|
2004-10-30 11:44:06 +00:00
|
|
|
|
2004-12-29 09:09:35 +00:00
|
|
|
if (sync_mode) {
|
2004-10-30 17:50:51 +00:00
|
|
|
sync_pipe_stop();
|
2004-02-03 17:59:01 +00:00
|
|
|
}
|
2004-11-10 17:58:16 +00:00
|
|
|
|
|
|
|
capture_loop_stop();
|
2000-10-11 06:01:16 +00:00
|
|
|
}
|
|
|
|
|
Add a routine to kill a capture child if it exists, so that if we exit
(by deleting the main window or selecting File->Quit or typing ^Q) while
an "Update list of packets in real time" capture is in progress, we can
abort the capture.
Arrange that "fork_child" is -1 when there is no capture child, so said
routine knows when it can kill the child.
When we exit, kill off any capture child, using that routine, and, if
we're exiting due to a request to delete the main window and, if a read
is in progress (from an "Update list of packets in real time" capture),
don't delete the main window - just set the "Read aborted" flag, so that
the code doing the read will see that flag (it will be called because
the pipe to the capture child is closed due to the child exiting) will
see that and clean up and exit itself.
svn path=/trunk/; revision=4498
2002-01-08 09:32:15 +00:00
|
|
|
void
|
2004-12-29 09:09:35 +00:00
|
|
|
kill_capture_child(gboolean sync_mode)
|
Add a routine to kill a capture child if it exists, so that if we exit
(by deleting the main window or selecting File->Quit or typing ^Q) while
an "Update list of packets in real time" capture is in progress, we can
abort the capture.
Arrange that "fork_child" is -1 when there is no capture child, so said
routine knows when it can kill the child.
When we exit, kill off any capture child, using that routine, and, if
we're exiting due to a request to delete the main window and, if a read
is in progress (from an "Update list of packets in real time" capture),
don't delete the main window - just set the "Read aborted" flag, so that
the code doing the read will see that flag (it will be called because
the pipe to the capture child is closed due to the child exiting) will
see that and clean up and exit itself.
svn path=/trunk/; revision=4498
2002-01-08 09:32:15 +00:00
|
|
|
{
|
2004-12-29 09:09:35 +00:00
|
|
|
if (sync_mode) {
|
2004-10-30 11:44:06 +00:00
|
|
|
sync_pipe_kill();
|
|
|
|
}
|
Add a routine to kill a capture child if it exists, so that if we exit
(by deleting the main window or selecting File->Quit or typing ^Q) while
an "Update list of packets in real time" capture is in progress, we can
abort the capture.
Arrange that "fork_child" is -1 when there is no capture child, so said
routine knows when it can kill the child.
When we exit, kill off any capture child, using that routine, and, if
we're exiting due to a request to delete the main window and, if a read
is in progress (from an "Update list of packets in real time" capture),
don't delete the main window - just set the "Read aborted" flag, so that
the code doing the read will see that flag (it will be called because
the pipe to the capture child is closed due to the child exiting) will
see that and clean up and exit itself.
svn path=/trunk/; revision=4498
2002-01-08 09:32:15 +00:00
|
|
|
}
|
|
|
|
|
1999-07-09 04:18:36 +00:00
|
|
|
|
|
|
|
#endif /* HAVE_LIBPCAP */
|