Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
BrendanBall committed Feb 4, 2024
1 parent cb23cef commit aeeb69a
Show file tree
Hide file tree
Showing 15 changed files with 326 additions and 304 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[workspace]
members = ["dns_decode", "dns_encode"]
members = ["dns_decode", "dns_encode", "dns_types"]
resolver = "2"

3 changes: 2 additions & 1 deletion dns_decode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
dns_types = { path = "../dns_types" }
nom = "7.1.3"
hex = "0.4.3"
thiserror = "1.0.56"
thiserror = "1.0.56"
20 changes: 5 additions & 15 deletions dns_decode/src/message.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{message_header::*, query::*, resource_record::*};
use dns_types::*;
use nom::{multi::count, IResult};
use thiserror::Error;

Expand All @@ -8,21 +9,10 @@ pub enum ParseError {
Unknown,
}

#[derive(Debug, PartialEq)]
pub struct Message {
pub header: MessageHeader,
pub queries: Vec<Query>,
pub answers: Vec<ResourceRecord>,
}

impl TryFrom<&[u8]> for Message {
type Error = ParseError;

fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
// TODO improve error reporting
let (_, m) = message(input).map_err(|_op| ParseError::Unknown)?;
Ok(m)
}
pub fn parse_message(input: &[u8]) -> Result<Message, ParseError> {
// TODO improve error reporting
let (_, m) = message(input).map_err(|_op| ParseError::Unknown)?;
Ok(m)
}

