getdns_return_t getdns_pubkey_pinset_sanity_check( const getdns_list* pinset, getdns_list* errorlist) { size_t errorcount = 0, preverrs = 0, pins = 0, i; getdns_bindata err; getdns_dict * pin; getdns_bindata * data; if (errorlist) if (getdns_list_get_length(errorlist, &preverrs)) return GETDNS_RETURN_INVALID_PARAMETER; if (getdns_list_get_length(pinset, &pins)) PKP_SC_HARDERR("Can't get length of pinset", GETDNS_RETURN_INVALID_PARAMETER); if (pins < 2) PKP_SC_ERR("This pinset has fewer than 2 pins"); for (i = 0; i < pins; i++) { /* is it a dict? */ if (getdns_list_get_dict(pinset, i, &pin)) { PKP_SC_ERR("Could not retrieve a pin"); } else { /* does the pin have the right digest type? */ if (getdns_dict_get_bindata(pin, "digest", &data)) { PKP_SC_ERR("Pin has no 'digest' entry"); } else { if (data->size != sha256.size || memcmp(data->data, sha256.data, sha256.size)) PKP_SC_ERR("Pin has 'digest' other than sha256"); } /* if it does, is the value the right length? */ if (getdns_dict_get_bindata(pin, "value", &data)) { PKP_SC_ERR("Pin has no 'value' entry"); } else { if (data->size != SHA256_DIGEST_LENGTH) PKP_SC_ERR("Pin has the wrong size 'value' (should be 32 octets for sha256)"); } /* should we choke if it has some other key? for * extensibility, we will not treat this as an * error.*/ } } if (errorcount > 0) return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GOOD; }
getdns_list* GNUtil::convertToList(Local<Array> array) { uint32_t len = array->Length(); getdns_list* result = getdns_list_create(); for (uint32_t i = 0; i < len; ++i) { size_t idx = getdns_list_get_length(result, &idx); Local<Value> val = array->Get(i); GetdnsType type = getGetdnsType(val); switch (type) { case IntType: getdns_list_set_int(result, idx, val->ToUint32()->Value()); break; case BoolType: if (val->IsTrue()) { getdns_list_set_int(result, idx, GETDNS_EXTENSION_TRUE); } else { getdns_list_set_int(result, idx, GETDNS_EXTENSION_FALSE); } break; case StringType: { struct getdns_bindata strdata; String::Utf8Value utf8Str(val->ToString()); int len = utf8Str.length(); strdata.data = (uint8_t*) *utf8Str; strdata.size = len; getdns_list_set_bindata(result, idx, &strdata); } break; case BinDataType: { struct getdns_bindata bdata; bdata.data = (uint8_t*) node::Buffer::Data(val); bdata.size = node::Buffer::Length(val); getdns_list_set_bindata(result, idx, &bdata); } break; case ListType: { Local<Array> subArray = Local<Array>::Cast(val); struct getdns_list* sublist = GNUtil::convertToList(subArray); getdns_list_set_list(result, idx, sublist); getdns_list_destroy(sublist); } break; case DictType: { Local<Object> subObj = val->ToObject(); struct getdns_dict* subdict = GNUtil::convertToDict(subObj); if (subdict) { getdns_list_set_dict(result, idx, subdict); getdns_dict_destroy(subdict); } } break; default: break; } } return result; }
Local<Value> GNUtil::convertToJSObj(struct getdns_dict* dict) { if (!dict) { return Nan::Null(); } // try it as an IP char* ipStr = getdns_dict_to_ip_string(dict); if (ipStr) { Local<Value> result = Nan::New<String>(ipStr).ToLocalChecked(); free(ipStr); return result; } getdns_list* names; getdns_dict_get_names(dict, &names); size_t len = 0; Local<Object> result = Nan::New<Object>(); getdns_list_get_length(names, &len); for (size_t i = 0; i < len; ++i) { getdns_bindata* nameBin; getdns_list_get_bindata(names, i, &nameBin); Local<Value> name = Nan::New<String>((char*) nameBin->data).ToLocalChecked(); getdns_data_type type; getdns_dict_get_data_type(dict, (char*)nameBin->data, &type); switch (type) { case t_bindata: { getdns_bindata* data = NULL; getdns_dict_get_bindata(dict, (char*)nameBin->data, &data); result->Set(name, convertBinData(data, (char*) nameBin->data)); break; } case t_int: { uint32_t res = 0; getdns_dict_get_int(dict, (char*)nameBin->data, &res); result->Set(name, Nan::New<Integer>(res)); break; } case t_dict: { getdns_dict* subdict = NULL; getdns_dict_get_dict(dict, (char*)nameBin->data, &subdict); result->Set(name, GNUtil::convertToJSObj(subdict)); break; } case t_list: { getdns_list* list = NULL; getdns_dict_get_list(dict, (char*)nameBin->data, &list); result->Set(name, GNUtil::convertToJSArray(list)); break; } default: break; } } getdns_list_destroy(names); return result; }
/* * assert_ptr_in_answer asserts that a PTR record was * returned in the answer sections. */ void assert_ptr_in_answer(struct extracted_response *ex_response) { uint32_t ancount; size_t length; struct getdns_dict *rr_dict; uint32_t type; uint32_t ptr_records = 0; size_t i; ASSERT_RC(getdns_dict_get_int(ex_response->header, "ancount", &ancount), GETDNS_RETURN_GOOD, "Failed to extract \"nscount\""); ck_assert_msg(ancount >= 1, "Expected ancount >= 1, got %d", ancount); ASSERT_RC(getdns_list_get_length(ex_response->answer, &length), GETDNS_RETURN_GOOD, "Failed to extract \"answer\" length"); ck_assert_msg(length == ancount, "Expected \"answer\" length == ancount: %d, got %d", ancount, length); for(i = 0; i < length; i++) { ASSERT_RC(getdns_list_get_dict(ex_response->answer, i, &rr_dict), GETDNS_RETURN_GOOD, "Failed to extract \"answer\" record"); ASSERT_RC(getdns_dict_get_int(rr_dict, "type", &type), GETDNS_RETURN_GOOD, "Failed to extract \"type\" from answer record"); if(type == GETDNS_RRTYPE_PTR) ptr_records++; } ck_assert_msg(ptr_records == 1, "Expected to find one PTR record in answer section, got %d", ptr_records); }
/* * assert_soa_in_authority asserts that a SOA record was * returned in the authority sections. */ void assert_soa_in_authority(struct extracted_response *ex_response) { uint32_t nscount; size_t length; struct getdns_dict *rr_dict; uint32_t type; uint32_t soa_records = 0; size_t i; ASSERT_RC(getdns_dict_get_int(ex_response->header, "nscount", &nscount), GETDNS_RETURN_GOOD, "Failed to extract \"nscount\""); ck_assert_msg(nscount >= 1, "Expected nscount >= 1, got %d", nscount); ASSERT_RC(getdns_list_get_length(ex_response->authority, &length), GETDNS_RETURN_GOOD, "Failed to extract \"authority\" length"); ck_assert_msg(length == nscount, "Expected \"authority\" length == nscount: %d, got %d", nscount, length); for(i = 0; i < length; i++) { ASSERT_RC(getdns_list_get_dict(ex_response->authority, i, &rr_dict), GETDNS_RETURN_GOOD, "Failed to extract \"authority\" record"); ASSERT_RC(getdns_dict_get_int(rr_dict, "type", &type), GETDNS_RETURN_GOOD, "Failed to extract \"type\" from authority record"); if(type == GETDNS_RRTYPE_SOA) soa_records++; } ck_assert_msg(soa_records == 1, "Expected to find one SOA record in authority section, got %d", soa_records); }
getdns_return_t _getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list, struct mem_funcs *mf, sha256_pin_t **pinset_out) { getdns_return_t r; size_t pins, i; sha256_pin_t *out = NULL, *onext = NULL; getdns_dict * pin; getdns_bindata * data = NULL; if (r = getdns_list_get_length(pinset_list, &pins), r) return r; for (i = 0; i < pins; i++) { if (r = getdns_list_get_dict(pinset_list, i, &pin), r) goto fail; /* does the pin have the right digest type? */ if (r = getdns_dict_get_bindata(pin, "digest", &data), r) goto fail; if (data->size != sha256.size || memcmp(data->data, sha256.data, sha256.size)) { r = GETDNS_RETURN_INVALID_PARAMETER; goto fail; } /* if it does, is the value the right length? */ if (r = getdns_dict_get_bindata(pin, "value", &data), r) goto fail; if (data->size != SHA256_DIGEST_LENGTH) { r = GETDNS_RETURN_INVALID_PARAMETER; goto fail; } /* make a new pin */ onext = GETDNS_MALLOC(*mf, sha256_pin_t); if (onext == NULL) { r = GETDNS_RETURN_MEMORY_ERROR; goto fail; } onext->next = out; memcpy(onext->pin, data->data, SHA256_DIGEST_LENGTH); out = onext; } *pinset_out = out; return GETDNS_RETURN_GOOD; fail: while (out) { onext = out->next; GETDNS_FREE(*mf, out); out = onext; } return r; }
/* * assert_nodata asserts that ancount in the header and the * of the answer section (list) are both zero. */ void assert_nodata(struct extracted_response *ex_response) { uint32_t ancount; size_t length; ASSERT_RC(getdns_dict_get_int(ex_response->header, "ancount", &ancount), GETDNS_RETURN_GOOD, "Failed to extract \"ancount\""); ck_assert_msg(ancount == 0, "Expected ancount == 0, got %d", ancount); ASSERT_RC(getdns_list_get_length(ex_response->answer, &length), GETDNS_RETURN_GOOD, "Failed to extract \"answer\" length"); ck_assert_msg(length == 0, "Expected \"answer\" length == 0, got %d", length); }
Local<Value> GNUtil::convertToJSArray(struct getdns_list* list) { if (!list) { return Nan::Null(); } size_t len; getdns_list_get_length(list, &len); Local<Array> array = Nan::New<Array>(); for (size_t i = 0; i < len; ++i) { getdns_data_type type; getdns_list_get_data_type(list, i, &type); switch (type) { case t_bindata: { getdns_bindata* data = NULL; getdns_list_get_bindata(list, i, &data); array->Set(i, convertBinData(data, NULL)); break; } case t_int: { uint32_t res = 0; getdns_list_get_int(list, i, &res); array->Set(i, Nan::New<Integer>(res)); break; } case t_dict: { getdns_dict* dict = NULL; getdns_list_get_dict(list, i, &dict); array->Set(i, GNUtil::convertToJSObj(dict)); break; } case t_list: { getdns_list* sublist = NULL; getdns_list_get_list(list, i, &sublist); array->Set(i, GNUtil::convertToJSArray(sublist)); break; } default: break; } } return array; }
/* * assert_address_records_in_answer asserts that ancount in the header * is >= 1, ancount is equal to the length of "answer", and that all of * the records in the answer section are A and/or AAAA resource records * based on the value of the a/aaaa arguments. */ void assert_address_in_answer(struct extracted_response *ex_response, int a, int aaaa) { uint32_t ancount; size_t length; struct getdns_dict *rr_dict; uint32_t type; uint32_t address_records = 0; size_t i; ASSERT_RC(getdns_dict_get_int(ex_response->header, "ancount", &ancount), GETDNS_RETURN_GOOD, "Failed to extract \"ancount\""); ck_assert_msg(ancount >= 1, "Expected ancount >= 1, got %d", ancount); ASSERT_RC(getdns_list_get_length(ex_response->answer, &length), GETDNS_RETURN_GOOD, "Failed to extract \"answer\" length"); ck_assert_msg(length == ancount, "Expected \"answer\" length == ancount: %d, got %d", ancount, length); for(i = 0; i < length; i++) { ASSERT_RC(getdns_list_get_dict(ex_response->answer, i, &rr_dict), GETDNS_RETURN_GOOD, "Failed to extract \"answer\" record"); ASSERT_RC(getdns_dict_get_int(rr_dict, "type", &type), GETDNS_RETURN_GOOD, "Failed to extract \"type\" from answer record"); switch (type) { case GETDNS_RRTYPE_A: if(a && type == GETDNS_RRTYPE_A) address_records++; case GETDNS_RRTYPE_AAAA: if(aaaa && type == GETDNS_RRTYPE_AAAA) address_records++; } } ck_assert_msg(ancount == address_records, "ancount: %d address records mismatch: %d", ancount, address_records); }
/* 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); }
/*---------------------------------------- getkeyviadane fetch the smime/a key identified by the encoded keyid and host name populate *certtxt with the key record, caller must free certtxt */ void getkeyviadane(char *dname, int rrtype, char **certtxt) { int i; uint32_t status; size_t nans; size_t numrrs; int rrnum; char getdnserr[MAX_ERROR_STRING+1]; uint32_t recrrtype; getdns_return_t getdnsret; getdns_context *getdnsctx = NULL; getdns_dict *getdnsrsp = NULL; getdns_dict *dnsrec = NULL; getdns_dict *rr = NULL; getdns_dict *rrdata = NULL; getdns_list *dnsreplytree = NULL; getdns_list *dnsans = NULL; getdns_bindata *rawrdata = NULL; *certtxt = NULL; // create the context for DNS resolution using local OS system settings getdnsret = getdns_context_create(&getdnsctx, 1); if(getdnsret != GETDNS_RETURN_GOOD) { getdns_strerror(getdnsret, getdnserr, MAX_ERROR_STRING); fprintf(stderr, "error creating getdns context, %d, %s\n" , getdnsret, getdnserr); return; } // getdns_context_set_resolution_type(getdnsctx, GETDNS_RESOLUTION_STUB); // perform the DNS resolution request getdnsret = getdns_general_sync(getdnsctx, dname, rrtype, NULL, &getdnsrsp); if(getdnsret != GETDNS_RETURN_GOOD) { getdns_strerror(getdnsret, getdnserr, MAX_ERROR_STRING); fprintf(stderr, "DNS request failed, %d, %s\n", getdnsret, getdnserr); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } // sanity check the result of the query getdnsret = getdns_dict_get_int(getdnsrsp, (char *) "status", &status); if(getdnsret != GETDNS_RETURN_GOOD || status != GETDNS_RESPSTATUS_GOOD) { fprintf(stderr, "DNS request did not return results\n"); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } getdnsret = getdns_dict_get_list(getdnsrsp, (char *)"replies_tree", &dnsreplytree); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "DNS reply tree empty\n"); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } nans = 0; getdns_list_get_length(dnsreplytree, &nans); for(i=0; i<nans && *certtxt == NULL; i++) { // extract a record from the reply tree, extract answer from that record getdns_list_get_dict(dnsreplytree, i, &dnsrec); getdnsret = getdns_dict_get_list(dnsrec, (char *)"answer", &dnsans); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "answer missing from DNS reply tree, exiting\n"); exit(1); } // walk the RRs in the DNS answer getdns_list_get_length(dnsans, &numrrs); for(rrnum=0; rrnum < numrrs && *certtxt == NULL; rrnum++) { getdns_list_get_dict(dnsans, rrnum, &rr); recrrtype = 0; getdns_dict_get_int(rr, (char *)"type", &recrrtype); if(recrrtype == rrtype) { getdns_dict_get_dict(rr, (char *)"rdata", &rrdata); getdnsret = getdns_dict_get_bindata(rrdata, (char *)"rdata_raw" , &rawrdata); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "error, rdata missing address\n"); } else { *certtxt = (char *) malloc(rawrdata->size + 1); memcpy(*certtxt, rawrdata->data, rawrdata->size); *certtxt[rawrdata->size] = '\0'; } } } // for rrnum } // for i in nans getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } // getkeyviadane
int main(int argc, char *argv[]) { char *name = "getdnsapi.net"; getdns_context *context; getdns_return_t ret; getdns_dict *extensions; getdns_dict *response; uint32_t status; uint32_t dnssec_status; uint32_t type; getdns_list *replies_tree; size_t nanswers; int i; char element[MAXELEM]; if (argc > 1) name = argv[1]; if ((ret = getdns_context_create(&context, 1)) != GETDNS_RETURN_GOOD) { fprintf(stderr, "getdns_context_create: %s\n", getdns_get_errorstr_by_id(ret)); return 1; } extensions = getdns_dict_create(); if ((ret = getdns_dict_set_int(extensions, "/dnssec_return_status", GETDNS_EXTENSION_TRUE)) != GETDNS_RETURN_GOOD) { fprintf(stderr, "getdns_dict_set_int(dnssec_return_status): %s\n", getdns_get_errorstr_by_id(ret)); return 1; } if ((ret = getdns_address_sync(context, name, extensions, &response)) != GETDNS_RETURN_GOOD) { fprintf(stderr, "getdns_address_sync: %s\n", getdns_get_errorstr_by_id(ret)); return 1; } (void)getdns_dict_get_int(response, "status", &status); if (status != GETDNS_RESPSTATUS_GOOD) { printf("Bad status: "); switch (status) { case GETDNS_RESPSTATUS_NO_NAME: printf("GETDNS_RESPSTATUS_NO_NAME\n"); break; case GETDNS_RESPSTATUS_ALL_TIMEOUT: printf("GETDNS_RESPSTATUS_ALL_TIMEOUT\n"); break; default: break; } } if ((ret = getdns_dict_get_list(response, "/replies_tree", &replies_tree)) != GETDNS_RETURN_GOOD) { fprintf(stderr, "getdns_dict_get_list(replies_tree): %s\n", getdns_get_errorstr_by_id(ret)); return 1; } (void)getdns_list_get_length(replies_tree, &nanswers); printf("%d answers\n", (int)nanswers); for ( i = 0 ; i < (int)nanswers ; i++ ) { snprintf(element, MAXELEM, "/replies_tree/%d/dnssec_status", i); (void)getdns_dict_get_int(response, element, &dnssec_status); snprintf(element, MAXELEM, "/replies_tree/%d/answer/0/type", i); (void)getdns_dict_get_int(response, element, &type); printf("dnssec_status for %s record: %s\n", address_type_to_string(type), dnssec_status_to_string(dnssec_status)); } /* * handy debugging tool - uncomment if wanted */ /* printf("%s\n", getdns_pretty_print_dict(response)); */ return 0; }
/** * test the create, destroy and allocation functions */ void tst_create(void) { char msg[TSTMSGBUF]; size_t index; int i; getdns_return_t retval; struct getdns_list *list = NULL; /* make sure we can do a simple create/destroy first */ tstmsg_case_begin("tst_create"); tstmsg_case_msg("getdns_list_create"); list = getdns_list_create(); if (list != NULL) { tstmsg_case_msg("getdns_list_destroy(list)"); getdns_list_destroy(list); } tstmsg_case_msg("getdns_list_destroy(NULL)"); getdns_list_destroy(NULL); /* add items until we force it to allocate more storage */ tstmsg_case_msg("getdns_list_set_int(list, i) past block size"); list = getdns_list_create(); for (i = 0; i < GETDNS_LIST_BLOCKSZ + 2; i++) { retval = getdns_list_set_int(list, i, i); if (retval != GETDNS_RETURN_GOOD) { snprintf(msg, sizeof(msg), "getdns_list_set_int,i=%d,retval = %d", i, retval); tstmsg_case_msg(msg); } } tstmsg_case_msg("getdns_list_get_length(list)"); retval = getdns_list_get_length(list, &index); snprintf(msg, sizeof(msg), "list length = %d", (int) index); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_length()"); retval = getdns_list_get_length(NULL, &index); snprintf(msg, sizeof(msg), "NUll, %i, retval = %d", (int)index, retval); tstmsg_case_msg(msg); retval = getdns_list_get_length(NULL, NULL); snprintf(msg, sizeof(msg), "NUll, NULL, retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_list_get_length(list, NULL); snprintf(msg, sizeof(msg), "list, NULL, retval = %d", retval); tstmsg_case_msg(msg); getdns_list_destroy(list); tstmsg_case_end(); return; } /* tst_create */
/** * exercise the getdns_dict_get_names function */ void tst_getnames(void) { size_t index; size_t llen; uint32_t ansint; int i; getdns_return_t result; getdns_data_type dtype; struct getdns_dict *dict = NULL; struct getdns_list *list = NULL; tstmsg_case_begin("tst_getnames"); dict = getdns_dict_create(); /* degenerative use cases */ tstmsg_case_msg("getdns_dict_get_names(NULL, &list)"); getdns_dict_get_names(NULL, &list); getdns_list_destroy(list); tstmsg_case_msg("getdns_dict_get_names(dict, NULL)"); getdns_dict_get_names(dict, NULL); tstmsg_case_msg ("getdns_dict_get_names(dict, &list), empty dictionary"); getdns_dict_get_names(dict, &list); getdns_list_destroy(list); /* legit use case, add items out of order to exercise tree */ /* TODO: add elements of type dict, bindata, list to the dict */ i = 0; getdns_dict_set_int(dict, "foo", i++); getdns_dict_set_int(dict, "bar", i++); getdns_dict_set_int(dict, "quz", i++); getdns_dict_set_int(dict, "alpha", i++); getdns_dict_get_names(dict, &list); result = getdns_list_get_length(list, &llen); if (result != GETDNS_RETURN_GOOD) { tstmsg_case_msg ("getdns_list_get_length failed, exiting"); return; } if (llen != i) { tstmsg_case_msg ("getdns_list_get_length returned unreasonable length, exiting"); return; } for (index = 0; index < llen; index++) { getdns_list_get_data_type(list, index, &dtype); printf(" list item %d: ", (int) index); switch (dtype) { case t_bindata: printf("NOTIMPLEMENTED"); break; case t_dict: printf("NOTIMPLEMENTED"); break; case t_int: getdns_list_get_int(list, index, &ansint); printf("t_int, value=%d\n", ansint); break; case t_list: printf("NOTIMPLEMENTED"); break; default: printf("data type invalid"); break; } } getdns_dict_destroy(dict); getdns_list_destroy(list); tstmsg_case_end(); } /* tst_getnames */