GetUnicastIpAddressEntry 函数 (netioapi.h)

GetUnicastIpAddressEntry 函数检索本地计算机上现有单播 IP 地址条目的信息。

语法

IPHLPAPI_DLL_LINKAGE _NETIOAPI_SUCCESS_ NETIOAPI_API GetUnicastIpAddressEntry(
  [in, out] PMIB_UNICASTIPADDRESS_ROW Row
);

参数

[in, out] Row

指向单播 IP 地址条目 MIB_UNICASTIPADDRESS_ROW 结构条目的指针。 成功返回后,将使用现有单播 IP 地址的属性更新此结构。

返回值

如果函数成功,则返回值NO_ERROR。

如果函数失败,则返回值为以下错误代码之一。

返回代码 说明
ERROR_FILE_NOT_FOUND
系统找不到指定的文件。 如果由 Row参数指向的MIB_UNICASTIPADDRESS_ROW的 InterfaceLuidInterfaceIndex 成员指定的网络接口 LUID 或接口索引不是本地计算机上的值,则返回此错误。
ERROR_INVALID_PARAMETER
参数不正确。 如果在 Row 参数中传递 NULL 指针,Row 参数指向MIB_UNICASTIPADDRESS_ROWAddress 成员未设置为有效的单播 IPv4 或 IPv6 地址,或者未指定 Row 参数指向的MIB_UNICASTIPADDRESS_ROWInterfaceLuidInterfaceIndex 成员,则返回此错误。
ERROR_NOT_FOUND
找不到元素。 如果由 Row 参数指向的 MIB_UNICASTIPADDRESS_ROW 结构的 InterfaceLuidInterfaceIndex 成员指定的网络接口与 MIB_UNICASTIPADDRESS_ROW 结构中的 Address 成员中指定的 IP 地址不匹配,则返回此错误。
ERROR_NOT_SUPPORTED
不支持该请求。 如果本地计算机上没有 IPv4 堆栈,并且在 Row 参数指向的 MIB_UNICASTIPADDRESS_ROW 结构的 Address 成员中指定了 IPv4 地址,则返回此错误。 如果本地计算机上没有 IPv6 堆栈,并且 地址成员中 指定了 IPv6 地址,也会返回此错误。
其他
使用 FormatMessage 获取返回错误的消息字符串。

注解

GetUnicastIpAddressEntry 函数在 Windows Vista 及更高版本上定义。

GetUnicastIpAddressEntry 函数通常用于检索要修改的现有MIB_UNICASTIPADDRESS_ROW结构条目。 然后,应用程序可以更改要修改 的MIB_UNICASTIPADDRESS_ROW 条目中的成员,然后调用 SetUnicastIpAddressEntry 函数。

输入时,Row 参数指向的MIB_UNICASTIPADDRESS_ROW结构中的 Address 成员必须初始化为有效的单播 IPv4 或 IPv6 地址。 Address 成员中SOCKADDR_INET结构的si_family成员必须初始化为 AF_INETAF_INET6,并且必须将 SOCKADDR_INET 结构的相关 Ipv4Ipv6 成员设置为有效的单播 IP 地址。 此外,必须初始化指向 Row 参数的 MIB_UNICASTIPADDRESS_ROW 结构中的以下至少一个成员:InterfaceLuidInterfaceIndex

字段按上面列出的顺序使用。 因此,如果指定 了 InterfaceLuid ,则使用此成员来确定接口。 如果没有为 InterfaceLuid 成员设置值, (此成员的值设置为零) ,则接下来使用 InterfaceIndex 成员来确定接口。

调用成功时,GetUnicastIpAddressEntry 在输出中检索单播 IP 地址的其他属性,并填写 Row 参数指向的MIB_UNICASTIPADDRESS_ROW结构。

可以调用 GetUnicastIpAddressTable 函数来枚举本地计算机上的单播 IP 地址条目。

示例

以下示例检索命令行中指定的单播 IP 地址条目,并从检索到 的 MIB_UNICASTIPADDRESS_ROW 结构中输出一些值。


#ifndef UNICODE
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <Windows.h.>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>

// Need to link with Iphlpapi.lib and Ws2_32.lib
#pragma comment (lib, "iphlpapi.lib")
#pragma comment (lib, "Ws2_32.lib")

void PrintUnicastIpAddress(PMIB_UNICASTIPADDRESS_ROW pIpRow);

