gethostbynameの引数にipアドレスを指定した場合の動作
#include <stdio.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main(int argc, char **argv) { struct hostent *host = gethostbyname(argv[1]); printf("h_name = %s\n", host->h_name); printf("ip = "); for (char **addrp = host->h_addr_list; *addrp != NULL; addrp++) { struct in_addr addr; addr.s_addr = *((in_addr_t *) *addrp); char* ip = inet_ntoa(addr); printf(" %s", ip); } printf("\n"); }
$ gcc -std=c99 gethostbyname.c $ ./a.out www.google.com h_name = www.google.com ip = 216.58.220.196 $ ./a.out 216.58.220.196 h_name = 216.58.220.196 ip = 216.58.220.196
ホスト名とIPアドレス両方に対応したアプリを作る場合、条件分岐しなくてよいので便利ではあるのだけども、統一感はないかな。SUSやPOSIXとしてはIPアドレスを指定した場合の動作は定義していない。
The name argument of gethostbyname() shall be a node name; the behavior of gethostbyname() when passed a numeric address string is unspecified. For IPv4, a numeric address string shall be in the dotted-decimal notation described in inet_addr().
The Base Specifications Issue 6
W. Richard StevensのUnix Network Programmingのp.308によると、RloginがIPアドレスに対応していなかったかららしい
This code was added because the Rlogin client accepts only a hostname, calling gethostbyname, and will not accept a dotted-decimal string[Vixie 1996]
アプリ側の問題をライブラリ側で実装するのはどうなんだろうと一瞬思ったが、他のアプリにとっても便利だと思うのでまあいいのか
4.3BSD-Renoの頃]にはこのコードは入っているな
struct hostent * gethostbyname(name) char *name; { ... if ((host_addr.s_addr = inet_addr(name)) == -1) { h_errno = HOST_NOT_FOUND; return((struct hostent *) NULL); } host.h_name = name; host.h_aliases = host_aliases; host_aliases[0] = NULL; host.h_addrtype = AF_INET; host.h_length = sizeof(u_long); h_addr_ptrs[0] = (char *)&host_addr; h_addr_ptrs[1] = (char *)0; #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ host.h_addr_list = h_addr_ptrs; #else host.h_addr = h_addr_ptrs[0]; #endif return (&host);