/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
* 2002, 2003, 2004
* Ohio University.
*
* ---
*
* Starting with the release of tcptrace version 6 in 2001, tcptrace
* is licensed under the GNU General Public License (GPL). We believe
* that, among the available licenses, the GPL will do the best job of
* allowing tcptrace to continue to be a valuable, freely-available
* and well-maintained tool for the networking community.
*
* Previous versions of tcptrace were released under a license that
* was much less restrictive with respect to how tcptrace could be
* used in commercial products. Because of this, I am willing to
* consider alternate license arrangements as allowed in Section 10 of
* the GNU GPL. Before I would consider licensing tcptrace under an
* alternate agreement with a particular individual or company,
* however, I would have to be convinced that such an alternative
* would be to the greater benefit of the networking community.
*
* ---
*
* This file is part of Tcptrace.
*
* Tcptrace was originally written and continues to be maintained by
* Shawn Ostermann with the help of a group of devoted students and
* users (see the file 'THANKS'). The work on tcptrace has been made
* possible over the years through the generous support of NASA GRC,
* the National Science Foundation, and Sun Microsystems.
*
* Tcptrace 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.
*
* Tcptrace 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 Tcptrace (in the file 'COPYING'); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Author: Shawn Ostermann
* School of Electrical Engineering and Computer Science
* Ohio University
* Athens, OH
* ostermann@cs.ohiou.edu
* http://www.tcptrace.org/
*/
#include "tcptrace.h"
static char const GCC_UNUSED rcsid[] =
"$Header: /usr/local/cvs/tcptrace/mod_collie.c,v 5.7 2003/11/19 14:38:02 sdo Exp $";
#ifdef LOAD_MODULE_COLLIE
#include "mod_collie.h"
/* this module was written as a favor for a friend, but serves as a */
/* useful little example of a quick hack... :-) */
/* additional info kept per connection */
struct conn_info {
tcp_pair *ptp;
struct conn_info *next;
};
static struct conn_info *connhead = NULL;
/* additional info kept per UDP pair */
struct uconn_info {
udp_pair *pup;
struct uconn_info *next;
};
static struct uconn_info *uconnhead = NULL;
/* locally-global info */
static char *collie_filename = NULL;
static Bool print_labels = TRUE;
/* local routines */
static struct conn_info *MakeConnRec(void);
static struct uconn_info *MakeUDPConnRec(void);
static char *collie_name(ipaddr ipaddress);
static char *collie_dots(ipaddr ipaddress);
static char *collie_time(struct timeval *ptime);
static char *collie_date(time_t timestamp);
static void ParseArgs(char *argstring);
/* Set it up */
int
collie_init(
int argc,
char *argv[])
{
int i;
int enable=0;
char *args = NULL;
for (i=1; i < argc; ++i) {
if (!argv[i])
continue; /* argument already taken by another module... */
if (strncmp(argv[i],"-x",2) == 0) {
if (strncasecmp(argv[i]+2,"collie",sizeof("collie")-1) == 0) {
/* I want to be called */
args = argv[i]+(sizeof("-xcollie")-1);
enable = 1;
argv[i] = NULL;
}
}
}
if (!enable)
return(0); /* don't call me again */
/* parse any arguments for ME */
ParseArgs(args);
/* we don't want the normal output */
printsuppress = TRUE;
/* please also include UDP packets */
do_udp = TRUE;
return(1); /* TRUE means call collie_read and collie_done later */
}
static struct conn_info *
MakeConnRec(void)
{
struct conn_info *pci;
pci = MallocZ(sizeof(struct conn_info));
/* chain it in (at head of list) */
pci->next = connhead;
connhead = pci;
return(pci);
}
static struct uconn_info *
MakeUDPConnRec(void)
{
struct uconn_info *puci;
puci = MallocZ(sizeof(struct uconn_info));
/* chain it in (at head of list) */
puci->next = uconnhead;
uconnhead = puci;
return(puci);
}
#define LABEL(str)(print_labels?str:"")
#define DESCR(ptr)\
printf("\n"); \
printf("%s%s \n",\
LABEL("Session Start: "),\
collie_time(&(ptr)->first_time));\
printf("%s%s\n",\
LABEL("Session End: "),\
collie_time(&(ptr)->last_time));\
printf("%s%s\n",\
LABEL("Source IP address: "),\
collie_dots((ptr)->addr_pair.a_address));\
printf("%s%u\n",\
LABEL("Source Port: "),\
(unsigned)(ptr)->addr_pair.a_port);\
printf("%s%s\n",\
LABEL("Source Fully Qualified domain name: "),\
collie_name((ptr)->addr_pair.a_address));\
printf("%s%s\n",\
LABEL("Destination IP address: "),\
collie_dots((ptr)->addr_pair.b_address));\
printf("%s%u\n",\
LABEL("Destination Port: "),\
(unsigned)(ptr)->addr_pair.b_port);\
printf("%s%s\n",\
LABEL("Destination Fully Qualified domain name: "),\
collie_name((ptr)->addr_pair.b_address));\
printf("%s%" FS_ULL "\n",\
LABEL("Bytes Transferred Source to Destination: "),\
(ptr)->a2b.data_bytes);\
printf("%s%" FS_ULL "\n",\
LABEL("Bytes Transferred Destination to Source: "),\
(ptr)->b2a.data_bytes);\
printf("%s%" FS_ULL "\n",\
LABEL("Packets Transferred Source to Destination: "),\
(ptr)->a2b.packets);\
printf("%s%" FS_ULL "\n",\
LABEL("Packets Transferred Destination to Source: "),\
(ptr)->b2a.packets);
void
collie_done(void)
{
struct conn_info *pci;
struct uconn_info *upci;
struct stat statbuf;
/* check the input file timestamp */
if (stat(collie_filename,&statbuf) != 0) {
perror(collie_filename);
exit(-1);
}
/* print meta information */
printf("\n");
printf("%s%s\n",
LABEL("Source file: "),
collie_filename);
printf("%s%s\n",
LABEL("File modification timestamp: "),
collie_date(statbuf.st_mtime));
printf("%s%s\n",
LABEL("First packet: "),
collie_time(&first_packet));
printf("%s%s\n",
LABEL("Last packet: "),
collie_time(&last_packet));
/* print out the TCP connections */
if (print_labels)
printf("\nTCP Connections\n");
for (pci=connhead; pci; pci=pci->next) {
DESCR(pci->ptp)
}
/* print out the UDP connections */
if (print_labels)
printf("\nUDP Connections\n");
for (upci=uconnhead; upci; upci=upci->next) {
DESCR(upci->pup)
}
}
/* called for each new file */
void
collie_newfile(
char *newfile,
u_long filesize,
Bool fcompressed)
{
if (collie_filename == NULL)
collie_filename = strdup(newfile);
else {
fprintf(stderr,"\n\n\
Sorry, as the problem was defined, only a single file can be\n\
processed at a time\n");
exit(-1);
}
}
void
collie_usage(void)
{
printf("\t-xcollie\"[-ln]\tprovide connection summary\n");
printf("\t -l attach labels\n");
printf("\t -n no labels please\n");
}
void *
collie_newconn(
tcp_pair *ptp)
{
struct conn_info *pci;
pci = MakeConnRec();
pci->ptp = ptp;
return(pci);
}
void *
collie_newudpconn(
udp_pair *pup)
{
struct uconn_info *puci;
puci = MakeUDPConnRec();
puci->pup = pup;
return(puci);
}
/* return the IP address in IPv4 or IPv6 dotted representation */
static char *collie_dots(
ipaddr ipaddress)
{
char *pch;
int map = resolve_ipaddresses;
resolve_ipaddresses = 0;
pch = HostName(ipaddress);
resolve_ipaddresses = map;
return(pch);
}
/* convert the IP address to a name */
static char *collie_name(
ipaddr ipaddress)
{
char *pch;
int map = resolve_ipaddresses;
resolve_ipaddresses = 1;
pch = HostName(ipaddress);
resolve_ipaddresses = map;
return(pch);
}
/* return a date stamp that we like */
/* Unix format: "Fri Sep 13 00:00:00 1986\n" */
/* 1 2 */
/* 012345678901234567890123456 */
static char *
collie_date(
time_t timestamp)
{
struct tm *ptm;
char *now;
ptm = localtime(×tamp);
now = asctime(ptm);
/* nuke the newline */
now[24] = '\00';
return(now);
}
/* return a time stamp that we like */
/* Unix format: "Fri Sep 13 00:00:00 1986\n" */
/* 1 2 */
/* 012345678901234567890123456 */
static char *
collie_time(
struct timeval *ptime)
{
char *now;
now = ts2ascii(ptime);
return(now);
}
static void
ParseArgs(char *argstring)
{
int argc;
char **argv;
int i;
/* make sure there ARE arguments */
if (!(argstring && *argstring))
return;
/* break the string into normal arguments */
StringToArgv(argstring,&argc,&argv);
/* check the module args */
for (i=1; i < argc; ++i) {
if (debug > 1)
printf("Checking argv[%d]:%s\n", i, argv[i]);
if (strcmp(argv[i],"-d") == 0) {
debug = 1;
} else if (strcmp(argv[i],"-l") == 0) {
print_labels = TRUE;
} else if (strcmp(argv[i],"-n") == 0) {
print_labels = FALSE;
} else {
fprintf(stderr,"Collie module: bad argument '%s'\n",
argv[i]);
exit(-1);
}
}
}
#endif /* LOAD_MODULE_COLLIE */
syntax highlighted by Code2HTML, v. 0.9.1