Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <stdlib.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <malloc.h>
#include <netinet/in_systm.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <netinet/udp.h>
#define __FAVOR_BSD
#include <netinet/tcp.h>
//#include <netinet/udp.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <linux/if_ether.h>
#include <syslog.h>
#define PKTLEN 96 /* Should be enough for what we want */
#ifndef IP_MF
#define IP_MF 0x2000
#endif
/***** WATCH LEVELS ******/
#define MYSELFONLY 1
#define MYSUBNET 2
#define HUMANITARIAN 3
/***** REPORT LEVELS *****/
#define REPORTALL 1
#define REPORTDOS 2
#define REPORTSCAN 3
struct floodinfo {
u_short sport;
struct floodinfo *next;
};
struct addrlist {
u_long saddr;
int cnt;
int wwwcnt;
struct addrlist *next;
};
struct atk {
u_long saddr;
u_char eaddr[ETH_ALEN];
time_t atktime;
};
struct pktin {
u_long saddr;
u_short sport;
u_short dport;
time_t timein;
u_char eaddr[ETH_ALEN];
struct floodinfo *fi;
struct pktin *next;
};
struct scaninfo {
u_long addr;
struct atk teardrop;
struct atk land;
struct atk icmpfrag;
struct pktin *tcpin;
struct pktin *udpin;
struct scaninfo *next;
u_long icmpcnt;
} ;
struct scaninfo *Gsilist = NULL, *Gsi;
u_long Gmaddr;
time_t Gtimer = 10, Gtimein;
int Gportlimit = 7;
int Gsynflood = 8;
int Gwebcount = 40;
int Gicmplimit = 5;
int Gwatchlevel = MYSELFONLY;
int Greportlevel = REPORTALL;
char *Gprogramname, *Gdevice = "eth0";
/******** IP packet info ********/
u_long Gsaddr, Gdaddr;
int Giplen, Gisfrag, Gid;
/****** Externals *************/
int SIOCGIFFLAGS;
int SIOCSIFFLAGS;
extern int errno;
extern char *optarg;
extern int optind, opterr;
void do_tcp(), do_udp(), do_icmp(), print_info(), process_packet();
void addtcp(), addudp(), clear_pktin(), buildnet();
void doargs(), usage(), addfloodinfo(), rmfloodinfo();
struct scaninfo *doicare(), *addtarget();
char *anetaddr(), *ether_ntoa();
u_char *readdevice();
int SIOCGIFFLAGS;
int SIOCSIFFLAGS;
main(argc, argv)
int argc;
char *argv[];
{
int pktlen = 0, i, netfd;
u_char *pkt;
char hostname[32];
struct hostent *hp;
time_t t;
doargs(argc, argv);
openlog("WATCHER", 0, LOG_DAEMON);
if(gethostname(hostname, sizeof(hostname)) < 0)
{
perror("gethostname");
exit(-1);
}
if((hp = gethostbyname(hostname)) == NULL)
{
fprintf(stderr, "Cannot find own address\n");
exit(-1);
}
memcpy((char *)&Gmaddr, hp->h_addr, hp->h_length);
buildnet();
if((netfd = initdevice(O_RDWR, 0)) < 0)
exit(-1);
/* Now read packets forever and process them. */
t = time((time_t *)0);
while(pkt = readdevice(netfd, &pktlen))
{
process_packet(pkt, pktlen);
if(time((time_t *)0) - t > Gtimer)
{
/* Times up. Print what we found and clean out old stuff. */
for(Gsi = Gsilist, i = 0; Gsi; Gsi = Gsi->next, i++)
{
clear_pktin(Gsi);
print_info();
Gsi->icmpcnt = 0;
}
t = time((time_t *)0);
}
}
}
/************************************************************************
Function: initdevice
Description: Set up the network device so we can read it.
**************************************************************************/
initdevice(int fd_flags, u_long dflags)
{
struct ifreq ifr;
int fd, flags = 0;
if((fd = socket(PF_INET, SOCK_PACKET, htons(0x0003))) < 0)
{
perror("Cannot open device socket");
exit(-1);
}
/* Get the existing interface flags */
strcpy(ifr.ifr_name, Gdevice);
if(ioctl(fd, SIOCGIFFLAGS, &ifr) < 0)
{
perror("Cannot get interface flags");
exit(-1);
}
ifr.ifr_flags |= IFF_PROMISC;
if(ioctl(fd, SIOCSIFFLAGS, &ifr) < 0)
{
perror("Cannot set interface flags");
exit(-1);
}
return(fd);
}