之前有想寫一個 FQDN 轉 IP 的東西
用了 gethostbyname() 去做,不過這個 function 只適用 IPv4
輸入了 v6 相關的位址,會直接吐一個 segmentation fault 出來@@
所以改用 getaddrinfo() 跟 getnameinfo 來做相關的功能
並且可以根據需求設定只取得 IPv4 or IPv6 的位址
程式碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
int main(int argc, char *argv[]) {
struct addrinfo hints, *result;
char hostname[1024];
int ret;
if (argc < 2) {
fprintf(stderr, "Usage: %s [host] [ip family(ipv4/ipv6)]...\n", argv[0]);
goto fail;
}
memset(&hints, 0, sizeof(hints));
if (argc == 3) {
if (strcmp(argv[2], "ipv4") == 0)
hints.ai_family = AF_INET;
else if (strcmp(argv[2], "ipv6") == 0)
hints.ai_family = AF_INET6;
else {
fprintf(stderr, "Usage: %s [host] [ip family(ipv4/ipv6)]...\n", argv[0]);
goto fail;
}
} else
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
ret = getaddrinfo(argv[1], NULL, &hints, &result);
if (ret != 0) {
fprintf(stderr, "%s.\n", gai_strerror(ret));
goto fail;
}
while (result != NULL) {
memset(hostname, 0, sizeof(hostname));
ret = getnameinfo(result->ai_addr,
result->ai_addrlen,
hostname,
sizeof(hostname),
NULL,
0,
NI_NUMERICHOST);
if (ret == 0) {
if (result->ai_family == AF_INET)
printf("IPv4 ---> %s\n", hostname);
else if (result->ai_family == AF_INET6)
printf("IPv6 ---> %s\n", hostname);
}
result = result->ai_next;
}
return 0;
fail:
return -1;
}
執行結果:
(1) ./a.out www.google.com
IPv4 ---> 173.194.72.99
IPv4 ---> 173.194.72.103
IPv4 ---> 173.194.72.104
IPv4 ---> 173.194.72.105
IPv4 ---> 173.194.72.106
IPv4 ---> 173.194.72.147
IPv6 ---> 2404:6800:4008:c01::93
(2) ./a.out www.google.com ipv4
IPv4 ---> 173.194.72.99
IPv4 ---> 173.194.72.103
IPv4 ---> 173.194.72.104
IPv4 ---> 173.194.72.105
IPv4 ---> 173.194.72.106
IPv4 ---> 173.194.72.147
(3) ./a.out www.google.com ipv6
IPv6 ---> 2404:6800:4008:c01::93

請先 登入 以發表留言。