diff --git a/src/address.rs b/src/address.rs index 16aa99ecb..0b5aba586 100644 --- a/src/address.rs +++ b/src/address.rs @@ -69,9 +69,18 @@ pub fn parse_addresses(input: &Opts) -> Vec { } } + // Finally, craft a list of addresses to be excluded from the scan. + let mut excluded_ips: Vec = Vec::new(); + if let Some(exclude_addresses) = &input.exclude_addresses { + for addr in exclude_addresses { + excluded_ips.extend(parse_address(addr, &backup_resolver)); + } + } + ips.into_iter() .collect::>() .into_iter() + .filter(|ip| !excluded_ips.contains(ip)) .collect() } @@ -209,6 +218,58 @@ mod tests { ); } + #[test] + fn parse_addresses_with_address_exclusions() { + let mut opts = Opts::default(); + opts.addresses = vec!["192.168.0.0/30".to_owned()]; + opts.exclude_addresses = Some(vec!["192.168.0.1".to_owned()]); + let ips = parse_addresses(&opts); + + assert_eq!( + ips, + [ + Ipv4Addr::new(192, 168, 0, 0), + Ipv4Addr::new(192, 168, 0, 2), + Ipv4Addr::new(192, 168, 0, 3) + ] + ); + } + + #[test] + fn parse_addresses_with_cidr_exclusions() { + let mut opts = Opts::default(); + opts.addresses = vec!["192.168.0.0/29".to_owned()]; + opts.exclude_addresses = Some(vec!["192.168.0.0/30".to_owned()]); + let ips = parse_addresses(&opts); + + assert_eq!( + ips, + [ + Ipv4Addr::new(192, 168, 0, 4), + Ipv4Addr::new(192, 168, 0, 5), + Ipv4Addr::new(192, 168, 0, 6), + Ipv4Addr::new(192, 168, 0, 7), + ] + ); + } + + #[test] + fn parse_addresses_with_incorrect_address_exclusions() { + let mut opts = Opts::default(); + opts.addresses = vec!["192.168.0.0/30".to_owned()]; + opts.exclude_addresses = Some(vec!["192.168.0.1".to_owned(), "im_wrong".to_owned()]); + let ips = parse_addresses(&opts); + + assert_eq!( + ips, + [ + Ipv4Addr::new(192, 168, 0, 0), + Ipv4Addr::new(192, 168, 0, 2), + Ipv4Addr::new(192, 168, 0, 3) + ] + ); + } + #[test] fn parse_correct_host_addresses() { let mut opts = Opts::default(); @@ -235,6 +296,7 @@ mod tests { assert!(ips.is_empty()); } + #[test] fn parse_hosts_file_and_incorrect_hosts() { // Host file contains IP, Hosts, incorrect IPs, incorrect hosts diff --git a/src/input.rs b/src/input.rs index a38752118..58144d819 100644 --- a/src/input.rs +++ b/src/input.rs @@ -151,6 +151,10 @@ pub struct Opts { #[arg(short, long, value_delimiter = ',')] pub exclude_ports: Option>, + /// A list of comma separated CIDRs, IPs, or hosts to be excluded from scanning. + #[arg(short = 'x', long = "exclude-addresses", value_delimiter = ',')] + pub exclude_addresses: Option>, + /// UDP scanning mode, finds UDP ports that send back responses #[arg(long)] pub udp: bool, @@ -217,7 +221,7 @@ impl Opts { self.ports = Some(ports); } - merge_optional!(range, resolver, ulimit, exclude_ports); + merge_optional!(range, resolver, ulimit, exclude_ports, exclude_addresses); } } @@ -241,6 +245,7 @@ impl Default for Opts { scripts: ScriptsRequired::Default, config_path: None, exclude_ports: None, + exclude_addresses: None, udp: false, } } @@ -266,6 +271,7 @@ pub struct Config { command: Option>, scripts: Option, exclude_ports: Option>, + exclude_addresses: Option>, udp: Option, } @@ -340,6 +346,7 @@ mod tests { scan_order: Some(ScanOrder::Random), scripts: None, exclude_ports: None, + exclude_addresses: None, udp: Some(false), } }