/*! \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; }
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; }