Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Nov 2000 18:48:31 -0800 (PST)
From:      dc@packetdesign.com
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/22730: tcpslice chokes on big files
Message-ID:  <200011100248.eAA2mVL93248@dhcp-168-0-25.packetdesign.com>

next in thread | raw e-mail | index | archive | help

>Number:         22730
>Category:       bin
>Synopsis:       tcpslice doesn't handle long file offsets
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 09 18:50:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Dave Cornelius
>Release:        FreeBSD 4.1-20000929-STABLE i386
>Organization:
PacketDesign.com
>Environment:

	FreeBSD 4.1-20000929-STABLE i386

>Description:

	tcpslice uses 'old'-style file offsets and routines
	for positioning the input file stream.  This has problems
	when the file being read gets 'large' (circa 2^31).

>How-To-Repeat:

	Generate a huge tcpdump file (sniff on a busy interface
	for a long time), then, try to use that file in tcpslice,
	with a starting date which is above 2GBytes in that file:

	tcpslice 973681608.015983 huge_file.td > foo

	Error reported is:

	tcpslice: fseek() failed in read_up_to()


>Fix:
	Patch follows; apply in src/usr.sbin/tcpdump/tcpslice.
	Gratuitous addition of braces in gwtm2secs.c to avoid gcc paranoia.

Index: gwtm2secs.c
===================================================================
RCS file: /home/cvs/freebsd/src/usr.sbin/tcpdump/tcpslice/gwtm2secs.c,v
retrieving revision 1.4
diff -u -r1.4 gwtm2secs.c
--- gwtm2secs.c	1999/08/28 05:11:32	1.4
+++ gwtm2secs.c	2000/11/10 01:28:34
@@ -47,10 +47,12 @@
 	 * distinguishes them, since we can't represent any time < 1970.
 	 */
 	if ( year < 100 )
+		{
 		if ( year >= 70 )
 			year += 1900;
 		else
 			year += 2000;
+		}
 
 	days = 0;
 	for ( i = 1970; i < year; ++i )
Index: search.c
===================================================================
RCS file: /home/cvs/freebsd/src/usr.sbin/tcpdump/tcpslice/search.c,v
retrieving revision 1.4
diff -u -r1.4 search.c
--- search.c	1999/08/28 05:11:32	1.4
+++ search.c	2000/11/10 01:28:34
@@ -378,26 +378,25 @@
 	        t1->tv_usec < t2->tv_usec);
 	}
 
-
 /* Given two timestamps on either side of desired_time and their positions,
  * returns the interpolated position of the desired_time packet.  Returns a
  * negative value if the desired_time is outside the given range.
  */
 
-static long
-interpolated_position( struct timeval *min_time, long min_pos,
-			struct timeval *max_time, long max_pos,
+static off_t
+interpolated_position( struct timeval *min_time, off_t min_pos,
+			struct timeval *max_time, off_t max_pos,
 			struct timeval *desired_time )
 	{
 	double full_span = timeval_diff( max_time, min_time );
 	double desired_span = timeval_diff( desired_time, min_time );
-	long full_span_pos = max_pos - min_pos;
+	off_t full_span_pos = max_pos - min_pos;
 	double fractional_offset = desired_span / full_span;
 
 	if ( fractional_offset < 0.0 || fractional_offset > 1.0 )
 		return -1;
 
-	return min_pos + (long) (fractional_offset * (double) full_span_pos);
+	return min_pos + (off_t) (fractional_offset * (double) full_span_pos);
 	}
 
 
@@ -412,14 +411,14 @@
 	{
 	struct pcap_pkthdr hdr;
 	const u_char *buf;
-	long pos;
+	off_t pos;
 	int status;
 
 	for ( ; ; )
 		{
 		struct timeval *timestamp;
 
-		pos = ftell( pcap_file( p ) );
+		pos = ftello( pcap_file( p ) );
 		buf = pcap_next( p, &hdr );
 
 		if ( buf == 0 )
@@ -443,13 +442,12 @@
 			}
 		}
 
-	if ( fseek( pcap_file( p ), pos, 0 ) < 0 )
-		error( "fseek() failed in read_up_to()" );
+	if ( fseeko( pcap_file( p ), pos, 0 ) < 0 )
+		error( "fseeko() failed in read_up_to()" );
 
 	return (status);
 	}
 
