a go dns packet parser
1package magna 2 3import ( 4 "encoding/binary" 5 "fmt" 6) 7 8// Decode decodes a question from buf at the offset 9func (q *Question) Decode(buf []byte, offset int) (int, error) { 10 var err error 11 q.QName, offset, err = decodeDomain(buf, offset) 12 if err != nil { 13 return offset, fmt.Errorf("question decode: failed to decode QName: %w", err) 14 } 15 16 qtype, offset, err := getU16(buf, offset) 17 if err != nil { 18 return offset, fmt.Errorf("question decode: failed to decode QType for %s: %w", q.QName, err) 19 } 20 21 qclass, offset, err := getU16(buf, offset) 22 if err != nil { 23 return offset, fmt.Errorf("question decode: failed to decode QClass for %s: %w", q.QName, err) 24 } 25 26 q.QType = DNSType(qtype) 27 q.QClass = DNSClass(qclass) 28 return offset, nil 29} 30 31// Encode serializes a Question into bytes, using a map to handle domain name compression offsets. 32func (q *Question) Encode(bytes []byte, offsets *map[string]uint16) ([]byte, error) { 33 var err error 34 bytes, err = encodeDomain(bytes, q.QName, offsets) 35 if err != nil { 36 return nil, fmt.Errorf("question encode: failed to encode QName %s: %w", q.QName, err) 37 } 38 39 bytes = binary.BigEndian.AppendUint16(bytes, uint16(q.QType)) 40 bytes = binary.BigEndian.AppendUint16(bytes, uint16(q.QClass)) 41 return bytes, nil 42}