Ethereal-users: Re: [ethereal-users] installation problems..
> The patch was available on the Karpski home page. Does anyone have a
> copy we can put on the ethereal home page?
Date: Sun, 3 Jan 1999 20:37:22 -0600 (EST)
From: Gerald Combs <gerald@xxxxxxxx>
To: Guy Harris <guy@xxxxxxxxxx>
cc: btx@xxxxxxxxx
Subject: Re: Patch to let Linux "libpcap" support timeouts
On Fri, 4 Dec 1998, Guy Harris wrote:
> Here's a modified version of the patch, which:
>
> keeps the timeout value in the "pcap_t" per-open structure,
> rather than using a single global variable;
>
> bypasses the "select()" call if the timeout is 0.
>
> I don't have a Linux box on which to test it, but, if it compiles and
> works, you should probably submit it to "libpcap@xxxxxxxxxx" so that it
> becomes part of the next "libpcap" release (if, as, and when *that* ever
> appears).
Under Linux, select() changes the timeout struct values to the time not
slept. In a loop, the timeout dwindles to zero in a hurry. I modified
your patch to pass in a fresh copy of the timeval struct each time
select() is called, and it appears to work well. The patch is included
below. I also sent a copy to "libpcap@xxxxxxxxxx".
*** pcap-int.h.orig Wed Nov 27 20:43:11 1996
--- pcap-int.h Sun Jan 3 17:36:51 1999
***************
*** 71,76 ****
--- 71,77 ----
int linktype;
int tzoff; /* timezone offset */
int offset; /* offset for proper alignment */
+ struct timeval timeout; /* packet timeout when reading live traffic */
struct pcap_sf sf;
struct pcap_md md;
*** pcap-linux.c.orig Fri Oct 3 00:39:53 1997
--- pcap-linux.c Sun Jan 3 19:22:36 1999
***************
*** 27,32 ****
--- 27,33 ----
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
+ #include <fcntl.h>
#include <net/if.h>
#ifdef HAVE_NET_IF_ARP_H
***************
*** 72,77 ****
--- 73,79 ----
register int caplen;
register u_char *bp;
struct sockaddr from;
+ struct timeval timeout;
int fromlen;
bp = p->buffer + p->offset;
***************
*** 84,89 ****
--- 86,114 ----
again:
do {
+ if (timerisset(&p->timeout)) {
+ /*
+ * Delay no more than the specified amount of
+ * time waiting for a packet to arrive, by
+ * using "select()" with that as a timeout
+ * to wait for the packet. Return 0 if no
+ * packet arrives.
+ */
+ fd_set set1;
+
+ FD_ZERO(&set1);
+ FD_SET(p->fd, &set1);
+
+ /*
+ * Linux modifies the timeout value, so we need to re-initialize
+ * it each time.
+ */
+ timeout.tv_sec = p->timeout.tv_sec;
+ timeout.tv_usec = p->timeout.tv_usec;
+ if (select(p->fd+1, &set1, NULL, NULL, &timeout) == 0)
+ return (0);
+ }
+
fromlen = sizeof(from);
cc = recvfrom(p->fd, bp, bufsize, 0, &from, &fromlen);
if (cc < 0) {
***************
*** 272,277 ****
--- 297,305 ----
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
goto bad;
}
+
+ p->timeout.tv_sec = to_ms / 1000;
+ p->timeout.tv_usec = (to_ms * 1000) % 1000000;
/* XXX */
if (promisc && broadcast) {