10
0
Fork 0
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:
Xander Bil 2024-02-29 23:03:33 +01:00
parent aa64201d30
commit 08b5947fbb
No known key found for this signature in database
GPG key ID: EC9706B54A278598
3 changed files with 88 additions and 47 deletions

View file

@ -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;

View file

@ -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,19 +214,19 @@ 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
}
}

View file

@ -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,