mirror of
https://github.com/ZeusWPI/ZNS.git
synced 2024-11-24 22:11:10 +01:00
Byte parser for RR
This commit is contained in:
parent
aa64201d30
commit
08b5947fbb
3 changed files with 88 additions and 47 deletions
|
@ -22,7 +22,7 @@ async fn create_query(message: Message) -> Message {
|
||||||
class: Class::IN,
|
class: Class::IN,
|
||||||
ttl: 4096,
|
ttl: 4096,
|
||||||
rdlength: ip.len() as u16,
|
rdlength: ip.len() as u16,
|
||||||
rdata: ip,
|
rdata: vec![1,2,3,4],
|
||||||
};
|
};
|
||||||
|
|
||||||
response.header.flags |= 0b1000010110000000;
|
response.header.flags |= 0b1000010110000000;
|
||||||
|
@ -46,7 +46,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let response = create_query(message).await;
|
let response = create_query(message).await;
|
||||||
println!("{:?}",response);
|
println!("{:?}",response);
|
||||||
let vec = Message::to_bytes(&response);
|
let vec = Message::to_bytes(response);
|
||||||
let decoded = Message::from_bytes(vec.as_slice());
|
let decoded = Message::from_bytes(vec.as_slice());
|
||||||
println!("{:?}",decoded);
|
println!("{:?}",decoded);
|
||||||
let _ = socket.send_to(vec.as_slice(),addr).await;
|
let _ = socket.send_to(vec.as_slice(),addr).await;
|
||||||
|
|
125
src/parser.rs
125
src/parser.rs
|
@ -2,7 +2,7 @@ use std::{mem::size_of, vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::ParseError,
|
errors::ParseError,
|
||||||
structs::{Class, Header, Message, Question, Type, RR},
|
structs::{Class, Header, LabelString, Message, Question, Type, RR},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, ParseError>;
|
type Result<T> = std::result::Result<T, ParseError>;
|
||||||
|
@ -33,7 +33,7 @@ pub trait FromBytes {
|
||||||
fn from_bytes(bytes: &[u8]) -> Result<Self>
|
fn from_bytes(bytes: &[u8]) -> Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
fn to_bytes(s: &Self) -> Vec<u8>
|
fn to_bytes(s: Self) -> Vec<u8>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ impl FromBytes for Header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_bytes(header: &Self) -> Vec<u8> {
|
fn to_bytes(header: Self) -> Vec<u8> {
|
||||||
let mut result: [u8; size_of::<Header>()] = [0; size_of::<Header>()];
|
let mut result: [u8; size_of::<Header>()] = [0; size_of::<Header>()];
|
||||||
|
|
||||||
result[0..2].copy_from_slice(&u16::to_be_bytes(header.id));
|
result[0..2].copy_from_slice(&u16::to_be_bytes(header.id));
|
||||||
|
@ -71,6 +71,33 @@ impl FromBytes for Header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromBytes for LabelString {
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
|
let mut i = 0;
|
||||||
|
let mut qname = vec![];
|
||||||
|
|
||||||
|
// Parse qname labels
|
||||||
|
while bytes[i] != 0 && bytes[i] as usize + i < bytes.len() {
|
||||||
|
qname
|
||||||
|
.push(String::from_utf8(bytes[i + 1..bytes[i] as usize + 1 + i].to_vec()).unwrap());
|
||||||
|
i += bytes[i] as usize + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
Ok((qname, i))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_bytes((name, _): Self) -> Vec<u8> {
|
||||||
|
let mut result: Vec<u8> = vec![];
|
||||||
|
for label in name {
|
||||||
|
result.push(label.len() as u8);
|
||||||
|
result.extend(label.as_bytes());
|
||||||
|
}
|
||||||
|
result.push(0);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromBytes for Question {
|
impl FromBytes for Question {
|
||||||
fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
// 16 for length octet + zero length octet
|
// 16 for length octet + zero length octet
|
||||||
|
@ -80,17 +107,7 @@ impl FromBytes for Question {
|
||||||
message: String::from("len of bytes smaller then minimum size"),
|
message: String::from("len of bytes smaller then minimum size"),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let mut qname = vec![];
|
let (qname, i) = LabelString::from_bytes(bytes)?;
|
||||||
let mut i = 0;
|
|
||||||
|
|
||||||
// Parse qname labels
|
|
||||||
while bytes[i] != 0 && bytes[i] as usize + i < bytes.len() {
|
|
||||||
qname.push(
|
|
||||||
String::from_utf8(bytes[i + 1..bytes[i] as usize + 1 + i].to_vec()).unwrap(),
|
|
||||||
);
|
|
||||||
i += bytes[i] as usize + 1;
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
|
|
||||||
if bytes.len() - i < size_of::<Class>() + size_of::<Type>() {
|
if bytes.len() - i < size_of::<Class>() + size_of::<Type>() {
|
||||||
Err(ParseError {
|
Err(ParseError {
|
||||||
|
@ -122,13 +139,8 @@ impl FromBytes for Question {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_bytes(question: &Self) -> Vec<u8> {
|
fn to_bytes(question: Self) -> Vec<u8> {
|
||||||
let mut result: Vec<u8> = vec![];
|
let mut result = LabelString::to_bytes((question.qname, 0));
|
||||||
for label in &question.qname {
|
|
||||||
result.push(label.len() as u8);
|
|
||||||
result.extend(label.as_bytes());
|
|
||||||
}
|
|
||||||
result.push(0);
|
|
||||||
result.extend(u16::to_be_bytes(question.qtype.to_owned() as u16));
|
result.extend(u16::to_be_bytes(question.qtype.to_owned() as u16));
|
||||||
result.extend(u16::to_be_bytes(question.qclass.to_owned() as u16));
|
result.extend(u16::to_be_bytes(question.qclass.to_owned() as u16));
|
||||||
result
|
result
|
||||||
|
@ -136,28 +148,55 @@ impl FromBytes for Question {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromBytes for RR {
|
impl FromBytes for RR {
|
||||||
fn from_bytes(bytes: &[u8]) -> Result<Self>
|
fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
where
|
let (name, i) = LabelString::from_bytes(bytes)?;
|
||||||
Self: Sized,
|
if bytes.len() - i < size_of::<Type>() + size_of::<Class>() + 6 {
|
||||||
{
|
Err(ParseError {
|
||||||
todo!()
|
object: String::from("RR"),
|
||||||
|
message: String::from("len of rest of bytes smaller then minimum size"),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let _type = Type::try_from(u16::from_be_bytes(bytes[i..i + 2].try_into().unwrap()))
|
||||||
|
.map_err(|_| ParseError {
|
||||||
|
object: String::from("Type"),
|
||||||
|
message: String::from("invalid"),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let class =
|
||||||
|
Class::try_from(u16::from_be_bytes(bytes[i + 2..i + 4].try_into().unwrap()))
|
||||||
|
.map_err(|_| ParseError {
|
||||||
|
object: String::from("Class"),
|
||||||
|
message: String::from("invalid"),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let ttl = i32::from_be_bytes(bytes[i + 4..i + 8].try_into().unwrap());
|
||||||
|
let rdlength = u16::from_be_bytes(bytes[i + 8..i + 10].try_into().unwrap());
|
||||||
|
|
||||||
|
if bytes.len() - i - 10 != rdlength as usize {
|
||||||
|
Err(ParseError {
|
||||||
|
object: String::from("RR"),
|
||||||
|
message: String::from("len of rest of bytes not equal to rdlength"),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Ok(RR {
|
||||||
|
name,
|
||||||
|
_type,
|
||||||
|
class,
|
||||||
|
ttl,
|
||||||
|
rdlength,
|
||||||
|
rdata: bytes[i + 10..].to_vec(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_bytes(rr: &Self) -> Vec<u8> {
|
fn to_bytes(rr: Self) -> Vec<u8> {
|
||||||
let mut result = vec![];
|
let mut result = LabelString::to_bytes((rr.name, 0));
|
||||||
for label in &rr.name {
|
|
||||||
result.push(label.len() as u8);
|
|
||||||
result.extend(label.as_bytes());
|
|
||||||
}
|
|
||||||
result.push(0);
|
|
||||||
result.extend(u16::to_be_bytes(rr._type.to_owned() as u16));
|
result.extend(u16::to_be_bytes(rr._type.to_owned() as u16));
|
||||||
result.extend(u16::to_be_bytes(rr.class.to_owned() as u16));
|
result.extend(u16::to_be_bytes(rr.class.to_owned() as u16));
|
||||||
result.extend(i32::to_be_bytes(rr.ttl.to_owned()));
|
result.extend(i32::to_be_bytes(rr.ttl.to_owned()));
|
||||||
result.extend(u16::to_be_bytes(4 as u16));
|
result.extend(u16::to_be_bytes(4 as u16));
|
||||||
result.push(93);
|
result.extend(rr.rdata);
|
||||||
result.push(184);
|
|
||||||
result.push(216);
|
|
||||||
result.push(34);
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,18 +214,18 @@ impl FromBytes for Message {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_bytes(message: &Self) -> Vec<u8> {
|
fn to_bytes(message: Self) -> Vec<u8> {
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
result.extend(Header::to_bytes(&message.header));
|
result.extend(Header::to_bytes(message.header));
|
||||||
result.extend(Question::to_bytes(&message.question));
|
result.extend(Question::to_bytes(message.question));
|
||||||
if message.answer.is_some() {
|
if message.answer.is_some() {
|
||||||
result.extend(RR::to_bytes(&message.answer.clone().unwrap()));
|
result.extend(RR::to_bytes(message.answer.unwrap()));
|
||||||
}
|
}
|
||||||
if message.authority.is_some() {
|
if message.authority.is_some() {
|
||||||
result.extend(RR::to_bytes(&message.authority.clone().unwrap()));
|
result.extend(RR::to_bytes(message.authority.unwrap()));
|
||||||
}
|
}
|
||||||
if message.additional.is_some() {
|
if message.additional.is_some() {
|
||||||
result.extend(RR::to_bytes(&message.additional.clone().unwrap()));
|
result.extend(RR::to_bytes(message.additional.unwrap()));
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,9 +43,11 @@ pub struct RR {
|
||||||
pub class: Class,
|
pub class: Class,
|
||||||
pub ttl: i32,
|
pub ttl: i32,
|
||||||
pub rdlength: u16,
|
pub rdlength: u16,
|
||||||
pub rdata: String,
|
pub rdata: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type LabelString = (Vec<String>,usize);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
field: Type,
|
field: Type,
|
||||||
|
|
Loading…
Reference in a new issue