1use std::cmp::max;
44use std::collections::HashMap;
45use std::fmt::{self, Display};
46use std::io::{Cursor, Read, Write};
47
48use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
49use owo_colors::OwoColorize;
50use rand::Rng;
51use rdata::opt::OptionCode;
52use repr_with_fallback::repr_with_fallback;
53#[cfg(feature = "serde")]
54use serde::Serialize;
55use strum_macros::EnumString;
56
57pub mod dnssec;
59pub mod error;
60pub mod name;
61pub mod rdata;
62
63use error::{DnssecError, EncodeError, ParseError, ToluolError};
64use rdata::{RdataTrait, OPT};
65
66pub use name::Name;
67pub use rdata::Rdata;
68
69#[cfg_attr(feature = "serde", derive(Serialize))]
74#[derive(PartialEq, Eq, Copy, Clone, Debug)]
75pub enum Opcode {
76 QUERY,
77 IQUERY,
78 STATUS,
79 NOTIFY,
80 UPDATE,
81 DSO,
82}
83
84#[cfg_attr(feature = "serde", derive(Serialize))]
90#[derive(PartialEq, Eq, Copy, Clone, Debug)]
91#[non_exhaustive]
92pub enum RCode {
93 NOERROR,
94 FORMERR,
95 SERVFAIL,
96 NXDOMAIN,
97 NOTIMP,
98 REFUSED,
99 YXDOMAIN,
100 YXRRSET,
101 NXRRSET,
102 NOTAUTH,
103 NOTZONE,
104 DSOTYPENI,
105 BADVERSBADSIG,
106 BADKEY,
107 BADTIME,
108 BADMODE,
109 BADNAME,
110 BADALG,
111 BADTRUNC,
112 BADCOOKIE,
113 }
115
116repr_with_fallback! {
117 #[cfg_attr(feature = "serde", derive(Serialize))]
125 #[derive(PartialEq, Eq, Copy, Clone, EnumString, Debug)]
126 #[non_exhaustive]
127 pub enum RecordType {
128 A = 1,
129 NS = 2,
130 CNAME = 5,
131 SOA = 6,
132 PTR = 12,
133 HINFO = 13,
134 MX = 15,
135 TXT = 16,
136 RP = 17,
137 AAAA = 28,
140 LOC = 29,
141 SRV = 33,
142 NAPTR = 35,
143 CERT = 37,
144 DNAME = 39,
145 OPT = 41,
146 DS = 43,
147 SSHFP = 44,
148 RRSIG = 46,
150 NSEC = 47,
151 DNSKEY = 48,
152 NSEC3 = 50,
154 NSEC3PARAM = 51,
155 TLSA = 52,
156 OPENPGPKEY = 61,
160 CAA = 257,
164 Unknown(u16),
167 }
168}
169
170#[cfg_attr(feature = "serde", derive(Serialize))]
176#[derive(PartialEq, Eq, Copy, Clone, Debug)]
177pub enum Class {
178 IN,
179 CH,
180 HS,
181 NONE,
182 ANY,
184}
185
186#[cfg_attr(feature = "serde", derive(Serialize))]
188#[derive(PartialEq, Eq, Copy, Clone, Debug)]
189pub struct HeaderFlags {
190 pub aa: bool,
193 pub tc: bool,
196 pub rd: bool,
199 pub ra: bool,
202 pub ad: bool,
208 pub cd: bool,
212}
213
214#[cfg_attr(feature = "serde", derive(Serialize))]
218#[derive(PartialEq, Eq, Clone, Debug)]
219pub struct Header {
220 pub msg_id: u16,
222 pub qr: bool,
224 pub opcode: Opcode,
226 pub flags: HeaderFlags,
228 pub rcode: Option<RCode>,
230 pub qdcount: u16,
232 pub ancount: u16,
234 pub nscount: u16,
236 pub arcount: u16,
238}
239
240#[cfg_attr(feature = "serde", derive(Serialize))]
244#[derive(PartialEq, Eq, Clone, Debug)]
245pub struct Question {
246 pub qname: Name,
248 pub qtype: RecordType,
250 pub qclass: Class,
252}
253
254#[cfg_attr(feature = "serde", derive(Serialize))]
259#[cfg_attr(feature = "serde", serde(untagged))]
260#[derive(PartialEq, Eq, Clone, Debug)]
261pub enum Record {
262 OPT(OptRecord),
263 NONOPT(NonOptRecord),
264}
265
266#[cfg_attr(feature = "serde", derive(Serialize))]
272#[derive(PartialEq, Eq, Copy, Clone, Debug)]
273pub enum OptFlags {
274 DO,
277}
278
279pub struct EdnsConfig {
281 pub do_flag: bool,
283 pub bufsize: u16,
285 pub client_cookie: Option<[u8; 8]>,
289 }
291
292#[cfg_attr(feature = "serde", derive(Serialize))]
296#[derive(PartialEq, Eq, Clone, Debug)]
297pub struct OptRecord {
298 pub owner: Name,
300 pub payload_size: u16,
303 pub rcode: Option<RCode>,
306 pub edns_version: u8,
308 pub flags: Vec<OptFlags>,
310 #[cfg_attr(feature = "serde", serde(skip))]
312 encoded_rdata: Vec<u8>, rdata: Rdata, }
315
316#[cfg_attr(feature = "serde", derive(Serialize))]
320#[derive(PartialEq, Eq, Clone, Debug)]
321pub struct NonOptRecord {
322 pub owner: Name,
324 pub rtype: RecordType,
326 pub class: Class,
328 pub ttl: u32,
330 #[cfg_attr(feature = "serde", serde(skip))]
332 encoded_rdata: Vec<u8>, rdata: Rdata,
334}
335
336#[cfg_attr(feature = "serde", derive(Serialize))]
340#[derive(PartialEq, Eq, Clone, Debug)]
341pub struct Message {
342 pub header: Header,
344 pub questions: Vec<Question>,
346 pub answers: Vec<Record>,
348 pub authoritative_answers: Vec<Record>,
350 pub additional_answers: Vec<Record>,
352}
353
354impl Opcode {
355 pub fn encode(&self) -> u8 {
357 match self {
358 Opcode::QUERY => 0,
359 Opcode::IQUERY => 1,
360 Opcode::STATUS => 2,
361 Opcode::NOTIFY => 4,
362 Opcode::UPDATE => 5,
363 Opcode::DSO => 6,
364 }
365 }
366
367 pub fn parse(val: u8) -> Result<Opcode, ParseError> {
371 Ok(match val {
372 0 => Opcode::QUERY,
373 1 => Opcode::IQUERY,
374 2 => Opcode::STATUS,
375 4 => Opcode::NOTIFY,
376 5 => Opcode::UPDATE,
377 6 => Opcode::DSO,
378 x => return Err(ParseError::InvalidOpcode(x)),
379 })
380 }
381}
382
383impl Display for Opcode {
384 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
385 write!(f, "{:?}", self)
386 }
387}
388
389impl RCode {
390 pub fn encode(&self) -> u8 {
396 match self {
397 RCode::NOERROR => 0,
398 RCode::FORMERR => 1,
399 RCode::SERVFAIL => 2,
400 RCode::NXDOMAIN => 3,
401 RCode::NOTIMP => 4,
402 RCode::REFUSED => 5,
403 RCode::YXDOMAIN => 6,
404 RCode::YXRRSET => 7,
405 RCode::NXRRSET => 8,
406 RCode::NOTAUTH => 9,
407 RCode::NOTZONE => 10,
408 RCode::DSOTYPENI => 11,
409 RCode::BADVERSBADSIG => 16 & 0b1111,
410 RCode::BADKEY => 17 & 0b1111,
411 RCode::BADTIME => 18 & 0b1111,
412 RCode::BADMODE => 19 & 0b1111,
413 RCode::BADNAME => 20 & 0b1111,
414 RCode::BADALG => 21 & 0b1111,
415 RCode::BADTRUNC => 22 & 0b1111,
416 RCode::BADCOOKIE => 23 & 0b1111,
417 }
418 }
419
420 pub fn parse(val: u16) -> Result<RCode, ParseError> {
426 Ok(match val {
427 0 => RCode::NOERROR,
428 1 => RCode::FORMERR,
429 2 => RCode::SERVFAIL,
430 3 => RCode::NXDOMAIN,
431 4 => RCode::NOTIMP,
432 5 => RCode::REFUSED,
433 6 => RCode::YXDOMAIN,
434 7 => RCode::YXRRSET,
435 8 => RCode::NXRRSET,
436 9 => RCode::NOTAUTH,
437 10 => RCode::NOTZONE,
438 11 => RCode::DSOTYPENI,
439 16 => RCode::BADVERSBADSIG,
440 17 => RCode::BADKEY,
441 18 => RCode::BADTIME,
442 19 => RCode::BADMODE,
443 20 => RCode::BADNAME,
444 21 => RCode::BADALG,
445 22 => RCode::BADTRUNC,
446 23 => RCode::BADCOOKIE,
447 x => return Err(ParseError::InvalidRcode(x)),
448 })
449 }
450}
451
452impl Display for RCode {
453 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
454 write!(f, "{:?}", self)
455 }
456}
457
458impl Display for RecordType {
459 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
460 match self {
461 RecordType::Unknown(x) => write!(f, "TYPE{}", x),
462 _ => write!(f, "{:?}", self),
463 }
464 }
465}
466
467impl Class {
468 pub fn encode(&self) -> u16 {
470 match self {
471 Class::IN => 1,
472 Class::CH => 3,
473 Class::HS => 4,
474 Class::NONE => 254,
475 Class::ANY => 255,
476 }
477 }
478
479 pub fn parse(val: u16) -> Result<Class, ParseError> {
483 Ok(match val {
484 1 => Class::IN,
485 3 => Class::CH,
486 4 => Class::HS,
487 254 => Class::NONE,
488 255 => Class::ANY,
489 x => return Err(ParseError::InvalidClass(x)),
490 })
491 }
492}
493
494impl Display for Class {
495 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
496 write!(f, "{:?}", self)
497 }
498}
499
500impl HeaderFlags {
501 pub fn from_flags(flags: u16) -> Self {
504 Self {
505 aa: (flags & (1 << 10)) != 0,
506 tc: (flags & (1 << 9)) != 0,
507 rd: (flags & (1 << 8)) != 0,
508 ra: (flags & (1 << 8)) != 0,
509 ad: (flags & (1 << 5)) != 0,
510 cd: (flags & (1 << 4)) != 0,
511 }
512 }
513
514 pub fn as_flags(&self) -> u16 {
517 let aa = if self.aa { 1 } else { 0 };
518 let tc = if self.tc { 1 } else { 0 };
519 let rd = if self.rd { 1 } else { 0 };
520 let ra = if self.ra { 1 } else { 0 };
521 let ad = if self.ad { 1 } else { 0 };
522 let cd = if self.cd { 1 } else { 0 };
523 (aa << 10) + (tc << 9) + (rd << 8) + (ra << 7) + (ad << 5) + (cd << 4)
524 }
525}
526
527impl Header {
528 pub fn new_response_header(
536 msg_id: u16,
537 opcode: Opcode,
538 flags: HeaderFlags,
539 rcode: RCode,
540 counts: [u16; 4],
541 ) -> Self {
542 Header {
543 msg_id,
544 qr: true,
545 opcode,
546 flags,
547 rcode: Some(rcode),
548 qdcount: counts[0],
549 ancount: counts[1],
550 nscount: counts[2],
551 arcount: counts[3],
552 }
553 }
554
555 pub fn new_query_header(
563 msg_id: u16,
564 opcode: Opcode,
565 flags: HeaderFlags,
566 edns: bool,
567 qdcount: u16,
568 ) -> Result<Self, EncodeError> {
569 if flags.aa || flags.ra {
570 Err(EncodeError::AaOrRaInQuery)
571 } else {
572 Ok(Header {
573 msg_id,
574 qr: false,
575 opcode,
576 flags,
577 rcode: None,
578 qdcount,
579 ancount: 0,
580 nscount: 0,
581 arcount: if edns { 1 } else { 0 },
582 })
583 }
584 }
585
586 pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
590 let mut buf = Vec::new();
591 self.encode_into(&mut buf)?;
592 Ok(buf)
593 }
594
595 pub fn encode_into(&self, buf: &mut impl Write) -> Result<(), EncodeError> {
598 let qr = if self.qr { 1u16 } else { 0u16 };
599 let opcode = self.opcode.encode() as u16;
600 let rcode = match &self.rcode {
601 Some(val) => val.encode() as u16,
602 None => 0u16,
603 };
604
605 let line_two = (qr << 15) + (opcode << 11) + self.flags.as_flags() + rcode;
606 buf.write_u16::<NetworkEndian>(self.msg_id)?;
607 buf.write_u16::<NetworkEndian>(line_two)?;
608 buf.write_u16::<NetworkEndian>(self.qdcount)?;
609 buf.write_u16::<NetworkEndian>(self.ancount)?;
610 buf.write_u16::<NetworkEndian>(self.nscount)?;
611 buf.write_u16::<NetworkEndian>(self.arcount)?;
612
613 Ok(())
614 }
615
616 pub fn parse(header: &mut Cursor<&[u8]>) -> Result<Self, ParseError> {
621 let msg_id = header.read_u16::<NetworkEndian>()?;
622 let line_two = header.read_u16::<NetworkEndian>()?;
623 let qr = (line_two & (1 << 15)) >> 15;
624 let opcode = Opcode::parse(((line_two & (0b1111 << 11)) >> 11) as u8)?;
625 let flags = HeaderFlags::from_flags(line_two & 0b0000011110110000);
626 let rcode = RCode::parse(line_two & 0b1111)?;
627
628 Ok(Header {
629 msg_id,
630 qr: qr != 0,
631 opcode,
632 flags,
633 rcode: if qr != 0 { Some(rcode) } else { None },
634 qdcount: header.read_u16::<NetworkEndian>()?,
635 ancount: header.read_u16::<NetworkEndian>()?,
636 nscount: header.read_u16::<NetworkEndian>()?,
637 arcount: header.read_u16::<NetworkEndian>()?,
638 })
639 }
640
641 pub fn info_str(&self) -> String {
644 let mut s = String::new();
645 if let Some(rcode) = self.rcode {
646 s.push_str(
647 format!(
648 "id: {}, opcode: {}, rcode: {}, flags: ",
649 self.msg_id, self.opcode, rcode
650 )
651 .as_str(),
652 );
653 } else {
654 s.push_str(format!("id: {}, opcode: {}, flags: ", self.msg_id, self.opcode).as_str());
655 }
656 if self.flags.aa {
657 s.push_str("aa ")
658 }
659 if self.flags.tc {
660 s.push_str("tc ")
661 }
662 if self.flags.rd {
663 s.push_str("rd ")
664 }
665 if self.flags.ra {
666 s.push_str("ra ")
667 }
668 if self.flags.ad {
669 s.push_str("ad ")
670 }
671 if self.flags.cd {
672 s.push_str("cd ")
673 }
674 s.remove(s.len() - 1); s
676 }
677}
678
679impl Display for Header {
680 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
681 let mut s = String::new();
682 if self.qr {
683 s.push_str("DNS Response (");
684 } else {
685 s.push_str("DNS Query (");
686 }
687 s.push_str(&self.info_str());
688 s.push(')');
689 write!(f, "{}", s)
690 }
691}
692
693impl Question {
694 pub fn new(name: Name, qtype: RecordType, qclass: Class) -> Self {
696 Question {
697 qname: name,
698 qtype,
699 qclass,
700 }
701 }
702
703 pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
707 let mut buf = Vec::new();
708 self.encode_into(&mut buf)?;
709 Ok(buf)
710 }
711
712 pub fn encode_into(&self, buf: &mut impl Write) -> Result<(), EncodeError> {
715 self.qname.encode_into(buf)?;
716 buf.write_u16::<NetworkEndian>(self.qtype.into())?;
717 buf.write_u16::<NetworkEndian>(self.qclass.encode())?;
718 Ok(())
719 }
720
721 pub fn parse(msg: &mut Cursor<&[u8]>) -> Result<Self, ParseError> {
726 let qname = Name::parse(msg, name::Compression::Allowed)?;
727 let qtype: RecordType = msg.read_u16::<NetworkEndian>()?.into();
728 let qclass = Class::parse(msg.read_u16::<NetworkEndian>()?)?;
729
730 Ok(Question {
731 qname,
732 qtype,
733 qclass,
734 })
735 }
736
737 pub fn as_padded_string(&self, owner_len: usize, output: Option<owo_colors::Stream>) -> String {
743 let mut res = String::new();
744
745 let mut owner = self.qname.to_string();
746 while owner.len() < owner_len {
747 owner.push(' ');
748 }
749
750 let mut qtype = self.qtype.to_string();
751 if let Some(stream) = output {
752 owner = owner.if_supports_color(stream, |s| s.green()).to_string();
753 qtype = qtype.if_supports_color(stream, |s| s.purple()).to_string();
754 }
755
756 res.push_str(format!("{} {}", owner, qtype).as_str());
757
758 res
759 }
760}
761
762impl Display for Question {
763 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
764 write!(
765 f,
766 "DNS Question for '{}' (type: {}, class: {})",
767 self.qname, self.qtype, self.qclass
768 )
769 }
770}
771
772impl Record {
773 pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
777 let mut buf = Vec::new();
778 self.encode_into(&mut buf)?;
779 Ok(buf)
780 }
781
782 pub fn encode_into(&self, buf: &mut impl Write) -> Result<(), EncodeError> {
785 match self {
786 Record::NONOPT(nonopt) => nonopt.encode_into(buf),
787 Record::OPT(opt) => opt.encode_into(buf),
788 }
789 }
790
791 pub fn parse(msg: &mut Cursor<&[u8]>, rcode: Option<RCode>) -> Result<Self, ParseError> {
797 let owner = Name::parse(msg, name::Compression::Allowed)?;
798 let atype: RecordType = msg.read_u16::<NetworkEndian>()?.into();
799 if atype == RecordType::OPT {
800 return OptRecord::parse(msg, owner, rcode);
801 }
802 let class = Class::parse(msg.read_u16::<NetworkEndian>()?)?;
803 let ttl = msg.read_u32::<NetworkEndian>()?;
804 let rdlength = msg.read_u16::<NetworkEndian>()?;
805
806 let mut encoded_rdata = vec![0; rdlength as usize];
807 let pos_rdata_start = msg.position();
808 msg.read_exact(&mut encoded_rdata)?;
809 msg.set_position(pos_rdata_start);
811 let rdata = Record::parse_rdata(&atype, msg, rdlength)?;
812
813 Ok(Record::NONOPT(NonOptRecord {
814 owner,
815 rtype: atype,
816 class,
817 ttl,
818 encoded_rdata,
819 rdata,
820 }))
821 }
822
823 pub fn parse_rdata(
832 atype: &RecordType,
833 msg: &mut Cursor<&[u8]>,
834 rdlength: u16,
835 ) -> Result<Rdata, ParseError> {
836 match atype {
837 RecordType::A => rdata::A::parse_rdata(msg, rdlength),
838 RecordType::NS => rdata::NS::parse_rdata(msg, rdlength),
839 RecordType::CNAME => rdata::CNAME::parse_rdata(msg, rdlength),
840 RecordType::SOA => rdata::SOA::parse_rdata(msg, rdlength),
841 RecordType::PTR => rdata::PTR::parse_rdata(msg, rdlength),
842 RecordType::HINFO => rdata::HINFO::parse_rdata(msg, rdlength),
843 RecordType::MX => rdata::MX::parse_rdata(msg, rdlength),
844 RecordType::TXT => rdata::TXT::parse_rdata(msg, rdlength),
845 RecordType::RP => rdata::RP::parse_rdata(msg, rdlength),
846 RecordType::AAAA => rdata::AAAA::parse_rdata(msg, rdlength),
847 RecordType::LOC => rdata::LOC::parse_rdata(msg, rdlength),
848 RecordType::SRV => rdata::SRV::parse_rdata(msg, rdlength),
849 RecordType::NAPTR => rdata::NAPTR::parse_rdata(msg, rdlength),
850 RecordType::CERT => rdata::CERT::parse_rdata(msg, rdlength),
851 RecordType::DNAME => rdata::DNAME::parse_rdata(msg, rdlength),
852 RecordType::OPT => rdata::OPT::parse_rdata(msg, rdlength),
853 RecordType::DS => rdata::DS::parse_rdata(msg, rdlength),
854 RecordType::SSHFP => rdata::SSHFP::parse_rdata(msg, rdlength),
855 RecordType::RRSIG => rdata::RRSIG::parse_rdata(msg, rdlength),
856 RecordType::NSEC => rdata::NSEC::parse_rdata(msg, rdlength),
857 RecordType::DNSKEY => rdata::DNSKEY::parse_rdata(msg, rdlength),
858 RecordType::NSEC3 => rdata::NSEC3::parse_rdata(msg, rdlength),
859 RecordType::NSEC3PARAM => rdata::NSEC3PARAM::parse_rdata(msg, rdlength),
860 RecordType::TLSA => rdata::TLSA::parse_rdata(msg, rdlength),
861 RecordType::OPENPGPKEY => rdata::OPENPGPKEY::parse_rdata(msg, rdlength),
862 RecordType::CAA => rdata::CAA::parse_rdata(msg, rdlength),
863 RecordType::Unknown(_) => {
864 let mut rdata = vec![0; rdlength as usize];
865 msg.read_exact(&mut rdata)?;
866 Ok(Rdata::Unknown(rdata))
867 }
868 }
869 }
870
871 pub fn as_opt(&self) -> Option<&OptRecord> {
873 match self {
874 Self::OPT(opt) => Some(opt),
875 Self::NONOPT(_) => None,
876 }
877 }
878
879 pub fn as_nonopt(&self) -> Option<&NonOptRecord> {
881 match self {
882 Self::NONOPT(nonopt) => Some(nonopt),
883 Self::OPT(_) => None,
884 }
885 }
886
887 pub fn into_opt(self) -> OptRecord {
889 match self {
890 Self::OPT(opt) => opt,
891 Self::NONOPT(_) => panic!("Record::into_opt() called on NONOPT variant"),
892 }
893 }
894
895 pub fn into_nonopt(self) -> NonOptRecord {
897 match self {
898 Self::NONOPT(nonopt) => nonopt,
899 Self::OPT(_) => panic!("Record::into_nonopt() called on OPT variant"),
900 }
901 }
902
903 pub fn rdata(&self) -> &Rdata {
905 match self {
906 Self::OPT(opt) => opt.rdata(),
907 Self::NONOPT(nonopt) => nonopt.rdata(),
908 }
909 }
910
911 pub fn rdata_mut(&mut self) -> &mut Rdata {
913 match self {
914 Self::OPT(opt) => opt.rdata_mut(),
915 Self::NONOPT(nonopt) => nonopt.rdata_mut(),
916 }
917 }
918}
919
920impl NonOptRecord {
921 pub fn new(owner: Name, class: Class, ttl: u32, rdata: Rdata) -> Result<Self, ToluolError> {
925 if rdata.as_opt().is_some() {
926 return Err(ToluolError::OptRdataForNonOptRecord);
927 }
928
929 let rtype = rdata.rtype();
930 let encoded_rdata = rdata.encode()?;
931
932 Ok(Self {
933 owner,
934 rtype,
935 class,
936 ttl,
937 rdata,
938 encoded_rdata,
939 })
940 }
941
942 pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
946 let mut buf = Vec::new();
947 self.encode_into(&mut buf)?;
948 Ok(buf)
949 }
950
951 pub fn encode_into(&self, buf: &mut impl Write) -> Result<(), EncodeError> {
954 self.owner.encode_into(buf)?;
955 buf.write_u16::<NetworkEndian>(self.rtype.into())?;
956 buf.write_u16::<NetworkEndian>(self.class.encode())?;
957 buf.write_u32::<NetworkEndian>(self.ttl)?;
958 buf.write_u16::<NetworkEndian>(self.encoded_rdata.len() as u16)?;
959 buf.write_all(&self.encoded_rdata)?;
960 Ok(())
961 }
962
963 pub fn canonicalize(&mut self, rrsig_labels: u8, original_ttl: u32) -> Result<(), DnssecError> {
981 if self.owner.label_count() < rrsig_labels {
982 return Err(DnssecError::InvalidRrsigLabelCount(
983 self.owner.label_count(),
984 rrsig_labels,
985 ));
986 }
987
988 self.owner.canonicalize();
989 self.rdata.canonicalize();
990 self.ttl = original_ttl;
991
992 let mut popped_label = None;
994 while self.owner.label_count() > rrsig_labels {
995 popped_label = self.owner.pop_front_label();
996 }
997
998 if popped_label.is_some() {
1000 self.owner.make_wildcard();
1001 }
1002
1003 self.encoded_rdata.clear();
1005 self.rdata.encode_into(&mut self.encoded_rdata)?;
1006
1007 Ok(())
1008 }
1009
1010 pub fn rdata(&self) -> &Rdata {
1012 &self.rdata
1013 }
1014
1015 pub fn rdata_mut(&mut self) -> &mut Rdata {
1017 &mut self.rdata
1018 }
1019
1020 pub fn as_string(
1033 &self,
1034 separate_with_single_space: bool,
1035 owner_len: Option<usize>,
1036 atype_len: Option<usize>,
1037 output: Option<owo_colors::Stream>,
1038 ) -> String {
1039 let mut owner = self.owner.to_string();
1040 if let Some(len) = owner_len {
1041 while owner.len() < len {
1042 owner.push(' ');
1043 }
1044 }
1045
1046 let mut atype = self.rtype.to_string();
1047 if let Some(len) = atype_len {
1048 while atype.len() < len {
1049 atype.push(' ');
1050 }
1051 }
1052
1053 if let Some(stream) = output {
1054 owner = owner.if_supports_color(stream, |s| s.green()).to_string();
1055 atype = atype.if_supports_color(stream, |s| s.purple()).to_string();
1056 }
1057
1058 if separate_with_single_space {
1059 format!("{} {} {} {}", owner, self.ttl, atype, self.rdata,)
1060 } else {
1061 format!("{} {:>6} {} {}", owner, self.ttl, atype, &self.rdata,)
1062 }
1063 }
1064}
1065
1066impl Display for NonOptRecord {
1067 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1068 write!(f, "{}", self.as_string(true, None, None, None))
1069 }
1070}
1071
1072impl Display for OptFlags {
1073 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1074 let flag = format!("{:?}", self);
1075 write!(f, "{}", flag.to_ascii_lowercase())
1076 }
1077}
1078
1079impl OptRecord {
1080 pub fn new(rcode: Option<RCode>, edns_config: EdnsConfig) -> Result<Self, EncodeError> {
1084 let mut flags = vec![];
1085 if edns_config.do_flag {
1086 flags.push(OptFlags::DO);
1087 }
1088 let mut options = HashMap::new();
1089 if let Some(cookie) = edns_config.client_cookie {
1090 options.insert(OptionCode::Cookie, cookie.to_vec());
1091 }
1092 let rdata = Rdata::OPT(OPT { options });
1093 Ok(Self {
1094 owner: Name::root(),
1095 payload_size: edns_config.bufsize,
1096 rcode,
1097 edns_version: 0,
1098 flags,
1099 encoded_rdata: rdata.encode()?,
1100 rdata,
1101 })
1102 }
1103
1104 pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
1108 let mut buf = Vec::new();
1109 self.encode_into(&mut buf)?;
1110 Ok(buf)
1111 }
1112
1113 pub fn encode_into(&self, buf: &mut impl Write) -> Result<(), EncodeError> {
1116 self.owner.encode_into(buf)?;
1117 buf.write_u16::<NetworkEndian>(RecordType::OPT.into())?;
1118 buf.write_u16::<NetworkEndian>(self.payload_size)?;
1119 let rcode = self.rcode.unwrap_or(RCode::NOERROR);
1120 let rcode = (((rcode.encode() as u16) & 0b111111110000) >> 4) as u8;
1121 buf.write_u8(rcode)?;
1122 buf.write_u8(self.edns_version)?;
1123 if self.flags.contains(&OptFlags::DO) {
1124 buf.write_u16::<NetworkEndian>(1 << 15)?;
1125 } else {
1126 buf.write_u16::<NetworkEndian>(0)?;
1127 }
1128 buf.write_u16::<NetworkEndian>(self.encoded_rdata.len() as u16)?;
1129 buf.write_all(&self.encoded_rdata)?;
1130 Ok(())
1131 }
1132
1133 pub fn as_padded_string(&self, prefix: &str, _output: Option<owo_colors::Stream>) -> String {
1139 let mut s = prefix.to_string();
1140
1141 s.push_str(&self.to_string());
1142
1143 if !self.opt_rdata().options.is_empty() {
1146 let options = self.rdata.to_string();
1147 let options_iter: Vec<_> = options.split(", ").collect();
1148 let options_str = options_iter.join("\n");
1149 s.push('\n');
1150 s.push_str(prefix);
1151 s.push_str(&options_str);
1152 }
1153
1154 s
1155 }
1156
1157 pub fn rdata(&self) -> &Rdata {
1159 &self.rdata
1160 }
1161
1162 pub fn rdata_mut(&mut self) -> &mut Rdata {
1164 &mut self.rdata
1165 }
1166
1167 pub fn opt_rdata(&self) -> &OPT {
1169 self.rdata.as_opt().expect("OPT record had non-OPT RDATA")
1170 }
1171
1172 pub fn opt_rdata_mut(&mut self) -> &mut OPT {
1174 self.rdata
1175 .as_mut_opt()
1176 .expect("OPT record had non-OPT RDATA")
1177 }
1178
1179 fn info_str(&self) -> Result<String, fmt::Error> {
1181 use fmt::Write;
1182 let mut s = String::new();
1183 write!(&mut s, "EDNS: Version {}, flags: ", self.edns_version)?;
1184 let mut wrote_flag = false;
1185 for (i, flag) in self.flags.iter().enumerate() {
1186 wrote_flag = true;
1187 write!(&mut s, "{}", flag)?;
1188 if i < self.flags.len() - 1 {
1189 write!(&mut s, " ")?;
1190 }
1191 }
1192 if !wrote_flag {
1193 write!(&mut s, "<none>, ")?;
1194 } else {
1195 write!(&mut s, ", ")?;
1196 }
1197 write!(&mut s, "payload size: {}", self.payload_size)?;
1198 Ok(s)
1199 }
1200
1201 fn parse(
1205 msg: &mut Cursor<&[u8]>,
1206 owner: Name,
1207 rcode: Option<RCode>,
1208 ) -> Result<Record, ParseError> {
1209 if !owner.is_root() {
1210 return Err(ParseError::InvalidOptName(owner));
1211 }
1212
1213 let payload_size = msg.read_u16::<NetworkEndian>()?;
1214 let ext_rcode = msg.read_u8()?;
1215 let rcode = if rcode.is_some() {
1216 match ext_rcode {
1217 0 => rcode,
1218 x => Some(RCode::parse(
1219 ((x as u16) << 4) + (rcode.unwrap().encode() as u16),
1220 )?),
1221 }
1222 } else {
1223 rcode
1224 };
1225 let edns_version = msg.read_u8()?;
1226 let mut flags = vec![];
1227 let do_flag = msg.read_u16::<NetworkEndian>()? & (1 << 15) != 0;
1228 if do_flag {
1229 flags.push(OptFlags::DO);
1230 }
1231
1232 let rdlength = msg.read_u16::<NetworkEndian>()?;
1233 let mut encoded_rdata = vec![0; rdlength as usize];
1234 let pos_rdata_start = msg.position();
1235 msg.read_exact(&mut encoded_rdata)?;
1236 msg.set_position(pos_rdata_start);
1238 let rdata = Record::parse_rdata(&RecordType::OPT, msg, rdlength)?;
1239
1240 Ok(Record::OPT(OptRecord {
1241 owner,
1242 payload_size,
1243 rcode,
1244 edns_version,
1245 flags,
1246 encoded_rdata,
1247 rdata,
1248 }))
1249 }
1250}
1251
1252impl Display for OptRecord {
1253 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1254 write!(f, "{}", self.info_str()?)
1255 }
1256}
1257
1258impl Display for Record {
1259 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1260 match self {
1261 Record::NONOPT(nonopt) => write!(f, "{}", nonopt),
1262 Record::OPT(opt) => write!(f, "{}", opt),
1263 }
1264 }
1265}
1266
1267impl Message {
1268 pub fn new_query(
1277 domain: Name,
1278 qtype: RecordType,
1279 opcode: Opcode,
1280 flags: HeaderFlags,
1281 edns: Option<EdnsConfig>,
1282 ) -> Result<Self, EncodeError> {
1283 if flags.aa || flags.ra {
1284 return Err(EncodeError::AaOrRaInQuery);
1285 }
1286
1287 let msg_id = rand::thread_rng().gen_range(0..(1u32 << 16)) as u16;
1288
1289 let header = Header::new_query_header(msg_id, opcode, flags, edns.is_some(), 1)?;
1290
1291 let mut additional_answers = Vec::new();
1292 if let Some(edns_config) = edns {
1293 additional_answers.push(Record::OPT(OptRecord::new(None, edns_config)?));
1294 }
1295
1296 Ok(Message {
1297 header,
1298 questions: vec![Question::new(domain, qtype, Class::IN)],
1299 answers: Vec::new(),
1300 authoritative_answers: Vec::new(),
1301 additional_answers,
1302 })
1303 }
1304
1305 pub fn new_response(
1311 msg_id: u16,
1312 opcode: Opcode,
1313 flags: HeaderFlags,
1314 rcode: RCode,
1315 questions: Vec<Question>,
1316 records: [Vec<Record>; 3],
1317 ) -> Self {
1318 Message {
1319 header: Header::new_response_header(
1320 msg_id,
1321 opcode,
1322 flags,
1323 rcode,
1324 [
1325 questions.len() as u16,
1326 records[0].len() as u16,
1327 records[1].len() as u16,
1328 records[2].len() as u16,
1329 ],
1330 ),
1331 questions,
1332 answers: records[0].clone(),
1333 authoritative_answers: records[1].clone(),
1334 additional_answers: records[2].clone(),
1335 }
1336 }
1337
1338 pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
1343 let mut buf = Vec::new();
1344 self.encode_into(&mut buf)?;
1345 Ok(buf)
1346 }
1347
1348 pub fn encode_into(&self, buf: &mut impl Write) -> Result<(), EncodeError> {
1351 self.header.encode_into(buf)?;
1352 for question in &self.questions {
1353 question.encode_into(buf)?;
1354 }
1355 for record in &self.answers {
1356 record.encode_into(buf)?;
1357 }
1358 for record in &self.authoritative_answers {
1359 record.encode_into(buf)?;
1360 }
1361 for record in &self.additional_answers {
1362 record.encode_into(buf)?;
1363 }
1364
1365 Ok(())
1366 }
1367
1368 pub fn parse(msg: &mut Cursor<&[u8]>) -> Result<Self, ParseError> {
1373 let mut header = Header::parse(msg)?;
1374
1375 if header.flags.tc {
1376 return Err(ParseError::TruncatedMessage);
1377 }
1378
1379 let qdcount = header.qdcount;
1380 let ancount = header.ancount;
1381 let nscount = header.nscount;
1382 let arcount = header.arcount;
1383 let questions = Message::parse_questions(msg, qdcount)?;
1384 let mut answers = Vec::new();
1385 let mut authoritative_answers = Vec::new();
1386 let mut additional_answers = Vec::new();
1387 if ancount > 0 {
1388 answers = Message::parse_records(msg, ancount, header.rcode)?;
1389 }
1390 if nscount > 0 {
1391 authoritative_answers = Message::parse_records(msg, nscount, header.rcode)?;
1392 }
1393 if arcount > 0 {
1394 additional_answers = Message::parse_records(msg, arcount, header.rcode)?;
1395 }
1396
1397 for answer in &additional_answers {
1398 if let Record::OPT(OptRecord { rcode, .. }) = answer {
1399 header.rcode = *rcode;
1400 }
1401 }
1402
1403 Ok(Message {
1404 header,
1405 questions,
1406 answers,
1407 authoritative_answers,
1408 additional_answers,
1409 })
1410 }
1411
1412 pub fn as_string(&self, output: Option<owo_colors::Stream>) -> String {
1417 let section_name = |s: &str, o: Option<owo_colors::Stream>| {
1418 let mut s = s.to_string();
1419 if let Some(stream) = o {
1420 s = s.if_supports_color(stream, |s| s.yellow()).to_string();
1421 }
1422 s
1423 };
1424
1425 let mut res = String::new();
1426
1427 let mut additional_answers = self.additional_answers.clone();
1428 let mut opt_index = None;
1429
1430 let mut max_owner_len = 0;
1431 let mut max_type_len = 0;
1432
1433 for q in &self.questions {
1434 max_owner_len = max(max_owner_len, q.qname.string_len());
1435 max_type_len = max(max_type_len, q.qtype.to_string().len());
1436 }
1437
1438 let answers = [
1439 &self.answers,
1440 &self.authoritative_answers,
1441 &self.additional_answers,
1442 ];
1443 let answers_iter = answers.iter().flat_map(|a| a.iter());
1444 for (i, answer) in answers_iter.enumerate() {
1445 match answer {
1446 Record::OPT(_) => {
1447 opt_index = Some(i - self.answers.len() - self.authoritative_answers.len());
1450 }
1451 Record::NONOPT(NonOptRecord {
1452 owner: name,
1453 rtype: atype,
1454 ..
1455 }) => {
1456 max_owner_len = max(max_owner_len, name.string_len());
1457 max_type_len = max(max_type_len, atype.to_string().len());
1458 }
1459 }
1460 }
1461
1462 res.push_str(section_name("Header:\n\t", output).as_str());
1465 res.push_str(format!("{}\n\n", self.header.info_str()).as_str());
1466
1467 if let Some(idx) = opt_index {
1469 let opt = additional_answers.remove(idx);
1470 let opt = opt
1471 .as_opt()
1472 .expect("Calculated incorrect index for OPT record");
1473 res.push_str(section_name("OPT Pseudosection:\n", output).as_str());
1474 res.push_str(&opt.as_padded_string("\t", output));
1475 res.push_str("\n\n");
1476 }
1477
1478 res.push_str(section_name("Question Section:\n", output).as_str());
1479 for question in &self.questions {
1480 res.push('\t');
1481 res.push_str(question.as_padded_string(max_owner_len, output).as_str());
1483 res.push('\n');
1484 }
1485 res.push('\n');
1486
1487 if !self.answers.is_empty() {
1488 res.push_str(section_name("Answer Section:\n", output).as_str());
1489 for answer in &self.answers {
1490 res.push('\t');
1491 res.push_str(
1492 answer
1493 .as_nonopt()
1494 .expect("Unexpected OPT record")
1495 .as_string(false, Some(max_owner_len), Some(max_type_len), output)
1496 .as_str(),
1497 );
1498 res.push('\n');
1499 }
1500 res.push('\n');
1501 }
1502
1503 if !self.authoritative_answers.is_empty() {
1504 res.push_str(section_name("Authoritative Section:\n", output).as_str());
1505 for answer in &self.authoritative_answers {
1506 res.push('\t');
1507 res.push_str(
1508 answer
1509 .as_nonopt()
1510 .expect("Unexpected OPT record")
1511 .as_string(false, Some(max_owner_len), Some(max_type_len), output)
1512 .as_str(),
1513 );
1514 res.push('\n');
1515 }
1516 res.push('\n');
1517 }
1518
1519 if !additional_answers.is_empty() {
1520 res.push_str(section_name("Additional Section:\n", output).as_str());
1521 for answer in &additional_answers {
1522 res.push('\t');
1523 res.push_str(
1524 answer
1525 .as_nonopt()
1526 .expect("Unexpected OPT record")
1527 .as_string(false, Some(max_owner_len), Some(max_type_len), output)
1528 .as_str(),
1529 );
1530 res.push('\n');
1531 }
1532 }
1533
1534 while res.chars().nth(res.len() - 1).unwrap() == '\n' {
1536 res.remove(res.len() - 1);
1537 }
1538
1539 res
1540 }
1541
1542 fn parse_questions(msg: &mut Cursor<&[u8]>, qdcount: u16) -> Result<Vec<Question>, ParseError> {
1544 let mut questions = Vec::with_capacity(qdcount as usize);
1545 for _i in 0..qdcount {
1546 questions.push(Question::parse(msg)?);
1547 }
1548
1549 Ok(questions)
1550 }
1551
1552 fn parse_records(
1554 msg: &mut Cursor<&[u8]>,
1555 ancount: u16,
1556 rcode: Option<RCode>,
1557 ) -> Result<Vec<Record>, ParseError> {
1558 let mut answers = Vec::with_capacity(ancount as usize);
1559 for _i in 0..ancount {
1560 answers.push(Record::parse(msg, rcode)?);
1561 }
1562
1563 Ok(answers)
1564 }
1565}