diff --git a/contrib/fspscan.c b/contrib/fspscan.c new file mode 100644 index 0000000..b58c2d9 --- /dev/null +++ b/contrib/fspscan.c @@ -0,0 +1,310 @@ +/* +This is an FSP port scanner that I wrote in late '92. It's not very fast, +but that was a limit of the original fver code (and of current versions +of fver). Just type "fspscan -h" to get help on how it's used. +My appologies for the nasty code...I just wanted something that worked. + + -Cuda +*/ +/* +I have ported it in September 2003 to modern C and added to FSP software +suite. Don't blame me for the code, i have not touched it. + + -Radim +*/ +/*********************************************************************\ +* Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu) * +* * +* You may copy or modify this file in any manner you wish, provided * +* that this notice is always included, and that you hold the author * +* harmless for any loss or damage resulting from the installation or * +* use of this software. * +\*********************************************************************/ + + +/**************************************************************** + * FindPort -- hack of fver to find valid ports on a FSP server * + * by Cuda. Yes, it's ugly, but it works for me. * + * Type "fspscan -h" to see how it is used. * + ****************************************************************/ + +#include "fspscan.h" +#include +#include +#include +#include +#include +#include + +char *host = NULL; +char *outputfile = NULL; +/* Default values */ +int localport = 9191; +int remoteport = 21; +int endport = 65535; +int retries = 3; +int client_trace = 0; + +static int myfd; +static struct sockaddr_in server_addr; +static unsigned short myseq = 0; +static unsigned short key; +int client_intr_state = 0; + +static struct sockaddr_in INET_ZERO; + +#define DSIZE (sizeof(int)*8) +#define SAVE(A) { int sav; sav = errno; A; errno = sav; } + +static void printhelp(int argc,char **argv) +{ + fprintf(stderr,"%s - an fsp port scanner\n",argv[0]); + fprintf(stderr,"Usage: %s [-h]\n",argv[0]); + fprintf(stderr," (prints this help screen)\n"); + fprintf(stderr," %s [-t][-o file][-r retries][-l local port][-i ip address][-p starting port][-e ending port]\n\n",argv[0]); + fprintf(stderr,"Defaults: (-o) file = stdout\n"); + fprintf(stderr," (-l) local port = 9191\n"); + fprintf(stderr," (-p) starting port = 21\n"); + fprintf(stderr," (-e) ending port = 65535\n"); + fprintf(stderr," (-r) retries = 3\n"); + fprintf(stderr," (-t) trace = off\n"); + fprintf(stderr," (-i) host-ip = none (host MUST be specified)\n"); + exit(0); +} + +static void fdclose(void) +{ + close(myfd); +} + +static void client_done(void) +{ + (void) client_interact(CC_BYE,0L,0,NULLP,0,NULLP); +} + +int main(int argc,char **argv) +{ + int i; + UBUF *ub; + FILE *logfile; + + while ((i = getopt(argc, argv, "htp:o:r:l:i:e:")) != EOF) { + switch(i) { + case 'h': + printhelp(argc, argv); + break; + case 't': + client_trace=1; + break; + case 'r': + retries=atoi(optarg); + break; + case 'p': + remoteport=atoi(optarg); + break; + case 'e': + endport=atoi(optarg); + break; + case 'l': + localport=atoi(optarg); + break; + case 'i': + host = (char *) malloc(strlen(optarg)+1); + strcpy(host, optarg); + break; + case 'o': + outputfile = (char *) malloc(strlen(optarg)+1); + strcpy(outputfile, optarg); + break; + case '?': + printhelp(argc, argv); + break; + default: + fprintf(stderr,"This error should not happen\n"); + } + } + + if (host == NULL) { + fprintf(stderr, "host/ip not specified, unable to continue\n"); + printhelp(argc, argv); + exit(-1); + } + + if (outputfile == NULL) { + logfile=stdout; + } else { + logfile=fopen(outputfile,"a+"); + } + + fprintf(logfile,"Scanning %s\n",host); + + for ( ; remoteport<=endport; ++remoteport) { + init_client(host,remoteport,localport); + signal(SIGINT,client_intr); + + ub = client_interact(CC_VERSION,0L, 0,NULLP, 0,NULLP); + if (ub) + /* success! */ + fprintf(logfile,"Found FSP ver: %s on port %0d\n", + ub->buf,remoteport); + else + fprintf(logfile,"%0d...nada\n",remoteport); + fflush(logfile); + fdclose(); + } + return 0; +} + + +UBUF *client_interact(cmd,pos,l1,p1,l2,p2) + unsigned cmd, l1, l2; + unsigned long pos; + unsigned char *p1, *p2; +{ + struct sockaddr_in from; + UBUF sbuf; + static UBUF rbuf; + unsigned char *s, *t, *d; + unsigned u, n, sum, mlen; + fd_set mask; + int retval, bytes, retry; + + sbuf.cmd = cmd; + sbuf.len = htons(l1); + sbuf.pos = htonl(pos); + + client_intr_state = 1; + FD_ZERO(&mask); + + for(u = l1, d = (unsigned char *) sbuf.buf; u--; *d++ = *p1++); + for(u = l2 ; u--; *d++ = *p2++); + mlen = d - (unsigned char *) &sbuf; + + for(retry = 0; retry < retries; retry++) { + sbuf.key = key; + sbuf.seq = myseq; + sbuf.sum = 0; + + for(t = (unsigned char *) &sbuf, sum = n = mlen; n--; sum += *t++); + sbuf.sum = sum + (sum >> 8); + if(client_trace && retry) + write(2,"R",1); + + if(sendto(myfd,&sbuf,mlen,0,(struct sockaddr*)&server_addr,sizeof(server_addr)) == -1) + { perror("sendto"); exit(1); } + FD_SET(myfd,&mask); + + while(1) { + retval = _x_select(&mask, 3000L); + + if((retval == -1) && (errno = EINTR)) continue; + + if(retval == 1) { /* an incoming message is waiting */ + bytes = sizeof(from); + if((bytes = recvfrom(myfd,(char*)&rbuf,sizeof(rbuf),0, + (struct sockaddr*)&from,&bytes)) < UBUF_HSIZE) continue; + + s = (unsigned char *) &rbuf; + d = s + bytes; + u = rbuf.sum; rbuf.sum = 0; + for(t = s, sum = 0; t < d; sum += *t++); + sum = (sum + (sum >> 8)) & 0xff; + if(sum != u) continue; /* wrong check sum */ + + rbuf.len = htons(rbuf.len); + rbuf.pos = htonl(rbuf.pos); + + if(rbuf.seq != myseq) continue; /* wrong seq # */ + if(rbuf.len+UBUF_HSIZE > bytes) continue; /* truncated. */ + + myseq++; key = rbuf.key; /* update seq and keys. */ + + if(client_intr_state == 2) { client_done(); exit(1); } + + return(&rbuf); + + } else break; /* go back to re-transmit buffer again */ + } + } + /* return NULL if there have been too many retries - ffindport hack */ + return(NULL); +} + + +void init_client(char *myhost,int port,int myport) +{ + if((myfd = _x_udp(&myport)) == -1) + { perror("socket open"); exit(1); } + + if(_x_adr(myhost,port,&server_addr) == -1) + { perror("server addr"); exit(1); } +} + + +void client_intr(int sig) +{ + switch(client_intr_state) { + case 0: exit(2); + case 1: client_intr_state = 2; break; + case 2: exit(3); + } +} + + +int _x_udp(int *port) +{ + int f, len, zz; + struct sockaddr_in me ; + struct sockaddr_in sin; + + me = sin = INET_ZERO; + + me.sin_port = htons((unsigned short) *port); + me.sin_family = AF_INET; + + if((f=socket(AF_INET,SOCK_DGRAM,0)) == -1) return(-1); + + if( setsockopt(f,SOL_SOCKET,SO_REUSEADDR,&zz,sizeof(zz)) < 0 || + bind(f,(struct sockaddr *) &me,(len = sizeof(me))) < 0 || + getsockname(f,(struct sockaddr*)&sin,&len) < 0) + { SAVE(((void) close(f))); return(-1); } + if(!*port) *port = ntohs((unsigned short) sin.sin_port); return(f); +} + +int _x_adr(char *host,int port,struct sockaddr_in *his) +{ + char myhost[128]; + struct hostent *H; + int i; + char *s, *d; + + *his = INET_ZERO; + if(!host) (void) gethostname(host = myhost,sizeof(myhost)); + + if((his->sin_addr.s_addr = inet_addr(host)) != INADDR_NONE) { + his->sin_family = AF_INET; + } else + if(H = gethostbyname(host)) { + for(s = (char *)H->h_addr, + d = (char *)&his->sin_addr, + i = H->h_length; i--; *d++ = *s++); + his->sin_family = H->h_addrtype; + } else return(-1); + his->sin_port = htons((unsigned short) port); + + return(0); +} + +int _x_select(fd_set *rf, long tt) /* tt is in unit of ms */ +{ + struct timeval timeout; + + if(tt != -1) + { + timeout.tv_sec = tt / 1000; + timeout.tv_usec = (tt % 1000)*1000; + return(select(DSIZE, rf, NULL, NULL, &timeout)); + } + + return(select(DSIZE, rf, NULL, NULL, (struct timeval *) 0)); +}