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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
use std::net::{SocketAddr, TcpListener, TcpStream, ToSocketAddrs};
use std::ops::Range;
/// Scan a port and return true if it's open.
///
/// # Example
/// ```no_run
/// use port_scanner::scan_port;
/// println!("Port 8000 open? {}", scan_port(8000));
/// ```
pub fn scan_port(port: u16) -> bool {
match TcpStream::connect(("0.0.0.0", port)) {
Ok(_) => true,
Err(_) => false,
}
}
/// Scan port of an address and return true if it's open.
///
/// # Example
/// ```no_run
/// use port_scanner::scan_port_addr;
/// println!("IP 192.168.1.1 has port 8000 open? {}", scan_port_addr("192.168.1.1:8000"));
/// ```
pub fn scan_port_addr<A: ToSocketAddrs>(addr: A) -> bool {
match TcpStream::connect(addr) {
Ok(_) => true,
Err(_) => false,
}
}
/// Scan specified ports and return a list of all open ports.
///
/// # Example
/// ```no_run
/// use port_scanner::scan_ports;
/// for open_port in scan_ports(vec![8000, 9000, 8888]) {
/// println!("Port {} is open", open_port);
/// }
/// ```
pub fn scan_ports(ports: Vec<u16>) -> Vec<u16> {
let mut open_ports = Vec::new();
for port in ports {
if scan_port(port) {
open_ports.push(port);
}
}
open_ports
}
/// Scan specified ports of addresses and return a list of all addresses with open ports.
///
/// # Example
/// ```no_run
/// use port_scanner::scan_ports_addrs;
/// for open_addr in scan_ports_addrs(vec!["192.168.1.1:8000", "192.168.1.2:8000"]) {
/// println!("IP {} has port {} open.", open_addr.ip(), open_addr.port());
/// }
/// ```
pub fn scan_ports_addrs<A: ToSocketAddrs>(addrs: Vec<A>) -> Vec<SocketAddr> {
let mut open_addrs = Vec::new();
for addr in addrs {
if scan_port_addr(&addr) {
let addr = addr.to_socket_addrs().unwrap().next().unwrap();
open_addrs.push(addr);
}
}
open_addrs
}
/// Scan a port range and return a list of all open ports.
///
/// # Example
/// ```no_run
/// use port_scanner::scan_ports_range;
/// for open_port in scan_ports_range(8000..9000) {
/// println!("Port {} is open", open_port);
/// }
/// ```
pub fn scan_ports_range(port_range: Range<u16>) -> Vec<u16> {
let mut open_ports = Vec::new();
for port in port_range {
if scan_port(port) {
open_ports.push(port);
}
}
open_ports
}
/// Request to the os the next open port.
///
/// # Example
/// ```no_run
/// use port_scanner::request_open_port;
/// println!("Port {}", request_open_port().unwrap_or(0));
/// ```
pub fn request_open_port() -> Option<u16> {
match TcpListener::bind("0.0.0.0:0") {
Ok(a) => {
match a.local_addr() {
Ok(a) => Some(a.port()),
Err(_) => None,
}
}
Err(_) => None,
}
}
/// Check if the local port is available.
///
/// # Example
/// ```no_run
/// use port_scanner::local_port_available;
/// println!("Is port 80 available to use? {}", local_port_available(80));
/// ```
pub fn local_port_available(port: u16) -> bool {
match TcpListener::bind(("127.0.0.1", port)) {
Ok(_) => true,
Err(_) => false,
}
}
/// Check if the local ports are available.
///
/// # Example
/// ```no_run
/// use port_scanner::local_ports_available;
/// for available in local_ports_available(vec![80, 81]) {
/// println!("Port {} is available to use", available);
/// }
/// ```
pub fn local_ports_available(ports: Vec<u16>) -> Vec<u16> {
let mut available = Vec::new();
for port in ports {
if local_port_available(port) {
available.push(port);
}
}
available
}
/// Check if the local ports are available.
///
/// # Example
/// ```no_run
/// use port_scanner::local_ports_available_range;
/// for available in local_ports_available_range(1..80) {
/// println!("Port {} is available to use", available);
/// }
/// ```
pub fn local_ports_available_range(port_range: Range<u16>) -> Vec<u16> {
let mut available = Vec::new();
for port in port_range {
if local_port_available(port) {
available.push(port);
}
}
available
}