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>
