91 lines
2.7 KiB
Rust
91 lines
2.7 KiB
Rust
use bytes::{Bytes, Buf};
|
|
use std::io::Cursor;
|
|
|
|
use ser::DnsPacketData;
|
|
use errors::*;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct HexShortBlob(Bytes);
|
|
|
|
// Similar to `ShortText`, but uses (unquoted, no spaces allowed) hex
|
|
// for text representation; "-" when empty
|
|
impl DnsPacketData for HexShortBlob {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
check_enough_data!(data, 1, "HexShortBlob length");
|
|
let label_len = data.get_u8() as usize;
|
|
check_enough_data!(data, label_len, "HexShortBlob content");
|
|
let pos = data.position() as usize;
|
|
let text = data.get_ref().slice(pos, pos + label_len);
|
|
data.advance(label_len);
|
|
Ok(HexShortBlob(text))
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct Base32ShortBlob(Bytes);
|
|
|
|
// Similar to `ShortText`, but uses (unquoted, no spaces allowed) base32
|
|
// for text representation; "-" when empty
|
|
impl DnsPacketData for Base32ShortBlob {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
check_enough_data!(data, 1, "Base32ShortBlob length");
|
|
let label_len = data.get_u8() as usize;
|
|
check_enough_data!(data, label_len, "Base32ShortBlob content");
|
|
let pos = data.position() as usize;
|
|
let text = data.get_ref().slice(pos, pos + label_len);
|
|
data.advance(label_len);
|
|
Ok(Base32ShortBlob(text))
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct LongText(Vec<Bytes>);
|
|
|
|
// RFC 1035 names this `One or more <character-string>`. No following
|
|
// field allowed.
|
|
impl DnsPacketData for LongText {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
let mut texts = Vec::new();
|
|
loop {
|
|
check_enough_data!(data, 1, "LongText length");
|
|
let label_len = data.get_u8() as usize;
|
|
check_enough_data!(data, label_len, "LongText content");
|
|
let pos = data.position() as usize;
|
|
texts.push(data.get_ref().slice(pos, pos + label_len));
|
|
data.advance(label_len);
|
|
if !data.has_remaining() { break; }
|
|
}
|
|
Ok(LongText(texts))
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct RemainingText(Bytes);
|
|
|
|
// No length byte, just all data to end of record. uses base64 encoding
|
|
// for text representation
|
|
impl DnsPacketData for RemainingText {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
let pos = data.position() as usize;
|
|
let len = data.remaining();
|
|
let text = data.get_ref().slice(pos, pos + len);
|
|
data.advance(len);
|
|
Ok(RemainingText(text))
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct HexRemainingBlob(Bytes);
|
|
|
|
// No length byte, just all data to end of record. uses hex encoding for
|
|
// text representation (spaces are ignored - last field in record).
|
|
impl DnsPacketData for HexRemainingBlob {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
let pos = data.position() as usize;
|
|
let len = data.remaining();
|
|
let text = data.get_ref().slice(pos, pos + len);
|
|
data.advance(len);
|
|
Ok(HexRemainingBlob(text))
|
|
}
|
|
}
|