use bytes::{Bytes, Buf, BufMut}; use crate::errors::*; use crate::ser::packet::{DnsPacketData, DnsPacketWriteContext}; use std::io::{Cursor, Read}; use std::mem::size_of; use std::net::{Ipv4Addr, Ipv6Addr}; impl DnsPacketData for () { fn deserialize(_data: &mut Cursor) -> Result { Ok(()) } fn serialize(&self, _context: &mut DnsPacketWriteContext, _packet: &mut Vec) -> Result<()> { Ok(()) } } impl DnsPacketData for std::marker::PhantomData { fn deserialize(_data: &mut Cursor) -> Result { Ok(std::marker::PhantomData) } fn serialize(&self, _context: &mut DnsPacketWriteContext, _packet: &mut Vec) -> Result<()> { Ok(()) } } impl DnsPacketData for u8 { fn deserialize(data: &mut Cursor) -> Result { check_enough_data!(data, size_of::(), "u8"); Ok(data.get_u8()) } fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec) -> Result<()> { packet.reserve(size_of::()); packet.put_u8(*self); Ok(()) } } impl DnsPacketData for u16 { fn deserialize(data: &mut Cursor) -> Result { check_enough_data!(data, size_of::(), "u16"); Ok(data.get_u16_be()) } fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec) -> Result<()> { packet.reserve(size_of::()); packet.put_u16_be(*self); Ok(()) } } impl DnsPacketData for u32 { fn deserialize(data: &mut Cursor) -> Result { check_enough_data!(data, size_of::(), "u32"); Ok(data.get_u32_be()) } fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec) -> Result<()> { packet.reserve(size_of::()); packet.put_u32_be(*self); Ok(()) } } impl DnsPacketData for Ipv4Addr { fn deserialize(data: &mut Cursor) -> Result { check_enough_data!(data, size_of::(), "Ipv4Addr"); Ok(data.get_u32_be().into()) } fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec) -> Result<()> { let data = self.octets(); debug_assert!(data.len() == 4); packet.reserve(data.len()); packet.put_slice(&data); Ok(()) } } impl DnsPacketData for Ipv6Addr { fn deserialize(data: &mut Cursor) -> Result { check_enough_data!(data, 16, "Ipv6Addr"); let mut buf = [0u8; 16]; data.read_exact(&mut buf)?; Ok(buf.into()) } fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec) -> Result<()> { let data = self.octets(); debug_assert!(data.len() == 16); packet.reserve(data.len()); packet.put_slice(&data); Ok(()) } } #[cfg(test)] mod tests { use crate::errors::*; fn deserialize(data: &'static [u8]) -> Result { use bytes::{Bytes,Buf}; use std::io::Cursor; let mut c = Cursor::new(Bytes::from_static(data)); let result = T::deserialize(&mut c)?; if c.remaining() != 0 { failure::bail!("data remaining: {}", c.remaining()) } Ok(result) } #[test] fn test_u16() { assert!(deserialize::(b"\x80\x08").unwrap() == 0x8008); } #[derive(super::DnsPacketData, PartialEq, Eq, Debug)] struct Unit; #[test] fn test_unit() { assert_eq!(deserialize::(b"").unwrap(), Unit); } #[derive(super::DnsPacketData, PartialEq, Eq, Debug)] struct Tuple(u16); #[test] fn test_tuple() { assert_eq!(deserialize::(b"\x04\xd2").unwrap(), Tuple(1234)); } }