Documentation
¶
Overview ¶
Package dnsdecode parses DNS messages on the wire — the most-traffic-bearing UDP protocol on the internet and a staple of every blue-team / red-team / network-debugging workflow.
Wrap-vs-native judgement ¶
Native. DNS is defined by RFC 1035 + a long tail of supporting RFCs (1996 NOTIFY, 2136 UPDATE, 2671/6891 EDNS, 4034/4035 DNSSEC, 6844 CAA, 6698 TLSA, 9460 SVCB/HTTPS, etc.). The wire format is a 12-byte header + four length-prefixed section lists, with RR data dispatched on a 16-bit type. Name compression uses 14-bit pointers (top 2 bits set on the length byte). Pasting a hex blob from Wireshark / tshark / a dig +short capture is enough — no key material, no cryptography, no live network attach.
What this package covers ¶
- DNS header (RFC 1035 §4.1.1): transaction ID, flag fields broken out as QR (query/response), Opcode (QUERY/IQUERY/STATUS/NOTIFY/UPDATE), AA (authoritative answer), TC (truncation), RD (recursion desired), RA (recursion available), AD (authentic data, DNSSEC), CD (checking disabled, DNSSEC), and RCODE (NOERROR / FORMERR / SERVFAIL / NXDOMAIN / NOTIMP / REFUSED / YXDOMAIN / YXRRSET / NXRRSET / NOTAUTH / NOTZONE / plus EDNS extended RCODEs).
- Section counts: QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT.
- Question section (RFC 1035 §4.1.2): QNAME with compression pointer resolution, QTYPE, QCLASS.
- RR sections with type-specific decode for the common types operators care about:
- A (1) — 4-byte IPv4.
- NS (2) — owner-domain name.
- CNAME (5) — canonical name.
- SOA (6) — primary NS, RNAME, serial, refresh, retry, expire, minimum.
- PTR (12) — domain name (reverse-DNS).
- MX (15) — preference + exchange.
- TXT (16) — list of <character-string>s.
- AAAA (28) — 16-byte IPv6 in canonical colon form.
- SRV (33) — priority + weight + port + target.
- OPT (41, EDNS) — UDP-size from class field, extended RCODE + version + DO flag from TTL field, and per-option [code, length, raw data].
- DNSKEY (48) — flags + protocol + algorithm + key data hex; key-tag (RFC 4034 Appx B) when computable.
- DS (43) — key tag + algorithm + digest type + digest hex.
- CAA (257, RFC 6844) — flags + tag + value (plus the well-known tags issue / issuewild / iodef / contactemail / contactphone).
- Name decompression with pointer-chain max-depth guard to defeat the classic pointer-loop denial-of-service.
- RCODE / Opcode / RR type / RR class lookup tables.
What this package does NOT cover (deliberately out of scope) ¶
- DNSSEC signature validation (RRSIG / NSEC / NSEC3 walk) — RRSIG records are surfaced with type-covered and key-tag fields but the signature blob is exposed as base64; cryptographic validation is a separate iteration that needs a trust-anchor store.
- TLSA (52) and SVCB/HTTPS (64/65) — well-defined but usage is still niche; future Spec when real captures surface.
- LOC (29), NAPTR (35), URI (256), and the long-tail experimental types — the type code is named but the RDATA is surfaced as raw hex.
- DNS-over-HTTPS / DNS-over-TLS / DNS-over-QUIC framing — those wrap the same DNS message on the wire, so callers feed the inner message here.
- Multi-message reassembly for TCP (the 2-byte length prefix used by TCP DNS) — operators are expected to strip the prefix before passing the message body.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CAAData ¶
type CAAData struct {
Flags int `json:"flags"`
IsCritical bool `json:"is_critical"`
Tag string `json:"tag"`
Value string `json:"value"`
}
CAAData is the type-257 RDATA per RFC 6844.
type DNSKEYData ¶
type DNSKEYData struct {
Flags int `json:"flags"`
IsKSK bool `json:"is_ksk"`
IsZSK bool `json:"is_zsk"`
Protocol int `json:"protocol"`
Algorithm int `json:"algorithm"`
AlgorithmName string `json:"algorithm_name"`
KeyTag int `json:"key_tag"`
PublicKeyHex string `json:"public_key_hex"`
}
DNSKEYData is the type-48 RDATA.
type DSData ¶
type DSData struct {
KeyTag int `json:"key_tag"`
Algorithm int `json:"algorithm"`
AlgorithmName string `json:"algorithm_name"`
DigestType int `json:"digest_type"`
DigestTypeName string `json:"digest_type_name"`
DigestHex string `json:"digest_hex"`
}
DSData is the type-43 RDATA.
type Flags ¶
type Flags struct {
QR int `json:"qr"`
QRName string `json:"qr_name"`
Opcode int `json:"opcode"`
OpcodeName string `json:"opcode_name"`
AuthAnswer bool `json:"authoritative_answer"`
Truncation bool `json:"truncation"`
RecursionDesired bool `json:"recursion_desired"`
RecursionAvail bool `json:"recursion_available"`
AuthenticData bool `json:"authentic_data"`
CheckingDisabled bool `json:"checking_disabled"`
RCode int `json:"rcode"`
RCodeName string `json:"rcode_name"`
}
Flags is the broken-out DNS header flag bits.
type Message ¶
type Message struct {
HexInput string `json:"hex_input"`
TransactionID int `json:"transaction_id"`
Flags *Flags `json:"flags"`
QDCount int `json:"qdcount"`
ANCount int `json:"ancount"`
NSCount int `json:"nscount"`
ARCount int `json:"arcount"`
Questions []*Question `json:"questions,omitempty"`
Answers []*Record `json:"answers,omitempty"`
Authority []*Record `json:"authority,omitempty"`
Additional []*Record `json:"additional,omitempty"`
}
Message is the decoded view of a DNS packet.
func DecodeBytes ¶
DecodeBytes parses a raw DNS message.
type OPTData ¶
type OPTData struct {
UDPSize int `json:"udp_size"`
ExtendedRCode int `json:"extended_rcode"`
Version int `json:"version"`
DOFlag bool `json:"do_flag"`
Options []OPTOption `json:"options,omitempty"`
}
OPTData is the type-41 RDATA: EDNS pseudo-RR. UDP size + extended RCODE/version/DO are pulled out of the class + TTL fields per RFC 6891.
type OPTOption ¶
type OPTOption struct {
Code int `json:"code"`
Name string `json:"name"`
Length int `json:"length"`
DataHex string `json:"data_hex,omitempty"`
}
OPTOption is one EDNS option [code, length, raw hex].
type Question ¶
type Question struct {
Name string `json:"name"`
Type int `json:"type"`
TypeName string `json:"type_name"`
Class int `json:"class"`
ClassName string `json:"class_name"`
}
Question is one entry in the question section.
type Record ¶
type Record struct {
Name string `json:"name"`
Type int `json:"type"`
TypeName string `json:"type_name"`
Class int `json:"class"`
ClassName string `json:"class_name"`
TTL uint32 `json:"ttl,omitempty"`
RDataLength int `json:"rdata_length"`
RDataHex string `json:"rdata_hex,omitempty"`
// Type-specific decoded fields. Only one of these is
// populated per record; the others are empty.
IPv4 string `json:"ipv4,omitempty"`
IPv6 string `json:"ipv6,omitempty"`
Target string `json:"target,omitempty"`
TextRecords []string `json:"text_records,omitempty"`
MX *MXData `json:"mx,omitempty"`
SOA *SOAData `json:"soa,omitempty"`
SRV *SRVData `json:"srv,omitempty"`
OPT *OPTData `json:"opt,omitempty"`
DNSKEY *DNSKEYData `json:"dnskey,omitempty"`
DS *DSData `json:"ds,omitempty"`
CAA *CAAData `json:"caa,omitempty"`
}
Record is one resource record. Only the field that matches the type is populated; everything else is RDataHex.
type SOAData ¶
type SOAData struct {
PrimaryNS string `json:"primary_ns"`
ResponsibleName string `json:"responsible_name"`
Serial uint32 `json:"serial"`
RefreshSec uint32 `json:"refresh_sec"`
RetrySec uint32 `json:"retry_sec"`
ExpireSec uint32 `json:"expire_sec"`
MinimumSec uint32 `json:"minimum_sec"`
}
SOAData is the type-6 RDATA: zone authority.