Reading — step 1 of 5
Read
Name Compression Decoder
DNS messages are usually < 512 bytes (UDP). To keep them small, RFC 1035 §4.1.4 specifies name compression: any name suffix that has appeared earlier in the message can be replaced with a 2-byte pointer.
Pointer encoding
A pointer starts with the top two bits set:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 1 1| OFFSET |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
The remaining 14 bits are an absolute byte-offset from the start of the message. Detection rule:
if (byte & 0xC0) == 0xC0: # 0b11000000 == top 2 bits set
pointer = ((byte & 0x3F) << 8) | next_byte
The four label-type combinations:
| top 2 bits | meaning | RFC |
|---|---|---|
00 | regular label (length < 64) | §4.1.4 |
11 | pointer | §4.1.4 |
01, 10 | reserved (do not use) | §4.1.4 |
Decoding rules
- Read length byte. If
0→ end of name. - If
(byte & 0xC0) == 0xC0→ it's a pointer. Read next byte, compute the 14-bit offset, jump to it. - After jumping, you keep reading labels (and possibly more pointers) until you hit
\x00. - Stop when you hit the terminator; the message position you return to the caller is the position after the original pointer, not after the followed name.
Loop detection
A malicious or buggy message can have pointers that cycle. RFC requires resolvers to bound work — typically by recording visited offsets and rejecting on revisit.
Worked example
Build a DNS response that contains example.com at offset 12 and www.example.com at offset 25:
00..11 12-byte header
12..24 07 'e' 'x' 'a' 'm' 'p' 'l' 'e' 03 'c' 'o' 'm' 00 ; full name
25..30 03 'w' 'w' 'w' C0 0C ; "www" + pointer to 12
Decoding at offset 25:
- read
03→ label length 3, read "www" - read
C0→ pointer marker. Read0C→ offset 0x000C = 12 - jump to 12, decode
example.comnormally - terminator → done. Return name
"www.example.com", next position31(after the 2-byte pointer, NOT after the dereferenced name).
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…