48 lines
1.4 KiB
Rust
48 lines
1.4 KiB
Rust
|
use bytes::Bytes;
|
||
|
use common_types::*;
|
||
|
use failure::{ResultExt, Fail};
|
||
|
use ser::text::{DnsTextFormatter, next_field};
|
||
|
use ser::packet::remaining_bytes;
|
||
|
use common_types::binary::HEXLOWER_PERMISSIVE_ALLOW_WS;
|
||
|
use std::fmt;
|
||
|
use errors::*;
|
||
|
|
||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||
|
pub struct UnknownRecord {
|
||
|
rr_type: Type,
|
||
|
raw: Bytes,
|
||
|
}
|
||
|
|
||
|
impl UnknownRecord {
|
||
|
pub fn new(rr_type: Type, raw: Bytes) -> Self {
|
||
|
UnknownRecord {
|
||
|
rr_type: rr_type,
|
||
|
raw: raw,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn deserialize(rr_type: Type, data: &mut ::std::io::Cursor<Bytes>) -> Result<Self> {
|
||
|
Ok(UnknownRecord::new(rr_type, remaining_bytes(data)))
|
||
|
}
|
||
|
|
||
|
pub fn dns_parse(rr_type: Type, data: &mut &str) -> Result<Self> {
|
||
|
let field = next_field(data)?;
|
||
|
ensure!(field == r"\#", "expect \\# token to mark generic encoding");
|
||
|
let field = next_field(data).context("generic record data length")?;
|
||
|
let len: usize = field.parse()?;
|
||
|
|
||
|
let result = HEXLOWER_PERMISSIVE_ALLOW_WS.decode(data.as_bytes())
|
||
|
.with_context(|e| e.context(format!("invalid hex: {:?}", data)))?;
|
||
|
ensure!(len == result.len(), "length {} doesn't match length of encoded data {}", len, result.len());
|
||
|
|
||
|
Ok(UnknownRecord {
|
||
|
rr_type,
|
||
|
raw: result.into(),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
pub fn dns_format(&self, f: &mut DnsTextFormatter) -> fmt::Result {
|
||
|
write!(f, "TYPE{} \\# {} {}", self.rr_type.0, self.raw.len(), HEXLOWER_PERMISSIVE_ALLOW_WS.encode(&self.raw))
|
||
|
}
|
||
|
}
|