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 ldns_rdf_deep_free(name);
00130 if (pkt) {
00131
00132 names = ldns_pkt_rr_list_by_type(pkt,
00133 LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
00134 }
00135 return names;
00136 }
00137
00138
00139 ldns_rr_list *
00140 ldns_get_rr_list_hosts_frm_fp(FILE *fp)
00141 {
00142 return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
00143 }
00144
00145 ldns_rr_list *
00146 ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
00147 {
00148 ssize_t i, j;
00149 size_t cnt;
00150 char *line;
00151 char *word;
00152 char *addr;
00153 char *rr_str;
00154 ldns_buffer *linebuf;
00155 ldns_rr *rr;
00156 ldns_rr_list *list;
00157 ldns_rdf *tmp;
00158 bool ip6;
00159 ldns_status parse_result;
00160
00161 line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
00162 word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
00163 addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
00164 rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
00165 ip6 = false;
00166 list = ldns_rr_list_new();
00167 rr = NULL;
00168 if(!line || !word || !addr || !rr_str || !list) {
00169 LDNS_FREE(line);
00170 LDNS_FREE(word);
00171 LDNS_FREE(addr);
00172 LDNS_FREE(rr_str);
00173 ldns_rr_list_free(list);
00174 return NULL;
00175 }
00176
00177 for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
00178 i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
00179
00180 if (line[0] == '#') {
00181 continue;
00182 }
00183
00184 linebuf = LDNS_MALLOC(ldns_buffer);
00185 if(!linebuf) {
00186 LDNS_FREE(line);
00187 LDNS_FREE(word);
00188 LDNS_FREE(addr);
00189 LDNS_FREE(rr_str);
00190 ldns_rr_list_deep_free(list);
00191 return NULL;
00192 }
00193
00194 ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
00195 for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
00196 j > 0;
00197 j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
00198 if (cnt == 0) {
00199
00200 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
00201 word))) {
00202
00203 ldns_rdf_deep_free(tmp);
00204 ip6 = true;
00205 } else {
00206 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
00207 word))) {
00208
00209 ldns_rdf_deep_free(tmp);
00210 ip6 = false;
00211 } else {
00212
00213 break;
00214 }
00215 }
00216 (void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
00217 } else {
00218
00219 if (ip6) {
00220 snprintf(rr_str, LDNS_MAX_LINELEN,
00221 "%s IN AAAA %s", word, addr);
00222 } else {
00223 snprintf(rr_str, LDNS_MAX_LINELEN,
00224 "%s IN A %s", word, addr);
00225 }
00226 parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
00227 if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
00228 ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
00229 }
00230 ldns_rr_free(rr);
00231 }
00232 }
00233 ldns_buffer_free(linebuf);
00234 }
00235 LDNS_FREE(line);
00236 LDNS_FREE(word);
00237 LDNS_FREE(addr);
00238 LDNS_FREE(rr_str);
00239 return list;
00240 }
00241
00242 ldns_rr_list *
00243 ldns_get_rr_list_hosts_frm_file(char *filename)
00244 {
00245 ldns_rr_list *names;
00246 FILE *fp;
00247
00248 if (!filename) {
00249 fp = fopen(LDNS_RESOLV_HOSTS, "r");
00250
00251 } else {
00252 fp = fopen(filename, "r");
00253 }
00254 if (!fp) {
00255 return NULL;
00256 }
00257
00258 names = ldns_get_rr_list_hosts_frm_fp(fp);
00259 fclose(fp);
00260 return names;
00261 }
00262
00263 uint16_t
00264 ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c,
00265 ldns_rr_list **ret)
00266 {
00267 ldns_rdf_type t;
00268 uint16_t names_found;
00269 ldns_resolver *r;
00270 ldns_status s;
00271
00272 t = ldns_rdf_get_type(node);
00273 names_found = 0;
00274 r = res;
00275
00276 if (res == NULL) {
00277
00278 s = ldns_resolver_new_frm_file(&r, NULL);
00279 if (s != LDNS_STATUS_OK) {
00280 return 0;
00281 }
00282 }
00283
00284 if (t == LDNS_RDF_TYPE_DNAME) {
00285
00286 *ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
00287 names_found = ldns_rr_list_rr_count(*ret);
00288 }
00289
00290 if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
00291
00292 *ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
00293 names_found = ldns_rr_list_rr_count(*ret);
00294 }
00295
00296 if (res == NULL) {
00297 ldns_resolver_deep_free(r);
00298 }
00299
00300 return names_found;
00301 }
00302
00303 bool
00304 ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
00305 {
00306
00307
00308 uint8_t window_block_nr;
00309 uint8_t bitmap_length;
00310 uint16_t type;
00311 uint16_t pos = 0;
00312 uint16_t bit_pos;
00313 ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1);
00314 uint8_t *data;
00315
00316 if (nsec_type_list == NULL) {
00317 return false;
00318 }
00319 data = ldns_rdf_data(nsec_type_list);
00320
00321 while(pos < ldns_rdf_size(nsec_type_list)) {
00322 window_block_nr = data[pos];
00323 bitmap_length = data[pos + 1];
00324 pos += 2;
00325
00326 for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
00327 if (ldns_get_bit(&data[pos], bit_pos)) {
00328 type = 256 * (uint16_t) window_block_nr + bit_pos;
00329
00330 if ((ldns_rr_type)type == t) {
00331
00332 return true;
00333 }
00334 }
00335 }
00336 pos += (uint16_t) bitmap_length;
00337 }
00338 return false;
00339 }
00340
00341 void
00342 ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
00343 {
00344 int16_t rdf;
00345 ldns_rdf *rd;
00346 va_list va_rdf;
00347 va_start(va_rdf, rdfnum);
00348
00349 for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
00350 {
00351 rd = ldns_rr_rdf(r, rdf);
00352 if (!rd) {
00353 continue;
00354 } else {
00355 ldns_rdf_print(fp, rd);
00356 fprintf(fp, " ");
00357 }
00358 }
00359 va_end(va_rdf);
00360 }