// Convert bindata into a good representational string or // into a buffer. Handles dname, printable, ".", // and an ip address if it is under a known key static Local<Value> convertBinData(getdns_bindata* data, const char* key) { bool printable = true; for (size_t i = 0; i < data->size; ++i) { if (!isprint(data->data[i])) { if (data->data[i] == 0 && i == data->size - 1) { break; } printable = false; break; } } // basic string? if (printable) { return Nan::New<String>( (char*) data->data, data->size ).ToLocalChecked(); // the root } else if (data->size == 1 && data->data[0] == 0) { return Nan::New<String>(".").ToLocalChecked(); // dname } else if (priv_getdns_bindata_is_dname(data)) { char* dname = NULL; if (getdns_convert_dns_name_to_fqdn(data, &dname) == GETDNS_RETURN_GOOD) { Local<Value> result = Nan::New<String>(dname).ToLocalChecked(); free(dname); return result; } // ip address } else if (key != NULL && (strcmp(key, "ipv4_address") == 0 || strcmp(key, "ipv6_address") == 0)) { char* ipStr = getdns_display_ip_address(data); if (ipStr) { Local<Value> result = Nan::New<String>(ipStr).ToLocalChecked(); free(ipStr); return result; } } // getting here implies we don't know how to convert it // to a string. return GNUtil::convertToBuffer(data->data, data->size); }
// potential helper to get the ip string of a dict char* getdns_dict_to_ip_string(getdns_dict* dict) { if (!dict) { return NULL; } getdns_bindata* data; getdns_return_t r; r = getdns_dict_get_bindata(dict, "address_type", &data); if (r != GETDNS_RETURN_GOOD) { return NULL; } if (data->size == 4 && (strcmp("IPv4", (char*) data->data) == 0 || strcmp("IPv6", (char*) data->data) == 0)) { r = getdns_dict_get_bindata(dict, "address_data", &data); if (r != GETDNS_RETURN_GOOD) { return NULL; } return getdns_display_ip_address(data); } return NULL; }
/* Set up the callback function, which will also do the processing of the results */ void callback(getdns_context *context, getdns_callback_type_t callback_type, getdns_dict *response, void *userarg, getdns_transaction_t transaction_id) { getdns_return_t r; /* Holder for all function returns */ getdns_list *replies_tree; size_t n_replies, i; (void) context; (void) userarg; /* unused parameters */ switch(callback_type) { case GETDNS_CALLBACK_CANCEL: printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); return; case GETDNS_CALLBACK_TIMEOUT: printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); return; case GETDNS_CALLBACK_ERROR: printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); return; default: break; } assert( callback_type == GETDNS_CALLBACK_COMPLETE ); if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree))) fprintf(stderr, "Could not get \"replies_tree\" from response"); else if ((r = getdns_list_get_length(replies_tree, &n_replies))) fprintf(stderr, "Could not get replies_tree\'s length"); else for (i = 0; i < n_replies && r == GETDNS_RETURN_GOOD; i++) { getdns_dict *reply; getdns_list *answer; size_t n_answers, j; if ((r = getdns_list_get_dict(replies_tree, i, &reply))) fprintf(stderr, "Could not get address %zu from just_address_answers", i); else if ((r = getdns_dict_get_list(reply, "answer", &answer))) fprintf(stderr, "Could not get \"address_data\" from address"); else if ((r = getdns_list_get_length(answer, &n_answers))) fprintf(stderr, "Could not get answer section\'s length"); else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) { getdns_dict *rr; getdns_bindata *address = NULL; if ((r = getdns_list_get_dict(answer, j, &rr))) fprintf(stderr, "Could net get rr %zu from answer section", j); else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD) printf("The IPv4 address is "); else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD) printf("The IPv6 address is "); if (address) { char *address_str; if (!(address_str = getdns_display_ip_address(address))) { fprintf(stderr, "Could not convert second address to string"); r = GETDNS_RETURN_MEMORY_ERROR; break; } printf("%s\n", address_str); free(address_str); } } } if (r) { assert( r != GETDNS_RETURN_GOOD ); fprintf(stderr, ": %d\n", r); } getdns_dict_destroy(response); }