mod character_string;
mod name;
mod packet;
mod packet_header;
mod question;
pub mod rdata;
mod resource_record;
use std::{collections::HashMap, convert::TryFrom};
pub use name::Name;
pub use packet::{Packet, PacketBuf, QuestionsIter};
pub use packet_header::PacketHeader;
pub use question::Question;
pub use resource_record::ResourceRecord;
pub use character_string::CharacterString;
const MAX_LABEL_LENGTH: usize = 63;
const MAX_NAME_LENGTH: usize = 255;
const MAX_CHARACTER_STRING_LENGTH: usize = 255;
const MAX_NULL_LENGTH: usize = 65535;
pub(crate) trait DnsPacketContent<'a> {
fn parse(data: &'a [u8], position: usize) -> crate::Result<Self>
where
Self: Sized;
fn append_to_vec(&self, out: &mut Vec<u8>) -> crate::Result<()>;
fn compress_append_to_vec(
&self,
out: &mut Vec<u8>,
_name_refs: &mut HashMap<u64, usize>,
) -> crate::Result<()> {
self.append_to_vec(out)
}
fn len(&self) -> usize;
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TYPE {
A,
AAAA,
NS,
MD,
MF,
CNAME,
SOA,
MB,
MG,
MR,
NULL,
WKS,
PTR,
HINFO,
MINFO,
MX,
TXT,
SRV,
Unknown(u16),
}
impl From<TYPE> for u16 {
fn from(value: TYPE) -> Self {
match value {
TYPE::A => 1,
TYPE::AAAA => 28,
TYPE::NS => 2,
TYPE::MD => 3,
TYPE::MF => 4,
TYPE::CNAME => 5,
TYPE::SOA => 6,
TYPE::MB => 7,
TYPE::MG => 8,
TYPE::MR => 9,
TYPE::NULL => 10,
TYPE::WKS => 11,
TYPE::PTR => 12,
TYPE::HINFO => 13,
TYPE::MINFO => 14,
TYPE::MX => 15,
TYPE::TXT => 16,
TYPE::SRV => 33,
TYPE::Unknown(x) => x,
}
}
}
impl From<u16> for TYPE {
fn from(value: u16) -> Self {
use self::TYPE::*;
match value {
1 => A,
2 => NS,
3 => MD,
4 => MF,
5 => CNAME,
6 => SOA,
7 => MB,
8 => MG,
9 => MR,
10 => NULL,
11 => WKS,
12 => PTR,
13 => HINFO,
14 => MINFO,
15 => MX,
16 => TXT,
28 => AAAA,
33 => SRV,
v => TYPE::Unknown(v),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum QTYPE {
A = 1,
AAAA = 28,
NS = 2,
MD = 3,
MF = 4,
CNAME = 5,
SOA = 6,
MB = 7,
MG = 8,
MR = 9,
NULL = 10,
WKS = 11,
PTR = 12,
HINFO = 13,
MINFO = 14,
MX = 15,
TXT = 16,
SRV = 33,
AXFR = 252,
MAILB = 253,
MAILA = 254,
ANY = 255,
}
impl TryFrom<u16> for QTYPE {
type Error = crate::SimpleDnsError;
fn try_from(value: u16) -> Result<Self, Self::Error> {
use self::QTYPE::*;
match value {
1 => Ok(A),
2 => Ok(NS),
3 => Ok(MD),
4 => Ok(MF),
5 => Ok(CNAME),
6 => Ok(SOA),
7 => Ok(MB),
8 => Ok(MG),
9 => Ok(MR),
10 => Ok(NULL),
11 => Ok(WKS),
12 => Ok(PTR),
13 => Ok(HINFO),
14 => Ok(MINFO),
15 => Ok(MX),
16 => Ok(TXT),
28 => Ok(AAAA),
33 => Ok(SRV),
252 => Ok(AXFR),
253 => Ok(MAILB),
254 => Ok(MAILA),
255 => Ok(ANY),
v => Err(Self::Error::InvalidQType(v)),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CLASS {
IN = 1,
CS = 2,
CH = 3,
HS = 4,
}
impl TryFrom<u16> for CLASS {
type Error = crate::SimpleDnsError;
fn try_from(value: u16) -> Result<Self, Self::Error> {
use self::CLASS::*;
match value {
1 => Ok(IN),
2 => Ok(CS),
3 => Ok(CH),
4 => Ok(HS),
v => Err(Self::Error::InvalidClass(v)),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum QCLASS {
IN = 1,
CS = 2,
CH = 3,
HS = 4,
ANY = 255,
}
impl TryFrom<u16> for QCLASS {
type Error = crate::SimpleDnsError;
fn try_from(value: u16) -> Result<Self, Self::Error> {
use self::QCLASS::*;
match value {
1 => Ok(IN),
2 => Ok(CS),
3 => Ok(CH),
4 => Ok(HS),
255 => Ok(ANY),
v => Err(Self::Error::InvalidQClass(v)),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum OPCODE {
StandardQuery = 0,
InverseQuery = 1,
ServerStatusRequest = 2,
Reserved,
}
impl From<u16> for OPCODE {
fn from(code: u16) -> Self {
match code {
0 => OPCODE::StandardQuery,
1 => OPCODE::InverseQuery,
2 => OPCODE::ServerStatusRequest,
_ => OPCODE::Reserved,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum RCODE {
NoError = 0,
FormatError = 1,
ServerFailure = 2,
NameError = 3,
NotImplemented = 4,
Refused = 5,
Reserved,
}
impl From<u16> for RCODE {
fn from(code: u16) -> Self {
match code {
0 => RCODE::NoError,
1 => RCODE::FormatError,
2 => RCODE::ServerFailure,
3 => RCODE::NameError,
4 => RCODE::NotImplemented,
5 => RCODE::Refused,
_ => RCODE::Reserved,
}
}
}