Custom error type for parsing #11

Merged
mice_on_drugs merged 2 commits from parse-error-enum into master 2022-04-03 17:20:44 +02:00
Showing only changes of commit bc278b7d39 - Show all commits

View File

@ -38,6 +38,12 @@ pub enum DNSRCode {
NOTINZONE = 10, NOTINZONE = 10,
} }
#[derive(Debug)]
pub enum DNSParseErr {
DatagramLengthError,
SliceError(std::array::TryFromSliceError)
}
impl From<u16> for DNSRCode { impl From<u16> for DNSRCode {
fn from(val: u16) -> Self { fn from(val: u16) -> Self {
match val { match val {
@ -109,18 +115,14 @@ impl DNSHeader {
const OPCODE_OFFSET: u16 = 1; const OPCODE_OFFSET: u16 = 1;
const RCODE_OFFSET: u16 = 11; const RCODE_OFFSET: u16 = 11;
pub fn from_udp_datagram(datagram: &[u8]) -> Result<Self, &'static str> { pub fn from_udp_datagram(datagram: &[u8]) -> Result<Self, DNSParseErr> {
if datagram.len() < 11 { if datagram.len() < 11 {
return Err("Not enough data"); return Err(DNSParseErr::DatagramLengthError);
} }
let id = u16::from_be_bytes((&datagram[..2]).try_into().map_err(|_err| "Invalid id")?); let id = u16::from_be_bytes((&datagram[..2]).try_into()?);
let flags = u16::from_be_bytes( let flags = u16::from_be_bytes((&datagram[2..4]).try_into()?);
(&datagram[2..4])
.try_into()
.map_err(|_err| "Invalid flags")?,
);
let qr = (flags & DNSHeader::QR_MASK) != 0; let qr = (flags & DNSHeader::QR_MASK) != 0;
let opcode = DNSOpCode::from((flags & DNSHeader::OPCODE_MASK) >> DNSHeader::OPCODE_OFFSET); let opcode = DNSOpCode::from((flags & DNSHeader::OPCODE_MASK) >> DNSHeader::OPCODE_OFFSET);
let aa = (flags & DNSHeader::AA_MASK) != 0; let aa = (flags & DNSHeader::AA_MASK) != 0;
@ -131,26 +133,10 @@ impl DNSHeader {
let cd = (flags & DNSHeader::CD_MASK) != 0; let cd = (flags & DNSHeader::CD_MASK) != 0;
let rcode = DNSRCode::from((flags & DNSHeader::RCODE_MASK) >> DNSHeader::RCODE_OFFSET); let rcode = DNSRCode::from((flags & DNSHeader::RCODE_MASK) >> DNSHeader::RCODE_OFFSET);
let qd_zo_count = u16::from_be_bytes( let qd_zo_count = u16::from_be_bytes((&datagram[4..6]).try_into()?);
(&datagram[4..6]) let an_pr_count = u16::from_be_bytes((&datagram[6..8]).try_into()?);
.try_into() let ns_up_count = u16::from_be_bytes((&datagram[8..10]).try_into()?);
.map_err(|_err| "Invalid qd_zo_count")?, let ar_count = u16::from_be_bytes((&datagram[10..12]).try_into()?);
);
let an_pr_count = u16::from_be_bytes(
(&datagram[6..8])
.try_into()
.map_err(|_err| "Invalid an_pr_count")?,
);
let ns_up_count = u16::from_be_bytes(
(&datagram[8..10])
.try_into()
.map_err(|_err| "Invalid ns_up_count")?,
);
let ar_count = u16::from_be_bytes(
(&datagram[10..12])
.try_into()
.map_err(|_err| "Invalid ar_count")?,
);
Ok(DNSHeader { Ok(DNSHeader {
id, id,
@ -170,3 +156,9 @@ impl DNSHeader {
}) })
} }
} }
impl From<std::array::TryFromSliceError> for DNSParseErr {
fn from(err: std::array::TryFromSliceError) -> Self {
DNSParseErr::SliceError(err)
}
}