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}