ddingz 2021. 12. 28. 13:26

도메인 네임으로부터 IP 주소를 얻거나 IP 주소로부터 해당 호스트의 도메인 네임을 얻으려면 DNS(Domain name Service) 서버의 도움을 받아야 한다.

#include <netdb.h>
struct hostent *gethostbyname(const char *hname);
struct hostent *gethostbyaddr(const char *in_addr, int len, int family);

gethostbyname()은 도메인 네임 hname을 스트링 형태로 입력받고(예를 들면 "www.github.com") 그 이름에 해당하는 호스트의 각종 정보를 가지고 있는 hostent 구조체의 포인터를 리턴한다.
gethostbyaddr()은 IP 주소를 포함하고 있는 구조체 in_addr의 포인터와 이 주소의 길이, 주소 타입을 입력하여 해당 호스트의 정보를 가지고 있는 hostent 구조체의 포인터를 리턴한다.
구조체 hostent의 정의는 다음과 같다.

struct hostent {
    char *h_name; // 호스트 이름
    char **h_aliases; // 호스트 별명들
    int h_addrtype; // 호스트 주소의 종류 (AF_INET=2 등)
    int h_length; // 주소의 크기(바이트 단위이며 IPv4에서는 4임)
    char **h_addr_list; // IP 주소 리스트
};
#define h_addr h_addr_list[0] // 첫 번째 (대표) 주소

h_addr은 호스트의 첫 번째 IP 주소 즉, 호스트의 대표 주소인 h_addr_list[0]을 가리킨다.


get_hostent.c

도메인 네임으로부터 해당 호스트의 hostent 구조체 정보를 구한 후 hostent 구조체의 내용을 모두 출력해 보는 프로그램이다.
먼저 목적지 호스트의 도메인 네임을 명령 인자로 받고 gethostbyname()을 이용하여 목적지 호스트의 hostent 구조체를 얻는다.
다음에는 hostent 내에 있는 호스트 이름, 별명(있으면), 주소 체계, dotted decimal 인터넷 주소를 화면에 출력한다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h> // memcpy 함수 선언
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>

int main(int argc, char *argv[]) {
    struct hostent *hp;
    struct in_addr in;
    int i;
    char buf[20];

    if (argc < 2) {
        printf("Usage : %s hostname\n", argv[0]);
        exit(1);
    }

    hp = gethostbyname(argv[1]);
    if (hp == NULL) {
        printf("gethostbyname fail\n");
        exit(0);
    }

    printf("호스트 이름 : %s\n", hp->h_name);
    printf("호스트 주소타입 번호 : %d\n", hp->h_addrtype);
    printf("호스트 주소의 길이 : %d\n", hp->h_length);
    for (i = 0; hp->h_addr_list[i]; i++) {
        memcpy(&in.s_addr, hp->h_addr_list[i], sizeof(in.s_addr));
        inet_ntop(AF_INET, &in, buf, sizeof(buf));
        printf("IP 주소(%d 번째) : %s\n", i + 1, buf);
    }
    for (i = 0; hp->h_aliases[i]; i++)
        printf("호스트 별명(%d 번째) : %s\n", i + 1, hp->h_aliases[i]);
    puts("");

    return 0;
}

실행 결과


get_host_byaddr.c

입력된 dotted decimal 주소로부터 gethostbyaddr()을 이용하여 해당 호스트를 찾아 도메인 네임을 얻는 프로그램이다.
한편, 현재 사용중인 자신의 컴퓨터의 도메인 이름을 얻으려면 uname()이나 gethostname()을 이용하면 된다.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc, char *argv[]) {
    struct hostent *myhost;
    struct in_addr in;

    if (argc < 2) {
        printf("사용법 : %s ip_address\n", argv[0]);
        exit(0);
    }

    inet_pton(AF_INET, argv[1], &in.s_addr); // dotted decimal -> 32bit 주소
    myhost = gethostbyaddr((char *)&(in.s_addr), sizeof(in.s_addr), AF_INET);
    if (myhost == NULL) {
        printf("Error at gethostbyaddr()\n");
        exit(0);
    }

    printf("호스트 이름 : %s\n", myhost->h_name);

    return 0;
}

실행 결과