Skip to main content

dns_message/
resource_record.rs

1use crate::question::Name;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct ResourceRecord<'a> {
5    pub rr_name: Name<'a>,
6    pub rr_type: RRType,
7    pub rr_class: RRClass,
8    pub rr_ttl: u32,
9    pub rr_rd_length: u16,
10    pub rr_data: &'a [u8],
11}
12
13impl<'a> ResourceRecord<'a> {
14    pub fn new(
15        rr_name: Name<'a>,
16        rr_type: RRType,
17        rr_class: RRClass,
18        rr_ttl: u32,
19        rr_rd_length: u16,
20        rr_data: &'a [u8],
21    ) -> Self {
22        Self {
23            rr_name,
24            rr_type,
25            rr_class,
26            rr_ttl,
27            rr_rd_length,
28            rr_data,
29        }
30    }
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum RRType {
35    A,
36    NS,
37    CNAME,
38    SOA,
39    PTR,
40    MX,
41    TXT,
42    AAAA,
43    SRV,
44    Unknown(u16),
45}
46
47impl RRType {
48    pub fn from_u16(value: u16) -> Self {
49        match value {
50            1 => RRType::A,
51            2 => RRType::NS,
52            5 => RRType::CNAME,
53            6 => RRType::SOA,
54            12 => RRType::PTR,
55            15 => RRType::MX,
56            16 => RRType::TXT,
57            28 => RRType::AAAA,
58            33 => RRType::SRV,
59            other => RRType::Unknown(other),
60        }
61    }
62
63    pub fn to_u16(&self) -> u16 {
64        match *self {
65            RRType::A => 1,
66            RRType::NS => 2,
67            RRType::CNAME => 5,
68            RRType::SOA => 6,
69            RRType::PTR => 12,
70            RRType::MX => 15,
71            RRType::TXT => 16,
72            RRType::AAAA => 28,
73            RRType::SRV => 33,
74            RRType::Unknown(v) => v,
75        }
76    }
77
78    pub fn from_rr_bytes(h: u8, l: u8) -> Self {
79        let value = ((h as u16) << 8) | (l as u16);
80        RRType::from_u16(value)
81    }
82
83    pub fn to_rr_bytes(&self) -> (u8, u8) {
84        let value = self.to_u16();
85        let h = (value >> 8) as u8;
86        let l = (value & 0xFF) as u8;
87        (h, l)
88    }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub enum RRClass {
93    IN,
94    CS,
95    CH,
96    HS,
97    Unknown(u16),
98}
99
100impl RRClass {
101    pub fn from_u16(value: u16) -> Self {
102        match value {
103            1 => RRClass::IN,
104            2 => RRClass::CS,
105            3 => RRClass::CH,
106            4 => RRClass::HS,
107            other => RRClass::Unknown(other),
108        }
109    }
110
111    pub fn to_u16(&self) -> u16 {
112        match *self {
113            RRClass::IN => 1,
114            RRClass::CS => 2,
115            RRClass::CH => 3,
116            RRClass::HS => 4,
117            RRClass::Unknown(v) => v,
118        }
119    }
120
121    pub fn from_rr_bytes(h: u8, l: u8) -> Self {
122        let value = ((h as u16) << 8) | (l as u16);
123        RRClass::from_u16(value)
124    }
125
126    pub fn to_rr_bytes(&self) -> (u8, u8) {
127        let value = self.to_u16();
128        let h = (value >> 8) as u8;
129        let l = (value & 0xFF) as u8;
130        (h, l)
131    }
132}