184 lines
4.9 KiB
Rust
184 lines
4.9 KiB
Rust
use hickory_resolver::proto::rr::rdata::*;
|
|
use hickory_resolver::Resolver;
|
|
use hickory_resolver::config::*;
|
|
|
|
use core::fmt;
|
|
|
|
use crate::config::Config;
|
|
|
|
// #[derive(Debug)]
|
|
pub struct Domain {
|
|
domain_name: String,
|
|
subdomains: Vec<Domain>,
|
|
a_records: Vec<A>,
|
|
aaaa_records: Vec<AAAA>,
|
|
txt_records: Vec<TXT>,
|
|
mx_records: Vec<MX>,
|
|
ns_records: Vec<NS>,
|
|
soa_records: Vec<SOA>, // Subdomains CAN have there own SOA records if their zones point elsewhere
|
|
resolver: Resolver,
|
|
}
|
|
|
|
impl fmt::Display for Domain {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "Domain name: {}\n", self.domain_name)?;
|
|
write!(f, "DNS Records\n\n")?;
|
|
for rec in &self.a_records {
|
|
write!(f, "A: {}\n", rec)?;
|
|
}
|
|
for rec in &self.aaaa_records {
|
|
write!(f, "AAAA: {}\n", rec)?;
|
|
}
|
|
for rec in &self.mx_records {
|
|
write!(f, "MX: {}\n", rec)?;
|
|
}
|
|
for rec in &self.txt_records {
|
|
write!(f, "TXT: {}\n", rec)?;
|
|
}
|
|
for rec in &self.ns_records {
|
|
write!(f, "NS: {}\n", rec)?;
|
|
}
|
|
for rec in &self.soa_records {
|
|
write!(f, "SOA: {}\n", rec)?;
|
|
}
|
|
write!(f, "\n\nSubdomains:\n\n")?;
|
|
for subdomain in &self.subdomains {
|
|
write!(f, "{}:\n", subdomain.domain_name)?;
|
|
for rec in &subdomain.a_records {
|
|
write!(f, "\tA: {}\n", rec)?;
|
|
}
|
|
}
|
|
write!(f, "\n")
|
|
}
|
|
}
|
|
|
|
impl Domain {
|
|
pub fn new(domain: String) -> Domain {
|
|
Domain {
|
|
domain_name: domain,
|
|
subdomains: vec![],
|
|
a_records: vec![],
|
|
aaaa_records: vec![],
|
|
txt_records: vec![],
|
|
mx_records: vec![],
|
|
ns_records: vec![],
|
|
soa_records: vec![],
|
|
resolver: Resolver::new(ResolverConfig::default(), ResolverOpts::default()).unwrap(),
|
|
}
|
|
}
|
|
|
|
pub fn append_subdomain(&mut self, subdomain: String) {
|
|
let mut new_domain = String::from(subdomain);
|
|
new_domain.push_str(".");
|
|
new_domain.push_str(&self.domain_name);
|
|
let subdomain = Domain::new(new_domain);
|
|
self.subdomains.push(subdomain);
|
|
// println!("Added: {}", new_domain);
|
|
}
|
|
|
|
pub fn apply_config(&mut self, config: &Config) {
|
|
for subdomain in &config.subdomains {
|
|
self.append_subdomain(subdomain.to_string());
|
|
}
|
|
self.append_subdomain(config.wildcard_test.to_string())
|
|
}
|
|
|
|
pub fn lookup_all_records(&mut self) {
|
|
// Lookup A records
|
|
self.lookup_a();
|
|
|
|
// Lookup AAAA records
|
|
self.lookup_aaaa();
|
|
|
|
// Lookup MX records
|
|
self.lookup_mx();
|
|
|
|
// Lookup TXT records
|
|
self.lookup_txt();
|
|
|
|
// Lookup TXT records
|
|
self.lookup_ns();
|
|
|
|
// Lookup TXT records
|
|
self.lookup_soa();
|
|
|
|
// Do subdomains?
|
|
for subdomain in &mut self.subdomains {
|
|
// println!("Looking up subdomain: {}", subdomain.domain_name);
|
|
subdomain.lookup_all_records();
|
|
}
|
|
}
|
|
|
|
fn lookup_a(&mut self) {
|
|
let response = self.resolver.ipv4_lookup(&self.domain_name);
|
|
match response {
|
|
Ok(rec) => {
|
|
for entry in rec {
|
|
self.a_records.push(entry);
|
|
}
|
|
},
|
|
Err(_err) => {},
|
|
}
|
|
}
|
|
|
|
fn lookup_aaaa(&mut self) {
|
|
let response = self.resolver.ipv6_lookup(&self.domain_name);
|
|
match response {
|
|
Ok(rec) => {
|
|
for entry in rec {
|
|
self.aaaa_records.push(entry);
|
|
}
|
|
},
|
|
Err(_err) => {} // Log error
|
|
}
|
|
}
|
|
|
|
fn lookup_mx(&mut self) {
|
|
let response = self.resolver.mx_lookup(&self.domain_name);
|
|
match response {
|
|
Ok(rec) => {
|
|
for entry in rec {
|
|
self.mx_records.push(entry);
|
|
}
|
|
},
|
|
Err(_err) => {},
|
|
}
|
|
}
|
|
|
|
fn lookup_txt(&mut self) {
|
|
let response = self.resolver.txt_lookup(&self.domain_name);
|
|
match response {
|
|
Ok(rec) => {
|
|
for entry in rec {
|
|
self.txt_records.push(entry);
|
|
}
|
|
},
|
|
Err(_err) => {},
|
|
}
|
|
}
|
|
|
|
fn lookup_ns(&mut self) {
|
|
let response = self.resolver.ns_lookup(&self.domain_name);
|
|
match response {
|
|
Ok(rec) => {
|
|
for entry in rec {
|
|
self.ns_records.push(entry);
|
|
}
|
|
},
|
|
Err(_err) => {},
|
|
}
|
|
}
|
|
|
|
fn lookup_soa(&mut self) {
|
|
let response = self.resolver.soa_lookup(&self.domain_name);
|
|
match response {
|
|
Ok(rec) => {
|
|
for entry in rec {
|
|
self.soa_records.push(entry);
|
|
}
|
|
},
|
|
Err(_err) => {},
|
|
}
|
|
}
|
|
}
|