1#include "../include/scanner.hpp"
12#include <sys/socket.h>
17 throw std::invalid_argument{
"IP address is not valid!"};
20 tmpPorts.reserve(ports.size());
21 for (
auto const prt : ports) {
22 if (std::optional port{
parsePort(prt)}) [[likely]]
23 tmpPorts.push_back(*port);
25 throw std::invalid_argument{std::string{prt} +
" is not a valid port!"};
31[[nodiscard]] std::vector<std::pair<port_t, bool>>
Scanner::scan()
const {
32 std::vector<std::pair<port_t, bool>> result{};
34 std::vector<std::thread> threads{};
35 threads.reserve(
m_ports.size());
36 for (
auto const port :
m_ports) {
37 threads.push_back(std::thread{[
this, port, &result]() {
40 result.push_back(std::pair{port, isAccessible});
45 for (
auto &thread : threads)
53 return inet_pton(AF_INET, ip.c_str(), &address) == 1;
58 return inet_pton(AF_INET6, ip.c_str(), &address6) == 1;
63 char const *strEnd{str + std::strlen(str)};
64 std::from_chars_result
const res{std::from_chars(str, strEnd, prt)};
66 if (res.ec not_eq std::errc() or prt < MIN_PORT or prt > MAX_PORT or res.ptr not_eq strEnd)
70 return {
static_cast<port_t>(prt)};
76 hints.ai_family = AF_UNSPEC;
77 hints.ai_socktype = SOCK_STREAM;
79 std::string
const portStr{std::to_string(port)};
80 if (getaddrinfo(
m_ip.c_str(), portStr.c_str(), &hints, &res) not_eq 0 or not res)
83 int const sockfd{socket(res->ai_family, SOCK_STREAM, 0)};
84 if (sockfd == -1) [[unlikely]] {
91 setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout,
sizeof(timeout));
93 int const result{connect(sockfd, res->ai_addr, res->ai_addrlen)};
ports_t m_ports
Target ports.
std::vector< std::pair< port_t, bool > > scan() const
Scans all specified ports on the target IP address.
bool isIPv6(ipaddr_t const &ip) const noexcept
Checks if the given IP address string is a syntactically valid IPv6 address.
std::mutex m_mtx
Mutable mutex for thread safety.
bool isPortAccessible(port_t const port) const
Attempts to establish a TCP connection to the specified port. This function incorporates a timeout (T...
std::optional< port_t > parsePort(char const *str) const noexcept
Attempts to parse a C-string into a port_t. It also validates if the parsed number falls within the [...
bool isIPv4(ipaddr_t const &ip) const noexcept
Checks if the given IP address string is a syntactically valid IPv4 address.
Scanner(ipaddr_t const &ip, std::vector< char const * > const &ports)
Constructs a Scanner with a target IP address and a vector of ports to scan.
ipaddr_t m_ip
Target IP address.
int constexpr TIMEOUT_MS
Timeout in milliseconds for socket connection attempts.
std::vector< port_t > ports_t
Vector of ports type.
uint16_t port_t
Port number type.
std::string ipaddr_t
IP address type.