/* Dinko Korunic, kreator@fly.srk.fer.hr Wed Nov 22 18:19:16 CET 2000 This program is under GPL licence. Host port connection timer developed for magazine Mreza */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Solaris compatibility tweak */ #ifndef INADDR_NONE # define INADDR_NONE ((unsigned long)-1) #endif #define MAXLINE 1 /* How much bytes to read from host */ #define MAXHOSTNAME 256 /* How long can hostname be */ /* #define MOREPRECISE /* Do measuring in msecs or just secs */ /* Connect to host. Return -1 on error, socket fd on success */ int connecthost(char *hostname, unsigned int port) { struct sockaddr_in servaddr; struct hostent *hostptr; struct in_addr ip; int socketfd, flags, option=1; memset(&servaddr, 0, sizeof(servaddr)); if (hostname==NULL) return -1; ip.s_addr=inet_addr(hostname); if (ip.s_addr!=INADDR_NONE) hostptr=NULL; else if ((hostptr=gethostbyname(hostname))!=NULL) memcpy(&ip.s_addr, hostptr->h_addr_list[0], hostptr->h_length); if (hostptr) { servaddr.sin_family=hostptr->h_addrtype; servaddr.sin_addr.s_addr=ip.s_addr; } else { if (ip.s_addr==INADDR_NONE) return -1; servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=ip.s_addr; } if ((socketfd=socket(servaddr.sin_family, SOCK_STREAM, 0))==-1) { perror("Cannot open socket stream"); exit(EXIT_FAILURE); } if ((flags=fcntl(socketfd, F_GETFL, 0))==-1) { perror("Cannot make read socket flags"); exit(EXIT_FAILURE); } if (fcntl(socketfd, F_SETFL, flags|O_NONBLOCK)==-1) { perror("Cannot make socket nonblocking"); exit(EXIT_FAILURE); } if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char *)&option, sizeof(option))==-1) perror("Cannot set socket reusable"); servaddr.sin_port=htons(port); if (connect(socketfd, (struct sockaddr *)&servaddr, sizeof(servaddr))==-1) if (errno!=EINPROGRESS) { perror("Error connecting to host"); close(socketfd); return -1; } return socketfd; } /* Read data from host and time it. Returns -1 on error or seconds elapsed on success */ int readhost(char *hostname, unsigned int port, struct timeval *etime) { int socketfd; char inbuf[MAXLINE]; struct timeval time1, time2; gettimeofday(&time1, NULL); if ((socketfd=connecthost(hostname, port))>=0) { memset(inbuf, 0, sizeof(inbuf)); if (read(socketfd, inbuf, MAXLINE-1)==-1) return -1; gettimeofday(&time2, NULL); } else return -1; close(socketfd); time2.tv_sec-=time1.tv_sec; time2.tv_usec-=time1.tv_usec; *etime=time2; return 0; } /* Loop reading from input files */ int main(int argc, char **argv) { char usage[]="There should be 2 arguments:\n" "name of input file and name of output file.\n" "Input file should be like: servername port\n", myhostname[MAXHOSTNAME]; time_t mytime=time(NULL); int myport; struct timeval etime; FILE *myinput, *myoutput; if (argc!=3) { fputs(usage, stderr); exit(EXIT_FAILURE); } if ((myinput=fopen(argv[1], "r"))==NULL) { perror("Cannot open input file"); exit(EXIT_FAILURE); } umask(077); if ((myoutput=fopen(argv[2], "a"))==NULL) { perror("Cannot open output file"); exit(EXIT_FAILURE); } fprintf(myoutput, "Statistics on %s", ctime(&mytime)); while (fscanf(myinput, "%s %d", myhostname, &myport)!=EOF) { if (readhost(myhostname, myport, &etime)!=-1) fprintf(myoutput, "%s:%d - %ld %s\n", myhostname, myport, (etime.tv_usec<0)?etime.tv_sec:etime.tv_usec, (etime.tv_usec<0)?"sec":"usec"); else fprintf(myoutput, "%s:%d - unreachable\n", myhostname, myport); } fclose(myinput); fclose(myoutput); return EXIT_SUCCESS; }