int __cdecl wmain(int argc, WCHAR **argv)
{

    // Declare and initialize variables

    ULONG Result = 0;
    ULONG ifIndex;

    // default to unspecified address family
    ULONG addressFamily = AF_UNSPEC;

    IN_ADDR Ipv4Addr;
    IN6_ADDR Ipv6Addr;

    MIB_UNICASTIPADDRESS_ROW ipRow = {0};
    
    // Validate the parameters
    if (argc < 4) {
        wprintf(L"usage: %s <AddressFamily> <IPAddress> <InterfaceIndex>\n", argv[0]);
        wprintf(L"   Gets the UnicastIpAddressEntry for an AddressFamily,\n");
        wprintf(L"     Interface Index, and IP address\n");
        wprintf(L"   Examples\n");
        wprintf(L"     Get the IPv4 loopback at interface index=1\n");
        wprintf(L"       %s 4 127.0.0.1 1\n", argv[0]);
        wprintf(L"     Get the IPv6 loopback at interface index=1\n");
        wprintf(L"       %s 6 ::1 1\n", argv[0]);
        exit(1);
    }

    if (_wtoi(argv[1]) == 4) {
        addressFamily = AF_INET;
        if (InetPtonW(addressFamily, argv[2], &Ipv4Addr) != 1) {
            wprintf(L"Unable to parse IPv4 address string: %s\n", argv[3]);
            exit(1);
        }
    } else if (_wtoi(argv[1]) == 6) {
        addressFamily = AF_INET6;
        if (InetPton(addressFamily, argv[2], &Ipv6Addr) != 1) {
            wprintf(L"Unable to parse IPv6 address string: %s\n", argv[3]);
            exit(1);
        }
    }

    ifIndex = _wtoi(argv[3]);

    ipRow.Address.si_family = (ADDRESS_FAMILY) addressFamily;
    ipRow.InterfaceIndex = ifIndex;

    if (addressFamily == AF_INET) {
        ipRow.Address.si_family = AF_INET;
        memcpy(&ipRow.Address.Ipv4.sin_addr, &Ipv4Addr, sizeof (IN_ADDR));
    }
    if (addressFamily == AF_INET6) {
        ipRow.Address.si_family = AF_INET6;
        memcpy(&ipRow.Address.Ipv6.sin6_addr, &Ipv6Addr, sizeof (IN6_ADDR));
    }

    Result = GetUnicastIpAddressEntry(&ipRow);
    if (Result != NO_ERROR) {
        wprintf(L"GetUnicastIpAddressEntry returned error: %lu\n", Result);
        exit(1);
    }
    PrintUnicastIpAddress(&ipRow);
    
    exit(0);
}

