getnameinfo-sample_beta
getnameinfo-sample_alpha - Shammerismの内容から、getnameinfo を使用する際にはIPアドレスをベースに動作させたい、と思い考えてみた。getnameinfo に必要な入力は sockaddr 構造体。IPアドレスから sockaddr 構造体を手に入れるには・・・ということで、Shammerismで使ったgetaddrinfoを使おうと思い立った。
addrinfo 構造体の内容を再引用。
struct addrinfo { int ai_flags; /* input flags */ int ai_family; /* protocol family for socket */ int ai_socktype; /* socket type */ int ai_protocol; /* protocol for socket */ socklen_t ai_addrlen; /* length of socket-address */ struct sockaddr *ai_addr; /* socket-address for socket */ char *ai_canonname; /* canonical name for service location */ struct addrinfo *ai_next; /* pointer to next in list */ };
ai_addr が目的のsockaddr構造体だ。というわけで、
- IPアドレスからaddrinfo構造体を作成
- ホスト名やサービス名を格納するための変数を用意
- 作成したaddrinfo->ai_addrをgetnameinfoの引数に渡す
- 同時にホスト名やサービス名を格納するための変数も渡す
という感じでいけるはず。
#include <arpa/inet.h> #include <err.h> #include <netdb.h> #include <stdio.h> #include <string.h> int main(int argc, char* args[]){ if( argc == 3 ){ // 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 addrinfo hints, *res, *res0; int error; char addrstring[100]; void *ptr; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(args[1], NULL, &hints, &res0); if( error ) { errx(1, "%s\n", gai_strerror(error)); } for( res = res0 ; res != NULL ; res = res->ai_next) { getnameinfo((struct sockaddr *)res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); printf("host=%s, serv=%s\n", hbuf, sbuf); } if( res != NULL ){ freeaddrinfo(res); } } else { printf("Usage: %s $IP_ADDRESS $PORT\n", args[0]); } return 0; }
実行結果は以下。
$ ./a.out 127.0.0.1 21 host=127.0.0.1, serv=0 $ ./a.out 127.0.0.1 22 host=127.0.0.1, serv=0 $ ./a.out 127.0.0.1 23 host=127.0.0.1, serv=0 $ ./a.out 127.0.0.1 80 host=127.0.0.1, serv=0
サービスは相変わらず0だ・・・うーむ、、、