Ethereal-dev: [Ethereal-dev] Patches for capture.c and tethereal.c (0.9.0)
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Graeme Hewson <ghewson@xxxxxxxxxxxxxxxxxxx>
Date: Sun, 30 Dec 2001 19:11:19 +0000
Ethereal and tethereal ignore errors from pcap_dispatch. This means they can look as if they're capturing packets even if the interface (such as a dial-up PPP link) is down. Someone might think he could start capturing with the interface down, bring up the interface, and ethereal/tethereal would then start recording data. That won't work, though. The attached patches add checks for pcap_dispatch, and stop capturing if the call fails. The patch for tethereal also fixes a couple of other problems: 1. A misplaced period in a message. 2. SIGTERM and SIGINT are ignored until pcap_dispatch next returns. This could be a problem if a capture filter is defined, for instance. My patch uses setjmp and longjmp, so I hope there are no portability issues. Graeme Hewson
--- capture.c.orig Sun Dec 9 15:16:38 2001
+++ capture.c Sat Dec 29 18:51:52 2001
@@ -209,6 +209,7 @@
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 @@
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 @@
* 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)
@@ -1703,6 +1713,20 @@
/* delete stop conditions */
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,
--- tethereal.c.orig Fri Dec 21 22:26:49 2001
+++ tethereal.c Sun Dec 30 17:06:24 2001
@@ -57,6 +57,7 @@
#ifdef HAVE_LIBPCAP
#include <pcap.h>
+#include <setjmp.h>
#endif
#ifdef HAVE_LIBZ
@@ -125,6 +126,7 @@
gint linktype;
pcap_t *pch;
wtap_dumper *pdh;
+ jmp_buf stopenv;
gboolean go;
} loop_data;
@@ -755,14 +757,15 @@
/* 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 @@
* 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 @@
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,7 @@
static void
capture_cleanup(int signum)
{
- /* Just set the loop flag to false. This will initiate
- a proper termination. */
- ld.go = FALSE;
+ longjmp(ld.stopenv, 1);
}
#endif /* HAVE_LIBPCAP */
- Prev by Date: [Ethereal-dev] Executing Error: "g_main_context_iteration" could not be founded in the DLL "glib-1.3.dll"
- Next by Date: [Ethereal-dev] Can't change timestamp format on ICMP packet
- Previous by thread: [Ethereal-dev] Executing Error: "g_main_context_iteration" could not be founded in the DLL "glib-1.3.dll"
- Next by thread: [Ethereal-dev] Can't change timestamp format on ICMP packet
- Index(es):