a go dns packet parser
1package magna 2 3import "encoding/binary" 4 5// Decode decodes the header from the bytes. 6func (h *Header) Decode(buf []byte, offset int) (int, error) { 7 var err error 8 h.ID, offset, err = getU16(buf, offset) 9 if err != nil { 10 return len(buf), err 11 } 12 13 flags, offset, err := getU16(buf, offset) 14 if err != nil { 15 return len(buf), err 16 } 17 18 h.QDCount, offset, err = getU16(buf, offset) 19 if err != nil { 20 return len(buf), err 21 } 22 23 h.ANCount, offset, err = getU16(buf, offset) 24 if err != nil { 25 return len(buf), err 26 } 27 28 h.NSCount, offset, err = getU16(buf, offset) 29 if err != nil { 30 return len(buf), err 31 } 32 33 h.ARCount, offset, err = getU16(buf, offset) 34 if err != nil { 35 return len(buf), err 36 } 37 38 h.QR = ((flags >> 15) & 0x01) == 1 39 h.OPCode = OPCode((flags >> 11) & 0x0F) 40 h.AA = ((flags >> 10) & 0x01) == 1 41 h.TC = ((flags >> 9) & 0x01) == 1 42 h.RD = ((flags >> 8) & 0x01) == 1 43 h.RA = ((flags >> 7) & 0x01) == 1 44 h.Z = uint8((flags >> 4) & 0x07) 45 h.RCode = RCode((flags & 0x0F)) 46 47 return offset, nil 48} 49 50// Encode encodes the header packet to the byte representation. 51func (h *Header) Encode() []byte { 52 bytes := make([]byte, 0, 12) 53 54 bytes = binary.BigEndian.AppendUint16(bytes, h.ID) 55 56 var flags uint16 57 if h.QR { 58 flags |= 1 << 15 59 } 60 61 flags |= uint16(h.OPCode) << 11 62 63 if h.AA { 64 flags |= 1 << 10 65 } 66 67 if h.TC { 68 flags |= 1 << 9 69 } 70 71 if h.RD { 72 flags |= 1 << 8 73 } 74 75 if h.RA { 76 flags |= 1 << 7 77 } 78 79 flags |= uint16(h.Z) << 4 80 flags |= uint16(h.RCode) 81 82 bytes = binary.BigEndian.AppendUint16(bytes, flags) 83 bytes = binary.BigEndian.AppendUint16(bytes, h.QDCount) 84 bytes = binary.BigEndian.AppendUint16(bytes, h.ANCount) 85 bytes = binary.BigEndian.AppendUint16(bytes, h.NSCount) 86 bytes = binary.BigEndian.AppendUint16(bytes, h.ARCount) 87 88 return bytes 89}