Skip to content
Name Compression Decoder
step 1/5

Reading — step 1 of 5

Read

~2 min readDNS Wire Format

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 bitsmeaningRFC
00regular label (length < 64)§4.1.4
11pointer§4.1.4
01, 10reserved (do not use)§4.1.4

Decoding rules

  1. Read length byte. If 0 → end of name.
  2. If (byte & 0xC0) == 0xC0 → it's a pointer. Read next byte, compute the 14-bit offset, jump to it.
  3. After jumping, you keep reading labels (and possibly more pointers) until you hit \x00.
  4. 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. Read 0C → offset 0x000C = 12
  • jump to 12, decode example.com normally
  • terminator → done. Return name "www.example.com", next position 31 (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…