dns_message_parser/decode/
dns.rsuse crate::decode::Decoder;
use crate::{DecodeError, DecodeResult, Dns, Flags, Opcode, RCode, MAXIMUM_DNS_PACKET_SIZE};
use std::convert::TryFrom;
impl<'a, 'b: 'a> Decoder<'a, 'b> {
fn flags(&mut self) -> DecodeResult<Flags> {
let buffer = self.u8()?;
let qr = (buffer & 0b1000_0000) != 0;
let opcode = (buffer & 0b0111_1000) >> 3;
let opcode = match Opcode::try_from(opcode) {
Ok(opcode) => opcode,
Err(buffer) => return Err(DecodeError::Opcode(buffer)),
};
let aa = (buffer & 0b0000_0100) != 0;
let tc = (buffer & 0b0000_0010) != 0;
let rd = (buffer & 0b0000_0001) != 0;
let buffer = self.u8()?;
let ra = (buffer & 0b1000_0000) != 0;
let z = buffer & 0b0100_0000;
if z != 0 {
return Err(DecodeError::ZNotZeroes(z));
}
let ad = (buffer & 0b0010_0000) != 0;
let cd = (buffer & 0b0001_0000) != 0;
let rcode = buffer & 0b0000_1111;
match RCode::try_from(rcode) {
Ok(rcode) => Ok(Flags {
qr,
opcode,
aa,
tc,
rd,
ra,
ad,
cd,
rcode,
}),
Err(buffer) => Err(DecodeError::RCode(buffer)),
}
}
}
impl<'a, 'b: 'a> Decoder<'b, 'b> {
fn dns(&'a mut self) -> DecodeResult<Dns> {
if self.offset != 0 {
return Err(DecodeError::Offset(self.offset));
}
let bytes_len = self.bytes.len();
if bytes_len < 12 {
return Err(DecodeError::NotEnoughBytes(bytes_len, 12));
} else if bytes_len > MAXIMUM_DNS_PACKET_SIZE {
return Err(DecodeError::DnsPacketTooBig(bytes_len));
}
let id = self.u16()?;
let flags = self.flags()?;
let question_count = self.u16()?;
let answer_count = self.u16()?;
let authority_count = self.u16()?;
let additional_count = self.u16()?;
let mut questions = Vec::with_capacity(question_count as usize);
for _ in 0..question_count {
questions.push(self.question()?);
}
let mut answers = Vec::with_capacity(answer_count as usize);
for _ in 0..answer_count {
answers.push(self.rr()?);
}
let mut authorities = Vec::with_capacity(authority_count as usize);
for _ in 0..authority_count {
authorities.push(self.rr()?);
}
let mut additionals = Vec::with_capacity(additional_count as usize);
for _ in 0..additional_count {
additionals.push(self.rr()?);
}
let is_finished = self.is_finished()?;
let dns = Dns {
id,
flags,
questions,
answers,
authorities,
additionals,
};
if is_finished {
Ok(dns)
} else {
Err(DecodeError::RemainingBytes(self.offset, dns))
}
}
}
impl_decode!(Flags, flags);
impl_decode!(Dns, dns);