use crate::records::{BannerHostRecord, BannerScanRecord, DropBox, ScanRecord};
use crate::serializer::deserialize_dropbox;
use crate::tcp_worker::{Grabber, Scnr};
use dns_lookup::lookup_host;
use std::error::Error;
use std::net::{AddrParseError, IpAddr};
use std::str::FromStr;
use tokio::fs::File;
use tokio::io::AsyncReadExt;
pub struct RadioFlyer {}
impl RadioFlyer {
pub async fn string_drop(
addr: &str,
msg: &str,
port: u16,
) -> Result<BannerHostRecord, Box<dyn Error>> {
let host = host_check(addr).await.expect("bad host");
match Grabber::string_grab(host, port, msg, 80).await {
Ok(banner) => {
let host = host.to_string();
let banner_record: BannerHostRecord = BannerHostRecord { host, port, banner };
Ok(banner_record)
}
Err(error) => Err(error),
}
}
pub async fn get_banner(addr: &str, port: u16) -> Result<BannerHostRecord, Box<dyn Error>> {
let host = host_check(addr).await?;
let banner = Grabber::banner_grab(host, port, 80).await?;
let host = host.to_string();
let banner_record: BannerHostRecord = BannerHostRecord { host, port, banner };
Ok(banner_record)
}
pub async fn scan_drop(
addr: &str,
ports: Vec<u16>,
timeout: u64,
) -> Result<ScanRecord, Box<dyn Error>> {
let host = host_check(addr).await?;
let open_ports = Scnr::scan(host, ports, timeout).await?;
let host = host.to_string();
let record = ScanRecord { host, open_ports };
Ok(record)
}
pub async fn scan_drops(
addrs: Vec<&str>,
ports: Vec<u16>,
timeout: u64,
) -> Result<Vec<ScanRecord>, Box<dyn Error>> {
let mut records: Vec<ScanRecord> = vec![];
for addr in addrs {
let host = host_check(addr).await?;
let open_ports = Scnr::scan(host, ports.clone(), timeout).await?;
let host = host.to_string();
let record = ScanRecord { host, open_ports };
records.push(record);
}
Ok(records)
}
pub async fn banner_drop(
addr: &str,
ports: Vec<u16>,
timeout: u64,
) -> Result<BannerScanRecord, Box<dyn Error>> {
let host = host_check(addr).await?;
let banners = Scnr::banner_scan(host, ports, timeout).await?;
let host = host.to_string();
let record = BannerScanRecord { host, banners };
Ok(record)
}
pub async fn banner_drops(
addrs: Vec<&str>,
ports: Vec<u16>,
timeout: u64,
) -> Result<Vec<BannerScanRecord>, Box<dyn Error>> {
let mut records: Vec<BannerScanRecord> = vec![];
for addr in addrs {
let host = host_check(addr).await?;
let banners = Scnr::banner_scan(host, ports.clone(), timeout).await?;
let host = host.to_string();
let record = BannerScanRecord { host, banners };
records.push(record);
}
Ok(records)
}
pub async fn host_drop(addr: &str) -> Result<Vec<String>, Box<dyn Error>> {
let ip_vecs: Vec<IpAddr> = lookup_host(addr).unwrap();
let mut return_array: Vec<String> = vec![];
for ip in ip_vecs {
return_array.push(ip.to_string())
}
Ok(return_array)
}
}
pub struct CommonCarrier {}
impl CommonCarrier {
pub async fn from_file(file_name: &str) -> Result<Vec<ScanRecord>, Box<dyn Error>> {
let mut file = File::open(file_name).await?;
let mut data = String::new();
file.read_to_string(&mut data).await?;
let records = CommonCarrier::from_string(&data).await?;
Ok(records)
}
pub async fn from_string(db_string: &str) -> Result<Vec<ScanRecord>, Box<dyn Error>> {
let dropbox: DropBox = deserialize_dropbox(db_string).await?;
let mut return_vector: Vec<ScanRecord> = vec![];
for mut address in dropbox.addresses {
for i in 0..dropbox.global_ports.len() {
address.ports.push(dropbox.global_ports[i]);
}
address.ports.dedup();
match RadioFlyer::scan_drop(&address.host, address.ports, 60).await {
Ok(record) => return_vector.push(record),
Err(_) => continue,
}
}
Ok(return_vector)
}
}
async fn host_check(addr: &str) -> std::result::Result<IpAddr, AddrParseError> {
match IpAddr::from_str(addr) {
Err(_) => {
let ip_vecs: Vec<IpAddr> = lookup_host(addr).unwrap();
IpAddr::from_str(&ip_vecs[0].to_string())
}
Ok(IpAddr::V4(..)) => IpAddr::from_str(addr),
Ok(IpAddr::V6(..)) => IpAddr::from_str(addr),
}
}