static isc_result_t probe_name(struct probe_trans *trans, dns_rdatatype_t type) { isc_result_t result; struct probe_ns *pns; struct server *server; REQUIRE(trans->reqid == NULL); REQUIRE(type == dns_rdatatype_a || type == dns_rdatatype_aaaa); for (pns = trans->current_ns; pns != NULL; pns = ISC_LIST_NEXT(pns, link)) { for (server = ISC_LIST_HEAD(pns->servers); server != NULL; server = ISC_LIST_NEXT(server, link)) { if ((type == dns_rdatatype_a && server->result_a == none) || (type == dns_rdatatype_aaaa && server->result_aaaa == none)) { pns->current_server = server; goto found; } } } found: trans->current_ns = pns; if (pns == NULL) return (ISC_R_NOMORE); INSIST(pns->current_server != NULL); dns_message_reset(trans->qmessage, DNS_MESSAGE_INTENTRENDER); result = make_querymessage(trans->qmessage, trans->qname, type); if (result != ISC_R_SUCCESS) return (result); result = dns_client_startrequest(client, trans->qmessage, trans->rmessage, &pns->current_server->address, 0, DNS_MESSAGEPARSE_BESTEFFORT, NULL, 120, 0, 4, probe_task, request_done, trans, &trans->reqid); return (result); }
int main(int argc, char *argv[]) { int ch, i, gai_error; struct addrinfo hints, *res; isc_textregion_t tr; dns_client_t *client = NULL; isc_result_t result; isc_sockaddr_t sa; dns_message_t *qmessage, *rmessage; dns_rdatatype_t type = dns_rdatatype_a; isc_buffer_t *outputbuf; while ((ch = getopt(argc, argv, "t:")) != -1) { switch (ch) { case 't': tr.base = optarg; tr.length = strlen(optarg); result = dns_rdatatype_fromtext(&type, &tr); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid RRtype: %s\n", optarg); exit(1); } break; default: usage(); } } argc -= optind; argv += optind; if (argc < 2) usage(); isc_lib_register(); result = dns_lib_init(); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_lib_init failed: %d\n", result); exit(1); } result = dns_client_create(&client, 0); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_client_create failed: %d\n", result); exit(1); } /* Prepare message structures */ mctx = NULL; qmessage = NULL; rmessage = NULL; result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create a memory context\n"); exit(1); } result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &qmessage); if (result == ISC_R_SUCCESS) { result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rmessage); } if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create messages\n"); exit(1); } /* Initialize the nameserver address */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_NUMERICHOST; gai_error = getaddrinfo(argv[0], "53", &hints, &res); if (gai_error != 0) { fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(gai_error)); exit(1); } INSIST(res->ai_addrlen <= sizeof(sa.type)); memcpy(&sa.type, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); sa.length = res->ai_addrlen; ISC_LINK_INIT(&sa, link); /* Construct qname */ result = make_querymessage(qmessage, argv[1], type); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create a query\n"); exit(1); } /* Send request and wait for a response */ result = dns_client_request(client, qmessage, rmessage, &sa, 0, 0, NULL, 60, 0, 3); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to get a response: %s\n", dns_result_totext(result)); } /* Dump the response */ outputbuf = NULL; result = isc_buffer_allocate(mctx, &outputbuf, 65535); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to allocate a result buffer\n"); exit(1); } for (i = 0; i < DNS_SECTION_MAX; i++) { print_section(rmessage, i, outputbuf); isc_buffer_clear(outputbuf); } isc_buffer_free(&outputbuf); /* Cleanup */ dns_message_destroy(&qmessage); dns_message_destroy(&rmessage); isc_mem_destroy(&mctx); dns_client_destroy(&client); dns_lib_shutdown(); exit(0); }