Make the "go" member of the "loop_data" structure in Ethereal a
"gboolean", as it's a Boolean value, and move it to the beginning of the structure in Tethereal, as it is in Ethereal. From Graeme Hewson: Check for "pcap_dispatch()" returning -1, meaning an error occurred; if it does, stop capturing, and report the error. If we get a signal in tethereal, stop the capture with a "longjmp()", rather than by clearning the "go" flag; "pcap_dispatch()", on many platforms, keeps reading rather than returning a captured packet count of 0 if the system call to read packets returns -1 with an errno of EINTR, so the "pcap_dispatch()" won't be broken out of if the signal handler returns. Fix a typo in an error message. svn path=/trunk/; revision=4471
This commit is contained in:
parent
98b2ecb304
commit
b1f4093d1a
2
AUTHORS
2
AUTHORS
|
@ -853,6 +853,8 @@ Endoh Akira <endoh[AT]netmarks.co.jp> {
|
|||
|
||||
Graeme Hewson <graeme.hewson[AT]oracle.com> {
|
||||
Additional Ascend codes, and IETF codes, for Radius
|
||||
Handle errors from "pcap_dispatch()"
|
||||
Fix Tethereal so signals break it out of the capture loop
|
||||
}
|
||||
|
||||
Pasi Eronen <pasi.eronen[at]nixu.com> {
|
||||
|
|
28
capture.c
28
capture.c
|
@ -1,7 +1,7 @@
|
|||
/* capture.c
|
||||
* Routines for packet capture windows
|
||||
*
|
||||
* $Id: capture.c,v 1.163 2001/12/04 08:25:55 guy Exp $
|
||||
* $Id: capture.c,v 1.164 2002/01/03 22:03:24 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -204,11 +204,12 @@ static float pct(gint, gint);
|
|||
static void stop_capture(int signo);
|
||||
|
||||
typedef struct _loop_data {
|
||||
gint go; /* TRUE as long as we're supposed to keep capturing */
|
||||
gboolean go; /* TRUE as long as we're supposed to keep capturing */
|
||||
gint max; /* Number of packets we're supposed to capture - 0 means infinite */
|
||||
int err; /* if non-zero, error seen while capturing */
|
||||
gint linktype;
|
||||
gint sync_packets;
|
||||
gboolean pcap_err; /* TRUE if error from pcap */
|
||||
gboolean from_pipe; /* TRUE if we are capturing data from a pipe */
|
||||
gboolean modified; /* TRUE if data in the pipe uses modified pcap headers */
|
||||
gboolean byte_swapped; /* TRUE if data in the pipe is byte swapped */
|
||||
|
@ -1303,6 +1304,7 @@ capture(gboolean *stats_known, struct pcap_stat *stats)
|
|||
ld.max = cfile.count;
|
||||
ld.err = 0; /* no error seen yet */
|
||||
ld.linktype = WTAP_ENCAP_UNKNOWN;
|
||||
ld.pcap_err = FALSE;
|
||||
ld.from_pipe = FALSE;
|
||||
ld.sync_packets = 0;
|
||||
ld.counts.sctp = 0;
|
||||
|
@ -1639,10 +1641,18 @@ capture(gboolean *stats_known, struct pcap_stat *stats)
|
|||
* it.
|
||||
*/
|
||||
inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
|
||||
if (inpkts < 0) {
|
||||
ld.pcap_err = TRUE;
|
||||
ld.go = FALSE;
|
||||
}
|
||||
} else
|
||||
inpkts = 0;
|
||||
#else
|
||||
inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
|
||||
if (inpkts < 0) {
|
||||
ld.pcap_err = TRUE;
|
||||
ld.go = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (inpkts > 0)
|
||||
|
@ -1704,6 +1714,20 @@ capture(gboolean *stats_known, struct pcap_stat *stats)
|
|||
cnd_delete(cnd_stop_capturesize);
|
||||
cnd_delete(cnd_stop_timeout);
|
||||
|
||||
if (ld.pcap_err) {
|
||||
snprintf(errmsg, sizeof(errmsg), "Error while capturing packets: %s",
|
||||
pcap_geterr(pch));
|
||||
if (capture_child) {
|
||||
/* Tell the parent, so that they can pop up the message;
|
||||
we're going to exit, so if we try to pop it up, either
|
||||
it won't pop up or it'll disappear as soon as we exit. */
|
||||
send_errmsg_to_parent(errmsg);
|
||||
} else {
|
||||
/* Just pop up the message ourselves. */
|
||||
simple_dialog(ESD_TYPE_WARN, NULL, "%s", errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
if (ld.err != 0) {
|
||||
get_capture_file_io_error(errmsg, sizeof(errmsg), cfile.save_file, ld.err,
|
||||
FALSE);
|
||||
|
|
28
tethereal.c
28
tethereal.c
|
@ -1,6 +1,6 @@
|
|||
/* tethereal.c
|
||||
*
|
||||
* $Id: tethereal.c,v 1.112 2001/12/21 20:32:53 guy Exp $
|
||||
* $Id: tethereal.c,v 1.113 2002/01/03 22:03:24 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -57,6 +57,7 @@
|
|||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
#include <pcap.h>
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
|
@ -122,10 +123,11 @@ static gboolean line_buffered;
|
|||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
typedef struct _loop_data {
|
||||
gboolean go; /* TRUE as long as we're supposed to keep capturing */
|
||||
gint linktype;
|
||||
pcap_t *pch;
|
||||
wtap_dumper *pdh;
|
||||
gboolean go;
|
||||
jmp_buf stopenv;
|
||||
} loop_data;
|
||||
|
||||
static loop_data ld;
|
||||
|
@ -755,14 +757,15 @@ main(int argc, char *argv[])
|
|||
/* Do the low-level work of a capture.
|
||||
Returns TRUE if it succeeds, FALSE otherwise. */
|
||||
static int
|
||||
capture(int packet_count, int out_file_type)
|
||||
capture(volatile int packet_count, int out_file_type)
|
||||
{
|
||||
gchar open_err_str[PCAP_ERRBUF_SIZE];
|
||||
gchar lookup_net_err_str[PCAP_ERRBUF_SIZE];
|
||||
bpf_u_int32 netnum, netmask;
|
||||
struct bpf_program fcode;
|
||||
void (*oldhandler)(int);
|
||||
int err, inpkts;
|
||||
int err;
|
||||
volatile int inpkts = 0;
|
||||
char errmsg[1024+1];
|
||||
condition *cnd_stop_capturesize;
|
||||
condition *cnd_stop_timeout;
|
||||
|
@ -848,7 +851,7 @@ capture(int packet_count, int out_file_type)
|
|||
* we just warn the user, and punt and use 0.
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"Warning: Couldn't obtain netmask info (%s)\n.", lookup_net_err_str);
|
||||
"Warning: Couldn't obtain netmask info (%s).\n", lookup_net_err_str);
|
||||
netmask = 0;
|
||||
}
|
||||
if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
|
||||
|
@ -923,12 +926,15 @@ capture(int packet_count, int out_file_type)
|
|||
|
||||
if (packet_count == 0)
|
||||
packet_count = -1; /* infinite capturng */
|
||||
ld.go = TRUE;
|
||||
if (!setjmp(ld.stopenv))
|
||||
ld.go = TRUE;
|
||||
else
|
||||
ld.go = FALSE;
|
||||
while (ld.go) {
|
||||
if (packet_count > 0)
|
||||
packet_count--;
|
||||
inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
|
||||
if (packet_count == 0) {
|
||||
if (packet_count == 0 || inpkts < 0) {
|
||||
ld.go = FALSE;
|
||||
} else if (cnd_eval(cnd_stop_timeout) == TRUE) {
|
||||
/* The specified capture time has elapsed; stop the capture. */
|
||||
|
@ -1038,9 +1044,11 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
|
|||
static void
|
||||
capture_cleanup(int signum)
|
||||
{
|
||||
/* Just set the loop flag to false. This will initiate
|
||||
a proper termination. */
|
||||
ld.go = FALSE;
|
||||
/* Longjmp back to the starting point; "pcap_dispatch()", on many
|
||||
platforms, just keeps looping if it gets EINTR, so if we set
|
||||
"ld.go" to FALSE and return, we won't break out of it and quit
|
||||
capturing. */
|
||||
longjmp(ld.stopenv, 1);
|
||||
}
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
|
||||
|
|
Loading…
Reference in New Issue