ネットワークインターフェース情報一覧を取得する(getifaddrs)

機器に設定されている全てのネットワークインターフェースに付いている、IPアドレス、ネットマスク、ブロードキャストアドレス、フラグなどの情報一覧を取得するには、getifaddrs関数(※システムコールではありません)を利用します。 getifaddrs関数はIPv4とIPv6両方に関する情報をリストとして取得できます。

getifaddrsで取得したifaddrs構造体はfreeifaddrs関数を利用して解放する必要があります。

getifaddrsを利用したサンプルプログラム

以下に、getifaddrsを利用したサンプルプログラムを示します。 フラグ、IPアドレス、ネットマスクを表示しています。


#include <stdio.h>
#include <string.h>
#include <ifaddrs.h>
#include <sys/socket.h>
#include <netinet/in.h>

int
main()
{
  struct ifaddrs *ifa_list;
  struct ifaddrs *ifa;
  int n;
  char addrstr[256], netmaskstr[256];

  /* (1) */
  n = getifaddrs(&ifa_list);
  if (n != 0) {
    return 1;
  }

  /* (2) */
  for(ifa = ifa_list; ifa != NULL; ifa=ifa->ifa_next) {

    /* (3) */
    printf("%s\n", ifa->ifa_name);
    printf("  0x%.8x\n", ifa->ifa_flags);

    memset(addrstr, 0, sizeof(addrstr));
    memset(netmaskstr, 0, sizeof(netmaskstr));

    if (ifa->ifa_addr->sa_family == AF_INET) {  /* (4) */
      inet_ntop(AF_INET,
        &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
        addrstr, sizeof(addrstr));

      inet_ntop(AF_INET,
        &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr,
        netmaskstr, sizeof(netmaskstr));

      printf("  IPv4: %s netmask %s\n", addrstr, netmaskstr);

    } else if (ifa->ifa_addr->sa_family == AF_INET6) { /* (5) */
      inet_ntop(AF_INET6,
        &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
        addrstr, sizeof(addrstr));

      inet_ntop(AF_INET6,
        &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr,
        netmaskstr, sizeof(netmaskstr));

      printf("  IPv6: %s netmask %s\n", addrstr, netmaskstr);
    } else { /* (6) */
      printf("  else:%d\n", ifa->ifa_addr->sa_family);
    }

    printf("\n");
  }

  /* (7) */
  freeifaddrs(ifa_list);

  return 0;
}

  • getifaddrsを利用しています。
  • for文を利用してifa_listの全ての要素に対してイテレーションを行います。
  • ifa_nameに格納されているネットワークインターフェース名とフラグを表示しています。
  • AF_INET6の場合は「IPv4」と表示してIPアドレスとネットマスクを表示しています。
  • AF_INET6の場合は「IPv6」と表示してIPアドレスとネットマスクを表示しています。
  • AF_INET, AF_INET6以外のsa_familyの場合は、sa_familyの値だけを表示しています。
  • freeifaddrsを利用してifa_listに割り当てられたメモリを解放しています。

上記サンプルプログラムを実行すると以下のような結果が出力されます。 なお、sa_familyが17となっているのはAF_PACKETです。


lo
  0x00010049
  else:17

eth0
  0x00011043
  else:17

lo
  0x00010049
  IPv4: 127.0.0.1 netmask 255.0.0.0

eth0
  0x00011043
  IPv4: 192.168.4.3 netmask 255.255.255.0

lo
  0x00010049
  IPv6: ::1 netmask ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff

eth0
  0x00011043
  IPv6: fe80::0c10:ff92:c8fe:62fc netmask ffff:ffff:ffff:ffff::