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>