diff --git a/smmapdfw/libsmmapdfw/htdns.c b/smmapdfw/libsmmapdfw/htdns.c index 07efc76..f4875bc 100644 --- a/smmapdfw/libsmmapdfw/htdns.c +++ b/smmapdfw/libsmmapdfw/htdns.c @@ -330,6 +330,9 @@ static void** get_rrs(char *domain, int qtype) { cnt = get_domain_name(answer, cnt, NULL); type = get16(answer->buf, cnt); syslog(LOG_DEBUG, "get_rrs: answer type %d", type); + + //if (type != qtype) + // printf("answer type mismatch: %d != %d\n", type, qtype); /* assert(type==qtype); */ cnt += 2; class = get16(answer->buf, cnt); @@ -363,37 +366,77 @@ mx_rdata_t** get_mx_rrs(char *domain) { if (domain == NULL) return NULL; - rdata_t **rdata = get_rrs(domain, T_MX); + rdata_t **rdata = (rdata_t**) get_rrs(domain, T_MX); - if ((NULL == rdata) || (NULL == *rdata)) { + if ((NULL == rdata) || (NULL == *rdata)) return NULL; - } else if ((*rdata)->type != T_MX) { - free_rrs((void**)rdata); - return NULL; - } else { - return (mx_rdata_t**) rdata; + + rdata_t **rdata2; + mx_rdata_t **mx_rdata = NULL; + int i = 0; // one for the termination + for (rdata2 = rdata; *rdata2 != NULL; rdata2++) { + if ((*rdata2)->type == T_MX) { + mx_rdata = (mx_rdata_t**) htrealloc(mx_rdata, sizeof(mx_rdata_t*) * (i + 2)); + *(mx_rdata + i) = (mx_rdata_t*) *rdata2; + i++; + } else { + /* it's not, free it */ + free_rdata(*rdata2); + } } + + /* free the old container */ + free(rdata); + + /* terminate the new container */ + *((int**)(mx_rdata + i)) = NULL; + + return mx_rdata; } a_rdata_t** get_a_rrs(char *domain) { if (domain == NULL) return NULL; - rdata_t **rdata, **rdata2; cname_rdata_t **cname_rdata; - rdata = (rdata_t**) get_rrs(domain, T_A); + rdata_t **rdata = (rdata_t**) get_rrs(domain, T_A); if ((NULL == rdata) || (NULL == *rdata)) return NULL; - if ((*rdata)->type == T_CNAME) { - cname_rdata = (cname_rdata_t**) rdata; - rdata2 = (rdata_t**) get_a_rrs((*cname_rdata)->cname); - free_rrs((void**)rdata); - rdata = rdata2; + rdata_t **rdata2; + a_rdata_t **a_rdata = NULL; + int i = 0; // one for the termination + for (rdata2 = rdata; *rdata2 != NULL; rdata2++) { + if ((*rdata2)->type == T_A) { + a_rdata = (a_rdata_t**) htrealloc(a_rdata, sizeof(a_rdata_t*) * (i + 2)); + *(a_rdata + i) = *rdata2; + i++; + } else if ((*rdata2)->type == T_CNAME) { + cname_rdata_t *cname_rdata = (cname_rdata_t*) *rdata2; + a_rdata_t **a_rdata_recurse = get_a_rrs(cname_rdata->cname); + if ((NULL != a_rdata_recurse) && (NULL != *a_rdata_recurse)) { + a_rdata_t **a_rdata2; + for (a_rdata2 = a_rdata_recurse; *a_rdata2 != NULL; a_rdata2++) { + a_rdata = (a_rdata_t**) htrealloc(a_rdata, sizeof(a_rdata_t*) * (i + 2)); + *(a_rdata + i) = *a_rdata2; + i++; + } + free(a_rdata_recurse); + } + } else { + /* it's not, free it */ + free_rdata(*rdata2); + } } - return (a_rdata_t**) rdata; + /* free the old container */ + free(rdata); + + /* terminate the new container */ + *((int**)(a_rdata + i)) = NULL; + + return a_rdata; } @@ -404,34 +447,38 @@ mx_rdata_t** get_best_mx_rrs(char *domain) { if (domain == NULL) return NULL; - mx_rdata_t **all_mx_rrs, **mx_rdata2, **best_mx_rrs; - int min_pref = 10000000; - int all_cnt = 0; - int best_cnt = 0; int i = 0; - all_mx_rrs = get_mx_rrs(domain); + + mx_rdata_t **all_mx_rrs = get_mx_rrs(domain); if (NULL == all_mx_rrs) return NULL; /* how much are there at all and what is the minimum preference */ + int min_pref = 10000000; + int all_cnt = 0; + mx_rdata_t **mx_rdata2; for (mx_rdata2 = all_mx_rrs; *mx_rdata2 != NULL; mx_rdata2++) { all_cnt++; min_pref = min(min_pref, (*mx_rdata2)->preference); } + //printf("all_cnt: %d, min_pref: %d\n", all_cnt, min_pref); + /* how much are there of the minimum preference */ + int best_cnt = 0; for (mx_rdata2 = all_mx_rrs; *mx_rdata2 != NULL; mx_rdata2++) if ((*mx_rdata2)->preference == min_pref) best_cnt++; + //printf("best_cnt: %d\n", best_cnt); if (all_cnt == best_cnt) { /* all of them are minimum */ return all_mx_rrs; } else { /* space for the minimum pref rr's */ - best_mx_rrs = (mx_rdata_t**) htmalloc(sizeof(mx_rdata_t*) * (best_cnt+1)); + mx_rdata_t **best_mx_rrs = (mx_rdata_t**) htmalloc(sizeof(mx_rdata_t*) * (best_cnt+1)); for (mx_rdata2 = all_mx_rrs; *mx_rdata2 != NULL; mx_rdata2++) { if ((*mx_rdata2)->preference == min_pref) { /* is a minimum one, keep it */ @@ -439,7 +486,7 @@ mx_rdata_t** get_best_mx_rrs(char *domain) { i++; } else { /* it's not, free it */ - free_mx_rdata(*mx_rdata2); + free_rdata(*mx_rdata2); } } /* free the old container */ diff --git a/smmapdfw/libsmmapdfw/htdnstest.c b/smmapdfw/libsmmapdfw/htdnstest.c index 3a4c6d0..7ede62c 100644 --- a/smmapdfw/libsmmapdfw/htdnstest.c +++ b/smmapdfw/libsmmapdfw/htdnstest.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "htdns.h" @@ -33,23 +34,40 @@ int main(int argc, char **args) { - if (argc != 2) { - printf("give domain to test on commandline\n"); + if (argc != 3) { + printf("give domain to test and query type on commandline\n"); exit(1); } char *domain = args[1]; + char *type = args[2]; - mx_rdata_t **mx_rdata = get_best_mx_rrs(domain); - if (mx_rdata == NULL) { - printf("no mx-rr found\n"); - } else { - mx_rdata_t **mx_rdata2; - for (mx_rdata2 = mx_rdata; *mx_rdata2 != NULL; mx_rdata2++) { - printf("--> %d, %s\n", (*mx_rdata2)->preference, (*mx_rdata2)->exchange); - } + if (! strcmp(type, "mx")) { + mx_rdata_t **mx_rdata = get_best_mx_rrs(domain); + if (mx_rdata == NULL) { + printf("no mx-rr found\n"); + } else { + mx_rdata_t **mx_rdata2; + for (mx_rdata2 = mx_rdata; *mx_rdata2 != NULL; mx_rdata2++) { + printf("--> %d, %s\n", (*mx_rdata2)->preference, (*mx_rdata2)->exchange); + } - free_rrs((void**)mx_rdata); + free_rrs((void**)mx_rdata); + } + } else if (! strcmp(type, "a")) { + a_rdata_t **a_rdata = get_a_rrs(domain); + if (a_rdata == NULL) { + printf("nothing found\n"); + } else { + a_rdata_t **a_rdata2; + for (a_rdata2 = a_rdata; *a_rdata2 != NULL; a_rdata2++) { + printf("--> %08x, %d.%d.%d.%d\n", htonl((*a_rdata2)->address), + (htonl((*a_rdata2)->address)&0xff000000)>>24, (htonl((*a_rdata2)->address)&0x00ff0000)>>16, + (htonl((*a_rdata2)->address)&0x0000ff00)>>8, (htonl((*a_rdata2)->address)&0x000000ff)); + } + + free_rrs((void**)a_rdata); + } } }