From Ian Schorr: capinfo - provides capture file information.

svn path=/trunk/; revision=11555
This commit is contained in:
Olivier Biot 2004-07-28 20:51:29 +00:00
parent 1f7a025246
commit cb6b29786b
6 changed files with 611 additions and 10 deletions

View File

@ -60,13 +60,14 @@ ACLOCAL_AMFLAGS = `./aclocal-flags`
# automake will arrange that the Makefile define it as the union of all
# the "man{section}_MANS" variables.
#
bin_PROGRAMS = @ethereal_bin@ @editcap_bin@ @mergecap_bin@ @tethereal_bin@ @dftest_bin@ @randpkt_bin@ @text2pcap_bin@
bin_PROGRAMS = @ethereal_bin@ @capinfo_bin@ @editcap_bin@ @mergecap_bin@ @tethereal_bin@ @dftest_bin@ @randpkt_bin@ @text2pcap_bin@
bin_SCRIPTS = @idl2eth_bin@
man1_MANS = @ethereal_man@ @editcap_man@ @mergecap_man@ @tethereal_man@ @text2pcap_man@ @idl2eth_man@
man1_MANS = @ethereal_man@ @capinfo_man@ @editcap_man@ @mergecap_man@ @tethereal_man@ @text2pcap_man@ @idl2eth_man@
man4_MANS = @etherealfilter_man@
man_MANS =
EXTRA_PROGRAMS = ethereal tethereal editcap mergecap dftest randpkt text2pcap
EXTRA_PROGRAMS = ethereal tethereal capinfo editcap mergecap dftest \
randpkt text2pcap
EXTRA_SCRIPTS = idl2eth
#
@ -74,8 +75,8 @@ EXTRA_SCRIPTS = idl2eth
# contains the "AUTHORS-SHORT" and "manuf" files and a "diameter" directory.
#
pkgdata_DATA = AUTHORS-SHORT manuf ethereal.html tethereal.html \
ethereal-filter.html editcap.html idl2eth.html mergecap.html \
text2pcap.html
ethereal-filter.html capinfo.html editcap.html \
idl2eth.html mergecap.html text2pcap.html
#
# Install the Diameter DTD and XML files in the "diameter" subdirectory
@ -276,9 +277,11 @@ text2pcap_LDADD = $(text2pcap_optional_objects) \
mergecap_DEPENDENCIES = wiretap/libwiretap.la
# This is the automake dependency variable for the executable
capinfo_DEPENDENCIES = wiretap/libwiretap.la
editcap_DEPENDENCIES = wiretap/libwiretap.la
# This automake variable adds to the link-line for the executable
capinfo_LDADD = wiretap/libwiretap.la @GLIB_LIBS@
editcap_LDADD = wiretap/libwiretap.la @GLIB_LIBS@
mergecap_LDADD = wiretap/libwiretap.la @GLIB_LIBS@
@ -401,6 +404,7 @@ EXTRA_DIST = \
aclocal-fallback/gtk.m4 \
aclocal-flags \
autogen.sh \
capinfo.c \
capture-wpcap.c \
capture-wpcap.h \
cleanbld.bat \
@ -429,6 +433,7 @@ EXTRA_DIST = \
doc/README.tapping \
doc/README.tvbuff \
doc/README.xml-output \
doc/capinfo.pod \
doc/dfilter2pod.pl \
doc/editcap.pod \
doc/ethereal-filter.pod.template \
@ -559,6 +564,10 @@ ethereal-filter.4: tethereal doc/ethereal-filter.pod.template
(cd doc ; \
$(MAKE) ../ethereal-filter.4 )
capinfo.1: doc/capinfo.pod
(cd doc ; \
$(MAKE) ../capinfo.1 )
editcap.1: doc/editcap.pod
(cd doc ; \
$(MAKE) ../editcap.1 )
@ -587,6 +596,10 @@ ethereal-filter.html: tethereal doc/ethereal-filter.pod.template
(cd doc ; \
$(MAKE) ../ethereal-filter.html )
capinfo.html: doc/capinfo.pod
(cd doc ; \
$(MAKE) ../capinfo.html )
editcap.html: doc/editcap.pod
(cd doc ; \
$(MAKE) ../editcap.html )

View File

