共用方式為


SendARP 函式 (iphlpapi.h)

SendARP 函式會傳送位址解析通訊協定 (ARP) 要求,以取得對應至指定目的地 IPv4 位址的實體位址。

語法

IPHLPAPI_DLL_LINKAGE DWORD SendARP(
  [in]      IPAddr DestIP,
  [in]      IPAddr SrcIP,
  [out]     PVOID  pMacAddr,
  [in, out] PULONG PhyAddrLen
);

參數

[in] DestIP

目的地 IPv4 位址,格式為 IPAddr 結構。 ARP 要求會嘗試取得對應至此 IPv4 位址的實體位址。

[in] SrcIP

寄件者的來源 IPv4 位址,格式為 IPAddr 結構。 此參數是選擇性的,可用來選取介面以傳送ARP專案的要求。 呼叫端可以指定與此參數 INADDR_ANY IPv4 位址對應的零。

[out] pMacAddr

ULONG 變數陣列的指標。 此陣列至少必須有兩個 ULONG 元素,才能保存乙太網路或令牌通道實體位址。 這個陣列的前六個字節會收到對應至 DestIP 參數所指定IPv4位址的實體位址。

[in, out] PhyAddrLen

在輸入時, ULONG 值的指標會指定緩衝區大小上限,以位元組為單位,應用程式已設定為接收實體位址或 MAC 位址。 乙太網路或令牌通道實體位址的緩衝區大小至少應為6個字節

接收實體地址的緩衝區是由 pMacAddr 參數所指向。

在成功輸出時,此參數會指向值,指定寫入 pMacAddr 所指向之緩衝區的位元元組數目。

傳回值

如果函式成功,傳回值會NO_ERROR。

如果函式失敗,傳回值就是下列其中一個錯誤碼。

傳回碼 Description
ERROR_BAD_NET_NAME
找不到網路名稱。 當 ARP 回復 SendARP 要求未收到時,Windows Vista 和更新版本會傳回此錯誤。 如果無法連線到目的地 IPv4 位址,因為目的地 IPv4 位址不在相同的子網上,或目的地電腦未運作,就會發生此錯誤。
ERROR_BUFFER_OVERFLOW
檔案名稱太長。 如果 PhyAddrLen 參數指向的 ULONG 值小於 6,則 Windows Vista 會傳回此錯誤,這是儲存完整實體位址所需的大小。
ERROR_GEN_FAILURE
連接至系統的裝置無法運作。 未收到 ARP 回復 SendARP 要求時,Windows Server 2003 和更早版本會傳回此錯誤。 如果無法連線到目的地 IPv4 位址,因為目的地 IPv4 位址不在相同子網上,或目的地電腦未運作,就會發生此錯誤。
ERROR_INVALID_PARAMETER
其中一個參數無效。 如果 pMacAddrPhyAddrLen 參數是 NULL 指標,則會在 Windows Server 2003 和更早版本上傳回 此錯誤
ERROR_INVALID_USER_BUFFER
提供的用戶緩衝區對要求的作業無效。 如果 PhyAddrLen 參數指向的 ULONG 值為零,則會在 Windows Server 2003 和更早版本上傳回此錯誤。
ERROR_NOT_FOUND
Element not found. 如果 SrcIp 參數未在本機電腦上的介面上指定來源 IPv4 位址,或 INADDR_ANY IP 位址 (IPv4 位址為 0.0.0.0.0) ,則會在 Windows Vista 上傳回此錯誤。
ERROR_NOT_SUPPORTED
本機電腦上執行的作業系統不支援 SendARP 函式。
其他
如果函式失敗,請使用 FormatMessage 取得傳回錯誤的訊息字串。

備註

SendARP 函式可用來要求實體硬體位址 (有時稱為對應至指定目的地 IPv4 位址的 MAC 位址) 。 如果所要求的資訊不在本機計算機的ARP數據表中, 則SendARP 函式會導致傳送ARP要求以取得實體位址。 如果函式成功,則會在 pMacAddr 參數指向的數位中傳回對應至指定目的地 IPv4 位址的實體位址。

