#if !defined(NAPC_MAGIC_h)
	#define NAPC_MAGIC_h

	#include <libnapc.h>

	#include <napc-panic/napc-panic.h>

	typedef uint32_t napc_init_magic;

	#define NAPC_MAGIC_MEMBER napc_init_magic _init_magic

	#define NAPC_MAGIC_DESTROYED NAPC_U32_LITERAL(0xFFFFFFFF)

	#define NAPC_MAGIC_INIT(type, obj) (obj)->_init_magic = (NAPC_MAGIC_ ## type)
	#define NAPC_MAGIC_DESTROY(obj) (obj)->_init_magic = NAPC_MAGIC_DESTROYED

	// Used to silence -Waddress warnings
	#define PV_NAPC_MAGIC_GET_VALUE(obj) \
		((void *)(obj) != NULL ? (obj)->_init_magic : 0)

	#define NAPC_MAGIC_ASSERT(type, obj)                                   \
		do {                                                               \
			const napc_init_magic actual   = PV_NAPC_MAGIC_GET_VALUE(obj); \
			const napc_init_magic expected = (NAPC_MAGIC_ ## type);        \
			if (actual == NAPC_MAGIC_DESTROYED) {                          \
				NAPC_PANIC("Attempt to use destroyed " # type);            \
			} else if (actual != expected) {                               \
				NAPC_PANIC("Detected uninitialized " # type);              \
#include <module/dns/_private/_dns.h>

bool napc_DNS_parseRequest(
	napc__DNSRequest *out,
	const void *buffer, napc_size buffer_size
) {
	napc__DNSHeader header;

	if (!napc_DNS_parseHeader(&header, buffer, buffer_size)) {
		return false;
	}

	napc__Reader reader;
	napc_Reader_init(&reader, buffer, buffer_size);

	// skip DNS header we just read
	if (!napc_Reader_readU8Array(&reader, 12, NULL)) return false;

	if (header.question_count != 1) {
		PV_NAPC_DNS_WARNING(
			"Request contains other than 1 question (%d questions).", header.question_count
		);

		return false;
	}

	// question count capped at max 1
	napc__DNSQuery *q = out ? &out->query : NULL;

	if (!PV_napc_DNS_parseQuerySection(q, &reader)) {
		return false;
	}

	if (out) {
		memcpy(&out->header, &header, sizeof(header));
	}

	return true;
}

Run, Test & Debug on Linux. Deploy on Arduino.

Jump right in!