summaryrefslogtreecommitdiff
path: root/src/dns/packet
diff options
context:
space:
mode:
authorTyler Murphy <tylerm@tylerm.dev>2023-04-05 23:08:09 -0400
committerTyler Murphy <tylerm@tylerm.dev>2023-04-05 23:08:09 -0400
commitbb85374b79086cd8efde24d23a1bffeb97cae26b (patch)
treea36e2df6a89e567822820ac110afec6a13eacbf6 /src/dns/packet
parentfinish dns and start webserver (diff)
downloadwrapper-bb85374b79086cd8efde24d23a1bffeb97cae26b.tar.gz
wrapper-bb85374b79086cd8efde24d23a1bffeb97cae26b.tar.bz2
wrapper-bb85374b79086cd8efde24d23a1bffeb97cae26b.zip
new c version
Diffstat (limited to 'src/dns/packet')
-rw-r--r--src/dns/packet/buffer.rs227
-rw-r--r--src/dns/packet/header.rs102
-rw-r--r--src/dns/packet/mod.rs128
-rw-r--r--src/dns/packet/query.rs78
-rw-r--r--src/dns/packet/question.rs31
-rw-r--r--src/dns/packet/record.rs544
-rw-r--r--src/dns/packet/result.rs22
7 files changed, 0 insertions, 1132 deletions
diff --git a/src/dns/packet/buffer.rs b/src/dns/packet/buffer.rs
deleted file mode 100644
index 058156e..0000000
--- a/src/dns/packet/buffer.rs
+++ /dev/null
@@ -1,227 +0,0 @@
-use crate::Result;
-
-pub struct PacketBuffer {
- pub buf: Vec<u8>,
- pub pos: usize,
- pub size: usize,
-}
-
-impl PacketBuffer {
- pub fn new(buf: Vec<u8>) -> Self {
- Self {
- size: buf.len(),
- buf,
- pos: 0,
- }
- }
-
- pub fn pos(&self) -> usize {
- self.pos
- }
-
- pub fn step(&mut self, steps: usize) -> Result<()> {
- self.pos += steps;
-
- Ok(())
- }
-
- pub fn seek(&mut self, pos: usize) -> Result<()> {
- self.pos = pos;
-
- Ok(())
- }
-
- pub fn read(&mut self) -> Result<u8> {
- if self.pos >= self.size {
- return Err("Tried to read past end of buffer".into());
- }
- let res = self.buf[self.pos];
- self.pos += 1;
- Ok(res)
- }
-
- pub fn get(&mut self, pos: usize) -> Result<u8> {
- if pos >= self.size {
- return Err("Tried to read past end of buffer".into());
- }
- Ok(self.buf[pos])
- }
-
- pub fn get_range(&mut self, start: usize, len: usize) -> Result<&[u8]> {
- if start + len >= self.size {
- return Err("Tried to read past end of buffer".into());
- }
- Ok(&self.buf[start..start + len])
- }
-
- pub fn read_u16(&mut self) -> Result<u16> {
- let res = ((self.read()? as u16) << 8) | (self.read()? as u16);
-
- Ok(res)
- }
-
- pub fn read_u32(&mut self) -> Result<u32> {
- let res = ((self.read()? as u32) << 24)
- | ((self.read()? as u32) << 16)
- | ((self.read()? as u32) << 8)
- | (self.read()? as u32);
-
- Ok(res)
- }
-
- pub fn read_qname(&mut self, outstr: &mut String) -> Result<()> {
- let mut pos = self.pos();
- let mut jumped = false;
-
- let mut delim = "";
- let max_jumps = 5;
- let mut jumps_performed = 0;
- loop {
- // Dns Packets are untrusted data, so we need to be paranoid. Someone
- // can craft a packet with a cycle in the jump instructions. This guards
- // against such packets.
- if jumps_performed > max_jumps {
- return Err(format!("Limit of {max_jumps} jumps exceeded").into());
- }
-
- let len = self.get(pos)?;
-
- if (len & 0xC0) == 0xC0 {
- if !jumped {
- self.seek(pos + 2)?;
- }
-
- let b2 = self.get(pos + 1)? as u16;
- let offset = (((len as u16) ^ 0xC0) << 8) | b2;
- pos = offset as usize;
- jumped = true;
- jumps_performed += 1;
- continue;
- }
-
- pos += 1;
-
- if len == 0 {
- break;
- }
-
- outstr.push_str(delim);
-
- let str_buffer = self.get_range(pos, len as usize)?;
- outstr.push_str(&String::from_utf8_lossy(str_buffer).to_lowercase());
-
- delim = ".";
-
- pos += len as usize;
- }
-
- if !jumped {
- self.seek(pos)?;
- }
-
- Ok(())
- }
-
- pub fn read_string(&mut self, outstr: &mut String) -> Result<()> {
- let len = self.read()?;
-
- self.read_string_n(outstr, len)?;
-
- Ok(())
- }
-
- pub fn read_string_n(&mut self, outstr: &mut String, len: u8) -> Result<()> {
- let mut pos = self.pos;
-
- let str_buffer = self.get_range(pos, len as usize)?;
-
- let mut i = 0;
- for b in str_buffer {
- let c = *b as char;
- if c == '\0' {
- break;
- }
- outstr.push(c);
- i += 1;
- }
-
- pos += i;
- self.seek(pos)?;
-
- Ok(())
- }
-
- pub fn write(&mut self, val: u8) -> Result<()> {
- if self.size < self.pos {
- self.size = self.pos;
- }
-
- if self.buf.len() <= self.size {
- self.buf.resize(self.size + 1, 0x00);
- }
-
- self.buf[self.pos] = val;
- self.pos += 1;
- Ok(())
- }
-
- pub fn write_u8(&mut self, val: u8) -> Result<()> {
- self.write(val)?;
-
- Ok(())
- }
-
- pub fn write_u16(&mut self, val: u16) -> Result<()> {
- self.write((val >> 8) as u8)?;
- self.write((val & 0xFF) as u8)?;
-
- Ok(())
- }
-
- pub fn write_u32(&mut self, val: u32) -> Result<()> {
- self.write(((val >> 24) & 0xFF) as u8)?;
- self.write(((val >> 16) & 0xFF) as u8)?;
- self.write(((val >> 8) & 0xFF) as u8)?;
- self.write((val & 0xFF) as u8)?;
-
- Ok(())
- }
-
- pub fn write_qname(&mut self, qname: &str) -> Result<()> {
- for label in qname.split('.') {
- let len = label.len();
-
- self.write_u8(len as u8)?;
- for b in label.as_bytes() {
- self.write_u8(*b)?;
- }
- }
-
- if !qname.is_empty() {
- self.write_u8(0)?;
- }
-
- Ok(())
- }
-
- pub fn write_string(&mut self, text: &str) -> Result<()> {
- for b in text.as_bytes() {
- self.write_u8(*b)?;
- }
-
- Ok(())
- }
-
- pub fn set(&mut self, pos: usize, val: u8) -> Result<()> {
- self.buf[pos] = val;
-
- Ok(())
- }
-
- pub fn set_u16(&mut self, pos: usize, val: u16) -> Result<()> {
- self.set(pos, (val >> 8) as u8)?;
- self.set(pos + 1, (val & 0xFF) as u8)?;
-
- Ok(())
- }
-}
diff --git a/src/dns/packet/header.rs b/src/dns/packet/header.rs
deleted file mode 100644
index 2355ecb..0000000
--- a/src/dns/packet/header.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-use super::{buffer::PacketBuffer, result::ResultCode};
-use crate::Result;
-
-#[derive(Clone, Debug)]
-pub struct DnsHeader {
- pub id: u16, // 16 bits
-
- pub recursion_desired: bool, // 1 bit
- pub truncated_message: bool, // 1 bit
- pub authoritative_answer: bool, // 1 bit
- pub opcode: u8, // 4 bits
- pub response: bool, // 1 bit
-
- pub rescode: ResultCode, // 4 bits
- pub checking_disabled: bool, // 1 bit
- pub authed_data: bool, // 1 bit
- pub z: bool, // 1 bit
- pub recursion_available: bool, // 1 bit
-
- pub questions: u16, // 16 bits
- pub answers: u16, // 16 bits
- pub authoritative_entries: u16, // 16 bits
- pub resource_entries: u16, // 16 bits
-}
-
-impl DnsHeader {
- pub fn new() -> Self {
- Self {
- id: 0,
-
- recursion_desired: false,
- truncated_message: false,
- authoritative_answer: false,
- opcode: 0,
- response: false,
-
- rescode: ResultCode::NOERROR,
- checking_disabled: false,
- authed_data: false,
- z: false,
- recursion_available: false,
-
- questions: 0,
- answers: 0,
- authoritative_entries: 0,
- resource_entries: 0,
- }
- }
-
- pub fn read(&mut self, buffer: &mut PacketBuffer) -> Result<()> {
- self.id = buffer.read_u16()?;
- let flags = buffer.read_u16()?;
- let a = (flags >> 8) as u8;
- let b = (flags & 0xFF) as u8;
- self.recursion_desired = (a & (1 << 0)) > 0;
- self.truncated_message = (a & (1 << 1)) > 0;
- self.authoritative_answer = (a & (1 << 2)) > 0;
- self.opcode = (a >> 3) & 0x0F;
- self.response = (a & (1 << 7)) > 0;
-
- self.rescode = ResultCode::from_num(b & 0x0F);
- self.checking_disabled = (b & (1 << 4)) > 0;
- self.authed_data = (b & (1 << 5)) > 0;
- self.z = (b & (1 << 6)) > 0;
- self.recursion_available = (b & (1 << 7)) > 0;
-
- self.questions = buffer.read_u16()?;
- self.answers = buffer.read_u16()?;
- self.authoritative_entries = buffer.read_u16()?;
- self.resource_entries = buffer.read_u16()?;
-
- // Return the constant header size
- Ok(())
- }
-
- pub fn write(&self, buffer: &mut PacketBuffer) -> Result<()> {
- buffer.write_u16(self.id)?;
-
- buffer.write_u8(
- (self.recursion_desired as u8)
- | ((self.truncated_message as u8) << 1)
- | ((self.authoritative_answer as u8) << 2)
- | (self.opcode << 3)
- | ((self.response as u8) << 7),
- )?;
-
- buffer.write_u8(
- (self.rescode as u8)
- | ((self.checking_disabled as u8) << 4)
- | ((self.authed_data as u8) << 5)
- | ((self.z as u8) << 6)
- | ((self.recursion_available as u8) << 7),
- )?;
-
- buffer.write_u16(self.questions)?;
- buffer.write_u16(self.answers)?;
- buffer.write_u16(self.authoritative_entries)?;
- buffer.write_u16(self.resource_entries)?;
-
- Ok(())
- }
-}
diff --git a/src/dns/packet/mod.rs b/src/dns/packet/mod.rs
deleted file mode 100644
index 9873b94..0000000
--- a/src/dns/packet/mod.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-use std::net::IpAddr;
-
-use self::{
- buffer::PacketBuffer, header::DnsHeader, query::QueryType, question::DnsQuestion,
- record::DnsRecord,
-};
-use crate::Result;
-
-pub mod buffer;
-pub mod header;
-pub mod query;
-pub mod question;
-pub mod record;
-pub mod result;
-
-#[derive(Clone, Debug)]
-pub struct Packet {
- pub header: DnsHeader,
- pub questions: Vec<DnsQuestion>,
- pub answers: Vec<DnsRecord>,
- pub authorities: Vec<DnsRecord>,
- pub resources: Vec<DnsRecord>,
-}
-
-impl Packet {
- pub fn new() -> Self {
- Self {
- header: DnsHeader::new(),
- questions: Vec::new(),
- answers: Vec::new(),
- authorities: Vec::new(),
- resources: Vec::new(),
- }
- }
-
- pub fn from_buffer(buffer: &mut PacketBuffer) -> Result<Self> {
- let mut result = Self::new();
- result.header.read(buffer)?;
-
- for _ in 0..result.header.questions {
- let mut question = DnsQuestion::new("".to_string(), QueryType::UNKNOWN(0));
- question.read(buffer)?;
- result.questions.push(question);
- }
-
- for _ in 0..result.header.answers {
- let rec = DnsRecord::read(buffer)?;
- result.answers.push(rec);
- }
- for _ in 0..result.header.authoritative_entries {
- let rec = DnsRecord::read(buffer)?;
- result.authorities.push(rec);
- }
- for _ in 0..result.header.resource_entries {
- let rec = DnsRecord::read(buffer)?;
- result.resources.push(rec);
- }
-
- Ok(result)
- }
-
- pub fn write(&mut self, buffer: &mut PacketBuffer) -> Result<()> {
- self.header.questions = self.questions.len() as u16;
- self.header.answers = self.answers.len() as u16;
- self.header.authoritative_entries = self.authorities.len() as u16;
- self.header.resource_entries = self.resources.len() as u16;
-
- self.header.write(buffer)?;
-
- for question in &self.questions {
- question.write(buffer)?;
- }
- for rec in &self.answers {
- rec.write(buffer)?;
- }
- for rec in &self.authorities {
- rec.write(buffer)?;
- }
- for rec in &self.resources {
- rec.write(buffer)?;
- }
-
- Ok(())
- }
-
- pub fn get_random_a(&self) -> Option<IpAddr> {
- self.answers
- .iter()
- .filter_map(|record| match record {
- DnsRecord::A { addr, .. } => Some(IpAddr::V4(*addr)),
- DnsRecord::AAAA { addr, .. } => Some(IpAddr::V6(*addr)),
- _ => None,
- })
- .next()
- }
-
- fn get_ns<'a>(&'a self, qname: &'a str) -> impl Iterator<Item = (&'a str, &'a str)> {
- self.authorities
- .iter()
- .filter_map(|record| match record {
- DnsRecord::NS { domain, host, .. } => Some((domain.as_str(), host.as_str())),
- _ => None,
- })
- .filter(move |(domain, _)| qname.ends_with(*domain))
- }
-
- pub fn get_resolved_ns(&self, qname: &str) -> Option<IpAddr> {
- self.get_ns(qname)
- .flat_map(|(_, host)| {
- self.resources
- .iter()
- .filter_map(move |record| match record {
- DnsRecord::A { domain, addr, .. } if domain == host => {
- Some(IpAddr::V4(*addr))
- }
- DnsRecord::AAAA { domain, addr, .. } if domain == host => {
- Some(IpAddr::V6(*addr))
- }
- _ => None,
- })
- })
- .next()
- }
-
- pub fn get_unresolved_ns<'a>(&'a self, qname: &'a str) -> Option<&'a str> {
- self.get_ns(qname).map(|(_, host)| host).next()
- }
-}
diff --git a/src/dns/packet/query.rs b/src/dns/packet/query.rs
deleted file mode 100644
index 732b9b2..0000000
--- a/src/dns/packet/query.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-#[derive(PartialEq, Eq, Debug, Clone, Hash, Copy)]
-pub enum QueryType {
- UNKNOWN(u16),
- A, // 1
- NS, // 2
- CNAME, // 5
- SOA, // 6
- PTR, // 12
- MX, // 15
- TXT, // 16
- AAAA, // 28
- SRV, // 33
- OPT, // 41
- CAA, // 257
- AR, // 1000
- AAAAR, // 1001
-}
-
-impl QueryType {
- pub fn to_num(&self) -> u16 {
- match *self {
- Self::UNKNOWN(x) => x,
- Self::A => 1,
- Self::NS => 2,
- Self::CNAME => 5,
- Self::SOA => 6,
- Self::PTR => 12,
- Self::MX => 15,
- Self::TXT => 16,
- Self::AAAA => 28,
- Self::SRV => 33,
- Self::OPT => 41,
- Self::CAA => 257,
- Self::AR => 1000,
- Self::AAAAR => 1001,
- }
- }
-
- pub fn from_num(num: u16) -> Self {
- match num {
- 1 => Self::A,
- 2 => Self::NS,
- 5 => Self::CNAME,
- 6 => Self::SOA,
- 12 => Self::PTR,
- 15 => Self::MX,
- 16 => Self::TXT,
- 28 => Self::AAAA,
- 33 => Self::SRV,
- 41 => Self::OPT,
- 257 => Self::CAA,
- 1000 => Self::AR,
- 1001 => Self::AAAAR,
- _ => Self::UNKNOWN(num),
- }
- }
-
- pub fn allowed_actions(&self) -> (bool, bool) {
- // 0. duplicates allowed
- // 1. allowed to be created by database
- match self {
- QueryType::UNKNOWN(_) => (false, false),
- QueryType::A => (true, true),
- QueryType::NS => (false, true),
- QueryType::CNAME => (false, true),
- QueryType::SOA => (false, false),
- QueryType::PTR => (false, true),
- QueryType::MX => (false, true),
- QueryType::TXT => (true, true),
- QueryType::AAAA => (true, true),
- QueryType::SRV => (false, true),
- QueryType::OPT => (false, false),
- QueryType::CAA => (false, true),
- QueryType::AR => (false, true),
- QueryType::AAAAR => (false, true),
- }
- }
-}
diff --git a/src/dns/packet/question.rs b/src/dns/packet/question.rs
deleted file mode 100644
index 9042e1c..0000000
--- a/src/dns/packet/question.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use super::{buffer::PacketBuffer, query::QueryType, Result};
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct DnsQuestion {
- pub name: String,
- pub qtype: QueryType,
-}
-
-impl DnsQuestion {
- pub fn new(name: String, qtype: QueryType) -> Self {
- Self { name, qtype }
- }
-
- pub fn read(&mut self, buffer: &mut PacketBuffer) -> Result<()> {
- buffer.read_qname(&mut self.name)?;
- self.qtype = QueryType::from_num(buffer.read_u16()?); // qtype
- let _ = buffer.read_u16()?; // class
-
- Ok(())
- }
-
- pub fn write(&self, buffer: &mut PacketBuffer) -> Result<()> {
- buffer.write_qname(&self.name)?;
-
- let typenum = self.qtype.to_num();
- buffer.write_u16(typenum)?;
- buffer.write_u16(1)?;
-
- Ok(())
- }
-}
diff --git a/src/dns/packet/record.rs b/src/dns/packet/record.rs
deleted file mode 100644
index 88008f0..0000000
--- a/src/dns/packet/record.rs
+++ /dev/null
@@ -1,544 +0,0 @@
-use std::net::{Ipv4Addr, Ipv6Addr};
-
-use rand::RngCore;
-use serde::{Deserialize, Serialize};
-use tracing::{trace, warn};
-
-use super::{buffer::PacketBuffer, query::QueryType, Result};
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
-pub enum DnsRecord {
- UNKNOWN {
- domain: String,
- qtype: u16,
- data_len: u16,
- ttl: u32,
- }, // 0
- A {
- domain: String,
- addr: Ipv4Addr,
- ttl: u32,
- }, // 1
- NS {
- domain: String,
- host: String,
- ttl: u32,
- }, // 2
- CNAME {
- domain: String,
- host: String,
- ttl: u32,
- }, // 5
- SOA {
- domain: String,
- mname: String,
- nname: String,
- serial: u32,
- refresh: u32,
- retry: u32,
- expire: u32,
- minimum: u32,
- ttl: u32,
- }, // 6
- PTR {
- domain: String,
- pointer: String,
- ttl: u32,
- }, // 12
- MX {
- domain: String,
- priority: u16,
- host: String,
- ttl: u32,
- }, // 15
- TXT {
- domain: String,
- text: Vec<String>,
- ttl: u32,
- }, //16
- AAAA {
- domain: String,
- addr: Ipv6Addr,
- ttl: u32,
- }, // 28
- SRV {
- domain: String,
- priority: u16,
- weight: u16,
- port: u16,
- target: String,
- ttl: u32,
- }, // 33
- CAA {
- domain: String,
- flags: u8,
- length: u8,
- tag: String,
- value: String,
- ttl: u32,
- }, // 257
- AR {
- domain: String,
- ttl: u32,
- },
- AAAAR {
- domain: String,
- ttl: u32,
- },
-}
-
-impl DnsRecord {
- pub fn read(buffer: &mut PacketBuffer) -> Result<Self> {
- let mut domain = String::new();
- buffer.read_qname(&mut domain)?;
-
- let qtype_num = buffer.read_u16()?;
- let qtype = QueryType::from_num(qtype_num);
- let _ = buffer.read_u16()?;
- let ttl = buffer.read_u32()?;
- let data_len = buffer.read_u16()?;
-
- trace!("Reading DNS Record TYPE: {:?}", qtype);
-
- let header_pos = buffer.pos();
-
- match qtype {
- QueryType::A => {
- let raw_addr = buffer.read_u32()?;
- let addr = Ipv4Addr::new(
- ((raw_addr >> 24) & 0xFF) as u8,
- ((raw_addr >> 16) & 0xFF) as u8,
- ((raw_addr >> 8) & 0xFF) as u8,
- (raw_addr & 0xFF) as u8,
- );
-
- Ok(Self::A { domain, addr, ttl })
- }
- QueryType::AAAA => {
- let raw_addr1 = buffer.read_u32()?;
- let raw_addr2 = buffer.read_u32()?;
- let raw_addr3 = buffer.read_u32()?;
- let raw_addr4 = buffer.read_u32()?;
- let addr = Ipv6Addr::new(
- ((raw_addr1 >> 16) & 0xFFFF) as u16,
- (raw_addr1 & 0xFFFF) as u16,
- ((raw_addr2 >> 16) & 0xFFFF) as u16,
- (raw_addr2 & 0xFFFF) as u16,
- ((raw_addr3 >> 16) & 0xFFFF) as u16,
- (raw_addr3 & 0xFFFF) as u16,
- ((raw_addr4 >> 16) & 0xFFFF) as u16,
- (raw_addr4 & 0xFFFF) as u16,
- );
-
- Ok(Self::AAAA { domain, addr, ttl })
- }
- QueryType::NS => {
- let mut ns = String::new();
- buffer.read_qname(&mut ns)?;
-
- Ok(Self::NS {
- domain,
- host: ns,
- ttl,
- })
- }
- QueryType::CNAME => {
- let mut cname = String::new();
- buffer.read_qname(&mut cname)?;
-
- Ok(Self::CNAME {
- domain,
- host: cname,
- ttl,
- })
- }
- QueryType::SOA => {
- let mut mname = String::new();
- buffer.read_qname(&mut mname)?;
-
- let mut nname = String::new();
- buffer.read_qname(&mut nname)?;
-
- let serial = buffer.read_u32()?;
- let refresh = buffer.read_u32()?;
- let retry = buffer.read_u32()?;
- let expire = buffer.read_u32()?;
- let minimum = buffer.read_u32()?;
-
- Ok(Self::SOA {
- domain,
- mname,
- nname,
- serial,
- refresh,
- retry,
- expire,
- minimum,
- ttl,
- })
- }
- QueryType::PTR => {
- let mut pointer = String::new();
- buffer.read_qname(&mut pointer)?;
-
- Ok(Self::PTR {
- domain,
- pointer,
- ttl,
- })
- }
- QueryType::MX => {
- let priority = buffer.read_u16()?;
- let mut mx = String::new();
- buffer.read_qname(&mut mx)?;
-
- Ok(Self::MX {
- domain,
- priority,
- host: mx,
- ttl,
- })
- }
- QueryType::TXT => {
- let mut text = Vec::new();
-
- loop {
- let mut s = String::new();
- buffer.read_string(&mut s)?;
-
- if s.len() == 0 {
- break;
- } else {
- text.push(s);
- }
- }
-
- Ok(Self::TXT { domain, text, ttl })
- }
- QueryType::SRV => {
- let priority = buffer.read_u16()?;
- let weight = buffer.read_u16()?;
- let port = buffer.read_u16()?;
-
- let mut target = String::new();
- buffer.read_qname(&mut target)?;
-
- Ok(Self::SRV {
- domain,
- priority,
- weight,
- port,
- target,
- ttl,
- })
- }
- QueryType::CAA => {
- let flags = buffer.read()?;
- let length = buffer.read()?;
-
- let mut tag = String::new();
- buffer.read_string_n(&mut tag, length)?;
-
- let value_len = (data_len as usize) + header_pos - buffer.pos;
- let mut value = String::new();
- buffer.read_string_n(&mut value, value_len as u8)?;
-
- Ok(Self::CAA {
- domain,
- flags,
- length,
- tag,
- value,
- ttl,
- })
- }
- QueryType::UNKNOWN(_) | _ => {
- buffer.step(data_len as usize)?;
-
- Ok(Self::UNKNOWN {
- domain,
- qtype: qtype_num,
- data_len,
- ttl,
- })
- }
- }
- }
-
- pub fn write(&self, buffer: &mut PacketBuffer) -> Result<usize> {
- let start_pos = buffer.pos();
-
- trace!("Writing DNS Record {:?}", self);
-
- match *self {
- Self::A {
- ref domain,
- ref addr,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::A.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
- buffer.write_u16(4)?;
-
- let octets = addr.octets();
- buffer.write_u8(octets[0])?;
- buffer.write_u8(octets[1])?;
- buffer.write_u8(octets[2])?;
- buffer.write_u8(octets[3])?;
- }
- Self::NS {
- ref domain,
- ref host,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::NS.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
-
- let pos = buffer.pos();
- buffer.write_u16(0)?;
-
- buffer.write_qname(host)?;
-
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16)?;
- }
- Self::CNAME {
- ref domain,
- ref host,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::CNAME.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
-
- let pos = buffer.pos();
- buffer.write_u16(0)?;
-
- buffer.write_qname(host)?;
-
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16)?;
- }
- Self::SOA {
- ref domain,
- ref mname,
- ref nname,
- serial,
- refresh,
- retry,
- expire,
- minimum,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::SOA.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
-
- let pos = buffer.pos();
- buffer.write_u16(0)?;
-
- buffer.write_qname(mname)?;
- buffer.write_qname(nname)?;
- buffer.write_u32(serial)?;
- buffer.write_u32(refresh)?;
- buffer.write_u32(retry)?;
- buffer.write_u32(expire)?;
- buffer.write_u32(minimum)?;
-
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16)?;
- }
- Self::PTR {
- ref domain,
- ref pointer,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::NS.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
-
- let pos = buffer.pos();
- buffer.write_u16(0)?;
-
- buffer.write_qname(&pointer)?;
-
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16)?;
- }
- Self::MX {
- ref domain,
- priority,
- ref host,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::MX.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
-
- let pos = buffer.pos();
- buffer.write_u16(0)?;
-
- buffer.write_u16(priority)?;
- buffer.write_qname(host)?;
-
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16)?;
- }
- Self::TXT {
- ref domain,
- ref text,
- ttl,
- } => {
- buffer.write_qname(&domain)?;
- buffer.write_u16(QueryType::TXT.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
-
- let pos = buffer.pos();
- buffer.write_u16(0)?;
-
- if text.is_empty() {
- return Ok(buffer.pos() - start_pos);
- }
-
- for s in text {
- buffer.write_u8(s.len() as u8)?;
- buffer.write_string(&s)?;
- }
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16)?;
- }
- Self::AAAA {
- ref domain,
- ref addr,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::AAAA.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
- buffer.write_u16(16)?;
-
- for octet in &addr.segments() {
- buffer.write_u16(*octet)?;
- }
- }
- Self::SRV {
- ref domain,
- priority,
- weight,
- port,
- ref target,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::SRV.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
-
- let pos = buffer.pos();
- buffer.write_u16(0)?;
-
- buffer.write_u16(priority)?;
- buffer.write_u16(weight)?;
- buffer.write_u16(port)?;
- buffer.write_qname(target)?;
-
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16)?;
- }
- Self::CAA {
- ref domain,
- flags,
- length,
- ref tag,
- ref value,
- ttl,
- } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::CAA.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
-
- let pos = buffer.pos();
- buffer.write_u16(0)?;
-
- buffer.write_u8(flags)?;
- buffer.write_u8(length)?;
- buffer.write_string(tag)?;
- buffer.write_string(value)?;
-
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16)?;
- }
- Self::AR { ref domain, ttl } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::A.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
- buffer.write_u16(4)?;
-
- let mut rand = rand::thread_rng();
- buffer.write_u32(rand.next_u32())?;
- }
- Self::AAAAR { ref domain, ttl } => {
- buffer.write_qname(domain)?;
- buffer.write_u16(QueryType::A.to_num())?;
- buffer.write_u16(1)?;
- buffer.write_u32(ttl)?;
- buffer.write_u16(4)?;
-
- let mut rand = rand::thread_rng();
- buffer.write_u32(rand.next_u32())?;
- buffer.write_u32(rand.next_u32())?;
- buffer.write_u32(rand.next_u32())?;
- buffer.write_u32(rand.next_u32())?;
- }
- Self::UNKNOWN { .. } => {
- warn!("Skipping record: {self:?}");
- }
- }
-
- Ok(buffer.pos() - start_pos)
- }
-
- pub fn get_domain(&self) -> String {
- self.get_shared_domain().0
- }
-
- pub fn get_qtype(&self) -> QueryType {
- self.get_shared_domain().1
- }
-
- pub fn get_ttl(&self) -> u32 {
- self.get_shared_domain().2
- }
-
- fn get_shared_domain(&self) -> (String, QueryType, u32) {
- match self {
- DnsRecord::UNKNOWN {
- domain, ttl, qtype, ..
- } => (domain.clone(), QueryType::UNKNOWN(*qtype), *ttl),
- DnsRecord::AAAA { domain, ttl, .. } => (domain.clone(), QueryType::AAAA, *ttl),
- DnsRecord::A { domain, ttl, .. } => (domain.clone(), QueryType::A, *ttl),
- DnsRecord::NS { domain, ttl, .. } => (domain.clone(), QueryType::NS, *ttl),
- DnsRecord::CNAME { domain, ttl, .. } => (domain.clone(), QueryType::CNAME, *ttl),
- DnsRecord::SOA { domain, ttl, .. } => (domain.clone(), QueryType::SOA, *ttl),
- DnsRecord::PTR { domain, ttl, .. } => (domain.clone(), QueryType::PTR, *ttl),
- DnsRecord::MX { domain, ttl, .. } => (domain.clone(), QueryType::MX, *ttl),
- DnsRecord::TXT { domain, ttl, .. } => (domain.clone(), QueryType::TXT, *ttl),
- DnsRecord::SRV { domain, ttl, .. } => (domain.clone(), QueryType::SRV, *ttl),
- DnsRecord::CAA { domain, ttl, .. } => (domain.clone(), QueryType::CAA, *ttl),
- DnsRecord::AR { domain, ttl, .. } => (domain.clone(), QueryType::AR, *ttl),
- DnsRecord::AAAAR { domain, ttl, .. } => (domain.clone(), QueryType::AAAAR, *ttl),
- }
- }
-}
diff --git a/src/dns/packet/result.rs b/src/dns/packet/result.rs
deleted file mode 100644
index 41c8ba9..0000000
--- a/src/dns/packet/result.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum ResultCode {
- NOERROR = 0,
- FORMERR = 1,
- SERVFAIL = 2,
- NXDOMAIN = 3,
- NOTIMP = 4,
- REFUSED = 5,
-}
-
-impl ResultCode {
- pub fn from_num(num: u8) -> Self {
- match num {
- 1 => Self::FORMERR,
- 2 => Self::SERVFAIL,
- 3 => Self::NXDOMAIN,
- 4 => Self::NOTIMP,
- 5 => Self::REFUSED,
- 0 | _ => Self::NOERROR,
- }
- }
-}