MCPcopy
hub / github.com/google/gopacket / DecodeFromBytes

Method DecodeFromBytes

layers/dns.go:304–392  ·  view source on GitHub ↗

DecodeFromBytes decodes the slice into the DNS struct.

(data []byte, df gopacket.DecodeFeedback)

Source from the content-addressed store, hash-verified

302
303// DecodeFromBytes decodes the slice into the DNS struct.
304func (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
305 d.buffer = d.buffer[:0]
306
307 if len(data) < 12 {
308 df.SetTruncated()
309 return errDNSPacketTooShort
310 }
311
312 // since there are no further layers, the baselayer's content is
313 // pointing to this layer
314 d.BaseLayer = BaseLayer{Contents: data[:len(data)]}
315 d.ID = binary.BigEndian.Uint16(data[:2])
316 d.QR = data[2]&0x80 != 0
317 d.OpCode = DNSOpCode(data[2]>>3) & 0x0F
318 d.AA = data[2]&0x04 != 0
319 d.TC = data[2]&0x02 != 0
320 d.RD = data[2]&0x01 != 0
321 d.RA = data[3]&0x80 != 0
322 d.Z = uint8(data[3]>>4) & 0x7
323 d.ResponseCode = DNSResponseCode(data[3] & 0xF)
324 d.QDCount = binary.BigEndian.Uint16(data[4:6])
325 d.ANCount = binary.BigEndian.Uint16(data[6:8])
326 d.NSCount = binary.BigEndian.Uint16(data[8:10])
327 d.ARCount = binary.BigEndian.Uint16(data[10:12])
328
329 d.Questions = d.Questions[:0]
330 d.Answers = d.Answers[:0]
331 d.Authorities = d.Authorities[:0]
332 d.Additionals = d.Additionals[:0]
333
334 offset := 12
335 var err error
336 for i := 0; i < int(d.QDCount); i++ {
337 var q DNSQuestion
338 if offset, err = q.decode(data, offset, df, &d.buffer); err != nil {
339 return err
340 }
341 d.Questions = append(d.Questions, q)
342 }
343
344 // For some horrible reason, if we do the obvious thing in this loop:
345 // var r DNSResourceRecord
346 // if blah := r.decode(blah); err != nil {
347 // return err
348 // }
349 // d.Foo = append(d.Foo, r)
350 // the Go compiler thinks that 'r' escapes to the heap, causing a malloc for
351 // every Answer, Authority, and Additional. To get around this, we do
352 // something really silly: we append an empty resource record to our slice,
353 // then use the last value in the slice to call decode. Since the value is
354 // already in the slice, there's no WAY it can escape... on the other hand our
355 // code is MUCH uglier :(
356 for i := 0; i < int(d.ANCount); i++ {
357 d.Answers = append(d.Answers, DNSResourceRecord{})
358 if offset, err = d.Answers[i].decode(data, offset, df, &d.buffer); err != nil {
359 d.Answers = d.Answers[:i] // strip off erroneous value
360 return err
361 }

Callers 4

decodeDNSFunction · 0.95
BenchmarkDecodeDNSLayerFunction · 0.95
TestDNSDoesNotMallocFunction · 0.95
TestDNSPacketWriteAnswerFunction · 0.95

Calls 4

decodeMethod · 0.95
DNSOpCodeTypeAlias · 0.85
DNSResponseCodeTypeAlias · 0.85
SetTruncatedMethod · 0.65

Tested by 3

BenchmarkDecodeDNSLayerFunction · 0.76
TestDNSDoesNotMallocFunction · 0.76
TestDNSPacketWriteAnswerFunction · 0.76