@ -78,6 +78,10 @@ tethereal_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \
$(ZLIB_LIBS)
!ENDIF
capinfo_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \
wsock32.lib user32.lib \
$(GLIB_LIBS)
editcap_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \
wsock32.lib user32.lib \
$(GLIB_LIBS)
@ -106,7 +110,7 @@ randpkt_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \
$(GLIB_LIBS) \
$(NET_SNMP_DIR)\win32\lib\netsnmp.lib
EXECUTABLES=ethereal.exe ethereal-gtk2.exe tethereal.exe editcap.exe mergecap.exe text2pcap.exe
EXECUTABLES=ethereal.exe ethereal-gtk2.exe tethereal.exe capinfo.exe editcap.exe mergecap.exe text2pcap.exe
RESOURCES=image\ethereal.res image\libethereal.res image\tethereal.res image\editcap.res image\mergecap.res image\text2pcap.res image\wiretap.res
@ -161,6 +165,12 @@ tethereal.exe : config.h svnversion.h $(tethereal_OBJECTS) $(EXTRA_OBJECTS) epan
/OUT:tethereal.exe $(conflags) $(conlibsdll) $(LDFLAGS) /SUBSYSTEM:console $(tethereal_LIBS) $(tethereal_OBJECTS) $(EXTRA_OBJECTS) image\tethereal.res
<<
capinfo.exe : config.h capinfo.obj getopt.obj wiretap\wiretap-$(WTAP_VERSION).lib image\editcap.res
@echo Linking $@
$(LINK) @<<
/OUT:capinfo.exe $(conflags) $(conlibsdll) $(LDFLAGS) /SUBSYSTEM:console capinfo.obj getopt.obj $(capinfo_LIBS) image\editcap.res
<<
editcap.exe : config.h editcap.obj getopt.obj wiretap\wiretap-$(WTAP_VERSION).lib image\editcap.res
@echo Linking $@
$(LINK) @<<
@ -247,7 +257,7 @@ gtk2_distclean:
clean: gtk2_distclean
rm -f $(ethereal_OBJECTS) $(tethereal_OBJECTS) $(EXTRA_OBJECTS) \
$(EXECUTABLES) $(PDB_FILE) \
editcap.obj mergecap.obj text2pcap.obj getopt.obj\
capinfo.obj editcap.obj mergecap.obj text2pcap.obj getopt.obj\
text2pcap-scanner.obj text2pcap-scanner.c rdps.obj \
rdps.pdb rdps.exe rdps.ilk config.h ps.c AUTHORS-SHORT \
dftest.obj dftest.exe randpkt.obj randpkt.ext doxygen.cfg \

341
capinfo.c Executable file
View File

