dns-message-parser 0.2.0

Libary to encode and decode DNS packets
Documentation
use bytes::Bytes;

use crate::{Dns, Flags, Opcode, Question, RCode, MAXIMUM_DNS_PACKET_SIZE, RR};

use num_traits::FromPrimitive;

use super::{decode_u16, decode_u8, DecodeError, DecodeResult};

impl Flags {
    pub fn decode(bytes: &Bytes, offset: &mut usize) -> DecodeResult<Flags> {
        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::new(qr, opcode, aa, tc, rd, ra, ad, cd, rcode))
        } else {
            Err(DecodeError::RCodeError)
        }
    }
}

impl Dns {
    pub fn decode(bytes: &Bytes) -> DecodeResult<Dns> {
        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::new(
            id,
            flags,
            questions,
            answers,
            authorities,
            additionals,
        ))
    }
}