1use byteorder::{BigEndian, ByteOrder};
2use rand::prelude::*;
3
4use crate::compress::*;
5use crate::constants::*;
6use crate::dns_sector::*;
7use crate::edns_iterator::*;
8use crate::errors::*;
9use crate::question_iterator::*;
10use crate::renamer::*;
11use crate::response_iterator::*;
12use crate::rr_iterator::*;
13use crate::synth::gen;
14
15#[derive(Debug)]
19pub struct ParsedPacket {
20 pub packet: Option<Vec<u8>>,
21 pub offset_question: Option<usize>,
22 pub offset_answers: Option<usize>,
23 pub offset_nameservers: Option<usize>,
24 pub offset_additional: Option<usize>,
25 pub offset_edns: Option<usize>,
26 pub edns_count: u16,
27 pub ext_rcode: Option<u8>,
28 pub edns_version: Option<u8>,
29 pub ext_flags: Option<u16>,
30 pub maybe_compressed: bool,
31 pub max_payload: usize,
32 pub cached: Option<(Vec<u8>, u16, u16)>,
33}
34
35impl ParsedPacket {
36 pub fn empty() -> Self {
38 let mut parsed_packet = ParsedPacket {
39 packet: Some(vec![0; 12]),
40 offset_question: None,
41 offset_answers: None,
42 offset_nameservers: None,
43 offset_additional: None,
44 offset_edns: None,
45 edns_count: 0,
46 ext_rcode: None,
47 edns_version: None,
48 ext_flags: None,
49 maybe_compressed: false,
50 max_payload: DNS_MAX_UNCOMPRESSED_SIZE,
51 cached: None,
52 };
53 let mut rng = thread_rng();
54 let tid: u16 = rng.gen();
55 parsed_packet.set_tid(tid);
56 parsed_packet.set_flags(DNS_FLAG_RD);
57 parsed_packet.set_response(false);
58 parsed_packet
59 }
60
61 #[inline]
63 pub fn into_packet(self) -> Vec<u8> {
64 self.packet.unwrap()
65 }
66
67 #[inline]
69 pub fn packet(&self) -> &[u8] {
70 self.packet.as_ref().unwrap()
71 }
72
73 #[inline]
74 pub fn packet_mut(&mut self) -> &mut Vec<u8> {
75 self.packet.as_mut().unwrap()
76 }
77
78 pub fn into_iter_question(&mut self) -> Option<QuestionIterator<'_>> {
80 QuestionIterator::new(RRIterator::new(self, Section::Question)).next()
81 }
82
83 pub fn into_iter_answer(&mut self) -> Option<AnswerIterator<'_>> {
85 AnswerIterator::new(RRIterator::new(self, Section::Answer)).next()
86 }
87
88 pub fn into_iter_nameservers(&mut self) -> Option<NameServersIterator<'_>> {
90 NameServersIterator::new(RRIterator::new(self, Section::NameServers)).next()
91 }
92
93 pub fn into_iter_additional(&mut self) -> Option<AdditionalIterator<'_>> {
95 AdditionalIterator::new(RRIterator::new(self, Section::Additional)).next()
96 }
97
98 pub fn into_iter_additional_including_opt(&mut self) -> Option<AdditionalIterator<'_>> {
100 AdditionalIterator::new(RRIterator::new(self, Section::Additional)).next_including_opt()
101 }
102
103 pub fn into_iter_edns(&mut self) -> Option<EdnsIterator<'_>> {
105 EdnsIterator::new(RRIterator::new(self, Section::Edns)).next()
106 }
107
108 pub fn copy_header(&self, header: &mut Vec<u8>) {
110 header.extend(&self.packet()[..DNS_HEADER_SIZE]);
111 }
112
113 pub fn copy_raw_edns_section(&self, raw_edns: &mut Vec<u8>) -> usize {
115 let offset_edns = match self.offset_edns {
116 None => return 0,
117 Some(offset_edns) => offset_edns,
118 };
119 debug_assert!(offset_edns >= 1 + DNS_RR_HEADER_SIZE);
120 if offset_edns < 1 + DNS_RR_HEADER_SIZE {
121 return 0;
122 }
123 let offset_edns_header = offset_edns - (1 + DNS_RR_HEADER_SIZE);
124 debug_assert_eq!(self.packet()[offset_edns_header], 0);
125 let edns_len = self.packet().len() - offset_edns_header;
126 raw_edns.extend_from_slice(&self.packet()[offset_edns_header..]);
127 edns_len
128 }
129
130 #[inline]
132 pub fn tid(&self) -> u16 {
133 BigEndian::read_u16(&self.packet()[DNS_TID_OFFSET..])
134 }
135
136 pub fn set_tid(&mut self, tid: u16) {
138 BigEndian::write_u16(&mut self.packet_mut()[DNS_TID_OFFSET..], tid)
139 }
140
141 pub fn flags(&self) -> u32 {
147 let mut rflags = BigEndian::read_u16(&self.packet()[DNS_FLAGS_OFFSET..]);
148 rflags &= !0x7800; rflags &= !0x000f; (self.ext_flags.unwrap_or(0) as u32) << 16 | (rflags as u32)
151 }
152
153 pub fn set_flags(&mut self, flags: u32) {
156 let mut rflags = (flags & 0xffff) as u16;
157 rflags &= !0x7800; rflags &= !0x000f; let mut v = BigEndian::read_u16(&self.packet()[DNS_FLAGS_OFFSET..]);
160 v &= !0x7800;
161 v &= !0x000f;
162 v |= rflags;
163 BigEndian::write_u16(&mut self.packet_mut()[DNS_FLAGS_OFFSET..], v);
164 }
165
166 pub fn dnssec(&self) -> bool {
169 let flags = self.flags();
170 if flags & DNS_FLAG_QR == 0 {
171 (flags & DNS_FLAG_DO) != 0
172 } else {
173 (flags & DNS_FLAG_AD) != 0
174 }
175 }
176
177 #[inline]
179 pub fn is_response(&self) -> bool {
180 self.flags() & DNS_FLAG_QR == DNS_FLAG_QR
181 }
182
183 #[inline]
185 pub fn set_response(&mut self, is_response: bool) {
186 let mut oll = BigEndian::read_u16(&self.packet()[DNS_FLAGS_OFFSET..]);
187 if is_response {
188 oll |= DNS_FLAG_QR as u16
189 } else {
190 oll &= !(DNS_FLAG_QR as u16)
191 }
192 BigEndian::write_u16(&mut self.packet_mut()[DNS_FLAGS_OFFSET..], oll);
193 }
194
195 #[inline]
197 pub fn rcode(&self) -> u8 {
198 let rflags = self.packet()[DNS_FLAGS_OFFSET + 1];
199 rflags & 0x0f
200 }
201
202 pub fn set_rcode(&mut self, rcode: u8) {
204 let p = &mut self.packet_mut()[DNS_FLAGS_OFFSET + 1];
205 *p &= !0x0f;
206 *p |= rcode & 0x0f;
207 }
208
209 #[inline]
211 pub fn opcode(&self) -> u8 {
212 let rflags = self.packet()[DNS_FLAGS_OFFSET];
213 (rflags & 0x78) >> 3
214 }
215
216 pub fn set_opcode(&mut self, opcode: u8) {
218 let p = &mut self.packet_mut()[DNS_FLAGS_OFFSET];
219 *p &= !0x78;
220 *p |= (opcode << 3) & 0x78;
221 }
222
223 #[inline]
225 pub fn max_payload(&self) -> usize {
226 self.max_payload
227 }
228
229 pub fn rrcount_inc(&mut self, section: Section) -> Result<u16, Error> {
231 let packet = &mut self.packet_mut();
232 let mut rrcount = match section {
233 Section::Question => {
234 let rrcount = DNSSector::qdcount(packet);
235 if rrcount >= 1 {
236 bail!(DSError::InvalidPacket(
237 "A DNS packet can only contain up to one question"
238 ));
239 }
240 rrcount
241 }
242 Section::Answer => DNSSector::ancount(packet),
243 Section::NameServers => DNSSector::nscount(packet),
244 Section::Additional => DNSSector::arcount(packet),
245 _ => panic!("Trying to increment a the number of records in a pseudosection"),
246 };
247 if rrcount >= 0xffff {
248 bail!(DSError::InvalidPacket(
249 "Too many records in the same question"
250 ));
251 }
252 rrcount += 1;
253 match section {
254 Section::Question => DNSSector::set_qdcount(packet, rrcount),
255 Section::Answer => DNSSector::set_ancount(packet, rrcount),
256 Section::NameServers => DNSSector::set_nscount(packet, rrcount),
257 Section::Additional => DNSSector::set_arcount(packet, rrcount),
258 _ => panic!("EDNS section doesn't have a records count"),
259 }
260 Ok(rrcount)
261 }
262
263 pub fn rrcount_dec(&mut self, section: Section) -> Result<u16, Error> {
265 let packet = &mut self.packet_mut();
266 let mut rrcount = match section {
267 Section::Question => DNSSector::qdcount(packet),
268 Section::Answer => DNSSector::ancount(packet),
269 Section::NameServers => DNSSector::nscount(packet),
270 Section::Additional => DNSSector::arcount(packet),
271 _ => panic!("Trying to decrement a the number of records in a pseudosection"),
272 };
273 if rrcount <= 0 {
274 panic!(
275 "Trying to decrement a number of records that was already 0 in section {:?}",
276 section
277 );
278 }
279 rrcount -= 1;
280 match section {
281 Section::Question => DNSSector::set_qdcount(packet, rrcount),
282 Section::Answer => DNSSector::set_ancount(packet, rrcount),
283 Section::NameServers => DNSSector::set_nscount(packet, rrcount),
284 Section::Additional => DNSSector::set_arcount(packet, rrcount),
285 _ => panic!("EDNS section doesn't have a records count"),
286 }
287
288 Ok(rrcount)
289 }
290
291 fn insertion_offset(&self, section: Section) -> Result<usize, Error> {
292 let offset = match section {
293 Section::Question => self
294 .offset_answers
295 .or(self.offset_nameservers)
296 .or(self.offset_additional)
297 .unwrap_or_else(|| self.packet().len()),
298 Section::Answer => self
299 .offset_nameservers
300 .or(self.offset_additional)
301 .unwrap_or_else(|| self.packet().len()),
302 Section::NameServers => self
303 .offset_additional
304 .unwrap_or_else(|| self.packet().len()),
305 Section::Additional => self.packet().len(),
306 _ => panic!("insertion_offset() is not suitable to adding EDNS pseudorecords"),
307 };
308 Ok(offset)
309 }
310
311 pub fn insert_rr(&mut self, section: Section, rr: gen::RR) -> Result<(), Error> {
312 if self.maybe_compressed {
313 let uncompressed = Compress::uncompress(self.packet())?;
314 self.packet = Some(uncompressed);
315 self.recompute()?;
316 debug_assert!(!self.maybe_compressed);
317 }
318 let rr_len = rr.packet.len();
319 if DNS_MAX_UNCOMPRESSED_SIZE - self.packet().len() < rr_len {
320 bail!(DSError::PacketTooLarge)
321 }
322 let insertion_offset = self.insertion_offset(section)?;
323 let packet_len = self.packet().len();
324 let new_len = packet_len + rr_len;
325 self.packet_mut().reserve(rr_len);
326 if insertion_offset == new_len {
327 self.packet_mut().extend_from_slice(&rr.packet);
328 } else {
329 let packet = self.packet_mut();
330 packet.resize(new_len, 0);
331 packet.copy_within(insertion_offset..packet_len, insertion_offset + rr_len);
332 packet[insertion_offset..insertion_offset + rr_len].copy_from_slice(&rr.packet);
333 }
334 self.rrcount_inc(section)?;
335 match section {
336 Section::Question => {
337 self.offset_question = self.offset_question.or(Some(insertion_offset));
338
339 self.offset_answers = self.offset_answers.map(|x| x + rr_len);
340 self.offset_nameservers = self.offset_nameservers.map(|x| x + rr_len);
341 self.offset_additional = self.offset_additional.map(|x| x + rr_len);
342 self.offset_edns = self.offset_edns.map(|x| x + rr_len);
343 }
344 Section::Answer => {
345 self.offset_answers = self.offset_answers.or(Some(insertion_offset));
346
347 self.offset_nameservers = self.offset_nameservers.map(|x| x + rr_len);
348 self.offset_additional = self.offset_additional.map(|x| x + rr_len);
349 self.offset_edns = self.offset_edns.map(|x| x + rr_len);
350 }
351 Section::NameServers => {
352 self.offset_nameservers = self.offset_nameservers.or(Some(insertion_offset));
353
354 self.offset_additional = self.offset_additional.map(|x| x + rr_len);
355 self.offset_edns = self.offset_edns.map(|x| x + rr_len);
356 }
357 Section::Additional => {
358 self.offset_additional = self.offset_additional.or(Some(insertion_offset));
359 }
360 _ => panic!("insertion_offset() is not suitable to adding EDNS pseudorecords"),
361 }
362 Ok(())
363 }
364
365 pub fn insert_rr_from_string(&mut self, section: Section, rr_str: &str) -> Result<(), Error> {
366 let rr = gen::RR::from_string(rr_str)?;
367 self.insert_rr(section, rr)
368 }
369
370 pub fn recompute(&mut self) -> Result<(), Error> {
375 if !self.maybe_compressed {
376 return Ok(());
377 }
378 let dns_sector = DNSSector::new(self.packet.take().expect("self.packet is None"))?;
379 let parsed_packet = dns_sector.parse()?;
380 self.offset_question = parsed_packet.offset_question;
381 self.offset_answers = parsed_packet.offset_answers;
382 self.offset_nameservers = parsed_packet.offset_nameservers;
383 self.offset_additional = parsed_packet.offset_additional;
384 self.offset_edns = parsed_packet.offset_edns;
385 assert_eq!(self.edns_count, parsed_packet.edns_count);
386 assert_eq!(self.ext_rcode, parsed_packet.ext_rcode);
387 assert_eq!(self.edns_version, parsed_packet.edns_version);
388 assert_eq!(self.ext_flags, parsed_packet.ext_flags);
389 self.maybe_compressed = false;
390 self.packet = Some(parsed_packet.into_packet());
391 self.cached = None;
392 Ok(())
393 }
394
395 pub fn question_raw0(&mut self) -> Option<(&[u8], u16, u16)> {
398 if let Some(ref cached) = self.cached {
399 return Some((&cached.0, cached.1, cached.2));
400 }
401 let offset = match self.offset_question {
402 None => return None,
403 Some(offset) => offset,
404 };
405 let mut name = Vec::with_capacity(DNS_MAX_HOSTNAME_LEN);
406 let uncompressed_name_result =
407 Compress::copy_uncompressed_name(&mut name, self.packet(), offset);
408 let offset = uncompressed_name_result.final_offset;
409 let (rr_type, rr_class) = {
410 let rdata = &self.packet()[offset..];
411 let rr_type = BigEndian::read_u16(&rdata[DNS_RR_TYPE_OFFSET..]);
412 let rr_class = BigEndian::read_u16(&rdata[DNS_RR_CLASS_OFFSET..]);
413 (rr_type, rr_class)
414 };
415 self.cached = Some((name, rr_type, rr_class));
416 let cached = self.cached.as_ref().unwrap();
417 Some((&cached.0, cached.1, cached.2))
418 }
419
420 pub fn question_raw(&mut self) -> Option<(&[u8], u16, u16)> {
423 self.question_raw0()
424 .map(|(name, rr_type, rr_class)| (&name[..name.len() - 1], rr_type, rr_class))
425 }
426
427 pub fn question(&mut self) -> Option<(Vec<u8>, u16, u16)> {
430 if let Some(ref cached) = self.cached {
431 let mut name_str = Compress::raw_name_to_str(&cached.0, 0);
432 name_str.make_ascii_lowercase();
433 return Some((name_str, cached.1, cached.2));
434 }
435 let offset = match self.offset_question {
436 None => return None,
437 Some(offset) => offset,
438 };
439 let mut name_str = Compress::raw_name_to_str(self.packet(), offset);
440 name_str.make_ascii_lowercase();
441 let offset = offset + Compress::raw_name_len(&self.packet()[offset..]);
442 let (rr_type, rr_class) = {
443 let rdata = &self.packet()[offset..];
444 let rr_type = BigEndian::read_u16(&rdata[DNS_RR_TYPE_OFFSET..]);
445 let rr_class = BigEndian::read_u16(&rdata[DNS_RR_CLASS_OFFSET..]);
446 (rr_type, rr_class)
447 };
448 Some((name_str, rr_type, rr_class))
449 }
450
451 pub fn qtype_qclass(&self) -> Option<(u16, u16)> {
453 if let Some(ref cached) = self.cached {
454 return Some((cached.1, cached.2));
455 }
456 let offset = match self.offset_question {
457 None => return None,
458 Some(offset) => offset,
459 };
460 let offset = offset + Compress::raw_name_len(&self.packet()[offset..]);
461 let (rr_type, rr_class) = {
462 let rdata = &self.packet()[offset..];
463 let rr_type = BigEndian::read_u16(&rdata[DNS_RR_TYPE_OFFSET..]);
464 let rr_class = BigEndian::read_u16(&rdata[DNS_RR_CLASS_OFFSET..]);
465 (rr_type, rr_class)
466 };
467 Some((rr_type, rr_class))
468 }
469
470 pub fn rename_with_raw_names(
474 &mut self,
475 target_name: &[u8],
476 source_name: &[u8],
477 match_suffix: bool,
478 ) -> Result<(), Error> {
479 let packet = Renamer::rename_with_raw_names(self, target_name, source_name, match_suffix)?;
480 self.packet = Some(packet);
481 let dns_sector = DNSSector::new(self.packet.take().unwrap())?;
482 let parsed_packet = dns_sector.parse()?; self.offset_question = parsed_packet.offset_question;
484 self.offset_answers = parsed_packet.offset_answers;
485 self.offset_nameservers = parsed_packet.offset_nameservers;
486 self.offset_additional = parsed_packet.offset_additional;
487 self.offset_edns = parsed_packet.offset_edns;
488 assert_eq!(self.edns_count, parsed_packet.edns_count);
489 assert_eq!(self.ext_rcode, parsed_packet.ext_rcode);
490 assert_eq!(self.edns_version, parsed_packet.edns_version);
491 assert_eq!(self.ext_flags, parsed_packet.ext_flags);
492 self.maybe_compressed = true;
493 Ok(())
494 }
495}