1 use super::*; 2 3 // Header is a representation of a DNS message header. 4 #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] 5 pub struct Header { 6 pub id: u16, 7 pub response: bool, 8 pub op_code: OpCode, 9 pub authoritative: bool, 10 pub truncated: bool, 11 pub recursion_desired: bool, 12 pub recursion_available: bool, 13 pub rcode: RCode, 14 } 15 16 impl fmt::Display for Header { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 18 write!( 19 f, 20 "dnsmessage.Header{{id: {}, response: {}, op_code: {}, authoritative: {}, truncated: {}, recursion_desired: {}, recursion_available: {}, rcode: {} }}", 21 self.id, 22 self.response, 23 self.op_code, 24 self.authoritative, 25 self.truncated, 26 self.recursion_desired, 27 self.recursion_available, 28 self.rcode 29 ) 30 } 31 } 32 33 impl Header { pack(&self) -> (u16, u16)34 pub fn pack(&self) -> (u16, u16) { 35 let id = self.id; 36 let mut bits = self.op_code << 11 | self.rcode as u16; 37 if self.recursion_available { 38 bits |= HEADER_BIT_RA 39 } 40 if self.recursion_desired { 41 bits |= HEADER_BIT_RD 42 } 43 if self.truncated { 44 bits |= HEADER_BIT_TC 45 } 46 if self.authoritative { 47 bits |= HEADER_BIT_AA 48 } 49 if self.response { 50 bits |= HEADER_BIT_QR 51 } 52 53 (id, bits) 54 } 55 } 56 57 #[derive(Default, Copy, Clone, PartialOrd, PartialEq, Eq)] 58 pub enum Section { 59 #[default] 60 NotStarted = 0, 61 Header = 1, 62 Questions = 2, 63 Answers = 3, 64 Authorities = 4, 65 Additionals = 5, 66 Done = 6, 67 } 68 69 impl From<u8> for Section { from(v: u8) -> Self70 fn from(v: u8) -> Self { 71 match v { 72 0 => Section::NotStarted, 73 1 => Section::Header, 74 2 => Section::Questions, 75 3 => Section::Answers, 76 4 => Section::Authorities, 77 5 => Section::Additionals, 78 _ => Section::Done, 79 } 80 } 81 } 82 83 impl fmt::Display for Section { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 85 let s = match *self { 86 Section::NotStarted => "NotStarted", 87 Section::Header => "Header", 88 Section::Questions => "question", 89 Section::Answers => "answer", 90 Section::Authorities => "authority", 91 Section::Additionals => "additional", 92 Section::Done => "Done", 93 }; 94 write!(f, "{s}") 95 } 96 } 97 98 // header is the wire format for a DNS message header. 99 #[derive(Default)] 100 pub struct HeaderInternal { 101 pub id: u16, 102 pub bits: u16, 103 pub questions: u16, 104 pub answers: u16, 105 pub authorities: u16, 106 pub additionals: u16, 107 } 108 109 impl HeaderInternal { count(&self, sec: Section) -> u16110 pub(crate) fn count(&self, sec: Section) -> u16 { 111 match sec { 112 Section::Questions => self.questions, 113 Section::Answers => self.answers, 114 Section::Authorities => self.authorities, 115 Section::Additionals => self.additionals, 116 _ => 0, 117 } 118 } 119 120 // pack appends the wire format of the header to msg. pack(&self, mut msg: Vec<u8>) -> Vec<u8>121 pub(crate) fn pack(&self, mut msg: Vec<u8>) -> Vec<u8> { 122 msg = pack_uint16(msg, self.id); 123 msg = pack_uint16(msg, self.bits); 124 msg = pack_uint16(msg, self.questions); 125 msg = pack_uint16(msg, self.answers); 126 msg = pack_uint16(msg, self.authorities); 127 msg = pack_uint16(msg, self.additionals); 128 msg 129 } 130 unpack(&mut self, msg: &[u8], off: usize) -> Result<usize>131 pub(crate) fn unpack(&mut self, msg: &[u8], off: usize) -> Result<usize> { 132 let (id, off) = unpack_uint16(msg, off)?; 133 self.id = id; 134 135 let (bits, off) = unpack_uint16(msg, off)?; 136 self.bits = bits; 137 138 let (questions, off) = unpack_uint16(msg, off)?; 139 self.questions = questions; 140 141 let (answers, off) = unpack_uint16(msg, off)?; 142 self.answers = answers; 143 144 let (authorities, off) = unpack_uint16(msg, off)?; 145 self.authorities = authorities; 146 147 let (additionals, off) = unpack_uint16(msg, off)?; 148 self.additionals = additionals; 149 150 Ok(off) 151 } 152 header(&self) -> Header153 pub(crate) fn header(&self) -> Header { 154 Header { 155 id: self.id, 156 response: (self.bits & HEADER_BIT_QR) != 0, 157 op_code: ((self.bits >> 11) & 0xF) as OpCode, 158 authoritative: (self.bits & HEADER_BIT_AA) != 0, 159 truncated: (self.bits & HEADER_BIT_TC) != 0, 160 recursion_desired: (self.bits & HEADER_BIT_RD) != 0, 161 recursion_available: (self.bits & HEADER_BIT_RA) != 0, 162 rcode: RCode::from((self.bits & 0xF) as u8), 163 } 164 } 165 } 166