diff --git a/src/domain.rs b/src/domain.rs new file mode 100644 index 0000000..45fec5d --- /dev/null +++ b/src/domain.rs @@ -0,0 +1,174 @@ +use hickory_resolver::proto::rr::rdata::*; +use hickory_resolver::Resolver; +use hickory_resolver::config::*; + +use core::fmt; + +// #[derive(Debug)] +pub struct Domain { + domain_name: String, + subdomains: Vec, + a_records: Vec, + aaaa_records: Vec, + txt_records: Vec, + mx_records: Vec, + ns_records: Vec, + soa_records: Vec, // 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 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) => {}, + } + } +} diff --git a/src/main.rs b/src/main.rs index 9e596a3..18f8019 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,181 +1,8 @@ -use hickory_resolver::proto::rr::rdata::*; -use hickory_resolver::Resolver; -use hickory_resolver::config::*; - -use core::fmt; - -// #[derive(Debug)] -struct Domain { - domain_name: String, - subdomains: Vec, - a_records: Vec, - aaaa_records: Vec, - txt_records: Vec, - mx_records: Vec, - ns_records: Vec, - soa_records: Vec, // 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")?; - for subdomain in &self.subdomains { - write!(f, "{}\n", subdomain.domain_name)?; - for rec in &subdomain.a_records { - write!(f, "A: {}\n", rec)?; - } - } - write!(f, "\n") - } -} - -impl Domain { - 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(), - } - } - - 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); - } - - 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) => {}, - } - } -} - +mod domain; +use crate::domain::Domain; fn main() { - let mut test = Domain::new("swin.edu.au.".to_string()); + let mut test = Domain::new("pigandpilgrim.com.au".to_string()); test.append_subdomain("www".to_string()); test.append_subdomain("mail".to_string()); test.append_subdomain("ftp".to_string());