ldns_rr * ldns_axfr_next(ldns_resolver *resolver) { ldns_rr *cur_rr; uint8_t *packet_wire; size_t packet_wire_size; ldns_lookup_table *rcode; ldns_status status; /* check if start() has been called */ if (!resolver || resolver->_socket == 0) { return NULL; } if (resolver->_cur_axfr_pkt) { if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) { ldns_pkt_free(resolver->_cur_axfr_pkt); resolver->_cur_axfr_pkt = NULL; return ldns_axfr_next(resolver); } cur_rr = ldns_rr_clone(ldns_rr_list_rr( ldns_pkt_answer(resolver->_cur_axfr_pkt), resolver->_axfr_i)); resolver->_axfr_i++; if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) { resolver->_axfr_soa_count++; if (resolver->_axfr_soa_count >= 2) { close(resolver->_socket); resolver->_socket = 0; ldns_pkt_free(resolver->_cur_axfr_pkt); resolver->_cur_axfr_pkt = NULL; } } return cur_rr; } else { packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size); if(!packet_wire) return NULL; status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire, packet_wire_size); free(packet_wire); resolver->_axfr_i = 0; if (status != LDNS_STATUS_OK) { /* TODO: make status return type of this function (...api change) */ fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status)); return NULL; } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) { rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt)); fprintf(stderr, "Error in AXFR: %s\n", rcode->name); return NULL; } else { return ldns_axfr_next(resolver); } } }
/** match all of the packet */ static int match_all(ldns_pkt* q, ldns_pkt* p) { if(ldns_pkt_get_opcode(q) != ldns_pkt_get_opcode(p)) { verbose(3, "allmatch: opcode different"); return 0;} if(ldns_pkt_get_rcode(q) != ldns_pkt_get_rcode(p)) { verbose(3, "allmatch: rcode different"); return 0;} if(ldns_pkt_id(q) != ldns_pkt_id(p)) { verbose(3, "allmatch: id different"); return 0;} if(cmp_bool(ldns_pkt_qr(q), ldns_pkt_qr(p)) != 0) { verbose(3, "allmatch: qr different"); return 0;} if(cmp_bool(ldns_pkt_aa(q), ldns_pkt_aa(p)) != 0) { verbose(3, "allmatch: aa different"); return 0;} if(cmp_bool(ldns_pkt_tc(q), ldns_pkt_tc(p)) != 0) { verbose(3, "allmatch: tc different"); return 0;} if(cmp_bool(ldns_pkt_rd(q), ldns_pkt_rd(p)) != 0) { verbose(3, "allmatch: rd different"); return 0;} if(cmp_bool(ldns_pkt_cd(q), ldns_pkt_cd(p)) != 0) { verbose(3, "allmatch: cd different"); return 0;} if(cmp_bool(ldns_pkt_ra(q), ldns_pkt_ra(p)) != 0) { verbose(3, "allmatch: ra different"); return 0;} if(cmp_bool(ldns_pkt_ad(q), ldns_pkt_ad(p)) != 0) { verbose(3, "allmatch: ad different"); return 0;} if(ldns_pkt_qdcount(q) != ldns_pkt_qdcount(p)) { verbose(3, "allmatch: qdcount different"); return 0;} if(ldns_pkt_ancount(q) != ldns_pkt_ancount(p)) { verbose(3, "allmatch: ancount different"); return 0;} if(ldns_pkt_nscount(q) != ldns_pkt_nscount(p)) { verbose(3, "allmatch: nscount different"); return 0;} if(ldns_pkt_arcount(q) != ldns_pkt_arcount(p)) { verbose(3, "allmatch: arcount different"); return 0;} if(!match_list(ldns_pkt_question(q), ldns_pkt_question(p))) { verbose(3, "allmatch: qd section different"); return 0;} if(!match_list(ldns_pkt_answer(q), ldns_pkt_answer(p))) { verbose(3, "allmatch: an section different"); return 0;} if(!match_list(ldns_pkt_authority(q), ldns_pkt_authority(p))) { verbose(3, "allmatch: ns section different"); return 0;} if(!match_list(ldns_pkt_additional(q), ldns_pkt_additional(p))) { verbose(3, "allmatch: ar section different"); return 0;} if(!match_edns(q, p)) { verbose(3, "edns different."); return 0;} return 1; }
static int l_pkt_ancount(lua_State *L) { ldns_pkt *p = (ldns_pkt*)lua_touserdata(L, 1); if (!p) { return 0; } lua_pushnumber(L, (lua_Number)ldns_pkt_ancount(p)); return 1; }
void dnspkt_printresp (ldns_pkt *pkt, struct timeval ts, host_t *src, host_t *dst) { FILE *output = dnsfile_resp(); __print_ts(output, ts); __print_ip(output, src); __print_ip(output, dst); fprintf(output, "%u\t", (uint16_t)ldns_pkt_size(pkt)); fprintf(output, "%u\t", ldns_pkt_aa(pkt)); fprintf(output, "%u\t", ldns_pkt_tc(pkt)); fprintf(output, "%u\t", ldns_pkt_rd(pkt)); fprintf(output, "%u\t", ldns_pkt_ra(pkt)); fprintf(output, "%u\t", ldns_pkt_get_rcode(pkt)); fprintf(output, "%u\t", ldns_pkt_qdcount(pkt)); fprintf(output, "%u\t", ldns_pkt_ancount(pkt)); fprintf(output, "%u\t", ldns_pkt_nscount(pkt)); fprintf(output, "%u\t", ldns_pkt_arcount(pkt)); ldns_rr_list *rrlist = ldns_pkt_question(pkt); if (ldns_rr_list_rr_count(rrlist) > 0) { ldns_rr_print(output, ldns_rr_list_rr(rrlist, 0)); } else { fprintf(output, "\t\t\n"); } }
/* * Copies the packet header data to the buffer in wire format */ static ldns_status ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet) { uint8_t flags; uint16_t arcount; if (ldns_buffer_reserve(buffer, 12)) { ldns_buffer_write_u16(buffer, ldns_pkt_id(packet)); flags = ldns_pkt_qr(packet) << 7 | ldns_pkt_get_opcode(packet) << 3 | ldns_pkt_aa(packet) << 2 | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet); ldns_buffer_write_u8(buffer, flags); flags = ldns_pkt_ra(packet) << 7 /*| ldns_pkt_z(packet) << 6*/ | ldns_pkt_ad(packet) << 5 | ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet); ldns_buffer_write_u8(buffer, flags); ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet)); ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet)); ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet)); /* add EDNS0 and TSIG to additional if they are there */ arcount = ldns_pkt_arcount(packet); if (ldns_pkt_tsig(packet)) { arcount++; } if (ldns_pkt_edns(packet)) { arcount++; } ldns_buffer_write_u16(buffer, arcount); } return ldns_buffer_status(buffer); }
ldns_status do_chase(ldns_resolver *res, ldns_rdf *name, ldns_rr_type type, ldns_rr_class c, ldns_rr_list *trusted_keys, ldns_pkt *pkt_o, uint16_t qflags, ldns_rr_list *prev_key_list, int verbosity) { ldns_rr_list *rrset = NULL; ldns_status result; ldns_rr *orig_rr = NULL; /* ldns_rr_list *sigs; ldns_rr *cur_sig; uint16_t sig_i; ldns_rr_list *keys; */ ldns_pkt *pkt; ldns_status tree_result; ldns_dnssec_data_chain *chain; ldns_dnssec_trust_tree *tree; const ldns_rr_descriptor *descriptor; descriptor = ldns_rr_descript(type); ldns_dname2canonical(name); pkt = ldns_pkt_clone(pkt_o); if (!name) { ldns_pkt_free(pkt); return LDNS_STATUS_EMPTY_LABEL; } if (verbosity != -1) { printf(";; Chasing: "); ldns_rdf_print(stdout, name); if (descriptor && descriptor->_name) { printf(" %s\n", descriptor->_name); } else { printf(" type %d\n", type); } } if (!trusted_keys || ldns_rr_list_rr_count(trusted_keys) < 1) { } if (pkt) { rrset = ldns_pkt_rr_list_by_name_and_type(pkt, name, type, LDNS_SECTION_ANSWER ); if (!rrset) { /* nothing in answer, try authority */ rrset = ldns_pkt_rr_list_by_name_and_type(pkt, name, type, LDNS_SECTION_AUTHORITY ); } /* answer might be a cname, chase that first, then chase cname target? (TODO) */ if (!rrset) { rrset = ldns_pkt_rr_list_by_name_and_type(pkt, name, LDNS_RR_TYPE_CNAME, LDNS_SECTION_ANSWER ); if (!rrset) { /* nothing in answer, try authority */ rrset = ldns_pkt_rr_list_by_name_and_type(pkt, name, LDNS_RR_TYPE_CNAME, LDNS_SECTION_AUTHORITY ); } } } else { /* no packet? */ if (verbosity >= 0) { fprintf(stderr, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR)); fprintf(stderr, "\n"); } return LDNS_STATUS_MEM_ERR; } if (!rrset) { /* not found in original packet, try again */ ldns_pkt_free(pkt); pkt = NULL; pkt = ldns_resolver_query(res, name, type, c, qflags); if (!pkt) { if (verbosity >= 0) { fprintf(stderr, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_NETWORK_ERR)); fprintf(stderr, "\n"); } return LDNS_STATUS_NETWORK_ERR; } if (verbosity >= 5) { ldns_pkt_print(stdout, pkt); } rrset = ldns_pkt_rr_list_by_name_and_type(pkt, name, type, LDNS_SECTION_ANSWER ); } orig_rr = ldns_rr_new(); /* if the answer had no answer section, we need to construct our own rr (for instance if * the rr qe asked for doesn't exist. This rr will be destroyed when the chain is freed */ if (ldns_pkt_ancount(pkt) < 1) { ldns_rr_set_type(orig_rr, type); ldns_rr_set_owner(orig_rr, ldns_rdf_clone(name)); chain = ldns_dnssec_build_data_chain(res, qflags, rrset, pkt, ldns_rr_clone(orig_rr)); } else { /* chase the first answer */ chain = ldns_dnssec_build_data_chain(res, qflags, rrset, pkt, NULL); } if (verbosity >= 4) { printf("\n\nDNSSEC Data Chain:\n"); ldns_dnssec_data_chain_print(stdout, chain); } result = LDNS_STATUS_OK; tree = ldns_dnssec_derive_trust_tree(chain, NULL); if (verbosity >= 2) { printf("\n\nDNSSEC Trust tree:\n"); ldns_dnssec_trust_tree_print(stdout, tree, 0, true); } if (ldns_rr_list_rr_count(trusted_keys) > 0) { tree_result = ldns_dnssec_trust_tree_contains_keys(tree, trusted_keys); if (tree_result == LDNS_STATUS_DNSSEC_EXISTENCE_DENIED) { if (verbosity >= 1) { printf("Existence denied or verifiably insecure\n"); } result = LDNS_STATUS_OK; } else if (tree_result != LDNS_STATUS_OK) { if (verbosity >= 1) { printf("No trusted keys found in tree: first error was: %s\n", ldns_get_errorstr_by_id(tree_result)); } result = tree_result; } } else { result = -1; if (verbosity >= 0) { printf("You have not provided any trusted keys.\n"); } } ldns_rr_free(orig_rr); ldns_dnssec_trust_tree_free(tree); ldns_dnssec_data_chain_deep_free(chain); ldns_rr_list_deep_free(rrset); ldns_pkt_free(pkt); /* ldns_rr_free(orig_rr);*/ return result; }
ldns_rr * ldns_axfr_next(ldns_resolver *resolver) { ldns_rr *cur_rr; uint8_t *packet_wire; size_t packet_wire_size; ldns_lookup_table *rcode; ldns_status status; /* check if start() has been called */ if (!resolver || resolver->_socket == 0) { return NULL; } if (resolver->_cur_axfr_pkt) { if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) { ldns_pkt_free(resolver->_cur_axfr_pkt); resolver->_cur_axfr_pkt = NULL; return ldns_axfr_next(resolver); } cur_rr = ldns_rr_clone(ldns_rr_list_rr( ldns_pkt_answer(resolver->_cur_axfr_pkt), resolver->_axfr_i)); resolver->_axfr_i++; if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) { resolver->_axfr_soa_count++; if (resolver->_axfr_soa_count >= 2) { #ifndef USE_WINSOCK close(resolver->_socket); #else closesocket(resolver->_socket); #endif resolver->_socket = 0; ldns_pkt_free(resolver->_cur_axfr_pkt); resolver->_cur_axfr_pkt = NULL; } } return cur_rr; } else { packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size); if(!packet_wire) return NULL; status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire, packet_wire_size); free(packet_wire); resolver->_axfr_i = 0; if (status != LDNS_STATUS_OK) { /* TODO: make status return type of this function (...api change) */ fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status)); /* RoRi: we must now also close the socket, otherwise subsequent uses of the same resolver structure will fail because the link is still open or in an undefined state */ #ifndef USE_WINSOCK close(resolver->_socket); #else closesocket(resolver->_socket); #endif resolver->_socket = 0; return NULL; } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) { rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt)); fprintf(stderr, "Error in AXFR: %s\n", rcode->name); /* RoRi: we must now also close the socket, otherwise subsequent uses of the same resolver structure will fail because the link is still open or in an undefined state */ #ifndef USE_WINSOCK close(resolver->_socket); #else closesocket(resolver->_socket); #endif resolver->_socket = 0; return NULL; } else { return ldns_axfr_next(resolver); } } }
void compare(struct dns_info *d1, struct dns_info *d2) { ldns_pkt *p1, *p2, *pq; bool diff = false; char *pstr1, *pstr2; struct timeval now; char *compare_result; size_t file_nr; gettimeofday(&now, NULL); if (verbosity > 0) { printf("Id: %u\n", (unsigned int) d1->seq); } if (strcmp(d1->qdata, d2->qdata) != 0) { fprintf(stderr, "Query differs!\n"); fprintf(stdout, "q: %d:%d\n%s\n%s\n%s\n", (int)d1->seq, (int)d2->seq, d1->qdata, d1->qdata, d2->qdata); } else { if (strcmp(d1->adata, d2->adata) != 0) { if (advanced_match) { /* try to read the packet and sort the sections */ p1 = read_hex_pkt(d1->adata); p2 = read_hex_pkt(d2->adata); if (p1) { ldns_pkt_set_timestamp(p1, now); } if (p2) { ldns_pkt_set_timestamp(p2, now); } if (p1 && ldns_pkt_qdcount(p1) > 0) { ldns_rr_list2canonical(ldns_pkt_question(p1)); ldns_rr_list_sort(ldns_pkt_question(p1)); } if (p1 && ldns_pkt_ancount(p1) > 0) { ldns_rr_list2canonical(ldns_pkt_answer(p1)); ldns_rr_list_sort(ldns_pkt_answer(p1)); } if (p1 && ldns_pkt_nscount(p1) > 0) { ldns_rr_list2canonical(ldns_pkt_authority(p1)); ldns_rr_list_sort(ldns_pkt_authority(p1)); } if (p1 && ldns_pkt_arcount(p1) > 0) { ldns_rr_list2canonical(ldns_pkt_additional(p1)); ldns_rr_list_sort(ldns_pkt_additional(p1)); } if (p2 && ldns_pkt_qdcount(p2) > 0) { ldns_rr_list2canonical(ldns_pkt_question(p2)); ldns_rr_list_sort(ldns_pkt_question(p2)); } if (p2 && ldns_pkt_ancount(p2) > 0) { ldns_rr_list2canonical(ldns_pkt_answer(p2)); ldns_rr_list_sort(ldns_pkt_answer(p2)); } if (p2 && ldns_pkt_nscount(p2) > 0) { ldns_rr_list2canonical(ldns_pkt_authority(p2)); ldns_rr_list_sort(ldns_pkt_authority(p2)); } if (p2 && ldns_pkt_arcount(p2) > 0) { ldns_rr_list2canonical(ldns_pkt_additional(p2)); ldns_rr_list_sort(ldns_pkt_additional(p2)); } /* simply do string comparison first */ pstr1 = ldns_pkt2str(p1); pstr2 = ldns_pkt2str(p2); if ((!p1 && !p2) || strcmp(pstr1, pstr2) != 0) { /* okay strings still differ, get the query and do a match for the match files */ pq = read_hex_pkt(d1->qdata); compare_result = compare_to_file(pq, p1, p2); if (compare_result != NULL) { /*fprintf(stderr, compare_result);*/ if (compare_result[strlen(compare_result)-1] == '\n') { compare_result[strlen(compare_result)-1] = 0; } file_nr = add_known_difference(compare_result); if (store_known_differences) { fprintf(known_differences[file_nr].file, "q: %d:%d\n%s\n%s\n%s\n", (int)d1->seq, (int)d2->seq, d1->qdata, d1->adata, d2->adata); } free(compare_result); diff = false; } else { diff=false; printf("Error: Unknown difference in packet number %u:\n", (unsigned int) total_nr_of_packets); ldns_pkt_print(stdout, pq); printf("\n"); ldns_pkt_print(stdout, p1); printf("\n"); ldns_pkt_print(stdout, p2); printf("Quitting at packet %u\n", (unsigned int) d1->seq); exit(1); } ldns_pkt_free(pq); } else { sames++; } if (diff) { if (show_originals) { fprintf(stdout, "%d:%d\n%s\n%s\n%s\n", (int)d1->seq, (int)d2->seq, d1->qdata, d1->adata, d2->adata); } else { fprintf(stdout, "%d:%d\n", (int)d1->seq, (int)d2->seq); if (!dump_hex(stdout, p1)) { fprintf(stdout, "%s", d1->adata); } fprintf(stdout, "\n"); if (!dump_hex(stdout, p2)) { fprintf(stdout, "%s", d2->adata); } fprintf(stdout, "\n"); } } LDNS_FREE(pstr1); LDNS_FREE(pstr2); ldns_pkt_free(p1); ldns_pkt_free(p2); } else { fprintf(stdout, "%d:%d\n%s\n%s\n%s\n", (int)d1->seq, (int)d2->seq, d1->qdata, d1->adata, d2->adata); } } else { sames++; bytesames++; } } }
int getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res) { int result; unsigned int i, j, index_ans, index_sig; struct rrsetinfo *rrset = NULL; struct rdatainfo *rdata; size_t len; ldns_resolver *ldns_res; ldns_rdf *domain = NULL; ldns_pkt *pkt = NULL; ldns_rr_list *rrsigs = NULL, *rrdata = NULL; ldns_status err; ldns_rr *rr; /* check for invalid class and type */ if (rdclass > 0xffff || rdtype > 0xffff) { result = ERRSET_INVAL; goto fail; } /* don't allow queries of class or type ANY */ if (rdclass == 0xff || rdtype == 0xff) { result = ERRSET_INVAL; goto fail; } /* don't allow flags yet, unimplemented */ if (flags) { result = ERRSET_INVAL; goto fail; } /* Initialize resolver from resolv.conf */ domain = ldns_dname_new_frm_str(hostname); if ((err = ldns_resolver_new_frm_file(&ldns_res, NULL)) != \ LDNS_STATUS_OK) { result = ERRSET_FAIL; goto fail; } #ifdef LDNS_DEBUG ldns_resolver_set_debug(ldns_res, true); #endif /* LDNS_DEBUG */ ldns_resolver_set_dnssec(ldns_res, true); /* Use DNSSEC */ /* make query */ pkt = ldns_resolver_query(ldns_res, domain, rdtype, rdclass, LDNS_RD); /*** TODO: finer errcodes -- see original **/ if (!pkt || ldns_pkt_ancount(pkt) < 1) { result = ERRSET_FAIL; goto fail; } /* initialize rrset */ rrset = calloc(1, sizeof(struct rrsetinfo)); if (rrset == NULL) { result = ERRSET_NOMEMORY; goto fail; } rrdata = ldns_pkt_rr_list_by_type(pkt, rdtype, LDNS_SECTION_ANSWER); rrset->rri_nrdatas = ldns_rr_list_rr_count(rrdata); if (!rrset->rri_nrdatas) { result = ERRSET_NODATA; goto fail; } /* copy name from answer section */ len = ldns_rdf_size(ldns_rr_owner(ldns_rr_list_rr(rrdata, 0))); if ((rrset->rri_name = malloc(len)) == NULL) { result = ERRSET_NOMEMORY; goto fail; } memcpy(rrset->rri_name, ldns_rdf_data(ldns_rr_owner(ldns_rr_list_rr(rrdata, 0))), len); rrset->rri_rdclass = ldns_rr_get_class(ldns_rr_list_rr(rrdata, 0)); rrset->rri_rdtype = ldns_rr_get_type(ldns_rr_list_rr(rrdata, 0)); rrset->rri_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrdata, 0)); debug2("ldns: got %u answers from DNS", rrset->rri_nrdatas); /* Check for authenticated data */ if (ldns_pkt_ad(pkt)) { rrset->rri_flags |= RRSET_VALIDATED; } else { /* AD is not set, try autonomous validation */ ldns_rr_list * trusted_keys = ldns_rr_list_new(); debug2("ldns: trying to validate RRset"); /* Get eventual sigs */ rrsigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, LDNS_SECTION_ANSWER); rrset->rri_nsigs = ldns_rr_list_rr_count(rrsigs); debug2("ldns: got %u signature(s) (RRTYPE %u) from DNS", rrset->rri_nsigs, LDNS_RR_TYPE_RRSIG); if ((err = ldns_verify_trusted(ldns_res, rrdata, rrsigs, trusted_keys)) == LDNS_STATUS_OK) { rrset->rri_flags |= RRSET_VALIDATED; debug2("ldns: RRset is signed with a valid key"); } else { debug2("ldns: RRset validation failed: %s", ldns_get_errorstr_by_id(err)); } ldns_rr_list_deep_free(trusted_keys); } /* allocate memory for answers */ rrset->rri_rdatas = calloc(rrset->rri_nrdatas, sizeof(struct rdatainfo)); if (rrset->rri_rdatas == NULL) { result = ERRSET_NOMEMORY; goto fail; } /* allocate memory for signatures */ if (rrset->rri_nsigs > 0) { rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); if (rrset->rri_sigs == NULL) { result = ERRSET_NOMEMORY; goto fail; } } /* copy answers & signatures */ for (i=0, index_ans=0, index_sig=0; i< pkt->_header->_ancount; i++) { rdata = NULL; rr = ldns_rr_list_rr(ldns_pkt_answer(pkt), i); if (ldns_rr_get_class(rr) == rrset->rri_rdclass && ldns_rr_get_type(rr) == rrset->rri_rdtype) { rdata = &rrset->rri_rdatas[index_ans++]; } if (rr->_rr_class == rrset->rri_rdclass && rr->_rr_type == LDNS_RR_TYPE_RRSIG && rrset->rri_sigs) { rdata = &rrset->rri_sigs[index_sig++]; } if (rdata) { size_t rdata_offset = 0; rdata->rdi_length = 0; for (j=0; j< rr->_rd_count; j++) { rdata->rdi_length += ldns_rdf_size(ldns_rr_rdf(rr, j)); } rdata->rdi_data = malloc(rdata->rdi_length); if (rdata->rdi_data == NULL) { result = ERRSET_NOMEMORY; goto fail; } /* Re-create the raw DNS RDATA */ for (j=0; j< rr->_rd_count; j++) { len = ldns_rdf_size(ldns_rr_rdf(rr, j)); memcpy(rdata->rdi_data + rdata_offset, ldns_rdf_data(ldns_rr_rdf(rr, j)), len); rdata_offset += len; } } } *res = rrset; result = ERRSET_SUCCESS; fail: /* freerrset(rrset); */ ldns_rdf_deep_free(domain); ldns_pkt_free(pkt); ldns_rr_list_deep_free(rrsigs); ldns_rr_list_deep_free(rrdata); ldns_resolver_deep_free(ldns_res); return result; }
ldns_status ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_list **nsec_rrs, ldns_rr_list **nsec_rr_sigs) { uint16_t nsec_i; ldns_rr_list *nsecs; ldns_status result; if (verbosity >= 5) { printf("VERIFY DENIAL FROM:\n"); ldns_pkt_print(stdout, pkt); } result = LDNS_STATUS_CRYPTO_NO_RRSIG; /* Try to see if there are NSECS in the packet */ nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC, LDNS_SECTION_ANY_NOQUESTION); if (nsecs) { for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsecs); nsec_i++) { /* there are four options: * - name equals ownername and is covered by the type bitmap * - name equals ownername but is not covered by the type bitmap * - name falls within nsec coverage but is not equal to the owner name * - name falls outside of nsec coverage */ if (ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), name) == 0) { /* printf("CHECKING NSEC:\n"); ldns_rr_print(stdout, ldns_rr_list_rr(nsecs, nsec_i)); printf("DAWASEM\n"); */ if (ldns_nsec_bitmap_covers_type( ldns_nsec_get_bitmap(ldns_rr_list_rr(nsecs, nsec_i)), type)) { /* Error, according to the nsec this rrset is signed */ result = LDNS_STATUS_CRYPTO_NO_RRSIG; } else { /* ok nsec denies existence */ if (verbosity >= 3) { printf(";; Existence of data set with this type denied by NSEC\n"); } /*printf(";; Verifiably insecure.\n");*/ if (nsec_rrs && nsec_rr_sigs) { (void) get_dnssec_rr(pkt, ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), LDNS_RR_TYPE_NSEC, nsec_rrs, nsec_rr_sigs); } ldns_rr_list_deep_free(nsecs); return LDNS_STATUS_OK; } } else if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, nsec_i), name)) { if (verbosity >= 3) { printf(";; Existence of data set with this name denied by NSEC\n"); } if (nsec_rrs && nsec_rr_sigs) { (void) get_dnssec_rr(pkt, ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), LDNS_RR_TYPE_NSEC, nsec_rrs, nsec_rr_sigs); } ldns_rr_list_deep_free(nsecs); return LDNS_STATUS_OK; } else { /* nsec has nothing to do with this data */ } } ldns_rr_list_deep_free(nsecs); } else if( (nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC3, LDNS_SECTION_ANY_NOQUESTION)) ) { ldns_rr_list* sigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, LDNS_SECTION_ANY_NOQUESTION); ldns_rr* q = ldns_rr_new(); if(!sigs) return LDNS_STATUS_MEM_ERR; if(!q) return LDNS_STATUS_MEM_ERR; ldns_rr_set_question(q, 1); ldns_rr_set_ttl(q, 0); ldns_rr_set_owner(q, ldns_rdf_clone(name)); if(!ldns_rr_owner(q)) return LDNS_STATUS_MEM_ERR; ldns_rr_set_type(q, type); result = ldns_dnssec_verify_denial_nsec3(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0); ldns_rr_free(q); ldns_rr_list_deep_free(nsecs); ldns_rr_list_deep_free(sigs); } return result; }
ldns_status output_packet(ldns_buffer *output, const ldns_pkt *pkt, struct sockaddr_storage sa, lookup_context_t* context) { const ldns_output_format *fmt = ldns_output_format_nocomments; uint16_t i; ldns_status status = LDNS_STATUS_OK; time_t now = time(NULL); char nsbuffer[INET6_ADDRSTRLEN]; char* ip_prefix = ""; char* ip_suffix = ""; switch (((struct sockaddr *) &sa)->sa_family) { case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in *) &sa)->sin_addr), nsbuffer, INET_ADDRSTRLEN); break; case AF_INET6: inet_ntop(AF_INET6, &(((struct sockaddr_in6 *) &sa)->sin6_addr), nsbuffer, INET6_ADDRSTRLEN); ip_prefix = "["; ip_suffix = "]"; break; default: exit(1); } if (!pkt) { if(0 > ldns_buffer_printf(output, "")) { abort(); } return LDNS_STATUS_OK; } if(!context->cmd_args.only_responses) { if(0 > ldns_buffer_printf(output, "%s%s%s:%u %ld ", ip_prefix, ip_suffix, nsbuffer, ntohs(((struct sockaddr_in *) &sa)->sin_port), now)) { abort(); } for (i = 0; i < ldns_pkt_qdcount(pkt); i++) { status = ldns_rr2buffer_str_fmt(output, fmt, ldns_rr_list_rr(ldns_pkt_question(pkt), i)); if (status != LDNS_STATUS_OK) { return status; } } } if (ldns_buffer_status_ok(output)) { for (i = 0; i < ldns_pkt_ancount(pkt); i++) { if(!context->cmd_args.only_responses) { if(0 > ldns_buffer_printf(output, "\t")) { abort(); } } status = ldns_rr2buffer_str_fmt(output, fmt, ldns_rr_list_rr(ldns_pkt_answer(pkt), i)); if (status != LDNS_STATUS_OK) { return status; } } if(!context->cmd_args.no_authority) { if(0 > ldns_buffer_printf(output, "\n")) { abort(); } for (i = 0; i < ldns_pkt_nscount(pkt); i++) { if(!context->cmd_args.only_responses) { ldns_buffer_printf(output, "\t"); } status = ldns_rr2buffer_str_fmt(output, fmt, ldns_rr_list_rr(ldns_pkt_authority(pkt), i)); if (status != LDNS_STATUS_OK) { return status; } } } if(context->cmd_args.additional) { for (i = 0; i < ldns_pkt_arcount(pkt); i++) { if(!context->cmd_args.only_responses) { ldns_buffer_printf(output, "\t"); } status = ldns_rr2buffer_str_fmt(output, fmt, ldns_rr_list_rr(ldns_pkt_additional(pkt), i)); if (status != LDNS_STATUS_OK) { return status; } } } } else { return ldns_buffer_status(output); } return status; }
int output_cbor(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char *payload, size_t payloadlen) { ldns_pkt *pkt = 0; ldns_status ldns_rc; if (!payload) { return DUMP_CBOR_EINVAL; } if (!payloadlen) { return DUMP_CBOR_EINVAL; } /* if (!cbor_stringrefs) {*/ /* cbor_stringrefs = calloc(1, cbor_stringref_size);*/ /* }*/ if (!cbor_buf) { if (!(cbor_buf = calloc(1, cbor_size + cbor_reserve))) { return DUMP_CBOR_ENOMEM; } } if (cbor_flushed) { CborError cbor_err; cbor_encoder_init(&cbor_root, cbor_buf, cbor_size, 0); /* cbor_err = cbor_encode_tag(&cbor_root, 256);*/ /* if (cbor_err == CborNoError)*/ cbor_err = cbor_encoder_create_array(&cbor_root, &cbor_pkts, CborIndefiniteLength); if (cbor_err != CborNoError) { fprintf(stderr, "cbor init error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); return DUMP_CBOR_ECBOR; } cbor_flushed = 0; } ldns_rc = ldns_wire2pkt(&pkt, payload, payloadlen); if (ldns_rc != LDNS_STATUS_OK) { fprintf(stderr, "ldns error [%d]: %s\n", ldns_rc, ldns_get_errorstr_by_id(ldns_rc)); return DUMP_CBOR_ELDNS; } if (!pkt) { return DUMP_CBOR_ELDNS; } CborEncoder cbor, ip; CborError cbor_err = CborNoError; int should_flush = 0; cbor_err = append_cbor_map(&cbor_pkts, &cbor, CborIndefiniteLength, &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "dateSeconds", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_double(&cbor, (double)ts.tv_sec + ( (double)ts.tv_usec / 1000000 ), &should_flush); /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "dateNanoFractions", &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ts.tv_usec * 1000, &should_flush);*/ if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "ip", &should_flush); /* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, proto, &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "sourceIpAddress", &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, ia_str(from), &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "sourcePort", &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, sport, &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "destinationIpAddress", &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, ia_str(to), &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "destinationPort", &should_flush);*/ /* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, dport, &should_flush);*/ if (cbor_err == CborNoError) cbor_err = append_cbor_array(&cbor, &ip, CborIndefiniteLength, &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&ip, proto, &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&ip, ia_str(from), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&ip, sport, &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&ip, ia_str(to), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&ip, dport, &should_flush); if (cbor_err == CborNoError) cbor_err = close_cbor_container(&cbor, &ip, &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "ID", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_pkt_id(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "QR", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_boolean(&cbor, ldns_pkt_qr(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "Opcode", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_pkt_get_opcode(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "AA", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_boolean(&cbor, ldns_pkt_aa(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "TC", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_boolean(&cbor, ldns_pkt_tc(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "RD", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_boolean(&cbor, ldns_pkt_rd(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "RA", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_boolean(&cbor, ldns_pkt_ra(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "AD", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_boolean(&cbor, ldns_pkt_ad(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "CD", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_boolean(&cbor, ldns_pkt_cd(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "RCODE", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_pkt_get_rcode(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "QDCOUNT", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_pkt_qdcount(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "ANCOUNT", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_pkt_ancount(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "NSCOUNT", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_pkt_nscount(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "ARCOUNT", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_pkt_arcount(pkt), &should_flush); /* questionRRs */ if (ldns_pkt_qdcount(pkt) > 0) { ldns_rr_list *list = ldns_pkt_question(pkt); ldns_rr *rr; size_t n, qdcount = ldns_pkt_qdcount(pkt); ldns_buffer *dname; char *dname_str; if (!list) { ldns_pkt_free(pkt); return DUMP_CBOR_ELDNS; } rr = ldns_rr_list_rr(list, 0); if (!rr) { ldns_pkt_free(pkt); return DUMP_CBOR_ELDNS; } if (!(dname = ldns_buffer_new(512))) { ldns_pkt_free(pkt); return DUMP_CBOR_ENOMEM; } if (ldns_rdf2buffer_str_dname(dname, ldns_rr_owner(rr)) != LDNS_STATUS_OK) { ldns_buffer_free(dname); ldns_pkt_free(pkt); return DUMP_CBOR_ELDNS; } ldns_buffer_write_u8(dname, 0); if (!(dname_str = ldns_buffer_export(dname))) { ldns_buffer_free(dname); ldns_pkt_free(pkt); return DUMP_CBOR_ENOMEM; } if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "QNAME", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, dname_str, &should_flush); free(dname_str); ldns_buffer_free(dname); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "QCLASS", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_rr_get_class(rr), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "QTYPE", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ldns_rr_get_type(rr), &should_flush); if (qdcount > 1) { CborEncoder queries; if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "questionRRs", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_array(&cbor, &queries, CborIndefiniteLength, &should_flush); for (n = 1; cbor_err == CborNoError && n < qdcount; n++) { CborEncoder query; rr = ldns_rr_list_rr(list, n); if (!rr) { ldns_pkt_free(pkt); return DUMP_CBOR_ELDNS; } if (!(dname = ldns_buffer_new(512))) { ldns_pkt_free(pkt); return DUMP_CBOR_ENOMEM; } if (ldns_rdf2buffer_str_dname(dname, ldns_rr_owner(rr)) != LDNS_STATUS_OK) { ldns_buffer_free(dname); ldns_pkt_free(pkt); return DUMP_CBOR_ELDNS; } ldns_buffer_write_u8(dname, 0); if (!(dname_str = ldns_buffer_export(dname))) { ldns_buffer_free(dname); ldns_pkt_free(pkt); return DUMP_CBOR_ENOMEM; } if (cbor_err == CborNoError) cbor_err = append_cbor_map(&queries, &query, CborIndefiniteLength, &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&query, "NAME", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&query, dname_str, &should_flush); free(dname_str); ldns_buffer_free(dname); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&query, "CLASS", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&query, ldns_rr_get_class(rr), &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&query, "TYPE", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&query, ldns_rr_get_type(rr), &should_flush); if (cbor_err == CborNoError) cbor_err = close_cbor_container(&queries, &query, &should_flush); } if (cbor_err == CborNoError) cbor_err = close_cbor_container(&cbor, &queries, &should_flush); } } /* answerRRs */ if (ldns_pkt_ancount(pkt) > 0) { CborEncoder cbor_rrs; if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "answerRRs", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush); cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_answer(pkt), ldns_pkt_ancount(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush); } /* authorityRRs */ if (ldns_pkt_nscount(pkt) > 0) { CborEncoder cbor_rrs; if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "authorityRRs", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush); cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_authority(pkt), ldns_pkt_nscount(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush); } /* additionalRRs */ if (ldns_pkt_arcount(pkt) > 0) { CborEncoder cbor_rrs; if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "additionalRRs", &should_flush); if (cbor_err == CborNoError) cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush); cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_additional(pkt), ldns_pkt_arcount(pkt), &should_flush); if (cbor_err == CborNoError) cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush); } ldns_pkt_free(pkt); if (cbor_err == CborNoError) cbor_err = close_cbor_container(&cbor_pkts, &cbor, &should_flush); if (cbor_err != CborNoError) { fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); return DUMP_CBOR_ECBOR; } if (should_flush) { if ((cbor_err = cbor_encoder_close_container_checked(&cbor_root, &cbor_pkts)) != CborNoError) { fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err)); return DUMP_CBOR_ECBOR; } fprintf(stderr, "cbor output: %lu bytes\n", cbor_encoder_get_buffer_size(&cbor_root, cbor_buf)); cbor_flushed = 1; return DUMP_CBOR_FLUSH; } return DUMP_CBOR_OK; }