Example #1
0
/*! \brief Callback from ENUM lookup function */
static int enum_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
{
	struct enum_context *c = context;
	void *p = NULL;
	int res;

	res = parse_naptr((unsigned char *)c->dst, c->dstlen, c->tech, c->techlen, answer, len, (unsigned char *)c->naptrinput);

	if (res < 0) {
		ast_log(LOG_WARNING, "Failed to parse naptr\n");
		return -1;
	} else if ((res == 0) && !ast_strlen_zero(c->dst)) { /* ok, we got needed NAPTR */
		if (c->options & ENUMLOOKUP_OPTIONS_COUNT) { /* counting RRs */
			c->count++;
			snprintf(c->dst, c->dstlen, "%d", c->count);
		} else  {
			if ((p = ast_realloc(c->naptr_rrs, sizeof(*c->naptr_rrs) * (c->naptr_rrs_count + 1)))) {
				c->naptr_rrs = p;
				memcpy(&c->naptr_rrs[c->naptr_rrs_count].naptr, answer, sizeof(c->naptr_rrs->naptr));
				c->naptr_rrs[c->naptr_rrs_count].result = ast_strdup(c->dst);
				c->naptr_rrs[c->naptr_rrs_count].tech = ast_strdup(c->tech);
				c->naptr_rrs[c->naptr_rrs_count].sort_pos = c->naptr_rrs_count;
				c->naptr_rrs_count++;
			}
			c->dst[0] = 0;
		}
		return 0;
	}

	return 0;
}
switch_status_t ldns_lookup(const char *number, const char *root, char *server_name[ENUM_MAXNAMESERVERS] , enum_record_t **results)
{
	ldns_resolver *res = NULL;
	ldns_rdf *domain = NULL;
	ldns_pkt *p = NULL;
	ldns_rr_list *naptr = NULL;
	ldns_status s = LDNS_STATUS_ERR;
	ldns_rdf *serv_rdf;
	switch_status_t status = SWITCH_STATUS_FALSE;
	char *name = NULL;
	struct timeval to = { 0, 0};
	int inameserver = 0;
	int added_server = 0;

	if (!(name = reverse_number(number, root))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parse Error!\n");
		goto end;
	}
	
	if (!(domain = ldns_dname_new_frm_str(name))) {
		goto end;
	}
	
	if (server_name) {
		res = ldns_resolver_new();
		switch_assert(res);
		
		for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) {
			if ( server_name[inameserver] != NULL ) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding Nameserver [%s]\n", server_name[inameserver]);
				if ((serv_rdf = ldns_rdf_new_addr_frm_str( server_name[inameserver] ))) {
					s = ldns_resolver_push_nameserver(res, serv_rdf);
					ldns_rdf_deep_free(serv_rdf);
					added_server = 1;
				}
			} 
		}
	} 
	if (!added_server) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No Nameservers specified, using host default\n");
		/* create a new resolver from /etc/resolv.conf */
		s = ldns_resolver_new_frm_file(&res, NULL);
	}

	if (s != LDNS_STATUS_OK) {
		goto end;
	}

	to.tv_sec = globals.timeout / 1000;
	to.tv_usec = (globals.timeout % 1000) * 1000;

	ldns_resolver_set_timeout(res, to);
	ldns_resolver_set_retry(res, (uint8_t)globals.retries);
	ldns_resolver_set_random(res, globals.random);

	if ((p = ldns_resolver_query(res,
								 domain,
								 LDNS_RR_TYPE_NAPTR,
								 LDNS_RR_CLASS_IN,
								 LDNS_RD))) {
		/* retrieve the NAPTR records from the answer section of that
		 * packet
		 */

		if ((naptr = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NAPTR, LDNS_SECTION_ANSWER))) {
			size_t i;

			ldns_rr_list_sort(naptr); 

			for (i = 0; i < ldns_rr_list_rr_count(naptr); i++) {
				parse_naptr(ldns_rr_list_rr(naptr, i), number, results);
			}

			//ldns_rr_list_print(stdout, naptr);
			ldns_rr_list_deep_free(naptr);
			status = SWITCH_STATUS_SUCCESS;
		}
	}

 end:

	switch_safe_free(name);
	
	if (domain) {
		ldns_rdf_deep_free(domain);
	}

	if (p) {
		ldns_pkt_free(p);
	}

	if (res) {
		ldns_resolver_deep_free(res);
	}

	return status;
}
Example #3
0
dns_result ReadName(unsigned char *reader, size_t data_len, unsigned short type, unsigned char *dns,
    char *output_buf, size_t output_buf_size)
{
    if (type < 1 || type > 256)
    {
        return DNS_RESULT_ERR;
    }
    switch (type)
    {
    case T_A:
        return parse_ip(reader, output_buf, output_buf_size);
        break;
    case T_NS:
        // printf("datalen: %d", data_len);
        parse_ns(reader, (unsigned short)data_len, dns, output_buf, output_buf_size);
        break;
    case T_CNAME:
        parse_cname(reader, dns, output_buf, output_buf_size, data_len);
        break;
    case T_SOA:
        parse_soa(reader, (unsigned short)data_len, dns, output_buf, output_buf_size);
        break;
    case T_PTR:
        parse_ptr(reader, (unsigned short)data_len, dns, output_buf, output_buf_size);
        break;
    case T_HINFO:
        parse_hinfo(reader, (unsigned short)data_len, output_buf, output_buf_size);
        break;
    case T_MX:
        parse_mx(reader, (unsigned short)data_len, dns, output_buf, output_buf_size);
        break;
    case T_TXT:
        return parse_txt(reader, data_len, output_buf, output_buf_size);
        break;
    case T_RP:
        parse_rp(reader, dns, output_buf, output_buf_size, data_len);
        break;
    case T_AFSDB:
        parse_afsdb(reader, dns, output_buf, output_buf_size, data_len);
        break;
    case T_AAAA:
        parse_aaaa(reader, output_buf, output_buf_size);
        break;
    case T_LOC:
        parse_loc(reader, output_buf, output_buf_size);
        break;
    case T_SRV:
        parse_srv(reader, dns, output_buf, output_buf_size, data_len);
        break;
    case T_NAPTR:
        return parse_naptr(reader, (unsigned short)data_len, output_buf, output_buf_size);
        break;
    case T_RRSIG:
        parse_rrsig(reader, dns, (unsigned short)data_len, output_buf, output_buf_size);
        break;
    case T_NSEC:
        parse_nsec(reader, dns, output_buf, output_buf_size, data_len);
        break;
    case T_DNSKEY:
        parse_dnskey(reader, (unsigned short)data_len, output_buf, output_buf_size);
        break;
    default:
        parse_default(reader, (unsigned short)data_len, output_buf, output_buf_size);
        break;
    }
    return DNS_RESULT_OK;
}