extern "C" { #include #include #include #include #include #include #include #include #include #include } #define BUFSIZE 8192 #include #include #include #include #include std::expected Router::AddRoute(std::string address, uint64_t prefix, std::string gateway) { struct sockaddr_in sa; if (inet_pton(AF_INET, address.data(), &(sa.sin_addr)) == 1) { } else { return std::unexpected(std::format("Incorrect address {}", address)); } struct rtentry rt; memset(&rt, 0, sizeof(rt)); struct sockaddr_in *sin; sin = (struct sockaddr_in*)&rt.rt_dst; sin->sin_family = AF_INET; if (inet_pton(AF_INET, address.data(), &sin->sin_addr) != 1) { int errnoCopy = errno; std::string error = std::strerror(errnoCopy); return std::unexpected(std::format("Incorrect address {}, error: {}", address, error)); }; sin = (struct sockaddr_in*) &rt.rt_gateway; sin->sin_family = AF_INET; if (inet_pton(AF_INET, gateway.data(), &sin->sin_addr) != 1) { int errnoCopy = errno; std::string error = std::strerror(errnoCopy); return std::unexpected(std::format("Incorrect address {}, error: {}", gateway, error)); }; char buffer[INET_ADDRSTRLEN]; uint32_t mask = (prefix == 0) ? 0 : htonl(~((1U << (32 - prefix)) - 1)); //uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix)); struct in_addr addr; addr.s_addr = mask; const char *dottedmask; if ((dottedmask = inet_ntop(AF_INET, &addr, buffer, INET_ADDRSTRLEN)) == NULL) { int errnoCopy = errno; std::string error = std::strerror(errnoCopy); return std::unexpected(std::format("Incorrect prefix {}, error: {}", prefix, error)); }; sin = (struct sockaddr_in*) &rt.rt_genmask; sin->sin_family = AF_INET; if (inet_pton(AF_INET, dottedmask, &sin->sin_addr) != 1) { int errnoCopy = errno; std::string error = std::strerror(errnoCopy); return std::unexpected(std::format("Incorrect address {}, error: {}", gateway, error)); }; rt.rt_flags = RTF_UP | RTF_GATEWAY; //rt.rt_dev = std::string("eth0").data(); int sockfd = 0; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { int errnoCopy = errno; std::string error = std::strerror(errnoCopy); return std::unexpected(std::format("Error: {}", error)); } if (ioctl(sockfd, SIOCADDRT, &rt) < 0) { close(sockfd); int errnoCopy = errno; std::string error = std::strerror(errnoCopy); return std::unexpected(std::format("Cannot set route, error: {}", error)); } close(sockfd); return {}; }