networking · intermediate · ~12 min · safe pentest lab

Localhost port checker (open/closed)

Probe one TCP port on localhost using the same pattern a sysadmin uses to check 'is my service up'.

Challenge

Write a tiny diagnostic helper that answers one question about your own machine: is something listening on 127.0.0.1:port? It is just socket() + connect() — if the connection succeeds, a listener is there.

Task

Implement int is_port_open(int port) that tries to connect to 127.0.0.1:port and reports the result.

Input

One int port — the loopback port to probe.

Output

Returns:

  • 1 — a TCP listener is on 127.0.0.1:port (the connect succeeded).
  • 0 — the port is refused (ECONNREFUSED; no listener).
  • -1 — a real error (for example, the socket could not be created).

Example

is_port_open(port_with_a_listener)   ->   1
is_port_open(1)                       ->   0   (nothing listening; refused)

Edge cases

  • ECONNREFUSED is the explicit "no listener" signal: return 0.
  • Any other errno is a real error: return -1.
  • Save errno before calling close() (close can overwrite it).
  • Close the socket on every code path, including success.

Rules

  • Hard-code 127.0.0.1 inside the function. There is no host parameter — the function is structurally incapable of probing third-party hosts.

Why this matters

The simplest 'is it alive?' check. Hard-coded to loopback so it's structurally incapable of misuse.

Input format

One integer port number to probe on 127.0.0.1.

Output format

1 (open), 0 (refused/no listener), or -1 (real error).

Constraints

Hard-code 127.0.0.1 (no host parameter). Distinguish ECONNREFUSED (return 0) from other errors (return -1). Close the fd on every code path.

Starter code

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int is_port_open(int port) {
    /* TODO */
    return -1;
}

Common mistakes

Leaking the fd. Treating every -1 as 'closed' instead of distinguishing ECONNREFUSED from real errors. Adding a host parameter (defeats the safety design).

Edge cases to handle

Port 1 / port 65535 boundaries. A port that is open AND immediately closes the connection. Errno being clobbered by close() — save it first.

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.