/*************************[GateScan20.C]************************** 
 * Based on the bong's code <-- helped a shitload                *
 * added...                                                      *
 * - cleaned the code up a little bit                            *
 * - now logs all wingate servers                                *
 * - added the portscanner                                       *
 * [MAJOR PROPS GO TO:]                                          *
 *	codesearc, ]{ewl, Punk182, Nforcer, bong, S-y-S          *
 *	#ehforce@unet, #c@unet, Sslash, as2r|azz, funkey         *
 *	MAJOR thanx to packet storm security for posting this    *
 *	up. thanx to SIN(Self Induced Negativity member Hogs_head*
 * [ANTI PROPS GO TO:[I've got my reasons...]]                   * 
 *	#fts(2) <-- never really liked them :P                   *
 *  	#wicked, Ellison, fuCKfaCe (Don't have many enemies...)  *
 *************************[GateScan20.C]**************************
*/ 
 

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>
#include <errno.h> 
#define HIGH_PORT 1024
#define SA struct sockaddr
#define SIN_LEN sizeof(struct sockaddr_in)
#define IPV4_ADDRLEN 16
#define cl "[0m"
#define mag "[35m"
#define cyn "[36m"
#define wht "[37m"
#define hbl "[1;30m"
#define hmag "[1;35m"
#define hcyn "[1;36m"
#define hwh "[1;37m"

void ShowVer();


/* Portscanner */
void portscan(char *the_ip)
{   
   struct hostent *scand;       
   struct sockaddr_in scan;
   int sck; 
   int c, portnum;
     ShowVer();
     printf("Scanning....\n");
     for(portnum=1; portnum<HIGH_PORT; portnum++){               
   
       if(isdigit(*the_ip)){
         scan.sin_addr.s_addr = inet_addr(the_ip);
     } else{                                                
         scand = gethostbyname(the_ip);
         strncpy((char *)&scan.sin_addr, (char *)scand->h_addr, sizeof(scan.sin_addr));     
           }
   
     scan.sin_family = AF_INET;
     scan.sin_port   = htons(portnum);
     sck = socket(AF_INET, SOCK_STREAM, 0);             
    
       if(sck < 0){
         printf("Socket cannot be established!\n");
                  }

     c = connect(sck, (struct sockaddr *)&scan, sizeof(scan)); /* connect the socket */
       if(c < 0){
                  
     } else{
                
         printf("\t [%s]:%d\n",the_ip,portnum);
           }
  
 shutdown(sck, 2);
}
 close(sck);
}

void ShowHelp(char *, char *);
void ShowVer()
{
   fprintf(stderr, "[%sG%sateScan%s.%sC%s[%smisteri0%s%s@%sunet]]\n",cyn,mag,hbl,cyn,cl,hwh,cl,cyn,cl);
}
int ConnectCheck(struct sockaddr_in, int, int);

const char *ipv4_ntop(int, const void *, char *, size_t);
const char *ipv4_showname(int , const void *, char *, size_t);

FILE *stream; /* Declare the Ol' FILE STREAM */

