1998-09-16 02:39:15 +00:00
|
|
|
/* capture.c
|
|
|
|
* Routines for packet capture windows
|
|
|
|
*
|
1999-10-01 21:52:03 +00:00
|
|
|
* $Id: capture.c,v 1.75 1999/10/01 21:51:55 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
|
|
|
|
|
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-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-09-09 02:42:40 +00:00
|
|
|
#include "gtk/main.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "packet.h"
|
|
|
|
#include "file.h"
|
1999-09-01 03:04:24 +00:00
|
|
|
#include "gtk/menu.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "capture.h"
|
|
|
|
#include "util.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 */
|
|
|
|
int sync_pipe[2]; /* used to sync father */
|
|
|
|
int fork_mode; /* fork a child to do the capture */
|
|
|
|
int quit_after_cap; /* Makes a "capture only mode". Implies -k */
|
|
|
|
gboolean capture_child; /* if this is the child for "-F"/"-S" */
|
|
|
|
|
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;
|
|
|
|
|
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
|
|
|
/* Create a temporary file and start a capture to it. */
|
1998-09-16 02:39:15 +00:00
|
|
|
void
|
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
|
|
|
do_capture(void)
|
|
|
|
{
|
|
|
|
char tmpname[128+1];
|
|
|
|
|
1999-09-23 07:04:23 +00:00
|
|
|
/* Choose a random name for the capture buffer */
|
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
|
|
|
cf.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
|
|
|
|
if (cf.save_file_fd == -1) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"The file to which the capture would be saved (\"%s\")"
|
|
|
|
"could not be opened: %s.", tmpname, strerror(errno));
|
|
|
|
return;
|
|
|
|
}
|
Close the capture file in "do_capture()", right before unlinking the
current capture file if it's a temporary file, out of paranoia (so that
we don't get into a state where we have a capture file open but unlinked
- it's probably harmless to be in that state, as the file will remain
around until close, modulo NFS fun, and we may never be in that state
for very long, but I'd rather have it obviously stated in the code).
Remove the close in "capture()", and put one before the other call to
"capture()", in "main_realize_cb()" (is that call necessary, e.g. if you
pass "-r <filename>" *and* "-k", for some perverse reason, as
command-line arguments?).
If "cf.save_file" is non-null, free it before setting it, regardless of
whether it refers to a temporary file name or not.
svn path=/trunk/; revision=712
1999-09-23 07:57:23 +00:00
|
|
|
close_cap_file(&cf, info_bar, file_ctx);
|
|
|
|
if (cf.save_file != NULL) {
|
|
|
|
/* If the current file is a temporary capture file, remove it. */
|
|
|
|
if (!cf.user_saved)
|
|
|
|
unlink(cf.save_file); /* silently ignore error */
|
|
|
|
g_free(cf.save_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
|
|
|
cf.save_file = g_strdup(tmpname);
|
|
|
|
cf.user_saved = 0;
|
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
|
|
|
|
|
|
|
run_capture();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Start a capture to a file we've opened; "cf.save_file" is the
|
|
|
|
pathname of the file, and "cf.save_file_fd" is the file descriptor
|
|
|
|
we got when we opened it. */
|
|
|
|
void
|
|
|
|
run_capture(void)
|
|
|
|
{
|
|
|
|
u_char c;
|
|
|
|
int i;
|
|
|
|
guint byte_count;
|
|
|
|
char *msg;
|
|
|
|
|
1999-09-23 07:20:20 +00:00
|
|
|
if (sync_mode || fork_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];
|
|
|
|
int err;
|
|
|
|
|
|
|
|
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-09-23 07:04:23 +00:00
|
|
|
if (sync_mode)
|
|
|
|
pipe(sync_pipe);
|
|
|
|
if ((fork_child = fork()) == 0) {
|
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
|
|
|
/* args: -k -- capture
|
|
|
|
* -i interface specification
|
|
|
|
* -w file to write
|
|
|
|
* -W file descriptor to write
|
|
|
|
* -c count to capture
|
|
|
|
* -Q quit after capture (forces -k)
|
|
|
|
* -s snaplen
|
|
|
|
* -S sync mode
|
|
|
|
* -m / -b fonts
|
|
|
|
* -f "filter expression"
|
|
|
|
*/
|
|
|
|
if (sync_mode) {
|
|
|
|
close(1);
|
|
|
|
dup(sync_pipe[1]);
|
|
|
|
close(sync_pipe[0]);
|
If we're given the "-k" flag, don't start the capture until after we've:
popped up the top-level window (so that it looks like a capture
started from "Capture/Start");
initialized the colors (so that we don't dump core when reading
in the capture file);
popped up any message box for failure to read the preferences
file.
This means we start the capture in "main()", rather than in the realize
callback for the main window, so get rid of that callback.
If we're a child process that's just capturing to a file for our parent
to read, however, we shouldn't pop up the top-level window, because
that's our parent's job; when running that child, set its "argv[0]" to a
special name, so that
1) it shows up in a "ps" with a special name;
2) we don't have to invent Yet Another Flag to say "you're the
child".
(We may want to use the name to turn on *all* behaviors that the capture
child, and only the capture child, should exhibit.)
If "-w" and "-k" were both specified, attempt to open the file specified
by "-w" and, if that succeeds, set "cf.save_file_fd" to refer to it, so
that "-w" plus "-k" works again, rather than popping up a "The file to
which the capture would be saved ... could not be opened: Bad file
descriptor." message box.
svn path=/trunk/; revision=739
1999-09-30 06:11:51 +00:00
|
|
|
execlp(ethereal_path, CHILD_NAME, "-k", "-Q", "-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,
|
|
|
|
"-c", scount, "-s", ssnap, "-S",
|
|
|
|
"-m", medium_font, "-b", bold_font,
|
|
|
|
(cf.cfilter == NULL)? 0 : "-f",
|
|
|
|
(cf.cfilter == NULL)? 0 : cf.cfilter,
|
|
|
|
(const char *)NULL);
|
|
|
|
}
|
|
|
|
else {
|
If we're given the "-k" flag, don't start the capture until after we've:
popped up the top-level window (so that it looks like a capture
started from "Capture/Start");
initialized the colors (so that we don't dump core when reading
in the capture file);
popped up any message box for failure to read the preferences
file.
This means we start the capture in "main()", rather than in the realize
callback for the main window, so get rid of that callback.
If we're a child process that's just capturing to a file for our parent
to read, however, we shouldn't pop up the top-level window, because
that's our parent's job; when running that child, set its "argv[0]" to a
special name, so that
1) it shows up in a "ps" with a special name;
2) we don't have to invent Yet Another Flag to say "you're the
child".
(We may want to use the name to turn on *all* behaviors that the capture
child, and only the capture child, should exhibit.)
If "-w" and "-k" were both specified, attempt to open the file specified
by "-w" and, if that succeeds, set "cf.save_file_fd" to refer to it, so
that "-w" plus "-k" works again, rather than popping up a "The file to
which the capture would be saved ... could not be opened: Bad file
descriptor." message box.
svn path=/trunk/; revision=739
1999-09-30 06:11:51 +00:00
|
|
|
execlp(ethereal_path, CHILD_NAME, "-k", "-Q", "-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,
|
|
|
|
"-c", scount, "-s", ssnap,
|
|
|
|
"-m", medium_font, "-b", bold_font,
|
|
|
|
(cf.cfilter == NULL)? 0 : "-f",
|
|
|
|
(cf.cfilter == NULL)? 0 : cf.cfilter,
|
|
|
|
(const char *)NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
cf.filename = cf.save_file;
|
|
|
|
if (sync_mode) {
|
|
|
|
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.
|
|
|
|
XXX - reap it and report the status. */
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL, "Capture child process died");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (c == ';')
|
|
|
|
break;
|
|
|
|
if (!isdigit(c)) {
|
|
|
|
/* Child process handed us crap. */
|
|
|
|
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) {
|
|
|
|
/* Success. */
|
|
|
|
err = tail_cap_file(cf.save_file, &cf);
|
|
|
|
if (err != 0) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
file_open_error_message(err, FALSE), cf.save_file);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Failure. */
|
|
|
|
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,
|
|
|
|
"Capture child process failed: Error %s reading its error message.",
|
|
|
|
strerror(errno));
|
|
|
|
} else if (i == 0) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"Capture child process failed: EOF reading its error message.");
|
|
|
|
} else
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL, msg);
|
|
|
|
g_free(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
capture();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/* Do the low-level work of a 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
|
|
|
void
|
|
|
|
capture(void)
|
|
|
|
{
|
1999-08-14 23:47:20 +00:00
|
|
|
GtkWidget *cap_w, *main_vb, *count_lb, *tcp_lb, *udp_lb, *icmp_lb,
|
1999-08-10 20:06:39 +00:00
|
|
|
*ospf_lb, *gre_lb, *netbios_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];
|
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;
|
|
|
|
ld.counts.netbios = 0;
|
|
|
|
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. */
|
1998-09-16 02:39:15 +00:00
|
|
|
pch = pcap_open_live(cf.iface, cf.snap, 1, 250, err_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
|
|
|
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
|
|
|
}
|
|
|
|
|
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
|
|
|
if (capture_child && sync_mode) {
|
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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
while (ld.go) {
|
|
|
|
while (gtk_events_pending()) gtk_main_iteration();
|
|
|
|
inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
|
|
|
|
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);
|
|
|
|
|
|
|
|
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));
|
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
|
|
|
if (capture_child && sync_mode && ld.sync_packets) {
|
|
|
|
/* 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:
|
|
|
|
if (err < 0) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"The file to which the capture was being"
|
|
|
|
" saved (\"%s\") could not be closed: Error %d.",
|
|
|
|
cf.save_file, err);
|
|
|
|
} else {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"The file to which the capture was being"
|
|
|
|
" saved (\"%s\") could not be closed: %s.",
|
|
|
|
cf.save_file, strerror(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-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));
|
|
|
|
|
|
|
|
if (quit_after_cap) {
|
1999-05-11 18:51:10 +00:00
|
|
|
/* DON'T unlink the save file. Presumably someone wants it. */
|
|
|
|
gtk_exit(0);
|
|
|
|
}
|
|
|
|
|
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 ((err = open_cap_file(cf.save_file, &cf)) == 0) {
|
|
|
|
/* Set the read filter to NULL. */
|
|
|
|
cf.rfcode = NULL;
|
|
|
|
err = read_cap_file(&cf);
|
|
|
|
set_menu_sensitivity("/File/Save", TRUE);
|
|
|
|
set_menu_sensitivity("/File/Save As...", FALSE);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
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 */
|
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
|
|
|
if (capture_child && sync_mode) {
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
if (quit_after_cap)
|
|
|
|
gtk_exit(0);
|
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) {
|
|
|
|
whdr.ts = phdr->ts;
|
|
|
|
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
|
|
|
}
|
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:
|
1999-02-09 00:35:38 +00:00
|
|
|
capture_eth(pd, phdr->caplen, &ld->counts);
|
|
|
|
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:
|
1999-02-09 00:35:38 +00:00
|
|
|
capture_fddi(pd, phdr->caplen, &ld->counts);
|
|
|
|
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:
|
1999-02-09 00:35:38 +00:00
|
|
|
capture_tr(pd, phdr->caplen, &ld->counts);
|
|
|
|
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:
|
1999-02-09 00:35:38 +00:00
|
|
|
capture_null(pd, phdr->caplen, &ld->counts);
|
|
|
|
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:
|
1999-02-09 00:35:38 +00:00
|
|
|
capture_ppp(pd, phdr->caplen, &ld->counts);
|
|
|
|
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:
|
1999-02-09 00:35:38 +00:00
|
|
|
capture_raw(pd, phdr->caplen, &ld->counts);
|
|
|
|
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 */
|