// DNS message header (RFC 1035 section 4.1.1).
///|
pub struct Header {
id : UInt16
flags : UInt16
qdcount : UInt16
ancount : UInt16
nscount : UInt16
arcount : UInt16
}
///|
pub let flag_qr : UInt16 = 0x8000
///|
pub let flag_tc : UInt16 = 0x0200
///|
pub let flag_rd : UInt16 = 0x0100
///|
pub let flag_ra : UInt16 = 0x0080
///|
pub let flag_aa : UInt16 = 0x0400
///|
pub fn Header::encode(self : Header) -> Array[Byte] {
let buf = Array::make(dns_header_size, (0).to_byte())
ignore(wire_put_u16(buf, 0, self.id))
ignore(wire_put_u16(buf, 2, self.flags))
ignore(wire_put_u16(buf, 4, self.qdcount))
ignore(wire_put_u16(buf, 6, self.ancount))
ignore(wire_put_u16(buf, 8, self.nscount))
ignore(wire_put_u16(buf, 10, self.arcount))
buf
}
///|
pub fn decode_header(
bytes : Array[Byte],
offset? : Int = 0,
) -> Result[(Header, Int), String] {
match wire_check_range(bytes, offset, dns_header_size) {
Err(err) => Err("DNS header: " + err)
Ok(_) => {
let (id, o1) = match wire_get_u16(bytes, offset) {
Ok(value) => value
Err(err) => return Err("DNS header: " + err)
}
let (flags, o2) = match wire_get_u16(bytes, o1) {
Ok(value) => value
Err(err) => return Err("DNS header: " + err)
}
let (qdcount, o3) = match wire_get_u16(bytes, o2) {
Ok(value) => value
Err(err) => return Err("DNS header: " + err)
}
let (ancount, o4) = match wire_get_u16(bytes, o3) {
Ok(value) => value
Err(err) => return Err("DNS header: " + err)
}
let (nscount, o5) = match wire_get_u16(bytes, o4) {
Ok(value) => value
Err(err) => return Err("DNS header: " + err)
}
let (arcount, o6) = match wire_get_u16(bytes, o5) {
Ok(value) => value
Err(err) => return Err("DNS header: " + err)
}
Ok(({ id, flags, qdcount, ancount, nscount, arcount }, o6))
}
}
}
///|
fn Header::is_response(self : Header) -> Bool {
(self.flags & flag_qr) != 0
}
///|
fn Header::is_truncated(self : Header) -> Bool {
(self.flags & flag_tc) != 0
}
///|
fn Header::rcode(self : Header) -> Int {
(self.flags & mask_rcode).to_int()
}
///|
fn Header::opcode(self : Header) -> UInt16 {
(self.flags & mask_opcode) >> 11
}