SockDB Linux 版 次のような機能を実現します 1.ローカルホスト名を表示する 2.起動引数がないとき:ローカルホスト名に設定されているIPアドレスを表示する 3.起動引数にドメイン名(FQDN)を指定したとき:ドメイン名に設定されている IPアドレスを表示する

プロジェクトの作成 ファイル→新規作成→クロスプラットフォーム→メイクファイルプロジェクト プロジェクト名:SockDB 「ソリューションのディレクトリを作成する」のチェックを外す。

(*)プロジェクトのプロパティは、VisualC++ for Linuxを使ったプログラム を見て設定してください。

プロジェクト→既存の項目の追加を選びstdThread.cpp, stdThread.h, makefileを追加します プロジェクト→新規の項目の追加を選びSockDB.cppを追加します

【makefile】 CC=g++ -g3 -O0 #CC=g++ PROGRAM=SockDB OBJS=SockDB.o stdThread.o SRCS=$(OBJS:%.o=%.cpp) INCLUDE=stdThread.h LFLAGS=-lpthread $(PROGRAM):$(OBJS) $(SRCS) $(INCLUDE) $(CC) -o $(PROGRAM) $(SRCS) $(LFLAGS)

【SockDB.cpp】 #include “stdThread.h” // 作成した関数のプロトタイプ宣言 void GetHostName(); void GetHostAddress(LPSTR pszCurHost); int main(int argc, char *argv[]) { int iRet = -1; LPSTR pszCurHost = NULL; // 起動引数のチェック if (argc == 2) pszCurHost = argv[1]; // ドメイン名が指定された GetHostName(); // ローカルホスト名の取得 GetHostAddress(pszCurHost); // アドレスの取得 iRet = 0; return(iRet); } ///////////////////////////////////////////////// // function // ローカルホスト名の取得 // parameter // なし // return // なし ///////////////////////////////////////////////// void GetHostName() { char szHostName[NI_MAXHOST]; // ホスト名格納エリア char szMsg[NI_MAXHOST]; // ローカルホスト名の取得 if (gethostname(szHostName, sizeof(szHostName)) == SOCKET_ERROR) sprintf(szMsg, “Err: %d”, errno); else sprintf(szMsg, “%s”, szHostName); fprintf(stderr, “%s\n”, szMsg); } ///////////////////////////////////////////////// // function // ホスト名からIPアドレスを取得する // ホスト名がNULLのときはローカルホスト名を使用する // parameter // LPSTR pszCurHost [in]ホスト名/NULL // return // なし ///////////////////////////////////////////////// void GetHostAddress(LPSTR pszCurHost) { char szHostName[NI_MAXHOST]; // ホスト名格納エリア addrinfo hints, *pres = NULL, *pTemp = NULL; char szHostAddr[NI_MAXHOST]; // アドレス格納エリア int iCount = 1; // ホスト名をszHostNameに格納 if (pszCurHost != NULL) { strcpy(szHostName, pszCurHost); } else { if (gethostname(szHostName, sizeof(szHostName)) == SOCKET_ERROR) goto L_END; } // hintsの初期化 memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // IPv4, IPv6ともに列挙対象とする   // hintに従ってアドレス情報を取得する if (getaddrinfo(szHostName, NULL, &hints, &pres) != 0) goto L_END; // 順番にpresの中に格納されている情報を表示する pTemp = pres; while (pTemp != NULL) { // NI_NUMERICHOST 数値形式のホスト名(IPアドレス) if (getnameinfo(pTemp->ai_addr, (socklen_t)pTemp->ai_addrlen, szHostAddr, sizeof(szHostAddr), NULL, 0, NI_NUMERICHOST) == 0) { fprintf(stderr, “%d family:%2d Address:%s\n”, iCount, pTemp->ai_family, szHostAddr); } pTemp = pTemp->ai_next; // 次の情報へ移動 iCount++; } freeaddrinfo(pres); // 取得した情報を破棄 L_END: return; }

hintsの初期化で hints.ai_family = AF_UNSPEC; を指定すると、対象がすべてのファミリつまりIPv4, IPv6になります。 AF_INETを指定するとIPv4, AF_INET6を指定するとIPV6のみが対象となります。

if(getaddrinfo(szHostName, NULL, &hints, &pres) != 0) と、ホスト名のみを指定すると指定したホストのアドレス情報が ヒントに指定した条件でpresに格納されます。

if (getnameinfo(pTemp->ai_addr, (socklen_t)pTemp->ai_addrlen, szHostAddr, sizeof(szHostAddr), NULL, 0, NI_NUMERICHOST) == 0) とNI_NUMERICHOSTを指定するとpTemp->ai_addrに格納されている IPアドレス(バイナリ)が数値形式でszHostAddrに格納されます。 pTemp->ai_addrはIPv4のときsockaddr_inで、IPv6のときsockaddr_in6に なります。

引数にwww.oji-koji.comを指定して動かすとIPv4とIPv6をDNS サーバに登録してありますので、ちゃんと取得できています

$ ./SockDB www.oji-koji.com tk2-235-27468.vs.sakura.ne.jp 1 family:10 Address:2001:e42:102:1535:160:16:119:222 2 family:10 Address:2001:e42:102:1535:160:16:119:222 3 family:10 Address:2001:e42:102:1535:160:16:119:222 4 family: 2 Address:160.16.119.222 5 family: 2 Address:160.16.119.222 6 family: 2 Address:160.16.119.222

【参考】
プロジェクトSockDB for Linux(zip)
引数にドメイン名、サービス名を指定すると
IPアドレスとポート番号を表示する