Skip to content

Commit

Permalink
decode dns class properly (#635)
Browse files Browse the repository at this point in the history
* decode dns class properly
  • Loading branch information
dmachard authored Mar 4, 2024
1 parent 6371fa0 commit 06c9293
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 71 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ The [`_integration`](./docs/_integration) folder contains DNS-collector `configu

## Performance

Tuning may be neccesary to deal with a large traffic loads.
Tuning may be necessary to deal with a large traffic loads.
Please refer to the [performance tuning](./docs/performance.md) guide if needed.

## Contributing
Expand Down
5 changes: 3 additions & 2 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ global:
# - protocol: protocol UDP, TCP
# - length: the length of the query or reply in bytes
# - length-unit: the length of the query or reply in bytes with unit
# - qtype: dns qtype
# - qname: dns qname
# - qtype: dns query type
# - qname: dns query name
# - qclass: dns query class
# - latency: computed latency between queries and replies
# - answercount: the number of answer
# - ttl: answer ttl, only the first one value
Expand Down
41 changes: 33 additions & 8 deletions dnsutils/dns_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ const DNSLen = 12
const UNKNOWN = "UNKNOWN"

var (
Class = map[int]string{
1: "IN",
3: "CH",
4: "HS",
254: "NONE",
255: "ANY",
}
Rdatatypes = map[int]string{
0: "NONE",
1: "A",
Expand Down Expand Up @@ -124,6 +131,7 @@ var ErrDecodeDNSLabelTooShort = errors.New("malformed pkt, dns payload too short
var ErrDecodeQuestionQtypeTooShort = errors.New("malformed pkt, not enough data to decode qtype")
var ErrDecodeDNSAnswerTooShort = errors.New("malformed pkt, not enough data to decode answer")
var ErrDecodeDNSAnswerRdataTooShort = errors.New("malformed pkt, not enough data to decode rdata answer")
var ErrDecodeQuestionQclassTooShort = errors.New("malformed pkt, not enough data to decode qclass")

func RdatatypeToString(rrtype int) string {
if value, ok := Rdatatypes[rrtype]; ok {
Expand All @@ -139,6 +147,13 @@ func RcodeToString(rcode int) string {
return UNKNOWN
}

func ClassToString(class int) string {
if value, ok := Class[class]; ok {
return value
}
return UNKNOWN
}

// error returned if decoding of DNS packet payload fails.
type decodingError struct {
part string
Expand Down Expand Up @@ -273,14 +288,15 @@ func DecodePayload(dm *DNSMessage, header *DNSHeader, config *pkgconfig.Config)
var payloadOffset int
// decode DNS question
if header.Qdcount > 0 {
dnsQname, dnsRRtype, offsetrr, err := DecodeQuestion(header.Qdcount, dm.DNS.Payload)
dnsQname, dnsRRtype, dnsQclass, offsetrr, err := DecodeQuestion(header.Qdcount, dm.DNS.Payload)
if err != nil {
dm.DNS.MalformedPacket = true
return &decodingError{part: "query", err: err}
}

dm.DNS.Qname = dnsQname
dm.DNS.Qtype = RdatatypeToString(dnsRRtype)
dm.DNS.Qclass = ClassToString(dnsQclass)
payloadOffset = offsetrr
}

Expand Down Expand Up @@ -358,10 +374,11 @@ DNS QUESTION
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
func DecodeQuestion(qdcount int, payload []byte) (string, int, int, error) {
func DecodeQuestion(qdcount int, payload []byte) (string, int, int, int, error) {
offset := DNSLen
var qname string
var qtype int
var qclass int

for i := 0; i < qdcount; i++ {
// the specification allows more than one query in DNS packet,
Expand All @@ -373,18 +390,26 @@ func DecodeQuestion(qdcount int, payload []byte) (string, int, int, error) {
// Decode QNAME
qname, offset, err = ParseLabels(offset, payload)
if err != nil {
return "", 0, 0, err
return "", 0, 0, 0, err
}

// decode QTYPE and support invalid packet, some abuser sends it...
if len(payload[offset:]) < 4 {
return "", 0, 0, ErrDecodeQuestionQtypeTooShort
if len(payload[offset:]) < 2 {
return "", 0, 0, 0, ErrDecodeQuestionQtypeTooShort
} else {
qtype = int(binary.BigEndian.Uint16(payload[offset : offset+2]))
offset += 4
offset += 2
}

// decode QCLASS
if len(payload[offset:]) < 2 {
return "", 0, 0, 0, ErrDecodeQuestionQclassTooShort
} else {
qclass = int(binary.BigEndian.Uint16(payload[offset : offset+2]))
offset += 2
}
}
return qname, qtype, offset, nil
return qname, qtype, qclass, offset, nil
}

/*
Expand Down Expand Up @@ -461,7 +486,7 @@ func DecodeAnswer(ancount int, startOffset int, payload []byte) ([]DNSAnswer, in
a := DNSAnswer{
Name: name,
Rdatatype: rdatatype,
Class: int(class),
Class: ClassToString(int(class)),
TTL: int(ttl),
Rdata: parsed,
}
Expand Down
Loading

0 comments on commit 06c9293

Please sign in to comment.