只有在目的地 IPv4 位址位於本機子網上,才能使用 IPv4 位址的實體位址, (可以直接連線 IPv4 位址,而不需通過任何路由器) 。 如果目的地 IPv4 位址不在本機子網上, SendARP 函式將會失敗。

如果 Windows Vista 和更新版本上的 SendARP 函式成功,本機電腦上的 ARP 數據表會隨著結果更新。 如果 Windows Server 2003 和更早版本上的 SendARP 函式成功,本機電腦上的 ARP 數據表不會受到影響。

Windows Vista 和更新版本的 SendARP 函式會傳回與 Windows Server 2003 和更早版本 SendARP 函式不同的錯誤傳回值。

在 Windows Vista 和更新版本上,以 pMacAddrPhyAddrLen 參數的形式傳遞至 SendARP 函式的 NULL 指標會導致存取違規,並終止應用程式。 如果 Windows Vista 和更新版本和ERROR_BAD_NET_NAMEERROR_BUFFER_OVERFLOWERROR_NOT_FOUND發生錯誤,PhyAddrLen 參數所指向的 ULONG 值會設定為零。 如果 Windows Vista 和更新版本上 PhyAddrLen 參數指向的 ULONG 值小於 6,SendARP 函式會傳回ERROR_BUFFER_OVERFLOW指出接收實體地址的緩衝區太小。 如果 SrcIp 參數指定 IPv4 位址不是本機電腦上的介面,Windows Vista 和更新版本的 SendARP 函式會傳回 ERROR_NOT_FOUND

在 Windows Server 2003 和更早版本上,當做 pMacAddrPhyAddrLen 參數傳遞至 SendARP 函式的 NULL 指標會傳回ERROR_INVALID_PARAMETER。 如果在 Windows Server 2003 和更早版本發生錯誤,而且會傳回ERROR_GEN_FAILUREERROR_INVALID_USER_BUFFER,PhyAddrLen 參數所指向的 ULONG 值會設定為零。 如果 PhyAddrLen 參數指向的 ULONG 值在 Windows Server 2003 和更早版本小於 6,SendARP 函式不會傳回錯誤,但只會傳回 pMacAddr 參數所指向數位中硬體位址的一部分。 因此,如果 PhyAddrLen 參數所指向的值是 4,則 pMacAddr 參數所指向的陣列中只會傳回前 4 個字節的硬體位址。 如果 SrcIp 參數指定的 IPv4 位址不是本機電腦上的介面,Windows Server 2003 和更早版本的 SendARP 函式會忽略 SrcIp 參數,並在本機電腦上針對來源 IPv4 位址使用 IPv4 位址。

GetIpNetTable 函式會擷取本機電腦上的ARP資料表,以將IPv4位址對應至實體位址。

CreateIpNetEntry 函式會在本機電腦的 ARP 數據表中建立 ARP 專案。

DeleteIpNetEntry 函式會從本機電腦上的 ARP 資料表中刪除 ARP 專案。

SetIpNetEntry 函式會修改本機電腦上 ARP 數據表中的現有 ARP 專案。

FlushIpNetTable 函式會從本機電腦上的 ARP 數據表中刪除指定介面的所有 ARP 專案。

在 Windows Vista 和更新版本上, ResolveIpNetEntry2 函式可用來取代 SendARP 函式。 如果傳遞至 ResolveIpNetEntry2 函式之MIB_IPNET_ROW2結構的 Address 成員是 IPv4 位址,就會傳送 ARP 要求。

在 Windows Vista 上,當傳遞至這些函式之 MIB_IPNET_ROW2 結構的 Address 成員是 IPv4 位址時,可以使用新的函式群組來存取、修改和刪除 ARP 數據表專案。 新的函式包括: GetIpNetTable2CreateIpNetEntry2DeleteIpNetEntry2FlushIpNetTable2SetIpNetEntry2

如需 IPAddr 資料類型的相關信息,請參閱 Windows 資料類型。 若要在虛線十進位表示法和 IPAddr 格式之間轉換IP位址,請使用 inet_addrinet_ntoa 函式。

