home *** CD-ROM | disk | FTP | other *** search
- /*
- extract - A network log processor
- Copyright (C) 1993 Douglas Lee Schales, David K. Hess, David R. Safford
-
- Please see the file `COPYING' for the complete copyright notice.
-
- extract.c - 03/20/93
-
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <netdb.h>
- #include <errno.h>
- #include <malloc.h>
- #include <unistd.h>
- #include <netinet/in.h>
-
-
- #include "extract.h"
- #include "chario.h"
- #include "parser.h"
- #include "interp.h"
- #include "stdunix.h"
-
- extern char *inet_ntoa(struct in_addr);
- extern int getopt(int, char **, char *);
- extern char *optarg;
- extern int optind;
-
- extern struct parsetree *parse(void);
- extern void extract(int, struct parsetree *);
- extern char *getportname(unsigned short);
- extern void flushbuf(void);
- extern void writebin(struct tcpsynout *);
- extern void writeascii(struct tcpsynout *);
- extern void writebuf(struct tcpsynout *);
- extern void setlogmode(int);
- extern void setlogfile(FILE *);
- extern char *gettimestr(struct timeval);
- static void helpscreen(char *);
-
- #define LOGBINARY 0
- #define LOGASCII 1
-
- int resolve = 1;
- #define TCPDATA 0
- #define UDPDATA 1
- int udptcpflag = TCPDATA;
-
- int
- main(int argc, char **argv)
- {
- struct parsetree *parsetree;
- int logmode = LOGASCII;
- FILE *outfile = stdout;
- FILE *dumpfile = stdin;
- int file = 0, expr = 0, errflag = 0;
- int status;
- char *membufname;
- int c;
-
- while((c=getopt(argc, argv, "d:e:f:E:F:o:utabnh")) != -1){
- switch(c){
- case 'a':
- logmode = LOGASCII;
- break;
- case 'b':
- logmode = LOGBINARY;
- break;
- case 'n':
- resolve = 0;
- break;
- case 't':
- udptcpflag = TCPDATA;
- break;
- case 'u':
- udptcpflag = UDPDATA;
- break;
- case 'f':
- if((status = addfile(optarg)) != NOERR){
- errflag++;
- if(status == FILEERR){
- perror(optarg);
- exit(1);
- }
- else {
- fprintf(stderr, "%s: unexpected error\n", optarg);
- exit(1);
- }
- }
- file++;
- break;
- case 'F':
- if((status = includefile(optarg)) != NOERR){
- errflag++;
- if(status == FILEERR){
- perror(optarg);
- exit(1);
- }
- else {
- fprintf(stderr, "%s: unexpected error\n", optarg);
- exit(1);
- }
- }
- file++;
- break;
- case 'e':
- membufname = (char *)malloc(20);
- sprintf(membufname, "argv[%d]", optind-1);
- if((status = addmembuf(optarg, membufname)) != NOERR){
- fprintf(stderr, "-e: unexpected error\n");
- errflag++;
- }
- expr++;
- break;
- case 'E':
- membufname = (char *)malloc(20);
- sprintf(membufname, "argv[%d]", optind-1);
- if((status = includemembuf(optarg, membufname)) != NOERR){
- fprintf(stderr, "-E: unexpected error\n");
- errflag++;
- }
- expr++;
- break;
- case 'd':
- if(!(dumpfile = fopen(optarg, "r"))){
- perror(optarg);
- errflag++;
- }
- break;
- case 'o':
- if(!errflag && !(outfile = fopen(optarg, "w"))){
- perror(optarg);
- errflag++;
- }
- break;
- case 'h':
- helpscreen(argv[0]);
- exit(0);
- break;
- default:
- errflag++;
- break;
- }
- }
- if(errflag)
- exit(1);
-
- if(!file && !expr)
- addmembuf("{print}", "");
-
- setlogfile(outfile);
- setlogmode(logmode);
- if((parsetree = parse()))
- extract(fileno(dumpfile), parsetree);
- else
- exit(1);
- return 0;
- }
-
- void
- helpscreen(char *name)
- {
- fprintf(stdout,"\
- %s: usage: %s [options]\n\
- options: -a ASCII output (the default)\n\
- -b Binary output
- -n Use IP addresses for ASCII output\n\
- -h Print this help screen\n\
- -e script Specify script inline\n\
- -E script Specify script inline\n\
- -f file Specify script filename\n\
- -F file Specify script filename\n\
- -d dumpfile Specify dump file to process (def: stdin)\n\
- -o outfile Specify output file (def: stdout)\n\
- \n\
- %s processes a binary dump file created by 'tcpsynlogger',\n\
- selecting records to output. The syntax of the script file is similar\n\
- to awk(1). The script can be specified on the command line or can be\n\
- stored in a file. All scripts specified by '-e', '-E', '-f', '-F' are\n\
- in effect, processed as a single file. Scripts specified by '-e' and\n\
- '-f' are appended, whereas scripts specified by '-E' and '-F' are pre-\n\
- pended. The use of '-E' or '-F' along with a '#!%s -f' script\n\
- executable allows insertion of additional script lines from the command\n\
- line.\n",
- name, name, name, name);
- }
-
- int
- nread(int fd, char *buf, int numbytes)
- {
- int count = numbytes;
- int n;
-
- while(count){
- if((n = read(fd, buf, count)) > 0){
- buf += n;
- count -= n;
- }
- else
- break;
- }
- return numbytes-count;
- }
-
- void
- extract(int fd, struct parsetree *pt)
- {
- struct tcpsynout buf[1000];
- int i, n;
-
- while((n=nread(fd, (char *)&buf, sizeof(buf))) > 0){
- for(i=0;i<(n/sizeof(struct tcpsynout));i++)
- interp(&buf[i], pt);
- }
- flushbuf();
- }
-
- int outlogmode = LOGBINARY;
- FILE *logfile = stdout;
-
- void
- setlogfile(FILE *f)
- {
- logfile = f;
- }
-
- void
- setlogmode(int logmode)
- {
- outlogmode = logmode;
- }
-
- #define OUTBUFSIZE 1000
- struct tcpsynout outbuffer[OUTBUFSIZE];
- static int outptr = 0;
-
- void
- writebuf(struct tcpsynout *outbuf)
- {
- switch(outlogmode){
- case LOGBINARY:
- writebin(outbuf);
- break;
- case LOGASCII:
- writeascii(outbuf);
- break;
- default:
- fprintf(stderr, "Internal error... unknown output mode.\n");
- exit(1);
- break;
- }
- }
-
- void
- writebin(struct tcpsynout *outbuf)
- {
- if(outptr == OUTBUFSIZE)
- flushbuf();
- memcpy(&outbuffer[outptr++], outbuf, sizeof(struct tcpsynout));
- }
-
- void
- flushbuf(void)
- {
- if(outptr)
- write(fileno(logfile), (char *)outbuffer,
- sizeof(struct tcpsynout)*outptr);
- outptr = 0;
- }
-
- void
- writeascii(struct tcpsynout *outbuf)
- {
- struct in_addr haddr;
- extern char *cgethostbyaddr(struct in_addr);
-
- fputs(gettimestr(outbuf->tp), logfile);
- fprintf(logfile, " %8X ", outbuf->tcpseq);
- memcpy(&haddr.s_addr, &outbuf->ipsrcaddr, 4);
- fprintf(logfile, "%-21s", resolve ? cgethostbyaddr(haddr) : inet_ntoa(haddr));
- fputc(' ', logfile);
- fputs(getportname(outbuf->tcpsrcport), logfile);
- fputs(" -> ", logfile);
- memcpy(&haddr.s_addr, &outbuf->ipdstaddr, 4);
- fprintf(logfile, "%-21s", resolve ? cgethostbyaddr(haddr) : inet_ntoa(haddr));
- fputc(' ', logfile);
- fputs(getportname(outbuf->tcpdstport), logfile);;
- fputc('\n', logfile);
- fflush(logfile);
- }
-
- char *
- getportname(unsigned short p)
- {
- struct servent *se;
- static char result[80];
-
- if(resolve && (se = getservbyport((unsigned int)ntohs(p),
- udptcpflag == TCPDATA ? "tcp" : "udp")))
- strcpy(result, se->s_name);
- else
- sprintf(result, "%u", (unsigned int)ntohs(p));
-
- return result;
- }
-