ports_scanner/
lib.rs

1use std::collections::HashMap;
2use std::net::{Shutdown, TcpStream};
3
4use anyhow::Result;
5use ipnet::IpNet;
6use lazy_static::lazy_static;
7
8lazy_static! {
9    /// Source: https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
10    pub static ref PORTS: HashMap<u16, &'static str> = {
11        let mut m = HashMap::new();
12        m.insert(20, "ftp data");
13        m.insert(21, "ftp control");
14        m.insert(22, "secure shell (ssh)");
15        m.insert(23, "Telnet");
16        m.insert(25, "Simple Mail Transfer Protocol (SMTP)");
17        m.insert(43, "whois");
18        m.insert(53, "Domain Name System (DNS)");
19        m.insert(
20            67,
21            "Bootstrap Protocol (BOOTP) or Dynamic Host Configuration Protocol (DHCP)",
22        );
23        m.insert(
24            68,
25            "Bootstrap Protocol (BOOTP) or Dynamic Host Configuration Protocol (DHCP)",
26        );
27        m.insert(69, "Trivial File Transfer Protocol (TFTP)");
28        m.insert(70, "Gopher");
29        m.insert(79, "Finger");
30        m.insert(80, "http");
31        m.insert(88, "Kerberos authentication system");
32        m.insert(109, "Post Office Protocol (POP) version 2");
33        m.insert(110, "Post Office Protocol (POP) version 3");
34        m.insert(113, "Ident/Authentication protocol");
35        m.insert(115, "Simple File Transfer Protocol (SMTP)");
36        m.insert(119, "Network News Transfer Protocol (NNTP)");
37        m.insert(123, "Network Time Protocol (NTP)");
38        m.insert(137, "NetBIOS Name Service");
39        m.insert(138, "NetBIOS Datagram Service");
40        m.insert(139, "NetBIOS Session Service");
41        m.insert(143, "Internet Message Access Protocol (IMAP)");
42        m.insert(161, "Simple Network Management Protocol (SNMP)");
43        m.insert(162, "Simple Network Management Protocol (SNMP) Trap Service (SNMPTRAP)");
44        m.insert(177, "X Display Manager Control Protocol (XDMCP)");
45        m.insert(179, "Border Gateway Protocol (BGP)");
46        m.insert(194, "Internet Relay Chat (IRC)");
47        m.insert(389, "Lightweight Directory Access Protocol (LDAP)");
48        m.insert(443, "https");
49        m.insert(445, "Microsoft-DS Directory Services/SAMBA (SMB)");
50        m.insert(456, "Simple File Transfer Protocol (SMTP) over SSL");
51        m.insert(510, "FirstClass Unified Communications");
52        m.insert(514, "Remote Shell or syslog");
53        m.insert(546, "Dynamic Host Configuration Protocol (DHCP) IPv6 (DHCPv6) client");
54        m.insert(547, "Dynamic Host Configuration Protocol (DHCP) IPv6 (DHCPv6) server");
55        m.insert(548, "Apple Filing Protocol (AFP) over TCP");
56        m.insert(631, "Internet Printing Protocol (IPP), Common Unix Printing System (CUPS) admin console");
57        m.insert(636, "LDAP over SSL (LDAPS)");
58        m.insert(666, "DOOM");
59        m.insert(853, "DNS over TLS");
60        m.insert(873, "rsync");
61        m.insert(989, "FTP data over TLS");
62        m.insert(990, "FTP control over TLS");
63        m.insert(992, "Telnet over TLS");
64        m.insert(993, "Internet Message Access Protocol (IMAP) over TLS (IMAPS)");
65        m.insert(995, "Post Office Protocol (POP) version 3 over TLS");
66        m
67    };
68}
69
70pub fn scan(host: &str) -> Result<bool> {
71    let stream = match TcpStream::connect(host) {
72        Ok(s) => s,
73        Err(_) => {
74            return Ok(false);
75        }
76    };
77    stream.shutdown(Shutdown::Both).unwrap_or_default();
78    Ok(true)
79}
80
81pub fn scan_range(range: IpNet) -> Result<Vec<String>> {
82    let mut found = vec![];
83
84    for ip in range.hosts() {
85        for port in 1..65535u16 {
86            let host = format!("{ip}:{port}");
87            if scan(&host)? {
88                found.push(host);
89            }
90        }
91    }
92
93    Ok(found)
94}