1use std::mem::transmute;
4use std::net::{Ipv4Addr, Ipv6Addr};
5
6use crate::message::{DecodeError, EncodeError, MsgReader, MsgWriter};
7
8#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10pub enum Class {
11 Internet,
13 Any,
15 Other(u16),
17}
18
19impl Class {
20 pub fn from_u16(u: u16) -> Class {
22 match u {
23 1 => Class::Internet,
24 255 => Class::Any,
25 n => Class::Other(n),
26 }
27 }
28
29 pub fn to_u16(&self) -> u16 {
31 match *self {
32 Class::Internet => 1,
33 Class::Any => 255,
34 Class::Other(n) => n,
35 }
36 }
37}
38
39#[derive(Copy, Clone, Debug, Eq, PartialEq)]
41pub enum RecordType {
42 A,
44 AAAA,
46 CName,
48 Mx,
50 Ns,
52 Ptr,
54 Soa,
56 Srv,
58 Txt,
60 Other(u16),
62}
63
64macro_rules! record_types {
65 ( $( $name:ident => $code:expr , )+ ) => {
66 impl RecordType {
67 pub fn from_u16(u: u16) -> RecordType {
69 match u {
70 $( $code => RecordType::$name , )+
71 n => RecordType::Other(n),
72 }
73 }
74
75 pub fn to_u16(&self) -> u16 {
77 match *self {
78 $( RecordType::$name => $code , )+
79 RecordType::Other(n) => n,
80 }
81 }
82 }
83 }
84}
85
86record_types! {
87 A => 1,
88 AAAA => 28,
89 CName => 5,
90 Mx => 15,
91 Ns => 2,
92 Ptr => 12,
93 Soa => 6,
94 Srv => 33,
95 Txt => 16,
96}
97
98pub trait Record: Sized {
100 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError>;
102
103 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError>;
105
106 fn record_type() -> RecordType;
108}
109
110#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
112pub struct A {
113 pub address: Ipv4Addr,
115}
116
117impl Record for A {
118 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
119 let mut buf = [0; 4];
120 data.read(&mut buf)?;
121 Ok(A {
122 address: Ipv4Addr::new(buf[0], buf[1], buf[2], buf[3]),
123 })
124 }
125
126 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
127 data.write(&self.address.octets())
128 }
129
130 fn record_type() -> RecordType {
131 RecordType::A
132 }
133}
134
135#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
137pub struct AAAA {
138 pub address: Ipv6Addr,
140}
141
142impl Record for AAAA {
143 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
144 let mut buf = [0; 16];
145 data.read(&mut buf)?;
146 let segments: [u16; 8] = unsafe { transmute(buf) };
147 Ok(AAAA {
148 address: Ipv6Addr::new(
149 u16::from_be(segments[0]),
150 u16::from_be(segments[1]),
151 u16::from_be(segments[2]),
152 u16::from_be(segments[3]),
153 u16::from_be(segments[4]),
154 u16::from_be(segments[5]),
155 u16::from_be(segments[6]),
156 u16::from_be(segments[7]),
157 ),
158 })
159 }
160
161 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
162 let mut segments = self.address.segments();
163 for seg in &mut segments {
164 *seg = seg.to_be()
165 }
166 let buf: [u8; 16] = unsafe { transmute(segments) };
167 data.write(&buf)
168 }
169
170 fn record_type() -> RecordType {
171 RecordType::AAAA
172 }
173}
174
175#[derive(Clone, Debug, PartialEq, Eq, Hash)]
177pub struct CName {
178 pub name: String,
180}
181
182impl Record for CName {
183 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
184 Ok(CName {
185 name: data.read_name()?,
186 })
187 }
188
189 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
190 data.write_name(&self.name)
191 }
192
193 fn record_type() -> RecordType {
194 RecordType::CName
195 }
196}
197
198#[derive(Clone, Debug, PartialEq, Eq, Hash)]
200pub struct Mx {
201 pub preference: u16,
204 pub exchange: String,
206}
207
208impl Record for Mx {
209 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
210 Ok(Mx {
211 preference: data.read_u16()?,
212 exchange: data.read_name()?,
213 })
214 }
215
216 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
217 data.write_u16(self.preference)?;
218 data.write_name(&self.exchange)
219 }
220
221 fn record_type() -> RecordType {
222 RecordType::Mx
223 }
224}
225
226#[derive(Clone, Debug, PartialEq, Eq, Hash)]
228pub struct Ns {
229 pub name: String,
231}
232
233impl Record for Ns {
234 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
235 Ok(Ns {
236 name: data.read_name()?,
237 })
238 }
239
240 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
241 data.write_name(&self.name)
242 }
243
244 fn record_type() -> RecordType {
245 RecordType::Ns
246 }
247}
248
249#[derive(Clone, Debug, PartialEq, Eq, Hash)]
251pub struct Ptr {
252 pub name: String,
254}
255
256impl Record for Ptr {
257 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
258 Ok(Ptr {
259 name: data.read_name()?,
260 })
261 }
262
263 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
264 data.write_name(&self.name)
265 }
266
267 fn record_type() -> RecordType {
268 RecordType::Ptr
269 }
270}
271
272#[derive(Clone, Debug, PartialEq, Eq, Hash)]
274pub struct Soa {
275 pub mname: String,
278 pub rname: String,
281 pub serial: u32,
284 pub refresh: u32,
286 pub retry: u32,
289 pub expire: u32,
292 pub minimum: u32,
295}
296
297impl Record for Soa {
298 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
299 Ok(Soa {
300 mname: data.read_name()?,
301 rname: data.read_name()?,
302 serial: data.read_u32()?,
303 refresh: data.read_u32()?,
304 retry: data.read_u32()?,
305 expire: data.read_u32()?,
306 minimum: data.read_u32()?,
307 })
308 }
309
310 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
311 data.write_name(&self.mname)?;
312 data.write_name(&self.rname)?;
313 data.write_u32(self.serial)?;
314 data.write_u32(self.refresh)?;
315 data.write_u32(self.retry)?;
316 data.write_u32(self.expire)?;
317 data.write_u32(self.minimum)?;
318 Ok(())
319 }
320
321 fn record_type() -> RecordType {
322 RecordType::Soa
323 }
324}
325
326#[derive(Clone, Debug, PartialEq, Eq, Hash)]
328pub struct Srv {
329 pub priority: u16,
331 pub weight: u16,
333 pub port: u16,
335 pub target: String,
337}
338
339impl Record for Srv {
340 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
341 Ok(Srv {
342 priority: data.read_u16()?,
343 weight: data.read_u16()?,
344 port: data.read_u16()?,
345 target: data.read_name()?,
346 })
347 }
348
349 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
350 data.write_u16(self.priority)?;
351 data.write_u16(self.weight)?;
352 data.write_u16(self.port)?;
353 data.write_name(&self.target)?;
354 Ok(())
355 }
356
357 fn record_type() -> RecordType {
358 RecordType::Srv
359 }
360}
361
362#[derive(Clone, Debug, PartialEq, Eq, Hash)]
364pub struct Txt {
365 pub data: Vec<u8>,
367}
368
369impl Record for Txt {
370 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
371 Ok(Txt {
372 data: data.read_character_string()?,
373 })
374 }
375
376 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
377 data.write_character_string(&self.data)
378 }
379
380 fn record_type() -> RecordType {
381 RecordType::Txt
382 }
383}