如何从 SOCKADDR 结构中获取 IPv4 地址?
How to get IPv4 address from SOCKADDR structure?
我不知道如何从 IP_ADAPTER_UNICAST_ADDRESS_LH 的 Address
字段中获取实际的 IP v4 地址(例如 192.168.1.1 或其对应的 32 位整数压缩形式)结构体。我进入了链接列表和相应的 MSDN 链接的兔子洞,但 SOCKADDR
是它切断的地方。 SOCKADDR
是通用数据持有者,必须将其转换为 IPv4 变体才能获得数据的结构化视图。
问题是,我找不到哪个结构是 SOCKADDR
的 IPv4 映射。已尝试 in_addr
,获取垃圾值。
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);
^^^^????
}
}
}
给定一个 SOCKADDR*
,查看其 sa_family
字段以确定地址类型。
对于 AF_INET
地址,将 SOCKADDR*
类型转换为 SOCKADDR_IN*
,然后您可以访问其 sin_addr
字段。
对于 AF_INET6
地址,将 SOCKADDR*
类型转换为 SOCKADDR_IN6*
然后您可以访问它的 sin6_addr
字段。
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...
}
}
我不知道如何从 IP_ADAPTER_UNICAST_ADDRESS_LH 的 Address
字段中获取实际的 IP v4 地址(例如 192.168.1.1 或其对应的 32 位整数压缩形式)结构体。我进入了链接列表和相应的 MSDN 链接的兔子洞,但 SOCKADDR
是它切断的地方。 SOCKADDR
是通用数据持有者,必须将其转换为 IPv4 变体才能获得数据的结构化视图。
问题是,我找不到哪个结构是 SOCKADDR
的 IPv4 映射。已尝试 in_addr
,获取垃圾值。
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);
^^^^????
}
}
}
给定一个 SOCKADDR*
,查看其 sa_family
字段以确定地址类型。
对于
AF_INET
地址,将SOCKADDR*
类型转换为SOCKADDR_IN*
,然后您可以访问其sin_addr
字段。对于
AF_INET6
地址,将SOCKADDR*
类型转换为SOCKADDR_IN6*
然后您可以访问它的sin6_addr
字段。
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...
}
}