【问题标题】:How to get IPv4 address from SOCKADDR structure?如何从 SOCKADDR 结构中获取 IPv4 地址?
【发布时间】:2019-07-21 13:54:42
【问题描述】:

我不知道如何从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_IN
  • @RbMm:宾果游戏!谢谢你。发布答案?

标签: windows winapi winsock winsock2


【解决方案1】:

给定一个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...
    }
}

【讨论】:

    猜你喜欢
    • 2010-11-19
    • 2010-12-21
    • 2010-11-06
    • 1970-01-01
    • 2017-04-16
    • 2012-04-22
    • 1970-01-01
    • 2012-12-25
    相关资源
    最近更新 更多