範例

下列程式代碼示範如何取得與指定 IPv4 位址相關聯的硬體或媒體存取控制 (MAC) 位址。

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

void usage(char *pname)
{
    printf("Usage: %s [options] ip-address\n", pname);
    printf("\t -h \t\thelp\n");
    printf("\t -l length \tMAC physical address length to set\n");
    printf("\t -s src-ip \tsource IP address\n");
    exit(1);
}

int __cdecl main(int argc, char **argv)
{
    DWORD dwRetVal;
    IPAddr DestIp = 0;
    IPAddr SrcIp = 0;       /* default for src ip */
    ULONG MacAddr[2];       /* for 6-byte hardware addresses */
    ULONG PhysAddrLen = 6;  /* default to length of six bytes */

    char *DestIpString = NULL;
    char *SrcIpString = NULL;

    BYTE *bPhysAddr;
    unsigned int i;

    if (argc > 1) {
        for (i = 1; i < (unsigned int) argc; i++) {
            if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
                switch (tolower(argv[i][1])) {
                case 'l':
                    PhysAddrLen = (ULONG) atol(argv[++i]);
                    break;
                case 's':
                    SrcIpString = argv[++i];
                    SrcIp = inet_addr(SrcIpString);
                    break;
                case 'h':
                default:
                    usage(argv[0]);
                    break;
                }               /* end switch */
            } else
                DestIpString = argv[i];
        }                       /* end for */
    } else
        usage(argv[0]);

    if (DestIpString == NULL || DestIpString[0] == '\0')
        usage(argv[0]);

    DestIp = inet_addr(DestIpString);

    memset(&MacAddr, 0xff, sizeof (MacAddr));

    printf("Sending ARP request for IP address: %s\n", DestIpString);

    dwRetVal = SendARP(DestIp, SrcIp, &MacAddr, &PhysAddrLen);

    if (dwRetVal == NO_ERROR) {
        bPhysAddr = (BYTE *) & MacAddr;
        if (PhysAddrLen) {
            for (i = 0; i < (int) PhysAddrLen; i++) {
                if (i == (PhysAddrLen - 1))
                    printf("%.2X\n", (int) bPhysAddr[i]);
                else
                    printf("%.2X-", (int) bPhysAddr[i]);
            }
        } else
            printf
                ("Warning: SendArp completed successfully, but returned length=0\n");

    } else {
        printf("Error: SendArp failed with error: %d", dwRetVal);
        switch (dwRetVal) {
        case ERROR_GEN_FAILURE:
            printf(" (ERROR_GEN_FAILURE)\n");
            break;
        case ERROR_INVALID_PARAMETER:
            printf(" (ERROR_INVALID_PARAMETER)\n");
            break;
        case ERROR_INVALID_USER_BUFFER:
            printf(" (ERROR_INVALID_USER_BUFFER)\n");
            break;
        case ERROR_BAD_NET_NAME:
            printf(" (ERROR_GEN_FAILURE)\n");
            break;
        case ERROR_BUFFER_OVERFLOW:
            printf(" (ERROR_BUFFER_OVERFLOW)\n");
            break;
        case ERROR_NOT_FOUND:
            printf(" (ERROR_NOT_FOUND)\n");
            break;
        default:
            printf("\n");
            break;
        }
    }

    return 0;
}


規格需求

需求
最低支援的用戶端 Windows 2000 Professional [僅限傳統型應用程式]
最低支援的伺服器 Windows 2000 Server [僅限桌面應用程式]
目標平台 Windows
標頭 iphlpapi.h
程式庫 Iphlpapi.lib
Dll Iphlpapi.dll

另請參閱

CreateIpNetEntry

CreateIpNetEntry2

CreateProxyArpEntry

DeleteIpNetEntry

DeleteIpNetEntry2

DeleteProxyArpEntry

FlushIpNetTable

FlushIpNetTable2

GetIpNetEntry2

GetIpNetTable2

IP 協助程式函式參考

IP 協助程式起始頁

IPAddr

ResolveIpNetEntry2

SetIpNetEntry

SetIpNetEntry2