I can't figure out how to get the actual IP v4 address (e. g. 192.168.1.1 or its corresponding packed form as a 32-bit integer) from the Address
field of IP_ADAPTER_UNICAST_ADDRESS_LH structure. I went down the rabbit hole of the linked lists and corresponding MSDN links, but SOCKADDR
is where it cuts off. SOCKADDR
is the generic data holder, it has to be cast to the IPv4 variant in order to obtain a structured view of the data.
Trouble is, I can't find which structure is the IPv4 mapping for SOCKADDR
. Tried in_addr
, getting garbage values.
auto pAddresses = static_cast<IP_ADAPTER_ADDRESSES*>(malloc(defaultBufferSize));
ULONG outBufLen = defaultBufferSize;
constexpr ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
auto result = GetAdaptersAddresses(AF_INET /* Only IP v4 since no cameras use v6 yet */, flags, nullptr, pAddresses, &outBufLen);
uint32_t ipV4Address = 0;
// Iterating over the returned adapter info structures
for (auto currentInterfaceInfo = pAddresses; currentInterfaceInfo != nullptr; currentInterfaceInfo = currentInterfaceInfo->Next)
{
if (currentInterfaceInfo->IfType != IF_TYPE_IEEE80211 || currentInterfaceInfo->Ipv4Enabled != 1 || currentInterfaceInfo->ReceiveOnly != 0)
continue;
if (currentInterfaceInfo->FirstUnicastAddress)
{
for (auto addressInfo = currentInterfaceInfo->FirstUnicastAddress; addressInfo != nullptr; addressInfo = currentInterfaceInfo->FirstUnicastAddress->Next)
{
if (!addressInfo->Address.lpSockaddr || addressInfo->Address.lpSockaddr->sa_family != AF_INET /* IP v4 */)
continue;
auto ipv4AddrInfo = reinterpret_cast<in_addr*>(addressInfo->Address.lpSockaddr);
^^^^????
}
}
}
Given a SOCKADDR*
, look at its sa_family
field to determine the address type.
for an AF_INET
address, typecast the SOCKADDR*
to SOCKADDR_IN*
, and then you can access its sin_addr
field.
for an AF_INET6
address, typecast the SOCKADDR*
to SOCKADDR_IN6*
and then you can access its sin6_addr
field.
std::vector<BYTE> buffer(defaultBufferSize);
auto pAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buffer.data());
ULONG outBufLen = defaultBufferSize;
constexpr ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
auto result = GetAdaptersAddresses(AF_INET /* Only IP v4 since no cameras use v6 yet */, flags, nullptr, pAddresses, &outBufLen);
uint32_t ipV4Address = 0;
// Iterating over the returned adapter info structures
for (auto currentInterfaceInfo = pAddresses; currentInterfaceInfo != nullptr; currentInterfaceInfo = currentInterfaceInfo->Next)
{
if (currentInterfaceInfo->IfType != IF_TYPE_IEEE80211 || currentInterfaceInfo->Ipv4Enabled != 1 || currentInterfaceInfo->ReceiveOnly != 0)
continue;
for (auto addressInfo = currentInterfaceInfo->FirstUnicastAddress; addressInfo != nullptr; addressInfo = addressInfo->Next)
{
if (!addressInfo->Address.lpSockaddr || addressInfo->Address.lpSockaddr->sa_family != AF_INET /* IP v4 */)
continue;
auto ipv4AddrInfo = reinterpret_cast<sockaddr_in*>(addressInfo->Address.lpSockaddr);
// use ipv4AddrInfo->sin_addr as needed...
}
}