#include "network.hpp" #include #include #include #include namespace drp::util::network { bool is_localhost(const sockaddr_storage& address, const socklen_t addressLength) { // iterate through all the interfaces ifaddrs* interfaces; if (getifaddrs(&interfaces) == -1) throw std::runtime_error("Could not get network interfaces."); bool result = false; for (const ifaddrs *interface = interfaces; interface; interface = interface->ifa_next) { // if the interface family does not correspond to the server candidate, ignore it if (interface->ifa_addr->sa_family != address.ss_family) continue; switch (address.ss_family) { case AF_INET: { const auto interfaceIpv4 = reinterpret_cast(interface->ifa_addr); const auto addressIpv4 = reinterpret_cast(&address); // the family have already been checked. if (std::memcmp(&interfaceIpv4->sin_addr, &addressIpv4->sin_addr, sizeof(in_addr)) == 0) result = true; break; } case AF_INET6: { const auto interfaceIpv6 = reinterpret_cast(interface->ifa_addr); const auto addressIpv6 = reinterpret_cast(&address); // the interface and the family have already been checked. if (std::memcmp(&interfaceIpv6->sin6_addr, &addressIpv6->sin6_addr, sizeof(in6_addr)) == 0) result = true; break; } default: throw std::runtime_error("Unknown address family."); } if (result == true) break; } freeifaddrs(interfaces); return result; } }