cybersecurity · intermediate · ~18 min · safe pentest lab

Detect port scanners in a connection log

Per-key fan-out counting over a text log.

Challenge

Find the port scanners in a connection log — sources that fan out across many distinct destination ports.

Task

Implement int count_scanners(const char *log, int threshold) that returns how many source IPs connected to more than threshold distinct destination ports.

Input

  • log: a NUL-terminated, newline-separated string of "<src_ip> <dst_port>" lines, baked into the harness.
  • threshold: the distinct-port count an IP must exceed to be flagged (strictly greater than).

Bounded for this exercise: at most 64 distinct IPs, 128 distinct ports each.

Output

Returns int: the number of source IPs whose count of distinct ports is > threshold. Returns 0 for an empty or NULL log.

Example

log: 10.0.0.5 hits ports 22,23,80,443,8080; 10.0.0.9 hits 80,80; 10.0.0.7 hits 21,22
count_scanners(log, 3)    ->   1   (only 10.0.0.5, with 5 distinct ports)
count_scanners(log, 1)    ->   2   (10.0.0.5 and 10.0.0.7)
count_scanners(log, 10)   ->   0
count_scanners(NULL, 3)   ->   0

Edge cases

  • A repeated (ip, port) pair counts the port only once.
  • The threshold is exclusive — an IP with exactly threshold distinct ports is not counted.
  • Empty or NULL log returns 0.

Rules

  • Static buffer only — no live network traffic.

Why this matters

A host that touches many distinct ports in a short window is the classic port-scan signature. Counting fan-out per source IP is the detection.

Input format

A NUL-terminated newline-separated "<src_ip> <dst_port>" log and an integer threshold.

Output format

An int: the count of source IPs touching more than threshold distinct ports (0 if none/NULL).

Constraints

Distinct ports per IP; threshold is exclusive; static buffer only; <=64 IPs, <=128 ports each.

Starter code

int count_scanners(const char *log, int threshold) {
    /* TODO */
    (void)log; (void)threshold;
    return 0;
}

Common mistakes

Counting repeated (ip,port) pairs more than once. Off-by-one on the threshold (it's exclusive).

Edge cases to handle

Empty log. Duplicate lines. An IP exactly at the threshold (not counted).

Complexity

O(lines × distinct-ports).

Background lessons

Up next

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