1998-09-16 02:39:15 +00:00
|
|
|
/* capture.c
|
|
|
|
* Routines for packet capture windows
|
|
|
|
*
|
2000-01-26 23:09:21 +00:00
|
|
|
* $Id: capture.c,v 1.92 2000/01/26 23:09:21 guy Exp $
|
1998-09-16 03:22:19 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@zing.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
1998-10-10 03:32:20 +00:00
|
|
|
|
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-10-10 03:32:20 +00:00
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
1999-07-31 23:06:13 +00:00
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
|
# include <sys/stat.h>
|
|
|
|
#endif
|
|
|
|
|
1999-11-29 01:54:01 +00:00
|
|
|
#ifdef HAVE_SYS_WAIT_H
|
|
|
|
# include <sys/wait.h>
|
|
|
|
#endif
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <gtk/gtk.h>
|
1998-12-17 05:42:33 +00:00
|
|
|
#include <stdlib.h>
|
1999-04-06 16:24:50 +00:00
|
|
|
#include <stdio.h>
|
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
|
|
|
#include <ctype.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <string.h>
|
1999-10-02 06:26:53 +00:00
|
|
|
#include <fcntl.h>
|
1999-08-03 20:51:41 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
1998-10-13 07:03:37 +00:00
|
|
|
#include <unistd.h>
|
1999-08-03 20:51:41 +00:00
|
|
|
#endif
|
|
|
|
|
1998-12-29 04:05:38 +00:00
|
|
|
#include <time.h>
|
1999-08-03 20:51:41 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <sys/socket.h>
|
1999-08-03 20:51:41 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_IOCTL_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <sys/ioctl.h>
|
1999-08-03 20:51:41 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NET_IF_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <net/if.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
|
|
|
|
1998-10-10 03:32:20 +00:00
|
|
|
#ifdef NEED_SNPRINTF_H
|
1998-10-13 07:03:37 +00:00
|
|
|
# ifdef HAVE_STDARG_H
|
|
|
|
# include <stdarg.h>
|
|
|
|
# else
|
|
|
|
# include <varargs.h>
|
|
|
|
# endif
|
1998-10-10 03:32:20 +00:00
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
1999-10-02 19:24:27 +00:00
|
|
|
#ifndef lib_pcap_h
|
|
|
|
#include <pcap.h>
|
|
|
|
#endif
|
|
|
|
|
1999-09-09 02:42:40 +00:00
|
|
|
#include "gtk/main.h"
|
1999-10-20 22:36:05 +00:00
|
|
|
#include "gtk/gtkglobals.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "packet.h"
|
|
|
|
#include "file.h"
|
|
|
|
#include "capture.h"
|
|
|
|
#include "util.h"
|
2000-01-03 06:59:25 +00:00
|
|
|
#include "simple_dialog.h"
|
1998-10-12 01:40:57 +00:00
|
|
|
#include "prefs.h"
|
1999-09-09 03:32:03 +00:00
|
|
|
#include "globals.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-10-01 21:52:03 +00:00
|
|
|
int sync_mode; /* fork a child to do the capture, and sync between them */
|
1999-11-29 01:54:01 +00:00
|
|
|
static int sync_pipe[2]; /* used to sync father */
|
1999-10-01 21:52:03 +00:00
|
|
|
int quit_after_cap; /* Makes a "capture only mode". Implies -k */
|
1999-10-02 20:00:46 +00:00
|
|
|
gboolean capture_child; /* if this is the child for "-S" */
|
1999-11-29 01:54:01 +00:00
|
|
|
static guint cap_input_id;
|
1999-10-01 21:52:03 +00:00
|
|
|
|
1999-11-29 01:54:01 +00:00
|
|
|
static void cap_file_input_cb(gpointer, gint, GdkInputCondition);
|
1999-06-19 01:14:51 +00:00
|
|
|
static void capture_stop_cb(GtkWidget *, gpointer);
|
|
|
|
static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
|
|
|
|
const u_char *);
|
1999-09-09 03:32:03 +00:00
|
|
|
static float pct(gint, gint);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-08-15 22:31:22 +00:00
|
|
|
typedef struct _loop_data {
|
|
|
|
gint go;
|
|
|
|
gint max;
|
|
|
|
gint linktype;
|
|
|
|
gint sync_packets;
|
|
|
|
packet_counts counts;
|
Add to Wiretap the ability to write capture files; for now, it can only
write them in "libpcap" format, but the mechanism can have other formats
added.
When creating the temporary file for a capture, use "create_tempfile()",
to close a security hole opened by the fact that "tempnam()" creates a
temporary file, but doesn't open it, and we open the file with the name
it gives us - somebody could remove the file and plant a link to some
file, and, if as may well be the case when Ethereal is capturing
packets, it's running as "root", that means we write a capture on top of
that file.... (The aforementioned changes to Wiretap let you open a
capture file for writing given an file descriptor, "fdopen()"-style,
which this change requires.)
svn path=/trunk/; revision=509
1999-08-18 04:17:38 +00:00
|
|
|
wtap_dumper *pdh;
|
1999-08-15 22:31:22 +00:00
|
|
|
} loop_data;
|
|
|
|
|
1999-10-02 06:26:53 +00:00
|
|
|
/* Open a specified file, or create a temporary file, and start a capture
|
|
|
|
to the file in question. */
|
1998-09-16 02:39:15 +00:00
|
|
|
void
|
1999-10-02 06:26:53 +00:00
|
|
|
do_capture(char *capfile_name)
|
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];
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
gboolean is_tempfile;
|
1999-10-02 06:26:53 +00:00
|
|
|
u_char c;
|
|
|
|
int i;
|
|
|
|
guint byte_count;
|
|
|
|
char *msg;
|
|
|
|
int err;
|
|
|
|
int capture_succeeded;
|
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
|
|
|
|
1999-10-02 06:26:53 +00:00
|
|
|
if (capfile_name != NULL) {
|
|
|
|
/* Try to open/create the specified file for use as a capture buffer. */
|
|
|
|
cf.save_file_fd = open(capfile_name, O_RDWR|O_TRUNC|O_CREAT, 0600);
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
is_tempfile = FALSE;
|
1999-10-02 06:26:53 +00:00
|
|
|
} else {
|
|
|
|
/* Choose a random name for the capture buffer */
|
|
|
|
cf.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
|
|
|
|
capfile_name = g_strdup(tmpname);
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
is_tempfile = TRUE;
|
1999-10-02 06:26:53 +00:00
|
|
|
}
|
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
|
|
|
if (cf.save_file_fd == -1) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"The 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));
|
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
|
|
|
return;
|
|
|
|
}
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
close_cap_file(&cf, info_bar);
|
|
|
|
g_assert(cf.save_file == NULL);
|
1999-10-02 06:26:53 +00:00
|
|
|
cf.save_file = 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
|
|
|
|
1999-10-02 20:00:46 +00:00
|
|
|
if (sync_mode) { /* use fork() for capture */
|
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
|
|
|
int fork_child;
|
|
|
|
char ssnap[24];
|
|
|
|
char scount[24]; /* need a constant for len of numbers */
|
|
|
|
char save_file_fd[24];
|
|
|
|
|
|
|
|
sprintf(ssnap,"%d",cf.snap); /* in lieu of itoa */
|
|
|
|
sprintf(scount,"%d",cf.count);
|
|
|
|
sprintf(save_file_fd,"%d",cf.save_file_fd);
|
|
|
|
signal(SIGCHLD, SIG_IGN);
|
1999-10-02 20:00:46 +00:00
|
|
|
pipe(sync_pipe);
|
1999-09-23 07:04:23 +00:00
|
|
|
if ((fork_child = fork()) == 0) {
|
1999-11-29 01:54:01 +00:00
|
|
|
/*
|
|
|
|
* Child process - run Ethereal with the right arguments to make
|
|
|
|
* it just pop up the live capture dialog box and capture with
|
|
|
|
* the specified capture parameters, writing to the specified file.
|
|
|
|
*
|
|
|
|
* args: -i interface specification
|
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
|
|
|
* -w file to write
|
|
|
|
* -W file descriptor to write
|
|
|
|
* -c count to capture
|
|
|
|
* -s snaplen
|
|
|
|
* -m / -b fonts
|
|
|
|
* -f "filter expression"
|
|
|
|
*/
|
1999-10-02 20:00:46 +00:00
|
|
|
close(1);
|
|
|
|
dup(sync_pipe[1]);
|
|
|
|
close(sync_pipe[0]);
|
|
|
|
execlp(ethereal_path, CHILD_NAME, "-i", cf.iface,
|
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
|
|
|
"-w", cf.save_file, "-W", save_file_fd,
|
1999-10-02 20:00:46 +00:00
|
|
|
"-c", scount, "-s", ssnap,
|
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
|
|
|
"-m", medium_font, "-b", bold_font,
|
|
|
|
(cf.cfilter == NULL)? 0 : "-f",
|
|
|
|
(cf.cfilter == NULL)? 0 : cf.cfilter,
|
|
|
|
(const char *)NULL);
|
1999-11-29 01:54:01 +00:00
|
|
|
} else {
|
|
|
|
/* Parent process - read messages from the child process over the
|
|
|
|
sync pipe. */
|
1999-10-02 20:00:46 +00:00
|
|
|
close(sync_pipe[1]);
|
|
|
|
|
|
|
|
/* Read a byte count from "sync_pipe[0]", terminated with a
|
|
|
|
colon; if the count is 0, the child process created the
|
|
|
|
capture file and we should start reading from it, otherwise
|
|
|
|
the capture couldn't start and the count is a count of bytes
|
|
|
|
of error message, and we should display the message. */
|
|
|
|
byte_count = 0;
|
|
|
|
for (;;) {
|
|
|
|
i = read(sync_pipe[0], &c, 1);
|
|
|
|
if (i == 0) {
|
|
|
|
/* EOF - the child process died.
|
1999-11-29 01:54:01 +00:00
|
|
|
Close the read side of the sync pipe, remove the capture file,
|
|
|
|
and report the failure.
|
|
|
|
XXX - reap the child process and report the status in detail. */
|
|
|
|
close(sync_pipe[0]);
|
|
|
|
unlink(cf.save_file);
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
g_free(cf.save_file);
|
1999-11-29 01:54:01 +00:00
|
|
|
cf.save_file = NULL;
|
1999-10-02 20:00:46 +00:00
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL, "Capture child process died");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (c == ';')
|
|
|
|
break;
|
|
|
|
if (!isdigit(c)) {
|
1999-11-29 01:54:01 +00:00
|
|
|
/* Child process handed us crap.
|
|
|
|
Close the read side of the sync pipe, remove the capture file,
|
|
|
|
and report the failure. */
|
|
|
|
close(sync_pipe[0]);
|
|
|
|
unlink(cf.save_file);
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
g_free(cf.save_file);
|
1999-11-29 01:54:01 +00:00
|
|
|
cf.save_file = NULL;
|
1999-10-02 20:00:46 +00:00
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"Capture child process sent us a bad message");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
byte_count = byte_count*10 + c - '0';
|
|
|
|
}
|
|
|
|
if (byte_count == 0) {
|
1999-11-29 01:54:01 +00:00
|
|
|
/* Success. Open the capture file, and set up to read it. */
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
err = start_tail_cap_file(cf.save_file, is_tempfile, &cf);
|
1999-11-29 01:54:01 +00:00
|
|
|
if (err == 0) {
|
|
|
|
/* We were able to open and set up to read the capture file;
|
|
|
|
arrange that our callback be called whenever it's possible
|
|
|
|
to read from the sync pipe, so that it's called when
|
|
|
|
the child process wants to tell us something. */
|
|
|
|
cap_input_id = gtk_input_add_full(sync_pipe[0],
|
|
|
|
GDK_INPUT_READ,
|
|
|
|
cap_file_input_cb,
|
|
|
|
NULL,
|
|
|
|
(gpointer) &cf,
|
|
|
|
NULL);
|
|
|
|
} else {
|
|
|
|
/* We weren't able to open the capture file; complain, and
|
|
|
|
close the sync pipe. */
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
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
|
|
|
file_open_error_message(err, FALSE), cf.save_file);
|
1999-11-29 01:54:01 +00:00
|
|
|
|
|
|
|
/* Close the sync pipe. */
|
|
|
|
close(sync_pipe[0]);
|
|
|
|
|
|
|
|
/* Don't unlink the save file - leave it around, for debugging
|
|
|
|
purposes. */
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
g_free(cf.save_file);
|
1999-11-29 01:54:01 +00:00
|
|
|
cf.save_file = NULL;
|
|
|
|
}
|
1999-10-02 20:00:46 +00:00
|
|
|
} else {
|
1999-11-29 01:54:01 +00:00
|
|
|
/* Failure - the child process sent us a message indicating
|
|
|
|
what the problem was. */
|
1999-10-02 20:00:46 +00:00
|
|
|
msg = g_malloc(byte_count + 1);
|
|
|
|
if (msg == NULL) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"Capture child process failed, but its error message was too big.");
|
|
|
|
} else {
|
|
|
|
i = read(sync_pipe[0], msg, byte_count);
|
|
|
|
if (i < 0) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
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
|
|
|
"Capture child process failed: Error %s reading its error message.",
|
|
|
|
strerror(errno));
|
1999-10-02 20:00:46 +00:00
|
|
|
} else if (i == 0) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
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
|
|
|
"Capture child process failed: EOF reading its error message.");
|
1999-10-02 20:00:46 +00:00
|
|
|
} else
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL, msg);
|
|
|
|
g_free(msg);
|
1999-11-29 01:54:01 +00:00
|
|
|
|
|
|
|
/* Close the sync pipe. */
|
|
|
|
close(sync_pipe[0]);
|
|
|
|
|
|
|
|
/* Get rid of the save file - the capture never started. */
|
|
|
|
unlink(cf.save_file);
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
g_free(cf.save_file);
|
1999-11-29 01:54:01 +00:00
|
|
|
cf.save_file = NULL;
|
1999-10-02 20:00:46 +00:00
|
|
|
}
|
|
|
|
}
|
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
|
|
|
}
|
1999-11-29 01:54:01 +00:00
|
|
|
} else {
|
|
|
|
/* Not sync mode. */
|
1999-10-02 06:00:07 +00:00
|
|
|
capture_succeeded = capture();
|
|
|
|
if (quit_after_cap) {
|
|
|
|
/* DON'T unlink the save file. Presumably someone wants it. */
|
|
|
|
gtk_exit(0);
|
|
|
|
}
|
|
|
|
if (capture_succeeded) {
|
|
|
|
/* Capture succeeded; read in the capture file. */
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
if ((err = open_cap_file(cf.save_file, is_tempfile, &cf)) == 0) {
|
1999-10-02 06:00:07 +00:00
|
|
|
/* Set the read filter to NULL. */
|
|
|
|
cf.rfcode = NULL;
|
|
|
|
err = read_cap_file(&cf);
|
|
|
|
}
|
|
|
|
}
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
/* We're not doing a capture any more, so we don't have a save
|
|
|
|
file. */
|
|
|
|
g_free(cf.save_file);
|
|
|
|
cf.save_file = NULL;
|
1999-10-02 06:00:07 +00:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
1999-11-29 01:54:01 +00:00
|
|
|
/* There's stuff to read from the sync pipe, meaning the child has sent
|
|
|
|
us a message, or the sync pipe has closed, meaning the child has
|
|
|
|
closed it (perhaps because it exited). */
|
|
|
|
static void
|
|
|
|
cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition)
|
|
|
|
{
|
|
|
|
capture_file *cf = (capture_file *)data;
|
|
|
|
char buffer[256+1], *p = buffer, *q = buffer;
|
|
|
|
int nread;
|
|
|
|
int to_read = 0;
|
|
|
|
gboolean exit_loop = FALSE;
|
|
|
|
int err;
|
|
|
|
int wstatus;
|
|
|
|
int wsignal;
|
|
|
|
char *msg;
|
|
|
|
char *sigmsg;
|
|
|
|
char sigmsg_buf[6+1+3+1];
|
|
|
|
char *coredumped;
|
|
|
|
|
|
|
|
/* avoid reentrancy problems and stack overflow */
|
|
|
|
gtk_input_remove(cap_input_id);
|
|
|
|
|
|
|
|
if ((nread = read(sync_pipe[0], buffer, 256)) <= 0) {
|
|
|
|
/* The child has closed the sync pipe, meaning it's not going to be
|
|
|
|
capturing any more packets. Pick up its exit status, and
|
|
|
|
complain if it died of a signal. */
|
|
|
|
if (wait(&wstatus) != -1) {
|
|
|
|
/* XXX - are there any platforms on which we can run that *don't*
|
|
|
|
support POSIX.1's <sys/wait.h> and macros therein? */
|
|
|
|
wsignal = wstatus & 0177;
|
|
|
|
coredumped = "";
|
|
|
|
if (wstatus == 0177) {
|
|
|
|
/* It stopped, rather than exiting. "Should not happen." */
|
|
|
|
msg = "stopped";
|
|
|
|
wsignal = (wstatus >> 8) & 0xFF;
|
|
|
|
} else {
|
|
|
|
msg = "terminated";
|
|
|
|
if (wstatus & 0200)
|
|
|
|
coredumped = " - core dumped";
|
|
|
|
}
|
|
|
|
if (wsignal != 0) {
|
|
|
|
switch (wsignal) {
|
|
|
|
|
|
|
|
case SIGHUP:
|
|
|
|
sigmsg = "Hangup";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGINT:
|
|
|
|
sigmsg = "Interrupted";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGQUIT:
|
|
|
|
sigmsg = "Quit";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGILL:
|
|
|
|
sigmsg = "Illegal instruction";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGTRAP:
|
|
|
|
sigmsg = "Trace trap";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGABRT:
|
|
|
|
sigmsg = "Abort";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGFPE:
|
|
|
|
sigmsg = "Arithmetic exception";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGKILL:
|
|
|
|
sigmsg = "Killed";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGBUS:
|
|
|
|
sigmsg = "Bus error";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGSEGV:
|
|
|
|
sigmsg = "Segmentation violation";
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
|
|
|
|
Linux is POSIX compliant. These are not POSIX-defined signals ---
|
|
|
|
ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
|
|
|
|
|
|
|
|
``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
|
|
|
|
were omitted from POSIX.1 because their behavior is
|
|
|
|
implementation dependent and could not be adequately catego-
|
|
|
|
rized. Conforming implementations may deliver these sig-
|
|
|
|
nals, but must document the circumstances under which they
|
|
|
|
are delivered and note any restrictions concerning their
|
|
|
|
delivery.''
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef SIGSYS
|
|
|
|
case SIGSYS:
|
|
|
|
sigmsg = "Bad system call";
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
case SIGPIPE:
|
|
|
|
sigmsg = "Broken pipe";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGALRM:
|
|
|
|
sigmsg = "Alarm clock";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGTERM:
|
|
|
|
sigmsg = "Terminated";
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
sprintf(sigmsg_buf, "Signal %d", wsignal);
|
|
|
|
sigmsg = sigmsg_buf;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"Child capture process %s: %s%s", msg, sigmsg, coredumped);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read what remains of the capture file, and finish the capture.
|
|
|
|
XXX - do something if this fails? */
|
|
|
|
err = finish_tail_cap_file(cf);
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
|
|
|
|
/* We're not doing a capture any more, so we don't have a save
|
|
|
|
file. */
|
|
|
|
g_free(cf->save_file);
|
|
|
|
cf->save_file = NULL;
|
|
|
|
|
1999-11-29 01:54:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer[nread] = '\0';
|
|
|
|
|
|
|
|
while(!exit_loop) {
|
|
|
|
/* look for (possibly multiple) '*' */
|
|
|
|
switch (*q) {
|
|
|
|
case '*' :
|
|
|
|
to_read += atoi(p);
|
|
|
|
p = q + 1;
|
|
|
|
q++;
|
|
|
|
break;
|
|
|
|
case '\0' :
|
|
|
|
/* XXX should handle the case of a pipe full (i.e. no star found) */
|
|
|
|
exit_loop = TRUE;
|
|
|
|
break;
|
|
|
|
default :
|
|
|
|
q++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read from the capture file the number of records the child told us
|
|
|
|
it added.
|
|
|
|
XXX - do something if this fails? */
|
|
|
|
err = continue_tail_cap_file(cf, to_read);
|
|
|
|
|
|
|
|
/* restore pipe handler */
|
|
|
|
cap_input_id = gtk_input_add_full (sync_pipe[0],
|
|
|
|
GDK_INPUT_READ,
|
|
|
|
cap_file_input_cb,
|
|
|
|
NULL,
|
|
|
|
(gpointer) cf,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/*
|
|
|
|
* Timeout, in milliseconds, for reads from the stream of captured packets.
|
|
|
|
*/
|
|
|
|
#define CAP_READ_TIMEOUT 250
|
|
|
|
|
1999-10-02 06:00:07 +00:00
|
|
|
/* Do the low-level work of a capture.
|
|
|
|
Returns TRUE if it succeeds, FALSE otherwise. */
|
|
|
|
int
|
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
|
|
|
capture(void)
|
|
|
|
{
|
1999-08-14 23:47:20 +00:00
|
|
|
GtkWidget *cap_w, *main_vb, *count_lb, *tcp_lb, *udp_lb, *icmp_lb,
|
2000-01-20 21:34:16 +00:00
|
|
|
*ospf_lb, *gre_lb, *netbios_lb, *ipx_lb, *vines_lb, *other_lb, *stop_bt;
|
1998-09-16 02:39:15 +00:00
|
|
|
pcap_t *pch;
|
|
|
|
gchar err_str[PCAP_ERRBUF_SIZE], label_str[32];
|
|
|
|
loop_data ld;
|
|
|
|
bpf_u_int32 netnum, netmask;
|
|
|
|
time_t upd_time, cur_time;
|
1999-08-10 11:08:38 +00:00
|
|
|
int err, inpkts;
|
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 errmsg[1024+1];
|
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
|
|
|
#ifdef linux
|
|
|
|
fd_set set1;
|
|
|
|
struct timeval timeout;
|
|
|
|
int pcap_fd;
|
|
|
|
#endif
|
1999-08-15 22:16:59 +00:00
|
|
|
|
1999-08-10 20:06:39 +00:00
|
|
|
ld.go = TRUE;
|
|
|
|
ld.counts.total = 0;
|
|
|
|
ld.max = cf.count;
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
ld.linktype = WTAP_ENCAP_UNKNOWN;
|
1999-08-10 20:06:39 +00:00
|
|
|
ld.sync_packets = 0;
|
|
|
|
ld.counts.tcp = 0;
|
|
|
|
ld.counts.udp = 0;
|
1999-08-14 23:47:20 +00:00
|
|
|
ld.counts.icmp = 0;
|
1999-08-10 20:06:39 +00:00
|
|
|
ld.counts.ospf = 0;
|
|
|
|
ld.counts.gre = 0;
|
1999-11-30 23:56:37 +00:00
|
|
|
ld.counts.ipx = 0;
|
1999-08-10 20:06:39 +00:00
|
|
|
ld.counts.netbios = 0;
|
2000-01-20 21:34:16 +00:00
|
|
|
ld.counts.vines = 0;
|
1999-08-10 20:06:39 +00:00
|
|
|
ld.counts.other = 0;
|
|
|
|
ld.pdh = NULL;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-09-23 07:04:23 +00:00
|
|
|
/* Open the network interface to capture from it. */
|
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
|
|
|
pch = pcap_open_live(cf.iface, cf.snap, 1, CAP_READ_TIMEOUT, err_str);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
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
|
|
|
if (pch == NULL) {
|
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
|
|
|
/* Well, we couldn't start the capture.
|
|
|
|
If this is a child process that does the capturing in sync
|
|
|
|
mode or fork mode, it shouldn't do any UI stuff until we pop up the
|
|
|
|
capture-progress window, and, since we couldn't start the
|
|
|
|
capture, we haven't popped it up. */
|
|
|
|
if (!capture_child) {
|
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
|
|
|
while (gtk_events_pending()) gtk_main_iteration();
|
|
|
|
}
|
|
|
|
snprintf(errmsg, sizeof errmsg,
|
|
|
|
"The capture session could not be initiated (%s).\n"
|
|
|
|
"Please check to make sure you have sufficient permissions, and that\n"
|
|
|
|
"you have the proper interface specified.", err_str);
|
1999-09-23 07:04:23 +00:00
|
|
|
goto error;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
if (cf.cfilter) {
|
1999-09-23 07:04:23 +00:00
|
|
|
/* A capture filter was specified; set it up. */
|
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
|
|
|
if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
|
|
|
|
snprintf(errmsg, sizeof errmsg,
|
|
|
|
"Can't use filter: Couldn't obtain netmask info (%s).", err_str);
|
1999-09-23 07:04:23 +00:00
|
|
|
goto error;
|
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
|
|
|
}
|
|
|
|
if (pcap_compile(pch, &cf.fcode, cf.cfilter, 1, netmask) < 0) {
|
|
|
|
snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
|
|
|
|
pcap_geterr(pch));
|
1999-09-23 07:04:23 +00:00
|
|
|
goto error;
|
1999-08-18 17:08:47 +00:00
|
|
|
}
|
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
|
|
|
if (pcap_setfilter(pch, &cf.fcode) < 0) {
|
|
|
|
snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
|
|
|
|
pcap_geterr(pch));
|
1999-09-23 07:04:23 +00:00
|
|
|
goto error;
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-23 07:04:23 +00:00
|
|
|
/* Set up to write to the capture file. */
|
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
|
|
|
ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch));
|
|
|
|
if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
|
|
|
|
strcpy(errmsg, "The network you're capturing from is of a type"
|
|
|
|
" that Ethereal doesn't support.");
|
1999-09-23 07:04:23 +00:00
|
|
|
goto error;
|
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
|
|
|
}
|
|
|
|
ld.pdh = wtap_dump_fdopen(cf.save_file_fd, WTAP_FILE_PCAP,
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
ld.linktype, pcap_snapshot(pch), &err);
|
1999-08-02 06:08:58 +00:00
|
|
|
|
1999-09-23 07:04:23 +00:00
|
|
|
if (ld.pdh == NULL) {
|
|
|
|
/* We couldn't set up to write to the capture file. */
|
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
|
|
|
switch (err) {
|
|
|
|
|
|
|
|
case WTAP_ERR_CANT_OPEN:
|
|
|
|
strcpy(errmsg, "The file to which the capture would be saved"
|
|
|
|
" couldn't be created for some unknown reason.");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WTAP_ERR_SHORT_WRITE:
|
|
|
|
strcpy(errmsg, "A full header couldn't be written to the file"
|
|
|
|
" to which the capture would be saved.");
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (err < 0) {
|
|
|
|
sprintf(errmsg, "The file to which the capture would be"
|
|
|
|
" saved (\"%s\") could not be opened: Error %d.",
|
|
|
|
cf.save_file, err);
|
|
|
|
} else {
|
|
|
|
sprintf(errmsg, "The file to which the capture would be"
|
|
|
|
" saved (\"%s\") could not be opened: %s.",
|
|
|
|
cf.save_file, strerror(err));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
1999-09-23 07:04:23 +00:00
|
|
|
goto error;
|
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
|
|
|
}
|
|
|
|
|
1999-10-02 20:00:46 +00:00
|
|
|
if (capture_child) {
|
1999-09-23 07:04:23 +00:00
|
|
|
/* Well, we should be able to start capturing.
|
|
|
|
|
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
|
|
|
This is the child process for a sync mode capture, so sync out
|
|
|
|
the capture file, so the header makes it to the file system,
|
|
|
|
and send a "capture started successfully and capture file created"
|
|
|
|
message to our parent so that they'll open the capture file and
|
|
|
|
update its windows to indicate that we have a live capture in
|
|
|
|
progress. */
|
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
|
|
|
fflush(wtap_dump_file(ld.pdh));
|
|
|
|
write(1, "0;", 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
|
|
gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture / Playback");
|
|
|
|
|
|
|
|
/* Container for capture display widgets */
|
|
|
|
main_vb = gtk_vbox_new(FALSE, 1);
|
|
|
|
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
|
|
|
|
gtk_widget_show(main_vb);
|
|
|
|
|
|
|
|
count_lb = gtk_label_new("Count: 0");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(count_lb);
|
|
|
|
|
|
|
|
tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(tcp_lb);
|
|
|
|
|
|
|
|
udp_lb = gtk_label_new("UDP: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(udp_lb);
|
|
|
|
|
|
|
|
icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(icmp_lb);
|
|
|
|
|
|
|
|
ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(ospf_lb);
|
|
|
|
|
|
|
|
gre_lb = gtk_label_new("GRE: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(gre_lb);
|
|
|
|
|
|
|
|
netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(netbios_lb);
|
|
|
|
|
1999-11-30 23:56:37 +00:00
|
|
|
ipx_lb = gtk_label_new("IPX: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), ipx_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(ipx_lb);
|
|
|
|
|
2000-01-20 21:34:16 +00:00
|
|
|
vines_lb = gtk_label_new("VINES: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), vines_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(vines_lb);
|
|
|
|
|
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
|
|
|
other_lb = gtk_label_new("Other: 0 (0.0%)");
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(other_lb);
|
|
|
|
|
|
|
|
stop_bt = gtk_button_new_with_label ("Stop");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
|
|
|
|
gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
|
|
|
|
GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
|
|
|
|
gtk_widget_grab_default(stop_bt);
|
|
|
|
GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
|
|
|
|
gtk_widget_grab_default(stop_bt);
|
|
|
|
gtk_widget_show(stop_bt);
|
|
|
|
|
|
|
|
gtk_widget_show(cap_w);
|
|
|
|
gtk_grab_add(cap_w);
|
|
|
|
|
|
|
|
upd_time = time(NULL);
|
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
|
|
|
#ifdef linux
|
|
|
|
pcap_fd = pcap_fileno(pch);
|
|
|
|
#endif
|
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
|
|
|
while (ld.go) {
|
|
|
|
while (gtk_events_pending()) gtk_main_iteration();
|
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
|
|
|
#ifdef linux
|
|
|
|
/*
|
|
|
|
* Sigh. The semantics of the read timeout argument to
|
|
|
|
* "pcap_open_live()" aren't particularly well specified by
|
|
|
|
* the "pcap" man page - at least with the BSD BPF code, the
|
|
|
|
* intent appears to be, at least in part, a way of cutting
|
|
|
|
* down the number of reads done on a capture, by blocking
|
|
|
|
* until the buffer fills or a timer expires - and the Linux
|
|
|
|
* libpcap doesn't actually support it, so we can't use it
|
|
|
|
* to break out of the "pcap_dispatch()" every 1/4 of a second
|
|
|
|
* or so.
|
|
|
|
*
|
|
|
|
* Thus, on Linux, we do a "select()" on the file descriptor for the
|
|
|
|
* capture, with a timeout of CAP_READ_TIMEOUT milliseconds, or
|
|
|
|
* CAP_READ_TIMEOUT*1000 microseconds.
|
|
|
|
*/
|
|
|
|
FD_ZERO(&set1);
|
|
|
|
FD_SET(pcap_fd, &set1);
|
|
|
|
timeout.tv_sec = 0;
|
|
|
|
timeout.tv_usec = CAP_READ_TIMEOUT*1000;
|
|
|
|
if (select(pcap_fd+1, &set1, NULL, NULL, &timeout) != 0) {
|
|
|
|
/*
|
|
|
|
* "select()" says we can read from it without blocking; go for
|
|
|
|
* it.
|
|
|
|
*/
|
|
|
|
inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
|
|
|
|
} else
|
|
|
|
inpkts = 0;
|
|
|
|
#else
|
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
|
|
|
inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
|
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
|
|
|
#endif
|
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
|
|
|
if (inpkts > 0)
|
|
|
|
ld.sync_packets += inpkts;
|
|
|
|
/* Only update once a second so as not to overload slow displays */
|
|
|
|
cur_time = time(NULL);
|
|
|
|
if (cur_time > upd_time) {
|
|
|
|
upd_time = cur_time;
|
|
|
|
|
|
|
|
sprintf(label_str, "Count: %d", ld.counts.total);
|
|
|
|
gtk_label_set(GTK_LABEL(count_lb), label_str);
|
|
|
|
|
|
|
|
sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
|
|
|
|
pct(ld.counts.tcp, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(tcp_lb), label_str);
|
|
|
|
|
|
|
|
sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
|
|
|
|
pct(ld.counts.udp, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(udp_lb), label_str);
|
|
|
|
|
|
|
|
sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
|
|
|
|
pct(ld.counts.icmp, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(icmp_lb), label_str);
|
|
|
|
|
|
|
|
sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
|
|
|
|
pct(ld.counts.ospf, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(ospf_lb), label_str);
|
|
|
|
|
|
|
|
sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
|
|
|
|
pct(ld.counts.gre, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(gre_lb), label_str);
|
|
|
|
|
|
|
|
sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
|
|
|
|
pct(ld.counts.netbios, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(netbios_lb), label_str);
|
|
|
|
|
1999-11-30 23:56:37 +00:00
|
|
|
sprintf(label_str, "IPX: %d (%.1f%%)", ld.counts.ipx,
|
|
|
|
pct(ld.counts.ipx, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(ipx_lb), label_str);
|
|
|
|
|
2000-01-20 21:34:16 +00:00
|
|
|
sprintf(label_str, "VINES: %d (%.1f%%)", ld.counts.vines,
|
|
|
|
pct(ld.counts.vines, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(vines_lb), label_str);
|
|
|
|
|
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
|
|
|
sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
|
|
|
|
pct(ld.counts.other, ld.counts.total));
|
|
|
|
gtk_label_set(GTK_LABEL(other_lb), label_str);
|
|
|
|
|
|
|
|
/* do sync here, too */
|
|
|
|
fflush(wtap_dump_file(ld.pdh));
|
1999-10-02 20:00:46 +00:00
|
|
|
if (capture_child && ld.sync_packets) {
|
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
|
|
|
/* This is the child process for a sync mode capture, so send
|
|
|
|
our parent a message saying we've written out "ld.sync_packets"
|
|
|
|
packets to the capture file. */
|
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 tmp[20];
|
|
|
|
sprintf(tmp, "%d*", ld.sync_packets);
|
|
|
|
write(1, tmp, strlen(tmp));
|
|
|
|
ld.sync_packets = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-23 07:04:23 +00:00
|
|
|
if (!wtap_dump_close(ld.pdh, &err)) {
|
|
|
|
/* XXX - in fork mode, this may not pop up, or, if it does,
|
|
|
|
it may disappear as soon as we exit.
|
|
|
|
|
|
|
|
We should have the parent process, while it's reading
|
|
|
|
the packet count update messages, catch error messages
|
|
|
|
and pop up a message box if it sees one. */
|
|
|
|
switch (err) {
|
|
|
|
|
|
|
|
case WTAP_ERR_CANT_CLOSE:
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"The file to which the capture was being saved"
|
|
|
|
" couldn't be closed for some unknown reason.");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WTAP_ERR_SHORT_WRITE:
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"Not all the data could be written to the file"
|
|
|
|
" to which the capture was being saved.");
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
1999-11-25 22:37:53 +00:00
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
1999-09-23 07:04:23 +00:00
|
|
|
"The file to which the capture was being"
|
|
|
|
" saved (\"%s\") could not be closed: %s.",
|
1999-11-25 22:37:53 +00:00
|
|
|
cf.save_file, wtap_strerror(err));
|
1999-09-23 07:04:23 +00:00
|
|
|
break;
|
1999-08-18 04:41:20 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
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
|
|
|
pcap_close(pch);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
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
|
|
|
gtk_grab_remove(GTK_WIDGET(cap_w));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(cap_w));
|
|
|
|
|
1999-10-02 06:00:07 +00:00
|
|
|
return TRUE;
|
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
|
|
|
|
1999-09-23 07:04:23 +00:00
|
|
|
error:
|
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
|
|
|
/* We couldn't even start the capture, so get rid of the capture
|
|
|
|
file. */
|
|
|
|
unlink(cf.save_file); /* silently ignore error */
|
Allow the user to save either all of the current capture, or only the
packets that are currently being displayed from that capture.
Centralize the code to control whether "File:Save" and "File:Save As"
are enabled (and *always* have "File:Save As" enabled if you have a
capture; "File:Save" is enabled only if you have a live capture you've
not yet saved, although it does the same thing as "File:Save As").
Have the "save_file" member of a "capture_file" structure represent
*only* the file currently being *written* to by a capture, and, if there
is no capture currently in progress, have it be NULL; the name of the
file currently being *displayed" is in the "filename" member, and an
"is_tempfile" member indicates whether it's a temporary file for a live
capture or not.
Have "close_cap_file()" delete the current capture file if it's a
temporary capture file that hasn't been saved (in its entirety - saving
selected frames doesn't count). Do the same (if there *is* a current
capture file) when exiting.
The "Ready to load or capture" message is the only statusbar message in
the "main" context; "close_cap_file()" should never pop it, it should
only pop whatever message exists in the "file" context, and thus has no
need to take, as an argument, the context for the message it should pop.
Update the man page to reflect the new behavior of "File:Save" and
"File:Save As", and to reflect recent changes to "Display:Match Selected".
svn path=/trunk/; revision=1170
1999-11-30 20:50:15 +00:00
|
|
|
g_free(cf.save_file);
|
|
|
|
cf.save_file = NULL;
|
1999-10-02 20:00:46 +00:00
|
|
|
if (capture_child) {
|
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
|
|
|
/* This is the child process for a sync mode capture.
|
|
|
|
Send the error message to our parent, so they can display a
|
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
|
|
|
dialog box containing it. */
|
|
|
|
int msglen = strlen(errmsg);
|
|
|
|
char lenbuf[10+1+1];
|
|
|
|
sprintf(lenbuf, "%u;", msglen);
|
|
|
|
write(1, lenbuf, strlen(lenbuf));
|
|
|
|
write(1, errmsg, msglen);
|
|
|
|
} else {
|
|
|
|
/* Display the dialog box ourselves; there's no parent. */
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL, errmsg);
|
Improve the alert boxes put up for file open/read/write errors. (Some
influence came from
http://developer.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-232.html
which has a section on dialog box and alert box messages. However,
we're largely dealing with technoids, not with The Rest Of Us, so I
didn't go as far as one perhaps should.)
Unfortunately, it looks like it's a bit more work to arrange that, if
you give a bad file name to the "-r" flag, the dialog box pop up only
*after* the main window pops up - it has the annoying habit of popping
up *before* the main window pops up, and sometimes getting *obscured* by
it, when I do that. The removal of the dialog box stuff from
"load_cap_file()" was intended to facilitate that work. (It might also
be nice if, when an open from the "File/Open" menu item fails, we keep
the file selection box open, and give the user a chance to correct
typos, choose another file name, etc.)
svn path=/trunk/; revision=310
1999-06-12 09:10:20 +00:00
|
|
|
}
|
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
|
|
|
if (pch != NULL)
|
|
|
|
pcap_close(pch);
|
|
|
|
|
1999-10-02 06:00:07 +00:00
|
|
|
return FALSE;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
1999-06-19 01:14:51 +00:00
|
|
|
static float
|
1998-09-16 02:39:15 +00:00
|
|
|
pct(gint num, gint denom) {
|
|
|
|
if (denom) {
|
|
|
|
return (float) num * 100.0 / (float) denom;
|
|
|
|
} else {
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-06-19 01:14:51 +00:00
|
|
|
static void
|
1998-09-16 02:39:15 +00:00
|
|
|
capture_stop_cb(GtkWidget *w, gpointer data) {
|
|
|
|
loop_data *ld = (loop_data *) data;
|
|
|
|
|
|
|
|
ld->go = FALSE;
|
|
|
|
}
|
|
|
|
|
1999-06-19 01:14:51 +00:00
|
|
|
static void
|
1998-09-16 02:39:15 +00:00
|
|
|
capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
|
|
|
|
const u_char *pd) {
|
Add to Wiretap the ability to write capture files; for now, it can only
write them in "libpcap" format, but the mechanism can have other formats
added.
When creating the temporary file for a capture, use "create_tempfile()",
to close a security hole opened by the fact that "tempnam()" creates a
temporary file, but doesn't open it, and we open the file with the name
it gives us - somebody could remove the file and plant a link to some
file, and, if as may well be the case when Ethereal is capturing
packets, it's running as "root", that means we write a capture on top of
that file.... (The aforementioned changes to Wiretap let you open a
capture file for writing given an file descriptor, "fdopen()"-style,
which this change requires.)
svn path=/trunk/; revision=509
1999-08-18 04:17:38 +00:00
|
|
|
struct wtap_pkthdr whdr;
|
1998-09-16 02:39:15 +00:00
|
|
|
loop_data *ld = (loop_data *) user;
|
1999-08-18 04:41:20 +00:00
|
|
|
int err;
|
Add to Wiretap the ability to write capture files; for now, it can only
write them in "libpcap" format, but the mechanism can have other formats
added.
When creating the temporary file for a capture, use "create_tempfile()",
to close a security hole opened by the fact that "tempnam()" creates a
temporary file, but doesn't open it, and we open the file with the name
it gives us - somebody could remove the file and plant a link to some
file, and, if as may well be the case when Ethereal is capturing
packets, it's running as "root", that means we write a capture on top of
that file.... (The aforementioned changes to Wiretap let you open a
capture file for writing given an file descriptor, "fdopen()"-style,
which this change requires.)
svn path=/trunk/; revision=509
1999-08-18 04:17:38 +00:00
|
|
|
|
1999-02-09 00:35:38 +00:00
|
|
|
if ((++ld->counts.total >= ld->max) && (ld->max > 0))
|
1998-09-29 21:39:29 +00:00
|
|
|
{
|
|
|
|
ld->go = FALSE;
|
|
|
|
}
|
Add to Wiretap the ability to write capture files; for now, it can only
write them in "libpcap" format, but the mechanism can have other formats
added.
When creating the temporary file for a capture, use "create_tempfile()",
to close a security hole opened by the fact that "tempnam()" creates a
temporary file, but doesn't open it, and we open the file with the name
it gives us - somebody could remove the file and plant a link to some
file, and, if as may well be the case when Ethereal is capturing
packets, it's running as "root", that means we write a capture on top of
that file.... (The aforementioned changes to Wiretap let you open a
capture file for writing given an file descriptor, "fdopen()"-style,
which this change requires.)
svn path=/trunk/; revision=509
1999-08-18 04:17:38 +00:00
|
|
|
if (ld->pdh) {
|
2000-01-26 23:09:21 +00:00
|
|
|
/* "phdr->ts" may not necessarily be a "struct timeval" - it may
|
|
|
|
be a "struct bpf_timeval", with member sizes wired to 32
|
|
|
|
bits - and we may go that way ourselves in the future, so
|
|
|
|
copy the members individually. */
|
|
|
|
whdr.ts.tv_sec = phdr->ts.tv_sec;
|
|
|
|
whdr.ts.tv_usec = phdr->ts.tv_usec;
|
Add to Wiretap the ability to write capture files; for now, it can only
write them in "libpcap" format, but the mechanism can have other formats
added.
When creating the temporary file for a capture, use "create_tempfile()",
to close a security hole opened by the fact that "tempnam()" creates a
temporary file, but doesn't open it, and we open the file with the name
it gives us - somebody could remove the file and plant a link to some
file, and, if as may well be the case when Ethereal is capturing
packets, it's running as "root", that means we write a capture on top of
that file.... (The aforementioned changes to Wiretap let you open a
capture file for writing given an file descriptor, "fdopen()"-style,
which this change requires.)
svn path=/trunk/; revision=509
1999-08-18 04:17:38 +00:00
|
|
|
whdr.caplen = phdr->caplen;
|
|
|
|
whdr.len = phdr->len;
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
whdr.pkt_encap = ld->linktype;
|
Add to Wiretap the ability to write capture files; for now, it can only
write them in "libpcap" format, but the mechanism can have other formats
added.
When creating the temporary file for a capture, use "create_tempfile()",
to close a security hole opened by the fact that "tempnam()" creates a
temporary file, but doesn't open it, and we open the file with the name
it gives us - somebody could remove the file and plant a link to some
file, and, if as may well be the case when Ethereal is capturing
packets, it's running as "root", that means we write a capture on top of
that file.... (The aforementioned changes to Wiretap let you open a
capture file for writing given an file descriptor, "fdopen()"-style,
which this change requires.)
svn path=/trunk/; revision=509
1999-08-18 04:17:38 +00:00
|
|
|
|
1999-08-18 04:41:20 +00:00
|
|
|
/* XXX - do something if this fails */
|
|
|
|
wtap_dump(ld->pdh, &whdr, pd, &err);
|
Add to Wiretap the ability to write capture files; for now, it can only
write them in "libpcap" format, but the mechanism can have other formats
added.
When creating the temporary file for a capture, use "create_tempfile()",
to close a security hole opened by the fact that "tempnam()" creates a
temporary file, but doesn't open it, and we open the file with the name
it gives us - somebody could remove the file and plant a link to some
file, and, if as may well be the case when Ethereal is capturing
packets, it's running as "root", that means we write a capture on top of
that file.... (The aforementioned changes to Wiretap let you open a
capture file for writing given an file descriptor, "fdopen()"-style,
which this change requires.)
svn path=/trunk/; revision=509
1999-08-18 04:17:38 +00:00
|
|
|
}
|
2000-01-23 08:55:37 +00:00
|
|
|
|
|
|
|
/* Set the initial payload to the packet length, and the initial
|
|
|
|
captured payload to the capture length (other protocols may
|
|
|
|
reduce them if their headers say they're less). */
|
|
|
|
pi.len = phdr->len;
|
|
|
|
pi.captured_len = phdr->caplen;
|
1999-08-10 11:08:38 +00:00
|
|
|
|
1999-02-09 00:35:38 +00:00
|
|
|
switch (ld->linktype) {
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
case WTAP_ENCAP_ETHERNET:
|
2000-01-23 08:55:37 +00:00
|
|
|
capture_eth(pd, 0, &ld->counts);
|
1999-02-09 00:35:38 +00:00
|
|
|
break;
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
case WTAP_ENCAP_FDDI:
|
Add a new Wiretap encapsulation type WTAP_ENCAP_FDDI_BITSWAPPED, meaning
"FDDI with the MAC addresses bit-swapped"; whether the MAC addresses are
bit-swapped is a property of the machine on which the capture was taken,
not of the machine on which the capture is being read - right now, none
of the capture file formats we read indicate whether FDDI MAC addresses
are bit-swapped, but this does let us treat non-"libpcap" captures as
being bit-swapped or not bit-swapped independent of the machine on which
they're being read (and of the machine on which they were captured, but
I have the impression they're bit-swapped on most platforms), and allows
us to, if, as, and when we implement packet capture in Wiretap, mark
packets in a capture file written in Wiretap-native format based on the
machine on which they are captured (assuming the rule "Ultrix, Alpha,
and BSD/OS are the only platforms that don't bit-swap", or some other
compile-time rule, gets the right answer, or that some platform has
drivers that can tell us whether the addresses are bit-swapped).
(NOTE: if, for any of the capture file formats used only on one
platform, FDDI MAC addresses aren't bit-swapped, the code to read that
capture file format should be fixed to flag them as not bit-swapped.)
Use the encapsulation type to decide whether to bit-swap addresses in
"dissect_fddi()".
svn path=/trunk/; revision=557
1999-08-24 03:19:34 +00:00
|
|
|
case WTAP_ENCAP_FDDI_BITSWAPPED:
|
2000-01-23 08:55:37 +00:00
|
|
|
capture_fddi(pd, &ld->counts);
|
1999-02-09 00:35:38 +00:00
|
|
|
break;
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
case WTAP_ENCAP_TR:
|
2000-01-23 08:55:37 +00:00
|
|
|
capture_tr(pd, 0, &ld->counts);
|
1999-02-09 00:35:38 +00:00
|
|
|
break;
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
case WTAP_ENCAP_NULL:
|
2000-01-23 08:55:37 +00:00
|
|
|
capture_null(pd, &ld->counts);
|
1999-02-09 00:35:38 +00:00
|
|
|
break;
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
case WTAP_ENCAP_PPP:
|
2000-01-23 08:55:37 +00:00
|
|
|
capture_ppp(pd, &ld->counts);
|
1999-02-09 00:35:38 +00:00
|
|
|
break;
|
DLT_NULL, from "libpcap", means different things on different platforms
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:
1) PPP-over-HDLC (some version of ISDN4BSD?);
2) big-endian AF_ value (BSD on big-endian platforms);
3) little-endian AF_ value (BSD on little-endian platforms);
4) two octets of 0 followed by an Ethernet type (Linux, at least
on little-endian platforms, as mutated by "libpcap").
Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.
Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.
Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.
Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.
Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces. Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).
Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.
svn path=/trunk/; revision=540
1999-08-22 00:47:56 +00:00
|
|
|
case WTAP_ENCAP_RAW_IP:
|
2000-01-23 08:55:37 +00:00
|
|
|
capture_raw(pd, &ld->counts);
|
1999-02-09 00:35:38 +00:00
|
|
|
break;
|
1999-08-22 02:29:40 +00:00
|
|
|
/* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
|
|
|
|
with LLC header following; we should implement it at some
|
|
|
|
point. */
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
1999-07-09 04:18:36 +00:00
|
|
|
|
|
|
|
#endif /* HAVE_LIBPCAP */
|