void PrintUnicastIpAddress(PMIB_UNICASTIPADDRESS_ROW pipRow)
{

    WCHAR Ipv4String[16] = { 0 };
    WCHAR Ipv6String[46] = { 0 };

    // Print some variables from the rows in the table
    wprintf(L"AddressFamily:\t\t\t ");
    switch (pipRow->Address.si_family) {
    case AF_INET:
        wprintf(L"IPv4\n");
        if (InetNtop(AF_INET, &pipRow->Address.Ipv4.sin_addr, Ipv4String, 16) !=
            NULL)
            wprintf(L"IPv4 Address:\t\t\t %ws\n", Ipv4String);
        break;
    case AF_INET6:
        wprintf(L"IPv6\n");
        if (InetNtop(AF_INET6, &pipRow->Address.Ipv6.sin6_addr, Ipv6String, 46)
            != NULL)
            wprintf(L"IPv6 Address:\t\t\t %s\n", Ipv6String);
        break;
    default:
        wprintf(L"Other: %d\n", pipRow->Address.si_family);
        break;
    }

    wprintf(L"Interface LUID NetLuidIndex:\t %lu\n",
           pipRow->InterfaceLuid.Info.NetLuidIndex);
    wprintf(L"Interface LUID IfType:\t\t ");
    switch (pipRow->InterfaceLuid.Info.IfType) {
    case IF_TYPE_OTHER:
        wprintf(L"Other\n");
        break;
    case IF_TYPE_ETHERNET_CSMACD:
        wprintf(L"Ethernet\n");
        break;
    case IF_TYPE_ISO88025_TOKENRING:
        wprintf(L"Token ring\n");
        break;
    case IF_TYPE_PPP:
        wprintf(L"PPP\n");
        break;
    case IF_TYPE_SOFTWARE_LOOPBACK:
        wprintf(L"Software loopback\n");
        break;
    case IF_TYPE_ATM:
        wprintf(L"ATM\n");
        break;
    case IF_TYPE_IEEE80211:
        wprintf(L"802.11 wireless\n");
        break;
    case IF_TYPE_TUNNEL:
        wprintf(L"Tunnel encapsulation\n");
        break;
    case IF_TYPE_IEEE1394:
        wprintf(L"IEEE 1394 (Firewire)\n");
        break;
    default:
        wprintf(L"Unknown: %d\n", pipRow->InterfaceLuid.Info.IfType);
        break;
    }

    wprintf(L"Interface Index:\t\t %lu\n", pipRow->InterfaceIndex);

    wprintf(L"Prefix Origin:\t\t\t ");
    switch (pipRow->PrefixOrigin) {
    case IpPrefixOriginOther:
        wprintf(L"IpPrefixOriginOther\n");
        break;
    case IpPrefixOriginManual:
        wprintf(L"IpPrefixOriginManual\n");
        break;
    case IpPrefixOriginWellKnown:
        wprintf(L"IpPrefixOriginWellKnown\n");
        break;
    case IpPrefixOriginDhcp:
        wprintf(L"IpPrefixOriginDhcp\n");
        break;
    case IpPrefixOriginRouterAdvertisement:
        wprintf(L"IpPrefixOriginRouterAdvertisement\n");
        break;
    case IpPrefixOriginUnchanged:
        wprintf(L"IpPrefixOriginUnchanged\n");
        break;
    default:
        wprintf(L"Unknown: %d\n", pipRow->PrefixOrigin);
        break;
    }

    wprintf(L"Suffix Origin:\t\t\t ");
    switch (pipRow->SuffixOrigin) {
    case IpSuffixOriginOther:
        wprintf(L"IpSuffixOriginOther\n");
        break;
    case IpSuffixOriginManual:
        wprintf(L"IpSuffixOriginManual\n");
        break;
    case IpSuffixOriginWellKnown:
        wprintf(L"IpSuffixOriginWellKnown\n");
        break;
    case IpSuffixOriginDhcp:
        wprintf(L"IpSuffixOriginDhcp\n");
        break;
    case IpSuffixOriginLinkLayerAddress:
        wprintf(L"IpSuffixOriginLinkLayerAddress\n");
        break;
    case IpSuffixOriginRandom:
        wprintf(L"IpSuffixOriginRandom\n");
        break;
    case IpSuffixOriginUnchanged:
        wprintf(L"IpSuffixOriginUnchanged\n");
        break;
    default:
        wprintf(L"Unknown: %d\n", pipRow->SuffixOrigin);
        break;
    }

    wprintf(L"Valid Lifetime:\t\t\t 0x%x (%u)\n",
           pipRow->ValidLifetime, pipRow->ValidLifetime);

    wprintf(L"Preferred Lifetime:\t\t 0x%x (%u)\n",
           pipRow->PreferredLifetime, pipRow->PreferredLifetime);

    wprintf(L"OnLink PrefixLength:\t\t %lu\n", pipRow->OnLinkPrefixLength);

    wprintf(L"Skip As Source:\t\t\t ");
    if (pipRow->SkipAsSource)
        wprintf(L"Yes\n");
    else
        wprintf(L"No\n");

    wprintf(L"Dad State:\t\t\t ");
    switch (pipRow->DadState) {
    case IpDadStateInvalid:
        wprintf(L"IpDadStateInvalid\n");
        break;
    case IpDadStateTentative:
        wprintf(L"IpDadStateTentative\n");
        break;
    case IpDadStateDuplicate:
        wprintf(L"IpDadStateDuplicate\n");
        break;
    case IpDadStateDeprecated:
        wprintf(L"IpDadStateDeprecated\n");
        break;
    case IpDadStatePreferred:
        wprintf(L"IpDadStatePreferred\n");
        break;
    default:
        wprintf(L"Unknown: %d\n", pipRow->DadState);
        break;
    }

    wprintf(L"\n");
}


要求

要求
最低受支持的客户端 Windows Vista [仅限桌面应用]
最低受支持的服务器 Windows Server 2008 [仅限桌面应用]
目标平台 Windows
标头 netioapi.h (包括 Iphlpapi.h)
Library Iphlpapi.lib
DLL Iphlpapi.dll

另请参阅

CreateUnicastIpAddressEntry

DeleteUnicastIpAddressEntry

GetUnicastIpAddressTable

IP 帮助程序函数参考

InitializeUnicastIpAddressEntry

MIB_UNICASTIPADDRESS_ROW

MIB_UNICASTIPADDRESS_TABLE

NotifyUnicastIpAddressChange

SetUnicastIpAddressEntry