1use std::mem::transmute;
4use std::net::{Ipv4Addr, Ipv6Addr};
5
6use 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 try!(data.read(&mut buf));
121 Ok(A{address: Ipv4Addr::new(buf[0], buf[1], buf[2], buf[3])})
122 }
123
124 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
125 data.write(&self.address.octets())
126 }
127
128 fn record_type() -> RecordType { RecordType::A }
129}
130
131#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
133pub struct AAAA {
134 pub address: Ipv6Addr,
136}
137
138impl Record for AAAA {
139 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
140 let mut buf = [0; 16];
141 try!(data.read(&mut buf));
142 let segments: [u16; 8] = unsafe { transmute(buf) };
143 Ok(AAAA{address: Ipv6Addr::new(
144 u16::from_be(segments[0]), u16::from_be(segments[1]),
145 u16::from_be(segments[2]), u16::from_be(segments[3]),
146 u16::from_be(segments[4]), u16::from_be(segments[5]),
147 u16::from_be(segments[6]), u16::from_be(segments[7]))})
148 }
149
150 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
151 let mut segments = self.address.segments();
152 for seg in &mut segments { *seg = seg.to_be() }
153 let buf: [u8; 16] = unsafe { transmute(segments) };
154 data.write(&buf)
155 }
156
157 fn record_type() -> RecordType { RecordType::AAAA }
158}
159
160#[derive(Clone, Debug, PartialEq, Eq, Hash)]
162pub struct CName {
163 pub name: String,
165}
166
167impl Record for CName {
168 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
169 Ok(CName{name: try!(data.read_name())})
170 }
171
172 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
173 data.write_name(&self.name)
174 }
175
176 fn record_type() -> RecordType { RecordType::CName }
177}
178
179#[derive(Clone, Debug, PartialEq, Eq, Hash)]
181pub struct Mx {
182 pub preference: u16,
185 pub exchange: String,
187}
188
189impl Record for Mx {
190 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
191 Ok(Mx{
192 preference: try!(data.read_u16()),
193 exchange: try!(data.read_name()),
194 })
195 }
196
197 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
198 try!(data.write_u16(self.preference));
199 data.write_name(&self.exchange)
200 }
201
202 fn record_type() -> RecordType { RecordType::Mx }
203}
204
205#[derive(Clone, Debug, PartialEq, Eq, Hash)]
207pub struct Ns {
208 pub name: String,
210}
211
212impl Record for Ns {
213 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
214 Ok(Ns{name: try!(data.read_name())})
215 }
216
217 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
218 data.write_name(&self.name)
219 }
220
221 fn record_type() -> RecordType { RecordType::Ns }
222}
223
224#[derive(Clone, Debug, PartialEq, Eq, Hash)]
226pub struct Ptr {
227 pub name: String,
229}
230
231impl Record for Ptr {
232 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
233 Ok(Ptr{name: try!(data.read_name())})
234 }
235
236 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
237 data.write_name(&self.name)
238 }
239
240 fn record_type() -> RecordType { RecordType::Ptr }
241}
242
243#[derive(Clone, Debug, PartialEq, Eq, Hash)]
245pub struct Soa {
246 pub mname: String,
249 pub rname: String,
252 pub serial: u32,
255 pub refresh: u32,
257 pub retry: u32,
259 pub expire: u32,
262 pub minimum: u32,
264}
265
266impl Record for Soa {
267 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
268 Ok(Soa{
269 mname: try!(data.read_name()),
270 rname: try!(data.read_name()),
271 serial: try!(data.read_u32()),
272 refresh: try!(data.read_u32()),
273 retry: try!(data.read_u32()),
274 expire: try!(data.read_u32()),
275 minimum: try!(data.read_u32()),
276 })
277 }
278
279 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
280 try!(data.write_name(&self.mname));
281 try!(data.write_name(&self.rname));
282 try!(data.write_u32(self.serial));
283 try!(data.write_u32(self.refresh));
284 try!(data.write_u32(self.retry));
285 try!(data.write_u32(self.expire));
286 try!(data.write_u32(self.minimum));
287 Ok(())
288 }
289
290 fn record_type() -> RecordType { RecordType::Soa }
291}
292
293#[derive(Clone, Debug, PartialEq, Eq, Hash)]
295pub struct Srv {
296 pub priority: u16,
298 pub weight: u16,
300 pub port: u16,
302 pub target: String,
304}
305
306impl Record for Srv {
307 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
308 Ok(Srv{
309 priority: try!(data.read_u16()),
310 weight: try!(data.read_u16()),
311 port: try!(data.read_u16()),
312 target: try!(data.read_name()),
313 })
314 }
315
316 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
317 try!(data.write_u16(self.priority));
318 try!(data.write_u16(self.weight));
319 try!(data.write_u16(self.port));
320 try!(data.write_name(&self.target));
321 Ok(())
322 }
323
324 fn record_type() -> RecordType { RecordType::Srv }
325}
326
327#[derive(Clone, Debug, PartialEq, Eq, Hash)]
329pub struct Txt {
330 pub data: Vec<u8>,
332}
333
334impl Record for Txt {
335 fn decode(data: &mut MsgReader) -> Result<Self, DecodeError> {
336 Ok(Txt{data: try!(data.read_character_string())})
337 }
338
339 fn encode(&self, data: &mut MsgWriter) -> Result<(), EncodeError> {
340 data.write_character_string(&self.data)
341 }
342
343 fn record_type() -> RecordType { RecordType::Txt }
344}