/* more sophisticated functions */ ldns_resolver * ldns_resolver_new(void) { ldns_resolver *r; r = LDNS_MALLOC(ldns_resolver); if (!r) { return NULL; } r->_searchlist = NULL; r->_nameservers = NULL; r->_rtt = NULL; /* defaults are filled out */ ldns_resolver_set_searchlist_count(r, 0); ldns_resolver_set_nameserver_count(r, 0); ldns_resolver_set_usevc(r, 0); ldns_resolver_set_port(r, LDNS_PORT); ldns_resolver_set_domain(r, NULL); ldns_resolver_set_defnames(r, false); ldns_resolver_set_retry(r, 3); ldns_resolver_set_retrans(r, 2); ldns_resolver_set_fallback(r, true); ldns_resolver_set_fail(r, false); ldns_resolver_set_edns_udp_size(r, 0); ldns_resolver_set_dnssec(r, false); ldns_resolver_set_dnssec_cd(r, false); ldns_resolver_set_dnssec_anchors(r, NULL); ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY); ldns_resolver_set_igntc(r, false); ldns_resolver_set_recursive(r, false); ldns_resolver_set_dnsrch(r, true); /* randomize the nameserver to be queried * when there are multiple */ ldns_resolver_set_random(r, true); ldns_resolver_set_debug(r, 0); r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC; r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC; /* TODO: fd=0 is actually a valid socket (stdin), replace with -1 */ r->_socket = 0; r->_axfr_soa_count = 0; r->_axfr_i = 0; r->_cur_axfr_pkt = NULL; r->_tsig_keyname = NULL; r->_tsig_keydata = NULL; r->_tsig_algorithm = NULL; return r; }
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; }
int main(int argc, char *argv[]) { ldns_resolver *res; ldns_rdf *name; ldns_rdf *version, *id; ldns_pkt *p; ldns_rr_list *addr; ldns_rr_list *info; ldns_status s; ldns_rdf *pop; size_t i; if (argc != 2) { usage(stdout, argv[0]); exit(EXIT_FAILURE); } else { /* create a rdf from the command line arg */ name = ldns_dname_new_frm_str(argv[1]); if (!name) { usage(stdout, argv[0]); exit(EXIT_FAILURE); } } /* create rdf for what we are going to ask */ version = ldns_dname_new_frm_str("version.bind"); id = ldns_dname_new_frm_str("hostname.bind"); /* create a new resolver from /etc/resolv.conf */ s = ldns_resolver_new_frm_file(&res, NULL); if (s != LDNS_STATUS_OK) { ldns_rdf_deep_free(name); exit(EXIT_FAILURE); } ldns_resolver_set_retry(res, 1); /* don't want to wait too long */ /* use the resolver to send it a query for the a/aaaa of name */ addr = ldns_get_rr_list_addr_by_name(res, name, LDNS_RR_CLASS_IN, LDNS_RD); if (!addr) { fprintf(stderr, " *** could not get an address for %s\n", argv[1]); ldns_rdf_deep_free(name); ldns_resolver_deep_free(res); exit(EXIT_FAILURE); } /* remove current list of nameservers from resolver */ while((pop = ldns_resolver_pop_nameserver(res))) { ldns_rdf_deep_free(pop); } /* can be multihomed */ for(i = 0; i < ldns_rr_list_rr_count(addr); i++) { if (i > 0) { fprintf(stdout, "\n"); } if (ldns_resolver_push_nameserver_rr(res, ldns_rr_list_rr(addr, i)) != LDNS_STATUS_OK) { printf("Error adding nameserver to resolver\n"); } ldns_rr_print(stdout, ldns_rr_list_rr(addr, i)); fprintf(stdout, "\n"); p = ldns_resolver_query(res, version, LDNS_RR_TYPE_TXT, LDNS_RR_CLASS_CH, LDNS_RD); if (p) { ldns_pkt_print(stdout, p); info = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_TXT, LDNS_SECTION_ANSWER); if (info) { ldns_rr_list_print(stdout, info); ldns_rr_list_deep_free(info); } else { printf(" *** version retrieval failed\n"); } ldns_pkt_free(p); } else { printf(" *** query failed\n"); } p = ldns_resolver_query(res, id, LDNS_RR_TYPE_TXT, LDNS_RR_CLASS_CH, LDNS_RD); if (p) { info = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_TXT, LDNS_SECTION_ANSWER); if (info) { ldns_rr_list_print(stdout, info); ldns_rr_list_deep_free(info); } else { printf(" *** id retrieval failed\n"); } ldns_pkt_free(p); } else { printf(" *** query failed for\n"); } ldns_rdf_deep_free(ldns_resolver_pop_nameserver(res)); } ldns_rdf_deep_free(name); ldns_resolver_deep_free(res); exit(EXIT_SUCCESS); }