nslookupを簡易実装しました。
入力されたドメイン名から
IPv4とIPv6を取得します。
まずは完成形をnslookupで
叩いてみてみます。

nslookup ドメイン名で
割り振られたIPアドレスを
表示させることが出来ます。
DNSしているだけです。
これとC++で同じことを
やってみましょう!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include<stdio.h> #include<stdlib.h> #include<netdb.h> #include<arpa/inet.h> int main(int argc, char *argv[]){ struct hostent *host; //ホスト名からアドレスを取得する際の入れ物 struct in_addr *addr4; //アドレスを入れ物から取り出すもの struct in6_addr *addr6; char buf4[INET_ADDRSTRLEN]; //inet_ntopを使うために必要 char buf6[INET6_ADDRSTRLEN]; if(argc<2){ printf("[-]How to use: %s <Host_name>\n", argv[0]); return -1; } printf("[+]%s\n", argv[1]); //IPv6 if((host=gethostbyname2(argv[1], AF_INET6))==NULL){ //ホスト名からアドレスを取得する。 fprintf(stderr, "[-]Error:gethostbyname2()_IPv6\n"); return -1; } addr6 = (struct in6_addr *)host->h_addr; //入れ物からアドレスを取り出す。 printf("[+]IPv6: %s\n", inet_ntop(AF_INET6, addr6, buf6, sizeof(buf6))); //文字列表記に変換して表示 //IPv4 if((host=gethostbyname2(argv[1], AF_INET))==NULL){ fprintf(stderr, "[-]Error:gethostbyname2()_IPv4\n"); return -1; } addr4 = (struct in_addr*)(host->h_addr); printf("[+]IPv4: %s\n", inet_ntop(AF_INET, addr4, buf4, sizeof(buf4))); return 0; } |
今回必要な関数は、
gethostbyname2()関数です。
これはホスト名から
ホスト情報を取得する関数です。
1 |
struct hostent *gethostbyname2(const char *name, int af); |
gethostbyname()関数も存在しますが、
それはIPv6に非対応なので、
gethostbyname2()を使いましょう。
第1引数に文字列が入ります。
第2引数にAF_INETか
AF_INET6が入ります。
要はIPv4かIPV6かです。
gethostbyname2関数は
ホスト名からホスト情報を
取得してくれます。
その際にhostent構造体という
入れ物が必要になります。
1 2 3 4 5 6 7 8 9 |
struct hostent { char *h_name; /* ホストの正式名称 */ char **h_aliases; /* 別名リスト */ int h_addrtype; /* ホストアドレスのタイプ (AF_INET6 など) */ int h_length; /* アドレスの長さ */ char **h_addr_list; /* NULL で終わるアドレスのリスト */ }; /* 最初のアドレス、ネットワークバイトオーダー */ #define h_addr h_addr_list[0] |
この構造体のメンバである
h_addr_listにアドレスが入っています。
最初のアドレスを示す要素は、
h_addrでアクセスできると
定義されているので、
ソースではh_addrでアクセスしています。
この状態のアドレスは、
バイナリなので私たちが
よく見かける文字列表記に直します。
その際にinet_ntop関数を使用します。
1 2 |
#include<arpa/inet.h> const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); |
ここで第3引数である
char *dstには、先ほどの
hostent構造体のh_addrを
指定します。
しかし一般的に、
なんやかんやと変換する機会が多い
ネットワークプログラミングでは、
in_addr構造体に変換します。
※変換しなくても正しく動作します。
IPv4とIPv6とでは、
使用する関数や構造体が
異なるので気を付けて下さい。
このソースを実行すると
以下の結果が得られます。

最後まで読んでいただきありがとうございました。