summaryrefslogtreecommitdiff
path: root/internal/dns/header.go
blob: 15355007aa6e95c30d85635b637b34452471e352 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package dns

// https://datatracker.ietf.org/doc/html/rfc5395
type Header struct {
	ID      uint16
	Flags   uint16
	QDCount uint16
	ANCount uint16
	NSCount uint16
	ARCount uint16
}

// https://datatracker.ietf.org/doc/html/rfc2929#section-2
// Flags has 16-bit Field. Each hexadecima value below indicates
// which items are active.
// Example 0 0000 0 0 0 0 000 0 0 000, so if only AA is active, then
// Example 1 0000 0 0 0 0 000 0 0 000, is 0x8000
// Query and Response
func (h *Header) QR() bool { return h.Flags&0x8000 != 0 }

// Opcode has 4-bit (14 -- 11)
func (h *Header) OpCode() uint8 { return uint8((h.Flags >> 11) & 0xF) }

// Authoritative Answer
func (h *Header) AA() bool { return h.Flags&0x0400 != 0 }

// Truncation
func (h *Header) TC() bool { return h.Flags&0x0200 != 0 }

// Recursion Desired
func (h *Header) RD() bool { return h.Flags&0x0100 != 0 }

// Recursion Available
func (h *Header) RA() bool { return h.Flags&0x0080 != 0 }

// Mutator Flags
func (h *Header) SetQR(v bool) { h.set(0x8000, v) }
func (h *Header) SetOpCode(v uint8) {
	h.Bits = (h.Bits &^ (0xF << 11)) |
		((uint16(v) & 0xF) << 11)
}
func (h *Header) SetAA(v bool) { h.set(0x0400, v) }
func (h *Header) SetTC(v bool) { h.set(0x0200, v) }
func (h *Header) SetRD(v bool) { h.set(0x0100, v) }
func (h *Header) SetRA(v bool) { h.set(0x0080, v) }
func (h *Header) SetZ(v uint8) { h.Bits = (h.Bits &^ 0xF) | (uint16(v) & 0xF) << 4) }
func (h *Header) SetAD(v bool) { h.set(0x0020, v) }
func (h *Header) SetCD(v bool) { h.set(0x0010, v) }
func (h *Header) SetRCode(v uint8)  { h.Bits = (h.Bits &^ 0xF) | (uint16(v) & 0xF) }

func (h *Header) set(mask uint16, v bool) {
    if v {
        h.Bits |= mask
    } else {
        h.Bits &^= mask
    }
}