mirror of
https://github.com/ZeusWPI/ZNS.git
synced 2024-11-28 15:01: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,
|
||||
ttl: 4096,
|
||||
rdlength: ip.len() as u16,
|
||||
rdata: ip,
|
||||
rdata: vec![1,2,3,4],
|
||||
};
|
||||
|
||||
response.header.flags |= 0b1000010110000000;
|
||||
|
@ -46,7 +46,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
tokio::spawn(async move {
|
||||
let response = create_query(message).await;
|
||||
println!("{:?}",response);
|
||||
let vec = Message::to_bytes(&response);
|
||||
let vec = Message::to_bytes(response);
|
||||
let decoded = Message::from_bytes(vec.as_slice());
|
||||
println!("{:?}",decoded);
|
||||
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::{
|
||||
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>;
|
||||
|
@ -33,7 +33,7 @@ pub trait FromBytes {
|
|||
fn from_bytes(bytes: &[u8]) -> Result<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn to_bytes(s: &Self) -> Vec<u8>
|
||||
fn to_bytes(s: Self) -> Vec<u8>
|
||||
where
|
||||
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>()];
|
||||
|
||||
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 {
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||
// 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"),
|
||||
})
|
||||
} else {
|
||||
let mut qname = vec![];
|
||||
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;
|
||||
let (qname, i) = LabelString::from_bytes(bytes)?;
|
||||
|
||||
if bytes.len() - i < size_of::<Class>() + size_of::<Type>() {
|
||||
Err(ParseError {
|
||||
|
@ -122,13 +139,8 @@ impl FromBytes for Question {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_bytes(question: &Self) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![];
|
||||
for label in &question.qname {
|
||||
result.push(label.len() as u8);
|
||||
result.extend(label.as_bytes());
|
||||
}
|
||||
result.push(0);
|
||||
fn to_bytes(question: Self) -> Vec<u8> {
|
||||
let mut result = LabelString::to_bytes((question.qname, 0));
|
||||
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
|
||||
|
@ -136,28 +148,55 @@ impl FromBytes for Question {
|
|||
}
|
||||
|
||||
impl FromBytes for RR {
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
todo!()
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||
let (name, i) = LabelString::from_bytes(bytes)?;
|
||||
if bytes.len() - i < size_of::<Type>() + size_of::<Class>() + 6 {
|
||||
Err(ParseError {
|
||||
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> {
|
||||
let mut result = vec![];
|
||||
for label in &rr.name {
|
||||
result.push(label.len() as u8);
|
||||
result.extend(label.as_bytes());
|
||||
}
|
||||
result.push(0);
|
||||
fn to_bytes(rr: Self) -> Vec<u8> {
|
||||
let mut result = LabelString::to_bytes((rr.name, 0));
|
||||
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(i32::to_be_bytes(rr.ttl.to_owned()));
|
||||
result.extend(u16::to_be_bytes(4 as u16));
|
||||
result.push(93);
|
||||
result.push(184);
|
||||
result.push(216);
|
||||
result.push(34);
|
||||
result.extend(rr.rdata);
|
||||
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![];
|
||||
result.extend(Header::to_bytes(&message.header));
|
||||
result.extend(Question::to_bytes(&message.question));
|
||||
result.extend(Header::to_bytes(message.header));
|
||||
result.extend(Question::to_bytes(message.question));
|
||||
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() {
|
||||
result.extend(RR::to_bytes(&message.authority.clone().unwrap()));
|
||||
result.extend(RR::to_bytes(message.authority.unwrap()));
|
||||
}
|
||||
if message.additional.is_some() {
|
||||
result.extend(RR::to_bytes(&message.additional.clone().unwrap()));
|
||||
result.extend(RR::to_bytes(message.additional.unwrap()));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
|
|
@ -43,9 +43,11 @@ pub struct RR {
|
|||
pub class: Class,
|
||||
pub ttl: i32,
|
||||
pub rdlength: u16,
|
||||
pub rdata: String,
|
||||
pub rdata: Vec<u8>,
|
||||
}
|
||||
|
||||
pub type LabelString = (Vec<String>,usize);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Response {
|
||||
field: Type,
|
||||
|
|
Loading…
Reference in a new issue