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
use bytes::{Bytes, BytesMut}; use crate::{Dns, Flags}; use num_traits::ToPrimitive; use super::{encode_u16, encode_u8, EncodeError, EncodeResult}; use std::collections::HashMap; impl Flags { pub fn encode(&self, bytes: &mut BytesMut) -> EncodeResult { let mut buffer = 0u8; if self.qr { buffer |= 0b1000_0000; } if let Some(opcode) = self.opcode.to_u8() { buffer |= opcode << 3; } else { return Err(EncodeError::OpcodeError); } if self.aa { buffer |= 0b0000_0100; } if self.tc { buffer |= 0b0000_0010; } if self.rd { buffer |= 0b0000_0001; } encode_u8(bytes, buffer); buffer = 0; if self.ra { buffer |= 0b1000_0000; } if self.ad { buffer |= 0b0010_0000; } if self.cd { buffer |= 0b0001_0000; } if let Some(rcode) = self.rcode.to_u8() { buffer |= rcode; } else { return Err(EncodeError::RCodeError); } encode_u8(bytes, buffer); Ok(()) } } impl Dns { pub fn encode(&self, bytes: &mut BytesMut) -> EncodeResult { encode_u16(bytes, self.id); self.flags.encode(bytes)?; encode_u16(bytes, self.questions.len() as u16); encode_u16(bytes, self.answers.len() as u16); encode_u16(bytes, self.authorities.len() as u16); encode_u16(bytes, self.additionals.len() as u16); let mut compression = HashMap::new(); for question in &self.questions { question.encode(bytes, &mut compression)?; } for answer in &self.answers { answer.encode(bytes, &mut compression)?; } for authority in &self.authorities { authority.encode(bytes, &mut compression)?; } for additional in &self.additionals { additional.encode(bytes, &mut compression)?; } Ok(()) } pub fn to_bytes(&self) -> Result<Bytes, EncodeError> { let mut bytes = BytesMut::new(); self.encode(&mut bytes)?; Ok(bytes.freeze()) } }