getaddrinfo.
getaddrinfogetaddrinfo()와 getnameinfo() 함수는 도메인 이름, 호스트 이름 및 IP 주소를 사람이 읽을 수 있는 텍스트 표현과 운영 체제의 네트워킹 API를 위한 구조화된 이진 형식 간에 변환한다. 두 기능 모두 POSIX 표준 애플리케이션 프로그래밍 인터페이스(API)에 포함되어 있다.
getaddrinfo와 getnameinfo는 서로 역함수다. 네트워크 프로토콜에 구애받지 않으며 IPv4와 IPv6을 모두 지원한다. 그것은 프로토콜 독립 응용프로그램을 구축하고 기존 IPv4 코드를 IPv6 인터넷으로 전환하기 위해 이름 확인을 위한 권장 인터페이스다.
내부적으로는 gethostbyname()과 같은 다른 하위 수준의 함수를 호출하여 DNS(Domain Name System)를 사용하여 분해능을 수행한다.
2016년 2월 16일 glibc의 getaddrinfo() 구현에서 버퍼 오버플로 기법을 사용하여 공격자에 의한 임의 코드를 실행할 수 있는 보안 버그가 발표되었다.[1]
구조 애드린포
네트워킹 API 내의 주소와 호스트명을 나타내는 데 사용되는 C 데이터 구조는 다음과 같다.
구조체 addrinfo {int ai_interfamily; int ai_intype; int ai_t ai_addrlen; 구조체 sockaddr* ai_addr; char* ai_info* ai_name; /* 정식 이름 */구조체 addrfo* ai_next; /* 이 구조체는 링크 리스트를 구성할 수 있다 */ }; 일부 구형 시스템에서 ai_addrlen의 유형은 socklen_t 대신 size_t이다. accept()와 getpeername()과 같은 대부분의 소켓 기능은 매개변수에 socklen_t * 타입을 요구하고 프로그래머는 종종 주소를 addrlenfo 구조의 ai_addrlen 요소에 전달한다. 예를 들어 size_t가 8바이트이고 socklen_t가 4바이트인 64비트 Solaris 9 시스템에서 유형이 호환되지 않으면 런타임 오류가 발생할 수 있다.
구조물은 자체적인 sa_family 필드가 있는 ai_family와 sockaddr을 포함한다. 이들은 일부 구현에서 getaddrinfo 함수로 구조가 생성될 때 동일한 값으로 설정된다.
getaddrinfoe. Getaddrinfoe.
getaddrinfo()는 호스트 이름이나 IP 주소를 나타내는 사람이 읽을 수 있는 텍스트 문자열을 구조체 애드린포 구조의 동적으로 할당된 링크된 목록으로 변환한다. 이 기능에 대한 기능 프로토타입은 다음과 같이 지정된다.
int getaddrinfo(const char* hostname, const char* 서비스, constucture addrinfo* 힌트, constucture addrinfo** res) - 호스트 이름
- "example.com"과 같은 도메인 이름, "message.0.0.1"과 같은 주소 문자열 또는 NULL일 수 있으며, 이 경우 힌트 플래그에 따라 주소가 0.0.0.0 또는 127.0.0.1이 할당된다.
- 서비스
- 문자열로 전달되는 포트 번호(예: "80") 또는 서비스 이름(예: "properties")일 수 있다. 후자의 경우 일반적인 구현에서는 getervbyname()을 사용하여 /etc/services 파일을 쿼리하여 서비스를 포트 번호로 해결한다.
- 힌트
- NULL 또는 요청된 서비스 유형의 애드린포 구조일 수 있다.
- 재방송하다
- 기능이 성공적으로 완료된 후 요청된 정보로 새로운 애드린포 구조를 가리키는 포인터다.[2] 함수는 성공 시 0을 반환하고 실패하면 0이 아닌 오류 값을 반환한다.[3]
구현은 플랫폼마다 다르지만, 기능은 먼저 서비스에서 분기하여 포트 번호를 얻으려고 시도한다. 문자열 값이 숫자일 경우 정수로 변환하고 htons()를 호출한다. www와 같은 서비스 이름인 경우, 힌트->ai_socktype에서 파생된 프로토콜을 해당 함수의 두 번째 매개 변수로 사용하여 getervbyname()으로 서비스를 조회한다. 그런 다음 호스트 이름이 주어지는 경우(NULL이 아닌 경우) gethostbyname()을 호출하여 해결하거나, 힌트->ai_flags가 AI_PASSIVE로 설정되어 있으면 0.0.0.0을, 그렇지 않으면 127.0.0.1을 사용한다. 그것은 이러한 조건들 중 하나에서 적절한 sockaddr_in으로 채워진 새로운 애드린포 구조를 할당하고 또한 처음에 검색된 포트를 그것에 추가한다. 마지막으로 **res 매개변수는 새로 할당된 애드린포 구조를 가리키도록 참조되지 않는다.[4] Mac OS용 Unix 버전과 같은 일부 구현에서는 힌트->ai_protocol이 힌트->ai_socktype 값을 재정의하는 반면, 다른 구현에서는 그 반대인 경우가 있으므로, 둘 다 여러 플랫폼에 걸쳐 동작하기 위해서는 코드가 동일한 값으로 정의되어야 한다.
프리어드딘포
이 함수는 getaddrinfo() 함수에 의해 할당된 메모리를 자유롭게 한다. 후자의 결과는 주소 ai에서 시작하는 애드린포 구조의 링크된 목록이기 때문에 freeaddrinfo()는 리스트를 루핑하여 각각을 차례로 자유화한다.
void freeaddrinfo(void addrinfo *ai); get nameinfoe.
getnameinfo() 함수는 구조체 sockaddr에 대한 포인터 형태의 IP 주소의 내부 이진 표현을 호스트 이름으로 구성된 텍스트 문자열로 변환하거나, 주소를 이름으로 확인할 수 없는 경우, 텍스트 IP 주소 표현뿐만 아니라 서비스 포트 이름이나 번호도 변환한다. 기능 프로토타입은 다음과 같이 지정된다.
int getnameinfo(구조체 sockaddr* sa, socklen_t salen, char* 호스트, size_t hostlen, char* serv, size_t servlen, int 플래그); 예
다음 예에서는 getaddrinfoe를 사용하여 도메인 이름 www.example.com을 주소 목록으로 확인한 다음 각 결과에 대해 getnameinfoe를 호출하여 주소에 대한 정식 이름을 반환한다. 일반적으로 이것은 특정 주소에 여러 개의 이름이 없는 한 원래의 호스트 이름을 생성하며, 이 경우 정식 이름이 반환된다. 이 예에서 도메인 이름은 세 번 인쇄되는데, 각 세 개의 결과마다 한 번씩 인쇄된다.
#include <stdio>.h> #include <stdlib>.h> #include <넷db>.h> #################h> ###s <sys/symes>.h> #ifndef NI_MAXHOST #define NI_MAXHOST 1025 #endif in main(void) {구조체 addrinfo* res; int error; /* 도메인 이름을 주소 목록으로 확인 */ error = getaddrinfo("www.example.com", NULL, NULL, < if (error != 0) { if (error == EAI_SYSTEM) { perror("getaddrinfo"); } 다른 {fprintf(stderr, "getaddrinfo: %s\n", gai_strror(error); } exit(EX)IT_FAILAY); } /* 반환된 모든 결과에 대해 루프를 반복하고 (res = 결과; res != NULL; res = res->ai_next) { char 호스트 이름[NI_MAXHOST]; error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, 0, 0); (infirm != 0) { fprintf(stderr, "getnameinfo: %s\n", gai_proror(info: %s\n", "gai_frror(info)"; }만약 (*filename != '\0') printff(": %s\n", 호스트 이름); } 프리어드딘포(freeaddrinfo); 반환 0; } 참고 항목
참조
- ^ "CVE-2015-7547: Glibc getaddrinfo stack-based buffer overflow".
- ^ Stevens R, Fenner, Rudoff [2003] UNIX® Network Programming Volume 1, Third Edition: 소켓 네트워킹 API. 게시자: 애디슨 웨슬리 프로페셔널. 펍. 날짜: 2003년 11월 14일 페이지 256
- ^ http://pubs.opengroup.org/onlinepubs/9699919799/ 31.5.18 액세스
- ^ Hajimu UMEMOTO [2000] getaddrinfo.c 액세스 위치: https://opensource.apple.com/source/passwordserver_sasl/passwordserver_sasl-14/cyrus_sasl/lib/getaddrinfo.c
외부 링크
- RFC 3493, IPv6용 기본 소켓 인터페이스 확장