Ethereal-users: Re: [ethereal-users] installation problems..

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: guy@xxxxxxxxxx (Guy Harris)
Date: Tue, 4 May 1999 15:54:18 -0700 (PDT)
> 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) {