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):