/* tcping does a nonblocking connect to test if a port is reachable.
* Its exit codes are:* -1 an error occured
* 0 port is open
* 1 port is closed
* 2 user timeout
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <fcntl.h>
#include <arpa/inet.h>
#define SRV_IP "8.8.8.8"
#define SRV_PORT 53
int main (int argc, char *argv[]) {
int sockfd;
struct sockaddr_in addr;
int error = 0;
int errlen;
int ret;
struct timeval timeout;
fd_set fdrset, fdwset;
timeout.tv_sec=10;
timeout.tv_usec=0;
if((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0){
printf("socket error.\n");
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(SRV_PORT);
if(inet_pton(AF_INET,SRV_IP,&addr.sin_addr) < 0){
printf("inet_pton error.\n");
close(sockfd);
return -1;
}
fcntl(sockfd, F_SETFL, O_NONBLOCK);
if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) != 0) {
if (errno != EINPROGRESS) {
printf("%s\n", strerror(errno));
return (-1);
}
FD_ZERO(&fdrset);
FD_SET(sockfd, &fdrset);
fdwset=fdrset;
if ((ret = select(sockfd+1, &fdrset, &fdwset, NULL, &timeout)) == 0) {
close(sockfd);
printf( "timeout.\n");
return(2);
}
if (FD_ISSET(sockfd, &fdrset) || FD_ISSET(sockfd, &fdwset)) {
errlen = sizeof(error);
if ((ret=getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &errlen)) != 0) {
printf( "getsockopt error.\n");
close(sockfd);
return(-1);
}
if (error != 0) {
printf( "closed.\n");
close(sockfd);
return(1);
}
} else {
printf("select: sockfd not set\n");
close(sockfd);
return(-1);
}
}
printf("connection established.\n ");
close(sockfd);
return 0;
}