cybersecurity · intermediate · ~12 min · safe pentest lab

Parse the 20-byte header of an IQ-samples capture

Mixed u32/u64 little-endian binary parsing with a magic check.

Challenge

Your job

Implement:

#include <stdint.h>
#include <stddef.h>
typedef struct {
    uint32_t sample_rate_hz;
    uint64_t center_freq_hz;
    uint32_t sample_count;
} iq_hdr_t;

int parse_iq_header(const uint8_t *buf, size_t n, iq_hdr_t *out);

Layout (20 bytes):

0..3   magic "IQHD"
4..7   sample_rate_hz   (u32 LE)
8..15  center_freq_hz   (u64 LE)
16..19 sample_count     (u32 LE)

Return 0 on valid magic + n >= 20. Return -1 on NULL inputs, n < 20, or wrong magic.

Hints

  1. (concept) Build the u64 with eight shifts, or two u32 reads combined via ((uint64_t)hi << 32) | lo.
  2. (common bug) Casting (uint64_t *)(buf + 8) — alignment-unsafe.

Why this matters

The same alignment-safe binary-parse discipline you used on pcap and ELF works here on a different fixture format.

Input format

A byte buffer of at least 20 bytes + the output struct pointer.

Output format

0 on success, -1 otherwise. Struct fields filled only on success.

Constraints

No pointer casts; build integers from bytes.

Starter code

#include <stdint.h>
#include <stddef.h>
typedef struct {
    uint32_t sample_rate_hz;
    uint64_t center_freq_hz;
    uint32_t sample_count;
} iq_hdr_t;
int parse_iq_header(const uint8_t *buf, size_t n, iq_hdr_t *out) {
    /* TODO */
    (void)buf; (void)n; (void)out;
    return -1;
}

Common mistakes

Using (uint64_t *) casts. Forgetting to memcmp the magic. n bound off-by-one.

Edge cases to handle

Maximum u64 value. Magic mismatch with otherwise valid sizes.

Complexity

O(1).

Background lessons

Up next

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