mirror of
https://github.com/edu4rdshl/unimap.git
synced 2026-07-17 23:24:49 +00:00
(feat): update from old clap definition
This commit is contained in:
parent
f5049e1074
commit
cba63c2a04
7 changed files with 173 additions and 243 deletions
206
src/args.rs
206
src/args.rs
|
|
@ -1,73 +1,167 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{defaults, logic::validate_target, misc::sanitize_target_string},
|
||||||
defaults,
|
|
||||||
logic::validate_target,
|
|
||||||
misc::{return_matches_vec, sanitize_target_string},
|
|
||||||
structs::Args,
|
|
||||||
},
|
|
||||||
chrono::Utc,
|
chrono::Utc,
|
||||||
clap::{load_yaml, value_t, App},
|
clap::Parser,
|
||||||
std::{collections::HashSet, time::Instant},
|
std::{collections::HashSet, time::Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
/// Scan only once by IP address and reduce scan times with Nmap for large amounts of data.
|
||||||
#[must_use]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub fn get_args() -> Args {
|
#[command(author = "Eduard Tolosa <edu4rdshl@protonmail.com>", version, about, long_about = None)]
|
||||||
let yaml = load_yaml!("cli.yml");
|
#[command(arg_required_else_help = true)]
|
||||||
let matches = App::from_yaml(yaml)
|
pub struct Args {
|
||||||
.version(clap::crate_version!())
|
/// Target host
|
||||||
.get_matches();
|
#[arg(short, long, conflicts_with_all = ["files", "stdin"])]
|
||||||
|
pub target: Option<String>,
|
||||||
|
|
||||||
Args {
|
/// Use a list of targets written in a file as input
|
||||||
target: {
|
#[arg(short, long, conflicts_with_all = ["target", "stdin"])]
|
||||||
let target = sanitize_target_string(
|
pub files: Vec<String>,
|
||||||
value_t!(matches, "target", String).unwrap_or_else(|_| String::new()),
|
|
||||||
);
|
/// Write to an output file. The name of the output file will be unimap-log-date
|
||||||
if validate_target(&target) {
|
#[arg(short, long, conflicts_with = "unique_output")]
|
||||||
target
|
pub output: bool,
|
||||||
|
|
||||||
|
/// Write the output in CSV format to the specified filename
|
||||||
|
#[arg(short, long, conflicts_with = "output")]
|
||||||
|
pub unique_output: Option<String>,
|
||||||
|
|
||||||
|
/// Remove informative messages
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub quiet: bool,
|
||||||
|
|
||||||
|
/// Number of threads to use to perform the resolution
|
||||||
|
#[arg(long)]
|
||||||
|
pub threads: Option<usize>,
|
||||||
|
|
||||||
|
/// Path to a file (or files) containing a list of DNS IP address. If no specified then a list of built-in DNS servers is used
|
||||||
|
#[arg(long = "resolvers")]
|
||||||
|
pub custom_resolvers: Vec<String>,
|
||||||
|
|
||||||
|
/// Ports to scan. You can specify a range of ports, a list, or both. Put them inside double quotes, for example: "22, 80, 443, 1000-5000"
|
||||||
|
#[arg(long)]
|
||||||
|
pub ports: Option<String>,
|
||||||
|
|
||||||
|
/// Nmap --min-rate value for ports scan
|
||||||
|
#[arg(long)]
|
||||||
|
pub min_rate: Option<String>,
|
||||||
|
|
||||||
|
/// Use fast scanning for ports (no version detection)
|
||||||
|
#[arg(long)]
|
||||||
|
pub fast_scan: bool,
|
||||||
|
|
||||||
|
/// Path to save the CSV data of the process and/or Nmap XML files. Default to logs/
|
||||||
|
#[arg(long, default_value = "unimap_logs")]
|
||||||
|
pub logs_dir: String,
|
||||||
|
|
||||||
|
/// Keep Nmap XML files created in the logs/ folder for every scanned IP. This data will be useful for other tasks
|
||||||
|
#[arg(short = 'k', long)]
|
||||||
|
pub no_keep_nmap_logs: bool,
|
||||||
|
|
||||||
|
/// Use raw output instead of a table
|
||||||
|
#[arg(short, long, conflicts_with = "url_output")]
|
||||||
|
pub raw_output: bool,
|
||||||
|
|
||||||
|
/// Use HOST:IP output format
|
||||||
|
#[arg(long, conflicts_with = "raw_output")]
|
||||||
|
pub url_output: bool,
|
||||||
|
|
||||||
|
/// Read from stdin instead of files or arguments
|
||||||
|
#[arg(long, conflicts_with_all = ["files", "target"])]
|
||||||
|
pub stdin: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Args {
|
||||||
|
/// Create the processed args with computed fields
|
||||||
|
#[must_use]
|
||||||
|
pub fn into_processed_args(self) -> ProcessedArgs {
|
||||||
|
let target = self.target.map_or_else(String::new, |target| {
|
||||||
|
let sanitized = sanitize_target_string(target);
|
||||||
|
if validate_target(&sanitized) {
|
||||||
|
sanitized
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
file_name: if matches.is_present("output") {
|
|
||||||
value_t!(matches, "logs-dir", String).unwrap_or_else(|_| "unimap_logs".to_string())
|
let file_name = if self.output {
|
||||||
+ "/"
|
format!(
|
||||||
+ "unimap"
|
"{}/unimap{}",
|
||||||
+ &Utc::now().format("-log-%Y-%m-%d_%H-%M-%S").to_string()
|
self.logs_dir,
|
||||||
+ ".csv"
|
Utc::now().format("-log-%Y-%m-%d_%H-%M-%S")
|
||||||
} else if matches.is_present("unique-output") {
|
) + ".csv"
|
||||||
matches.value_of("unique-output").unwrap().to_string()
|
} else if let Some(unique_output) = &self.unique_output {
|
||||||
|
unique_output.clone()
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
},
|
};
|
||||||
logs_dir: value_t!(matches, "logs-dir", String)
|
|
||||||
.unwrap_or_else(|_| "unimap_logs".to_string()),
|
let threads = if self.ports.is_some() && self.threads.is_none() {
|
||||||
threads: if matches.is_present("ports") && !matches.is_present("threads") {
|
|
||||||
30
|
30
|
||||||
} else {
|
} else {
|
||||||
value_t!(matches, "threads", usize).unwrap_or_else(|_| 50)
|
self.threads.unwrap_or(50)
|
||||||
},
|
};
|
||||||
version: clap::crate_version!().to_string(),
|
|
||||||
ports: value_t!(matches, "ports", String).unwrap_or_else(|_| String::new()),
|
let custom_resolvers_flag = !self.custom_resolvers.is_empty();
|
||||||
with_output: matches.is_present("output") || matches.is_present("unique-output"),
|
let custom_ports_range = self.ports.is_some();
|
||||||
unique_output_flag: matches.is_present("unique-output"),
|
let ports_value = self.ports.unwrap_or_default();
|
||||||
from_file_flag: matches.is_present("files"),
|
|
||||||
quiet_flag: matches.is_present("quiet"),
|
let resolvers = if custom_resolvers_flag {
|
||||||
custom_resolvers: matches.is_present("custom-resolvers"),
|
self.custom_resolvers
|
||||||
custom_ports_range: matches.is_present("ports"),
|
|
||||||
fast_scan: matches.is_present("fast-scan"),
|
|
||||||
no_keep_nmap_logs: matches.is_present("no-keep-nmap-logs"),
|
|
||||||
raw_output: matches.is_present("raw-output"),
|
|
||||||
url_output: matches.is_present("url-output"),
|
|
||||||
from_stdin: matches.is_present("stdin"),
|
|
||||||
files: return_matches_vec(&matches, "files"),
|
|
||||||
min_rate: value_t!(matches, "min-rate", String).unwrap_or_else(|_| String::new()),
|
|
||||||
resolvers: if matches.is_present("custom-resolvers") {
|
|
||||||
return_matches_vec(&matches, "custom-resolvers")
|
|
||||||
} else {
|
} else {
|
||||||
defaults::ipv4_resolvers()
|
defaults::ipv4_resolvers()
|
||||||
},
|
};
|
||||||
targets: HashSet::new(),
|
|
||||||
time_wasted: Instant::now(),
|
ProcessedArgs {
|
||||||
|
target,
|
||||||
|
file_name,
|
||||||
|
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||||
|
logs_dir: self.logs_dir,
|
||||||
|
threads,
|
||||||
|
ports: ports_value,
|
||||||
|
with_output: self.output || self.unique_output.is_some(),
|
||||||
|
unique_output_flag: self.unique_output.is_some(),
|
||||||
|
min_rate: self.min_rate.unwrap_or_default(),
|
||||||
|
from_file_flag: !self.files.is_empty(),
|
||||||
|
quiet_flag: self.quiet,
|
||||||
|
custom_resolvers: custom_resolvers_flag,
|
||||||
|
custom_ports_range,
|
||||||
|
no_keep_nmap_logs: self.no_keep_nmap_logs,
|
||||||
|
raw_output: self.raw_output,
|
||||||
|
fast_scan: self.fast_scan,
|
||||||
|
url_output: self.url_output,
|
||||||
|
from_stdin: self.stdin,
|
||||||
|
files: self.files,
|
||||||
|
resolvers,
|
||||||
|
targets: HashSet::new(),
|
||||||
|
time_wasted: Instant::now(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Processed args with computed fields and flags
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ProcessedArgs {
|
||||||
|
pub target: String,
|
||||||
|
pub file_name: String,
|
||||||
|
pub version: String,
|
||||||
|
pub logs_dir: String,
|
||||||
|
pub threads: usize,
|
||||||
|
pub ports: String,
|
||||||
|
pub with_output: bool,
|
||||||
|
pub unique_output_flag: bool,
|
||||||
|
pub min_rate: String,
|
||||||
|
pub from_file_flag: bool,
|
||||||
|
pub quiet_flag: bool,
|
||||||
|
pub custom_resolvers: bool,
|
||||||
|
pub custom_ports_range: bool,
|
||||||
|
pub no_keep_nmap_logs: bool,
|
||||||
|
pub raw_output: bool,
|
||||||
|
pub fast_scan: bool,
|
||||||
|
pub url_output: bool,
|
||||||
|
pub from_stdin: bool,
|
||||||
|
pub files: Vec<String>,
|
||||||
|
pub resolvers: Vec<String>,
|
||||||
|
pub targets: HashSet<String>,
|
||||||
|
pub time_wasted: Instant,
|
||||||
|
}
|
||||||
|
|
|
||||||
113
src/cli.yml
113
src/cli.yml
|
|
@ -1,113 +0,0 @@
|
||||||
name: Unimap
|
|
||||||
author: Eduard Tolosa <edu4rdshl@protonmail.com>
|
|
||||||
settings:
|
|
||||||
- ArgRequiredElseHelp
|
|
||||||
- StrictUtf8
|
|
||||||
about: Scan only once by IP address and reduce scan times with Nmap for large amounts of data.
|
|
||||||
args:
|
|
||||||
- target:
|
|
||||||
short: t
|
|
||||||
long: target
|
|
||||||
help: Target host.
|
|
||||||
takes_value: true
|
|
||||||
multiple: false
|
|
||||||
conflicts_with:
|
|
||||||
- files
|
|
||||||
- stdin
|
|
||||||
|
|
||||||
- files:
|
|
||||||
short: f
|
|
||||||
long: file
|
|
||||||
help: Use a list of targets writen in a file as input.
|
|
||||||
takes_value: true
|
|
||||||
multiple: true
|
|
||||||
conflicts_with:
|
|
||||||
- target
|
|
||||||
- stdin
|
|
||||||
|
|
||||||
- output:
|
|
||||||
short: o
|
|
||||||
long: output
|
|
||||||
help: Write to an output file. The name of the output file will be unimap-log-date.
|
|
||||||
takes_value: false
|
|
||||||
|
|
||||||
- unique-output:
|
|
||||||
short: u
|
|
||||||
long: unique-output
|
|
||||||
help: Write the output in CSV format to the specified filename.
|
|
||||||
takes_value: true
|
|
||||||
multiple: false
|
|
||||||
conflicts_with:
|
|
||||||
- output
|
|
||||||
|
|
||||||
- quiet:
|
|
||||||
short: q
|
|
||||||
long: quiet
|
|
||||||
help: Remove informative messages.
|
|
||||||
takes_value: false
|
|
||||||
|
|
||||||
- threads:
|
|
||||||
help: Number of threads to use to perform the resolution.
|
|
||||||
long: threads
|
|
||||||
takes_value: true
|
|
||||||
|
|
||||||
- custom-resolvers:
|
|
||||||
help: Path to a file (or files) containing a list of DNS IP address. If no specified then 1.6k of built-in valid DNS servers from public-dns.info are used.
|
|
||||||
long: resolvers
|
|
||||||
takes_value: true
|
|
||||||
multiple: true
|
|
||||||
|
|
||||||
- ports:
|
|
||||||
help: 'Ports to scan. You can specify a range of ports, a list, or both. Put them inside double quotes, for example: "22, 80, 443, 1000-5000"'
|
|
||||||
long: ports
|
|
||||||
takes_value: true
|
|
||||||
multiple: false
|
|
||||||
|
|
||||||
- min-rate:
|
|
||||||
help: Nmap --min-rate value for ports scan.
|
|
||||||
long: min-rate
|
|
||||||
takes_value: true
|
|
||||||
|
|
||||||
- fast-scan:
|
|
||||||
help: Use fast scanning for ports (no version detection).
|
|
||||||
long: fast-scan
|
|
||||||
takes_value: false
|
|
||||||
|
|
||||||
- logs-dir:
|
|
||||||
help: Path to save the CSV data of the process and/or Nmap XML files. Default to logs/.
|
|
||||||
long: logs-dir
|
|
||||||
takes_value: true
|
|
||||||
multiple: false
|
|
||||||
|
|
||||||
- no-keep-nmap-logs:
|
|
||||||
help: Keep Nmap XML files created in the logs/ folder for every scanned IP. This data will be useful for other tasks.
|
|
||||||
short: k
|
|
||||||
long: no-keep-nmap-logs
|
|
||||||
takes_value: false
|
|
||||||
multiple: false
|
|
||||||
|
|
||||||
- raw-output:
|
|
||||||
help: Use raw output instead of a table.
|
|
||||||
short: r
|
|
||||||
long: raw-output
|
|
||||||
takes_value: false
|
|
||||||
multiple: false
|
|
||||||
conflicts_with:
|
|
||||||
- url-output
|
|
||||||
|
|
||||||
- url-output:
|
|
||||||
help: Use HOST:IP output format.
|
|
||||||
long: url-output
|
|
||||||
takes_value: false
|
|
||||||
multiple: false
|
|
||||||
conflicts_with:
|
|
||||||
- raw-output
|
|
||||||
|
|
||||||
- stdin:
|
|
||||||
help: Read from stdin instead of files or aguments.
|
|
||||||
long: stdin
|
|
||||||
takes_value: false
|
|
||||||
multiple: false
|
|
||||||
conflicts_with:
|
|
||||||
- files
|
|
||||||
- target
|
|
||||||
15
src/files.rs
15
src/files.rs
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
|
args::ProcessedArgs,
|
||||||
errors::{Result, ResultExt},
|
errors::{Result, ResultExt},
|
||||||
structs::Args,
|
|
||||||
},
|
},
|
||||||
log::error,
|
log::error,
|
||||||
prettytable::Table,
|
prettytable::Table,
|
||||||
|
|
@ -14,14 +14,17 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn return_file_targets(args: &Args, mut files: Vec<String>) -> Vec<String> {
|
pub fn return_file_targets(args: &ProcessedArgs, mut files: Vec<String>) -> Vec<String> {
|
||||||
let mut targets: Vec<String> = Vec::new();
|
let mut targets: Vec<String> = Vec::new();
|
||||||
files.sort();
|
files.sort();
|
||||||
files.dedup();
|
files.dedup();
|
||||||
for f in files {
|
for f in files {
|
||||||
match File::open(&f) {
|
match File::open(&f) {
|
||||||
Ok(file) => {
|
Ok(file) => {
|
||||||
for target in BufReader::new(file).lines().flatten() {
|
for target in BufReader::new(file)
|
||||||
|
.lines()
|
||||||
|
.map_while(std::result::Result::ok)
|
||||||
|
{
|
||||||
targets.push(target);
|
targets.push(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +49,7 @@ pub fn table_to_file(table: &Table, file_name: Option<std::fs::File>) -> Result<
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn return_output_file(args: &Args) -> Option<File> {
|
pub fn return_output_file(args: &ProcessedArgs) -> Option<File> {
|
||||||
if args.file_name.is_empty() || !args.with_output {
|
if args.file_name.is_empty() || !args.with_output {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -67,7 +70,7 @@ pub fn check_full_path(full_path: &str) -> bool {
|
||||||
|| fs::create_dir_all(full_path).is_ok()
|
|| fs::create_dir_all(full_path).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_files(paths: &HashSet<String>) {
|
pub fn delete_files<S: ::std::hash::BuildHasher>(paths: &HashSet<String, S>) {
|
||||||
for file in paths {
|
for file in paths {
|
||||||
if Path::new(&file).exists() {
|
if Path::new(&file).exists() {
|
||||||
match std::fs::remove_file(file) {
|
match std::fs::remove_file(file) {
|
||||||
|
|
@ -78,7 +81,7 @@ pub fn delete_files(paths: &HashSet<String>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn string_to_file(data: String, mut file: File) -> Result<()> {
|
pub fn string_to_file(data: &str, mut file: File) -> Result<()> {
|
||||||
file.write_all(data.as_bytes())?;
|
file.write_all(data.as_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use {
|
use {
|
||||||
|
clap::Parser,
|
||||||
log::{error, Level},
|
log::{error, Level},
|
||||||
std::{collections::HashSet, iter::FromIterator},
|
std::{collections::HashSet, iter::FromIterator},
|
||||||
unimap::{args, errors::Result, files::return_file_targets, logger, misc, resolver_engine},
|
unimap::{args, errors::Result, files::return_file_targets, logger, misc, resolver_engine},
|
||||||
|
|
@ -10,7 +11,9 @@ fn run() -> Result<()> {
|
||||||
} else {
|
} else {
|
||||||
logger::init_with_level(Level::Info).unwrap();
|
logger::init_with_level(Level::Info).unwrap();
|
||||||
}
|
}
|
||||||
let mut arguments = args::get_args();
|
|
||||||
|
let mut arguments = args::Args::parse().into_processed_args();
|
||||||
|
|
||||||
if !arguments.files.is_empty() {
|
if !arguments.files.is_empty() {
|
||||||
arguments.targets =
|
arguments.targets =
|
||||||
HashSet::from_iter(return_file_targets(&arguments, arguments.files.clone()));
|
HashSet::from_iter(return_file_targets(&arguments, arguments.files.clone()));
|
||||||
|
|
|
||||||
25
src/misc.rs
25
src/misc.rs
|
|
@ -12,31 +12,6 @@ pub fn sanitize_target_string(target: String) -> String {
|
||||||
.replace('/', "")
|
.replace('/', "")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn return_matches_vec(matches: &clap::ArgMatches, value: &str) -> Vec<String> {
|
|
||||||
if matches.is_present(value) {
|
|
||||||
matches
|
|
||||||
.values_of(value)
|
|
||||||
.unwrap()
|
|
||||||
.map(str::to_owned)
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn return_matches_hashset(matches: &clap::ArgMatches, value: &str) -> HashSet<String> {
|
|
||||||
if matches.is_present(value) {
|
|
||||||
matches
|
|
||||||
.values_of(value)
|
|
||||||
.unwrap()
|
|
||||||
.map(str::to_owned)
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
HashSet::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_stdin() -> HashSet<String> {
|
pub fn read_stdin() -> HashSet<String> {
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
let mut stdin = io::stdin();
|
let mut stdin = io::stdin();
|
||||||
|
|
|
||||||
21
src/nmap.rs
21
src/nmap.rs
|
|
@ -1,18 +1,8 @@
|
||||||
use {
|
use {
|
||||||
crate::resolver_engine,
|
|
||||||
log::error,
|
log::error,
|
||||||
std::{path::Path, process::Command},
|
std::{net::Ipv4Addr, path::Path, process::Command},
|
||||||
};
|
};
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
static ref NMAP_DNS_RESOLVERS: String = resolver_engine::RESOLVERS
|
|
||||||
.clone()
|
|
||||||
.iter()
|
|
||||||
.map(ToString::to_string)
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Root {
|
pub struct Root {
|
||||||
|
|
@ -114,12 +104,19 @@ pub fn get_nmap_data(
|
||||||
min_rate: &str,
|
min_rate: &str,
|
||||||
ports: &str,
|
ports: &str,
|
||||||
fast_scan: bool,
|
fast_scan: bool,
|
||||||
|
resolvers: &[Ipv4Addr],
|
||||||
) -> Result<Nmaprun, serde_xml_rs::Error> {
|
) -> Result<Nmaprun, serde_xml_rs::Error> {
|
||||||
let min_rate = min_rate.to_string();
|
let min_rate = min_rate.to_string();
|
||||||
|
let nmap_dns_resolvers = resolvers
|
||||||
|
.iter()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(",");
|
||||||
|
|
||||||
let mut nmap_args = vec![
|
let mut nmap_args = vec![
|
||||||
"nmap",
|
"nmap",
|
||||||
"--dns-servers",
|
"--dns-servers",
|
||||||
&NMAP_DNS_RESOLVERS,
|
&nmap_dns_resolvers,
|
||||||
"-Pn",
|
"-Pn",
|
||||||
"-sS",
|
"-sS",
|
||||||
"--open",
|
"--open",
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,4 @@
|
||||||
use {
|
use crate::nmap::Port;
|
||||||
crate::nmap::Port,
|
|
||||||
std::{collections::HashSet, time::Instant},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Args {
|
|
||||||
pub target: String,
|
|
||||||
pub file_name: String,
|
|
||||||
pub version: String,
|
|
||||||
pub logs_dir: String,
|
|
||||||
pub threads: usize,
|
|
||||||
pub ports: String,
|
|
||||||
pub with_output: bool,
|
|
||||||
pub unique_output_flag: bool,
|
|
||||||
pub min_rate: String,
|
|
||||||
pub from_file_flag: bool,
|
|
||||||
pub quiet_flag: bool,
|
|
||||||
pub custom_resolvers: bool,
|
|
||||||
pub custom_ports_range: bool,
|
|
||||||
pub no_keep_nmap_logs: bool,
|
|
||||||
pub raw_output: bool,
|
|
||||||
pub fast_scan: bool,
|
|
||||||
pub url_output: bool,
|
|
||||||
pub from_stdin: bool,
|
|
||||||
pub files: Vec<String>,
|
|
||||||
pub resolvers: Vec<String>,
|
|
||||||
pub targets: HashSet<String>,
|
|
||||||
pub time_wasted: Instant,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct ResolvData {
|
pub struct ResolvData {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue