1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
use super::{decode_u16, decode_u8, DecodeError, DecodeResult}; use crate::{Dns, Flags, Opcode, Question, RCode, MAXIMUM_DNS_PACKET_SIZE, RR}; use num_traits::FromPrimitive; use std::ops::Deref; impl Flags { pub fn decode<T>(bytes: &T, offset: &mut usize) -> DecodeResult<Flags> where T: Deref<Target = [u8]>, { let buffer = decode_u8(bytes, offset)?; let qr = (buffer & 0b1000_0000) != 0; let opcode = if let Some(opcode) = Opcode::from_u8((buffer & 0b0111_1000) >> 3) { opcode } else { return Err(DecodeError::OpcodeError); }; let aa = (buffer & 0b0000_0100) != 0; let tc = (buffer & 0b0000_0010) != 0; let rd = (buffer & 0b0000_0001) != 0; let buffer = decode_u8(bytes, offset)?; let ra = (buffer & 0b1000_0000) != 0; if (buffer & 0b0100_0000) != 0 { return Err(DecodeError::ZNotZeroes); } let ad = (buffer & 0b0010_0000) != 0; let cd = (buffer & 0b0001_0000) != 0; if let Some(rcode) = RCode::from_u8(buffer & 0b0000_1111) { Ok(Flags { qr, opcode, aa, tc, rd, ra, ad, cd, rcode, }) } else { Err(DecodeError::RCodeError) } } } impl Dns { pub fn decode<T>(bytes: &T) -> DecodeResult<Dns> where T: Deref<Target = [u8]>, { let bytes_len = bytes.len(); if bytes_len < 16 { return Err(DecodeError::NotEnoughData); } else if bytes_len > MAXIMUM_DNS_PACKET_SIZE { return Err(DecodeError::TooMuchData); } let mut offset: usize = 0; let id = decode_u16(bytes, &mut offset)?; let flags = Flags::decode(bytes, &mut offset)?; let question_count = decode_u16(bytes, &mut offset)?; let answer_count = decode_u16(bytes, &mut offset)?; let authority_count = decode_u16(bytes, &mut offset)?; let additional_count = decode_u16(bytes, &mut offset)?; let mut questions = Vec::with_capacity(question_count as usize); for _ in 0..question_count { questions.push(Question::decode(bytes, &mut offset)?); } let mut answers = Vec::with_capacity(answer_count as usize); for _ in 0..answer_count { answers.push(RR::decode(bytes, &mut offset)?); } let mut authorities = Vec::with_capacity(authority_count as usize); for _ in 0..authority_count { authorities.push(RR::decode(bytes, &mut offset)?); } let mut additionals = Vec::with_capacity(additional_count as usize); for _ in 0..additional_count { additionals.push(RR::decode(bytes, &mut offset)?); } Ok(Dns { id, flags, questions, answers, authorities, additionals, }) } }