@ -0,0 +1,341 @@
/* capinfo.c
* Reports capture file information including # of packets, duration, others
*
* Copyright 2004 Ian Schorr
*
* $Id: $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <string.h>
#include <epan/packet.h>
#include "wtap.h"
#ifdef NEED_GETOPT_H
#include "getopt.h"
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
static gboolean cap_file_type = FALSE; /* Do not report capture type */
static gboolean cap_packet_count = FALSE; /* Do not produce packet count */
static gboolean cap_file_size = FALSE; /* Do not report file size */
static gboolean cap_data_size = FALSE; /* Do not report packet byte size */
static gboolean cap_duration = FALSE; /* Do not report capture duration */
static gboolean cap_start_time = FALSE;
static gboolean cap_end_time = FALSE;
static gboolean cap_data_rate_byte = FALSE;
static gboolean cap_data_rate_bit = FALSE;
static gboolean cap_packet_size = FALSE;
typedef struct _capture_info {
const char *filename;
guint16 file_type;
guint64 filesize;
guint64 packet_bytes;
double start_time;
double stop_time;
guint32 packet_count;
gboolean snap_set;
guint32 snaplen;
gboolean drops_known;
guint32 drop_count;
double duration;
double packet_rate;
double packet_size;
double data_rate; /* in bytes */
} capture_info;
static double
secs_usecs(guint32 s, guint32 us)
{
return (us / 1000000.0) + (double)s;
}
static void
print_stats(capture_info *cf_info)
{
gchar *file_type_string;
time_t start_time_t;
struct tm *start_time_tm;
time_t stop_time_t;
struct tm *stop_time_tm;
/* Build printable strings for various stats */
file_type_string = wtap_file_type_string(cf_info->file_type);
start_time_t = (long)cf_info->start_time;
stop_time_t = (long)cf_info->stop_time;
start_time_tm = localtime (&start_time_t);
stop_time_tm = localtime (&stop_time_t);
if (cap_file_type) printf("File Type: %s\n", file_type_string);
if (cap_packet_count) printf("Number of packets: %u \n", cf_info->packet_count);
if (cap_file_size) printf("File Size: %" PRIu64 " bytes\n", cf_info->filesize);
if (cap_data_size) printf("Data Size: %" PRIu64 " bytes\n", cf_info->packet_bytes);
if (cap_duration) printf("Capture duration: %f seconds\n", cf_info->duration);
if (cap_start_time) printf("Start time: %s", asctime (start_time_tm));
if (cap_end_time) printf("End time: %s", asctime (stop_time_tm));
if (cap_data_rate_byte) printf("Data rate: %.2f bytes/s\n", cf_info->data_rate);
if (cap_data_rate_bit) printf("Data rate: %.2f bits/s\n", cf_info->data_rate*8);
if (cap_packet_size) printf("Average packet size: %.2f bytes\n", cf_info->packet_size);
}
static int
process_cap_file(wtap *wth)
{
int err;
gchar *err_info;
struct stat cf_stat;
long data_offset;
guint32 packet = 0;
gint64 bytes = 0;
const struct wtap_pkthdr *phdr;
capture_info cf_info;
double start_time = 0;
double stop_time = 0;
double cur_time = 0;
/* Tally up data that we need to parse through the file to find */
while (wtap_read(wth, &err, &err_info, &data_offset)) {
phdr = wtap_phdr(wth);
cur_time = secs_usecs(phdr->ts.tv_sec, phdr->ts.tv_usec);
if(packet==0) {
start_time = cur_time;
stop_time = cur_time;
}
if (cur_time < start_time) {
start_time = cur_time;
}
if (cur_time > stop_time) {
stop_time = cur_time;
}
bytes+=phdr->len;
packet++;
}
if (err != 0) {
fprintf(stderr, "Error after reading %i packets\n", packet);
exit(1);
}
/* File size */
if (fstat(wtap_fd(wth), &cf_stat) < 0) {
wtap_close(wth);
return 1;
}
cf_info.filesize = cf_stat.st_size;
/* File Type */
cf_info.file_type = wtap_file_type(wth);
/* # of packets */
cf_info.packet_count = packet;
/* File Times */
cf_info.start_time = start_time;
cf_info.stop_time = stop_time;
cf_info.duration = stop_time-start_time;
/* Number of packet bytes */
cf_info.packet_bytes = bytes;
/* Data rate per second */
cf_info.data_rate = (double)bytes / (stop_time-start_time);
/* Avg packet size */
cf_info.packet_size = (double)bytes/packet;
print_stats(&cf_info);
return 0;
}
static void usage(gboolean is_error)
{
FILE *output;
if (!is_error) {
output = stdout;
/* XXX - add capinfo header info here */
}
else {
output = stderr;
}
fprintf(output, "Usage: capinfo [-t] [-c] [-s] [-d] [-u] [-a] [-e] [-y]\n");
fprintf(output, " [-i] [-z] [-h] <capfile>\n");
fprintf(output, " where\t-t display the capture type of <capfile>\n");
fprintf(output, " \t-c count the number of packets\n");
fprintf(output, " \t-s display the size of the file \n");
fprintf(output, " \t-d display the total length of all packets in the file\n");
fprintf(output, " \t (in bytes)\n");
fprintf(output, " \t-u display the capture duration (in seconds) \n");
fprintf(output, " \t-a display the capture start time\n");
fprintf(output, " \t-e display the capture end time\n");
fprintf(output, " \t-y display average data rate (in bytes)\n");
fprintf(output, " \t-i display average data rate (in bits)\n");
fprintf(output, " \t-z display average packet size (in bytes)\n");
fprintf(output, " \t-h produces this help listing.\n");
fprintf(output, "\n \t If no data flags are given, default is to display all statistics\n");
}
int main(int argc, char *argv[])
{
wtap *wth;
int err;
gchar *err_info;
extern char *optarg;
extern int optind;
int opt;
int status = 0;
/* Process the options first */
while ((opt = getopt(argc, argv, "tcsduaeyizvh")) !=-1) {
switch (opt) {
case 't':
cap_file_type = TRUE;
break;
case 'c':
cap_packet_count = TRUE;
break;
case 's':
cap_file_size = TRUE;
break;
case 'd':
cap_data_size = TRUE;
break;
case 'u':
cap_duration = TRUE;
break;
case 'a':
cap_start_time = TRUE;
break;
case 'e':
cap_end_time = TRUE;
break;
case 'y':
cap_data_rate_byte = TRUE;
break;
case 'i':
cap_data_rate_bit = TRUE;
break;
case 'z':
cap_packet_size = TRUE;
break;
case 'h':
usage(FALSE);
exit(1);
break;
case '?': /* Bad flag - print usage message */
usage(TRUE);
exit(1);
break;
}
}
if (optind < 2) {
/* If no arguments were given, by default display all statistics */
cap_file_type = TRUE;
cap_packet_count = TRUE;
cap_file_size = TRUE;
cap_data_size = TRUE;
cap_duration = TRUE;
cap_start_time = TRUE;
cap_end_time = TRUE;
cap_data_rate_byte = TRUE;
cap_data_rate_bit = TRUE;
cap_packet_size = TRUE;
}
if ((argc - optind) < 1) {
usage(TRUE);
exit(1);
}
wth = wtap_open_offline(argv[optind], &err, &err_info, FALSE);
if (!wth) {
fprintf(stderr, "editcap: Can't open %s: %s\n", argv[optind],
wtap_strerror(err));
switch (err) {
case WTAP_ERR_UNSUPPORTED:
case WTAP_ERR_UNSUPPORTED_ENCAP:
case WTAP_ERR_BAD_RECORD:
fprintf(stderr, "(%s)\n", err_info);
g_free(err_info);
break;
}
exit(1);
}
status = process_cap_file(wth);
wtap_close(wth);
return status;
}

