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 } }