1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
use crate::{read_u16_be, write_u16_be, DnsError};
use core::fmt::{Display, Formatter};
use fixed_buffer::FixedBuf;
/// > TYPE fields are used in resource records. Note that these types are a subset of QTYPEs.
///
/// <https://datatracker.ietf.org/doc/html/rfc1035#section-3.2.2>
///
/// > A record type is defined to store a host's IPv6 address. A host that has more than one
/// > IPv6 address must have more than one such record.
///
/// <https://datatracker.ietf.org/doc/html/rfc3596#section-2>
///
/// > QTYPE fields appear in the question part of a query. QTYPES are a superset of TYPEs, hence
/// > all TYPEs are valid QTYPEs.
///
/// <https://datatracker.ietf.org/doc/html/rfc1035#section-3.2.3>
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum DnsType {
/// IPv4 address
A,
/// IPv6 address
AAAA,
/// The canonical name for an alias
CNAME,
/// Mail exchange
MX,
/// Authoritative name server
NS,
/// Domain name pointer
PTR,
/// Marks the start of a zone of authority
SOA,
/// Text string
TXT,
ANY,
Unknown(u16),
}
impl DnsType {
#[must_use]
pub fn new(value: u16) -> Self {
match value {
1 => DnsType::A,
28 => DnsType::AAAA,
5 => DnsType::CNAME,
15 => DnsType::MX,
2 => DnsType::NS,
12 => DnsType::PTR,
6 => DnsType::SOA,
16 => DnsType::TXT,
255 => DnsType::ANY,
other => DnsType::Unknown(other),
}
}
#[must_use]
pub fn num(&self) -> u16 {
match self {
DnsType::A => 1,
DnsType::AAAA => 28,
DnsType::CNAME => 5,
DnsType::MX => 15,
DnsType::NS => 2,
DnsType::PTR => 12,
DnsType::SOA => 6,
DnsType::TXT => 16,
DnsType::ANY => 255,
DnsType::Unknown(other) => *other,
}
}
/// # Errors
/// Returns an error when `buf` does not contain a valid two-byte type code.
pub fn read<const N: usize>(buf: &mut FixedBuf<N>) -> Result<Self, DnsError> {
Ok(Self::new(read_u16_be(buf)?))
}
/// # Errors
/// Returns an error when `buf` fills up.
pub fn write<const N: usize>(&self, out: &mut FixedBuf<N>) -> Result<(), DnsError> {
write_u16_be(out, self.num())
}
}
impl Display for DnsType {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
match self {
DnsType::A => write!(f, "A"),
DnsType::AAAA => write!(f, "AAAA"),
DnsType::CNAME => write!(f, "CNAME"),
DnsType::MX => write!(f, "MX"),
DnsType::NS => write!(f, "NS"),
DnsType::PTR => write!(f, "PTR"),
DnsType::SOA => write!(f, "SOA"),
DnsType::TXT => write!(f, "TXT"),
DnsType::ANY => write!(f, "ANY"),
DnsType::Unknown(n) => write!(f, "Unknown({n})"),
}
}
}