Shammer's Philosophy

My private adversaria

getnameinfo-sample_alpha

とりあえず、man コマンドにあるヘルプを参考に書いてみた。

#include <arpa/inet.h>
#include <err.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char* args[]){
    if( argc == 2 ){
	// man getnameinfo sample
	// struct sockaddr *sa;    /* input */
	// char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
	//
	// if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
	//     errx(1, "could not get numeric hostname");
	// }
	// printf("host=%s, serv=%s\n", hbuf, sbuf);
	struct sockaddr_in sain;
	memset(&sain, 0, sizeof(sain));
	sain.sin_family = AF_INET;
	sain.sin_addr.s_addr = htonl(inet_addr(args[1]));
	struct sockaddr *sa = (struct sockaddr *)&sain;
	char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
	if( getnameinfo((struct sockaddr *)sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) ) {
	    errx(1, "Couldn't get numeric hostname\n");
	}
	printf("host=%s, serv=%s\n", hbuf, sbuf);
    }
    else {
	printf("Usage: %s $IP_ADDRESS\n", args[0]);
    }
    return 0;
}

実行結果は以下。

$ ./a.out 127.0.0.1
host=1.0.0.127, serv=0
$ ./a.out localhost
host=255.255.255.255, serv=0
$

何かがおかしい。man コマンドの内容によれば、

  1. sockaddr の構造体を用意
  2. ホスト名受け入れのための文字列変数を用意
  3. サービス名受け入れのための文字列変数を用意
  4. getnameinfo にsockaddr構造体と、ホスト名受け入れ用変数、サービス名受け入れ用変数を渡す
  5. ホスト名受け入れ用変数の内容とサービス名受け入れ用変数の内容を表示

という流れになるはずだが・・・やっぱり、構造体の作り方がおかしいのか?
そもそも、getnameinfo だから、ホスト名じゃなくて IP を渡すのが正しい使い方か。localhost を渡した場合の動作は無視してもいいかも。サービスが 0 になっているのも、sin_port 未指定だからという気がする。いずれにせよ、プログラムレベルであれこれ指定していては意味がない気が・・・一部しかわからない何らかの情報をインプットすることで、他の情報も補ってくれるっていう動作をするのが正しい気がする。引き続き試行錯誤は必要そうだな。。。