135 lines
3.3 KiB
Rust
135 lines
3.3 KiB
Rust
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<Bytes>) -> Result<Self> {
|
|
Ok(())
|
|
}
|
|
|
|
fn serialize(&self, _context: &mut DnsPacketWriteContext, _packet: &mut Vec<u8>) -> Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl<T: ?Sized> DnsPacketData for std::marker::PhantomData<T> {
|
|
fn deserialize(_data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
Ok(std::marker::PhantomData)
|
|
}
|
|
|
|
fn serialize(&self, _context: &mut DnsPacketWriteContext, _packet: &mut Vec<u8>) -> Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl DnsPacketData for u8 {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
check_enough_data!(data, size_of::<Self>(), "u8");
|
|
Ok(data.get_u8())
|
|
}
|
|
|
|
fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> Result<()> {
|
|
packet.reserve(size_of::<Self>());
|
|
packet.put_u8(*self);
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl DnsPacketData for u16 {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
check_enough_data!(data, size_of::<Self>(), "u16");
|
|
Ok(data.get_u16_be())
|
|
}
|
|
|
|
fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> Result<()> {
|
|
packet.reserve(size_of::<Self>());
|
|
packet.put_u16_be(*self);
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl DnsPacketData for u32 {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
check_enough_data!(data, size_of::<Self>(), "u32");
|
|
Ok(data.get_u32_be())
|
|
}
|
|
|
|
fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> Result<()> {
|
|
packet.reserve(size_of::<Self>());
|
|
packet.put_u32_be(*self);
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl DnsPacketData for Ipv4Addr {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
check_enough_data!(data, size_of::<u32>(), "Ipv4Addr");
|
|
Ok(data.get_u32_be().into())
|
|
}
|
|
|
|
fn serialize(&self, _context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> 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<Bytes>) -> Result<Self> {
|
|
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<u8>) -> 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<T: super::DnsPacketData>(data: &'static [u8]) -> Result<T> {
|
|
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::<u16>(b"\x80\x08").unwrap() == 0x8008);
|
|
}
|
|
|
|
#[derive(super::DnsPacketData, PartialEq, Eq, Debug)]
|
|
struct Unit;
|
|
|
|
#[test]
|
|
fn test_unit() {
|
|
assert_eq!(deserialize::<Unit>(b"").unwrap(), Unit);
|
|
}
|
|
|
|
#[derive(super::DnsPacketData, PartialEq, Eq, Debug)]
|
|
struct Tuple(u16);
|
|
|
|
#[test]
|
|
fn test_tuple() {
|
|
assert_eq!(deserialize::<Tuple>(b"\x04\xd2").unwrap(), Tuple(1234));
|
|
}
|
|
}
|