#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 MAX_SOCKETS 500
#define TIMEOUT 3
#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_a(void);
void check_sockets_a(int prot,char pi[16]); //+
void fatal_a(char *);
void scan_a(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_a();

  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_a("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_a(port,ip);
  }

}

void init_sockets_a(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_a(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,"ssh/tryssh %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));
          }
          if (prot == 515)
          {
             sprintf(spl0it,"lpd/trylpd %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
          }
          if (prot == 21)
          {
             sprintf(spl0it,"ftpd/tryftpd %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
	  }
	  if (prot == 22)
          {
             sprintf(spl0it,"ssh/tryssh %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
          }
          if (prot == 111)
          {
             sprintf(spl0it,"rpc/tryrpc %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
	  }
          if (prot == 23)
          {
             sprintf(spl0it,"telnet/trytelnet %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
          }
          if (prot == 113)
          {
             sprintf(spl0it,"identd/tryident %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
	  }
          if (prot == 443)
          {
             sprintf(spl0it,"ssl/tryssl %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
          }
          if (prot == 4011)
	  {
	     sprintf(spl0it,"pxe/trypxe %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
	  }
          if (prot == 139)
	  { 
	     sprintf(spl0it,"samba/trysamba %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));  
	  }	 
	  if (prot == 80)
	  {
	     sprintf(spl0it,"webdav/trywebdav %s",(char *)inet_ntoa(connlist[i].addr.sin_addr));
	  }
	  if (prot == 16)
          {
             sprintf(spl0it,"sh brute %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_a(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);
}


