@@ -39,7 +39,7 @@ func (d *DNSMessage) String() string {
3939 d .AuthorityRRs ,
4040 d .AdditionalRRs ,
4141 len (d .payload ),
42- d .queries (),
42+ d .rrecords (),
4343 )
4444}
4545
@@ -147,67 +147,97 @@ func bytesToStr(myBytes []byte) string {
147147 return unsafe .String (unsafe .SliceData (myBytes ), len (myBytes ))
148148}
149149
150- func extractDomain (data []byte , offset int ) (string , int ) {
151- var parts [] string
150+ func extractDomain (data []byte , tail [] byte ) (string , [] byte ) {
151+ var domainName string
152152 for {
153- blen := int (data [offset ])
154- offset ++
155- if blen == 0 {
153+ blen := tail [0 ]
154+ if blen >> 6 == 0b11 {
155+ offset := binary .BigEndian .Uint16 (tail [0 :2 ])& (1 << 14 - 1 ) - headerSizeDNS
156+ part , _ := extractDomain (data , data [offset :])
157+ domainName += part
158+ tail = tail [2 :]
156159 break
157160 }
158- if blen == 0xc0 {
159- offset = int (data [offset ]) - headerSizeDNS
160- blen = int (data [offset ])
161- offset ++
161+ tail = tail [1 :]
162+ if blen == 0 {
163+ break
162164 }
163- parts = append (parts , bytesToStr (data [offset :offset + blen ]))
164- offset += blen
165+ domainName += bytesToStr (tail [0 :blen ])
166+ domainName += "."
167+
168+ tail = tail [blen :]
165169 }
166- return strings . Join ( parts , "." ), offset
170+ return domainName , tail
167171}
168172
169- func (d * DNSMessage ) queries () string {
170- var (
171- sb strings.Builder
172- offset int
173- )
173+ func (d * DNSMessage ) rrecords () string {
174+ var sb strings.Builder
175+ tail := d .payload
174176 if d .Questions > 0 {
175177 sb .WriteString ("- Queries:\n " )
176178 for range d .Questions {
177179 var domain string
178- domain , offset = extractDomain (d .payload , offset )
179- typ := binary .BigEndian .Uint16 (d .payload [offset : offset + 2 ])
180- offset += 2
181- class := binary .BigEndian .Uint16 (d .payload [offset : offset + 2 ])
182- offset += 2
180+ domain , tail = extractDomain (d .payload , tail )
181+ typ := binary .BigEndian .Uint16 (tail [0 :2 ])
182+ class := binary .BigEndian .Uint16 (tail [2 :4 ])
183+ tail = tail [4 :]
183184 // TODO: add type and class description https://en.wikipedia.org/wiki/List_of_DNS_record_types
184185 sb .WriteString (fmt .Sprintf (" %s: type %d class %d\n " , domain , typ , class ))
185186 }
186187 }
187188 if d .AnswerRRs > 0 {
188189 sb .WriteString ("- Answers:\n " )
189190 for range d .AnswerRRs {
190- no := binary .BigEndian .Uint16 (d .payload [offset : offset + 2 ])
191- offset += 2
192- domain , _ := extractDomain (d .payload , int (no & 0xFF )- headerSizeDNS )
193- typ := binary .BigEndian .Uint16 (d .payload [offset : offset + 2 ])
194- offset += 2
195- class := binary .BigEndian .Uint16 (d .payload [offset : offset + 2 ])
196- offset += 2
197- ttl := binary .BigEndian .Uint32 (d .payload [offset : offset + 4 ])
198- offset += 4
199- rdl := int (binary .BigEndian .Uint16 (d .payload [offset : offset + 2 ]))
200- offset += 2
191+ var domain string
192+ domain , tail = extractDomain (d .payload , tail )
193+ typ := binary .BigEndian .Uint16 (tail [0 :2 ])
194+ class := binary .BigEndian .Uint16 (tail [2 :4 ])
195+ ttl := binary .BigEndian .Uint32 (tail [4 :8 ])
196+ rdl := int (binary .BigEndian .Uint16 (tail [8 :10 ]))
201197 //rdata := d.payload[offset : offset+rdl]
202- offset += rdl
203- sb .WriteString (fmt .Sprintf (" %s: type %d class %d ttl %d rdl %d \n " , domain , typ , class , ttl , rdl ))
198+ tail = tail [ 10 + rdl :]
199+ sb .WriteString (fmt .Sprintf (" %s: type %d class %d ttl %08x rdl %04x \n " , domain , typ , class , ttl , rdl ))
204200 }
205201 }
206202 if d .AuthorityRRs > 0 {
207-
203+ sb .WriteString ("- Authoritative nameservers:\n " )
204+ for range d .AuthorityRRs {
205+ var domain string
206+ domain , tail = extractDomain (d .payload , tail )
207+ typ := binary .BigEndian .Uint16 (tail [0 :2 ])
208+ class := binary .BigEndian .Uint16 (tail [2 :4 ])
209+ ttl := binary .BigEndian .Uint32 (tail [4 :8 ])
210+ rdl := int (binary .BigEndian .Uint16 (tail [8 :10 ]))
211+ //rdata := d.payload[offset : offset+rdl]
212+ tail = tail [10 + rdl :]
213+ sb .WriteString (fmt .Sprintf (" %s: type %d class %d ttl %d rdl %d\n " , domain , typ , class , ttl , rdl ))
214+ }
208215 }
209216 if d .AdditionalRRs > 0 {
217+ sb .WriteString ("- Additional records:\n " )
218+ for range d .AdditionalRRs {
219+ if tail [0 ] != 0 {
220+ var domain string
221+ domain , tail = extractDomain (d .payload , tail )
222+ typ := binary .BigEndian .Uint16 (tail [0 :2 ])
223+ class := binary .BigEndian .Uint16 (tail [2 :4 ])
224+ ttl := binary .BigEndian .Uint32 (tail [4 :8 ])
225+ rdl := int (binary .BigEndian .Uint16 (tail [8 :10 ]))
226+ //rdata := d.payload[offset : offset+rdl]
227+ tail = tail [10 + rdl :]
228+ sb .WriteString (fmt .Sprintf (" %s: type %d class %d ttl %d rdl %d\n " , domain , typ , class , ttl , rdl ))
229+ } else {
230+ tail = tail [1 :]
231+ typ := binary .BigEndian .Uint16 (tail [0 :2 ])
232+ ups := binary .BigEndian .Uint16 (tail [2 :4 ])
233+ t1 := tail [4 ]
234+ zres := binary .BigEndian .Uint16 (tail [5 :7 ])
235+ rdl := int (binary .BigEndian .Uint16 (tail [7 :9 ]))
236+ tail = tail [9 + rdl :]
237+ sb .WriteString (fmt .Sprintf (" Root: type %d UDP payload size %d t1 %d zres %d rdl %d\n " , typ , ups , t1 , zres , rdl ))
238+ }
210239
240+ }
211241 }
212242 return sb .String ()
213243}
0 commit comments