WinSock gethostbyaddr
gethostbyaddrは、IPアドレスからホスト情報を取得する(逆引き)。
gethostbyaddr関数は以下のように定義されている
struct hostent FAR * PASCAL FAR gethostbyaddr( IN const char FAR * addr, //取得したいホスト情報のインターネットアドレス IN int len, //インターネットアドレス長 IN int type); //アドレスファミリ(TCP/IPではAF_INET)
gethostbyaddr関数は失敗するとNULLポインタを返す。WSAGetLastError関数によって失敗した原因を調べることができる。
gethostbyaddr関数が失敗したときのWSAGetLsatErrorの値は以下の通り
戻り値 | 説明 |
WSANOTINITIALISED | この関数を使う前にWSAStartupの呼び出しを成功させておかなければならない |
WSAENETDOWN | ネットワークサブシステムが停止している |
WSAHOST_NOT_FOUND | 正式なホスト名が見つかりません |
WSATRY_AGAIN | 正式でないホストが見つからない。または、サーバーが停止している |
WSANO_RECOVERY | 回復不能なエラーが発生しました |
WSANO_DATA | 要求されたホスト名は有効である、しかし要求された種類のデータは見つかりませんでした |
WSAEINPROGRESS | ブロッキングWinSock1.1の呼び出しが現在進行中、またはサービスプロバイダーはまだコールバック関数を処理中です。 |
WSAEAFNOSUPPORT | 指定されたアドレスファミリ(type引数)は、WinSockの実装ではサポートされていません |
WSAEFAULT | name引数は、有効なユーザーアドレス空間の一部ではない |
WSAEINTR | ブロッキングWinSock1.1の呼び出しは、WSACancelBlockingCallによってキャンセルされた。 |
戻り値の型であるstruct hostent構造体は、winsock.h に以下のように定義されている
struct hostent { char FAR * h_name; /* official name of host */ char FAR * FAR * h_aliases; /* alias list */ short h_addrtype; /* host address type */ short h_length; /* length of address */ char FAR * FAR * h_addr_list; /* list of addresses */ #define h_addr h_addr_list[0] /* address, for backward compat */ };
「はてな」のIPアドレスを逆引きする
#include <stdio.h> #include <winsock.h> #pragma comment(lib, "wsock32.lib") void PrintHostent(LPHOSTENT lpHostEntry) { printf("HostName: %s\n", lpHostEntry->h_name); printf("h_length: %d\n", lpHostEntry->h_length); printf("h_addrtype: %s\n", lpHostEntry->h_addrtype == AF_INET ? "AF_INET" : "Unknown address type"); for (int i = 0; lpHostEntry->h_aliases[i] != NULL; i++) { printf("h_aliases[%d]: %s\n", i, lpHostEntry->h_aliases[i]); } for (int i = 0; lpHostEntry->h_addr_list[i] != NULL;i++) { LPIN_ADDR addr = (LPIN_ADDR)lpHostEntry->h_addr_list[i]; printf("h_addr_list[%d]: %s\n", i, inet_ntoa(*addr)); } } int main() { WSADATA wsaData; int nRet; LPHOSTENT lpHostEntry; char *lpIPAddress = "59.106.108.77"; IN_ADDR addr; nRet = WSAStartup(MAKEWORD(1, 1), &wsaData); if (nRet != 0) { fprintf(stderr, "WSAStartup error: %d\n", WSAGetLastError()); goto EXIT_FUNC; } addr.S_un.S_addr = inet_addr(lpIPAddress); if (addr.S_un.S_addr == INADDR_NONE) { fprintf(stderr, "inet_addr error\n"); goto EXIT_FUNC; } lpHostEntry = gethostbyaddr((const char*)&addr, sizeof(struct in_addr), AF_INET); if (lpHostEntry != NULL) { PrintHostent(lpHostEntry); } else { switch (WSAGetLastError()) { case WSANOTINITIALISED: puts("WSANOTINITIALISED"); break; case WSAENETDOWN: puts("WSAENETDOWN"); break; case WSAHOST_NOT_FOUND: puts("WSAHOST_NOT_FOUND"); break; case WSATRY_AGAIN: puts("WSATRY_AGAIN"); break; case WSANO_RECOVERY: puts("WSANO_RECOVERY"); break; case WSANO_DATA: puts("WSANO_DATA"); break; case WSAEINPROGRESS: puts("WSAEINPROGRESS"); break; case WSAEAFNOSUPPORT: puts("WSAEAFNOSUPPORT"); break; case WSAEFAULT: puts("WSAEFAULT"); break; case WSAEINTR: puts("WSAEINTR"); break; default: puts("Other error"); break; } } EXIT_FUNC: WSACleanup(); return 0; }
実行結果
HostName: d.st-hatena.com h_length: 4 h_addrtype: AF_INET h_addr_list[0]: 59.106.108.77