cybersecurity · intermediate · ~15 min · safe pentest lab

Count open ports in a saved nmap XML dump

Walk a static XML buffer with string functions and count specific tags.

Challenge

Count the open ports in a saved nmap XML dump — defenders read scan output far more often than they run scans.

Task

Implement int count_open_ports(const char *xml) that returns how many <port ...> elements are open (their inner <state state="open"/>). Skip closed and filtered ports.

Input

  • xml: a NUL-terminated string holding saved nmap XML, baked into the harness. It is never live nmap output.

Output

Returns a non-negative int: the number of open ports.

Example

"" -> 0
one open port -> 1
two open + one filtered -> 2

Edge cases

  • Empty string, or no <port> tags, returns 0.
  • All ports closed/filtered returns 0.
  • Malformed XML: count what you can and return — do not treat it as fatal.

Rules

  • Pure string parsing — no XML library, no allocation.
  • Bound the state="open" look-ahead by the next <port so a later open port can't be credited to an earlier filtered one. Match the closing quote so state="open|filtered" does not count.
  • Operate only on the buffer; never read past the NUL.

Why this matters

Defenders read scan output far more often than they run scans. A 20-line strstr walker is the canonical way to do it.

Input format

A NUL-terminated XML string.

Output format

A non-negative int — the count.

Constraints

No allocation. No XML library. Pure scan.

Starter code

#include <stddef.h>
#include <string.h>

int count_open_ports(const char *xml) {
    /* TODO */
    (void)xml;
    return 0;
}

Common mistakes

Matching state="open as a substring (catches "open|filtered"). Forgetting to bound the look-ahead.

Edge cases to handle

Empty string. No <port> tags. All closed/filtered. Malformed (unclosed tag) — count what you can.

Complexity

O(n) — single pass.

Background lessons

Up next

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