networking · intermediate · ~15 min · safe pentest lab
Bounds-safe label decoding with loop-proof refusal of pointers.
A DNS question name (QNAME) is stored as a series of length-prefixed labels: [len][bytes...][len][bytes...]... ending with a zero-length byte (0x00). Decode one from a packet byte buffer into a dotted string. The grader supplies fixed byte arrays — no DNS queries are sent.
Implement int parse_dns_qname(const uint8_t *pkt, size_t n, char *out, size_t cap) that decodes the QNAME at the start of pkt into a dotted name in out (e.g. www.example.com).
pkt, n: the packet bytes and the number of bytes available.out, cap: destination buffer and its capacity.Returns the number of bytes written to out (excluding the NUL terminator), or -1 on any error.
{3,'w','w','w', 7,'e','x','a','m','p','l','e', 3,'c','o','m', 0} -> 15, out="www.example.com"
{0} -> 0, out="" (root name)
{0xC0,0x0C} -> -1 (compression pointer rejected)
0x00) decodes to the empty string, returning 0.. between labels, but not before the first label.-1 on: NULL input, a label length that runs past n, output that would overflow cap, a missing 0x00 terminator, or a compression/reserved length byte (top two bits set, i.e. len & 0xC0). Compression pointers are refused because they can form decoding loops.Every DNS tool starts by decoding the label-encoded QNAME. Doing it safely means refusing compression pointers that could loop.
Packet bytes (pkt) and available length (n), plus an output buffer (out) with capacity (cap).
Returns the number of bytes written to out (excluding NUL), or -1 on any error.
Return -1 on NULL input, a label running past n, output overflow, missing 0x00 terminator, or a length byte with len & 0xC0 set (compression pointer).
#include <stdint.h>
#include <stddef.h>
int parse_dns_qname(const uint8_t *pkt, size_t n, char *out, size_t cap) {
/* TODO */
(void)pkt; (void)n; (void)out; (void)cap;
return -1;
}
Following compression pointers (can loop forever). Forgetting the inter-label dot. Reading past n.
Root name (single 0x00) → 0. Truncated label. Output too small.
O(n).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.