97 lines
3.0 KiB
C++
97 lines
3.0 KiB
C++
|
|
extern "C" {
|
|
#include <stdio.h>
|
|
#include <arpa/inet.h>
|
|
}
|
|
|
|
#include <format>
|
|
#include <expected>
|
|
#include <string>
|
|
#include <cmath>
|
|
|
|
#include <networkaux.hpp>
|
|
#include <stringaux.hpp>
|
|
|
|
uint netcapa6(const uint prefix) {
|
|
int hostBits = 128 - prefix;
|
|
int totalIPs = std::pow(2, hostBits);
|
|
return totalIPs;
|
|
}
|
|
|
|
|
|
uint netcapa4(const uint prefix) {
|
|
int hostBits = 32 - prefix;
|
|
int totalIPs = std::pow(2, hostBits);
|
|
return totalIPs;
|
|
}
|
|
|
|
|
|
std::expected<uint, std::string> netprefix(const std::string network) {
|
|
auto hostprefix = split(network, "/");
|
|
if (hostprefix.size() < 2) {
|
|
return std::unexpected("Incorrect network definition");
|
|
}
|
|
auto prefixRes = strtoint(hostprefix[1]);
|
|
if (!prefixRes) {
|
|
return std::unexpected("Incorrect tunnel network prefix:" + prefixRes.error());
|
|
}
|
|
return prefixRes.value();
|
|
}
|
|
|
|
std::expected<std::string, std::string> network(const std::string network) {
|
|
auto hostprefix = split(network, "/");
|
|
if (hostprefix.size() < 2) {
|
|
return std::unexpected("Incorrect network definition");
|
|
}
|
|
return hostprefix[0];
|
|
}
|
|
|
|
|
|
std::expected<std::string, std::string> nethost6(std::string network, uint prefix, uint32_t num) {
|
|
struct in6_addr addr;
|
|
unsigned char mask[16] = {0};
|
|
if (inet_pton(AF_INET6, network.data(), &addr) != 1) {
|
|
return std::unexpected(std::format("Invalid network address {}", network));
|
|
}
|
|
for (uint i = 0; i < prefix; i++) {
|
|
mask[i / 8] |= (1 << (7 - (i % 8)));
|
|
}
|
|
for (int i = 0; i < 16; i++) {
|
|
addr.s6_addr[i] &= mask[i];
|
|
}
|
|
|
|
uint64_t *host_part = (uint64_t *)&addr.s6_addr[8];
|
|
uint64_t hostnum = be64toh(*host_part);
|
|
hostnum += num;
|
|
*host_part = htobe64(hostnum);
|
|
|
|
char buffer[INET6_ADDRSTRLEN] = {'\0'};
|
|
inet_ntop(AF_INET6, &addr, buffer, INET6_ADDRSTRLEN);
|
|
|
|
return std::string(buffer);
|
|
}
|
|
|
|
|
|
std::expected<std::string, std::string> nethost4(std::string network, uint prefix, uint num) {
|
|
struct in_addr inaddr;
|
|
if (inet_pton(AF_INET, network.data(), &inaddr) != 1) {
|
|
return std::unexpected(std::format("Invalid network address {}", network));
|
|
}
|
|
uint32_t ip = ntohl(inaddr.s_addr);
|
|
uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix));
|
|
uint32_t fip = (ip & mask) + num;
|
|
struct in_addr ip_addr;
|
|
ip_addr.s_addr = htonl(fip);
|
|
return std::string(inet_ntoa(ip_addr));
|
|
}
|
|
|
|
std::expected<std::string, std::string> nethost(std::string network, uint prefix, uint num) {
|
|
struct sockaddr_in sa;
|
|
if (inet_pton(AF_INET, network.data(), &(sa.sin_addr)) == 1) {
|
|
return nethost4(network, prefix, num);
|
|
} else if (inet_pton(AF_INET6, network.data(), &(sa.sin_addr)) == 1) {
|
|
return nethost6(network, prefix, num);
|
|
}
|
|
return std::unexpected(std::format("Unknown network address {}", network));
|
|
}
|