cybersecurity · intermediate · ~15 min · safe pentest lab

Count suspicious IPs in a sample log

Walk a text buffer line by line, group by a key, count occurrences, and threshold the result.

Challenge

Count the noisy source IPs in an access-log buffer — the first move in any brute-force or scanner sweep.

Task

Implement int suspicious_ip_count(const char *log, int threshold) that returns how many distinct source IPs appear at least threshold times in log.

Input

  • log: a NUL-terminated, multi-line string of Common-Log-Format-style lines. Each line begins with an IP, then a space, then the rest of the line. The grader passes a fixed buffer baked into the harness.
  • threshold: minimum request count for an IP to be flagged (counted with >=).

Output

Returns a non-negative int: the number of distinct IPs whose appearance count meets or exceeds threshold.

Example

log has 10.0.0.1 x3, 10.0.0.2 x1, 10.0.0.3 x1
suspicious_ip_count(log, 3)   ->   1   (only 10.0.0.1)
suspicious_ip_count(log, 1)   ->   3   (all three)
suspicious_ip_count(log, 5)   ->   0

Edge cases

  • Empty buffer returns 0.
  • A line with no space is skipped.
  • An IP exactly at the threshold counts.
  • Each distinct IP is counted once toward the result, no matter how often it appears.

Rules

  • Operate only on the buffer the grader passes — no file or network I/O.

Why this matters

The same five-line function is the heart of every brute-force-detection tool ever written. Get it right once and you've defended a thousand servers.

Input format

A NUL-terminated multi-line string log and an integer threshold.

Output format

A non-negative int: the count of distinct IPs appearing at least threshold times.

Constraints

Static buffer only — no file or network I/O.

Starter code

#include <stdio.h>
#include <string.h>

int suspicious_ip_count(const char *log, int threshold) {
    /* TODO: count distinct source IPs that appear at least `threshold` times. */
    return 0;
}

Common mistakes

Re-scanning the whole table for every line and accidentally adding duplicate rows. Forgetting the terminating \n is optional on the last line. Reading past the end of the buffer when the IP is at the very end without a space.

Edge cases to handle

Empty log. A single line without a trailing newline. An IP repeated more than sizeof tab[0].ip characters (malformed input — skip it).

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