aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2006-05-20 22:01:08 +0000
committerGuy Harris <guy@alum.mit.edu>2006-05-20 22:01:08 +0000
commit37a570600e7188e9a0d3ef5bbdf66dec431689be (patch)
tree130195e06483cf3d322eda717d9b4536fd451e2a
parent629f0ecbe58ca0c083717496e679ba84fa7d6442 (diff)
Dumpcap doesn't need to ensure that it doesn't block indefinitely, as it
has no UI, nor does it need to ensure it processes only one packet at a time; get rid of the select stuff, and pass a count of -1 to pcap_dispatch() so it processes a single bufferfull of packets rather than just one packet at a time. svn path=/trunk/; revision=18194
-rw-r--r--capture_loop.c138
-rw-r--r--capture_loop.h26
2 files changed, 26 insertions, 138 deletions
diff --git a/capture_loop.c b/capture_loop.c
index 16d32bb350..d87854f534 100644
--- a/capture_loop.c
+++ b/capture_loop.c
@@ -628,17 +628,6 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
#endif
}
-/* XXX - will this work for tethereal? */
-#ifdef MUST_DO_SELECT
- if (!ld->from_cap_pipe) {
-#ifdef HAVE_PCAP_GET_SELECTABLE_FD
- ld->pcap_fd = pcap_get_selectable_fd(ld->pcap_h);
-#else
- ld->pcap_fd = pcap_fileno(ld->pcap_h);
-#endif
- }
-#endif
-
/* Does "open_err_str" contain a non-empty string? If so, "pcap_open_live()"
returned a warning; print it, but keep capturing. */
if (open_err_str[0] != '\0') {
@@ -843,115 +832,43 @@ capture_loop_dispatch(capture_options *capture_opts _U_, loop_data *ld,
#endif /* _WIN32 */
{
/* dispatch from pcap */
-#ifdef MUST_DO_SELECT
- /*
- * Sigh. The semantics of the read timeout argument to
- * "pcap_open_live()" aren't particularly well specified by
- * the "pcap" man page - at least with the BSD BPF code, the
- * intent appears to be, at least in part, a way of cutting
- * down the number of reads done on a capture, by blocking
- * until the buffer fills or a timer expires - and the Linux
- * libpcap doesn't actually support it, so we can't use it
- * to break out of the "pcap_dispatch()" every 1/4 of a second
- * or so. Linux's libpcap is not the only libpcap that doesn't
- * support the read timeout.
- *
- * Furthermore, at least on Solaris, the bufmod STREAMS module's
- * read timeout won't go off if no data has arrived, i.e. it cannot
- * be used to guarantee that a read from a DLPI stream will return
- * within a specified amount of time regardless of whether any
- * data arrives or not.
- *
- * Thus, on all platforms other than BSD, we do a "select()" on the
- * file descriptor for the capture, with a timeout of CAP_READ_TIMEOUT
- * milliseconds, or CAP_READ_TIMEOUT*1000 microseconds.
- *
- * "select()", on BPF devices, doesn't work as you might expect;
- * at least on some versions of some flavors of BSD, the timer
- * doesn't start until a read is done, so it won't expire if
- * only a "select()" or "poll()" is posted.
- *
- * If we have "pcap_get_selectable_fd()", we use it to get the
- * descriptor on which to select; if that's -1, it means there
- * is no descriptor on which you can do a "select()" (perhaps
- * because you're capturing on a special device, and that device's
- * driver unfortunately doesn't support "select()", in which case
- * we don't do the select - which means Ethereal might block,
- * unable to accept user input, until a packet arrives. If
- * that's unacceptable, plead with whoever supplies the software
- * for that device to add "select()" support.
- */
-#ifdef LOG_CAPTURE_VERBOSE
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_dispatch: from pcap_dispatch with select");
-#endif
- if (ld->pcap_fd != -1) {
- FD_ZERO(&set1);
- FD_SET(ld->pcap_fd, &set1);
- timeout.tv_sec = 0;
- timeout.tv_usec = CAP_READ_TIMEOUT*1000;
- sel_ret = select(ld->pcap_fd+1, &set1, NULL, NULL, &timeout);
- if (sel_ret > 0) {
- /*
- * "select()" says we can read from it without blocking; go for
- * it.
- */
- inpkts = pcap_dispatch(ld->pcap_h, 1, ld->packet_cb, (u_char *)ld);
- if (inpkts < 0) {
- ld->pcap_err = TRUE;
- ld->go = FALSE;
- }
- } else {
- inpkts = 0;
- if (sel_ret < 0 && errno != EINTR) {
- g_snprintf(errmsg, errmsg_len,
- "Unexpected error from select: %s", strerror(errno));
- report_capture_error(errmsg, please_report);
- ld->go = FALSE;
- }
- }
- }
- else
-#endif /* MUST_DO_SELECT */
- {
- /* dispatch from pcap without select */
#if 1
#ifdef LOG_CAPTURE_VERBOSE
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_dispatch: from pcap_dispatch");
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_dispatch: from pcap_dispatch");
#endif
- inpkts = pcap_dispatch(ld->pcap_h, 1, ld->packet_cb, (u_char *) ld);
- if (inpkts < 0) {
- ld->pcap_err = TRUE;
- ld->go = FALSE;
- }
+ inpkts = pcap_dispatch(ld->pcap_h, -1, ld->packet_cb, (u_char *) ld);
+ if (inpkts < 0) {
+ ld->pcap_err = TRUE;
+ ld->go = FALSE;
+ }
#else
- {
#ifdef LOG_CAPTURE_VERBOSE
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_dispatch: from pcap_next_ex");
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_dispatch: from pcap_next_ex");
#endif
- /* XXX - this is currently unused, as there is some confusion with pcap_next_ex() vs. pcap_dispatch() */
-
- /* WinPcap's remote capturing feature doesn't work, see http://wiki.ethereal.com/CaptureSetup_2fWinPcapRemote */
- /* for reference, an example remote interface: rpcap://[1.2.3.4]/\Device\NPF_{39993D68-7C9B-4439-A329-F2D888DA7C5C} */
+ /* XXX - this is currently unused, as there is some confusion with pcap_next_ex() vs. pcap_dispatch() */
- /* emulate dispatch from pcap */
- int in;
- struct pcap_pkthdr *pkt_header;
- u_char *pkt_data;
+ /* WinPcap's remote capturing feature doesn't work, see http://wiki.ethereal.com/CaptureSetup_2fWinPcapRemote */
+ /* for reference, an example remote interface: rpcap://[1.2.3.4]/\Device\NPF_{39993D68-7C9B-4439-A329-F2D888DA7C5C} */
- inpkts = 0;
- while( (in = pcap_next_ex(ld->pcap_h, &pkt_header, &pkt_data)) == 1) {
- ld->packet_cb( (u_char *) ld, pkt_header, pkt_data);
- inpkts++;
- }
+ /* emulate dispatch from pcap */
+ {
+ int in;
+ struct pcap_pkthdr *pkt_header;
+ u_char *pkt_data;
+
+ inpkts = 0;
+ while( (in = pcap_next_ex(ld->pcap_h, &pkt_header, &pkt_data)) == 1) {
+ ld->packet_cb( (u_char *) ld, pkt_header, pkt_data);
+ inpkts++;
+ }
- if(in < 0) {
- ld->pcap_err = TRUE;
- ld->go = FALSE;
- inpkts = in;
- }
+ if(in < 0) {
+ ld->pcap_err = TRUE;
+ ld->go = FALSE;
+ inpkts = in;
}
-#endif
}
+#endif
}
#ifdef LOG_CAPTURE_VERBOSE
@@ -1102,9 +1019,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
#ifndef _WIN32
ld.cap_pipe_fd = -1;
#endif
-#ifdef MUST_DO_SELECT
- ld.pcap_fd = 0;
-#endif
ld.packet_cb = capture_loop_packet_cb;
diff --git a/capture_loop.h b/capture_loop.h
index c0a91e2e24..4d2778793b 100644
--- a/capture_loop.h
+++ b/capture_loop.h
@@ -51,29 +51,6 @@ extern void capture_loop_stop(void);
/*** the following is internal only (should be moved to capture_loop_int.h) ***/
-/*
- * We don't want to do a "select()" on the pcap_t's file descriptor on
- * BSD (because "select()" doesn't work correctly on BPF devices on at
- * least some releases of some flavors of BSD), and we don't want to do
- * it on Windows (because "select()" is something for sockets, not for
- * arbitrary handles). (Note that "Windows" here includes Cygwin;
- * even in its pretend-it's-UNIX environment, we're using WinPcap, not
- * a UNIX libpcap.)
- *
- * We *do* want to do it on other platforms, as, on other platforms (with
- * the possible exception of Ultrix and Digital UNIX), the read timeout
- * doesn't expire if no packets have arrived, so a "pcap_dispatch()" call
- * will block until packets arrive, causing the UI to hang.
- *
- * XXX - the various BSDs appear to define BSD in <sys/param.h>; we don't
- * want to include it if it's not present on this platform, however.
- */
-#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && \
- !defined(__bsdi__) && !defined(__APPLE__) && !defined(_WIN32) && \
- !defined(__CYGWIN__)
-# define MUST_DO_SELECT
-#endif
-
typedef void (*capture_packet_cb_fct)(u_char *, const struct pcap_pkthdr *, const u_char *);
@@ -95,9 +72,6 @@ typedef struct _loop_data {
/* pcap "input file" */
pcap_t *pcap_h; /* pcap handle */
gboolean pcap_err; /* E: TRUE if error from pcap */
-#ifdef MUST_DO_SELECT
- int pcap_fd; /* pcap file descriptor */
-#endif
/* capture pipe (unix only "input file") */
gboolean from_cap_pipe; /* TRUE if we are capturing data from a capture pipe */