ネットワークインターフェースのARP情報を取得する

作成するアプリケーションによっては、ARPテーブルが必要になることもあります。 それらの情報を得るためには、GetIpNetTable()関数を使います。 ここでは、GetIpNetTable()の使い方を説明します。

サンプルコード

GetIpNetTable()を使ったサンプルコードを以下に示します。


#include <stdio.h>

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

int
main()
{
 DWORD i;
 PMIB_IPNETTABLE pIpNetTable = NULL;
 DWORD dwSize = 0;
 DWORD dwRetVal = 0;
 DWORD dwResult;

 dwResult = GetIpNetTable(NULL, &dwSize, 0);
 /* GetIpNetTable()で必要になるサイズを取得 */
 if (dwResult == ERROR_INSUFFICIENT_BUFFER) {
   pIpNetTable = (MIB_IPNETTABLE *) malloc (dwSize);
 }

 /* 実際にGetIpNetTable()を使う */
 if ((dwRetVal = GetIpNetTable(pIpNetTable, &dwSize, 0))
      == NO_ERROR) {
   if (pIpNetTable->dwNumEntries > 0) {
     for (i=0; i<pIpNetTable->dwNumEntries; i++) {
      printf("Address: %s\n",
        inet_ntoa(*(struct in_addr *)&pIpNetTable->table[i].dwAddr));

      /* 注意:この例ではdwPhysAddrLenが6であると仮定しています */
      /* 本来はこのように6であると仮定すべきではありません      */
      printf("Phys Addr Len: %d\n",
		pIpNetTable->table[i].dwPhysAddrLen);
      printf("Phys Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
	    pIpNetTable->table[i].bPhysAddr[0],
		pIpNetTable->table[i].bPhysAddr[1],
        pIpNetTable->table[i].bPhysAddr[2],
        pIpNetTable->table[i].bPhysAddr[3],
        pIpNetTable->table[i].bPhysAddr[4],
        pIpNetTable->table[i].bPhysAddr[5]);

       printf("Index:   %ld\n", pIpNetTable->table[i].dwIndex);
       printf("Type:   %ld\n", pIpNetTable->table[i].dwType);
       printf("\n");
     }
   }
 } else {
   printf("GetIpNetTable failed.\n");
   LPVOID lpMsgBuf;
			
   if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                     FORMAT_MESSAGE_FROM_SYSTEM | 
                     FORMAT_MESSAGE_IGNORE_INSERTS,
                     NULL,
                     dwRetVal,
                     MAKELANGID(LANG_NEUTRAL,
                                SUBLANG_DEFAULT), //Default language
                     (LPTSTR) &lpMsgBuf,
                     0,
                     NULL ))  {
                       printf("\tError: %s", lpMsgBuf);
   }

   LocalFree( lpMsgBuf );
 }

 return 0;
}

サンプルコード実行例

上記コードをコンパイルして出来たものを実行すると、以下のようになります。


C:> a.exe
Address: 192.168.0.1
Phys Addr Len: 6
Phys Address: 00:d2:03:6e:3c:17
Index:   16788213
Type:   3

GetIpNetTable()が利用する構造体

GetIpNetTable()が利用している、MIB_IPNETTABLEは以下のように宣言されています。


typedef struct _MIB_IPNETROW {
  DWORD dwIndex;
  DWORD dwPhysAddrLen;
  BYTE bPhysAddr[MAXLEN_PHYSADDR];
  DWORD dwAddr;
  DWORD dwType;
} MIB_IPNETROW, *PMIB_IPNETROW;

typedef struct _MIB_IPNETTABLE {
  DWORD dwNumEntries;
  MIB_IPNETROW table[ANY_SIZE];
} MIB_IPNETTABLE, *PMIB_IPNETTABLE;

MIB_IPNETROW

dwIndex ARPエントリに関連するAdapterのIndexです。
dwPhysAddrLen Physical Addressの長さを表します。
bPhysAddr Physical Addressを表します。長さはdwPhysAddrLenにより表されます。
dwAddr IPアドレスです。
dwType ARPエントリの種類を表します。4:static、3:dynamic、2:invalid、1:other

MIB_IPNETTABLE

dwNumEntries ARPエントリの数が入ります。
table MIB_IPNETROWの配列として、個々のARPエントリが格納されます。配列の長さはdwNumEntriesによって表されます。

IPv6基礎検定

YouTubeチャンネルやってます!