示例#1
0
文件: adns.c 项目: Estella/wraith
/* Perform an async dns lookup. This is host -> ip. For ip -> host, use
 * egg_dns_reverse(). We return a dns id that you can use to cancel the
 * lookup. */
int egg_dns_lookup(const char *host, interval_t timeout, dns_callback_t callback, void *client_data)
{
	dns_query_t *q = NULL;
	int i, cache_id;

	sdprintf("egg_dns_lookup(%s, %d)", host, timeout);

	if (is_dotted_ip(host)) {
		/* If it's already an ip, we're done. */
		dns_answer_t answer;

		answer_init(&answer);
		answer_add(&answer, host);
		callback(-1, client_data, host, answer.list);
		answer_free(&answer);
		return(-1);
	}

	/* Ok, now see if it's in our host cache. */
	for (i = 0; i < nhosts; i++) {
		if (!egg_strcasecmp(host, hosts[i].host)) {
			dns_answer_t answer;

			answer_init(&answer);
			answer_add(&answer, hosts[i].ip);
			callback(-1, client_data, host, answer.list);
			answer_free(&answer);
			return(-1);
		}
	}

	cache_id = cache_find(host);
	if (cache_id >= 0) {
		shuffleArray(cache[cache_id].answer.list, cache[cache_id].answer.len);
		callback(-1, client_data, host, cache[cache_id].answer.list);
		return(-1);
	}

	/* check if the query was already made */
        if (find_query(host))
          return(-2);

	/* Allocate our query struct. */
        q = alloc_query(client_data, callback, host);

        dns_send_query(q);

//        /* setup a timer to detect dead ns */
//	dns_create_timeout_timer(&q, host, timeout);

	/* Send the ipv4 query. */

	return(q->id);
}
示例#2
0
文件: adns.c 项目: Estella/wraith
/* Perform an async dns reverse lookup. This does ip -> host. For host -> ip
 * use egg_dns_lookup(). We return a dns id that you can use to cancel the
 * lookup. */
int egg_dns_reverse(const char *ip, interval_t timeout, dns_callback_t callback, void *client_data)
{
	dns_query_t *q;
	int i, cache_id;

	sdprintf("egg_dns_reverse(%s, %d)", ip, timeout);

	if (!is_dotted_ip(ip)) {
		/* If it's not a valid ip, don't even make the request. */
		callback(-1, client_data, ip, NULL);
		return(-1);
	}

	/* Ok, see if we have it in our host cache. */
	for (i = 0; i < nhosts; i++) {
		if (!egg_strcasecmp(hosts[i].ip, ip)) {
			dns_answer_t answer;

			answer_init(&answer);
			answer_add(&answer, hosts[i].host);
			callback(-1, client_data, ip, answer.list);
			answer_free(&answer);
			return(-1);
		}
	}

	cache_id = cache_find(ip);
        if (cache_id >= 0) {
		shuffleArray(cache[cache_id].answer.list, cache[cache_id].answer.len);
		callback(-1, client_data, ip, cache[cache_id].answer.list);
		return(-1);
	}

	/* check if the query was already made */
        if (find_query(ip))
          return(-1);

	q = alloc_query(client_data, callback, ip);

	/* We need to transform the ip address into the proper form
	 * for reverse lookup. */
	if (strchr(ip, ':')) {
		char temp[128] = "";

		socket_ipv6_to_dots(ip, temp);
sdprintf("dots: %s", temp);
		size_t iplen = strlen(temp) + 9 + 1;
		q->ip = (char *) my_calloc(1, iplen);
//		reverse_ip(temp, q->ip);
		strlcat(q->ip, temp, iplen);
		strlcat(q->ip, "ip6.arpa", iplen);
sdprintf("reversed ipv6 ip: %s", q->ip);
	}
	else {
		size_t iplen = strlen(ip) + 13 + 1;
		q->ip = (char *) my_calloc(1, iplen);
		reverse_ip(ip, q->ip);
		strlcat(q->ip, ".in-addr.arpa", iplen);
	}

        dns_send_query(q);

//	/* setup timer to detect dead ns */
//	dns_create_timeout_timer(&q, ip, timeout);

	return(q->id);
}
示例#3
0
文件: dns.c 项目: AmesianX/WinQEMU
/**
 * DNS: For given URL retrieves IPv4/IPv6 from DNS-server.
 *      <p>
 *      URL can be given in one of the following form: <ul>
 *      <li> scheme with full path with (without) user and password
 *           <br>(e.g. "http://*****:*****@www.host.org/url-path");
 *      <li> host name with url-path
 *           <br>(e.g. "www.host.org/url-path");
 *      <li> nothing but host name
 *           <br>(e.g. "www.host.org");
 *      </ul>
 *
 * @param  fd        socket descriptor
 * @param  url       the URL to be resolved
 * @param  domain_ip In case of SUCCESS stores extracted IP.
 *                   In case of FAULT stores zeros (0.0.0.0).
 * @return           TRUE - IP successfuly retrieved;
 *                   FALSE - error condition occurs.
 */
int8_t
dns_get_ip(int fd, int8_t * url, uint8_t * domain_ip, uint8_t ip_version)
{
	/* this counter is used so that we abort after 30 DNS request */
	int32_t i;
	/* this buffer stores host name retrieved from url */
	static int8_t host_name[0x100];

	(* domain_ip) = 0;

	// Retrieve host name from URL
	if (!urltohost((char *) url, (char *) host_name)) {
		printf("\nERROR:\t\t\tBad URL!\n");
		return 0;
	}

	// Reformat host name into a series of labels
	if (!hosttodomain((char *) host_name, (char *) dns_domain_name)) {
		printf("\nERROR:\t\t\tBad host name!\n");
		return 0;
	}

	// Check if DNS server is presented and accessible
	if (dns_server_ip == 0) {
		printf("\nERROR:\t\t\tCan't resolve domain name "
		       "(DNS server is not presented)!\n");
		return 0;
	}

	// Use DNS-server to obtain IP
	if (ip_version == 6)
		memset(dns_result_ipv6, 0, 16);
	else
		dns_result_ip = 0;
	dns_error = 0;
	strcpy((char *) dns_domain_cname, "");

	for(i = 0; i < 30; ++i) {
		// Use canonical name in case we obtained it
		if (strlen((char *) dns_domain_cname))
			dns_send_query(fd, dns_domain_cname, ip_version);
		else
			dns_send_query(fd, dns_domain_name, ip_version);

		// setting up a timer with a timeout of one seconds
		set_timer(TICKS_SEC);
		do {
			receive_ether(fd);
			if (dns_error)
				return 0; // FALSE - error
			if ((dns_result_ip != 0) && (ip_version == 4)) {
				memcpy(domain_ip, &dns_result_ip, 4);
				return 1; // TRUE - success (domain IP retrieved)
			}
			else if ((dns_result_ipv6[0] != 0) && (ip_version == 6)) {
				memcpy(domain_ip, dns_result_ipv6, 16);
				return 1; // TRUE - success (domain IP retrieved)
			}
		} while (get_timer() > 0);
	}

	printf("\nGiving up after %d DNS requests\n", i);
	return 0; // FALSE - domain name wasn't retrieved
}