1 #[cfg(test)] 2 mod message_test; 3 4 pub mod builder; 5 pub mod header; 6 pub mod name; 7 mod packer; 8 pub mod parser; 9 pub mod question; 10 pub mod resource; 11 12 use crate::error::*; 13 use header::*; 14 use packer::*; 15 use parser::*; 16 use question::*; 17 use resource::*; 18 19 use std::collections::HashMap; 20 use std::fmt; 21 22 // Message formats 23 24 // A Type is a type of DNS request and response. 25 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 26 pub enum DnsType { 27 // ResourceHeader.Type and question.Type 28 A = 1, 29 Ns = 2, 30 Cname = 5, 31 Soa = 6, 32 Ptr = 12, 33 Mx = 15, 34 Txt = 16, 35 Aaaa = 28, 36 Srv = 33, 37 Opt = 41, 38 39 // question.Type 40 Wks = 11, 41 Hinfo = 13, 42 Minfo = 14, 43 Axfr = 252, 44 All = 255, 45 46 Unsupported = 0, 47 } 48 49 impl Default for DnsType { 50 fn default() -> Self { 51 DnsType::Unsupported 52 } 53 } 54 55 impl From<u16> for DnsType { 56 fn from(v: u16) -> Self { 57 match v { 58 1 => DnsType::A, 59 2 => DnsType::Ns, 60 5 => DnsType::Cname, 61 6 => DnsType::Soa, 62 12 => DnsType::Ptr, 63 15 => DnsType::Mx, 64 16 => DnsType::Txt, 65 28 => DnsType::Aaaa, 66 33 => DnsType::Srv, 67 41 => DnsType::Opt, 68 69 // question.Type 70 11 => DnsType::Wks, 71 13 => DnsType::Hinfo, 72 14 => DnsType::Minfo, 73 252 => DnsType::Axfr, 74 255 => DnsType::All, 75 76 _ => DnsType::Unsupported, 77 } 78 } 79 } 80 81 impl fmt::Display for DnsType { 82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 83 let s = match *self { 84 DnsType::A => "A", 85 DnsType::Ns => "NS", 86 DnsType::Cname => "CNAME", 87 DnsType::Soa => "SOA", 88 DnsType::Ptr => "PTR", 89 DnsType::Mx => "MX", 90 DnsType::Txt => "TXT", 91 DnsType::Aaaa => "AAAA", 92 DnsType::Srv => "SRV", 93 DnsType::Opt => "OPT", 94 DnsType::Wks => "WKS", 95 DnsType::Hinfo => "HINFO", 96 DnsType::Minfo => "MINFO", 97 DnsType::Axfr => "AXFR", 98 DnsType::All => "ALL", 99 _ => "Unsupported", 100 }; 101 write!(f, "{}", s) 102 } 103 } 104 105 impl DnsType { 106 // pack_type appends the wire format of field to msg. 107 pub(crate) fn pack(&self, msg: Vec<u8>) -> Vec<u8> { 108 pack_uint16(msg, *self as u16) 109 } 110 111 pub(crate) fn unpack(&mut self, msg: &[u8], off: usize) -> Result<usize> { 112 let (t, o) = unpack_uint16(msg, off)?; 113 *self = DnsType::from(t); 114 Ok(o) 115 } 116 117 pub(crate) fn skip(msg: &[u8], off: usize) -> Result<usize> { 118 skip_uint16(msg, off) 119 } 120 } 121 122 // A Class is a type of network. 123 #[derive(Default, Copy, Clone, Debug, PartialEq, Eq)] 124 pub struct DnsClass(pub u16); 125 126 // ResourceHeader.Class and question.Class 127 pub const DNSCLASS_INET: DnsClass = DnsClass(1); 128 pub const DNSCLASS_CSNET: DnsClass = DnsClass(2); 129 pub const DNSCLASS_CHAOS: DnsClass = DnsClass(3); 130 pub const DNSCLASS_HESIOD: DnsClass = DnsClass(4); 131 // question.Class 132 pub const DNSCLASS_ANY: DnsClass = DnsClass(255); 133 134 impl fmt::Display for DnsClass { 135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 136 let other = format!("{}", self.0); 137 let s = match *self { 138 DNSCLASS_INET => "ClassINET", 139 DNSCLASS_CSNET => "ClassCSNET", 140 DNSCLASS_CHAOS => "ClassCHAOS", 141 DNSCLASS_HESIOD => "ClassHESIOD", 142 DNSCLASS_ANY => "ClassANY", 143 _ => other.as_str(), 144 }; 145 write!(f, "{}", s) 146 } 147 } 148 149 impl DnsClass { 150 // pack_class appends the wire format of field to msg. 151 pub(crate) fn pack(&self, msg: Vec<u8>) -> Vec<u8> { 152 pack_uint16(msg, self.0) 153 } 154 155 pub(crate) fn unpack(&mut self, msg: &[u8], off: usize) -> Result<usize> { 156 let (c, o) = unpack_uint16(msg, off)?; 157 *self = DnsClass(c); 158 Ok(o) 159 } 160 161 pub(crate) fn skip(msg: &[u8], off: usize) -> Result<usize> { 162 skip_uint16(msg, off) 163 } 164 } 165 166 // An OpCode is a DNS operation code. 167 pub type OpCode = u16; 168 169 // An RCode is a DNS response status code. 170 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 171 pub enum RCode { 172 // Message.Rcode 173 Success = 0, 174 FormatError = 1, 175 ServerFailure = 2, 176 NameError = 3, 177 NotImplemented = 4, 178 Refused = 5, 179 Unsupported, 180 } 181 182 impl Default for RCode { 183 fn default() -> Self { 184 RCode::Success 185 } 186 } 187 188 impl From<u8> for RCode { 189 fn from(v: u8) -> Self { 190 match v { 191 0 => RCode::Success, 192 1 => RCode::FormatError, 193 2 => RCode::ServerFailure, 194 3 => RCode::NameError, 195 4 => RCode::NotImplemented, 196 5 => RCode::Refused, 197 _ => RCode::Unsupported, 198 } 199 } 200 } 201 202 impl fmt::Display for RCode { 203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 204 let s = match *self { 205 RCode::Success => "RCodeSuccess", 206 RCode::FormatError => "RCodeFormatError", 207 RCode::ServerFailure => "RCodeServerFailure", 208 RCode::NameError => "RCodeNameError", 209 RCode::NotImplemented => "RCodeNotImplemented", 210 RCode::Refused => "RCodeRefused", 211 RCode::Unsupported => "RCodeUnsupported", 212 }; 213 write!(f, "{}", s) 214 } 215 } 216 217 // Internal constants. 218 219 // PACK_STARTING_CAP is the default initial buffer size allocated during 220 // packing. 221 // 222 // The starting capacity doesn't matter too much, but most DNS responses 223 // Will be <= 512 bytes as it is the limit for DNS over UDP. 224 const PACK_STARTING_CAP: usize = 512; 225 226 // UINT16LEN is the length (in bytes) of a uint16. 227 const UINT16LEN: usize = 2; 228 229 // UINT32LEN is the length (in bytes) of a uint32. 230 const UINT32LEN: usize = 4; 231 232 // HEADER_LEN is the length (in bytes) of a DNS header. 233 // 234 // A header is comprised of 6 uint16s and no padding. 235 const HEADER_LEN: usize = 6 * UINT16LEN; 236 237 const HEADER_BIT_QR: u16 = 1 << 15; // query/response (response=1) 238 const HEADER_BIT_AA: u16 = 1 << 10; // authoritative 239 const HEADER_BIT_TC: u16 = 1 << 9; // truncated 240 const HEADER_BIT_RD: u16 = 1 << 8; // recursion desired 241 const HEADER_BIT_RA: u16 = 1 << 7; // recursion available 242 243 // Message is a representation of a DNS message. 244 #[derive(Default, Debug)] 245 pub struct Message { 246 pub header: Header, 247 pub questions: Vec<Question>, 248 pub answers: Vec<Resource>, 249 pub authorities: Vec<Resource>, 250 pub additionals: Vec<Resource>, 251 } 252 253 impl fmt::Display for Message { 254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 255 let mut s = "dnsmessage.Message{Header: ".to_owned(); 256 s += self.header.to_string().as_str(); 257 258 s += ", Questions: "; 259 let v: Vec<String> = self.questions.iter().map(|q| q.to_string()).collect(); 260 s += &v.join(", "); 261 262 s += ", Answers: "; 263 let v: Vec<String> = self.answers.iter().map(|q| q.to_string()).collect(); 264 s += &v.join(", "); 265 266 s += ", Authorities: "; 267 let v: Vec<String> = self.authorities.iter().map(|q| q.to_string()).collect(); 268 s += &v.join(", "); 269 270 s += ", Additionals: "; 271 let v: Vec<String> = self.additionals.iter().map(|q| q.to_string()).collect(); 272 s += &v.join(", "); 273 274 write!(f, "{}", s) 275 } 276 } 277 278 impl Message { 279 // Unpack parses a full Message. 280 pub fn unpack(&mut self, msg: &[u8]) -> Result<()> { 281 let mut p = Parser::default(); 282 self.header = p.start(msg)?; 283 self.questions = p.all_questions()?; 284 self.answers = p.all_answers()?; 285 self.authorities = p.all_authorities()?; 286 self.additionals = p.all_additionals()?; 287 Ok(()) 288 } 289 290 // Pack packs a full Message. 291 pub fn pack(&mut self) -> Result<Vec<u8>> { 292 self.append_pack(vec![]) 293 } 294 295 // append_pack is like Pack but appends the full Message to b and returns the 296 // extended buffer. 297 pub fn append_pack(&mut self, b: Vec<u8>) -> Result<Vec<u8>> { 298 // Validate the lengths. It is very unlikely that anyone will try to 299 // pack more than 65535 of any particular type, but it is possible and 300 // we should fail gracefully. 301 if self.questions.len() > u16::MAX as usize { 302 return Err(Error::ErrTooManyQuestions); 303 } 304 if self.answers.len() > u16::MAX as usize { 305 return Err(Error::ErrTooManyAnswers); 306 } 307 if self.authorities.len() > u16::MAX as usize { 308 return Err(Error::ErrTooManyAuthorities); 309 } 310 if self.additionals.len() > u16::MAX as usize { 311 return Err(Error::ErrTooManyAdditionals); 312 } 313 314 let (id, bits) = self.header.pack(); 315 316 let questions = self.questions.len() as u16; 317 let answers = self.answers.len() as u16; 318 let authorities = self.authorities.len() as u16; 319 let additionals = self.additionals.len() as u16; 320 321 let h = HeaderInternal { 322 id, 323 bits, 324 questions, 325 answers, 326 authorities, 327 additionals, 328 }; 329 330 let compression_off = b.len(); 331 let mut msg = h.pack(b); 332 333 // RFC 1035 allows (but does not require) compression for packing. RFC 334 // 1035 requires unpacking implementations to support compression, so 335 // unconditionally enabling it is fine. 336 // 337 // DNS lookups are typically done over UDP, and RFC 1035 states that UDP 338 // DNS messages can be a maximum of 512 bytes long. Without compression, 339 // many DNS response messages are over this limit, so enabling 340 // compression will help ensure compliance. 341 let mut compression = Some(HashMap::new()); 342 343 for question in &self.questions { 344 msg = question.pack(msg, &mut compression, compression_off)?; 345 } 346 for answer in &mut self.answers { 347 msg = answer.pack(msg, &mut compression, compression_off)?; 348 } 349 for authority in &mut self.authorities { 350 msg = authority.pack(msg, &mut compression, compression_off)?; 351 } 352 for additional in &mut self.additionals { 353 msg = additional.pack(msg, &mut compression, compression_off)?; 354 } 355 356 Ok(msg) 357 } 358 } 359