1 use crate::error::*; 2 use crate::message::header::{Header, HeaderInternal, Section}; 3 use crate::message::name::Name; 4 use crate::message::question::Question; 5 use crate::message::resource::{unpack_resource_body, Resource, ResourceBody, ResourceHeader}; 6 use crate::message::{DnsClass, DnsType}; 7 8 // A Parser allows incrementally parsing a DNS message. 9 // 10 // When parsing is started, the Header is parsed. Next, each question can be 11 // either parsed or skipped. Alternatively, all Questions can be skipped at 12 // once. When all Questions have been parsed, attempting to parse Questions 13 // will return (nil, nil) and attempting to skip Questions will return 14 // (true, nil). After all Questions have been either parsed or skipped, all 15 // Answers, Authorities and Additionals can be either parsed or skipped in the 16 // same way, and each type of Resource must be fully parsed or skipped before 17 // proceeding to the next type of Resource. 18 // 19 // Note that there is no requirement to fully skip or parse the message. 20 #[derive(Default)] 21 pub 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 32 impl<'a> Parser<'a> { 33 // start parses the header and enables the parsing of Questions. start(&mut self, msg: &'a [u8]) -> Result<Header>34 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 check_advance(&mut self, sec: Section) -> Result<()>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 resource(&mut self, sec: Section) -> Result<Resource>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 resource_header(&mut self, sec: Section) -> Result<ResourceHeader>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 skip_resource(&mut self, sec: Section) -> Result<()>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 // question parses a single question. question(&mut self) -> Result<Question>106 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 // all_questions parses all Questions. all_questions(&mut self) -> Result<Vec<Question>>120 pub fn all_questions(&mut self) -> Result<Vec<Question>> { 121 // Multiple questions are valid according to the spec, 122 // but servers don't actually support them. There will 123 // be at most one question here. 124 // 125 // Do not pre-allocate based on info in self.header, since 126 // the data is untrusted. 127 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 // skip_question skips a single question. skip_question(&mut self) -> Result<()>143 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 // skip_all_questions skips all Questions. skip_all_questions(&mut self) -> Result<()>154 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 // answer_header parses a single answer ResourceHeader. answer_header(&mut self) -> Result<ResourceHeader>167 pub fn answer_header(&mut self) -> Result<ResourceHeader> { 168 self.resource_header(Section::Answers) 169 } 170 171 // answer parses a single answer Resource. answer(&mut self) -> Result<Resource>172 pub fn answer(&mut self) -> Result<Resource> { 173 self.resource(Section::Answers) 174 } 175 176 // all_answers parses all answer Resources. all_answers(&mut self) -> Result<Vec<Resource>>177 pub fn all_answers(&mut self) -> Result<Vec<Resource>> { 178 // The most common query is for A/AAAA, which usually returns 179 // a handful of IPs. 180 // 181 // Pre-allocate up to a certain limit, since self.header is 182 // untrusted data. 183 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 // skip_answer skips a single answer Resource. skip_answer(&mut self) -> Result<()>203 pub fn skip_answer(&mut self) -> Result<()> { 204 self.skip_resource(Section::Answers) 205 } 206 207 // skip_all_answers skips all answer Resources. skip_all_answers(&mut self) -> Result<()>208 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 // authority_header parses a single authority ResourceHeader. authority_header(&mut self) -> Result<ResourceHeader>221 pub fn authority_header(&mut self) -> Result<ResourceHeader> { 222 self.resource_header(Section::Authorities) 223 } 224 225 // authority parses a single authority Resource. authority(&mut self) -> Result<Resource>226 pub fn authority(&mut self) -> Result<Resource> { 227 self.resource(Section::Authorities) 228 } 229 230 // all_authorities parses all authority Resources. all_authorities(&mut self) -> Result<Vec<Resource>>231 pub fn all_authorities(&mut self) -> Result<Vec<Resource>> { 232 // Authorities contains SOA in case of NXDOMAIN and friends, 233 // otherwise it is empty. 234 // 235 // Pre-allocate up to a certain limit, since self.header is 236 // untrusted data. 237 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 // skip_authority skips a single authority Resource. skip_authority(&mut self) -> Result<()>257 pub fn skip_authority(&mut self) -> Result<()> { 258 self.skip_resource(Section::Authorities) 259 } 260 261 // skip_all_authorities skips all authority Resources. skip_all_authorities(&mut self) -> Result<()>262 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 // additional_header parses a single additional ResourceHeader. additional_header(&mut self) -> Result<ResourceHeader>275 pub fn additional_header(&mut self) -> Result<ResourceHeader> { 276 self.resource_header(Section::Additionals) 277 } 278 279 // additional parses a single additional Resource. additional(&mut self) -> Result<Resource>280 pub fn additional(&mut self) -> Result<Resource> { 281 self.resource(Section::Additionals) 282 } 283 284 // all_additionals parses all additional Resources. all_additionals(&mut self) -> Result<Vec<Resource>>285 pub fn all_additionals(&mut self) -> Result<Vec<Resource>> { 286 // Additionals usually contain OPT, and sometimes A/AAAA 287 // glue records. 288 // 289 // Pre-allocate up to a certain limit, since self.header is 290 // untrusted data. 291 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 // skip_additional skips a single additional Resource. skip_additional(&mut self) -> Result<()>311 pub fn skip_additional(&mut self) -> Result<()> { 312 self.skip_resource(Section::Additionals) 313 } 314 315 // skip_all_additionals skips all additional Resources. skip_all_additionals(&mut self) -> Result<()>316 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 // resource_body parses a single resource_boy. 329 // 330 // One of the XXXHeader methods must have been called before calling this 331 // method. resource_body(&mut self) -> Result<Box<dyn ResourceBody>>332 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 } 348