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#[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}