00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <ldns/config.h>
00015
00016 #include <ldns/ldns.h>
00017
00018 #ifdef HAVE_SSL
00019 #include <openssl/ssl.h>
00020 #include <openssl/sha.h>
00021 #endif
00022
00023 ldns_rr_list *
00024 ldns_get_rr_list_addr_by_name(ldns_resolver *res, ldns_rdf *name, ldns_rr_class c,
00025 uint16_t flags)
00026 {
00027 ldns_pkt *pkt;
00028 ldns_rr_list *aaaa;
00029 ldns_rr_list *a;
00030 ldns_rr_list *result = NULL;
00031 ldns_rr_list *hostsfilenames;
00032 size_t i;
00033 uint8_t ip6;
00034
00035 a = NULL;
00036 aaaa = NULL;
00037 result = NULL;
00038
00039 if (!res) {
00040 return NULL;
00041 }
00042 if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
00043 return NULL;
00044 }
00045
00046 ip6 = ldns_resolver_ip6(res);
00047
00048
00049 ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
00050
00051 hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
00052 for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
00053 if (ldns_rdf_compare(name,
00054 ldns_rr_owner(ldns_rr_list_rr(hostsfilenames,
00055 i))) == 0) {
00056 if (!result) {
00057 result = ldns_rr_list_new();
00058 }
00059 ldns_rr_list_push_rr(result,
00060 ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
00061 }
00062 }
00063 ldns_rr_list_deep_free(hostsfilenames);
00064
00065 if (result) {
00066 return result;
00067 }
00068
00069
00070 pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
00071 if (pkt) {
00072
00073 aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA,
00074 LDNS_SECTION_ANSWER);
00075 ldns_pkt_free(pkt);
00076 }
00077
00078 pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
00079 if (pkt) {
00080
00081 a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
00082 ldns_pkt_free(pkt);
00083 }
00084 ldns_resolver_set_ip6(res, ip6);
00085
00086 if (aaaa && a) {
00087 result = ldns_rr_list_cat_clone(aaaa, a);
00088 ldns_rr_list_deep_free(aaaa);
00089 ldns_rr_list_deep_free(a);
00090 return result;
00091 }
00092
00093 if (aaaa) {
00094 result = ldns_rr_list_clone(aaaa);
00095 }
00096
00097 if (a) {
00098 result = ldns_rr_list_clone(a);
00099 }
00100
00101 ldns_rr_list_deep_free(aaaa);
00102 ldns_rr_list_deep_free(a);
00103 return result;
00104 }
00105
00106 ldns_rr_list *
00107 ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class c,
00108 uint16_t flags)
00109 {
00110 ldns_pkt *pkt;
00111 ldns_rr_list *names;
00112 ldns_rdf *name;
00113
00114 names = NULL;
00115
00116 if (!res || !addr) {
00117 return NULL;
00118 }
00119
00120 if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
00121 ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
00122 return NULL;
00123 }
00124
00125 name = ldns_rdf_address_reverse(addr);
00126
00127
00128 pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
00129 if (pkt) {
00130
00131 names = ldns_pkt_rr_list_by_type(pkt,
00132 LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
00133 }
00134 return names;
00135 }
00136
00137
00138 ldns_rr_list *
00139 ldns_get_rr_list_hosts_frm_fp(FILE *fp)
00140 {
00141 return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
00142 }
00143
00144 ldns_rr_list *
00145 ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
00146 {
00147 ssize_t i, j;
00148 size_t cnt;
00149 char *line;
00150 char *word;
00151 char *addr;
00152 char *rr_str;
00153 ldns_buffer *linebuf;
00154 ldns_rr *rr;
00155 ldns_rr_list *list;
00156 ldns_rdf *tmp;
00157 bool ip6;
00158 ldns_status parse_result;
00159
00160 line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
00161 word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
00162 addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
00163 rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
00164 ip6 = false;
00165 list = ldns_rr_list_new();
00166 rr = NULL;
00167 if(!line || !word || !addr || !rr_str || !list) {
00168 LDNS_FREE(line);
00169 LDNS_FREE(word);
00170 LDNS_FREE(addr);
00171 LDNS_FREE(rr_str);
00172 ldns_rr_list_free(list);
00173 return NULL;
00174 }
00175
00176 for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
00177 i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
00178
00179 if (line[0] == '#') {
00180 continue;
00181 }
00182
00183 linebuf = LDNS_MALLOC(ldns_buffer);
00184 if(!linebuf) {
00185 LDNS_FREE(line);
00186 LDNS_FREE(word);
00187 LDNS_FREE(addr);
00188 LDNS_FREE(rr_str);
00189 ldns_rr_list_deep_free(list);
00190 return NULL;
00191 }
00192
00193 ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
00194 for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
00195 j > 0;
00196 j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
00197 if (cnt == 0) {
00198
00199 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
00200 word))) {
00201
00202 ldns_rdf_deep_free(tmp);
00203 ip6 = true;
00204 } else {
00205 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
00206 word))) {
00207
00208 ldns_rdf_deep_free(tmp);
00209 ip6 = false;
00210 } else {
00211
00212 break;
00213 }
00214 }
00215 (void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
00216 } else {
00217
00218 if (ip6) {
00219 snprintf(rr_str, LDNS_MAX_LINELEN,
00220 "%s IN AAAA %s", word, addr);
00221 } else {
00222 snprintf(rr_str, LDNS_MAX_LINELEN,
00223 "%s IN A %s", word, addr);
00224 }
00225 parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
00226 if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
00227 ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
00228 }
00229 ldns_rr_free(rr);
00230 }
00231 }
00232 ldns_buffer_free(linebuf);
00233 }
00234 LDNS_FREE(line);
00235 LDNS_FREE(word);
00236 LDNS_FREE(addr);
00237 LDNS_FREE(rr_str);
00238 return list;
00239 }
00240
00241 ldns_rr_list *
00242 ldns_get_rr_list_hosts_frm_file(char *filename)
00243 {
00244 ldns_rr_list *names;
00245 FILE *fp;
00246
00247 if (!filename) {
00248 fp = fopen(LDNS_RESOLV_HOSTS, "r");
00249
00250 } else {
00251 fp = fopen(filename, "r");
00252 }
00253 if (!fp) {
00254 return NULL;
00255 }
00256
00257 names = ldns_get_rr_list_hosts_frm_fp(fp);
00258 fclose(fp);
00259 return names;
00260 }
00261
00262 uint16_t
00263 ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c,
00264 ldns_rr_list **ret)
00265 {
00266 ldns_rdf_type t;
00267 uint16_t names_found;
00268 ldns_resolver *r;
00269 ldns_status s;
00270
00271 t = ldns_rdf_get_type(node);
00272 names_found = 0;
00273 r = res;
00274
00275 if (res == NULL) {
00276
00277 s = ldns_resolver_new_frm_file(&r, NULL);
00278 if (s != LDNS_STATUS_OK) {
00279 return 0;
00280 }
00281 }
00282
00283 if (t == LDNS_RDF_TYPE_DNAME) {
00284
00285 *ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
00286 names_found = ldns_rr_list_rr_count(*ret);
00287 }
00288
00289 if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
00290
00291 *ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
00292 names_found = ldns_rr_list_rr_count(*ret);
00293 }
00294
00295 if (res == NULL) {
00296 ldns_resolver_deep_free(r);
00297 }
00298
00299 return names_found;
00300 }
00301
00302 bool
00303 ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
00304 {
00305
00306
00307 uint8_t window_block_nr;
00308 uint8_t bitmap_length;
00309 uint16_t type;
00310 uint16_t pos = 0;
00311 uint16_t bit_pos;
00312 ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1);
00313 uint8_t *data;
00314
00315 if (nsec_type_list == NULL) {
00316 return false;
00317 }
00318 data = ldns_rdf_data(nsec_type_list);
00319
00320 while(pos < ldns_rdf_size(nsec_type_list)) {
00321 window_block_nr = data[pos];
00322 bitmap_length = data[pos + 1];
00323 pos += 2;
00324
00325 for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
00326 if (ldns_get_bit(&data[pos], bit_pos)) {
00327 type = 256 * (uint16_t) window_block_nr + bit_pos;
00328
00329 if ((ldns_rr_type)type == t) {
00330
00331 return true;
00332 }
00333 }
00334 }
00335 pos += (uint16_t) bitmap_length;
00336 }
00337 return false;
00338 }
00339
00340 void
00341 ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
00342 {
00343 int16_t rdf;
00344 ldns_rdf *rd;
00345 va_list va_rdf;
00346 va_start(va_rdf, rdfnum);
00347
00348 for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
00349 {
00350 rd = ldns_rr_rdf(r, rdf);
00351 if (!rd) {
00352 continue;
00353 } else {
00354 ldns_rdf_print(fp, rd);
00355 fprintf(fp, " ");
00356 }
00357 }
00358 va_end(va_rdf);
00359 }