#include <cstdlib> #include <iomanip> #include <iostream> #include <SFML/Network.hpp> #include <sstream> #include <string> #include <vector> static bool port_is_open(const std::string& address, int port) { return (sf::SocketTCP().connect(address, port) == sf::Socket::Done); } static std::vector<std::string> split(const std::string& string, char delimiter = ' ', bool allow_empty = false) { std::vector<std::string> tokens; std::stringstream sstream(string); std::string token; while (std::getline(sstream, token, delimiter)) { if (allow_empty || token.size() > 0) tokens.push_back(token); } return tokens; } static int string_to_int(const std::string& string) { std::stringstream sstream(string); int i; sstream >> i; return i; } template <typename T> static void swap(T& a, T& b) { T c = a; a = b; b = c; } template <typename T> static std::vector<T> range(T min, T max) { if (min > max) swap(min, max); if (min == max) return std::vector<T>(1, min); std::vector<T> values; for (; min <= max; ++min) values.push_back(min); return values; } static std::vector<int> parse_ports_list(const std::string& list) { std::vector<int> ports; for (const std::string& token : split(list, ',')) { std::vector<std::string> strrange = split(token, '-'); switch (strrange.size()) { case 0: ports.push_back(string_to_int(token)); break; case 1: ports.push_back(string_to_int(strrange[0])); break; case 2: { int min = string_to_int(strrange[0]), max = string_to_int(strrange[1]); for (int port : range(min, max)) ports.push_back(port); break; } default: break; } } return ports; } template <typename T> static T maximum(const std::vector<T>& values) { T max = values[0]; for (T value : values) { if (value > max) max = value; } return max; } template <typename T> static size_t digits(T value) { size_t count = (value < 0) ? 1 : 0; if (value == 0) return 0; while (value) { value /= 10; ++count; }; return count; } int main(int argc, char* argv[]) { std::string address; std::vector<int> ports; if (argc == 3) { address = argv[1]; ports = parse_ports_list(std::string(argv[2])); } else { std::string port_list; std::cout << "Address: " << std::flush; std::getline(std::cin, address); std::cout << "Port: " << std::flush; std::getline(std::cin, port_list); ports = parse_ports_list(port_list); } std::cout << "Showing open ports on " << address << "...\n"; size_t width = digits(maximum(ports)); for (int port : ports) { if (port_is_open(address, port)) std::cout << "Port " << std::setw(width) << port << " : OPEN\n"; } std::cout << std::flush; return 0; }