Skip to content

Commit

Permalink
adding rdata trait, tightening question parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Sarsoo committed Feb 2, 2024
1 parent 26d1a18 commit 0ae64f6
Show file tree
Hide file tree
Showing 12 changed files with 448 additions and 305 deletions.
30 changes: 30 additions & 0 deletions dnstp/src/message/answer/ip_address.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::fmt::{Debug, Formatter};
use std::net::{IpAddr, Ipv4Addr};

Check warning on line 2 in dnstp/src/message/answer/ip_address.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused import: `IpAddr`

Check warning on line 2 in dnstp/src/message/answer/ip_address.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused import: `IpAddr`
use crate::message::answer::RData;

pub struct IpRData {
pub rdata: Ipv4Addr
}

impl Debug for IpRData {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IP")
.field("data", &self.rdata)
.finish()
}
}

impl RData for IpRData {
fn to_bytes(&self) -> Vec<u8> {
return self.rdata.octets().to_vec();
}
}

impl IpRData {
pub fn from(rdata: Ipv4Addr) -> IpRData
{
IpRData {
rdata
}
}
}
47 changes: 43 additions & 4 deletions dnstp/src/message/answer.rs → dnstp/src/message/answer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
mod raw_rdata;
pub use raw_rdata::RawRData;

mod ip_address;
pub use ip_address::IpRData;

#[cfg(test)]
mod tests;

use std::fmt::{Debug, Display};

Check warning on line 10 in dnstp/src/message/answer/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused import: `Display`

Check warning on line 10 in dnstp/src/message/answer/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused import: `Display`
use crate::byte::{four_byte_split, two_byte_split};
use crate::message::question::{DNSQuestion, QClass, QType};
use crate::message::question::{DNSQuestion, QClass, QType, QuestionParseError};

Check warning on line 12 in dnstp/src/message/answer/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused import: `QuestionParseError`

Check warning on line 12 in dnstp/src/message/answer/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused import: `QuestionParseError`
use crate::string::encode_domain_name;

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]

pub trait RData: Debug {
fn to_bytes(&self) -> Vec<u8>;
}

#[derive(Debug)]
pub struct DNSAnswer {
pub name: String,
pub answer_type: QType,
pub class: QClass,
pub ttl: u32,
pub rd_length: u16,
pub r_data: Vec<u8>
pub r_data: Box<dyn RData>
}

impl DNSAnswer {
Expand All @@ -36,10 +51,22 @@ impl DNSAnswer {
ret.push(rd_length_split.0);
ret.push(rd_length_split.1);

ret.append(&mut self.r_data.clone());
ret.append(&mut self.r_data.to_bytes());

return ret
}

pub fn from_query(query: &DNSQuestion, data: Box<dyn RData>, ttl: Option<u32>) -> DNSAnswer
{
DNSAnswer {
name: query.qname.clone(),
answer_type: query.qtype,
class: query.qclass,
ttl: ttl.unwrap_or(0),
rd_length: data.to_bytes().len() as u16,
r_data: data
}
}
}

pub fn answers_to_bytes(answers: &Vec<DNSAnswer>) -> Vec<u8>
Expand All @@ -52,4 +79,16 @@ pub fn answers_to_bytes(answers: &Vec<DNSAnswer>) -> Vec<u8>
}

ret
}

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]
pub enum AnswerParseError {
ShortLength(usize),
QTypeParse(u8),
QClassParse(u8)
}

pub fn answers_from_bytes(bytes: Vec<u8>, total_answers: u16) -> Result<(i32, Vec<DNSAnswer>), AnswerParseError>

Check warning on line 91 in dnstp/src/message/answer/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused variable: `bytes`

Check warning on line 91 in dnstp/src/message/answer/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused variable: `total_answers`

Check warning on line 91 in dnstp/src/message/answer/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused variable: `bytes`

Check warning on line 91 in dnstp/src/message/answer/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test

unused variable: `total_answers`
{
Ok((0, vec![]))
}
29 changes: 29 additions & 0 deletions dnstp/src/message/answer/raw_rdata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::fmt::{Debug, Formatter};
use crate::message::answer::RData;

pub struct RawRData {
pub rdata: Vec<u8>
}

impl Debug for RawRData {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RawRData")
.field("data", &self.rdata)
.finish()
}
}

impl RData for RawRData {
fn to_bytes(&self) -> Vec<u8> {
return self.rdata.clone();
}
}

impl RawRData {
pub fn from(rdata: Vec<u8>) -> RawRData
{
RawRData {
rdata
}
}
}
27 changes: 27 additions & 0 deletions dnstp/src/message/answer/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::message::question::{DNSQuestion, QClass, QType, questions_from_bytes};

use super::*;

#[test]
#[ignore]
fn one_answer_back_and_forth() {
let q = DNSAnswer {
name: "google.com".to_string(),
answer_type: QType::A,
class: QClass::Internet,
ttl: 0,
rd_length: 0,
r_data: Box::from(RawRData::from(vec![]))
};

let mut q_bytes = q.to_bytes();
q_bytes.append(&mut vec![0, 0, 0, 0, 0, 0]);

let (q_read, q_reconstructed) = answers_from_bytes(q_bytes, 0).unwrap();

assert_eq!(q.name, q_reconstructed[0].name);
assert_eq!(q.answer_type, q_reconstructed[0].answer_type);
assert_eq!(q.class, q_reconstructed[0].class);
assert_eq!(q.ttl, q_reconstructed[0].ttl);
assert_eq!(q.rd_length, q_reconstructed[0].rd_length);
}
2 changes: 1 addition & 1 deletion dnstp/src/message/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl TryFrom<u16> for ResponseCode {
}

/// Represents a header including flag fields and record counts
#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]
#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Clone)]
pub struct DNSHeader {
/// Random ID for associating responses with requests
pub id: u16,
Expand Down
Loading

0 comments on commit 0ae64f6

Please sign in to comment.