Skip to main content

dns_message/
question.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub struct Label<'a> {
3    pub length: u8,
4    pub data: &'a [u8],
5}
6
7impl<'a> Label<'a> {
8    pub fn new(length: u8, data: &'a [u8]) -> Self {
9        Self { length, data }
10    }
11}
12
13/// A single element in a domain name: label, pointer, root, or reserved.
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum NameElement<'a> {
16    Label(Label<'a>),
17    Pointer(u16),
18    Root,
19    Reserved,
20}
21
22pub type Name<'a> = Vec<NameElement<'a>>;
23
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub struct Question<'a> {
26    pub q_name: Name<'a>,
27    pub q_type: QType,
28    pub q_class: QClass,
29}
30
31impl<'a> Question<'a> {
32    pub fn new(q_name: Vec<NameElement<'a>>, q_type: QType, q_class: QClass) -> Self {
33        Self {
34            q_name,
35            q_type,
36            q_class,
37        }
38    }
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum QType {
43    A,
44    NS,
45    CNAME,
46    SOA,
47    PTR,
48    MX,
49    TXT,
50    AAAA,
51    SRV,
52    ANY,
53    Unknown(u16),
54}
55
56impl QType {
57    pub fn from_u16(value: u16) -> Self {
58        match value {
59            1 => QType::A,
60            2 => QType::NS,
61            5 => QType::CNAME,
62            6 => QType::SOA,
63            12 => QType::PTR,
64            15 => QType::MX,
65            16 => QType::TXT,
66            28 => QType::AAAA,
67            33 => QType::SRV,
68            255 => QType::ANY,
69            other => QType::Unknown(other),
70        }
71    }
72
73    pub fn to_u16(&self) -> u16 {
74        match *self {
75            QType::A => 1,
76            QType::NS => 2,
77            QType::CNAME => 5,
78            QType::SOA => 6,
79            QType::PTR => 12,
80            QType::MX => 15,
81            QType::TXT => 16,
82            QType::AAAA => 28,
83            QType::SRV => 33,
84            QType::ANY => 255,
85            QType::Unknown(v) => v,
86        }
87    }
88
89    pub fn from_question_bytes(h: u8, l: u8) -> Self {
90        let value = ((h as u16) << 8) | (l as u16);
91        QType::from_u16(value)
92    }
93
94    pub fn to_question_bytes(&self) -> (u8, u8) {
95        let value = self.to_u16();
96        let h = (value >> 8) as u8;
97        let l = (value & 0xFF) as u8;
98        (h, l)
99    }
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103pub enum QClass {
104    IN,
105    CS,
106    CH,
107    HS,
108    ANY,
109    Unknown(u16),
110}
111
112impl QClass {
113    pub fn from_u16(value: u16) -> Self {
114        match value {
115            1 => QClass::IN,
116            2 => QClass::CS,
117            3 => QClass::CH,
118            4 => QClass::HS,
119            255 => QClass::ANY,
120            other => QClass::Unknown(other),
121        }
122    }
123
124    pub fn to_u16(&self) -> u16 {
125        match *self {
126            QClass::IN => 1,
127            QClass::CS => 2,
128            QClass::CH => 3,
129            QClass::HS => 4,
130            QClass::ANY => 255,
131            QClass::Unknown(v) => v,
132        }
133    }
134
135    pub fn from_question_bytes(h: u8, l: u8) -> Self {
136        let value = ((h as u16) << 8) | (l as u16);
137        QClass::from_u16(value)
138    }
139
140    pub fn to_question_bytes(&self) -> (u8, u8) {
141        let value = self.to_u16();
142        let h = (value >> 8) as u8;
143        let l = (value & 0xFF) as u8;
144        (h, l)
145    }
146}