/* EXCLUDED-TEAM  [www.excluded.org]
   ----------------------------------------

   scanscan.c
   scans the net traffic for ports scans - therefor scanscan.
----------
detects:
tcp portscans : syn, fin, null, xmas
icmp pings: echo, information request, netmask request, timestamp request
udp: warns you if one of the ports you can specify down (int udpports[ ])
         in the sources is requested. can be use to detect udp portscanns-
         especialy if ports like 31337 are requested....
----------

   QDP - Quick and Dirty Products


                "SCAN MY HOST
                      AND I LL RAPE YOUR HD!"
                              -l0om
*/

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/select.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>


/* CONSTANTS */

#define  SECONDS    2   /* wait till next part of tcp handshake must income */
#define  USECONDS   0   /* + SECONDS to wait for next packet (ack|rst)*/
#define  report     printf 

/* functions prototyps */

void header(void);
void help(void);
void icmpdetect(int icmpsock);
void udpdetect(int udpsock);
void tcpdetect(int tcpsock);
void errch(int i, char *mess);
static void sig_int(int sig);

unsigned int udpports[] = { 138,     /* udpdetect will listen for */
                            5000, 
			    31337 }; /* these destination ports feel */   
                                     /* free to add/remove some ports */

int main(int argc, char **argv)
{
  int icmps, udps, tcps;
  fd_set rset;

  header();
  if(argc != 1) help();

  signal(SIGINT, sig_int);   /* if it fails- no problem */

  errch((icmps = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)), 
             "cannot creat icmp socket - quit\n");
  errch((udps = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)),
              "cannot creat udp socket - quit\n");
  errch((tcps = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)),
              "cannot creat tcp socket - quit\n");

  while(1) {
  FD_ZERO(&rset);
  FD_SET(icmps, &rset);
  FD_SET(udps, &rset);
  FD_SET(tcps, &rset);
  
  select(icmps+udps+tcps+1, &rset, NULL, NULL, NULL);
   
    if(FD_ISSET(icmps, &rset))
      icmpdetect(icmps);
    if(FD_ISSET(udps, &rset))
      udpdetect(udps);
    if(FD_ISSET(tcps, &rset))
      tcpdetect(tcps);
  }
  return(0);
}

void tcpdetect(int tcpsock)
{
  fd_set rset;
  char buf[100];
  unsigned int saddr;
  struct iphdr *ip;
  struct tcphdr *tcp;
  struct timeval tv;

  tv.tv_sec = SECONDS;
  tv.tv_usec = USECONDS;

  ip = (struct iphdr *)buf;
  tcp = (struct tcphdr *)(buf + sizeof(struct iphdr));
  memset(buf, 0x00, sizeof(buf));

  errch(read(tcpsock, buf, sizeof(buf)), "read error!\n");

  /******************************************************
   ************ DETECT TCP NULL SCANNING ****************/

  if(tcp->syn==0 && tcp->ack==0 && tcp->rst==0 && tcp->fin==0 
     && tcp->urg==0 && tcp->psh==0) {
    report("%s : tcp null portscan detected\n",inet_ntoa(ip->saddr));
    return;
  }

  /******************************************************
   ************ DETECT TCP XMAS SCANNING ****************/

  if(tcp->urg==1 && tcp->psh==1 && tcp->fin==1) {
    report("%s : tcp xmas portscan detected\n",inet_ntoa(ip->saddr));
    return;
  }


  /******************************************************
   ************ DETECT TCP SYN SCANNING *****************/


  if(tcp->syn==1) {
    saddr = ip->saddr;
    
    FD_ZERO(&rset);
    FD_SET(tcpsock, &rset);
    switch(select(tcpsock+1, &rset, NULL, NULL, &tv)) {
    case -1:
      fprintf(stderr,"select error!\n");
      exit(-1);
 
    case 0: 
      report("%s : tcp stealth scan detected\n",inet_ntoa(ip->saddr));
      break;

    default:
      errch(read(tcpsock, buf, sizeof(buf)), "read error!\n");
      
      if(ip->saddr == saddr)
	if(tcp->ack==1 || tcp->rst==1) return; 
	 else report("%s : tcp stealth scan detected\n",inet_ntoa(saddr));
      else return;
    }
  }

  /****************************************************
   ************** DETECT FIN SCANNING *****************/

  if(tcp->fin == 1 && tcp->rst == 0 && tcp->ack == 0) {
    saddr = ip->saddr;

    FD_ZERO(&rset);
    FD_SET(tcpsock, &rset);
    switch(select(tcpsock+1, &rset, NULL, NULL, &tv)) {
    case -1:
      fprintf(stderr, "select error!\n");
      exit(-1);

    case 0: 
      report("%s : tcp fin scan detected\n",inet_ntoa(saddr));
      break;

    default:
      errch(read(tcpsock, buf, sizeof(buf)), "read error!\n");
      if(ip->saddr == saddr)
	if(tcp->ack == 1) return; /* a closing connection */
	else report("%s : tcp fin scan detected\n",inet_ntoa(saddr));
      else return;
    }
  }
}


void udpdetect(int udpsock)
{
  int arrysize, i;
  char buf[100];
  struct iphdr *ip;
  struct udphdr *udp;
    
  arrysize = ((sizeof(udpports))/(sizeof(int)));

  ip = (struct iphdr *)buf;
  udp = (struct udphdr *)(buf + sizeof(struct iphdr));
  memset(buf, 0x00, sizeof(buf));

  errch(read(udpsock, buf, sizeof(buf)), "read error!\n");

  for(i = 0; i < arrysize; i++) 
    if((int)(ntohs(udp->dest)) == udpports[i]) 
      report("%s : have send udp to port %d\n",
	     inet_ntoa(ip->saddr), ntohs(udp->dest));
}

void icmpdetect(int icmpsock)
{
  char buf[100];
  struct iphdr *ip;
  struct icmphdr *icmp;

  ip = (struct iphdr *)buf;
  icmp = (struct icmphdr *)(buf + sizeof(struct iphdr));
  memset(buf, 0x00, sizeof(buf));

  errch(read(icmpsock, buf, sizeof(buf)), "read error!\n");

  if(icmp->code == 0) switch(icmp->type) {
  case 8:
    report("%s : pinged our host with ECHO\n",
      inet_ntoa(ip->saddr));
    break;
  case 13:
    report("%s : pinged our host with TIME_STAMP_REQ\n",
      inet_ntoa(ip->saddr));
    break;
  case 15:
    report("%s : pinged our host with INFORMATION_REQ\n",
      inet_ntoa(ip->saddr));
    break;
  case 17:
    report("%s : pinged our host with NETMASK_REQ\n",
      inet_ntoa(ip->saddr));
    break;
  default: break;
  }
}

void sig_int(int sig)
{
  fflush(stdout); fflush(stdout);
  printf("BREAK: received interrupt signal- exiting...\n");
  sleep(1);
  exit(0);
}

void errch(int i, char *mess)
{
  if(i < 0) {
    fprintf(stderr, mess);
    exit(-1);
  }
}

void header(void) {
  puts("
EXCLUDED-TEAM  [www.excluded.org]
---------------------------------------
    scanscan - scanscan - scanscan

                -l0om-
---------------------------------------

");
}

void help(void)
{
  puts("
HELP:
*****

no arguments needed caus this works full automatic.
for information about how this works take a look on the sources.
");
}





