1use super::*;
2
3#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
5pub struct Header {
6 pub id: u16,
7 pub response: bool,
8 pub op_code: OpCode,
9 pub authoritative: bool,
10 pub truncated: bool,
11 pub recursion_desired: bool,
12 pub recursion_available: bool,
13 pub rcode: RCode,
14}
15
16impl fmt::Display for Header {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 write!(
19 f,
20 "dnsmessage.Header{{id: {}, response: {}, op_code: {}, authoritative: {}, truncated: {}, recursion_desired: {}, recursion_available: {}, rcode: {} }}",
21 self.id,
22 self.response,
23 self.op_code,
24 self.authoritative,
25 self.truncated,
26 self.recursion_desired,
27 self.recursion_available,
28 self.rcode
29 )
30 }
31}
32
33impl Header {
34 pub fn pack(&self) -> (u16, u16) {
35 let id = self.id;
36 let mut bits = self.op_code << 11 | self.rcode as u16;
37 if self.recursion_available {
38 bits |= HEADER_BIT_RA
39 }
40 if self.recursion_desired {
41 bits |= HEADER_BIT_RD
42 }
43 if self.truncated {
44 bits |= HEADER_BIT_TC
45 }
46 if self.authoritative {
47 bits |= HEADER_BIT_AA
48 }
49 if self.response {
50 bits |= HEADER_BIT_QR
51 }
52
53 (id, bits)
54 }
55}
56
57#[derive(Default, Copy, Clone, PartialOrd, PartialEq, Eq)]
58pub enum Section {
59 #[default]
60 NotStarted = 0,
61 Header = 1,
62 Questions = 2,
63 Answers = 3,
64 Authorities = 4,
65 Additionals = 5,
66 Done = 6,
67}
68
69impl From<u8> for Section {
70 fn from(v: u8) -> Self {
71 match v {
72 0 => Section::NotStarted,
73 1 => Section::Header,
74 2 => Section::Questions,
75 3 => Section::Answers,
76 4 => Section::Authorities,
77 5 => Section::Additionals,
78 _ => Section::Done,
79 }
80 }
81}
82
83impl fmt::Display for Section {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 let s = match *self {
86 Section::NotStarted => "NotStarted",
87 Section::Header => "Header",
88 Section::Questions => "question",
89 Section::Answers => "answer",
90 Section::Authorities => "authority",
91 Section::Additionals => "additional",
92 Section::Done => "Done",
93 };
94 write!(f, "{s}")
95 }
96}
97
98#[derive(Default)]
100pub struct HeaderInternal {
101 pub id: u16,
102 pub bits: u16,
103 pub questions: u16,
104 pub answers: u16,
105 pub authorities: u16,
106 pub additionals: u16,
107}
108
109impl HeaderInternal {
110 pub(crate) fn count(&self, sec: Section) -> u16 {
111 match sec {
112 Section::Questions => self.questions,
113 Section::Answers => self.answers,
114 Section::Authorities => self.authorities,
115 Section::Additionals => self.additionals,
116 _ => 0,
117 }
118 }
119
120 pub(crate) fn pack(&self, mut msg: Vec<u8>) -> Vec<u8> {
122 msg = pack_uint16(msg, self.id);
123 msg = pack_uint16(msg, self.bits);
124 msg = pack_uint16(msg, self.questions);
125 msg = pack_uint16(msg, self.answers);
126 msg = pack_uint16(msg, self.authorities);
127 msg = pack_uint16(msg, self.additionals);
128 msg
129 }
130
131 pub(crate) fn unpack(&mut self, msg: &[u8], off: usize) -> Result<usize> {
132 let (id, off) = unpack_uint16(msg, off)?;
133 self.id = id;
134
135 let (bits, off) = unpack_uint16(msg, off)?;
136 self.bits = bits;
137
138 let (questions, off) = unpack_uint16(msg, off)?;
139 self.questions = questions;
140
141 let (answers, off) = unpack_uint16(msg, off)?;
142 self.answers = answers;
143
144 let (authorities, off) = unpack_uint16(msg, off)?;
145 self.authorities = authorities;
146
147 let (additionals, off) = unpack_uint16(msg, off)?;
148 self.additionals = additionals;
149
150 Ok(off)
151 }
152
153 pub(crate) fn header(&self) -> Header {
154 Header {
155 id: self.id,
156 response: (self.bits & HEADER_BIT_QR) != 0,
157 op_code: ((self.bits >> 11) & 0xF) as OpCode,
158 authoritative: (self.bits & HEADER_BIT_AA) != 0,
159 truncated: (self.bits & HEADER_BIT_TC) != 0,
160 recursion_desired: (self.bits & HEADER_BIT_RD) != 0,
161 recursion_available: (self.bits & HEADER_BIT_RA) != 0,
162 rcode: RCode::from((self.bits & 0xF) as u8),
163 }
164 }
165}