-
 /* Positions the sf_readfile stream so that the next sf_read() will
  * return the first packet with a time greater than or equal to
  * desired_time.  desired_time must be greater than min_time and less
@@ -466,15 +464,15 @@
 
 int
 sf_find_packet( pcap_t *p,
-		struct timeval *min_time, long min_pos,
-		struct timeval *max_time, long max_pos,
+		struct timeval *min_time, off_t min_pos,
+		struct timeval *max_time, off_t max_pos,
 		struct timeval *desired_time )
 	{
 	int status = 1;
 	struct timeval min_time_copy, max_time_copy;
 	u_int num_bytes = MAX_BYTES_FOR_DEFINITE_HEADER;
 	int num_bytes_read;
-	long desired_pos, present_pos;
+	off_t desired_pos, present_pos;
 	u_char *buf, *hdrpos;
 	struct pcap_pkthdr hdr;
 
@@ -501,7 +499,7 @@
 			break;
 			}
 
-		present_pos = ftell( pcap_file( p ) );
+		present_pos = ftello( pcap_file( p ) );
 
 		if ( present_pos <= desired_pos &&
 		     desired_pos - present_pos < STRAIGHT_SCAN_THRESHOLD )
@@ -517,8 +515,8 @@
 		if ( desired_pos < min_pos )
 			desired_pos = min_pos;
 
-		if ( fseek( pcap_file( p ), desired_pos, 0 ) < 0 )
-			error( "fseek() failed in sf_find_packet()" );
+		if ( fseeko( pcap_file( p ), desired_pos, 0 ) < 0 )
+			error( "fseeko() failed in sf_find_packet()" );
 
 		num_bytes_read =
 			fread( (char *) buf, 1, num_bytes, pcap_file( p ) );
@@ -540,8 +538,8 @@
 		desired_pos += (hdrpos - buf);
 
 		/* Seek to the beginning of the header. */
-		if ( fseek( pcap_file( p ), desired_pos, 0 ) < 0 )
-			error( "fseek() failed in sf_find_packet()" );
+		if ( fseeko( pcap_file( p ), desired_pos, 0 ) < 0 )
+			error( "fseeko() failed in sf_find_packet()" );
 
 		if ( sf_timestamp_less_than( &hdr.ts, desired_time ) )
 			{ /* too early in the file */
Index: tcpslice.c
===================================================================
RCS file: /home/cvs/freebsd/src/usr.sbin/tcpdump/tcpslice/tcpslice.c,v
retrieving revision 1.10
diff -u -r1.10 tcpslice.c
--- tcpslice.c	2000/05/28 15:06:45	1.10
+++ tcpslice.c	2000/11/10 01:28:34
@@ -451,7 +451,7 @@
 extract_slice(char filename[], char write_file_name[],
 		struct timeval *start_time, struct timeval *stop_time)
 {
-	long start_pos, stop_pos;
+	off_t start_pos, stop_pos;
 	struct timeval file_start_time, file_stop_time;
 	struct pcap_pkthdr hdr;
 	pcap_t *p;
@@ -462,7 +462,7 @@
 		error( "bad tcpdump file %s: %s", filename, errbuf );
 
 	snaplen = pcap_snapshot( p );
-	start_pos = ftell( pcap_file( p ) );
+	start_pos = ftello( pcap_file( p ) );
 
 	if ( ! dumper )
 		{
@@ -483,7 +483,7 @@
 		error( "problems finding end packet of file %s",
 			filename );
 
-	stop_pos = ftell( pcap_file( p ) );
+	stop_pos = ftello( pcap_file( p ) );
 
 
 	/* sf_find_packet() requires that the time it's passed as its last
Index: tcpslice.h
===================================================================
RCS file: /home/cvs/freebsd/src/usr.sbin/tcpdump/tcpslice/tcpslice.h,v
retrieving revision 1.1
diff -u -r1.1 tcpslice.h
--- tcpslice.h	1995/03/08 12:53:41	1.1
+++ tcpslice.h	2000/11/10 01:28:34
@@ -52,8 +52,8 @@
 			struct timeval *last_timestamp );
 int	sf_timestamp_less_than( struct timeval *t1, struct timeval *t2 );
 int	sf_find_packet( struct pcap *p,
-		struct timeval *min_time, long min_pos,
-		struct timeval *max_time, long max_pos,
+		struct timeval *min_time, off_t min_pos,
+		struct timeval *max_time, off_t max_pos,
 		struct timeval *desired_time );
 
 void	error(const char *fmt, ...);

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011100248.eAA2mVL93248>