🎮
IP 주소와 도메인 이름 사이의 변환
January 16, 2024
IP 주소와 도메인 이름 사이의 변환
도메인 이름을 이용해서 IP 주소 얻어오기
#include <netdb.h>
struct hostent * gethostbyname(const char * hostname);
// 성공 시 hostent 구조체 변수의 주소 값, 실패 시 NULL 포인터 반환
해당 함수는 hostent
구조체 변수에 담겨서 반환되는데, 이 구조체는 다음과 같이 정의되어 있다.
struct hostent
{
char * h_name; // official name
char ** h_aliases; // alias list
int h_addrtype; // host address type
int h_length; // address length
char ** h_addr_list; // address list
}
위의 구조체 정의를 보니, IP정보만 반환되는 것이 아니라, 여러가지 다른 정보들도 덤으로 반환되는 것을 알 수 있다. 복잡하게 생각하지 않아도 된다. 도메인 이름을 IP로 변환하는 경우에는 h_addr_list
만 신경써도 된다.
h_name
: 공식 도메인 이름(Ofiicial domain name)이 저장된다.h_alias
: 하나의 IP에 매핑된 다른 여러 도메인 이름의 별칭리스트를 반환한다.h_addrtype
: IPv4만 아니라 IPv6도 지원한다. IPv4의 경우는AF_INET
이 저장된다.h_length
: 함수호출의 결과로 반환된 IP주소의 크기가 담긴다. IPv4는 4바이트, IPv6는 16바이트이다.h_addr_list
: 이 멤버를 통해서 도메인 이름에 대한 IP주소가 정수의 형태로 반환된다. 접속자가 많은 서버는 여러 IP주소를 둬서 부하를 분산시킨다.
gethostbyname
다음은 간단한 예제를 보이겠다.
예제
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
void error_handling(char *message);
int main(int argc, char *argv[])
{
int i;
struct hostent *host;
if(argc != 2)
{
printf("Usage : %s <addr>\n", argv[0]);
exit(1);
}
host = gethostbyname(argv[1]);
if(!host)
error_handling("gethost... error");
printf("Official name: %s \n", host->h_name);
for(i = 0 ; host -> h_aliases[i] ; i++)
printf("Aliases %d: %s \n", i+1, host->h_aliases[i]);
printf("Address type: %s \n",
(host -> h_addrtype == AF_INET)? "AF_INET":"AF_INET6");
for(i = 0 ; host -> h_addr_list[i] ; i++)
printf("IP addr %d: %s n", i+1,
inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
💡 구조체 hostent의 멤버 h_addr_list가 가리키는 배열이 in_addr의 포인터 배열이 아닌, char형 포인터 배열인 이유는, IPv4만 지원하는 것이 아니기 때문이다.
void포인터 배열로 선언되지 않은 이유는 void형 포인터가 표준화되기 이전에 정의되었기 때문이다.
gethostbyaddr
#include <netdb.h>
struct hostent * gethostbyaddr(const char * addr, socklen_t len, int family);
// 성공 시 hostent 구조체 변수의 주소 값, 실패 시 NULL 포인터 반환
addr
: IP주소를 지니는 in_addr 구조체 변수의 포인터 전달, IPv4 이외의 다양한 정보를 전달받을 수 있도록 일반화하기 위해서 매개변수를 char형 포인터로 선언.len
: 첫 번째 인자로 전달된 주소정보의 길이, IPv4의 경우 4, IPv6의 경우 16family
: 주소체계 정보 전달. IPv4의 경우 AF_INET, IPv6의 경우 AF_INET6 전달.
해당 함수의 예제는 생략한다.
윈도우 기반의 gethostbyname, gethostbyaddr
#include <winsock2.h>
struct hostent * gethostbyname(const char * name);
// 성공 시 hostent 구조체 변수의 주소 값, 실패 시 NULL 포인터 반환
#include <winsock2.h>
struct hostent * gethostbyaddr(const char * addr, int len, int type);
// 성공 시 hostent 구조체 변수의 주소 값, 실패 시 NULL 포인터 반환