higher.c

Go to the documentation of this file.
00001 /*
00002  * higher.c
00003  *
00004  * Specify some higher level functions that would
00005  * be usefull to would be developers
00006  *
00007  * a Net::DNS like library for C
00008  *
00009  * (c) NLnet Labs, 2004-2006
00010  *
00011  * See the file LICENSE for the license
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 /* HAVE_SSL */
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); /* we use INET_ANY here, save
00047                                          what was there */
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         /* add the RD flags, because we want an answer */
00070         pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
00071         if (pkt) {
00072                 /* extract the data we need */
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                 /* extract the data we need */
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         /* add the RD flags, because we want an answer */
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                 /* extract the data we need */
00132                 names = ldns_pkt_rr_list_by_type(pkt, 
00133                                 LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
00134         }
00135         return names;
00136 }
00137 
00138 /* read a line, put it in a buffer, parse the buffer */
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                 /* # is comment */
00180                 if (line[0] == '#') {
00181                         continue;
00182                 }
00183                 /* put it in a buffer for further processing */
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                                 /* the address */
00200                                 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, 
00201                                                                 word))) {
00202                                         /* ip6 */
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                                                 /* ip4 */
00209                                                 ldns_rdf_deep_free(tmp);
00210                                                 ip6 = false;
00211                                         } else {
00212                                                 /* kaput */
00213                                                 break;
00214                                         }
00215                                 }
00216                                 (void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
00217                         } else {
00218                                 /* la al la la */
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                 /* prepare a new resolver, using /etc/resolv.conf as a guide  */
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                 /* we're asked to query for a name */
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                 /* an address */
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         /* does the nsec cover the t given? */
00307         /* copied from host2str.c line 465: ldns_rdf2buffer_str_nsec */
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                                         /* we have a winner */
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, " "); /* not sure if we want to do this */
00357                 }
00358         }
00359         va_end(va_rdf);
00360 }

Generated on 8 Apr 2014 for ldns by  doxygen 1.4.7