webrtc_mdns/message/
parser.rs1use crate::error::*;
2use crate::message::header::{Header, HeaderInternal, Section};
3use crate::message::name::Name;
4use crate::message::question::Question;
5use crate::message::resource::{unpack_resource_body, Resource, ResourceBody, ResourceHeader};
6use crate::message::{DnsClass, DnsType};
7
8#[derive(Default)]
21pub struct Parser<'a> {
22 pub msg: &'a [u8],
23 pub header: HeaderInternal,
24
25 pub section: Section,
26 pub off: usize,
27 pub index: usize,
28 pub res_header_valid: bool,
29 pub res_header: ResourceHeader,
30}
31
32impl<'a> Parser<'a> {
33 pub fn start(&mut self, msg: &'a [u8]) -> Result<Header> {
35 *self = Parser {
36 msg,
37 ..Default::default()
38 };
39 self.off = self.header.unpack(msg, 0)?;
40 self.section = Section::Questions;
41 Ok(self.header.header())
42 }
43
44 fn check_advance(&mut self, sec: Section) -> Result<()> {
45 if self.section < sec {
46 return Err(Error::ErrNotStarted);
47 }
48 if self.section > sec {
49 return Err(Error::ErrSectionDone);
50 }
51 self.res_header_valid = false;
52 if self.index == self.header.count(sec) as usize {
53 self.index = 0;
54 self.section = Section::from(1 + self.section as u8);
55 return Err(Error::ErrSectionDone);
56 }
57 Ok(())
58 }
59
60 fn resource(&mut self, sec: Section) -> Result<Resource> {
61 let header = self.resource_header(sec)?;
62 self.res_header_valid = false;
63 let (body, off) =
64 unpack_resource_body(header.typ, self.msg, self.off, header.length as usize)?;
65 self.off = off;
66 self.index += 1;
67 Ok(Resource {
68 header,
69 body: Some(body),
70 })
71 }
72
73 fn resource_header(&mut self, sec: Section) -> Result<ResourceHeader> {
74 if self.res_header_valid {
75 return Ok(self.res_header.clone());
76 }
77 self.check_advance(sec)?;
78 let mut hdr = ResourceHeader::default();
79 let off = hdr.unpack(self.msg, self.off, 0)?;
80
81 self.res_header_valid = true;
82 self.res_header = hdr.clone();
83 self.off = off;
84 Ok(hdr)
85 }
86
87 fn skip_resource(&mut self, sec: Section) -> Result<()> {
88 if self.res_header_valid {
89 let new_off = self.off + self.res_header.length as usize;
90 if new_off > self.msg.len() {
91 return Err(Error::ErrResourceLen);
92 }
93 self.off = new_off;
94 self.res_header_valid = false;
95 self.index += 1;
96 return Ok(());
97 }
98 self.check_advance(sec)?;
99
100 self.off = Resource::skip(self.msg, self.off)?;
101 self.index += 1;
102 Ok(())
103 }
104
105 pub fn question(&mut self) -> Result<Question> {
107 self.check_advance(Section::Questions)?;
108 let mut name = Name::new("")?;
109 let mut off = name.unpack(self.msg, self.off)?;
110 let mut typ = DnsType::Unsupported;
111 off = typ.unpack(self.msg, off)?;
112 let mut class = DnsClass::default();
113 off = class.unpack(self.msg, off)?;
114 self.off = off;
115 self.index += 1;
116 Ok(Question { name, typ, class })
117 }
118
119 pub fn all_questions(&mut self) -> Result<Vec<Question>> {
121 let mut qs = vec![];
128 loop {
129 match self.question() {
130 Err(err) => {
131 if Error::ErrSectionDone == err {
132 return Ok(qs);
133 } else {
134 return Err(err);
135 }
136 }
137 Ok(q) => qs.push(q),
138 }
139 }
140 }
141
142 pub fn skip_question(&mut self) -> Result<()> {
144 self.check_advance(Section::Questions)?;
145 let mut off = Name::skip(self.msg, self.off)?;
146 off = DnsType::skip(self.msg, off)?;
147 off = DnsClass::skip(self.msg, off)?;
148 self.off = off;
149 self.index += 1;
150 Ok(())
151 }
152
153 pub fn skip_all_questions(&mut self) -> Result<()> {
155 loop {
156 if let Err(err) = self.skip_question() {
157 if Error::ErrSectionDone == err {
158 return Ok(());
159 } else {
160 return Err(err);
161 }
162 }
163 }
164 }
165
166 pub fn answer_header(&mut self) -> Result<ResourceHeader> {
168 self.resource_header(Section::Answers)
169 }
170
171 pub fn answer(&mut self) -> Result<Resource> {
173 self.resource(Section::Answers)
174 }
175
176 pub fn all_answers(&mut self) -> Result<Vec<Resource>> {
178 let mut n = self.header.answers as usize;
184 if n > 20 {
185 n = 20
186 }
187 let mut a = Vec::with_capacity(n);
188 loop {
189 match self.answer() {
190 Err(err) => {
191 if Error::ErrSectionDone == err {
192 return Ok(a);
193 } else {
194 return Err(err);
195 }
196 }
197 Ok(r) => a.push(r),
198 }
199 }
200 }
201
202 pub fn skip_answer(&mut self) -> Result<()> {
204 self.skip_resource(Section::Answers)
205 }
206
207 pub fn skip_all_answers(&mut self) -> Result<()> {
209 loop {
210 if let Err(err) = self.skip_answer() {
211 if Error::ErrSectionDone == err {
212 return Ok(());
213 } else {
214 return Err(err);
215 }
216 }
217 }
218 }
219
220 pub fn authority_header(&mut self) -> Result<ResourceHeader> {
222 self.resource_header(Section::Authorities)
223 }
224
225 pub fn authority(&mut self) -> Result<Resource> {
227 self.resource(Section::Authorities)
228 }
229
230 pub fn all_authorities(&mut self) -> Result<Vec<Resource>> {
232 let mut n = self.header.authorities as usize;
238 if n > 10 {
239 n = 10;
240 }
241 let mut a = Vec::with_capacity(n);
242 loop {
243 match self.authority() {
244 Err(err) => {
245 if Error::ErrSectionDone == err {
246 return Ok(a);
247 } else {
248 return Err(err);
249 }
250 }
251 Ok(r) => a.push(r),
252 }
253 }
254 }
255
256 pub fn skip_authority(&mut self) -> Result<()> {
258 self.skip_resource(Section::Authorities)
259 }
260
261 pub fn skip_all_authorities(&mut self) -> Result<()> {
263 loop {
264 if let Err(err) = self.skip_authority() {
265 if Error::ErrSectionDone == err {
266 return Ok(());
267 } else {
268 return Err(err);
269 }
270 }
271 }
272 }
273
274 pub fn additional_header(&mut self) -> Result<ResourceHeader> {
276 self.resource_header(Section::Additionals)
277 }
278
279 pub fn additional(&mut self) -> Result<Resource> {
281 self.resource(Section::Additionals)
282 }
283
284 pub fn all_additionals(&mut self) -> Result<Vec<Resource>> {
286 let mut n = self.header.additionals as usize;
292 if n > 10 {
293 n = 10;
294 }
295 let mut a = Vec::with_capacity(n);
296 loop {
297 match self.additional() {
298 Err(err) => {
299 if Error::ErrSectionDone == err {
300 return Ok(a);
301 } else {
302 return Err(err);
303 }
304 }
305 Ok(r) => a.push(r),
306 }
307 }
308 }
309
310 pub fn skip_additional(&mut self) -> Result<()> {
312 self.skip_resource(Section::Additionals)
313 }
314
315 pub fn skip_all_additionals(&mut self) -> Result<()> {
317 loop {
318 if let Err(err) = self.skip_additional() {
319 if Error::ErrSectionDone == err {
320 return Ok(());
321 } else {
322 return Err(err);
323 }
324 }
325 }
326 }
327
328 pub fn resource_body(&mut self) -> Result<Box<dyn ResourceBody>> {
333 if !self.res_header_valid {
334 return Err(Error::ErrNotStarted);
335 }
336 let (rb, _off) = unpack_resource_body(
337 self.res_header.typ,
338 self.msg,
339 self.off,
340 self.res_header.length as usize,
341 )?;
342 self.off += self.res_header.length as usize;
343 self.res_header_valid = false;
344 self.index += 1;
345 Ok(rb)
346 }
347}