1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use crate::decode::Decoder;
use crate::{DecodeError, DecodeResult, Dns, Flags, Opcode, RCode, MAXIMUM_DNS_PACKET_SIZE};
use std::convert::TryFrom;
impl<'a, 'b: 'a> Decoder<'a, 'b> {
fn flags(&mut self) -> DecodeResult<Flags> {
let buffer = self.u8()?;
let qr = (buffer & 0b1000_0000) != 0;
let opcode = (buffer & 0b0111_1000) >> 3;
let opcode = match Opcode::try_from(opcode) {
Ok(opcode) => opcode,
Err(buffer) => return Err(DecodeError::Opcode(buffer)),
};
let aa = (buffer & 0b0000_0100) != 0;
let tc = (buffer & 0b0000_0010) != 0;
let rd = (buffer & 0b0000_0001) != 0;
let buffer = self.u8()?;
let ra = (buffer & 0b1000_0000) != 0;
let z = buffer & 0b0100_0000;
if z != 0 {
return Err(DecodeError::ZNotZeroes(z));
}
let ad = (buffer & 0b0010_0000) != 0;
let cd = (buffer & 0b0001_0000) != 0;
let rcode = buffer & 0b0000_1111;
match RCode::try_from(rcode) {
Ok(rcode) => Ok(Flags {
qr,
opcode,
aa,
tc,
rd,
ra,
ad,
cd,
rcode,
}),
Err(buffer) => Err(DecodeError::RCode(buffer)),
}
}
}
impl<'a, 'b: 'a> Decoder<'b, 'b> {
fn dns(&'a mut self) -> DecodeResult<Dns> {
if self.offset != 0 {
return Err(DecodeError::Offset(self.offset));
}
let bytes_len = self.bytes.len();
if bytes_len < 12 {
return Err(DecodeError::NotEnoughBytes(bytes_len, 12));
} else if bytes_len > MAXIMUM_DNS_PACKET_SIZE {
return Err(DecodeError::DnsPacketTooBig(bytes_len));
}
let id = self.u16()?;
let flags = self.flags()?;
let question_count = self.u16()?;
let answer_count = self.u16()?;
let authority_count = self.u16()?;
let additional_count = self.u16()?;
let mut questions = Vec::with_capacity(question_count as usize);
for _ in 0..question_count {
questions.push(self.question()?);
}
let mut answers = Vec::with_capacity(answer_count as usize);
for _ in 0..answer_count {
answers.push(self.rr()?);
}
let mut authorities = Vec::with_capacity(authority_count as usize);
for _ in 0..authority_count {
authorities.push(self.rr()?);
}
let mut additionals = Vec::with_capacity(additional_count as usize);
for _ in 0..additional_count {
additionals.push(self.rr()?);
}
let is_finished = self.is_finished()?;
let dns = Dns {
id,
flags,
questions,
answers,
authorities,
additionals,
};
if is_finished {
Ok(dns)
} else {
Err(DecodeError::RemainingBytes(self.offset, dns))
}
}
}
impl_decode!(Flags, flags);
impl_decode!(Dns, dns);