티스토리 뷰



* 본 포스팅은 한국소프트웨어진흥원 출처의 리눅스 네트워크 프로그래밍 PDF 파일을 토대로 작성되었습니다.

* 개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있음을 밝힙니다.





사전에 깔고 들어가는 정보


※ 4 byte의 IP 주소를 편의에 따라 도메인 주소 또는 10진수(demical) 형태로 표현함



○ IP 주소

- 10진수 표현의 저장에는 15개의 문자로 구성된 문자열 변수가 사용됨

- IP 데이터그램을 네트워크 상에서 전송할 때 IP 헤더에는 2진수(binary) IP주소만 사용





IP 주소변환 


예제(ip_conv.c)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "stdio.h"
#include "netinet/in.h"
//inet_pton, inet_ntop 함수가 포함된 헤더파일
 
void main(int argc, char *argv[])
{
        struct in_addr addr;
        //2진수 IP 주소의 저장을 위한 구조체 사용
        char buf[20];
        //10진수 IP 주소의 저장을 위한 임시 변수
        
        printf("demical IP addr : %s\n", argv[1]);
        //입력받은 10진수 IP 주소를 명시
        
        inet_pton(AF_INET, argv[1], &addr.s_addr);
        printf("inet_pton(%s) : 0x%x\n", argv[1], addr.s_addr);
        //입력받은 값을 2진수 IP주소로 변환하여 addr 구조체에 저장
 
        inet_ntop(AF_INET, &addr.s_addr, buf, sizeof(buf));
        printf("inet_ntop(0x%x) = %s\n", addr.s_addr, buf);
        //addr 구조체의 2진수 IP주소 값을 10진수로 변환하여 buf에 sizeof(buf)만큼 저장
}


○ inet_pton() : 10진수 IP 주소를 2진수 IP 주소로 변환하는 함수

- inet_pton(AF_INET, 10진수 IP주소, 변환될 IP가 저장될 공간)

- 10진수로 표현된 IP 주소를 인자로 입력

- IPv6로 사용한다면 AF_INET6 를 인자로 준다.


○ inet_ntop() : 2진수 IP 주소를 10진수 IP 주소로 변환하는 함수

- inet_ntop(AF_INET, 2진수 IP주소, 변환될 IP가 저장될 공간(buf), buf의 크기)

- 2진수로 표현된 IP 주소를 인자로 입력

- IPv6로 사용한다면 AF_INET6 를 인자로 준다.



실행결과






도메인 주소변환 


※ DNS 서버의 도움을 받아 도메인 네임으로 부터 IP 주소를 얻거나

   IP 주소로 부터 도메인 네임을 얻음



※ 구조체 hostent : 호스트의 각종 정보를 저장한 구조체


1
2
3
4
5
6
7
8
struct hostent 
{
    char *h_name     //호스트 이름
    char **h_aliases //호스트 별명들
    int h_addrtype     //호스트 주소의 종류
    int h_length     //주소의 길이
    char **h_addr_list //IP 주소 리스트
};


○ gethostbyname() : 도메인 네임를 IP 주소로 변환하는 함수

- 도메인 네임을 문자열 형태로 입력

- 해당 호스트의 정보를 가진 hostent 구조체 포인터를 리턴


○ gethostbyaddr() : 2진수 IP 주소를 도메인 네임로 변환하는 함수

- IP 주소를 포함하고 있는 in_addr 구조체 포인터와 주소의 길이, 주소 타입 입력

- 해당 호스트의 정보를 가진 hostent 구조체를 리턴


※ 호스트의 정보를 얻기 위해서는 DNS 서버에서 Reverse DNS가 수행되어야 한다.

※ 그런데 최근 보안문제로 대부분의 DNS 서버가 Reverse DNS 기능을 제공하지 않는다.


2014. 05. 16 추가 내용

gethostbyname, gethostbyaddr 은 구식 방법으로써 현재 표준이 아니라고 합니다.

현재는 getnameinfo 함수가 표준으로써, getnameinfo 관련 링크를 첨부합니다. (영문)

http://man7.org/linux/man-pages/man3/getnameinfo.3.html

getnameinfo 함수에 대한 정보가 국내 사이트에 많지 않아서 조만간 직접 사용해보고 내용 추가하도록 하겠습니다.



gethostbyname 예제(domain_conv.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
#include "stdio.h"
#include "netinet/in.h"
#include "netdb.h"
//hostent 구조체와 gethostname 함수 포함 헤더
 
void main(int argc, char *argv[])
{
        struct hostent *host;
        struct in_addr addr;
 
        int i;
        char buf[20];
        
        host = gethostname(argv[1]);
        if(!host) 
        {
                printf("gethostbyname fail\n");
                exit(0);
        }
 
        printf("호스트 이름 : %s\n", host->h_name);
        printf("호스트 주소타입 번호 : %d\n", host->h_addrtype);
        printf("호스트 주소의 길이 : %d\n", host->h_length);
        for(i=0; host->h_addr_list[i]; i++) 
        {
                memcpy(&addr.s_addr, host->h_addr_list[i], sizeof(addr.s_addr));
                inet_ntop(AF_INET, &addr, buf, sizeof(buf));
                printf("IP 주소(%d 번째) : %s", i+1, buf);
        }
        for(i=0; host->h_aliases[i]; i++)
        {
                printf("호스트 별명(%d 번째) : %s", i+1, host->h_aliases[i]);
        }
}


실제로 gcc 로 컴파일 하면 컴파일에는 성공하나 프로그램을 구동하면

DNS 정보를 얻어 못하는 건지 어딘가에 문제가 있는지

gethostbyname fail 이 뜨는 것을 확인 할 수 있다.







공유하기 링크
태그 클라우드
, , , ,
프로필사진

Yowu (Yu Yongwoo)

흔한 백엔드 개발자입니다
우분투 데스크탑 개발 환경을 선호합니다
최근에는 vscode에 neovim 모드 올려서 쓰고 있습니다
개발용 키보드는 역시 해피해킹 프로2 무각입니다
락 밴드에서 드럼을 쳤습니다

«   2020/01   »
      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  
글 보관함
Total
2,615,804
Today
0
Yesterday
772