domain/base/header.rs
1//! The header of a DNS message.
2//!
3//! Each DNS message starts with a twelve octet long header section
4//! containing some general information related to the message as well as
5//! the number of records in each of the four sections that follow the header.
6//! Its content and format are defined in section 4.1.1 of [RFC 1035].
7//!
8//! In order to reflect the fact that changing the section counts may
9//! invalidate the rest of the message whereas the other elements of the
10//! header section can safely be modified, the whole header has been split
11//! into two separate types: [`Header`] contains the safely modifyable part
12//! at the beginning and [`HeaderCounts`] contains the section counts. In
13//! addition, the [`HeaderSection`] type wraps both of them into a single
14//! type.
15//!
16//! [RFC 1035]: https://tools.ietf.org/html/rfc1035
17
18use super::iana::{Opcode, Rcode};
19use super::wire::ParseError;
20use core::convert::TryInto;
21use core::{fmt, mem, str::FromStr};
22use octseq::builder::OctetsBuilder;
23use octseq::parse::Parser;
24
25//------------ Header --------------------------------------------------
26
27/// The first part of the header of a DNS message.
28///
29/// This type represents the information contained in the first four octets
30/// of the header: the message ID, opcode, rcode, and the various flags. It
31/// keeps those four octets in wire representation, i.e., in network byte
32/// order. The data is layed out like this:
33///
34/// ```text
35/// 1 1 1 1 1 1
36/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
37/// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
38/// | ID |
39/// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
40/// |QR| Opcode |AA|TC|RD|RA|Z |AD|CD| RCODE |
41/// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
42/// ```
43///
44/// Methods are available for accessing each of these fields. For more
45/// information on the fields, see these methods in the section
46/// [Field Access] below.
47///
48/// You can create owned values via the [`new`][Self::new] method or
49/// the `Default` trait. However, more often the type will
50/// be used via a reference into the octets of an actual message. The
51/// functions [`for_message_slice`][Self::for_message_slice] and
52/// [`for_message_slice_mut`][Self::for_message_slice_mut] create such
53/// references from an octets slice.
54///
55/// The basic structure and most of the fields re defined in [RFC 1035],
56/// except for the AD and CD flags, which are defined in [RFC 4035].
57///
58/// [Field Access]: #field-access
59/// [RFC 1035]: https://tools.ietf.org/html/rfc1035
60/// [RFC 4035]: https://tools.ietf.org/html/rfc4035
61#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
62pub struct Header {
63 /// The actual header in its wire format representation.
64 ///
65 /// This means that the ID field is in big endian.
66 inner: [u8; 4],
67}
68
69/// # Creation and Conversion
70///
71impl Header {
72 /// Creates a new header.
73 ///
74 /// The new header has all fields as either zero or false. Thus, the
75 /// opcode will be [`Opcode::Query`] and the response code will be
76 /// [`Rcode::NoError`].
77 #[must_use]
78 pub fn new() -> Self {
79 Self::default()
80 }
81
82 /// Creates a header reference from an octets slice of a message.
83 ///
84 /// # Panics
85 ///
86 /// This function panics if the slice is less than four octets long.
87 #[must_use]
88 pub fn for_message_slice(s: &[u8]) -> &Header {
89 assert!(s.len() >= mem::size_of::<Header>());
90 unsafe { &*(s.as_ptr() as *const Header) }
91 }
92
93 /// Creates a mutable header reference from an octets slice of a message.
94 ///
95 /// # Panics
96 ///
97 /// This function panics if the slice is less than four octets long.
98 pub fn for_message_slice_mut(s: &mut [u8]) -> &mut Header {
99 assert!(s.len() >= mem::size_of::<Header>());
100 unsafe { &mut *(s.as_mut_ptr() as *mut Header) }
101 }
102
103 /// Returns a reference to the underlying octets slice.
104 #[must_use]
105 pub fn as_slice(&self) -> &[u8] {
106 &self.inner
107 }
108}
109
110/// # Field Access
111///
112impl Header {
113 /// Returns the value of the ID field.
114 ///
115 /// The ID field is an identifier chosen by whoever created a query
116 /// and is copied into a response by a server. It allows matching
117 /// incoming responses to their queries.
118 ///
119 /// When choosing an ID for an outgoing message, make sure it is random
120 /// to avoid spoofing by guessing the message ID. If `std` support
121 /// is enabled, the method
122 #[cfg_attr(
123 feature = "std",
124 doc = "[`set_random_id`][Self::set_random_id]"
125 )]
126 #[cfg_attr(not(feature = "std"), doc = "`set_random_id`")]
127 /// can be used for this purpose.
128 #[must_use]
129 pub fn id(self) -> u16 {
130 u16::from_be_bytes(self.inner[..2].try_into().unwrap())
131 }
132
133 /// Sets the value of the ID field.
134 pub fn set_id(&mut self, value: u16) {
135 self.inner[..2].copy_from_slice(&value.to_be_bytes())
136 }
137
138 /// Sets the value of the ID field to a randomly chosen number.
139 #[cfg(feature = "rand")]
140 pub fn set_random_id(&mut self) {
141 self.set_id(::rand::random())
142 }
143
144 /// Returns whether the [QR](Flags::qr) bit is set.
145 #[must_use]
146 pub fn qr(self) -> bool {
147 self.get_bit(2, 7)
148 }
149
150 /// Sets the value of the [QR](Flags::qr) bit.
151 pub fn set_qr(&mut self, set: bool) {
152 self.set_bit(2, 7, set)
153 }
154
155 /// Returns the value of the Opcode field.
156 ///
157 /// This field specifies the kind of query a message contains. See
158 /// the [`Opcode`] type for more information on the possible values and
159 /// their meaning. Normal queries have the variant [`Opcode::Query`]
160 /// which is also the default value when creating a new header.
161 #[must_use]
162 pub fn opcode(self) -> Opcode {
163 Opcode::from_int((self.inner[2] >> 3) & 0x0F)
164 }
165
166 /// Sets the value of the opcode field.
167 pub fn set_opcode(&mut self, opcode: Opcode) {
168 self.inner[2] = self.inner[2] & 0x87 | (opcode.to_int() << 3);
169 }
170
171 /// Returns all flags contained in the header.
172 ///
173 /// This is a virtual field composed of all the flag bits that are present
174 /// in the header. The returned [`Flags`] type can be useful when you're
175 /// working with all flags, rather than a single one, which can be easily
176 /// obtained from the header directly.
177 #[must_use]
178 pub fn flags(self) -> Flags {
179 Flags {
180 qr: self.qr(),
181 aa: self.aa(),
182 tc: self.tc(),
183 rd: self.rd(),
184 ra: self.ra(),
185 ad: self.ad(),
186 cd: self.cd(),
187 }
188 }
189
190 /// Sets all flag bits.
191 pub fn set_flags(&mut self, flags: Flags) {
192 self.set_qr(flags.qr);
193 self.set_aa(flags.aa);
194 self.set_tc(flags.tc);
195 self.set_rd(flags.rd);
196 self.set_ra(flags.ra);
197 self.set_ad(flags.ad);
198 self.set_cd(flags.cd);
199 }
200
201 /// Returns whether the [AA](Flags::aa) bit is set.
202 #[must_use]
203 pub fn aa(self) -> bool {
204 self.get_bit(2, 2)
205 }
206
207 /// Sets the value of the [AA](Flags::aa) bit.
208 pub fn set_aa(&mut self, set: bool) {
209 self.set_bit(2, 2, set)
210 }
211
212 /// Returns whether the [TC](Flags::tc) bit is set.
213 #[must_use]
214 pub fn tc(self) -> bool {
215 self.get_bit(2, 1)
216 }
217
218 /// Sets the value of the [TC](Flags::tc) bit.
219 pub fn set_tc(&mut self, set: bool) {
220 self.set_bit(2, 1, set)
221 }
222
223 /// Returns whether the [RD](Flags::rd) bit is set.
224 #[must_use]
225 pub fn rd(self) -> bool {
226 self.get_bit(2, 0)
227 }
228
229 /// Sets the value of the [RD](Flags::rd) bit.
230 pub fn set_rd(&mut self, set: bool) {
231 self.set_bit(2, 0, set)
232 }
233
234 /// Returns whether the [RA](Flags::ra) bit is set.
235 #[must_use]
236 pub fn ra(self) -> bool {
237 self.get_bit(3, 7)
238 }
239
240 /// Sets the value of the [RA](Flags::ra) bit.
241 pub fn set_ra(&mut self, set: bool) {
242 self.set_bit(3, 7, set)
243 }
244
245 /// Returns whether the reserved bit is set.
246 ///
247 /// This bit must be `false` in all queries and responses.
248 #[must_use]
249 pub fn z(self) -> bool {
250 self.get_bit(3, 6)
251 }
252
253 /// Sets the value of the reserved bit.
254 pub fn set_z(&mut self, set: bool) {
255 self.set_bit(3, 6, set)
256 }
257
258 /// Returns whether the [AD](Flags::ad) bit is set.
259 #[must_use]
260 pub fn ad(self) -> bool {
261 self.get_bit(3, 5)
262 }
263
264 /// Sets the value of the [AD](Flags::ad) bit.
265 pub fn set_ad(&mut self, set: bool) {
266 self.set_bit(3, 5, set)
267 }
268
269 /// Returns whether the [CD](Flags::cd) bit is set.
270 #[must_use]
271 pub fn cd(self) -> bool {
272 self.get_bit(3, 4)
273 }
274
275 /// Sets the value of the [CD](Flags::cd) bit.
276 pub fn set_cd(&mut self, set: bool) {
277 self.set_bit(3, 4, set)
278 }
279
280 /// Returns the value of the RCODE field.
281 ///
282 /// The *response code* is used in a response to indicate what happened
283 /// when processing the query. See the [`Rcode`] type for information on
284 /// possible values and their meaning.
285 ///
286 /// [`Rcode`]: ../../iana/rcode/enum.Rcode.html
287 #[must_use]
288 pub fn rcode(self) -> Rcode {
289 Rcode::from_int(self.inner[3] & 0x0F)
290 }
291
292 /// Sets the value of the RCODE field.
293 pub fn set_rcode(&mut self, rcode: Rcode) {
294 self.inner[3] = self.inner[3] & 0xF0 | (rcode.to_int() & 0x0F);
295 }
296
297 //--- Internal helpers
298
299 /// Returns the value of the bit at the given position.
300 ///
301 /// The argument `offset` gives the byte offset of the underlying bytes
302 /// slice and `bit` gives the number of the bit with the most significant
303 /// bit being 7.
304 fn get_bit(self, offset: usize, bit: usize) -> bool {
305 self.inner[offset] & (1 << bit) != 0
306 }
307
308 /// Sets or resets the given bit.
309 fn set_bit(&mut self, offset: usize, bit: usize, set: bool) {
310 if set {
311 self.inner[offset] |= 1 << bit
312 } else {
313 self.inner[offset] &= !(1 << bit)
314 }
315 }
316}
317
318//------------ Flags ---------------------------------------------------
319
320/// The flags contained in the DNS message header.
321///
322/// This is a utility type that makes it easier to work with flags. It contains
323/// only standard DNS message flags that are part of the [`Header`], i.e., EDNS
324/// flags are not included.
325///
326/// This type has a text notation and can be created from it as well. Each
327/// flags that is set is represented by a two-letter token, which is the
328/// uppercase version of the flag name. If mutliple flags are set, the tokens
329/// are separated by space.
330///
331/// ```
332/// use core::str::FromStr;
333/// use domain::base::header::Flags;
334///
335/// let flags = Flags::from_str("QR AA").unwrap();
336/// assert!(flags.qr && flags.aa);
337/// assert_eq!(format!("{}", flags), "QR AA");
338/// ```
339#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
340pub struct Flags {
341 /// The `QR` bit specifies whether a message is a query (`false`) or a
342 /// response (`true`). In other words, this bit is actually stating whether
343 /// the message is *not* a query. So, perhaps it might be good to read ‘QR’
344 /// as ‘query response.’
345 pub qr: bool,
346
347 /// Using the `AA` bit, a name server generating a response states whether
348 /// it is authoritative for the requested domain name, ie., whether this
349 /// response is an *authoritative answer.* The field has no meaning in a
350 /// query.
351 pub aa: bool,
352
353 /// The *truncation* (`TC`) bit is set if there was more data available then
354 /// fit into the message. This is typically used when employing datagram
355 /// transports such as UDP to signal that the answer didn’t fit into a
356 /// response and the query should be tried again using a stream transport
357 /// such as TCP.
358 pub tc: bool,
359
360 /// The *recursion desired* (`RD`) bit may be set in a query to ask the name
361 /// server to try and recursively gather a response if it doesn’t have the
362 /// data available locally. The bit’s value is copied into the response.
363 pub rd: bool,
364
365 /// In a response, the *recursion available* (`RA`) bit denotes whether the
366 /// responding name server supports recursion. It has no meaning in a query.
367 pub ra: bool,
368
369 /// The *authentic data* (`AD`) bit is used by security-aware recursive name
370 /// servers to indicate that it considers all RRsets in its response are
371 /// authentic, i.e., have successfully passed DNSSEC validation.
372 pub ad: bool,
373
374 /// The *checking disabled* (`CD`) bit is used by a security-aware resolver
375 /// to indicate that it does not want upstream name servers to perform
376 /// verification but rather would like to verify everything itself.
377 pub cd: bool,
378}
379
380/// # Creation and Conversion
381///
382impl Flags {
383 /// Creates new flags.
384 ///
385 /// All flags will be unset.
386 #[must_use]
387 pub fn new() -> Self {
388 Self::default()
389 }
390}
391
392//--- Display & FromStr
393
394impl fmt::Display for Flags {
395 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
396 let mut sep = "";
397 if self.qr {
398 write!(f, "QR")?;
399 sep = " ";
400 }
401 if self.aa {
402 write!(f, "{}AA", sep)?;
403 sep = " ";
404 }
405 if self.tc {
406 write!(f, "{}TC", sep)?;
407 sep = " ";
408 }
409 if self.rd {
410 write!(f, "{}RD", sep)?;
411 sep = " ";
412 }
413 if self.ra {
414 write!(f, "{}RA", sep)?;
415 sep = " ";
416 }
417 if self.ad {
418 write!(f, "{}AD", sep)?;
419 sep = " ";
420 }
421 if self.cd {
422 write!(f, "{}CD", sep)?;
423 }
424 Ok(())
425 }
426}
427
428impl FromStr for Flags {
429 type Err = FlagsFromStrError;
430
431 fn from_str(s: &str) -> Result<Self, Self::Err> {
432 let mut flags = Flags::new();
433 for token in s.split(' ') {
434 match token {
435 "QR" | "Qr" | "qR" | "qr" => flags.qr = true,
436 "AA" | "Aa" | "aA" | "aa" => flags.aa = true,
437 "TC" | "Tc" | "tC" | "tc" => flags.tc = true,
438 "RD" | "Rd" | "rD" | "rd" => flags.rd = true,
439 "RA" | "Ra" | "rA" | "ra" => flags.ra = true,
440 "AD" | "Ad" | "aD" | "ad" => flags.ad = true,
441 "CD" | "Cd" | "cD" | "cd" => flags.cd = true,
442 "" => {}
443 _ => return Err(FlagsFromStrError),
444 }
445 }
446 Ok(flags)
447 }
448}
449
450//------------ HeaderCounts -------------------------------------------------
451
452/// The section count part of the header section of a DNS message.
453///
454/// This part consists of four 16 bit counters for the number of entries in
455/// the four sections of a DNS message. The type contains the sequence of
456/// these for values in wire format, i.e., in network byte order.
457///
458/// The counters are arranged in the same order as the sections themselves:
459/// QDCOUNT for the question section, ANCOUNT for the answer section,
460/// NSCOUNT for the authority section, and ARCOUNT for the additional section.
461/// These are defined in [RFC 1035].
462///
463/// Like with the other header part, you can create an owned value via the
464/// [`new`][Self::new] method or the `Default` trait or can get a reference
465/// to the value atop a message slice via
466/// [`for_message_slice`][Self::for_message_slice] or
467/// [`for_message_slice_mut`][Self::for_message_slice_mut].
468///
469/// For each field there are three methods for getting, setting, and
470/// incrementing.
471///
472/// [RFC 2136] defines the UPDATE method and reuses the four section for
473/// different purposes. Here the counters are ZOCOUNT for the zone section,
474/// PRCOUNT for the prerequisite section, UPCOUNT for the update section,
475/// and ADCOUNT for the additional section. The type has convenience methods
476/// for these fields as well so you don’t have to remember which is which.
477///
478/// [RFC 1035]: https://tools.ietf.org/html/rfc1035
479/// [RFC 2136]: https://tools.ietf.org/html/rfc2136
480#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
481pub struct HeaderCounts {
482 /// The actual headers in their wire-format representation.
483 ///
484 /// Ie., all values are stored big endian.
485 inner: [u8; 8],
486}
487
488/// # Creation and Conversion
489///
490impl HeaderCounts {
491 /// Creates a new value with all counters set to zero.
492 #[must_use]
493 pub fn new() -> Self {
494 Self::default()
495 }
496
497 /// Creates a header counts reference from the octets slice of a message.
498 ///
499 /// The slice `message` mut be the whole message, i.e., start with the
500 /// bytes of the [`Header`](struct.Header.html).
501 ///
502 /// # Panics
503 ///
504 /// This function panics if the octets slice is shorter than 24 octets.
505 #[must_use]
506 pub fn for_message_slice(message: &[u8]) -> &Self {
507 assert!(message.len() >= mem::size_of::<HeaderSection>());
508 unsafe {
509 &*((message[mem::size_of::<Header>()..].as_ptr())
510 as *const HeaderCounts)
511 }
512 }
513
514 /// Creates a mutable counts reference from the octets slice of a message.
515 ///
516 /// The slice `message` mut be the whole message, i.e., start with the
517 /// bytes of the [`Header`].
518 ///
519 /// # Panics
520 ///
521 /// This function panics if the octets slice is shorter than 24 octets.
522 pub fn for_message_slice_mut(message: &mut [u8]) -> &mut Self {
523 assert!(message.len() >= mem::size_of::<HeaderSection>());
524 unsafe {
525 &mut *((message[mem::size_of::<Header>()..].as_mut_ptr())
526 as *mut HeaderCounts)
527 }
528 }
529
530 /// Returns a reference to the raw octets slice of the header counts.
531 #[must_use]
532 pub fn as_slice(&self) -> &[u8] {
533 &self.inner
534 }
535
536 /// Returns a mutable reference to the octets slice of the header counts.
537 pub fn as_slice_mut(&mut self) -> &mut [u8] {
538 &mut self.inner
539 }
540
541 /// Sets the counts to those from `counts`.
542 pub fn set(&mut self, counts: HeaderCounts) {
543 self.as_slice_mut().copy_from_slice(counts.as_slice())
544 }
545}
546
547/// # Field Access
548///
549impl HeaderCounts {
550 //--- Count fields in regular messages
551
552 /// Returns the value of the QDCOUNT field.
553 ///
554 /// This field contains the number of questions in the first
555 /// section of the message, normally the question section.
556 #[must_use]
557 pub fn qdcount(self) -> u16 {
558 self.get_u16(0)
559 }
560
561 /// Sets the value of the QDCOUNT field.
562 pub fn set_qdcount(&mut self, value: u16) {
563 self.set_u16(0, value)
564 }
565
566 /// Increases the value of the QDCOUNT field by one.
567 ///
568 /// If increasing the counter would result in an overflow, returns an
569 /// error.
570 pub fn inc_qdcount(&mut self) -> Result<(), CountOverflow> {
571 match self.qdcount().checked_add(1) {
572 Some(count) => {
573 self.set_qdcount(count);
574 Ok(())
575 }
576 None => Err(CountOverflow),
577 }
578 }
579
580 /// Decreases the value of the QDCOUNT field by one.
581 ///
582 /// # Panics
583 ///
584 /// This method panics if the count is already zero.
585 pub fn dec_qdcount(&mut self) {
586 let count = self.qdcount();
587 assert!(count > 0);
588 self.set_qdcount(count - 1);
589 }
590
591 /// Returns the value of the ANCOUNT field.
592 ///
593 /// This field contains the number of resource records in the second
594 /// section of the message, normally the answer section.
595 #[must_use]
596 pub fn ancount(self) -> u16 {
597 self.get_u16(2)
598 }
599
600 /// Sets the value of the ANCOUNT field.
601 pub fn set_ancount(&mut self, value: u16) {
602 self.set_u16(2, value)
603 }
604
605 /// Increases the value of the ANCOUNT field by one.
606 ///
607 /// If increasing the counter would result in an overflow, returns an
608 /// error.
609 pub fn inc_ancount(&mut self) -> Result<(), CountOverflow> {
610 match self.ancount().checked_add(1) {
611 Some(count) => {
612 self.set_ancount(count);
613 Ok(())
614 }
615 None => Err(CountOverflow),
616 }
617 }
618
619 /// Decreases the value of the ANCOUNT field by one.
620 ///
621 /// # Panics
622 ///
623 /// This method panics if the count is already zero.
624 pub fn dec_ancount(&mut self) {
625 let count = self.ancount();
626 assert!(count > 0);
627 self.set_ancount(count - 1);
628 }
629
630 /// Returns the value of the NSCOUNT field.
631 ///
632 /// This field contains the number of resource records in the third
633 /// section of the message, normally the authority section.
634 #[must_use]
635 pub fn nscount(self) -> u16 {
636 self.get_u16(4)
637 }
638
639 /// Sets the value of the NSCOUNT field.
640 pub fn set_nscount(&mut self, value: u16) {
641 self.set_u16(4, value)
642 }
643
644 /// Increases the value of the NSCOUNT field by one.
645 ///
646 /// If increasing the counter would result in an overflow, returns an
647 /// error.
648 pub fn inc_nscount(&mut self) -> Result<(), CountOverflow> {
649 match self.nscount().checked_add(1) {
650 Some(count) => {
651 self.set_nscount(count);
652 Ok(())
653 }
654 None => Err(CountOverflow),
655 }
656 }
657
658 /// Decreases the value of the NSCOUNT field by one.
659 ///
660 /// # Panics
661 ///
662 /// This method panics if the count is already zero.
663 pub fn dec_nscount(&mut self) {
664 let count = self.nscount();
665 assert!(count > 0);
666 self.set_nscount(count - 1);
667 }
668
669 /// Returns the value of the ARCOUNT field.
670 ///
671 /// This field contains the number of resource records in the fourth
672 /// section of the message, normally the additional section.
673 #[must_use]
674 pub fn arcount(self) -> u16 {
675 self.get_u16(6)
676 }
677
678 /// Sets the value of the ARCOUNT field.
679 pub fn set_arcount(&mut self, value: u16) {
680 self.set_u16(6, value)
681 }
682
683 /// Increases the value of the ARCOUNT field by one.
684 ///
685 /// If increasing the counter would result in an overflow, returns an
686 /// error.
687 pub fn inc_arcount(&mut self) -> Result<(), CountOverflow> {
688 match self.arcount().checked_add(1) {
689 Some(count) => {
690 self.set_arcount(count);
691 Ok(())
692 }
693 None => Err(CountOverflow),
694 }
695 }
696
697 /// Decreases the value of the ARCOUNT field by one.
698 ///
699 /// # Panics
700 ///
701 /// This method panics if the count is already zero.
702 pub fn dec_arcount(&mut self) {
703 let count = self.arcount();
704 assert!(count > 0);
705 self.set_arcount(count - 1);
706 }
707
708 //--- Count fields in UPDATE messages
709
710 /// Returns the value of the ZOCOUNT field.
711 ///
712 /// This is the same as the `qdcount()`. It is used in UPDATE queries
713 /// where the first section is the zone section.
714 #[must_use]
715 pub fn zocount(self) -> u16 {
716 self.qdcount()
717 }
718
719 /// Sets the value of the ZOCOUNT field.
720 pub fn set_zocount(&mut self, value: u16) {
721 self.set_qdcount(value)
722 }
723
724 /// Returns the value of the PRCOUNT field.
725 ///
726 /// This is the same as the `ancount()`. It is used in UPDATE queries
727 /// where the first section is the prerequisite section.
728 #[must_use]
729 pub fn prcount(self) -> u16 {
730 self.ancount()
731 }
732
733 /// Sete the value of the PRCOUNT field.
734 pub fn set_prcount(&mut self, value: u16) {
735 self.set_ancount(value)
736 }
737
738 /// Returns the value of the UPCOUNT field.
739 ///
740 /// This is the same as the `nscount()`. It is used in UPDATE queries
741 /// where the first section is the update section.
742 #[must_use]
743 pub fn upcount(self) -> u16 {
744 self.nscount()
745 }
746
747 /// Sets the value of the UPCOUNT field.
748 pub fn set_upcount(&mut self, value: u16) {
749 self.set_nscount(value)
750 }
751
752 /// Returns the value of the ADCOUNT field.
753 ///
754 /// This is the same as the `arcount()`. It is used in UPDATE queries
755 /// where the first section is the additional section.
756 #[must_use]
757 pub fn adcount(self) -> u16 {
758 self.arcount()
759 }
760
761 /// Sets the value of the ADCOUNT field.
762 pub fn set_adcount(&mut self, value: u16) {
763 self.set_arcount(value)
764 }
765
766 //--- Internal helpers
767
768 /// Returns the value of the 16 bit integer starting at a given offset.
769 fn get_u16(self, offset: usize) -> u16 {
770 u16::from_be_bytes(self.inner[offset..offset + 2].try_into().unwrap())
771 }
772
773 /// Sets the value of the 16 bit integer starting at a given offset.
774 fn set_u16(&mut self, offset: usize, value: u16) {
775 self.inner[offset..offset + 2].copy_from_slice(&value.to_be_bytes())
776 }
777}
778
779//------------ HeaderSection -------------------------------------------------
780
781/// The complete header section of a DNS message.
782///
783/// Consists of a [`Header`] directly followed by a [`HeaderCounts`].
784///
785/// You can create an owned value via the [`new`][Self::new] function or the
786/// `Default` trait and acquire a pointer referring the the header section of
787/// an existing DNS message via the
788/// [`for_message_slice`][Self::for_message_slice] or
789/// [`for_message_slice_mut`][Self::for_message_slice_mut]
790/// functions.
791#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
792pub struct HeaderSection {
793 inner: [u8; 12],
794}
795
796/// # Creation and Conversion
797///
798impl HeaderSection {
799 /// Creates a new header section.
800 ///
801 /// The value will have all header and header counts fields set to zero
802 /// or false.
803 #[must_use]
804 pub fn new() -> Self {
805 Self::default()
806 }
807
808 /// Creates a reference from the octets slice of a message.
809 ///
810 /// # Panics
811 ///
812 /// This function panics if the octets slice is shorter than 12 octets.
813 #[must_use]
814 pub fn for_message_slice(s: &[u8]) -> &HeaderSection {
815 assert!(s.len() >= mem::size_of::<HeaderSection>());
816 unsafe { &*(s.as_ptr() as *const HeaderSection) }
817 }
818
819 /// Creates a mutable reference from the octets slice of a message.
820 ///
821 /// # Panics
822 ///
823 /// This function panics if the octets slice is shorter than 12 octets.
824 pub fn for_message_slice_mut(s: &mut [u8]) -> &mut HeaderSection {
825 assert!(s.len() >= mem::size_of::<HeaderSection>());
826 unsafe { &mut *(s.as_mut_ptr() as *mut HeaderSection) }
827 }
828
829 /// Returns a reference to the underlying octets slice.
830 #[must_use]
831 pub fn as_slice(&self) -> &[u8] {
832 &self.inner
833 }
834}
835
836/// # Access to Header and Counts
837///
838impl HeaderSection {
839 /// Returns a reference to the header.
840 #[must_use]
841 pub fn header(&self) -> &Header {
842 Header::for_message_slice(&self.inner)
843 }
844
845 /// Returns a mutable reference to the header.
846 pub fn header_mut(&mut self) -> &mut Header {
847 Header::for_message_slice_mut(&mut self.inner)
848 }
849
850 /// Returns a reference to the header counts.
851 #[must_use]
852 pub fn counts(&self) -> &HeaderCounts {
853 HeaderCounts::for_message_slice(&self.inner)
854 }
855
856 /// Returns a mutable reference to the header counts.
857 pub fn counts_mut(&mut self) -> &mut HeaderCounts {
858 HeaderCounts::for_message_slice_mut(&mut self.inner)
859 }
860}
861
862/// # Parsing and Composing
863///
864impl HeaderSection {
865 pub fn parse<Octs: AsRef<[u8]>>(
866 parser: &mut Parser<Octs>,
867 ) -> Result<Self, ParseError> {
868 let mut res = Self::default();
869 parser.parse_buf(&mut res.inner)?;
870 Ok(res)
871 }
872
873 pub fn compose<Target: OctetsBuilder + ?Sized>(
874 &self,
875 target: &mut Target,
876 ) -> Result<(), Target::AppendError> {
877 target.append_slice(&self.inner)
878 }
879}
880
881//--- AsRef and AsMut
882
883impl AsRef<Header> for HeaderSection {
884 fn as_ref(&self) -> &Header {
885 self.header()
886 }
887}
888
889impl AsMut<Header> for HeaderSection {
890 fn as_mut(&mut self) -> &mut Header {
891 self.header_mut()
892 }
893}
894
895impl AsRef<HeaderCounts> for HeaderSection {
896 fn as_ref(&self) -> &HeaderCounts {
897 self.counts()
898 }
899}
900
901impl AsMut<HeaderCounts> for HeaderSection {
902 fn as_mut(&mut self) -> &mut HeaderCounts {
903 self.counts_mut()
904 }
905}
906
907//============ Error Types ===================================================
908
909//------------ FlagsFromStrError --------------------------------------------
910
911/// An error happened when converting string to flags.
912#[derive(Debug)]
913pub struct FlagsFromStrError;
914
915impl fmt::Display for FlagsFromStrError {
916 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
917 write!(f, "illegal flags token")
918 }
919}
920
921#[cfg(feature = "std")]
922impl std::error::Error for FlagsFromStrError {}
923
924//------------ CountOverflow -------------------------------------------------
925
926/// An error happened while increasing a header count.
927#[derive(Debug)]
928pub struct CountOverflow;
929
930impl fmt::Display for CountOverflow {
931 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
932 write!(f, "increasing a header count lead to an overflow")
933 }
934}
935
936#[cfg(feature = "std")]
937impl std::error::Error for CountOverflow {}
938
939//============ Testing ======================================================
940
941#[cfg(test)]
942mod test {
943 use super::*;
944 use crate::base::iana::{Opcode, Rcode};
945
946 #[test]
947 #[cfg(feature = "std")]
948 fn for_slice() {
949 use std::vec::Vec;
950
951 let header = b"\x01\x02\x00\x00\x12\x34\x56\x78\x9a\xbc\xde\xf0";
952 let mut vec = Vec::from(&header[..]);
953 assert_eq!(
954 Header::for_message_slice(header).as_slice(),
955 b"\x01\x02\x00\x00"
956 );
957 assert_eq!(
958 Header::for_message_slice_mut(vec.as_mut()).as_slice(),
959 b"\x01\x02\x00\x00"
960 );
961 assert_eq!(
962 HeaderCounts::for_message_slice(header).as_slice(),
963 b"\x12\x34\x56\x78\x9a\xbc\xde\xf0"
964 );
965 assert_eq!(
966 HeaderCounts::for_message_slice_mut(vec.as_mut()).as_slice(),
967 b"\x12\x34\x56\x78\x9a\xbc\xde\xf0"
968 );
969 assert_eq!(
970 HeaderSection::for_message_slice(header).as_slice(),
971 header
972 );
973 assert_eq!(
974 HeaderSection::for_message_slice_mut(vec.as_mut()).as_slice(),
975 header
976 );
977 }
978
979 #[test]
980 #[should_panic]
981 fn short_header() {
982 let _ = Header::for_message_slice(b"134");
983 }
984
985 #[test]
986 #[should_panic]
987 fn short_header_counts() {
988 let _ = HeaderCounts::for_message_slice(b"12345678");
989 }
990
991 #[test]
992 #[should_panic]
993 fn short_header_section() {
994 let _ = HeaderSection::for_message_slice(b"1234");
995 }
996
997 macro_rules! test_field {
998 ($get:ident, $set:ident, $default:expr, $($value:expr),*) => {
999 $({
1000 let mut h = Header::new();
1001 assert_eq!(h.$get(), $default);
1002 h.$set($value);
1003 assert_eq!(h.$get(), $value);
1004 })*
1005 }
1006 }
1007
1008 #[test]
1009 #[allow(clippy::bool_assert_comparison)]
1010 fn header() {
1011 test_field!(id, set_id, 0, 0x1234);
1012 test_field!(qr, set_qr, false, true, false);
1013 test_field!(opcode, set_opcode, Opcode::Query, Opcode::Notify);
1014 test_field!(
1015 flags,
1016 set_flags,
1017 Flags::new(),
1018 Flags {
1019 qr: true,
1020 ..Default::default()
1021 }
1022 );
1023 test_field!(aa, set_aa, false, true, false);
1024 test_field!(tc, set_tc, false, true, false);
1025 test_field!(rd, set_rd, false, true, false);
1026 test_field!(ra, set_ra, false, true, false);
1027 test_field!(z, set_z, false, true, false);
1028 test_field!(ad, set_ad, false, true, false);
1029 test_field!(cd, set_cd, false, true, false);
1030 test_field!(rcode, set_rcode, Rcode::NoError, Rcode::Refused);
1031 }
1032
1033 #[test]
1034 fn counts() {
1035 let mut c = HeaderCounts {
1036 inner: [1, 2, 3, 4, 5, 6, 7, 8],
1037 };
1038 assert_eq!(c.qdcount(), 0x0102);
1039 assert_eq!(c.ancount(), 0x0304);
1040 assert_eq!(c.nscount(), 0x0506);
1041 assert_eq!(c.arcount(), 0x0708);
1042 c.inc_qdcount().unwrap();
1043 c.inc_ancount().unwrap();
1044 c.inc_nscount().unwrap();
1045 c.inc_arcount().unwrap();
1046 assert_eq!(c.inner, [1, 3, 3, 5, 5, 7, 7, 9]);
1047 c.set_qdcount(0x0807);
1048 c.set_ancount(0x0605);
1049 c.set_nscount(0x0403);
1050 c.set_arcount(0x0201);
1051 assert_eq!(c.inner, [8, 7, 6, 5, 4, 3, 2, 1]);
1052 }
1053
1054 #[test]
1055 fn update_counts() {
1056 let mut c = HeaderCounts {
1057 inner: [1, 2, 3, 4, 5, 6, 7, 8],
1058 };
1059 assert_eq!(c.zocount(), 0x0102);
1060 assert_eq!(c.prcount(), 0x0304);
1061 assert_eq!(c.upcount(), 0x0506);
1062 assert_eq!(c.adcount(), 0x0708);
1063 c.set_zocount(0x0807);
1064 c.set_prcount(0x0605);
1065 c.set_upcount(0x0403);
1066 c.set_adcount(0x0201);
1067 assert_eq!(c.inner, [8, 7, 6, 5, 4, 3, 2, 1]);
1068 }
1069
1070 #[test]
1071 fn inc_qdcount() {
1072 let mut c = HeaderCounts {
1073 inner: [0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1074 };
1075 assert!(c.inc_qdcount().is_ok());
1076 assert!(c.inc_qdcount().is_err());
1077 }
1078
1079 #[test]
1080 fn inc_ancount() {
1081 let mut c = HeaderCounts {
1082 inner: [0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff],
1083 };
1084 assert!(c.inc_ancount().is_ok());
1085 assert!(c.inc_ancount().is_err());
1086 }
1087
1088 #[test]
1089 fn inc_nscount() {
1090 let mut c = HeaderCounts {
1091 inner: [0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff],
1092 };
1093 assert!(c.inc_nscount().is_ok());
1094 assert!(c.inc_nscount().is_err());
1095 }
1096
1097 #[test]
1098 fn inc_arcount() {
1099 let mut c = HeaderCounts {
1100 inner: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe],
1101 };
1102 assert!(c.inc_arcount().is_ok());
1103 assert!(c.inc_arcount().is_err());
1104 }
1105
1106 #[cfg(feature = "std")]
1107 #[test]
1108 fn flags_display() {
1109 let f = Flags::new();
1110 assert_eq!(format!("{}", f), "");
1111 let f = Flags {
1112 qr: true,
1113 aa: true,
1114 tc: true,
1115 rd: true,
1116 ra: true,
1117 ad: true,
1118 cd: true,
1119 };
1120 assert_eq!(format!("{}", f), "QR AA TC RD RA AD CD");
1121 let mut f = Flags::new();
1122 f.rd = true;
1123 f.cd = true;
1124 assert_eq!(format!("{}", f), "RD CD");
1125 }
1126
1127 #[cfg(feature = "std")]
1128 #[test]
1129 fn flags_from_str() {
1130 let f1 = Flags::from_str("").unwrap();
1131 let f2 = Flags::new();
1132 assert_eq!(f1, f2);
1133 let f1 = Flags::from_str("QR AA TC RD RA AD CD").unwrap();
1134 let f2 = Flags {
1135 qr: true,
1136 aa: true,
1137 tc: true,
1138 rd: true,
1139 ra: true,
1140 ad: true,
1141 cd: true,
1142 };
1143 assert_eq!(f1, f2);
1144 let f1 = Flags::from_str("tC Aa CD rd").unwrap();
1145 let f2 = Flags {
1146 aa: true,
1147 tc: true,
1148 rd: true,
1149 cd: true,
1150 ..Default::default()
1151 };
1152 assert_eq!(f1, f2);
1153 let f1 = Flags::from_str("XXXX");
1154 assert!(f1.is_err());
1155 }
1156}