Custom error type for parsing #11
48
src/proto.rs
48
src/proto.rs
@ -109,18 +109,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, DNSParseError> {
|
||||||
if datagram.len() < 11 {
|
if datagram.len() < 11 {
|
||||||
return Err("Not enough data");
|
return Err(DNSParseError::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 +127,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 +150,15 @@ impl DNSHeader {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DNSParseError {
|
||||||
|
DatagramLengthError,
|
||||||
|
SliceError(std::array::TryFromSliceError)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::array::TryFromSliceError> for DNSParseError {
|
||||||
|
fn from(err: std::array::TryFromSliceError) -> Self {
|
||||||
|
DNSParseError::SliceError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user