之前有想寫一個 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
全站熱搜
留言列表