I\'m currently searching for a portable way of getting the local IP-addresses. Because I\'m using Boost anyway I thought it would be a good idea to use Boost.Asio for this t
Cross platform, but only because of the #ifdef _WIN32 … #else:
boost::asio::ip::address_v6 sinaddr_to_asio(sockaddr_in6 *addr) {
boost::asio::ip::address_v6::bytes_type buf;
memcpy(buf.data(), addr->sin6_addr.s6_addr, sizeof(addr->sin6_addr));
return boost::asio::ip::make_address_v6(buf, addr->sin6_scope_id);
}
#if defined(_WIN32)
#undef UNICODE
#include
// Headers that need to be included after winsock2.h:
#include
#include
typedef IP_ADAPTER_UNICAST_ADDRESS_LH Addr;
typedef IP_ADAPTER_ADDRESSES *AddrList;
std::vector get_local_interfaces() {
// It's a windows machine, we assume it has 512KB free memory
DWORD outBufLen = 1 << 19;
AddrList ifaddrs = (AddrList) new char[outBufLen];
std::vector res;
ULONG err = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER, NULL, ifaddrs,
&outBufLen);
if (err == NO_ERROR) {
for (AddrList addr = ifaddrs; addr != 0; addr = addr->Next) {
if (addr->OperStatus != IfOperStatusUp) continue;
// if (addr->NoMulticast) continue;
// Find the first IPv4 address
if (addr->Ipv4Enabled) {
for (Addr *uaddr = addr->FirstUnicastAddress; uaddr != 0; uaddr = uaddr->Next) {
if (uaddr->Address.lpSockaddr->sa_family != AF_INET) continue;
res.push_back(boost::asio::ip::make_address_v4(ntohl(reinterpret_cast(addr->ifa_addr)->sin_addr.s_addr)));
}
}
if (addr->Ipv6Enabled) {
for (Addr *uaddr = addr->FirstUnicastAddress; uaddr != 0; uaddr = uaddr->Next) {
if (uaddr->Address.lpSockaddr->sa_family != AF_INET6) continue;
res.push_back(sinaddr_to_asio(reinterpret_cast(addr->ifa_addr)));
}
}
}
} else {
}
delete[]((char *)ifaddrs);
return res;
}
#elif defined(__APPLE__) || defined(__linux__)
#include
#include
#include
#include
std::vector get_local_interfaces() {
std::vector res;
ifaddrs *ifs;
if (getifaddrs(&ifs)) {
return res;
}
for (auto addr = ifs; addr != nullptr; addr = addr->ifa_next) {
// No address? Skip.
if (addr->ifa_addr == nullptr) continue;
// Interface isn't active? Skip.
if (!(addr->ifa_flags & IFF_UP)) continue;
if(addr->ifa_addr->sa_family == AF_INET) {
res.push_back(boost::asio::ip::make_address_v4(ntohl(
reinterpret_cast(addr->ifa_addr)->sin_addr.s_addr)));
} else if(addr->ifa_addr->sa_family == AF_INET6) {
res.push_back(sinaddr_to_asio(reinterpret_cast(addr->ifa_addr)));
} else continue;
}
freeifaddrs(ifs);
return res;
}
#else
#error "..."
#endif