fn message(input: &[u8]) -> IResult<&[u8], Message> {
Expand Down
147 changes: 2 additions & 145 deletions dns_decode/src/message_header.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use dns_types::message_header::*;

use nom::{
bits::{bits, streaming::take},
error::Error,
Expand All @@ -6,151 +8,6 @@ use nom::{
};
use std::convert::Into;

#[derive(Debug, PartialEq)]
pub struct MessageHeader {
pub message_id: u16,
pub flags: Flags,
pub query_count: u16,
pub answer_count: u16,
pub name_server_count: u16,
pub additional_count: u16,
}

#[derive(Debug, PartialEq)]
pub struct Flags {
pub qr: QR,
pub opcode: Opcode,
pub aa: AuthoritativeAnswer,
pub truncated: Truncated,
pub recursion_desired: RecursionDesired,
pub recursion_available: RecursionAvailable,
pub rcode: Rcode,
}

#[derive(Debug, PartialEq)]
pub enum QR {
Query,
Response,
}

impl Into<QR> for u8 {
fn into(self) -> QR {
match self {
0 => QR::Query,
1 => QR::Response,
_ => unreachable!(),
}
}
}

#[derive(Debug, PartialEq)]
pub enum Opcode {
Query,
IQuery,
Status,
Unknown,
}

impl Into<Opcode> for u8 {
fn into(self) -> Opcode {
match self {
0 => Opcode::Query,
1 => Opcode::IQuery,
2 => Opcode::Status,
3 => Opcode::Unknown,
_ => unreachable!(),
}
}
}

#[derive(Debug, PartialEq)]
pub enum AuthoritativeAnswer {
Authoritative,
NonAuthoritative,
}

impl Into<AuthoritativeAnswer> for u8 {
fn into(self) -> AuthoritativeAnswer {
match self {
0 => AuthoritativeAnswer::NonAuthoritative,
1 => AuthoritativeAnswer::Authoritative,
_ => unreachable!(),
}
}
}

#[derive(Debug, PartialEq)]
pub enum Truncated {
Truncated,
NotTruncated,
}

impl Into<Truncated> for u8 {
fn into(self) -> Truncated {
match self {
0 => Truncated::NotTruncated,
1 => Truncated::Truncated,
_ => unreachable!(),
}
}
}

#[derive(Debug, PartialEq)]
pub enum RecursionDesired {
Desired,
NotDesired,
}

impl Into<RecursionDesired> for u8 {
fn into(self) -> RecursionDesired {
match self {
0 => RecursionDesired::NotDesired,
1 => RecursionDesired::Desired,
_ => unreachable!(),
}
}
}

#[derive(Debug, PartialEq)]
pub enum RecursionAvailable {
Available,
NotAvailable,
}

impl Into<RecursionAvailable> for u8 {
fn into(self) -> RecursionAvailable {
match self {
0 => RecursionAvailable::NotAvailable,
1 => RecursionAvailable::Available,
_ => unreachable!(),
}
}
}

#[derive(Debug, PartialEq)]
pub enum Rcode {
NoError,
FormatError,
ServerFailure,
NameError,
NotImplemented,
Refused,
}

impl Into<Rcode> for u8 {
fn into(self) -> Rcode {
match self {
0 => Rcode::NoError,
1 => Rcode::FormatError,
2 => Rcode::ServerFailure,
3 => Rcode::NameError,
4 => Rcode::NotImplemented,
5 => Rcode::Refused,
_ => unreachable!(),
}
}
}

fn dns_flags(input: &[u8]) -> IResult<&[u8], Flags> {
fn dns_flags_inner(
input: (&[u8], usize),
Expand Down
57 changes: 2 additions & 55 deletions dns_decode/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use dns_types::query::*;

use nom::{
bytes::complete::{tag, take},
combinator::iterator,
Expand All @@ -7,61 +9,6 @@ use nom::{
};
use std::convert::Into;

#[derive(Debug, PartialEq)]
pub struct Query {
pub name: Vec<String>,
pub query_type: QueryType,
pub query_class: QueryClass,
}

#[derive(Debug, PartialEq)]
pub enum QueryType {
A,
NS,
CNAME,
SOA,
WKS,
PTR,
MX,
SRV,
AAAA,
ANY,
Unknown(u16),
}

impl Into<QueryType> for u16 {
fn into(self) -> QueryType {
match self {
1 => QueryType::A,
2 => QueryType::NS,
5 => QueryType::CNAME,
6 => QueryType::SOA,
11 => QueryType::WKS,
12 => QueryType::PTR,
15 => QueryType::MX,
33 => QueryType::SRV,
28 => QueryType::AAAA,
255 => QueryType::ANY,
u => QueryType::Unknown(u),
}
}
}

#[derive(Debug, PartialEq)]
pub enum QueryClass {
Internet,
Unknown(u16),
}

impl Into<QueryClass> for u16 {
fn into(self) -> QueryClass {
match self {
1 => QueryClass::Internet,
u => QueryClass::Unknown(u),
}
}
}

fn label(input: &[u8]) -> IResult<&[u8], String> {
let (input, str_length) = be_u8(input)?;
if str_length == 0 {
Expand Down
79 changes: 2 additions & 77 deletions dns_decode/src/resource_record.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use dns_types::resource_record::*;
use nom::{
multi::length_value,
number::complete::{be_u128, be_u16, be_u32},
Expand All @@ -9,82 +10,6 @@ use std::{
net::{Ipv4Addr, Ipv6Addr},
};

#[derive(Debug, PartialEq)]
pub struct ResourceRecord {
pub name: Name,
pub resource_type: ResourceType,
pub resource_class: ResourceClass,
pub ttl: u32,
pub rdata: ResourceData,
}

#[derive(Debug, PartialEq)]
pub enum Name {
Value(Vec<String>),
Pointer(u16),
}

#[derive(Debug, PartialEq, Copy, Clone)]
pub enum ResourceType {
A,
NS,
CNAME,
SOA,
WKS,
PTR,
MX,
SRV,
AAAA,
Unknown(u16),
}

impl Into<ResourceType> for u16 {
fn into(self) -> ResourceType {
match self {
1 => ResourceType::A,
2 => ResourceType::NS,
5 => ResourceType::CNAME,
6 => ResourceType::SOA,
11 => ResourceType::WKS,
12 => ResourceType::PTR,
15 => ResourceType::MX,
33 => ResourceType::SRV,
28 => ResourceType::AAAA,
u => ResourceType::Unknown(u),
}
}
}

#[derive(Debug, PartialEq)]
pub enum ResourceClass {
Internet,
Unknown(u16),
}

impl Into<ResourceClass> for u16 {
fn into(self) -> ResourceClass {
match self {
1 => ResourceClass::Internet,
u => ResourceClass::Unknown(u),
}
}
}

#[derive(Debug, PartialEq)]
pub enum ResourceData {
SOA,
MX,
A(Ipv4Addr),
AAAA(Ipv6Addr),
PTR,
NS,
}

#[derive(Debug, PartialEq)]
pub struct ARecord {
ip_address: u32,
}

fn name(input: &[u8]) -> IResult<&[u8], Name> {
// TODO implement pointer/label properly
let (input, pointer) = be_u16(input)?;
Expand Down Expand Up @@ -168,7 +93,7 @@ mod tests {
#[test]
fn test_resource_record_aaaa_record() {
let dns_resource_record_bytes =
hex::decode("c00c001c00010000eee60010260628000010022000010248189325c81946").unwrap();
hex::decode("c00c001c00010000eee6001026062800022000010248189325c81946").unwrap();
let result = resource_record(&dns_resource_record_bytes);

assert_eq!(
Expand Down
Loading

0 comments on commit aeeb69a

Please sign in to comment.