#include #include #include #include #include #include #include #include #include #include #include #include #include int ConnectWithTimeout( int I__socket, struct sockaddr *address, size_t addressSize, int I__timeoutSeconds ) { int rCode=0; fd_set Write; unsigned long iMode; int fdCnt; struct timeval timeout = { .tv_sec = I__timeoutSeconds, .tv_usec = 0 }; /** Set the I__socket in non-blocking. **/ iMode = 1; errno = 0; if((-1) == ioctl(I__socket, FIONBIO, &iMode)) { rCode=errno; fprintf(stderr, "ioctlsocket() failed. errno[%d]\n", errno); goto CLEANUP; } /** Commence connection attempt. **/ errno=0; if((-1) == connect(I__socket, address, addressSize)) { rCode=errno; switch(rCode) { case EINPROGRESS: rCode=0; break; default: fprintf(stderr, "connect() failed. errno[%d, %s]\n", errno, sys_errlist[errno]); goto CLEANUP; } } /** Wait for connection or timeout. **/ do { /** Zero fdSet, then add caller's 'I__socket'. **/ FD_ZERO(&Write); FD_SET(I__socket, &Write); /** Wait... **/ errno=0; fdCnt=select(I__socket+1, NULL, &Write, NULL, &timeout); switch(fdCnt) { case (-1): rCode=errno; fprintf(stderr, "select() failed. errno[%d]\n", errno); goto CLEANUP; case 0: rCode=ETIME; goto CLEANUP; default: break; } } while(!FD_ISSET(I__socket, &Write)); CLEANUP: /** Return the I__socket to blocking mode. **/ if(iMode) { iMode = 0; errno = 0; if((-1) == ioctl(I__socket, FIONBIO, &iMode)) { rCode=errno; fprintf(stderr, "ioctlsocket() failed. errno[%d]\n", errno); goto CLEANUP; } } return(rCode); } int main(int argc, char **argv) { int rCode = 0; int sd = (-1); int start = 52; /* DNS port is 53 */ int end = 55; struct hostent *hostaddr; struct sockaddr_in servaddr; int port; /** Resolve the host name to an IP address. **/ h_errno=0; hostaddr = gethostbyname("8.8.8.8"); /* Google DNS server */ if(NULL == hostaddr) { printf("gethostbyname() failed. h_errno[%d]\n", h_errno); goto CLEANUP; } /** Port-scan. **/ for(port = start; port <= end; port++) { sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if((-1) == sd) { perror("Socket()\n"); rCode=errno; goto CLEANUP; } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); memcpy(&servaddr.sin_addr, hostaddr->h_addr, hostaddr->h_length); /** Attempt connection with timeout. **/ rCode=ConnectWithTimeout(sd, (struct sockaddr *)&servaddr, sizeof(servaddr), 1); switch(rCode) { case 0: printf("Port %d is open.\n", port); break; case ETIME: printf("Port %d is closed.\n", port); rCode=0; break; default: printf("ConnectWithTimeout() failed. rCode[%d]\n", rCode); close(sd); goto CLEANUP; } close(sd); sd=(-1); } CLEANUP: if((-1) != sd) close(sd); return(rCode); }