home *** CD-ROM | disk | FTP | other *** search
- /*
- udplogger - A UDP traffic logger
- Copyright (C) 1993 Douglas Lee Schales, David K. Hess, David R. Safford
-
- Please see the file `COPYING' for the complete copyright notice.
-
- udplog.c - 03/20/93
-
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/udp.h>
- #include <sys/time.h>
- #include <netdb.h>
- #include <memory.h>
-
- extern char *optarg;
- extern int optind, opterr;
-
- #include "defs.h"
-
- struct ipaddr {
- unsigned int addr:32;
- };
-
- struct tcpsynout {
- struct timeval tp;
- unsigned long ipsrcaddr;
- unsigned long ipdstaddr;
- unsigned long tcpseq;
- unsigned short tcpsrcport;
- unsigned short tcpdstport;
- };
-
- static void etherhandler(char *, int, struct timeval);
- static void udplog(struct ip *, struct timeval);
- static void udplogbin(struct tcpsynout *);
- static void udplogascii(struct tcpsynout *);
- static int isactive(struct tcpsynout *);
- static void udpage(struct timeval);
- static char *getudpportname(unsigned short);
- extern char *gettimestr(struct timeval);
-
- extern void pushfilter(int);
-
- #define LOGBINARY 0
- #define LOGASCII 1
- static int logtype = LOGBINARY;
- static FILE *logfile = stdout;
-
- int resolve = 0;
-
- extern char *getdefaultif(char *);
-
- main(int argc, char **argv)
- {
- char *eif = getdefaultif((char *)0);
- int fd;
- int c;
-
- while((c=getopt(argc, argv, "ni:abf:")) != -1){
- switch(c){
- case 'a':
- logtype = LOGASCII;
- break;
- case 'b':
- logtype = LOGBINARY;
- break;
- case 'n':
- resolve = 0;
- break;
- case 'i':
- eif = optarg;
- break;
- case 'f':
- if(!(logfile = fopen(optarg, "a"))){
- perror(optarg);
- exit(1);
- }
- break;
- default:
- fprintf(stderr, "Unknown option: %c\n", c);
- exit(1);
- }
- }
-
- fd = opennit(eif, pushfilter);
- procpkts(fd, etherhandler);
- }
-
- void
- etherhandler(char *pkt, int size, struct timeval tp)
- {
- udplog((struct ip *)(pkt + 14), tp);
- }
-
-
- void
- udplog(struct ip *ip, struct timeval tp)
- {
- struct udphdr *udp;
- struct tcpsynout outbuf;
-
- udp = (struct udphdr *)(((char *)ip) + sizeof(struct ip));
-
- memset((char *)&outbuf.tcpseq, 0, sizeof(long));
- memcpy((char *)&outbuf.tp, (char *)&tp, sizeof(struct timeval));
- memcpy((char *)&outbuf.ipsrcaddr, (char *)&ip->ip_src, 4);
- memcpy((char *)&outbuf.ipdstaddr, (char *)&ip->ip_dst, 4);
- memcpy((char *)&outbuf.tcpsrcport, (char *)&udp->uh_sport, 2);
- memcpy((char *)&outbuf.tcpdstport, (char *)&udp->uh_dport, 2);
-
- if(!isactive(&outbuf)){
- switch(logtype){
- case LOGBINARY:
- udplogbin(&outbuf);
- break;
- case LOGASCII:
- udplogascii(&outbuf);
- break;
- default:
- fprintf(stderr, "Log type unknown: %d\n", logtype);
- break;
- }
- }
- udpage(tp);
- }
-
- void
- udplogbin(struct tcpsynout *outbuf)
- {
- write(fileno(logfile), (char *)outbuf, sizeof(struct tcpsynout));
- }
-
- void
- udplogascii(struct tcpsynout *outbuf)
- {
- struct in_addr haddr;
-
- 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(getudpportname(outbuf->tcpsrcport), logfile);
- fputs(" -> ", logfile);
- memcpy(&haddr.s_addr, &outbuf->ipdstaddr, 4);
- fprintf(logfile, "%-21s", resolve ? cgethostbyaddr(haddr) : inet_ntoa(haddr));
- fputc(' ', logfile);
- fputs(getudpportname(outbuf->tcpdstport), logfile);;
- fputc('\n', logfile);
- fflush(logfile);
- }
-
- char *
- getudpportname(unsigned short p)
- {
- struct servent *se;
- static char result[80];
-
- if(resolve && (se = getservbyport((unsigned int)ntohs(p), "udp")))
- strcpy(result, se->s_name);
- else
- sprintf(result, "%u", (unsigned int)ntohs(p));
-
- return result;
- }
-
- struct udpactive {
- struct udpactive *next;
- struct tcpsynout buf;
- };
-
- struct udpactive *udphead = (struct udpactive *)0;
-
- int
- isactive(struct tcpsynout *buf)
- {
- struct udpactive *rove;
-
- for(rove=udphead;rove;rove=rove->next){
- if(!memcmp(&rove->buf.ipsrcaddr, &buf->ipsrcaddr, 4) &&
- !memcmp(&rove->buf.ipdstaddr, &buf->ipdstaddr, 4) &&
- !memcmp(&rove->buf.tcpsrcport, &buf->tcpsrcport, 2) &&
- !memcmp(&rove->buf.tcpdstport, &buf->tcpdstport, 2)){
- memcpy(&rove->buf.tp, &buf->tp, sizeof(struct timeval));
- return 1;
- }
- /* Response? */
- if(!memcmp(&rove->buf.ipsrcaddr, &buf->ipdstaddr, 4) &&
- !memcmp(&rove->buf.ipdstaddr, &buf->ipsrcaddr, 4) &&
- !memcmp(&rove->buf.tcpsrcport, &buf->tcpdstport, 2) &&
- !memcmp(&rove->buf.tcpdstport, &buf->tcpsrcport, 2)){
- memcpy(&rove->buf.tp, &buf->tp, sizeof(struct timeval));
- return 1;
- }
- }
- rove = (struct udpactive *)malloc(sizeof(struct udpactive));
- rove->next = udphead;
- udphead = rove;
- memcpy(&rove->buf, buf, sizeof(struct tcpsynout));
-
- return 0;
- }
-
- void
- udpage(struct timeval tp)
- {
- struct udpactive *rove, *prev, *temp;
-
- prev=(struct udpactive *)0;
- rove=udphead;
- while(rove){
- if((tp.tv_sec - rove->buf.tp.tv_sec) > 300){
- if(prev){
- prev->next = rove->next;
- free(rove);
- rove=prev->next;
- }
- else {
- udphead = rove->next;
- free(rove);
- rove=udphead->next;
- }
- }
- else {
- prev=rove;
- rove=rove->next;
- }
- }
- }
-
-