From 0ea58c6db429253a2b24c8dfa8f454e569b3b47c Mon Sep 17 00:00:00 2001 From: Mats Klepsland Date: Sat, 26 Dec 2015 13:38:19 +0100 Subject: [PATCH] Code cleanup --- src/dns.c | 260 ++++++++++++++++++++++------------------------- src/passivedns.c | 187 +++++++++++++++++----------------- 2 files changed, 215 insertions(+), 232 deletions(-) diff --git a/src/dns.c b/src/dns.c index 88adc08..756afcb 100644 --- a/src/dns.c +++ b/src/dns.c @@ -61,9 +61,9 @@ void dns_parser(packetinfo *pi) status = LDNS_STATUS_ERR; /* In DNS tcp messages, the first 2 bytes signal the - * amount of data to expect. So we need to skip them in the read. - */ - if (pi->plen <= 2) return; /* The minimum bytes in a packet, else return */ + * amount of data to expect. So we need to skip them in the read. */ + if (pi->plen <= 2) + return; /* The minimum bytes in a packet, else return */ if (pi->af == AF_INET) { switch (pi->ip4->ip_p) { @@ -162,9 +162,8 @@ void dns_parser(packetinfo *pi) } /* Send it off for processing */ - if (process_dns_answer(pi, dns_pkt) < 0) { + if (process_dns_answer(pi, dns_pkt) < 0) dlog("[D] process_dns_answer() returned -1\n"); - } } else { /* We need to get the DNS TID from the Query to later match with the @@ -195,9 +194,8 @@ void dns_parser(packetinfo *pi) * the TID in its tuple, but still this will make a mess :/ */ } - else { + else dlog("[D] New DNS Query\n"); - } if (!ldns_pkt_qdcount(dns_pkt)) { /* No questions or answers */ @@ -207,9 +205,9 @@ void dns_parser(packetinfo *pi) return; } - if ((pi->cxt->plid = ldns_pkt_id(dns_pkt))) { + if ((pi->cxt->plid = ldns_pkt_id(dns_pkt))) dlog("[D] DNS Query with TID = %d\n", pi->cxt->plid); - } + else { dlog("[E] Error getting DNS TID from Query!\n"); ldns_pkt_free(dns_pkt); @@ -223,8 +221,8 @@ void dns_parser(packetinfo *pi) int process_dns_answer(packetinfo *pi, ldns_pkt *dns_pkt) { - int rrcount_query; - int j; + int rrcount_query; + int j; ldns_rr_list *dns_query_domains; ldns_buffer *dns_buff; @@ -235,15 +233,15 @@ int process_dns_answer(packetinfo *pi, ldns_pkt *dns_pkt) /* Do we ever have more than one question? If we do, are we handling it correctly? */ - for (j = 0; j < rrcount_query; j++) { + for (j = 0; j < rrcount_query; j++) + { ldns_rdf *rdf_data; rdf_data = ldns_rr_owner(ldns_rr_list_rr(dns_query_domains, j)); dlog("[D] rdf_data: %p\n", rdf_data); - if (cache_dns_objects(pi, rdf_data, dns_buff, dns_pkt) != 0) { + if (cache_dns_objects(pi, rdf_data, dns_buff, dns_pkt) != 0) dlog("[D] cache_dns_objects() returned error\n"); - } } ldns_buffer_free(dns_buff); @@ -254,12 +252,12 @@ int process_dns_answer(packetinfo *pi, ldns_pkt *dns_pkt) 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; + 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); @@ -270,9 +268,9 @@ int cache_dns_objects(packetinfo *pi, ldns_rdf *rdf_data, return -1; } - dns_answer_domains = ldns_pkt_answer(dns_pkt); + 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); + domain_name = (unsigned char *) ldns_buffer2str(buff); if (domain_name == NULL) { dlog("[D] Error in ldns_buffer2str(%p)\n", buff); @@ -298,8 +296,8 @@ int cache_dns_objects(packetinfo *pi, ldns_rdf *rdf_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; + ldns_rr_list *dns_query_domains; + ldns_rr *rr; dnshash = hash(domain_name); dlog("[D] Hash: %lu\n", dnshash); @@ -314,30 +312,32 @@ int cache_dns_objects(packetinfo *pi, ldns_rdf *rdf_data, /* Print the SRC Error record */ print_passet(pr, NULL, rr, rdf_data, rcode); } - } else { + } + 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; - int to_offset = -1; - int len; - ldns_rr *rr; - ldns_rdf *rname; - unsigned char *rdomain_name = 0, *tmp1=NULL, *tmp2=NULL; + int offset = -1; + int to_offset = -1; + int len; + ldns_rr *rr; + ldns_rdf *rname; + unsigned char *rdomain_name = 0; + unsigned char *tmp1 = NULL; + unsigned char *tmp2 = NULL; rr = ldns_rr_list_rr(dns_answer_domains, j); switch (ldns_rr_get_type(rr)) { case LDNS_RR_TYPE_LOC: - if (config.dnsf & DNS_CHK_LOC) { + if (config.dnsf & DNS_CHK_LOC) offset = 0; - } break; case LDNS_RR_TYPE_GPOS: if (config.dnsf & DNS_CHK_LOC) { @@ -459,7 +459,6 @@ int cache_dns_objects(packetinfo *pi, ldns_rdf *rdf_data, if (offset == -1) { dlog("[D] LDNS_RR_TYPE not enabled/supported: %d\n", ldns_rr_get_type(rr)); - //data_offset = 0; continue; } do { @@ -469,32 +468,38 @@ int cache_dns_objects(packetinfo *pi, ldns_rdf *rdf_data, if (rname == NULL) { dlog("[D] ldns_rr_rdf returned: NULL\n"); - break;; + break; } ldns_rdf2buffer_str(buff, rname); rdomain_name = (unsigned char *) ldns_buffer2str(buff); - if (rdomain_name == NULL) continue; + + if (rdomain_name == NULL) + continue; len = strlen(rdomain_name) + 5; - if (tmp1 != NULL) len += strlen(tmp1); + + if (tmp1 != NULL) + len += strlen(tmp1); tmp2 = malloc(len); + if (tmp1 != NULL) { tmp2 = strcpy(tmp2, tmp1); tmp2 = strcat(tmp2, " "); } - else { + else tmp2 = strcpy(tmp2, ""); - } + free(tmp1); tmp2 = strcat(tmp2, rdomain_name); tmp1 = tmp2; free(rdomain_name); offset ++; } while (offset < to_offset); + rdomain_name = tmp1; - if (rname == NULL) { + + if (rname == NULL) continue; - } if (rdomain_name == NULL && offset <= 1) { dlog("[D] ldns_buffer2str returned: NULL\n"); @@ -537,9 +542,9 @@ void update_pdns_record_asset(packetinfo *pi, pdns_record *pr, ldns_rr *rr, unsigned char *rdomain_name) { pdns_asset *passet = pr->passet; - pdns_asset *head = passet; - ldns_rr *prr = NULL; - uint32_t len = 0; + pdns_asset *head = passet; + ldns_rr *prr = NULL; + uint32_t len = 0; dlog("Searching: %u, %s, %s\n", rr->_rr_type, pr->qname, rdomain_name); @@ -553,7 +558,7 @@ void update_pdns_record_asset(packetinfo *pi, pdns_record *pr, dlog("[*] rr match\n"); dlog("r:%s == a:%s\n", rdomain_name, passet->answer); if (strcmp((const char *)rdomain_name, - (const char *)passet->answer) == 0 ) { + (const char *)passet->answer) == 0 ) { dlog("[*] rname/answer match\n"); /* We have this, update and if its over 24h since last print - print it, then return */ @@ -561,14 +566,12 @@ void update_pdns_record_asset(packetinfo *pi, pdns_record *pr, passet->last_seen = pi->pheader->ts; passet->cip = pi->cxt->s_ip; /* This should always be the client IP */ passet->sip = pi->cxt->d_ip; /* This should always be the server IP */ - if (rr->_ttl > passet->rr->_ttl) { - passet->rr->_ttl = rr->_ttl; /* Catch the highest TTL seen */ - } + if (rr->_ttl > passet->rr->_ttl) + passet->rr->_ttl = rr->_ttl; /* Catch the highest TTL seen */ dlog("[*] DNS asset updated...\n"); if ((passet->last_seen.tv_sec - - passet->last_print.tv_sec) >= config.dnsprinttime) { + passet->last_print.tv_sec) >= config.dnsprinttime) print_passet(pr, passet, passet->rr, NULL, 0); - } return; } } @@ -582,36 +585,34 @@ void update_pdns_record_asset(packetinfo *pi, pdns_record *pr, config.p_s.dns_assets++; config.dns_assets++; prr = (ldns_rr*) calloc(1, sizeof(ldns_rr)); - prr->_owner = rr->_owner; - prr->_ttl = rr->_ttl; - prr->_rd_count = rr->_rd_count; - prr->_rr_type = rr->_rr_type; - prr->_rr_class = rr->_rr_class; + prr->_owner = rr->_owner; + prr->_ttl = rr->_ttl; + prr->_rd_count = rr->_rd_count; + prr->_rr_type = rr->_rr_type; + prr->_rr_class = rr->_rr_class; prr->_rdata_fields = rr->_rdata_fields; passet->seen = 1; passet->rr = prr; } - else { + else dlog("[D] BAD\n"); - } if (head != NULL ) { head->prev = passet; passet->next = head; } - else { + else passet->next = NULL; - } /* Populate new values */ passet->first_seen = pi->pheader->ts; - passet->last_seen = pi->pheader->ts; - passet->af = pi->cxt->af; - passet->cip = pi->cxt->s_ip; /* This should always be the client IP */ - passet->sip = pi->cxt->d_ip; /* This should always be the server IP */ - passet->prev = NULL; - len = strlen((char *)rdomain_name); - passet->answer = calloc(1, (len + 1)); + passet->last_seen = pi->pheader->ts; + passet->af = pi->cxt->af; + passet->cip = pi->cxt->s_ip; /* This should always be the client IP */ + passet->sip = pi->cxt->d_ip; /* This should always be the server IP */ + passet->prev = NULL; + len = strlen((char *)rdomain_name); + passet->answer = calloc(1, (len + 1)); strncpy((char *)passet->answer, (char *)rdomain_name, len); dlog("[D] Adding: %u, %s, %s\n",passet->rr->_rr_type, pr->qname, @@ -677,19 +678,17 @@ void print_passet(pdns_record *l, pdns_asset *p, ldns_rr *rr, #endif /* HAVE_JSON */ /* If pdns_asset is not defined, then this is a NXD record */ - if (p == NULL) { + if (p == NULL) is_err_record = 1; - } /* Use the correct file descriptor */ if (is_err_record && config.output_log_nxd) { - if (config.logfile_all) { + if (config.logfile_all) fd = config.logfile_fd; - } - else { + else fd = config.logfile_nxd_fd; - } - if (fd == NULL) return; + if (fd == NULL) + return; } else if (!is_err_record && config.output_log) { fd = config.logfile_fd; @@ -804,12 +803,10 @@ void print_passet(pdns_record *l, pdns_asset *p, ldns_rr *rr, snprintf(rr_type, 10, "MX"); break; default: - if (is_err_record) { + if (is_err_record) snprintf(rr_type, 10, "%d", ldns_rdf_get_type(lname)); - } - else { + else snprintf(rr_type, 10, "%d", p->rr->_rr_type); - } break; } @@ -853,7 +850,7 @@ void print_passet(pdns_record *l, pdns_asset *p, ldns_rr *rr, #ifdef HAVE_JSON if ((is_err_record && config.use_json_nxd) || - (!is_err_record && config.use_json)) { + (!is_err_record && config.use_json)) { jdata = json_object(); /* Print timestamp(s) */ @@ -963,39 +960,33 @@ void print_passet(pdns_record *l, pdns_asset *p, ldns_rr *rr, char timestr[200]; tmpTime = localtime(&l->last_seen.tv_sec); strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tmpTime); - if (is_err_record) { + if (is_err_record) offset += snprintf(output, sizeof(buffer) - offset, "%s.%06lu", timestr, l->last_seen.tv_usec); - } else { + else offset += snprintf(output, sizeof(buffer) - offset, "%s.%06lu", timestr, p->last_seen.tv_usec); - } - } else if ((config.fieldsf & FIELD_TIMESTAMP_S) && - (config.fieldsf & FIELD_TIMESTAMP_MS)) { - if (is_err_record) { + } + else if ((config.fieldsf & FIELD_TIMESTAMP_S) && + (config.fieldsf & FIELD_TIMESTAMP_MS)) { + if (is_err_record) offset += snprintf(output, sizeof(buffer) - offset, "%lu.%06lu", l->last_seen.tv_sec, l->last_seen.tv_usec); - } - else { + else offset += snprintf(output, sizeof(buffer) - offset, "%lu.%06lu", p->last_seen.tv_sec, p->last_seen.tv_usec); - } } else if (config.fieldsf & FIELD_TIMESTAMP_S) { - if (is_err_record) { + if (is_err_record) offset += snprintf(output, sizeof(buffer) - offset, "%lu", l->last_seen.tv_sec); - } - else { + else offset += snprintf(output, sizeof(buffer) - offset, "%lu", p->last_seen.tv_sec); - } } else if (config.fieldsf & FIELD_TIMESTAMP_MS) { - if (is_err_record) { + if (is_err_record) offset += snprintf(output, sizeof(buffer) - offset, "%06lu", l->last_seen.tv_usec); - } - else { + else offset += snprintf(output, sizeof(buffer) - offset, "%06lu", p->last_seen.tv_usec); - } } /* Print client IP */ @@ -1074,7 +1065,7 @@ void print_passet(pdns_record *l, pdns_asset *p, ldns_rr *rr, /* Print to syslog */ if ((is_err_record && config.output_syslog_nxd) || - (!is_err_record && config.output_syslog)) { + (!is_err_record && config.output_syslog)) { openlog(PDNS_IDENT, LOG_NDELAY, LOG_LOCAL7); syslog(LOG_INFO, "%s", output); closelog(); @@ -1107,19 +1098,19 @@ pdns_record *get_pdns_record(uint64_t dnshash, packetinfo *pi, unsigned char *domain_name) { pdns_record *pdnsr = dbucket[dnshash]; - pdns_record *head = pdnsr; - uint32_t len = 0; + pdns_record *head = pdnsr; + uint32_t len = 0; /* Search through the bucket */ while (pdnsr != NULL) { /* If found, update and return dnsr */ if (strcmp((const char *)domain_name, - (const char *)pdnsr->qname) == 0) { + (const char *)pdnsr->qname) == 0) { /* match :) */ pdnsr->last_seen = pi->pheader->ts; - pdnsr->cip = pi->cxt->s_ip; /* This should always be the client IP */ - pdnsr->sip = pi->cxt->d_ip; /* This should always be the server IP */ + pdnsr->cip = pi->cxt->s_ip; /* This should always be the client IP */ + pdnsr->sip = pi->cxt->d_ip; /* This should always be the server IP */ return pdnsr; } pdnsr = pdnsr->next; @@ -1132,21 +1123,21 @@ pdns_record *get_pdns_record(uint64_t dnshash, packetinfo *pi, config.p_s.dns_records++; config.dns_records++; } - if (head != NULL) { + if (head != NULL) head->prev = pdnsr; - } + /* Populate new values */ pdnsr->first_seen = pi->pheader->ts; - pdnsr->last_seen = pi->pheader->ts; - pdnsr->af = pi->cxt->af; - pdnsr->nxflag = 0; - pdnsr->cip = pi->cxt->s_ip; /* This should always be the client IP */ - pdnsr->sip = pi->cxt->d_ip; /* This should always be the server IP */ - pdnsr->next = head; - pdnsr->prev = NULL; - pdnsr->passet = NULL; - len = strlen((char *)domain_name); - pdnsr->qname = calloc(1, (len + 1)); + pdnsr->last_seen = pi->pheader->ts; + pdnsr->af = pi->cxt->af; + pdnsr->nxflag = 0; + pdnsr->cip = pi->cxt->s_ip; /* This should always be the client IP */ + pdnsr->sip = pi->cxt->d_ip; /* This should always be the server IP */ + pdnsr->next = head; + pdnsr->prev = NULL; + pdnsr->passet = NULL; + len = strlen((char *)domain_name); + pdnsr->qname = calloc(1, (len + 1)); strncpy((char *)pdnsr->qname, (char *)domain_name, len); dbucket[dnshash] = pdnsr; @@ -1190,9 +1181,8 @@ void expire_dns_records() pdnsr = pdnsr->next; delete_dns_record(tmp, &dbucket[iter]); - if (pdnsr == NULL && tmp_prev == NULL ) { + if (pdnsr == NULL && tmp_prev == NULL) dbucket[iter] = NULL; - } } else { /* Search through a domain record for assets to expire */ @@ -1250,19 +1240,18 @@ void expire_all_dns_records() pdnsr = pdnsr->next; delete_dns_record(tmp, &dbucket[iter]); - if (pdnsr == NULL) { + if (pdnsr == NULL) dbucket[iter] = NULL; - } } } } void delete_dns_record(pdns_record * pdnsr, pdns_record ** bucket_ptr) { - pdns_record *prev = pdnsr->prev; /* Older DNS record */ - pdns_record *next = pdnsr->next; /* Newer DNS record */ - pdns_asset *asset = pdnsr->passet; - pdns_asset *tmp_asset; + pdns_record *prev = pdnsr->prev; /* Older DNS record */ + pdns_record *next = pdnsr->next; /* Newer DNS record */ + pdns_asset *asset = pdnsr->passet; + pdns_asset *tmp_asset; dlog("[D] Deleting domain record: %s\n", pdnsr->qname); @@ -1271,13 +1260,12 @@ void delete_dns_record(pdns_record * pdnsr, pdns_record ** bucket_ptr) { /* Print the asset before we expires if it * has been updated since it last was printed */ - if (asset->last_seen.tv_sec > asset->last_print.tv_sec) { + if (asset->last_seen.tv_sec > asset->last_print.tv_sec) print_passet(pdnsr, asset, asset->rr, NULL, 0); - } + else if (asset->last_seen.tv_sec == asset->last_print.tv_sec) { - if (asset->last_seen.tv_usec > asset->last_print.tv_usec) { + if (asset->last_seen.tv_usec > asset->last_print.tv_usec) print_passet(pdnsr, asset, asset->rr, NULL, 0); - } } tmp_asset = asset; asset = asset->next; @@ -1319,13 +1307,12 @@ void expire_dns_assets(pdns_record *pdnsr, time_t expire_t) if (passet->last_seen.tv_sec <= expire_t) { /* Print the asset before we expires if it has been updated since it last was printed */ - if (passet->last_seen.tv_sec > passet->last_print.tv_sec) { + if (passet->last_seen.tv_sec > passet->last_print.tv_sec) print_passet(pdnsr, passet, passet->rr, NULL, 0); - } + else if (passet->last_seen.tv_sec == passet->last_print.tv_sec) { - if (passet->last_seen.tv_usec > passet->last_print.tv_usec) { + if (passet->last_seen.tv_usec > passet->last_print.tv_usec) print_passet(pdnsr, passet, passet->rr, NULL, 0); - } } /* Remove the asset from the linked list */ if (passet->prev) @@ -1339,9 +1326,8 @@ void expire_dns_assets(pdns_record *pdnsr, time_t expire_t) /* Delete the asset */ delete_dns_asset(&pdnsr->passet, tmp); } - else { + else passet = passet->next; - } } } @@ -1352,11 +1338,11 @@ void delete_dns_asset(pdns_asset **passet_head, pdns_asset *passet) if (passet == NULL) return; - pdns_asset *tmp_pa = NULL; + pdns_asset *tmp_pa = NULL; pdns_asset *next_pa = NULL; pdns_asset *prev_pa = NULL; - tmp_pa = passet; + tmp_pa = passet; next_pa = tmp_pa->next; prev_pa = tmp_pa->prev; @@ -1433,7 +1419,7 @@ void update_dns_stats(packetinfo *pi, uint8_t code) void parse_field_flags(char *args) { int i; - int ok = 0; + int ok = 0; int len = 0; uint8_t tmpf; @@ -1521,7 +1507,7 @@ void parse_field_flags(char *args) void parse_dns_flags(char *args) { int i; - int ok = 0; + int ok = 0; int len = 0; uint8_t tmpf; @@ -1534,7 +1520,7 @@ void parse_dns_flags(char *args) return; } - config.dnsf = 0; + config.dnsf = 0; config.dnsfe = 0; for (i = 0; i < len; i++){ diff --git a/src/passivedns.c b/src/passivedns.c index 75b0dd6..88a0408 100644 --- a/src/passivedns.c +++ b/src/passivedns.c @@ -29,7 +29,6 @@ #include #include #include -//#include #include #include #include @@ -93,7 +92,6 @@ void del_connection(connection *, connection **); void print_pdns_stats(); void free_config(); void reopen_log_files(); -//void dump_payload(const uint8_t* data,uint16_t dlen); void game_over (); void got_packet(u_char *useless, const struct pcap_pkthdr *pheader, const u_char *packet); @@ -175,31 +173,29 @@ void got_packet(u_char *useless, const struct pcap_pkthdr *pheader, void prepare_raw(packetinfo *pi) { pi->eth_hlen = 0; - if (IP_V((ip4_header *)pi->packet) == 4) { + if (IP_V((ip4_header *)pi->packet) == 4) pi->eth_type = ETHERNET_TYPE_IP; - } - else { + else pi->eth_type = ETHERNET_TYPE_IPV6; - } } void prepare_sll(packetinfo *pi) { pi->eth_hlen = SLL_HDR_LEN; - if (IP_V((ip4_header *)(pi->packet + SLL_HDR_LEN)) == 4) { + if (IP_V((ip4_header *)(pi->packet + SLL_HDR_LEN)) == 4) pi->eth_type = ETHERNET_TYPE_IP; - } - else { + else pi->eth_type = ETHERNET_TYPE_IPV6; - } } void prepare_eth(packetinfo *pi) { - if (pi->packet + ETHERNET_HEADER_LEN > pi->end_ptr) return; + if (pi->packet + ETHERNET_HEADER_LEN > pi->end_ptr) + return; + config.p_s.eth_recv++; - pi->eth_hdr = (ether_header *) (pi->packet); + pi->eth_hdr = (ether_header *) (pi->packet); pi->eth_type = ntohs(pi->eth_hdr->eth_ip_type); pi->eth_hlen = ETHERNET_HEADER_LEN; } @@ -230,7 +226,6 @@ void prepare_ip4(packetinfo *pi) pi->af = AF_INET; pi->ip4 = (ip4_header *) (pi->packet + pi->eth_hlen); pi->packet_bytes = (pi->ip4->ip_len - (IP_HL(pi->ip4) * 4)); - //vlog(0x3, "Got IPv4 Packet...\n"); } void parse_ip4(packetinfo *pi) @@ -240,6 +235,7 @@ void parse_ip4(packetinfo *pi) dlog("[D] Refusing to parse IPv4 packet: IPv4-hdr passed end_ptr\n"); return; } + switch (pi->ip4->ip_p) { case IP_PROTO_TCP: prepare_tcp(pi); @@ -268,6 +264,7 @@ void prepare_ip6ip(packetinfo *pi) pipi.pheader = pi->pheader; pipi.packet = (pi->packet + pi->eth_hlen + IP6_HEADER_LEN); pipi.end_ptr = pi->end_ptr; + if (pi->ip6->next == IP_PROTO_IP4) { prepare_ip4(&pipi); parse_ip4(&pipi); @@ -286,6 +283,7 @@ void prepare_ip4ip(packetinfo *pi) pipi.pheader = pi->pheader; pipi.packet = (pi->packet + pi->eth_hlen + (IP_HL(pi->ip4) * 4)); pipi.end_ptr = pi->end_ptr; + if (pi->ip4->ip_p == IP_PROTO_IP4) { prepare_ip4(&pipi); parse_ip4(&pipi); @@ -302,7 +300,6 @@ void prepare_ip6(packetinfo *pi) pi->af = AF_INET6; pi->ip6 = (ip6_header *) (pi->packet + pi->eth_hlen); pi->packet_bytes = pi->ip6->len; - //vlog(0x3, "Got IPv6 Packet...\n"); } void parse_ip6(packetinfo *pi) @@ -436,13 +433,11 @@ int connection_tracking(packetinfo *pi) } /* Find the right connection bucket */ - if (af == AF_INET) { + if (af == AF_INET) hash = CXT_HASH4(IP4ADDR(ip_src), IP4ADDR(ip_dst), src_port, dst_port, pi->proto); - } - else if (af == AF_INET6) { + else if (af == AF_INET6) hash = CXT_HASH6(ip_src, ip_dst, src_port, dst_port, pi->proto); - } else { dlog("[D] Only CTX with AF_INET and AF_INET6 are supported: %d\n", af); return 0; @@ -467,7 +462,8 @@ int connection_tracking(packetinfo *pi) /* This is a server */ dlog("[D] Found existing v4 server connection.\n"); return cxt_update_server(cxt, pi); - } else { + } + else { /* This is a client, where we saw a mid-stream DNS response first */ dlog("[D] Found existing unknown v4 server connection.\n"); return cxt_update_client(cxt, pi); @@ -492,10 +488,10 @@ int connection_tracking(packetinfo *pi) /* New connections are pushed on to the head of bucket[s_hash] */ cxt->next = head; - if (head != NULL) { + if (head != NULL) /* Are we double linked? */ head->prev = cxt; - } + bucket[hash] = cxt; pi->cxt = cxt; return cxt_update_unknown(cxt, pi); @@ -509,11 +505,12 @@ connection *cxt_new(packetinfo *pi) connection *cxt; config.cxtrackerid++; cxt = (connection *) calloc(1, sizeof(connection)); - //assert(cxt); cxt->cxid = config.cxtrackerid; - cxt->af = pi->af; - if (pi->tcph) cxt->s_tcpFlags |= pi->tcph->t_flags; + + if (pi->tcph) + cxt->s_tcpFlags |= pi->tcph->t_flags; + cxt->start_time = pi->pheader->ts.tv_sec; cxt->last_pkt_time = pi->pheader->ts.tv_sec; @@ -543,16 +540,20 @@ int cxt_update_client(connection *cxt, packetinfo *pi) { cxt->last_pkt_time = pi->pheader->ts.tv_sec; - if (pi->tcph) cxt->s_tcpFlags |= pi->tcph->t_flags; + if (pi->tcph) + cxt->s_tcpFlags |= pi->tcph->t_flags; + cxt->s_total_bytes += pi->packet_bytes; cxt->s_total_pkts += 1; pi->cxt = cxt; pi->sc = SC_CLIENT; + if (cxt->s_total_bytes > MAX_BYTE_CHECK || cxt->s_total_pkts > MAX_PKT_CHECK) { return 0; /* Don't Check! */ } + return SC_CLIENT; } @@ -560,16 +561,20 @@ int cxt_update_unknown(connection *cxt, packetinfo *pi) { cxt->last_pkt_time = pi->pheader->ts.tv_sec; - if (pi->tcph) cxt->s_tcpFlags |= pi->tcph->t_flags; + if (pi->tcph) + cxt->s_tcpFlags |= pi->tcph->t_flags; + cxt->s_total_bytes += pi->packet_bytes; cxt->s_total_pkts += 1; pi->cxt = cxt; pi->sc = SC_UNKNOWN; + if (cxt->s_total_bytes > MAX_BYTE_CHECK || cxt->s_total_pkts > MAX_PKT_CHECK) { return 0; /* Don't Check! */ } + return SC_UNKNOWN; } @@ -577,16 +582,19 @@ int cxt_update_server(connection *cxt, packetinfo *pi) { cxt->last_pkt_time = pi->pheader->ts.tv_sec; - if (pi->tcph) cxt->d_tcpFlags |= pi->tcph->t_flags; + if (pi->tcph) + cxt->d_tcpFlags |= pi->tcph->t_flags; + cxt->d_total_bytes += pi->packet_bytes; cxt->d_total_pkts += 1; pi->cxt = cxt; pi->sc = SC_SERVER; + if (cxt->d_total_bytes > MAX_BYTE_CHECK || - cxt->d_total_pkts > MAX_PKT_CHECK) { + cxt->d_total_pkts > MAX_PKT_CHECK) return 0; /* Don't check! */ - } + return SC_SERVER; } @@ -610,9 +618,8 @@ void end_all_sessions() cxt = cxt->next; del_connection(tmp, &bucket[cxkey]); - if (cxt == NULL) { + if (cxt == NULL) bucket[cxkey] = NULL; - } } } dlog("CXT in list before cleaning: %10u\n", config.llcxt); @@ -640,33 +647,28 @@ void end_sessions() if (cxt->proto == IP_PROTO_TCP) { /* FIN from both sides */ if (cxt->s_tcpFlags & TF_FIN && cxt->d_tcpFlags & TF_FIN - && (check_time - cxt->last_pkt_time) > 5) { + && (check_time - cxt->last_pkt_time) > 5) ended = 1; - } /* RST from either side */ + /* RST from either side */ else if ((cxt->s_tcpFlags & TF_RST || cxt->d_tcpFlags & TF_RST) - && (check_time - cxt->last_pkt_time) > 5) { + && (check_time - cxt->last_pkt_time) > 5) ended = 1; - } - else if ((check_time - cxt->last_pkt_time) > TCP_TIMEOUT) { + else if ((check_time - cxt->last_pkt_time) > TCP_TIMEOUT) expired = 1; - } } /* UDP */ else if (cxt->proto == IP_PROTO_UDP - && (check_time - cxt->last_pkt_time) > UDP_TIMEOUT) { + && (check_time - cxt->last_pkt_time) > UDP_TIMEOUT) expired = 1; - } /* ICMP */ else if (cxt->proto == IP_PROTO_ICMP || - cxt->proto == IP6_PROTO_ICMP) { - if ((check_time - cxt->last_pkt_time) > ICMP_TIMEOUT) { + cxt->proto == IP6_PROTO_ICMP) { + if ((check_time - cxt->last_pkt_time) > ICMP_TIMEOUT) expired = 1; - } } /* All other protocols */ - else if ((check_time - cxt->last_pkt_time) > OTHER_TIMEOUT) { + else if ((check_time - cxt->last_pkt_time) > OTHER_TIMEOUT) expired = 1; - } if (ended == 1 || expired == 1) { /* Remove from the hash */ @@ -682,13 +684,11 @@ void end_sessions() cxt = cxt->next; del_connection(tmp, &bucket[iter]); - if (cxt == NULL && tmp_pre == NULL) { + if (cxt == NULL && tmp_pre == NULL) bucket[iter] = NULL; - } } - else { + else cxt = cxt->next; - } } } dlog("CXT in list before cleaning: %10u\n", config.llcxt); @@ -744,18 +744,17 @@ const char *u_ntop_src(packetinfo *pi, char *dest) void check_interrupt() { dlog("[D] In interrupt. Flag: %d\n",config.intr_flag); - if (ISSET_INTERRUPT_END(config)) { + if (ISSET_INTERRUPT_END(config)) game_over(); - } - else if (ISSET_INTERRUPT_SESSION(config)) { + + else if (ISSET_INTERRUPT_SESSION(config)) set_end_sessions(); - } - else if (ISSET_INTERRUPT_DNS(config)) { + + else if (ISSET_INTERRUPT_DNS(config)) set_end_dns_records(); - } - else { + + else config.intr_flag = 0; - } } void sig_alarm_handler() @@ -826,23 +825,20 @@ static int set_chroot(void) char *absdir; /* Change to the directory */ - if (chdir(config.chroot_dir) != 0) { + if (chdir(config.chroot_dir) != 0) printf("set_chroot: Can not chdir to \"%s\": %s\n", config.chroot_dir,strerror(errno)); - } /* Always returns an absolute pathname */ absdir = getcwd(NULL, 0); /* Make the chroot call */ - if (chroot(absdir) < 0) { + if (chroot(absdir) < 0) printf("Could not chroot to \"%s\": absolute: %s: %s\n", config.chroot_dir, absdir, strerror(errno)); - } - if (chdir("/") < 0) { + if (chdir("/") < 0) printf("Could not chdir to \"/\" after chroot: %s\n", strerror(errno)); - } return 0; } @@ -896,28 +892,25 @@ int drop_privs(void) pw = getpwuid(userid); } - if (config.group_name == NULL && pw != NULL) { + if (config.group_name == NULL && pw != NULL) groupid = pw->pw_gid; - } } if (do_setgid) { - if ((i = setgid(groupid)) < 0) { + if ((i = setgid(groupid)) < 0) printf("Unable to set group ID: %s", strerror(i)); - } } endgrent(); endpwent(); if (do_setuid) { - if (getuid() == 0 && initgroups(config.user_name, groupid) < 0) { + if (getuid() == 0 && initgroups(config.user_name, groupid) < 0) printf("Unable to init group names (%s/%lu)", config.user_name, groupid); - } - if ((i = setuid(userid)) < 0) { + + if ((i = setuid(userid)) < 0) printf("Unable to set user ID: %s\n", strerror(i)); - } } return 0; } @@ -927,19 +920,18 @@ int is_valid_path(const char *path) char dir[STDBUF]; struct stat st; - if (path == NULL) { + if (path == NULL) return 0; - } memcpy(dir, path, strnlen(path, STDBUF)); dirname(dir); - if (stat(dir, &st) != 0) { + if (stat(dir, &st) != 0) return 0; - } - if (!S_ISDIR(st.st_mode) || access(dir, W_OK) == -1) { + + if (!S_ISDIR(st.st_mode) || access(dir, W_OK) == -1) return 0; - } + return 1; } @@ -949,17 +941,15 @@ int create_pid_file(const char *path) struct flock lock; int fd; - if (!path) { + if (!path) path = config.pidfile; - } - if (!is_valid_path(path)) { + + if (!is_valid_path(path)) printf("PID path \"%s\" aint writable", path); - } if ((fd = open(path, O_CREAT | O_WRONLY, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) return ERROR; - } /* PID file locking */ lock.l_type = F_WRLCK; @@ -971,15 +961,19 @@ int create_pid_file(const char *path) close(fd); return ERROR; } + snprintf(pid_buffer, sizeof(pid_buffer), "%d\n", (int)getpid()); + if (ftruncate(fd, 0) != 0) { close(fd); return ERROR; } + if (write(fd, pid_buffer, strlen(pid_buffer)) != 0) { close(fd); return ERROR; } + close(fd); return SUCCESS; } @@ -991,13 +985,11 @@ int daemonize() pid = fork(); - if (pid > 0) { + if (pid > 0) exit(0); /* Parent */ - } - if (pid < 0) { + if (pid < 0) return ERROR; - } setsid(); @@ -1010,9 +1002,8 @@ int daemonize() } } - if (config.pidfile) { + if (config.pidfile) return create_pid_file(config.pidfile); - } return SUCCESS; } @@ -1022,19 +1013,27 @@ void game_over() if (config.inpacket == 0) { expire_all_dns_records(); print_pdns_stats(); - if (config.handle != NULL) pcap_close(config.handle); + + if (config.handle != NULL) + pcap_close(config.handle); + config.handle = NULL; + #ifdef HAVE_PFRING if (config.use_pfring && config.pfhandle != NULL) { pfring_breakloop(config.pfhandle); pfring_close(config.pfhandle); } #endif /* HAVE_PFRING */ + end_all_sessions(); + if (config.logfile_fd != NULL && config.logfile_fd != stdout) fclose(config.logfile_fd); + if (config.logfile_nxd_fd != NULL && config.logfile_nxd_fd != stdout) fclose(config.logfile_nxd_fd); + free_config(); olog("\n[*] passivedns ended.\n"); exit(0); @@ -1044,10 +1043,10 @@ void game_over() void free_config() { - if (config.cfilter.bf_insns != NULL) free(config.cfilter.bf_insns); + if (config.cfilter.bf_insns != NULL) + free(config.cfilter.bf_insns); } - void print_pdns_stats() { olog("\n"); @@ -1303,13 +1302,11 @@ int main(int argc, char *argv[]) } /* Fall back to log file if syslog is not used */ - if (config.output_syslog == 0) { + if (config.output_syslog == 0) config.output_log = 1; - } - if (config.output_syslog_nxd == 0) { + if (config.output_syslog_nxd == 0) config.output_log_nxd = 1; - } /* Open log file */ if (config.output_log) {