extern "C" { #include #include } #include #include #include #include #include std::expected 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 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; }