cybersecurity · intermediate · ~15 min · safe pentest lab

Read the 24-byte pcap global header

Bounds-checked, alignment-safe binary parsing of a fixed-size header.

Challenge

Your job

Implement:

#include <stdint.h>
#include <stddef.h>
typedef struct {
    uint32_t magic;
    uint16_t version_major;
    uint16_t version_minor;
    int32_t  thiszone;
    uint32_t sigfigs;
    uint32_t snaplen;
    uint32_t linktype;
} pcap_hdr_t;

int read_pcap_header(const uint8_t *buf, size_t n, pcap_hdr_t *out);

Read the 24-byte header in little-endian (assume host = little-endian).

Return 0 if the magic equals 0xa1b2c3d4 and n >= 24, -1 otherwise (including NULL inputs).

Rules

  • Build each integer byte-by-byte with shifts. Do NOT cast (uint32_t *)buf — alignment-unsafe.
  • Read no bytes past buf[n-1].

Hints

  1. (concept) u32 = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24).
  2. (common bug) Treating thiszone as unsigned. It is signed (can be negative for some captures).
  3. (direction) A tiny helper static uint32_t rd32(const uint8_t *b) keeps the offsets readable.

Why this matters

Every forensic walk through a packet trace starts here. Read 24 bytes, validate the magic, classify the link type.

Input format

A const byte buffer of at least 24 bytes representing a pcap file's global header.

Output format

0 on valid magic, -1 otherwise. Struct fields filled on success.

Constraints

No pointer casts. No reads past n. Magic must be 0xa1b2c3d4.

Starter code

#include <stdint.h>
#include <stddef.h>
typedef struct {
    uint32_t magic;
    uint16_t version_major;
    uint16_t version_minor;
    int32_t  thiszone;
    uint32_t sigfigs;
    uint32_t snaplen;
    uint32_t linktype;
} pcap_hdr_t;

int read_pcap_header(const uint8_t *buf, size_t n, pcap_hdr_t *out) {
    /* TODO */
    (void)buf; (void)n; (void)out;
    return -1;
}

Common mistakes

Casting (uint32_t *)buf (alignment-unsafe). Forgetting the n >= 24 bound. Treating thiszone as unsigned.

Edge cases to handle

n exactly 24 (just fits). thiszone negative. NULL pointers.

Complexity

O(1) — fixed 24-byte read.

Background lessons

Up next

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