1use clap::Parser;
2
3#[derive(Parser, Debug)]
19#[command(author, version, about, long_about = None)]
20pub struct Args {
21 #[arg(short = 't', long)]
23 pub(crate) target: String,
24 #[arg(short, long, default_value = "none")]
26 pub verbosity: String,
27 #[arg(short = 'n', long, default_value = "4")]
29 pub(crate) threads: usize,
30 #[arg(short = 'p', long, default_value = "1:1024")]
32 pub(crate) port_range: String,
33 #[arg(short = 'm', long, default_value = "100")]
35 pub(crate) timeout: u64,
36 #[arg(long)]
39 pub(crate) probe: bool,
40}
41
42pub(crate) fn parse_ports(port_arg: &str) -> Vec<u16> {
43 let mut ports = Vec::new();
44 for port in port_arg.split(',') {
45 let port = port.trim();
46 if port.contains(':') {
47 let range: Vec<&str> = port.split(':').collect();
48 if range.len() == 2 {
49 let start: u16 = range[0]
50 .parse()
51 .expect("Invalid start port, expected similar to -p 1:1024");
52 let end: u16 = range[1]
53 .parse()
54 .expect("Invalid end port, expected similar to -p 1:1024");
55 for port in start..=end {
56 ports.push(port);
57 }
58 } else {
59 panic!("Invalid port: expected similar to -p 1:1024");
60 }
61 } else {
62 let port: u16 = port.parse().expect(&format!("Invalid port: {}", port));
63 ports.push(port);
64 }
65 }
66
67 ports
68}
69
70#[cfg(test)]
71mod tests {
72 use super::parse_ports;
73 #[test]
74 fn test_parse_ports() {
75 let port_range = "20:25,31,32,45:50";
76 let ports = parse_ports(port_range);
77 assert_eq!(
78 ports,
79 vec![20, 21, 22, 23, 24, 25, 31, 32, 45, 46, 47, 48, 49, 50]
80 );
81 }
82
83 #[test]
84 fn test_parse_ports_list_trimmed() {
85 let port_range = "14, 15, 29";
86 let ports = parse_ports(port_range);
87 assert_eq!(ports, vec![14, 15, 29]);
88 }
89
90 #[test]
91 #[should_panic(expected = "Invalid port:")]
92 fn test_parse_invalid_port_range() {
93 let port_range = "14-15";
94 let _ = parse_ports(port_range);
95 }
96 #[test]
97 #[should_panic(expected = "Invalid port:")]
98 fn test_parse_invalid_port_value() {
99 let port_range = "14, a2";
100 let _ = parse_ports(port_range);
101 }
102}