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

コードを書いていると、ネットワークインターフェースの情報として、IPアドレスやネットマスク(netmask)、ブロードキャストアドレス(broadcast address)なども知りたくなると思います。 それらの情報を得るためには、GetIpAddrTable()関数を使います。

サンプルコード

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


#include <stdio.h>

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

int
main()
{
 DWORD i;
 PMIB_IPADDRTABLE pIpAddrTable;
 DWORD dwSize = 0;
 DWORD dwRetVal = 0;

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

 /* 実際にGetIpAddrTable()を使う */
 if ((dwRetVal = GetIpAddrTable(pIpAddrTable, &dwSize, 0))
      == NO_ERROR) {
   if (pIpAddrTable->dwNumEntries > 0) {
     for (i=0; i<pIpAddrTable->dwNumEntries; i++) {
       printf("Address: %s\n",
        inet_ntoa(*(struct in_addr *)&pIpAddrTable->table[i].dwAddr));
       printf("Mask:    %s\n",
        inet_ntoa(*(struct in_addr *)&pIpAddrTable->table[i].dwMask));
       printf("Index:   %ld\n", pIpAddrTable->table[i].dwIndex);
       printf("BCast:   %ld\n", pIpAddrTable->table[i].dwBCastAddr);
       printf("Reasm:   %ld\n", pIpAddrTable->table[i].dwReasmSize);
       printf("\n");
     }
   }
 } else {
   printf("GetIpAddrTable 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.3
Mask:    255.255.255.0
Index:   2
BCast:   1
Reasm:   65535

Address: 127.0.0.1
Mask:    255.0.0.0
Index:   1
BCast:   1
Reasm:   65535

GetIpAddrTable()が利用する構造体

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


typedef struct _MIB_IPADDRROW {
  DWORD dwAddr;
  DWORDIF_INDEX dwIndex;
  DWORD dwMask;
  DWORD dwBCastAddr;
  DWORD dwReasmSize;
  unsigned short unused1;
  unsigned short wType;
} MIB_IPADDRROW, *PMIB_IPADDRROW;

typedef struct _MIB_IPADDRTABLE {
  DWORD dwNumEntries;
  MIB_IPADDRROW table[ANY_SIZE];
} MIB_IPADDRTABLE, *PMIB_IPADDRTABLE;

MIB_IPADDRROW

dwAddr IPアドレスです。
dwIndex IPアドレスに関連するAdapterのIndexです。
dwMask ネットマスクです。
dwBCastAddr ブロードキャストアドレスです。
dwReasmSize re-assembly size for received datagrams。
unused1 使われていません。
wType
MIB_IPADDR_PRIMARY
0x0001
Primary IP address
MIB_IPADDR_DYNAMIC
0x0004
Dynamic IP address
MIB_IPADDR_DISCONNECTED
0x0008
Address is on disconnected interface
MIB_IPADDR_DELETED
0x0040
Address is being deleted
MIB_IPADDR_TRANSIENT
0x0080
Transient address

MIB_IPADDRTABLE

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

最後に

(注)WindowsXPではIPv6がサポートされているため、GetIpAddrTable()ではなく、GetAdaptersAddresses()を使うことが推奨されています。 ただ、XPでもGetIpAddrTable()は利用可能なので、「IPv6なんて対応しないぜ!」という人はGetIpAddrTable()でも大丈夫です。

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