diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 77cf33d..112fb8a 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -251,6 +251,17 @@ mod test { 0x80, 0x00, 0x40, 0xc0, 0x60, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0xc0, 0x60, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08, ], + vec![ + 0x56, 0x48, 0x81, 0xa0, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x66, 0x6c, 0x61, 0x72, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, + 0x00, 0x41, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x41, 0x00, 0x01, 0x00, 0x00, 0x06, 0xd8, + 0x00, 0x3d, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x06, 0x02, 0x68, 0x33, 0x02, 0x68, + 0x32, 0x00, 0x04, 0x00, 0x08, 0x68, 0x10, 0x84, 0xe5, 0x68, 0x10, 0x85, 0xe5, 0x00, + 0x06, 0x00, 0x20, 0x26, 0x06, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x68, 0x10, 0x84, 0xe5, 0x26, 0x06, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x68, 0x10, 0x85, 0xe5, 0x00, 0x00, 0x29, 0x04, 0xd0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + ], ]; for input in inputs.iter() { diff --git a/src/parser/rdata/https.rs b/src/parser/rdata/https.rs new file mode 100644 index 0000000..399d519 --- /dev/null +++ b/src/parser/rdata/https.rs @@ -0,0 +1,48 @@ +use crate::{ParserError, Qname}; +use std::net::Ipv6Addr; + +#[derive(Debug)] +pub struct Record { + pub svc_priority: u16, + pub target_name: String, + pub svc_params: Vec, +} + +#[derive(Debug)] +pub struct SvcParam { + key: u16, + value: Vec, +} + +impl Record { + pub fn parse(mut data: &[u8], original: &[u8]) -> Result { + let svc_priority = u16::from_be_bytes([data[0], data[1]]); + data = &data[2..]; + + let (target_name, read) = Qname::read(data, original)?; + data = &data[read..]; + + let mut svc_params = vec![]; + + while !data.is_empty() { + let key = u16::from_be_bytes([data[0], data[1]]); + let value_length = u16::from_be_bytes([data[2], data[3]]) as usize; + + let value = data[4..4 + value_length].to_vec(); + + svc_params.push(SvcParam { key, value }); + + data = &data[4 + value_length..]; + } + + if !data.is_empty() { + return Err(ParserError::UnexpectedEOP); + } + + Ok(Self { + svc_priority, + target_name, + svc_params, + }) + } +} diff --git a/src/parser/rdata/mod.rs b/src/parser/rdata/mod.rs index 717ca8d..e6f983b 100644 --- a/src/parser/rdata/mod.rs +++ b/src/parser/rdata/mod.rs @@ -1,6 +1,7 @@ mod a; mod aaaa; mod cname; +mod https; mod nsec; mod ptr; mod srv; @@ -15,22 +16,24 @@ pub enum RData { Ptr(ptr::Record), Txt(txt::Record), Srv(srv::Record), - Nsec(nsec::Record), + Https(https::Record), Unknown(Type, Vec), } impl RData { pub fn parse(rtype: Type, data: &[u8], original: &[u8]) -> Result { + use RData::*; match rtype { - Type::A => Ok(RData::A(a::Record::parse(data, original)?)), - Type::Cname => Ok(RData::Cname(cname::Record::parse(data, original)?)), - Type::Ptr => Ok(RData::Ptr(ptr::Record::parse(data, original)?)), - Type::Txt => Ok(RData::Txt(txt::Record::parse(data, original)?)), - Type::Aaaa => Ok(RData::Aaaa(aaaa::Record::parse(data, original)?)), - Type::Srv => Ok(RData::Srv(srv::Record::parse(data, original)?)), - Type::Nsec => Ok(RData::Nsec(nsec::Record::parse(data, original)?)), - Type::Https => todo!(), + Type::A => Ok(A(a::Record::parse(data, original)?)), + Type::Cname => Ok(Cname(cname::Record::parse(data, original)?)), + Type::Ptr => Ok(Ptr(ptr::Record::parse(data, original)?)), + Type::Txt => Ok(Txt(txt::Record::parse(data, original)?)), + Type::Aaaa => Ok(Aaaa(aaaa::Record::parse(data, original)?)), + Type::Srv => Ok(Srv(srv::Record::parse(data, original)?)), + Type::Https => Ok(Https(https::Record::parse(data, original)?)), + + _ => Ok(Unknown(rtype, data.to_vec())), } } } diff --git a/src/parser/rdata/nsec.rs b/src/parser/rdata/nsec.rs index 16598ca..4a7cfe5 100644 --- a/src/parser/rdata/nsec.rs +++ b/src/parser/rdata/nsec.rs @@ -5,17 +5,6 @@ pub struct Record {} impl Record { pub fn parse(data: &[u8], original: &[u8]) -> Result { - println!("{:02x?}", &data[..]); - let (domain_name, mut read) = Qname::read(data, original)?; - println!("{:02x?}", &data[read..]); - - read += 1; - let rr_bitmap_len = data[read]; - - let rr_bitmap = u16::from_be_bytes([data[read], data[read + 1]]); - - println!("{:0x}", rr_bitmap_len); - - Ok(Self {}) + unimplemented!() } } diff --git a/src/parser/resource_record.rs b/src/parser/resource_record.rs index cd7549f..e1fcbae 100644 --- a/src/parser/resource_record.rs +++ b/src/parser/resource_record.rs @@ -66,6 +66,7 @@ pub enum Type { Srv = 33, Nsec = 47, Https = 65, + Opt = 41, } impl Type { @@ -80,6 +81,7 @@ impl Type { 33 => Ok(Srv), 47 => Ok(Nsec), 65 => Ok(Https), + 41 => Ok(Opt), v => Err(ParserError::UnknownRType(v)), } }