mcpinger/utils.cpp
2024-05-08 13:27:23 +02:00

64 lines
2.1 KiB
C++

#include "utils.h"
#include <arpa/inet.h>
#include <regex>
#include <unordered_set>
std::vector<std::string> cidrToIps(const std::string &cidr) {
std::vector<std::string> result;
// Buffer to hold the IP address in text form
int ip[4], bits; // Array to hold each byte of the IP, and the bits for subnet mask
// Parse CIDR notation
(void) sscanf(cidr.c_str(), "%d.%d.%d.%d/%d", &ip[0], &ip[1], &ip[2], &ip[3], &bits);
// Convert parsed IP to struct in_addr
struct in_addr ipAddr{};
ipAddr.s_addr = htonl((ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | ip[3]);
// Calculate network address and number of hosts
uint32_t ipNum = ntohl(ipAddr.s_addr);
uint32_t numHosts = (1 << (32 - bits)) - 2; // Host count excludes network and broadcast addresses
uint32_t network = ipNum & (~((1 << (32 - bits)) - 1)); // Network address
for (uint32_t i = 1; i <= numHosts; i++) {
struct in_addr addr{};
addr.s_addr = htonl(network + i);
char ipStr[INET_ADDRSTRLEN];
(void) inet_ntop(AF_INET, &addr, ipStr, INET_ADDRSTRLEN);
(void) result.emplace_back(ipStr);
}
return result;
}
// Utility function to check and expand CIDR or single IP
std::vector<std::string> parseIps(const std::string &input) {
std::vector<std::string> ips;
std::regex cidrPattern(R"(\b\d{1,3}(?:\.\d{1,3}){3}\/\d{1,2}\b)"); // Simple regex for CIDR validation
if (std::regex_match(input, cidrPattern)) {
// It's a CIDR
ips = cidrToIps(input);
} else {
// It's a single IP
ips.push_back(input);
}
return ips;
}
std::string makePathSafe(const std::string& input) {
// Define a set of characters that are not allowed in file names
const std::unordered_set<char> unsafeChars = {
'/', '\\', ':', '*', '?', '"', '<', '>', '|', '.'
};
// Start with the original string
std::string result = input;
// Replace each unsafe character with an underscore
for (char& c : result) {
if (unsafeChars.count(c)) {
c = '_';
}
}
return result;
}