static inline isc_result_t totext_sig(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("4294967295")]; dns_rdatatype_t covered; unsigned long ttl; unsigned long when; unsigned long exp; unsigned long foot; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == 24); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * XXXAG We should have something like dns_rdatatype_isknown() * that does the right thing with type 0. */ if (dns_rdatatype_isknown(covered) && covered != 0) { RETERR(dns_rdatatype_totext(covered, target)); } else { char buf[sizeof("65535")]; sprintf(buf, "%u", covered); RETERR(str_totext(buf, target)); } RETERR(str_totext(" ", target)); /* * Algorithm. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Labels. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Ttl. */ ttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu", ttl); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Sig exp. */ exp = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(exp, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); /* * Time signed. */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* * Footprint. */ foot = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", foot); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Signer. */ dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); /* * Sig. */ RETERR(str_totext(tctx->linebreak, target)); RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t totext_hip(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; unsigned int length, key_len, hit_len; unsigned char algorithm; char buf[sizeof("225 ")]; REQUIRE(rdata->type == dns_rdatatype_hip); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, ®ion); hit_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); key_len = uint16_fromregion(®ion); isc_region_consume(®ion, 2); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); /* * Algorithm */ sprintf(buf, "%u ", algorithm); RETERR(str_totext(buf, target)); /* * HIT. */ INSIST(hit_len < region.length); length = region.length; region.length = hit_len; RETERR(isc_hex_totext(®ion, 1, "", target)); region.length = length - hit_len; RETERR(str_totext(tctx->linebreak, target)); /* * Public KEY. */ INSIST(key_len <= region.length); length = region.length; region.length = key_len; RETERR(isc_base64_totext(®ion, 1, "", target)); region.length = length - key_len; RETERR(str_totext(tctx->linebreak, target)); /* * Rendezvous Servers. */ dns_name_init(&name, NULL); while (region.length > 0) { dns_name_fromregion(&name, ®ion); RETERR(dns_name_totext(&name, ISC_FALSE, target)); isc_region_consume(®ion, name.length); if (region.length > 0) RETERR(str_totext(tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
int main(int argc, char *argv[]) { char s[1000]; isc_result_t result; dns_fixedname_t wname, wname2, oname, compname, downname; isc_buffer_t source; isc_region_t r; dns_name_t *name, *origin, *comp, *down; isc_boolean_t downcase = ISC_FALSE; size_t len; isc_boolean_t quiet = ISC_FALSE; isc_boolean_t concatenate = ISC_FALSE; isc_boolean_t got_name = ISC_FALSE; isc_boolean_t check_absolute = ISC_FALSE; isc_boolean_t check_wildcard = ISC_FALSE; isc_boolean_t test_downcase = ISC_FALSE; isc_boolean_t inplace = ISC_FALSE; isc_boolean_t want_split = ISC_FALSE; unsigned int labels, split_label = 0; dns_fixedname_t fprefix, fsuffix; dns_name_t *prefix, *suffix; int ch; while ((ch = isc_commandline_parse(argc, argv, "acdiqs:w")) != -1) { switch (ch) { case 'a': check_absolute = ISC_TRUE; break; case 'c': concatenate = ISC_TRUE; break; case 'd': test_downcase = ISC_TRUE; break; case 'i': inplace = ISC_TRUE; break; case 'q': quiet = ISC_TRUE; break; case 's': want_split = ISC_TRUE; split_label = atoi(isc_commandline_argument); break; case 'w': check_wildcard = ISC_TRUE; break; } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc > 0) { if (strcasecmp("none", argv[0]) == 0) origin = NULL; else { len = strlen(argv[0]); isc_buffer_init(&source, argv[0], len); isc_buffer_add(&source, len); dns_fixedname_init(&oname); origin = &oname.name; result = dns_name_fromtext(origin, &source, dns_rootname, ISC_FALSE, NULL); if (result != 0) { fprintf(stderr, "dns_name_fromtext() failed: %d\n", result); exit(1); } } } else if (concatenate) origin = NULL; else origin = dns_rootname; if (argc >= 1) { if (strcasecmp("none", argv[1]) == 0) comp = NULL; else { len = strlen(argv[1]); isc_buffer_init(&source, argv[1], len); isc_buffer_add(&source, len); dns_fixedname_init(&compname); comp = &compname.name; result = dns_name_fromtext(comp, &source, origin, ISC_FALSE, NULL); if (result != 0) { fprintf(stderr, "dns_name_fromtext() failed: %d\n", result); exit(1); } } } else comp = NULL; dns_fixedname_init(&wname); name = dns_fixedname_name(&wname); dns_fixedname_init(&wname2); while (fgets(s, sizeof(s), stdin) != NULL) { len = strlen(s); if (len > 0U && s[len - 1] == '\n') { s[len - 1] = '\0'; len--; } isc_buffer_init(&source, s, len); isc_buffer_add(&source, len); if (len > 0U) result = dns_name_fromtext(name, &source, origin, downcase, NULL); else { if (name == dns_fixedname_name(&wname)) dns_fixedname_init(&wname); else dns_fixedname_init(&wname2); result = ISC_R_SUCCESS; } if (result != ISC_R_SUCCESS) { printf("%s\n", dns_result_totext(result)); if (name == dns_fixedname_name(&wname)) dns_fixedname_init(&wname); else dns_fixedname_init(&wname2); continue; } if (check_absolute && dns_name_countlabels(name) > 0) { if (dns_name_isabsolute(name)) printf("absolute\n"); else printf("relative\n"); } if (check_wildcard && dns_name_countlabels(name) > 0) { if (dns_name_iswildcard(name)) printf("wildcard\n"); else printf("not wildcard\n"); } dns_name_toregion(name, &r); if (!quiet) { print_wirename(&r); printf("%u labels, %u bytes.\n", dns_name_countlabels(name), r.length); } if (concatenate) { if (got_name) { printf("Concatenating.\n"); result = dns_name_concatenate(&wname.name, &wname2.name, &wname2.name, NULL); name = &wname2.name; if (result == ISC_R_SUCCESS) { if (check_absolute && dns_name_countlabels(name) > 0) { if (dns_name_isabsolute(name)) printf("absolute\n"); else printf("relative\n"); } if (check_wildcard && dns_name_countlabels(name) > 0) { if (dns_name_iswildcard(name)) printf("wildcard\n"); else printf("not " "wildcard\n"); } dns_name_toregion(name, &r); if (!quiet) { print_wirename(&r); printf("%u labels, " "%u bytes.\n", dns_name_countlabels(name), r.length); } } else printf("%s\n", dns_result_totext(result)); got_name = ISC_FALSE; } else got_name = ISC_TRUE; } isc_buffer_init(&source, s, sizeof(s)); if (dns_name_countlabels(name) > 0) result = dns_name_totext(name, ISC_FALSE, &source); else result = ISC_R_SUCCESS; if (result == ISC_R_SUCCESS) { isc_buffer_usedregion(&source, &r); if (r.length > 0) printf("%.*s\n", (int)r.length, r.base); else printf("<empty text name>\n"); if (!quiet) { printf("%u bytes.\n", source.used); } } else printf("%s\n", dns_result_totext(result)); if (test_downcase) { if (inplace) { down = name; } else { dns_fixedname_init(&downname); down = dns_fixedname_name(&downname); } result = dns_name_downcase(name, down, NULL); INSIST(result == ISC_R_SUCCESS); if (!quiet) { dns_name_toregion(down, &r); print_wirename(&r); printf("%u labels, %u bytes.\n", dns_name_countlabels(down), r.length); } isc_buffer_init(&source, s, sizeof(s)); print_name(down); } if (comp != NULL && dns_name_countlabels(name) > 0) { int order; unsigned int nlabels; dns_namereln_t namereln; namereln = dns_name_fullcompare(name, comp, &order, &nlabels); if (!quiet) { if (order < 0) printf("<"); else if (order > 0) printf(">"); else printf("="); switch (namereln) { case dns_namereln_contains: printf(", contains"); break; case dns_namereln_subdomain: printf(", subdomain"); break; case dns_namereln_commonancestor: printf(", common ancestor"); break; default: break; } if (namereln != dns_namereln_none && namereln != dns_namereln_equal) printf(", nlabels = %u", nlabels); printf("\n"); } printf("dns_name_equal() returns %s\n", dns_name_equal(name, comp) ? "TRUE" : "FALSE"); } labels = dns_name_countlabels(name); if (want_split && split_label < labels) { dns_fixedname_init(&fprefix); prefix = dns_fixedname_name(&fprefix); dns_fixedname_init(&fsuffix); suffix = dns_fixedname_name(&fsuffix); printf("splitting at label %u: ", split_label); dns_name_split(name, split_label, prefix, suffix); printf("\n prefix = "); print_name(prefix); printf(" suffix = "); print_name(suffix); } if (concatenate) { if (got_name) name = &wname2.name; else name = &wname.name; } } return (0); }
static inline isc_result_t totext_soa(ARGS_TOTEXT) { isc_region_t dregion; dns_name_t mname; dns_name_t rname; dns_name_t prefix; isc_boolean_t sub; int i; isc_boolean_t multiline; isc_boolean_t comment; REQUIRE(rdata->type == 6); REQUIRE(rdata->length != 0); multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0); if (multiline) comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0); else comment = ISC_FALSE; dns_name_init(&mname, NULL); dns_name_init(&rname, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, &dregion); dns_name_fromregion(&mname, &dregion); isc_region_consume(&dregion, name_length(&mname)); dns_name_fromregion(&rname, &dregion); isc_region_consume(&dregion, name_length(&rname)); sub = name_prefix(&mname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); sub = name_prefix(&rname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); if (multiline) RETERR(str_totext(" (" , target)); RETERR(str_totext(tctx->linebreak, target)); for (i = 0; i < 5; i++) { unsigned long num; unsigned int len = target->used; num = uint32_fromregion(&dregion); isc_region_consume(&dregion, 4); if (i >= 1 && (tctx->flags & DNS_STYLEFLAG_TTL_UNITS) != 0) { RETERR(dns_ttl_totext(num, ISC_FALSE, target)); } else { char buf[12]; sprintf(buf, "%lu", num); RETERR(str_totext(buf, target)); } if (comment) { len = target->used - len; INSIST(len <= 10); /* "0123456789 ; " */ RETERR(str_totext(len+" ; ", target)); RETERR(str_totext(soa_fieldnames[i], target)); /* Print times in week/day/hour/minute/second form */ if (i >= 1) { RETERR(str_totext(" (", target)); RETERR(dns_ttl_totext(num, ISC_TRUE, target)); RETERR(str_totext(")", target)); } RETERR(str_totext(tctx->linebreak, target)); } else if (i < 4) { RETERR(str_totext(tctx->linebreak, target)); } } if (multiline) RETERR(str_totext(")", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t totext_ipseckey(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; char buf[sizeof("255 ")]; unsigned short num; unsigned short gateway; REQUIRE(rdata->type == 45); REQUIRE(rdata->length >= 3); dns_name_init(&name, NULL); if (rdata->data[1] > 3U) return (ISC_R_NOTIMPLEMENTED); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); /* * Precedence. */ dns_rdata_toregion(rdata, ®ion); num = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); /* * Gateway type. */ gateway = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", gateway); RETERR(str_totext(buf, target)); /* * Algorithm. */ num = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); /* * Gateway. */ switch (gateway) { case 0: RETERR(str_totext(".", target)); break; case 1: RETERR(inet_totext(AF_INET, ®ion, target)); isc_region_consume(®ion, 4); break; case 2: RETERR(inet_totext(AF_INET6, ®ion, target)); isc_region_consume(®ion, 16); break; case 3: dns_name_fromregion(&name, ®ion); RETERR(dns_name_totext(&name, ISC_FALSE, target)); isc_region_consume(®ion, name_length(&name)); break; } /* * Key. */ if (region.length > 0U) { RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(®ion, 60, "", target)); else RETERR(isc_base64_totext(®ion, tctx->width - 2, tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
static inline isc_result_t totext_soa(ARGS_TOTEXT) { isc_region_t dregion; dns_name_t mname; dns_name_t rname; dns_name_t prefix; isc_boolean_t sub; int i; isc_boolean_t multiline; isc_boolean_t comment; REQUIRE(rdata->type == 6); REQUIRE(rdata->length != 0); multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0); comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0); dns_name_init(&mname, NULL); dns_name_init(&rname, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, &dregion); dns_name_fromregion(&mname, &dregion); isc_region_consume(&dregion, name_length(&mname)); dns_name_fromregion(&rname, &dregion); isc_region_consume(&dregion, name_length(&rname)); sub = name_prefix(&mname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); sub = name_prefix(&rname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); if (multiline) RETERR(str_totext(" (" , target)); RETERR(str_totext(tctx->linebreak, target)); for (i = 0; i < 5; i++) { char buf[sizeof("2147483647")]; unsigned long num; int numlen; num = uint32_fromregion(&dregion); isc_region_consume(&dregion, 4); numlen = snprintf(buf, sizeof(buf), "%lu", num); INSIST(numlen != -1 && (size_t)numlen < sizeof(buf)); RETERR(str_totext(buf, target)); if (multiline && comment) { RETERR(str_totext(" ; " + (unsigned int)numlen, target)); RETERR(str_totext(soa_fieldnames[i], target)); /* Print times in week/day/hour/minute/second form */ if (i >= 1) { RETERR(str_totext(" (", target)); RETERR(dns_ttl_totext(num, ISC_TRUE, target)); RETERR(str_totext(")", target)); } RETERR(str_totext(tctx->linebreak, target)); } else if (i < 4) { RETERR(str_totext(tctx->linebreak, target)); } } if (multiline) RETERR(str_totext(")", target)); return (ISC_R_SUCCESS); }
/* * we asked for, and got a CNAME of some kind. */ static void process_step_cname(dnskey_glob *gs, dnskey_lookup *dl, struct rrsetinfo *ans, int success) { struct rdatainfo *ri; isc_region_t region; dns_rdata_t rd; dns_rdata_cname_t cn; char simplebuf[80]; isc_buffer_t *cname_text; char cname_buf[DNS_NAME_MAXTEXT]; /* char cname_buf2[DNS_NAME_MAXTEXT]; */ switch(success) { case ERRSET_NONAME: case ERRSET_NODATA: /* no, no CNAME found, thing isn't there */ snprintf(simplebuf, sizeof(simplebuf), "RR of type %s for %s was not found (tried CNAMEs)", dl->wantedtype_name, dl->fqdn); output_transaction_line(gs, dl->tracking_id, 0, "RETRY", simplebuf); dl->step = dkl_done; return; case 0: /* aha! found a CNAME */ break; default: fatal: /* some other error */ snprintf(simplebuf, sizeof(simplebuf), "err=%d", success); output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf); dl->step = dkl_done; return; } /* * now process out the CNAMEs, and look them up, one by one... * there should be only one... We just use the first one that works. */ if(ans->rri_flags & RRSET_VALIDATED) { output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "OKAY"); } else { output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "not present"); } if(ans->rri_nrdatas != 1) { /* we got a number of CNAMEs different from 1! */ success=0; snprintf(simplebuf, sizeof(simplebuf), "illegal number of CNAMES: %d", ans->rri_nrdatas); output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf); dl->step = dkl_done; return; } /* process first CNAME record */ ri= &ans->rri_rdatas[0]; memset(®ion, 0, sizeof(region)); memset(&rd, 0, sizeof(rd)); region.base = ri->rdi_data; region.length = ri->rdi_length; dns_rdata_fromregion(&rd, dns_rdataclass_in, dns_rdatatype_cname, ®ion); /* we set mctx to NULL, which means that the tenure for * the stuff pointed to by cn will persist only as long * as rd persists. */ if(dns_rdata_tostruct(&rd, &cn, NULL) != ISC_R_SUCCESS) { /* failed, try next return error */ success=0; goto fatal; } cname_text=NULL; if(isc_buffer_allocate(gs->iscmem, &cname_text, DNS_NAME_MAXTEXT)) { success=0; goto fatal; } if(dns_name_totext(&cn.cname, ISC_TRUE, cname_text) != ISC_R_SUCCESS) { success=0; goto fatal; } cname_buf[0]='\0'; strncat(cname_buf, isc_buffer_base(cname_text), isc_buffer_usedlength(cname_text)); /* free up buffer */ isc_buffer_free(&cname_text); { /* add a trailing . */ char *end; end = &cname_buf[strlen(cname_buf)]; if(*end != '.') { strncat(cname_buf, ".", sizeof(cname_buf)); } } /* format out a text version */ output_transaction_line(gs, dl->tracking_id, 0, "CNAME", cname_buf); output_transaction_line(gs, dl->tracking_id, 0, "CNAMEFROM", dl->fqdn); /* check for loops in the CNAMEs! */ if(dns_name_equal(&dl->last_cname, &cn.cname) == ISC_TRUE) { /* damn, we found a loop! */ dl->step = dkl_done; return; } /* send new request. */ /* okay, so look this new thing up */ success = lwres_getrrsetbyname_init(cname_buf, dns_rdataclass_in, dl->wantedtype, 0 /*flags*/, gs->lwctx, &dl->las); if(success != ERRSET_SUCCESS) { return; } lwres_getrrsetbyname_xmit(gs->lwctx, &dl->las); dl->step = dkl_second; }
static void emit(unsigned int dtype, isc_boolean_t showall, char *lookaside, dns_rdata_t *rdata) { isc_result_t result; unsigned char buf[DNS_DS_BUFFERSIZE]; char text_buf[DST_KEY_MAXTEXTSIZE]; char name_buf[DNS_NAME_MAXWIRE]; char class_buf[10]; isc_buffer_t textb, nameb, classb; isc_region_t r; dns_rdata_t ds; dns_rdata_dnskey_t dnskey; isc_buffer_init(&textb, text_buf, sizeof(text_buf)); isc_buffer_init(&nameb, name_buf, sizeof(name_buf)); isc_buffer_init(&classb, class_buf, sizeof(class_buf)); dns_rdata_init(&ds); result = dns_rdata_tostruct(rdata, &dnskey, NULL); if (result != ISC_R_SUCCESS) fatal("can't convert DNSKEY"); if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && !showall) return; result = dns_ds_buildrdata(name, rdata, dtype, buf, &ds); if (result != ISC_R_SUCCESS) fatal("can't build record"); result = dns_name_totext(name, ISC_FALSE, &nameb); if (result != ISC_R_SUCCESS) fatal("can't print name"); /* Add lookaside origin, if set */ if (lookaside != NULL) { if (isc_buffer_availablelength(&nameb) < strlen(lookaside)) fatal("DLV origin '%s' is too long", lookaside); isc_buffer_putstr(&nameb, lookaside); if (lookaside[strlen(lookaside) - 1] != '.') { if (isc_buffer_availablelength(&nameb) < 1) fatal("DLV origin '%s' is too long", lookaside); isc_buffer_putstr(&nameb, "."); } } result = dns_rdata_totext(&ds, (dns_name_t *) NULL, &textb); if (result != ISC_R_SUCCESS) fatal("can't print rdata"); result = dns_rdataclass_totext(rdclass, &classb); if (result != ISC_R_SUCCESS) fatal("can't print class"); isc_buffer_usedregion(&nameb, &r); printf("%.*s ", (int)r.length, r.base); isc_buffer_usedregion(&classb, &r); printf("%.*s", (int)r.length, r.base); if (lookaside == NULL) printf(" DS "); else printf(" DLV "); isc_buffer_usedregion(&textb, &r); printf("%.*s\n", (int)r.length, r.base); }
static void byaddr_done(isc_task_t *task, isc_event_t *event) { ns_lwdclient_t *client; ns_lwdclientmgr_t *cm; dns_byaddrevent_t *bevent; int lwres; lwres_buffer_t lwb; dns_name_t *name; isc_result_t result; lwres_result_t lwresult; isc_region_t r; isc_buffer_t b; lwres_gnbaresponse_t *gnba; isc_uint16_t naliases; UNUSED(task); lwb.base = NULL; client = event->ev_arg; cm = client->clientmgr; INSIST(client->byaddr == (dns_byaddr_t *)event->ev_sender); bevent = (dns_byaddrevent_t *)event; gnba = &client->gnba; ns_lwdclient_log(50, "byaddr event result = %s", isc_result_totext(bevent->result)); result = bevent->result; if (result != ISC_R_SUCCESS) { dns_byaddr_destroy(&client->byaddr); isc_event_free(&event); bevent = NULL; if (client->na.family != AF_INET6 || (client->options & DNS_BYADDROPT_IPV6INT) != 0) { if (result == DNS_R_NCACHENXDOMAIN || result == DNS_R_NCACHENXRRSET || result == DNS_R_NXDOMAIN || result == DNS_R_NXRRSET) lwresult = LWRES_R_NOTFOUND; else lwresult = LWRES_R_FAILURE; ns_lwdclient_errorpktsend(client, lwresult); return; } /* * Fall back to ip6.int reverse if the default ip6.arpa * fails. */ client->options |= DNS_BYADDROPT_IPV6INT; start_byaddr(client); return; } for (name = ISC_LIST_HEAD(bevent->names); name != NULL; name = ISC_LIST_NEXT(name, link)) { b = client->recv_buffer; result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); if (result != ISC_R_SUCCESS) goto out; ns_lwdclient_log(50, "found name '%.*s'", (int)(client->recv_buffer.used - b.used), (char *)(b.base) + b.used); if (gnba->realname == NULL) { gnba->realname = (char *)(b.base) + b.used; gnba->realnamelen = client->recv_buffer.used - b.used; } else { naliases = gnba->naliases; if (naliases >= LWRES_MAX_ALIASES) break; gnba->aliases[naliases] = (char *)(b.base) + b.used; gnba->aliaslen[naliases] = client->recv_buffer.used - b.used; gnba->naliases++; } } dns_byaddr_destroy(&client->byaddr); isc_event_free(&event); /* * Render the packet. */ client->pkt.recvlength = LWRES_RECVLENGTH; client->pkt.authtype = 0; /* XXXMLG */ client->pkt.authlength = 0; client->pkt.result = LWRES_R_SUCCESS; lwres = lwres_gnbaresponse_render(cm->lwctx, gnba, &client->pkt, &lwb); if (lwres != LWRES_R_SUCCESS) goto out; r.base = lwb.base; r.length = lwb.used; client->sendbuf = r.base; client->sendlength = r.length; result = ns_lwdclient_sendreply(client, &r); if (result != ISC_R_SUCCESS) goto out; NS_LWDCLIENT_SETSEND(client); return; out: if (client->byaddr != NULL) dns_byaddr_destroy(&client->byaddr); if (lwb.base != NULL) lwres_context_freemem(cm->lwctx, lwb.base, lwb.length); if (event != NULL) isc_event_free(&event); }
static void lookup_done(isc_task_t *task, isc_event_t *event) { ns_lwdclient_t *client; ns_lwdclientmgr_t *cm; dns_lookupevent_t *levent; lwres_buffer_t lwb; dns_name_t *name; dns_rdataset_t *rdataset; dns_rdataset_t *sigrdataset; isc_result_t result; lwres_result_t lwresult; isc_region_t r; isc_buffer_t b; lwres_grbnresponse_t *grbn; int i; UNUSED(task); lwb.base = NULL; client = event->ev_arg; cm = client->clientmgr; INSIST(client->lookup == (dns_lookup_t *)event->ev_sender); levent = (dns_lookupevent_t *)event; grbn = &client->grbn; ns_lwdclient_log(50, "lookup event result = %s", isc_result_totext(levent->result)); result = levent->result; if (result != ISC_R_SUCCESS) { dns_lookup_destroy(&client->lookup); isc_event_free(&event); levent = NULL; switch (result) { case DNS_R_NXDOMAIN: case DNS_R_NCACHENXDOMAIN: result = ns_lwsearchctx_next(&client->searchctx); if (result != ISC_R_SUCCESS) lwresult = LWRES_R_NOTFOUND; else { start_lookup(client); return; } break; case DNS_R_NXRRSET: case DNS_R_NCACHENXRRSET: lwresult = LWRES_R_TYPENOTFOUND; break; default: lwresult = LWRES_R_FAILURE; } ns_lwdclient_errorpktsend(client, lwresult); return; } name = levent->name; b = client->recv_buffer; grbn->flags = 0; grbn->nrdatas = 0; grbn->rdatas = NULL; grbn->rdatalen = NULL; grbn->nsigs = 0; grbn->sigs = NULL; grbn->siglen = NULL; result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); if (result != ISC_R_SUCCESS) goto out; grbn->realname = (char *)isc_buffer_used(&b); grbn->realnamelen = isc_buffer_usedlength(&client->recv_buffer) - isc_buffer_usedlength(&b); ns_lwdclient_log(50, "found name '%.*s'", grbn->realnamelen, grbn->realname); grbn->rdclass = cm->view->rdclass; grbn->rdtype = client->rdtype; rdataset = levent->rdataset; if (rdataset != NULL) { /* The normal case */ grbn->nrdatas = dns_rdataset_count(rdataset); grbn->rdatas = isc_mem_get(cm->mctx, grbn->nrdatas * sizeof(unsigned char *)); if (grbn->rdatas == NULL) goto out; grbn->rdatalen = isc_mem_get(cm->mctx, grbn->nrdatas * sizeof(lwres_uint16_t)); if (grbn->rdatalen == NULL) goto out; i = 0; result = fill_array(&i, rdataset, grbn->nrdatas, grbn->rdatas, grbn->rdatalen); if (result != ISC_R_SUCCESS) goto out; INSIST(i == grbn->nrdatas); grbn->ttl = rdataset->ttl; if (rdataset->trust == dns_trust_secure) grbn->flags |= LWRDATA_VALIDATED; } else { /* The SIG query case */ result = iterate_node(grbn, levent->db, levent->node, cm->mctx); if (result != ISC_R_SUCCESS) goto out; } ns_lwdclient_log(50, "filled in %d rdata%s", grbn->nrdatas, (grbn->nrdatas == 1) ? "" : "s"); sigrdataset = levent->sigrdataset; if (sigrdataset != NULL) { grbn->nsigs = dns_rdataset_count(sigrdataset); grbn->sigs = isc_mem_get(cm->mctx, grbn->nsigs * sizeof(unsigned char *)); if (grbn->sigs == NULL) goto out; grbn->siglen = isc_mem_get(cm->mctx, grbn->nsigs * sizeof(lwres_uint16_t)); if (grbn->siglen == NULL) goto out; i = 0; result = fill_array(&i, sigrdataset, grbn->nsigs, grbn->sigs, grbn->siglen); if (result != ISC_R_SUCCESS) goto out; INSIST(i == grbn->nsigs); ns_lwdclient_log(50, "filled in %d signature%s", grbn->nsigs, (grbn->nsigs == 1) ? "" : "s"); } dns_lookup_destroy(&client->lookup); isc_event_free(&event); /* * Render the packet. */ client->pkt.recvlength = LWRES_RECVLENGTH; client->pkt.authtype = 0; /* XXXMLG */ client->pkt.authlength = 0; client->pkt.result = LWRES_R_SUCCESS; lwresult = lwres_grbnresponse_render(cm->lwctx, grbn, &client->pkt, &lwb); if (lwresult != LWRES_R_SUCCESS) goto out; isc_mem_put(cm->mctx, grbn->rdatas, grbn->nrdatas * sizeof(unsigned char *)); isc_mem_put(cm->mctx, grbn->rdatalen, grbn->nrdatas * sizeof(lwres_uint16_t)); if (grbn->sigs != NULL) isc_mem_put(cm->mctx, grbn->sigs, grbn->nsigs * sizeof(unsigned char *)); if (grbn->siglen != NULL) isc_mem_put(cm->mctx, grbn->siglen, grbn->nsigs * sizeof(lwres_uint16_t)); r.base = lwb.base; r.length = lwb.used; client->sendbuf = r.base; client->sendlength = r.length; result = ns_lwdclient_sendreply(client, &r); if (result != ISC_R_SUCCESS) goto out2; NS_LWDCLIENT_SETSEND(client); return; out: if (grbn->rdatas != NULL) isc_mem_put(cm->mctx, grbn->rdatas, grbn->nrdatas * sizeof(unsigned char *)); if (grbn->rdatalen != NULL) isc_mem_put(cm->mctx, grbn->rdatalen, grbn->nrdatas * sizeof(lwres_uint16_t)); if (grbn->sigs != NULL) isc_mem_put(cm->mctx, grbn->sigs, grbn->nsigs * sizeof(unsigned char *)); if (grbn->siglen != NULL) isc_mem_put(cm->mctx, grbn->siglen, grbn->nsigs * sizeof(lwres_uint16_t)); out2: if (client->lookup != NULL) dns_lookup_destroy(&client->lookup); if (lwb.base != NULL) lwres_context_freemem(cm->lwctx, lwb.base, lwb.length); if (event != NULL) isc_event_free(&event); ns_lwdclient_log(50, "error constructing getrrsetbyname response"); ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); }
int main(int argc, char *argv[]) { dns_db_t *db; dns_dbnode_t *node; isc_result_t result; dns_name_t name; dns_offsets_t offsets; size_t len; isc_buffer_t source, target; char s[1000]; char b[255]; dns_rdataset_t rdataset, sigrdataset; int ch; dns_rdatatype_t type = 1; isc_boolean_t printnode = ISC_FALSE; isc_boolean_t addmode = ISC_FALSE; isc_boolean_t delmode = ISC_FALSE; isc_boolean_t holdmode = ISC_FALSE; isc_boolean_t verbose = ISC_FALSE; isc_boolean_t done = ISC_FALSE; isc_boolean_t quiet = ISC_FALSE; isc_boolean_t time_lookups = ISC_FALSE; isc_boolean_t found_as; isc_boolean_t find_zonecut = ISC_FALSE; isc_boolean_t noexact_zonecut = ISC_FALSE; int i, v; dns_rdatasetiter_t *rdsiter; char t1[256]; char t2[256]; isc_buffer_t tb1, tb2; isc_region_t r1, r2; dns_fixedname_t foundname; dns_name_t *fname; unsigned int options = 0, zcoptions; isc_time_t start, finish; const char *origintext; dbinfo *dbi; dns_dbversion_t *version; dns_name_t *origin; size_t memory_quota = 0; dns_trust_t trust = 0; unsigned int addopts; isc_log_t *lctx = NULL; size_t n; dns_result_register(); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(dns_dbtable_create(mctx, dns_rdataclass_in, &dbtable) == ISC_R_SUCCESS); strcpy(dbtype, "rbt"); while ((ch = isc_commandline_parse(argc, argv, "c:d:t:z:P:Q:glpqvT")) != -1) { switch (ch) { case 'c': result = load(isc_commandline_argument, ".", ISC_TRUE); if (result != ISC_R_SUCCESS) printf("cache load(%s) %08x: %s\n", isc_commandline_argument, result, isc_result_totext(result)); break; case 'd': n = strlcpy(dbtype, isc_commandline_argument, sizeof(dbtype)); if (n >= sizeof(dbtype)) { fprintf(stderr, "bad db type '%s'\n", isc_commandline_argument); exit(1); } break; case 'g': options |= (DNS_DBFIND_GLUEOK|DNS_DBFIND_VALIDATEGLUE); break; case 'l': RUNTIME_CHECK(isc_log_create(mctx, &lctx, NULL) == ISC_R_SUCCESS); isc_log_setcontext(lctx); dns_log_init(lctx); dns_log_setcontext(lctx); break; case 'q': quiet = ISC_TRUE; verbose = ISC_FALSE; break; case 'p': printnode = ISC_TRUE; break; case 'P': pause_every = atoi(isc_commandline_argument); break; case 'Q': memory_quota = atoi(isc_commandline_argument); isc_mem_setquota(mctx, memory_quota); break; case 't': type = atoi(isc_commandline_argument); break; case 'T': time_lookups = ISC_TRUE; break; case 'v': verbose = ISC_TRUE; break; case 'z': origintext = strrchr(isc_commandline_argument, '/'); if (origintext == NULL) origintext = isc_commandline_argument; else origintext++; /* Skip '/'. */ result = load(isc_commandline_argument, origintext, ISC_FALSE); if (result != ISC_R_SUCCESS) printf("zone load(%s) %08x: %s\n", isc_commandline_argument, result, isc_result_totext(result)); break; } } argc -= isc_commandline_index; argv += isc_commandline_index; POST(argv); if (argc != 0) printf("ignoring trailing arguments\n"); /* * Some final initialization... */ dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); dbi = NULL; origin = dns_rootname; version = NULL; if (time_lookups) { TIME_NOW(&start); } while (!done) { if (!quiet) printf("\n"); if (fgets(s, sizeof(s), stdin) == NULL) { done = ISC_TRUE; continue; } len = strlen(s); if (len > 0U && s[len - 1] == '\n') { s[len - 1] = '\0'; len--; } if (verbose && dbi != NULL) { if (dbi->wversion != NULL) printf("future version (%p)\n", dbi->wversion); for (i = 0; i < dbi->rcount; i++) if (dbi->rversions[i] != NULL) printf("open version %d (%p)\n", i, dbi->rversions[i]); } dns_name_init(&name, offsets); if (strcmp(s, "!R") == 0) { DBI_CHECK(dbi); if (dbi->rcount == MAXVERSIONS) { printf("too many open versions\n"); continue; } dns_db_currentversion(dbi->db, &dbi->rversions[dbi->rcount]); printf("opened version %d\n", dbi->rcount); dbi->version = dbi->rversions[dbi->rcount]; version = dbi->version; dbi->rcount++; continue; } else if (strcmp(s, "!W") == 0) { DBI_CHECK(dbi); if (dbi->wversion != NULL) { printf("using existing future version\n"); dbi->version = dbi->wversion; version = dbi->version; continue; } result = dns_db_newversion(dbi->db, &dbi->wversion); if (result != ISC_R_SUCCESS) print_result("", result); else printf("newversion\n"); dbi->version = dbi->wversion; version = dbi->version; continue; } else if (strcmp(s, "!C") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; delmode = ISC_FALSE; if (dbi->version == NULL) continue; if (dbi->version == dbi->wversion) { printf("closing future version\n"); dbi->wversion = NULL; } else { for (i = 0; i < dbi->rcount; i++) { if (dbi->version == dbi->rversions[i]) { dbi->rversions[i] = NULL; printf("closing open version %d\n", i); break; } } } dns_db_closeversion(dbi->db, &dbi->version, ISC_TRUE); version = NULL; continue; } else if (strcmp(s, "!X") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; delmode = ISC_FALSE; if (dbi->version == NULL) continue; if (dbi->version == dbi->wversion) { printf("aborting future version\n"); dbi->wversion = NULL; } else { for (i = 0; i < dbi->rcount; i++) { if (dbi->version == dbi->rversions[i]) { dbi->rversions[i] = NULL; printf("closing open version %d\n", i); break; } } } dns_db_closeversion(dbi->db, &dbi->version, ISC_FALSE); version = NULL; continue; } else if (strcmp(s, "!A") == 0) { DBI_CHECK(dbi); delmode = ISC_FALSE; if (addmode) addmode = ISC_FALSE; else addmode = ISC_TRUE; printf("addmode = %s\n", addmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!D") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; if (delmode) delmode = ISC_FALSE; else delmode = ISC_TRUE; printf("delmode = %s\n", delmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!H") == 0) { DBI_CHECK(dbi); if (holdmode) holdmode = ISC_FALSE; else holdmode = ISC_TRUE; printf("holdmode = %s\n", holdmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!HR") == 0) { DBI_CHECK(dbi); for (i = 0; i < dbi->hold_count; i++) dns_db_detachnode(dbi->db, &dbi->hold_nodes[i]); dbi->hold_count = 0; holdmode = ISC_FALSE; printf("held nodes have been detached\n"); continue; } else if (strcmp(s, "!VC") == 0) { DBI_CHECK(dbi); printf("switching to current version\n"); dbi->version = NULL; version = NULL; continue; } else if (strstr(s, "!V") == s) { DBI_CHECK(dbi); v = atoi(&s[2]); if (v >= dbi->rcount || v < 0) { printf("unknown open version %d\n", v); continue; } if (dbi->rversions[v] == NULL) { printf("version %d is not open\n", v); continue; } printf("switching to open version %d\n", v); dbi->version = dbi->rversions[v]; version = dbi->version; continue; } else if (strstr(s, "!TR") == s) { trust = (unsigned int)atoi(&s[3]); printf("trust level is now %u\n", (unsigned int)trust); continue; } else if (strstr(s, "!T") == s) { type = (unsigned int)atoi(&s[2]); printf("now searching for type %u\n", type); continue; } else if (strcmp(s, "!G") == 0) { if ((options & DNS_DBFIND_GLUEOK) != 0) options &= ~DNS_DBFIND_GLUEOK; else options |= DNS_DBFIND_GLUEOK; printf("glue ok = %s\n", ((options & DNS_DBFIND_GLUEOK) != 0) ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!GV") == 0) { if ((options & DNS_DBFIND_VALIDATEGLUE) != 0) options &= ~DNS_DBFIND_VALIDATEGLUE; else options |= DNS_DBFIND_VALIDATEGLUE; printf("validate glue = %s\n", ((options & DNS_DBFIND_VALIDATEGLUE) != 0) ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!WC") == 0) { if ((options & DNS_DBFIND_NOWILD) != 0) options &= ~DNS_DBFIND_NOWILD; else options |= DNS_DBFIND_NOWILD; printf("wildcard matching = %s\n", ((options & DNS_DBFIND_NOWILD) == 0) ? "TRUE" : "FALSE"); continue; } else if (strstr(s, "!LS ") == s) { DBI_CHECK(dbi); list(dbi, &s[4]); continue; } else if (strcmp(s, "!LS") == 0) { DBI_CHECK(dbi); list(dbi, NULL); continue; } else if (strstr(s, "!DU ") == s) { DBI_CHECK(dbi); result = dns_db_dump(dbi->db, dbi->version, s+4); if (result != ISC_R_SUCCESS) { printf("\n"); print_result("", result); } continue; } else if (strcmp(s, "!PN") == 0) { if (printnode) printnode = ISC_FALSE; else printnode = ISC_TRUE; printf("printnode = %s\n", printnode ? "TRUE" : "FALSE"); continue; } else if (strstr(s, "!P") == s) { DBI_CHECK(dbi); v = atoi(&s[2]); dbi->pause_every = v; continue; } else if (strcmp(s, "!+") == 0) { DBI_CHECK(dbi); dbi->ascending = ISC_TRUE; continue; } else if (strcmp(s, "!-") == 0) { DBI_CHECK(dbi); dbi->ascending = ISC_FALSE; continue; } else if (strcmp(s, "!DB") == 0) { dbi = NULL; origin = dns_rootname; version = NULL; printf("now searching all databases\n"); continue; } else if (strncmp(s, "!DB ", 4) == 0) { dbi = select_db(s+4); if (dbi != NULL) { db = dbi->db; origin = dns_db_origin(dbi->db); version = dbi->version; addmode = ISC_FALSE; delmode = ISC_FALSE; holdmode = ISC_FALSE; } else { db = NULL; version = NULL; origin = dns_rootname; printf("database not found; " "now searching all databases\n"); } continue; } else if (strcmp(s, "!ZC") == 0) { if (find_zonecut) find_zonecut = ISC_FALSE; else find_zonecut = ISC_TRUE; printf("find_zonecut = %s\n", find_zonecut ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!NZ") == 0) { if (noexact_zonecut) noexact_zonecut = ISC_FALSE; else noexact_zonecut = ISC_TRUE; printf("noexact_zonecut = %s\n", noexact_zonecut ? "TRUE" : "FALSE"); continue; } isc_buffer_init(&source, s, len); isc_buffer_add(&source, len); isc_buffer_init(&target, b, sizeof(b)); result = dns_name_fromtext(&name, &source, origin, 0, &target); if (result != ISC_R_SUCCESS) { print_result("bad name: ", result); continue; } if (dbi == NULL) { zcoptions = 0; if (noexact_zonecut) zcoptions |= DNS_DBTABLEFIND_NOEXACT; db = NULL; result = dns_dbtable_find(dbtable, &name, zcoptions, &db); if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH) { if (!quiet) { printf("\n"); print_result("", result); } continue; } isc_buffer_init(&tb1, t1, sizeof(t1)); result = dns_name_totext(dns_db_origin(db), ISC_FALSE, &tb1); if (result != ISC_R_SUCCESS) { printf("\n"); print_result("", result); dns_db_detach(&db); continue; } isc_buffer_usedregion(&tb1, &r1); printf("\ndatabase = %.*s (%s)\n", (int)r1.length, r1.base, (dns_db_iszone(db)) ? "zone" : "cache"); } node = NULL; dns_rdataset_init(&rdataset); dns_rdataset_init(&sigrdataset); if (find_zonecut && dns_db_iscache(db)) { zcoptions = options; if (noexact_zonecut) zcoptions |= DNS_DBFIND_NOEXACT; result = dns_db_findzonecut(db, &name, zcoptions, 0, &node, fname, &rdataset, &sigrdataset); } else { result = dns_db_find(db, &name, version, type, options, 0, &node, fname, &rdataset, &sigrdataset); } if (!quiet) { if (dbi != NULL) printf("\n"); print_result("", result); } found_as = ISC_FALSE; switch (result) { case ISC_R_SUCCESS: case DNS_R_GLUE: case DNS_R_CNAME: case DNS_R_ZONECUT: break; case DNS_R_DNAME: case DNS_R_DELEGATION: found_as = ISC_TRUE; break; case DNS_R_NXRRSET: if (dns_rdataset_isassociated(&rdataset)) break; if (dbi != NULL) { if (holdmode) { RUNTIME_CHECK(dbi->hold_count < MAXHOLD); dbi->hold_nodes[dbi->hold_count++] = node; node = NULL; } else dns_db_detachnode(db, &node); } else { dns_db_detachnode(db, &node); dns_db_detach(&db); } continue; case DNS_R_NXDOMAIN: if (dns_rdataset_isassociated(&rdataset)) break; /* FALLTHROUGH */ default: if (dbi == NULL) dns_db_detach(&db); if (quiet) print_result("", result); continue; } if (found_as && !quiet) { isc_buffer_init(&tb1, t1, sizeof(t1)); isc_buffer_init(&tb2, t2, sizeof(t2)); result = dns_name_totext(&name, ISC_FALSE, &tb1); if (result != ISC_R_SUCCESS) { print_result("", result); dns_db_detachnode(db, &node); if (dbi == NULL) dns_db_detach(&db); continue; } result = dns_name_totext(fname, ISC_FALSE, &tb2); if (result != ISC_R_SUCCESS) { print_result("", result); dns_db_detachnode(db, &node); if (dbi == NULL) dns_db_detach(&db); continue; } isc_buffer_usedregion(&tb1, &r1); isc_buffer_usedregion(&tb2, &r2); printf("found %.*s as %.*s\n", (int)r1.length, r1.base, (int)r2.length, r2.base); } if (printnode) dns_db_printnode(db, node, stdout); if (!found_as && type == dns_rdatatype_any) { rdsiter = NULL; result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); if (result == ISC_R_SUCCESS) { if (!quiet) print_rdatasets(fname, rdsiter); dns_rdatasetiter_destroy(&rdsiter); } else print_result("", result); } else { if (!quiet) print_rdataset(fname, &rdataset); if (dns_rdataset_isassociated(&sigrdataset)) { if (!quiet) print_rdataset(fname, &sigrdataset); dns_rdataset_disassociate(&sigrdataset); } if (dbi != NULL && addmode && !found_as) { rdataset.ttl++; rdataset.trust = trust; if (dns_db_iszone(db)) addopts = DNS_DBADD_MERGE; else addopts = 0; result = dns_db_addrdataset(db, node, version, 0, &rdataset, addopts, NULL); if (result != ISC_R_SUCCESS) print_result("", result); if (printnode) dns_db_printnode(db, node, stdout); } else if (dbi != NULL && delmode && !found_as) { result = dns_db_deleterdataset(db, node, version, type, 0); if (result != ISC_R_SUCCESS) print_result("", result); if (printnode) dns_db_printnode(db, node, stdout); } dns_rdataset_disassociate(&rdataset); } if (dbi != NULL) { if (holdmode) { RUNTIME_CHECK(dbi->hold_count < MAXHOLD); dbi->hold_nodes[dbi->hold_count++] = node; node = NULL; } else dns_db_detachnode(db, &node); } else { dns_db_detachnode(db, &node); dns_db_detach(&db); } } if (time_lookups) { isc_uint64_t usec; TIME_NOW(&finish); usec = isc_time_microdiff(&finish, &start); printf("elapsed time: %lu.%06lu seconds\n", (unsigned long)(usec / 1000000), (unsigned long)(usec % 1000000)); } unload_all(); dns_dbtable_detach(&dbtable); if (lctx != NULL) isc_log_destroy(&lctx); if (!quiet) isc_mem_stats(mctx, stdout); return (0); }