//ver [Thu Apr 5 21:09:53 CEST 2001] -- 638 /*================================================================ ************************* ****** ***** *** ** * ++[X3ni0n]++ xenion@libero.it ~ http://www.tba.tsx.org 4/4/2k+1 ************************* ****** ***** *** ** * SBANNER 2.0.beta another banner scanner.. ya :) compile: gcc -Wall -o sbanner ./sbanner.c usage: ./sbanner Specifies the timeout for the first char of the banner Specifies the timeout for connect() example: ./sbanner ip_list log_ftp_file 21 20 20 notes -there isn't output to stdout, only to (if STDOUT=0) -at the moment, it doesn't support more than 1 socket simultaneously -bugs? mailme at xenion@libero.it -BUG 1: se ci si connette e si disconnette prima il server, si impalla ================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #define STDOUT 1 // print log to stdout (there will be anyway the logfile) #define CH_DELAY 2 /* in a few cases it's better to set "CH_DELAY timeout_banner" */ /* return 1 if there are data to read from socket s in (timeout) seconds, otherwise 0 */ int s_data(int s, int timeout) { fd_set s_set; struct timeval tv; FD_ZERO(&s_set); // clear the s_set set FD_SET(s, &s_set); // add the file descriptor s in s_set set tv.tv_sec= timeout; tv.tv_usec= 0; return(select(s+1, &s_set, NULL, NULL, &tv)); } /* return 1 if the socket s is writeable in (timeout) seconds, otherwise 0 */ int w_data(int s, int timeout) { fd_set s_set; struct timeval tv; FD_ZERO(&s_set); // clear the s_set set FD_SET(s, &s_set); // add the file descriptor s in s_set set tv.tv_sec= timeout; tv.tv_usec= 0; return(select(s+1, NULL, &s_set, NULL, &tv)); } /* make and open socket */ int call_socket(char *hostname, unsigned short port, int timeout_connect) { struct sockaddr_in sa; struct hostent *hp; int s; void *optval; socklen_t *optlen; if((hp= gethostbyname(hostname)) == NULL) return(-1); memset(&sa,0,sizeof(sa)); memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length); sa.sin_family= hp->h_addrtype; sa.sin_port= htons((u_short)port); if((s= socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) return(-2); fcntl(s,F_SETFL,O_NONBLOCK); /* enable O_NONBLOCK on socket s */ /* from connect man : EINPROGRESS The socket is non-blocking and the connection can- not be completed immediately. It is possible to select(2) or poll(2) for completion by selecting the socket for writing. After select indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the rea- son for the failure). */ connect(s,(struct sockaddr *)&sa,sizeof sa); if(!w_data(s,timeout_connect)) { // if socket isn't writeable .. close(s); return(-3); } getsockopt(s, SOL_SOCKET, SO_ERROR, &optval, optlen); if(optval!= 0) { close(s); return(-4); } return(s); } /* *banner will contain all data coming from the socket */ int sbann(char *hostname, unsigned short port, char *banner, int timeout_banner, int timeout_connect) { int s; unsigned count0= 0; if((s= call_socket(hostname,port,timeout_connect)) < 0) return(s); if(!s_data(s,timeout_banner)) return(-5); for (;;) { if(s_data(s,CH_DELAY)) { read(s,&banner[count0],1); count0++; } else { banner[count0]= 0; close(s); return(1); } } } /* get ip from ip_list file valid ip: (3 '.' in ip)and(7<=total_length_ip<=15) */ int getip(FILE *f1, char *ip) { char LMAX=120; // max line length unsigned char c1,c2,c3; do { c1= c2= c3= 0; if(fgets(ip,LMAX,f1)==NULL) return(0); // if EOF, scan done. while((ip[c1]>=48 && ip[c1]<=57)||ip[c1]==46) c1++; ip[c1]=0; for(c2= 0; c2!= c1; c2++) if(ip[c2]=='.') c3++; } while ( ( c1<7 || c1>15 ) || c3!= 3 ); /*while ip isn't ok..*/ return(1); } /* fputs something like "Wed Jun 30 21:49:08 1993\n" in f1 */ void instime(FILE *f1) { struct tm *t1; time_t lt; lt= time(NULL); t1= localtime(<); fputs(asctime(t1),f1); } int main(int argc, char **argv) { char host[255],ban[400]; FILE *in,*log; unsigned port,timeout_banner,timeout_connect; int ERR; if(argc<6) { printf("sBanner v2.0.beta by xenion@libero.it, tba member\n\n"); printf("usage: ./sbanner \n"); return 1; } if ((in= fopen(argv[1],"r"))==NULL) { printf("%s: invalid ip file\n",argv[1]); return -1; } if ((log= fopen(argv[2],"a+"))==NULL) { printf("%s: invalid log file\n",argv[2]); return -1; } port= atoi(argv[3]); if(port>65535||port<1) { printf("invalid port.\n"); return -1; } timeout_banner= atoi(argv[4]); if(timeout_banner<1) { printf("invalid timeout_banner.\n"); return -1; } timeout_connect= atoi(argv[5]); if(timeout_connect<1) { printf("invalid timeout_connect.\n"); return -1; } fprintf(log,"sBanner %s %s %d %d %d\nCTime: ", argv[1],argv[2],port,timeout_banner,timeout_connect); instime(log); if(STDOUT) setvbuf(stdout,NULL,_IONBF,0); /*main loop*/ while(getip(in,host)) { if(STDOUT) printf("Trying %s:%d ..",host,port); fprintf(log,"Trying %s:%d ..",host,port); ERR= sbann(host, port, ban, timeout_banner, timeout_connect); if(ERR==1) { /* ok, there's an available banner :) */ if(STDOUT) printf("ok\n%s\n",ban); fprintf(log,"ok\n%s\n",ban); } else switch (ERR) { case -1: if(STDOUT) printf("err: -1\n"); fprintf(log,"-1\n"); break; case -2: if(STDOUT) printf("err: -2\n"); fprintf(log,"-2\n"); break; case -3: if(STDOUT) printf("err: -3\n"); fprintf(log,"-3\n"); break; case -4: if(STDOUT) printf("err: -4\n"); fprintf(log,"-4\n"); break; case -5: if(STDOUT) printf("err: -5\n"); fprintf(log,"-5\n"); break; default: printf("uh?\n"); } fflush(log); } if(STDOUT) printf("done.\n\n"); fprintf(log,"done. \nCTime:"); instime(log); fclose(in); fclose(log); return (1); }