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
}