-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rs
111 lines (102 loc) · 3.05 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::env;
use std::io::{self, Write};
use std::net::{IpAddr, TcpStream};
use std::process;
use std::str::FromStr;
use std::sync::mpsc::{channel, Sender};
use std::thread;
const MAX: u16 = 65535;
struct Arguments {
flag: String,
ipaddr: IpAddr,
threads: u16,
}
impl Arguments {
fn new(args: &[String]) -> Result<Arguments, &'static str> {
if args.len() < 2 {
return Err("not enough arguments");
} else if args.len() > 4 {
return Err("too many arguments");
}
let f = args[1].clone();
if let Ok(ipaddr) = IpAddr::from_str(&f) {
return Ok(Arguments {
flag: String::from(""),
ipaddr,
threads: 4,
});
} else {
let flag = args[1].clone();
if flag.contains("-h") || flag.contains("-help") && args.len() == 2 {
println!("Usage: -j to select how many threads you want \r\n -h or --help to show this help message");
return Err("help");
} else if flag.contains("-h") || flag.contains("-help") {
return Err("too many arguments");
} else if flag.contains("-j") {
let ipaddr = match IpAddr::from_str(&args[3]) {
Ok(s) => s,
Err(_) => return Err("not a valid IPADDR; must be IPv4 or IPv6"),
};
let threads = match args[2].parse::<u16>() {
Ok(s) => s,
Err(_) => return Err("failed to parse thread number"),
};
return Ok(Arguments {
threads,
flag,
ipaddr,
});
} else {
return Err("invalid syntax");
}
}
}
}
fn scan(tx: Sender<u16>, start_port: u16, addr: IpAddr, num_threads: u16) {
let mut port: u16 = start_port + 1;
loop {
match TcpStream::connect((addr, port)) {
Ok(_) => {
print!(".");
io::stdout().flush().unwrap();
tx.send(port).unwrap();
}
Err(_) => {}
}
if (MAX - port) <= num_threads {
break;
}
port += num_threads;
}
}
fn main() {
let args: Vec<String> = env::args().collect();
let program = args[0].clone();
let arguments = Arguments::new(&args).unwrap_or_else(|err| {
if err.contains("help") {
process::exit(0);
} else {
eprintln!("{} problem parsing arguments: {}", program, err);
process::exit(0);
}
});
let num_threads = arguments.threads;
let addr = arguments.ipaddr;
let (tx, rx) = channel();
for i in 0..num_threads {
let tx = tx.clone();
thread::spawn(move || {
scan(tx, i, addr, num_threads);
});
}
let mut out = vec![];
drop(tx);
for p in rx {
out.push(p);
}
println!("");
out.sort();
for v in out {
println!("{} is open", v);
}
}