View File

@ -510,6 +510,22 @@ AC_SUBST(editcap_bin)
AC_SUBST(editcap_man)
# Enable/disable capinfo
AC_ARG_ENABLE(capinfo,
[ --enable-capinfo build capinfo. [default=yes]],enable_capinfo=$enableval,enable_capinfo=yes)
if test "x$enable_capinfo" = "xyes" ; then
capinfo_bin="capinfo\$(EXEEXT)"
capinfo_man="capinfo.1"
else
capinfo_bin=""
capinfo_man=""
fi
AC_SUBST(capinfo_bin)
AC_SUBST(capinfo_man)
# Enable/disable mergecap
AC_ARG_ENABLE(mergecap,
@ -1227,6 +1243,7 @@ echo ""
echo "The Ethereal package has been configured with the following options."
echo " Build ethereal : $enable_ethereal"
echo " Build tethereal : $enable_tethereal"
echo " Build capinfo : $enable_capinfo"
echo " Build editcap : $enable_editcap"
echo " Build mergecap : $enable_mergecap"
echo " Build text2pcap : $enable_text2pcap"

View File

@ -26,10 +26,10 @@
include ../config.nmake
doc: ethereal.html tethereal.html ethereal-filter.html editcap.html \
idl2eth.html mergecap.html text2pcap.html
doc: ethereal.html tethereal.html ethereal-filter.html capinfo.html \
editcap.html idl2eth.html mergecap.html text2pcap.html
man: ethereal.1 tethereal.1 ethereal-filter.4 editcap.1 \
man: ethereal.1 tethereal.1 ethereal-filter.4 capinfo.1 editcap.1 \
idl2eth.1 mergecap.1 text2pcap.1
ethereal-tmp.pod: ethereal.pod ../AUTHORS-SHORT
@ -86,6 +86,19 @@ ethereal-filter.pod: ethereal-filter.pod.template ../tethereal.exe
rm -f libethereal.dll wiretap-$(WTAP_VERSION).dll
cd doc
capinfo.1: capinfo.pod ../config.h
$(POD2MAN) \
--center="The Ethereal Network Analyzer" \
--release=$(VERSION) \
capinfo.pod > capinfo.1
capinfo.html: capinfo.pod ../config.h
$(POD2HTML) \
--title="capinfo - The Ethereal Network Analyzer $(VERSION)" \
--noindex \
capinfo.pod > capinfo.html
editcap.1: editcap.pod ../config.h
$(POD2MAN) \
--center="The Ethereal Network Analyzer" \
@ -138,6 +151,7 @@ clean:
rm -f ethereal.html ethereal.1 ethereal-tmp.pod
rm -f tethereal.html tethereal.1
rm -f ethereal-filter.html ethereal-filter.4 ethereal-filter.pod
rm -f capinfo.html capinfo.1
rm -f editcap.html editcap.1
rm -f idl2eth.html idl2eth.1
rm -f mergecap.html mergecap.1

206
doc/capinfo.pod Executable file
View File

@ -0,0 +1,206 @@
=head1 NAME
capinfo - Prints information about binary capture files
=head1 SYNOPSYS
B<capinfo>
S<[ B<-t> ]>
S<[ B<-c> ]>
S<[ B<-s> ]>
S<[ B<-d> ]>
S<[ B<-u> ]>
S<[ B<-a> ]>
S<[ B<-e> ]>
S<[ B<-y> ]>
S<[ B<-i> ]>
S<[ B<-z> ]>
S<[ B<-h> ]>
I<capfile>
=head1 DESCRIPTION
B<Capinfo> is a program that reads a saved capture file and returns any
or all of several statistics about that file. B<Capinfo> is able to detect
and read any capture supported by the B<Ethereal> package.
B<Capinfo> can read the following file formats:
=over 4
=item *
libpcap/WinPcap, tcpdump and various other tools using tcpdump's capture format
=item *
B<snoop> and B<atmsnoop>
=item *
Shomiti/Finisar B<Surveyor> captures
=item *
Novell B<LANalyzer> captures
=item *
Microsoft B<Network Monitor> captures
=item *
AIX's B<iptrace> captures
=item *
Cinco Networks B<NetXRay> captures
=item *
Network Associates Windows-based B<Sniffer> captures
=item *
Network General/Network Associates DOS-based B<Sniffer> (compressed or uncompressed) captures
=item *
AG Group/WildPackets B<EtherPeek>/B<TokenPeek>/B<AiroPeek>/B<EtherHelp>/B<PacketGrabber> captures
=item *
B<RADCOM>'s WAN/LAN analyzer captures
=item *
Network Instruments B<Observer> version 9 captures
=item *
B<Lucent/Ascend> router debug output
=item *
files from HP-UX's B<nettl>
=item *
B<Toshiba's> ISDN routers dump output
=item *
the output from B<i4btrace> from the ISDN4BSD project
=item *
traces from the B<EyeSDN> USB S0.
=item *
the output in B<IPLog> format from the Cisco Secure Intrusion Detection System
=item *
B<pppd logs> (pppdump format)
=item *
the output from VMS's B<TCPIPtrace>/B<TCPtrace>/B<UCX$TRACE> utilities
=item *
the text output from the B<DBS Etherwatch> VMS utility
=item *
Visual Networks' B<Visual UpTime> traffic capture
=item *
the output from B<CoSine> L2 debug
=item *
the output from Accellent's B<5Views> LAN agents
=item *
Endace Measurement Systems' ERF format captures
=item *
Linux Bluez Bluetooth stack B<hcidump -w> traces
=back
There is no need to tell B<Capinfo> what type of
file you are reading; it will determine the file type by itself.
B<Capinfo> is also capable of reading any of these file formats if they
are compressed using gzip. B<Capinfo> recognizes this directly from the
file; the '.gz' extension is not required for this purpose.
The user specifies which statistics to report by specifying flags
corresponding to the statistic. If no flags are specified, B<Capinfo> will
report all statistics available.
=head1 OPTIONS
=over 4
=item -t
Displays the capture type of the capture file.
=item -c
Counts the number of packets in the capture file.
=item -s
Displays the size of the file, in bytes. This reports
the size of the capture file itself.
=item -d
Displays the total length of all packets in the file, in
bytes. This counts the size of the packets as they appeared
in their original form, not as they appear in this file.
For example, if a packet was originally 1514 bytes and only
256 of those bytes were saved to the capture file (if packets
were captured with a snaplen or other slicing option),
B<Capinfo> will consider the packet to have been 1514 bytes.
=item -u
Displays the capture duration, in seconds. This is the
difference in time between the earliest packet seen and
latest packet seen.
=item -a
Displays the start time of the capture. B<Capinfo> considers
the earliest timestamp seen to be the start time, so the
first packet in the capture is not necessarily the earliest -
if packets exist "out-of-order", time-wise, in the capture,
B<Capinfo> detects this.
=item -e
Displays the end time of the capture. B<Capinfo> considers
the latest timestamp seen to be the end time, so the
last packet in the capture is not necessarily the latest -
if packets exist "out-of-order", time-wise, in the capture,
B<Capinfo> detects this.
=item -y
Displays the average data rate, in bytes
=item -i
Displays the average data rate, in bits
=item -z
displays the average packet size, in bytes
=item -h
Prints the help listing and exits.
=back
=head1 SEE ALSO
I<tcpdump(8)>, I<pcap(3)>, I<ethereal(1)>, I<mergecap(1)>, I<editcap(1)>, I<tethereal(1)>
=head1 NOTES
B<Capinfo> is part of the B<Ethereal> distribution. The latest version
of B<Ethereal> can be found at B<http://www.ethereal.com>.
=head1 AUTHORS
Original Author
-------- ------
Ian Schorr <ian[AT]ianschorr.com>
Contributors
------------