int cache_dns_objects(packetinfo *pi, ldns_rdf *rdf_data, ldns_buffer *buff, ldns_pkt *dns_pkt) { int j; int dns_answer_domain_cnt; uint64_t dnshash; ldns_status status; pdns_record *pr = NULL; ldns_rr_list *dns_answer_domains; unsigned char *domain_name = 0; ldns_buffer_clear(buff); status = ldns_rdf2buffer_str(buff, rdf_data); if (status != LDNS_STATUS_OK) { dlog("[D] Error in ldns_rdf2buffer_str(): %d\n", status); return(-1); } dns_answer_domains = ldns_pkt_answer(dns_pkt); dns_answer_domain_cnt = ldns_rr_list_rr_count(dns_answer_domains); domain_name = (unsigned char *) ldns_buffer2str(buff); if (domain_name == NULL) { dlog("[D] Error in ldns_buffer2str(%p)\n", buff); return(-1); } else { dlog("[D] domain_name: %s\n", domain_name); dlog("[D] dns_answer_domain_cnt: %d\n",dns_answer_domain_cnt); } if (dns_answer_domain_cnt == 0 && ldns_pkt_get_rcode(dns_pkt) != 0) { uint16_t rcode = ldns_pkt_get_rcode(dns_pkt); dlog("[D] Error return code: %d\n", rcode); /* PROBLEM: * As there is no valid ldns_rr here and we cant fake one that will * be very unique, we cant push this to the normal * bucket[hash->linked_list]. We should probably allocate a static * bucket[MAX_NXDOMAIN] to hold NXDOMAINS, and when that is full, pop * out the oldest (LRU). A simple script quering for random non existing * domains could easly put stress on passivedns (think conficker etc.) * if the bucket is to big or non efficient. We would still store data * such as: fistseen,lastseen,client_ip,server_ip,class,query,NXDOMAIN */ if (config.dnsfe & (pdns_chk_dnsfe(rcode))) { ldns_rr_list *dns_query_domains; ldns_rr_class class; ldns_rr_type type; ldns_rr *rr; dnshash = hash(domain_name); dlog("[D] Hash: %lu\n", dnshash); /* Check if the node exists, if not, make it */ pr = get_pdns_record(dnshash, pi, domain_name); /* Set the SRC flag: */ //lname_node->srcflag |= pdns_chk_dnsfe(rcode); dns_query_domains = ldns_pkt_question(dns_pkt); rr = ldns_rr_list_rr(dns_query_domains, 0); class = ldns_rr_get_class(rr); type = ldns_rr_get_type(rr); if ((pr->last_seen.tv_sec - pr->last_print.tv_sec) >= config.dnsprinttime) { /* Print the SRC Error record */ print_passet_err(pr, rdf_data, rr, rcode); } } else {
int cache_dns_objects(packetinfo *pi, ldns_rdf *rdf_data, ldns_buffer *buff, ldns_pkt *dns_pkt) { int j; int dns_answer_domain_cnt; uint64_t dnshash; ldns_status status; pdns_record *pr = NULL; ldns_rr_list *dns_answer_domains; unsigned char *domain_name = 0; ldns_buffer_clear(buff); status = ldns_rdf2buffer_str(buff, rdf_data); if (status != LDNS_STATUS_OK) { dlog("[D] Error in ldns_rdf2buffer_str(): %d\n", status); return -1; } dns_answer_domains = ldns_pkt_answer(dns_pkt); dns_answer_domain_cnt = ldns_rr_list_rr_count(dns_answer_domains); domain_name = (unsigned char *) ldns_buffer2str(buff); if (domain_name == NULL) { dlog("[D] Error in ldns_buffer2str(%p)\n", buff); return -1; } else { dlog("[D] domain_name: %s\n", domain_name); dlog("[D] dns_answer_domain_cnt: %d\n",dns_answer_domain_cnt); } if (dns_answer_domain_cnt == 0 && ldns_pkt_get_rcode(dns_pkt) != 0) { uint16_t rcode = ldns_pkt_get_rcode(dns_pkt); dlog("[D] Error return code: %d\n", rcode); /* PROBLEM: * As there is no valid ldns_rr here and we can't fake one that will * be very unique, we cant push this to the normal * bucket[hash->linked_list]. We should probably allocate a static * bucket[MAX_NXDOMAIN] to hold NXDOMAINS, and when that is full, pop * out the oldest (LRU). A simple script querying for random non-existing * domains could easily put stress on passivedns (think conficker etc.) * if the bucket is to big or non-efficient. We would still store data * such as: firstseen,lastseen,client_ip,server_ip,class,query,NXDOMAIN */ if (config.dnsfe & (pdns_chk_dnsfe(rcode))) { ldns_rr_list *dns_query_domains; ldns_rr *rr; dnshash = hash(domain_name); dlog("[D] Hash: %lu\n", dnshash); /* Check if the node exists, if not, make it */ pr = get_pdns_record(dnshash, pi, domain_name); /* Set the SRC flag: */ //lname_node->srcflag |= pdns_chk_dnsfe(rcode); dns_query_domains = ldns_pkt_question(dns_pkt); rr = ldns_rr_list_rr(dns_query_domains, 0); if ((pr->last_seen.tv_sec - pr->last_print.tv_sec) >= config.dnsprinttime) { /* Print the SRC Error record */ print_passet(pr, NULL, rr, rdf_data, rcode); } } else { dlog("[D] Error return code %d was not processed:%d\n", pdns_chk_dnsfe(rcode), config.dnsfe); } free(domain_name); return 0; } for (j = 0; j < dns_answer_domain_cnt; j++) { int offset = -1; ldns_rr *rr; ldns_rdf *rname; unsigned char *rdomain_name = 0; rr = ldns_rr_list_rr(dns_answer_domains, j); switch (ldns_rr_get_type(rr)) { case LDNS_RR_TYPE_AAAA: if (config.dnsf & DNS_CHK_AAAA) offset = 0; break; case LDNS_RR_TYPE_A: if (config.dnsf & DNS_CHK_A) offset = 0; break; case LDNS_RR_TYPE_PTR: if (config.dnsf & DNS_CHK_PTR) offset = 0; break; case LDNS_RR_TYPE_CNAME: if (config.dnsf & DNS_CHK_CNAME) offset = 0; break; case LDNS_RR_TYPE_DNAME: if (config.dnsf & DNS_CHK_DNAME) offset = 0; break; case LDNS_RR_TYPE_NAPTR: if (config.dnsf & DNS_CHK_NAPTR) offset = 0; break; case LDNS_RR_TYPE_RP: if (config.dnsf & DNS_CHK_RP) offset = 0; break; case LDNS_RR_TYPE_SRV: if (config.dnsf & DNS_CHK_SRV) offset = 3; break; case LDNS_RR_TYPE_TXT: if (config.dnsf & DNS_CHK_TXT) offset = 0; break; case LDNS_RR_TYPE_SOA: if (config.dnsf & DNS_CHK_SOA) offset = 0; break; case LDNS_RR_TYPE_MX: if (config.dnsf & DNS_CHK_MX) offset = 1; break; case LDNS_RR_TYPE_NS: if (config.dnsf & DNS_CHK_NS) offset = 0; break; default: offset = -1; dlog("[D] ldns_rr_get_type: %d\n", ldns_rr_get_type(rr)); break; } if (offset == -1) { dlog("[D] LDNS_RR_TYPE not enabled/supported: %d\n", ldns_rr_get_type(rr)); //data_offset = 0; continue; } /* Get the rdf data from the rr */ rname = ldns_rr_rdf(rr, offset); if (rname == NULL) { dlog("[D] ldns_rr_rdf returned: NULL\n"); continue; } ldns_buffer_clear(buff); ldns_rdf2buffer_str(buff, rname); rdomain_name = (unsigned char *) ldns_buffer2str(buff); if (rdomain_name == NULL) { dlog("[D] ldns_buffer2str returned: NULL\n"); continue; } dlog("[D] rdomain_name: %s\n", rdomain_name); if (pr == NULL) { dnshash = hash(domain_name); dlog("[D] Hash: %lu\n", dnshash); /* Check if the node exists, if not, make it */ pr = get_pdns_record(dnshash, pi, domain_name); } /* Update the pdns record with the pdns asset */ update_pdns_record_asset(pi, pr, rr, rdomain_name); /* If CNAME, free domain_name, and cp rdomain_name to domain_name */ if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_CNAME) { if (config.dnsf & DNS_CHK_CNAME) { int len; free(domain_name); len = strlen((char *)rdomain_name); domain_name = calloc(1, (len + 1)); strncpy((char *)domain_name, (char *)rdomain_name, len); dnshash = hash(domain_name); dlog("[D] Hash: %lu\n", dnshash); pr = get_pdns_record(dnshash, pi, domain_name); } } /* Free the rdomain_name */ free(rdomain_name); } free(domain_name); return 0; }