int main(int argc, char *argv[]) {
   int i,j=0,status,Children=128,Timeout=7,Resolve=0,class=0;
   char DestIP[15],*NetworkID,c,*num3;
   struct sockaddr_in DestAddress;
   if(atoi(argv[2])==3)
     {
       portscan(argv[1]);
     }
   if(argc < 3) ShowHelp(argv[0], "");
   NetworkID = argv[1];
   num3=argv[2];
   class=atoi(num3);
   opterr = 0;
   while((c = getopt(argc, argv, "Rp:C:t:")) != -1) {
      switch(c) {
         case 'R': Resolve = -1; break;
         case 'C': Children = atoi(optarg); break;
         case 't': Timeout = atoi(optarg); break;
         case '?': ShowHelp(argv[0], "ERROR: unrecognized option"); break;
      }
   }
   if(Children < 1) ShowHelp(argv[0], "ERROR: invalid number of children");
   if(Timeout < 1) ShowHelp(argv[0], "ERROR: invalid timeout");
   ShowVer();
   if (class==1)
   fprintf(stderr, "Scanning %s.*.*:23 children:%i, timeout:%i\n\n", 
   NetworkID,Children, Timeout);
   if (class==2)
   fprintf(stderr, "Scanning %s.*:23 children:%i, timeout:%i\n\n",NetworkID, Children, Timeout);   
   DestAddress.sin_family = AF_INET;
   DestAddress.sin_port = htons(23);
   if (class==1){
   for(j = 0; j < 256; j++) {
   for(i = 0; i < Children; i++) {
      sprintf(DestIP, "%s.%d.%d", NetworkID,j, i);
      inet_aton(DestIP, &DestAddress.sin_addr);
      if(!fork()) ConnectCheck(DestAddress, Timeout, Resolve);
   }
   for(i = Children + 1; i < 256; i++) {
      wait(&status); /* wait till a child dies to make another */
      sprintf(DestIP, "%s.%d.%d", NetworkID,j, i);
      inet_aton(DestIP, &DestAddress.sin_addr);
      if(!fork()) ConnectCheck(DestAddress, Timeout, Resolve);
   }
 }
 }
 if (class==2){
   for(i = 0; i < Children; i++) {
      sprintf(DestIP, "%s.%d", NetworkID, i);  
      inet_aton(DestIP, &DestAddress.sin_addr);
      if(!fork()) ConnectCheck(DestAddress, Timeout, Resolve);
   }   
   for(i = Children + 1; i < 256; i++) {
      wait(&status); /* wait till a child dies to make another */
      sprintf(DestIP, "%s.%d", NetworkID, i);
      inet_aton(DestIP, &DestAddress.sin_addr);
      if(!fork()) ConnectCheck(DestAddress, Timeout, Resolve);
   }
   for(;;) {
      if((waitpid(-1, &status, WNOHANG) == -1) && (errno == ECHILD))
            exit(EXIT_SUCCESS);   
}   
}
}

int ConnectCheck(struct sockaddr_in DestAddr, int Timeout, int Resolve)
 {
   int result,ret,SocketFD;
   char Hostname[60],buffer1[64];
   if((SocketFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) exit (EXIT_FAILURE);
   alarm(Timeout);
   result = connect(SocketFD, (SA *)&DestAddr, SIN_LEN);
   if (!result) {
      alarm(Timeout);
         memset(buffer1, '\0', 64);
         if ((ret = read(SocketFD, buffer1, 64))  > 0)
         {
            ret = read(SocketFD, buffer1, 64);
            if(!(memcmp(buffer1, "WinGate>", 8)) ||
               !(memcmp(buffer1, "Too man", 7)))
            {
      stream = fopen("wingatelist.txt","a");
      printf("Wingate found: %s\n\a",ipv4_ntop(AF_INET,&DestAddr.sin_addr.s_addr,Hostname,59));
      fprintf(stream,"%s\n",ipv4_ntop(AF_INET,&DestAddr.sin_addr.s_addr,Hostname,59));
      fclose(stream);
      }}
      close(SocketFD);
  }

   exit(EXIT_SUCCESS);
}

const char *
ipv4_ntop(int family, const void *addrptr, char *strptr, size_t len) {
   const u_char *p = (const u_char *)addrptr;
   if(family == AF_INET) {
      char temp[IPV4_ADDRLEN];
      snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
      if(strlen(temp) >= len) {
         errno = ENOSPC;
         return(NULL);
      }
      strcpy(strptr, temp);
      return(strptr);
   }
   errno = EAFNOSUPPORT;
   return(NULL);
}

const char *
ipv4_showname(int family, const void *addrptr, char *strptr, size_t len) {
   struct hostent *hentry;
   size_t aflen;
   if(family == AF_INET) aflen = 4;
   else {
      errno = EAFNOSUPPORT;
      return(NULL);
   }
   if((hentry = gethostbyaddr(addrptr, aflen, family)) != NULL) {
      if(strlen(hentry->h_name) < len) {
         strcpy(strptr, hentry->h_name);
         return(strptr);
      }
   }

   return(ipv4_ntop(family, addrptr, strptr, len));
}

void ShowHelp(char *argv0, char *ErrMsg) {
   ShowVer();
   printf("v2.0 now includes intergrated portscanner\n");
   printf("Based bong's <bong26@hotmail.com> code\n");
   printf("Output of wingate servers will be written in wingatelist.txt\n");
   printf("Usage: %s <network> <class> [option]\n",argv0);
   printf(" class: 1 class b network ID <x.x> \n");
   printf("        2 class c network ID <x.x.x>\n");
   printf("        3 portscan the host...\n");
   printf(" [-C <children>]\tmaximum simultaneous children\n");
   printf(" [-t <timeout>] \tseconds before connection timeout\n\n");
   exit (EXIT_FAILURE);
}
















