Files
stvpn/works/iprange.cpp
T
2026-05-07 17:53:17 +02:00

71 lines
2.0 KiB
C++

extern "C" {
#include <stdio.h>
#include <arpa/inet.h>
}
#include <format>
#include <expected>
#include <string>
#include <ostream>
#include <iostream>
std::expected<std::string, std::string> network6(std::string network, int prefix) {
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 (int 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 += 2;
*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> network4(std::string network, int prefix) {
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) + 1;
struct in_addr ip_addr;
ip_addr.s_addr = htonl(ip);
return std::string(inet_ntoa(ip_addr));
}
int main() {
auto net4Res = network4("192.168.1.154", 26);
if (!net4Res) {
std::cerr << net4Res.error() << std::endl;
return 1;
}
std::cout << net4Res.value() << std::endl;
auto net6Res = network6("2001:db8:abcd:1234::0", 64);
if (!net6Res) {
std::cerr << net6Res.error() << std::endl;
return 1;
}
std::cout << net6Res.value() << std::endl;
return 0;
}