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 #include <openssl/ssl.h>
00019 #include <openssl/sha.h>
00020 
00021 ldns_rr_list *
00022 ldns_get_rr_list_addr_by_name(ldns_resolver *res, ldns_rdf *name, ldns_rr_class c, 
00023                 uint16_t flags)
00024 {
00025         ldns_pkt *pkt;
00026         ldns_rr_list *aaaa;
00027         ldns_rr_list *a;
00028         ldns_rr_list *result = NULL;
00029         ldns_rr_list *hostsfilenames;
00030         size_t i;
00031         uint8_t ip6;
00032 
00033         a = NULL; 
00034         aaaa = NULL; 
00035         result = NULL;
00036 
00037         if (!res) {
00038                 return NULL;
00039         }
00040         if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
00041                 return NULL;
00042         }
00043 
00044         ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
00045                                          what was there */
00046 
00047         ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
00048         
00049         hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
00050         for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
00051                 if (ldns_rdf_compare(name, 
00052                                         ldns_rr_owner(ldns_rr_list_rr(hostsfilenames, 
00053                                                         i))) == 0) {
00054                         if (!result) {
00055                                 result = ldns_rr_list_new();
00056                         }
00057                         ldns_rr_list_push_rr(result, 
00058                                         ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
00059                 }
00060         }
00061         ldns_rr_list_deep_free(hostsfilenames);
00062 
00063         if (result) {
00064                 return result;
00065         }
00066 
00067         /* add the RD flags, because we want an answer */
00068         pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
00069         if (pkt) {
00070                 /* extract the data we need */
00071                 aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA, 
00072                         LDNS_SECTION_ANSWER);
00073                 ldns_pkt_free(pkt);
00074         } 
00075 
00076         pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
00077         if (pkt) {
00078                 /* extract the data we need */
00079                 a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
00080                 ldns_pkt_free(pkt);
00081         } 
00082         ldns_resolver_set_ip6(res, ip6);
00083 
00084         if (aaaa && a) {
00085                 result = ldns_rr_list_cat_clone(aaaa, a);
00086                 ldns_rr_list_deep_free(aaaa);
00087                 ldns_rr_list_deep_free(a);
00088                 return result;
00089         }
00090         
00091         if (aaaa) {
00092                 result = ldns_rr_list_clone(aaaa);
00093         }
00094         
00095         if (a) {
00096                 result = ldns_rr_list_clone(a);
00097         }
00098 
00099         ldns_rr_list_deep_free(aaaa);
00100         ldns_rr_list_deep_free(a);
00101         return result;
00102 }
00103 
00104 ldns_rr_list *
00105 ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class c, 
00106                 uint16_t flags)
00107 {
00108         ldns_pkt *pkt;
00109         ldns_rr_list *names;
00110         ldns_rdf *name;
00111         size_t i;
00112 
00113         i = 0; 
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         if (pkt) {
00130                 /* extract the data we need */
00131                 names = ldns_pkt_rr_list_by_type(pkt, 
00132                                 LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
00133         }
00134         return names;
00135 }
00136 
00137 /* read a line, put it in a buffer, parse the buffer */
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 
00168         for(i = ldns_fget_token_l(fp, line, "\n", 0, line_nr);
00169                         i > 0; i = ldns_fget_token_l(fp, line, "\n", 0, line_nr)) {
00170                 /* # is comment */
00171                 if (line[0] == '#') {
00172                         continue;
00173                 }
00174                 /* put it in a buffer for further processing */
00175                 linebuf = LDNS_MALLOC(ldns_buffer);
00176 
00177                 ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
00178                 for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, 0);
00179                                 j > 0;
00180                                 j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, 0), cnt++) {
00181                         if (cnt == 0) {
00182                                 /* the address */
00183                                 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, 
00184                                                                 word))) {
00185                                         /* ip6 */
00186                                         ldns_rdf_deep_free(tmp);
00187                                         ip6 = true;
00188                                 } else {
00189                                         if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, 
00190                                                                         word))) {
00191                                                 /* ip4 */
00192                                                 ldns_rdf_deep_free(tmp);
00193                                                 ip6 = false;
00194                                         } else {
00195                                                 /* kaput */
00196                                                 break;
00197                                         }
00198                                 }
00199                                 strncpy(addr, word, LDNS_IP6ADDRLEN);
00200                         } else {
00201                                 /* la al la la */
00202                                 if (ip6) {
00203                                         snprintf(rr_str, LDNS_MAX_LINELEN, 
00204                                                 "%s IN AAAA %s", word, addr);
00205                                 } else {
00206                                         snprintf(rr_str, LDNS_MAX_LINELEN, 
00207                                                 "%s IN A %s", word, addr);
00208                                 }
00209                                 parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
00210                                 if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
00211                                         ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
00212                                 }
00213                                 ldns_rr_free(rr);
00214                         }
00215                 }
00216                 ldns_buffer_free(linebuf);
00217         }
00218         LDNS_FREE(line);
00219         LDNS_FREE(word);
00220         LDNS_FREE(addr);
00221         LDNS_FREE(rr_str);
00222         return list;
00223 }
00224 
00225 ldns_rr_list *
00226 ldns_get_rr_list_hosts_frm_file(char *filename)
00227 {
00228         ldns_rr_list *names;
00229         FILE *fp;
00230 
00231         if (!filename) {
00232                 fp = fopen(LDNS_RESOLV_HOSTS, "r");
00233         
00234         } else {
00235                 fp = fopen(filename, "r");
00236         }
00237         if (!fp) {
00238                 return NULL;
00239         }
00240 
00241         names = ldns_get_rr_list_hosts_frm_fp(fp);
00242         fclose(fp);
00243         return names;
00244 }
00245 
00246 uint16_t
00247 ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c, 
00248                 ldns_rr_list **ret)
00249 {
00250         ldns_rdf_type t;
00251         uint16_t names_found;
00252         ldns_resolver *r;
00253         ldns_status s;
00254 
00255         t = ldns_rdf_get_type(node);
00256         names_found = 0;
00257         r = res;
00258 
00259         if (res == NULL) {
00260                 /* prepare a new resolver, using /etc/resolv.conf as a guide  */
00261                 s = ldns_resolver_new_frm_file(&r, NULL);
00262                 if (s != LDNS_STATUS_OK) {
00263                         return 0;
00264                 } 
00265         }
00266 
00267         if (t == LDNS_RDF_TYPE_DNAME) {
00268                 /* we're asked to query for a name */
00269                 *ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
00270                 names_found = ldns_rr_list_rr_count(*ret);
00271         }
00272 
00273         if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
00274                 /* an address */
00275                 *ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
00276                 names_found = ldns_rr_list_rr_count(*ret);
00277         }
00278 
00279         if (res == NULL) {
00280                 ldns_resolver_deep_free(r);
00281         }
00282         
00283         return names_found;
00284 }
00285 
00286 bool
00287 ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
00288 {
00289         /* does the nsec cover the t given? */
00290         /* copied from host2str.c line 465: ldns_rdf2buffer_str_nsec */
00291         uint8_t window_block_nr;
00292         uint8_t bitmap_length;
00293         uint16_t type;
00294         uint16_t pos = 0;
00295         uint16_t bit_pos;
00296         ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1); 
00297         uint8_t *data = ldns_rdf_data(nsec_type_list);
00298 
00299         while(pos < ldns_rdf_size(nsec_type_list)) {
00300                 window_block_nr = data[pos];
00301                 bitmap_length = data[pos + 1];
00302                 pos += 2;
00303 
00304                 for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
00305                         if (ldns_get_bit(&data[pos], bit_pos)) {
00306                                 type = 256 * (uint16_t) window_block_nr + bit_pos;
00307 
00308                                 if ((ldns_rr_type)type == t) {
00309                                         /* we have a winner */
00310                                         return true;
00311                                 }
00312                         }
00313                 }
00314                 pos += (uint16_t) bitmap_length;
00315         }
00316         return false;
00317 }
00318 
00319 void
00320 ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
00321 {
00322         int16_t rdf;
00323         ldns_rdf *rd;
00324         va_list va_rdf;
00325         va_start(va_rdf, rdfnum);
00326 
00327         for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int)) 
00328         {
00329                 rd = ldns_rr_rdf(r, rdf);
00330                 if (!rd) {
00331                         continue;
00332                 } else {
00333                         ldns_rdf_print(fp, rd);
00334                         fprintf(fp, " "); /* not sure if we want to do this */
00335                 }
00336         }
00337         va_end(va_rdf);
00338 }

Generated on Wed Feb 20 06:40:43 2008 for ldns by  doxygen 1.5.4