Open / Closed / Refused Port Scanner (Synchronous, Single-Threaded)
Description
This is a simple TCP port scanner written in C.
It performs synchronous scanning (no multithreading) and checks ports sequentially.
The program:
- Resolves a host using
getaddrinfo()
- Iterates through a range of ports
- Attempts a TCP connection
- Reports:
- Open ports
- Closed (refused) ports
- Other connection failures and error codes
Build
Compile using gcc:
Usage
Example:
Source Code
// LIBC header for I/O fprintf()
#include <stdio.h>
// LIBC header for memory control and error handling
#include <stdlib.h>
// LIBC header for string manipulation functionality memset()
#include <string.h>
// POSIX header for protocol definitions for getaddrinfo(), struct addrinfo, gai_strerror()
#include <netdb.h>
// POSIX header for handling numerical IP addresses for inet_ntop()
#include <arpa/inet.h>
// POSIX header for socket definitions for struct sockaddr_in
#include <sys/socket.h>
// POSIX header for miscellaneous symbolic constants and types like NULL
#include <unistd.h>
// POSIX header for error number definitions for errno
#include <errno.h>
// POSIX header for fixed width integer types for uint16_t
#include <stdint.h>
int main(int argc, char **argv) {
// check if an argument was passed for host
if (argc != 2) {
fprintf(stderr, "Usage: %s <host domain>\n", argv[0]);
return EXIT_FAILURE;
}
/*
* hint: hints of the type of address or format we expect
* res: linked list iterator
* res0: linked list head of all found responses
*/
struct addrinfo hint, *res, *res0;
int error; // return code holder for getaddrinfo()
memset(&hint, 0, sizeof(hint));
// set our hints:
hint.ai_family = AF_INET; // IPv4
hint.ai_protocol = IPPROTO_TCP; // TCP protocol
// attempt to retrieve linked list of resolutions
error = getaddrinfo(argv[1], NULL, &hint, &res0);
if (error) {
fprintf(stderr, "Error: %s\n", gai_strerror(error));
return EXIT_FAILURE;
}
// iterate through linked list
for (res = res0; res; res = res->ai_next) {
char ip_str[INET_ADDRSTRLEN];
// cast to sockaddr_in
struct sockaddr_in *psockaddr =
(struct sockaddr_in *)res->ai_addr;
if (inet_ntop(psockaddr->sin_family,
&(psockaddr->sin_addr),
ip_str,
sizeof(ip_str)) == NULL) {
fprintf(stderr, "Failed to convert IP to string!\n");
continue;
}
// Cycle through ports
for (uint16_t port = 4990; port <= 65535; port++) {
// Set port
psockaddr->sin_port = htons(port);
// Create socket
int fd = socket(res->ai_family,
res->ai_socktype,
res->ai_protocol);
if (fd == -1) continue;
// Attempt connection
int rc = connect(fd, res->ai_addr, res->ai_addrlen);
if (rc == 0) {
printf("Connection open %s:%u\n", ip_str, port);
} else {
int saved_errno = errno;
if (saved_errno == ECONNREFUSED) {
printf("Connection closed %s:%u (refused)\n",
ip_str, port);
} else {
printf("Connection failed %s:%u (errno=%d)\n",
ip_str, port, saved_errno);
}
}
close(fd);
}
}
// free dynamically allocated memory
freeaddrinfo(res0);
return 0;
}
Notes
- Single-threaded → slow for large scans.
- Uses blocking
connect().
- IPv4 only (
AF_INET).
Open / Closed / Refused Port Scanner (Synchronous, Single-Threaded)
Description
This is a simple TCP port scanner written in C.
It performs synchronous scanning (no multithreading) and checks ports sequentially.
The program:
getaddrinfo()Build
Compile using
gcc:Usage
Example:
Source Code
Notes
connect().AF_INET).