EnumInterface Linux版
Linux版ではgetifaddrsを使います。
プロジェクトの作成
ファイル→新規作成→クロスプラットフォーム→メイクファイルプロジェクト
プロジェクト名:EnumInterface
「ソリューションのディレクトリを作成する」のチェックを外す。
(*)プロジェクトのプロパティは、VisualC++ for Linuxを使ったプログラム
を見て設定してください。
SockDBのプロジェクトからstdThread.cpp, stdThread.h, makefileをコピーし
既存の項目の追加としてプロジェクトに追加します。
プロジェクト→新規の項目の追加を選びEnumInterface.cppを追加します。
【makefileの変更】 CC=g++ -g3 -O0 #CC=g++ PROGRAM=EnumInterface OBJS=EnumInterface.o stdThread.o SRCS=$(OBJS:%.o=%.cpp) INCLUDE=stdThread.h LFLAGS=-lpthread $(PROGRAM):$(OBJS) $(SRCS) $(INCLUDE) $(CC) -o $(PROGRAM) $(SRCS) $(LFLAGS)
使用する関数
int getifaddrs(struct ifaddrs **ifap); // インターフェースのアドレスを取得する
void freeifaddrs(struct ifaddrs *ifa); // 取得した情報の開放
ifaddrsから情報を読み出すには次のようにします。
ifaddrs構造体は、メンバに* ifa_nextを持つリストなので、これがNULLになるまで
順番にたどっていくと取得した情報を読み出すことができます。
ここで使用するメンバ変数は、次のものです。
struct ifaddrs *ifa_next; // Next item in list
char *ifa_name; // Name of interface
struct sockaddr *ifa_addr; // Address of interface
struct sockaddr *ifa_netmask; // Netmask of interface
ここで使用する新たなソケットAPI(インターフェース名からインデックスを取得する)
unsigned int if_nametoindex(const char *ifname);
(*)sockaddrはIPv4(sockaddr_in), IPv6(sockaddr_in6)の共通部分を
表す構造体です。
IPv4/IPv6共通で使用できるソケットライブラリでは、アドレス構造体
としてこれを使用します。
EnumInterface.cppは次のようになります。
#include “stdThread.h” #include <ifaddrs.h> #include <net/if.h> int main(void) { int iRet = 0; struct ifaddrs *pifaddrs = NULL, *pifa; char szAddr[NI_MAXHOST], szMask[NI_MAXHOST]; // アダプタリストの取得 if (getifaddrs(&pifaddrs) == -1) goto L_END; // アダプタ一覧を出力 pifa = pifaddrs; while(pifa) { // アドレスがないものは対象外 if (pifa->ifa_addr == NULL) goto L_NEXT; // IPv4/IPv6以外は対象外 if ((pifa->ifa_addr->sa_family != AF_INET) && (pifa->ifa_addr->sa_family != AF_INET6)) goto L_NEXT; fprintf(stderr, “Name:%s\n”, pifa->ifa_name); // インターフェース名前からインデックスを取得する fprintf(stderr, “Index:%d\n”, if_nametoindex(pifa->ifa_name)); if (pifa->ifa_addr->sa_family == AF_INET) // IPv4の時IPアドレスとネットマスクを調べる { inet_ntop(AF_INET, &((struct sockaddr_in *)pifa->ifa_addr)->sin_addr, szAddr, sizeof(szAddr)); inet_ntop(AF_INET, &((struct sockaddr_in *)pifa->ifa_netmask)->sin_addr, szMask, sizeof(szMask)); fprintf(stderr, ” IPv4: %s netmask %s\n”, szAddr, szMask); } else if (pifa->ifa_addr->sa_family == AF_INET6) // IPv6の時IPアドレスとネットマスクを調べる { inet_ntop(AF_INET6, &((struct sockaddr_in6 *)pifa->ifa_addr)->sin6_addr, szAddr, sizeof(szAddr)); inet_ntop(AF_INET6, &((struct sockaddr_in6 *)pifa->ifa_netmask)->sin6_addr, szMask, sizeof(szMask)); fprintf(stderr, ” IPv6: %s netmask %s\n”, szAddr, szMask); } fprintf(stderr, “\n”); L_NEXT: pifa = pifa->ifa_next; } iRet = 0; L_END: if (pifaddrs != NULL) freeifaddrs(pifaddrs); return(iRet); }
実行してみましょう。
インターフェースインデックス、インターフェース名、IPアドレスが列挙されます。
$ ./EnumInterface Name:lo Index:1 IPv4: 127.0.0.1 netmask 255.0.0.0 Name:eth0 Index:2 IPv4: 160.16.119.222 netmask 255.255.254.0 Name:lo Index:1 IPv6: ::1 netmask ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff Name:eth0 Index:2 IPv6: 2001:e42:102:1535:160:16:119:222 netmask ffff:ffff:ffff:ffff:: Name:eth0 Index:2 IPv6: fe80::9ea3:baff:fe01:f1ec netmask ffff:ffff:ffff:ffff::
【参考】
プロジェクトEnumInterface for Linux(zip)