가 resolveip
유틸리티의 기본 기능 모방 다음 코드, 가정 주소 :한다 getaddrinfo (3) 지정 hints->의 IPv6를 반환하지 않습니다 ai_socktype를이
#define _POSIX_SOURCE /* getaddrinfo() */
#include <sys/types.h> /* getaddrinfo(), struct addrinfo, struct sockaddr */
#include <sys/socket.h> /* getaddrinfo(), struct addrinfo, struct sockaddr, AF_* */
#include <netdb.h> /* getaddrinfo(), struct addrinfo, struct sockaddr */
#include <arpa/inet.h> /* inet_ntop() */
#include <stdio.h> /* fprintf(), printf(), perror(), stderr */
#include <stdlib.h> /* EXIT_SUCCESS */
int main(int argc, char** argv) {
for(int i = 1; i < argc; ++i) { /* For each hostname */
char* hostname = argv[i];
struct addrinfo* res; /* We retrieve the addresses */
if(getaddrinfo(hostname, NULL, NULL, &res) == -1) {
perror("getaddrinfo");
continue;
}
for(; res->ai_next; res = res->ai_next) { /* We print the addresses */
switch(res->ai_addr->sa_family) {
case AF_INET: {
struct in_addr addr = ((struct sockaddr_in*)(res->ai_addr))->sin_addr;
char buffer[17]; printf("%s: %s\n", hostname, inet_ntop(AF_INET, &addr, buffer, 17)); break;
} case AF_INET6: {
struct in6_addr addr = ((struct sockaddr_in6*)(res->ai_addr))->sin6_addr;
char buffer[40]; printf("%s: %s\n", hostname, inet_ntop(AF_INET6, &addr, buffer, 40)); break;
} default: {
fprintf(stderr, "%s: Unknown address family\n", hostname);
}
}
}
freeaddrinfo(res); /* We release the allocated resources */
} return EXIT_SUCCESS;
}
위의 코드를 첫 번째로 google.com
호출을 인수 만이 다음과 비슷한 것을 출력합니다 :
google.com: 173.194.35.87
google.com: 173.194.35.87
google.com: 173.194.35.87
google.com: 173.194.35.95
google.com: 173.194.35.95
google.com: 173.194.35.95
google.com: 173.194.35.88
google.com: 173.194.35.88
google.com: 173.194.35.88
google.com: 2a00:1450:4008:800::101f
google.com: 2a00:1450:4008:800::101f
중복 항목을 제거하려고한다고 가정합니다. 따라서 우리가 검색하고자하는 결과의 종류에 대한 힌트가 포함 된 구조를 만들자.
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = 0,
.ai_protocol = 0,
.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG)
}; if(getaddrinfo(hostname, NULL, &hints, &res) == -1) {
perror("getaddrinfo");
continue;
}
것은 지금 우리를 보자 임의에 ai_socktype
필드를 지정하여 중복 항목을 필터링 : 구조가 getaddrinfo(3)
맨에 의해 명령으로 기본값으로 초기화되기 때문에 다음 수정, 어떤 방법으로 출력에 영향을주지 않습니다 값 :
google.com: 173.194.35.87
google.com: 173.194.35.95
google.com: 173.194.35.88
이제 브 우리를 보자
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_DGRAM,
.ai_protocol = 0,
.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG)
};
아아, 우리는 이제 IPv6 주소를 잃었다 원래의 힌트가없는 버전으로 RT :
if(getaddrinfo(hostname, NULL, NULL, &res) == -1) {
perror("getaddrinfo");
continue;
}
그리고 우리가 지금하는 대신 수동 필터링을 사용하자가 :
google.com: 173.194.35.87
google.com: 173.194.35.95
google.com: 173.194.35.88
google.com: 2a00:1450:4008:801::101f
:
for(; res->ai_next; res = res->ai_next) {
if(res->ai_socktype != SOCK_DGRAM) continue;
...
}
이제 모든 방식으로 작동 그것은 가정된다
getaddrinfo(3)
함수에 대한 힌트와 반환 된 레코드의 수동 필터링 사이의 불일치가 어디에서 발생하는지 궁금합니다. glibc 2.17을 사용하여 Linux 커널 3.8.0-32에서 테스트되었습니다.
당신이 컴퓨터에 구성된 IPv6 주소를 가지고 있습니까 할 필요가? | AI_ADDRCONFIG에서 IPv6를 반환하지 않습니다 사용 .ai_socktype = 0 , .ai_protocol = 0, .ai_flags = (AI_V4MAPPED { .ai_family = AF_UNSPEC'에 대한 힌트를 설정하기 때문에 당신은 내가, 할 생각하지 – nos
할 경우 주소 AI_ADDRCONFIG) }'IPv6 주소를 반환합니다. 'ai_socktype'을'0' 이외의 값으로 설정하면 결과에서 사라집니다. – Witiko