/*
* Copyright (c) 2000 Paul Herman
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: tcpprof.c,v 1.7 2002/01/19 04:31:37 pherman Exp $
*/
#include "tcpprof.h"
char numbers_only = 0;
char filterexpr[BUF_SIZ] = "";
char registered_only = 0;
char src_dest_split = 0;
int ports_to_show = IPPORT_RESERVED;
int lines_to_show = -1;
#define USAGE \
"Usage: %s [-?hnpR] [-f filter expr] [-i interface] [-P port] \
\n [-r file] [-s seconds] [-S letters] [-t lines] \
\n -?, -h - display this help \
\n -d - show source/dest statistics \
\n -f filter expr - tcpdump(1) filter expression \
\n -i interface - do live capture on [interface], not from file \
\n -n - don't resolve network numbers \
\n -p - non-promiscuous mode when doing live capture \
\n -P port - ignore port numbers >= port \
\n -r file - read tcpdump data from file \
\n -R - display only registered ports \
\n -s seconds - capture only [seconds] long \
\n -S letters - collect stats \
\n a - collect ALL stats \
\n l - collect link stats \
\n i - collect ip stats \
\n p - collect port stats \
\n h - collect host stats \
\n n - collect network stats \
\n -t lines - show at most [lines] lines for each stat \
\n \
\nExample: %s -S ph -r data.dump \
\n Displays port and host statistics from the file 'data.dump' \
\n"
void my_hook(packet_data *pd, void **args) {
u_int *types;
types = (u_int *) *args++;
stats_insert(pd, *types);
}
/*
* process_file() takes the output of tcpdump, saves packets, and creates
* statistics
*/
void process_file(char *fname, u_int s_types, int flags, Double capture_seconds) {
void *argv[1];
stats_initdb(s_types);
argv[0] = (void *) &s_types;
if (get_dump_data(fname, filterexpr, flags, capture_seconds, my_hook, argv) == 0)
show_results(s_types);
stats_closedb();
}
u_int parse_stats_types(char *in) {
u_int ret = 0;
while (*in) {
if (*in == 'l' || *in == 'a' ) ret |= TYPE_LINK;
if (*in == 'i' || *in == 'a' ) ret |= TYPE_IP_PROTO;
if (*in == 'p' || *in == 'a' ) ret |= TYPE_PORT;
if (*in == 'h' || *in == 'a' ) ret |= TYPE_HOST;
if (*in == 'n' || *in == 'a' ) ret |= TYPE_NET;
in++;
}
return ret;
}
int Usage(int r, char *prog) {
fprintf(stderr, USAGE, my_basename(prog), prog);
return r;
}
void error(char *s) {
fprintf(stderr, "error: %s\n", s);
Usage(-1, "tcpprof"); exit(-1);
}
int main(int argc, char **argv) {
char filename[BUF_SIZ];
u_int stats_types = TYPE_ALL;
int flags = GET_TCPD_COUNT_LINKSIZE | GET_TCPD_DO_LIVE_PROMISC;
int ch;
Double capture_seconds = -1.0;
filename[0] = 0;
while ( (ch = getopt(argc, argv, "h?ndpP:Rf:i:s:S:r:t:")) != -1) {
switch(ch) {
case 'h':
case '?':
return Usage(1, argv[0]);
break;
case 'd':
src_dest_split = 1;
break;
case 'f':
strncpy(filterexpr, optarg, BUF_SIZ);
break;
case 'i':
strncpy(filename, optarg, BUF_SIZ);
flags |= GET_TCPD_DO_LIVE;
break;
case 'r':
strncpy(filename, optarg, BUF_SIZ);
flags &= ~GET_TCPD_DO_LIVE;
break;
case 'n':
numbers_only = 1;
break;
case 'p':
flags &= ~GET_TCPD_DO_LIVE_PROMISC;
break;
case 'P':
ports_to_show = (int) strtol(optarg, NULL, 10);
registered_only = 1;
break;
case 'R':
registered_only = 1;
break;
case 's':
capture_seconds = atof(optarg);
if (capture_seconds <= 0.0 &&
capture_seconds != -1.0)
return Usage(1, argv[0]);
break;
case 'S':
stats_types |= parse_stats_types(optarg);
break;
case 't':
lines_to_show = (int) strtol(optarg, NULL, 10);
break;
default:
break;
}
}
if (filename == NULL || strlen(filename) < 1) {
strncpy(filename, "auto", BUF_SIZ);
flags |= GET_TCPD_DO_LIVE;
}
process_file(filename, stats_types, flags, capture_seconds);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1