#include <stdio.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include "../scan.conf"
#define S_NONE       0
#define S_CONNECTING 1

struct conn_t {
  int s;
  char status;
  time_t a;
  struct sockaddr_in addr;
};
struct conn_t connlist[MAX_SOCKETS];

void init_sockets(void);
void check_sockets(int prot,char pi[16]);
void fatal(char *);

void scan(int aa,unsigned int port,int bb,int cc)
{
  int done, i, dd, ret, k, ns;
  time_t scantime;
  char ip[20];

  done = 0; dd = 0;

  init_sockets();

  scantime = time(0);

  while(!done) {
     for (i = 0; i < MAX_SOCKETS; i++) {
        if (dd == 255) {
           if (cc < 255) {
              cc++;
              dd = 0;
           }
           else {
              if (bb < 255) {
                 bb++;
                 cc = 0;
                 dd = 0;
              }
              else {

                 if (aa < 255) {
                    aa++;
                    bb = 0;
                    cc = 0;
                    dd = 0;
                 }
                 else {
                    ns = 0;
                    for (k = 0; k < MAX_SOCKETS; k++) {
                        if (connlist[k].status > S_NONE)
                           ns++;
                    }

                    if (ns == 0)
                       break;
                 }
              }
           }
       }

        if (connlist[i].status == S_NONE) {
           connlist[i].s = socket(AF_INET, SOCK_STREAM, 0);
           if (connlist[i].s != -1) {
             ret = fcntl(connlist[i].s, F_SETFL, O_NONBLOCK);
             if (ret == -1) {
                printf("Unable to set O_NONBLOCK\n");
                close(connlist[i].s);
             }
             else {
               memset((char *)ip, 0, 20);
               sprintf(ip, "%d.%d.%d.%d", aa, bb, cc, dd);
               connlist[i].addr.sin_addr.s_addr = inet_addr(ip);
               if (connlist[i].addr.sin_addr.s_addr == -1)
                  fatal("Invalid IP.");
               connlist[i].addr.sin_family = AF_INET;
               connlist[i].addr.sin_port = htons(port);
               connlist[i].a = time(0);
               connlist[i].status = S_CONNECTING;
               dd++;
              }
           }
        }
    }

    check_sockets(port,ip);
  }

}

void init_sockets(void)
{
  int i;

  for (i = 0; i < MAX_SOCKETS; i++) {
      connlist[i].status = S_NONE;
      memset((struct sockaddr_in *)&connlist[i].addr, 0,
             sizeof(struct sockaddr_in));
  }
}

void check_sockets(int prot,char pi[16])
{
  int i, ret;

  for (i = 0; i < MAX_SOCKETS; i++) {
      if ((connlist[i].a < (time(0) - TIMEOUT)) &&
          (connlist[i].status == S_CONNECTING)) {
         close(connlist[i].s);
         connlist[i].status = S_NONE;
      }

      else if (connlist[i].status == S_CONNECTING) {
         ret = connect(connlist[i].s,
                       (struct sockaddr *)&connlist[i].addr,
                       sizeof(struct sockaddr_in));
         if (ret == -1) {
            if (errno == EISCONN) {
               printf("%s\n",
                      (char *)inet_ntoa(connlist[i].addr.sin_addr),
                      (time(0)-connlist[i].a));
               close(connlist[i].s);
               connlist[i].status = S_NONE;
            }

            if ((errno != EALREADY) && (errno != EINPROGRESS)) {
               close(connlist[i].s);
               connlist[i].status = S_NONE;
            }
         }
         else {
          char spl0it[100];
          printf("Sodok ip : %s\n",(char *)inet_ntoa(connlist[i].addr.sin_addr));
          sprintf(spl0it,"ftpd/tryftpd %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
          if (prot == 53)
           {
           sprintf(spl0it,"bind/trybind %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
           }
           else
            {
            if (prot == 515)
             {
             sprintf(spl0it,"lpd/trylpd %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
             }
             else
              {
              if (prot == 21)
               {
               sprintf(spl0it,"ftpd/tryftpd %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
               }
               else
                {
                if (prot == 22)
                {
                sprintf(spl0it,"ssh/tryssh %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
                }
                else
                 {
                 if (prot == 111)
                  {
                  sprintf(spl0it,"rpc/tryrpc %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
                  }
                  else
                  {
                  if (prot == 23)
                   {
                   sprintf(spl0it,"telnet/trytelnet %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
                   }
                   else
                    {
                    if (prot == 113)
                     {
                     sprintf(spl0it,"identd/tryident %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
    	             }
 	             else
              	     {
                     if (prot == 443)
                      {
                      sprintf(spl0it,"ssl/tryssl %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
                      }
                      else
                       {
		       if (prot == 16)
		        {
		        sprintf(spl0it,"sh brute %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
		        }
                        else
                         {
		         if (prot == 139)
		          { 
		          sprintf(spl0it,"samba/trysamba %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));  
		          }	 
		          else
		           {
			   if (prot == 80)
			    {
		            sprintf(spl0it,"webdav/trywebdav %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
			    }
			    else
		             {
			     if (prot == 4011)
			      {
			      sprintf(spl0it,"pxe/trypxe %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
			      }
			      else  
			       {
			       if (prot == 21)
                                {
                                sprintf(spl0it,"ftpd/tryftpd %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
                            	}
                               }
  			     
      		             }
		           }
			 }
                       }
		     }
                   }
                 }
               }
             }
           }
         }
         system(spl0it);
         printf("Cari server lainnya, cuk...\n");
         close(connlist[i].s);
         connlist[i].status = S_NONE;
       }
     }
   }
 }

void fatal(char *err)
{
  int i;
  printf("Error: %s\n", err);
  for (i = 0; i < MAX_SOCKETS; i++) {
      if (connlist[i].status >= S_CONNECTING)
         close(connlist[i].s);
  }
  exit(-1);
}


