之前有想寫一個 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

 

參考資料:
http://my.oschina.net/u/158589/blog/62896

zzzaaa12 發表在 痞客邦 PIXNET 留言(0) 人氣()