use bytes::{Bytes, Buf, BufMut, BigEndian}; use errors::*; use ser::packet::{DnsPacketData, DnsPacketWriteContext}; use std::io::{Cursor, Read}; use std::mem::size_of; use std::net::{Ipv4Addr, Ipv6Addr}; 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::()) } fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec) -> Result<()> { packet.reserve(size_of::()); packet.put_u16::(*self); Ok(()) } } impl DnsPacketData for u32 { fn deserialize(data: &mut Cursor) -> Result { check_enough_data!(data, size_of::(), "u32"); Ok(data.get_u32::()) } fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec) -> Result<()> { packet.reserve(size_of::()); packet.put_u32::(*self); Ok(()) } } impl DnsPacketData for Ipv4Addr { fn deserialize(data: &mut Cursor) -> Result { check_enough_data!(data, size_of::(), "Ipv4Addr"); Ok(data.get_u32::().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 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 { bail!("data remaining: {}", c.remaining()) } Ok(result) } #[test] fn test_u16() { assert!(deserialize::(b"\x80\x08").unwrap() == 0x8008); } }