testing-debugging · advanced · ~15 min

Fault-Tolerant Protocol Parser Harness

Implement robust binary packet header parsing with bounds checking and integrity verification.

Challenge

Binary protocol parsers face corrupt, truncated, and malicious input packets. A defensive parser validates magic markers, minimum length, payload bounds, and computes a checksum before trusting packet fields.

Your Task

Given the packet format:

  • Offset 0: uint8_t magic (Must equal 0xAA)
  • Offset 1: uint8_t version (Must equal 1)
  • Offset 2..3: uint16_t payload_len (Network byte order / Big Endian)
  • Offset 4..5: uint16_t checksum (Simple additive 16-bit sum of all preceding 4 header bytes)
  • Offset 6+: Payload bytes
typedef struct {
    uint8_t version;
    uint16_t payload_len;
    const uint8_t *payload;
} DecodedPacket;

Implement:

int parse_network_packet(const uint8_t *data, size_t len, DecodedPacket *out);

Rules

  1. If data == NULL, out == NULL, or len < 6, return -1.
  2. If data[0] != 0xAA or data[1] != 1, return -1.
  3. Decode payload_len = ((uint16_t)data[2] << 8) | data[3].
  4. If 6 + (size_t)payload_len > len, return -1 (packet truncated).
  5. Checksum check: expected checksum = data[0] + data[1] + data[2] + data[3]. Decoded checksum is ((uint16_t)data[4] << 8) | data[5]. If they do not match, return -1.
  6. On success: populate out->version = 1, out->payload_len = payload_len, out->payload = data + 6, and return 0.

Example

uint8_t pkt[] = {0xAA, 0x01, 0x00, 0x03, 0x00, 0xAE, 'A', 'B', 'C'};
DecodedPacket p;
parse_network_packet(pkt, sizeof(pkt), &p); // returns 0, p.payload_len == 3

Input format

data: pointer to raw packet bytes; len: total buffer length; out: pointer to destination DecodedPacket.

Output format

Returns 0 on valid verified packet; -1 on corruption or truncation.

Constraints

Zero heap allocations. Zero-copy payload reference.

Starter code

#include <stddef.h>
#include <stdint.h>

typedef struct {
    uint8_t version;
    uint16_t payload_len;
    const uint8_t *payload;
} DecodedPacket;

/* Parse packet with magic 0xAA, version 1, and 16-bit header checksum. */
int parse_network_packet(const uint8_t *data, size_t len, DecodedPacket *out) {
    (void)data; (void)len; (void)out;
    return -1;
}

Common mistakes

Buffer overflow when payload_len exceeds packet length; endianness decoding bugs.

Edge cases to handle

len < 6 returns -1; payload_len == 0 succeeds if checksum matches; invalid magic or checksum fails.

Background lessons

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