rr_functions.c

Go to the documentation of this file.
00001 /*
00002  * rr_function.c
00003  *
00004  * function that operate on specific rr types
00005  *
00006  * (c) NLnet Labs, 2004-2006
00007  * See the file LICENSE for the license
00008  */
00009 
00010 /*
00011  * These come strait from perldoc Net::DNS::RR::xxx
00012  * first the read variant, then the write. This is
00013  * not complete.
00014  */
00015 
00016 #include <ldns/config.h>
00017 
00018 #include <ldns/ldns.h>
00019 
00020 #include <limits.h>
00021 #include <strings.h>
00022 
00030 static ldns_rdf *
00031 ldns_rr_function(ldns_rr_type type, const ldns_rr *rr, size_t pos)
00032 {
00033         if (!rr || ldns_rr_get_type(rr) != type) {
00034                 return NULL;
00035         }
00036         return ldns_rr_rdf(rr, pos);
00037 }
00038 
00047 static bool
00048 ldns_rr_set_function(ldns_rr_type type, ldns_rr *rr, ldns_rdf *rdf, size_t pos)
00049 {
00050         ldns_rdf *pop;
00051         if (!rr || ldns_rr_get_type(rr) != type) {
00052                 return false;
00053         }
00054         pop = ldns_rr_set_rdf(rr, rdf, pos);
00055         ldns_rdf_deep_free(pop);
00056         return true;
00057 }
00058 
00059 /* A/AAAA records */
00060 ldns_rdf *
00061 ldns_rr_a_address(const ldns_rr *r)
00062 {
00063         /* 2 types to check, cannot use the macro */
00064         if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A &&
00065                         ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) {
00066                 return NULL;
00067         }
00068         return ldns_rr_rdf(r, 0);
00069 }
00070 
00071 bool
00072 ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f)
00073 {
00074         /* 2 types to check, cannot use the macro... */
00075         ldns_rdf *pop;
00076         if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A &&
00077                         ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) {
00078                 return false;
00079         }
00080         pop = ldns_rr_set_rdf(r, f, 0);
00081         if (pop) {
00082                 LDNS_FREE(pop);
00083                 return true;
00084         } else {
00085                 return false;
00086         }
00087 }
00088 
00089 /* NS record */
00090 ldns_rdf *
00091 ldns_rr_ns_nsdname(const ldns_rr *r)
00092 {
00093         return ldns_rr_function(LDNS_RR_TYPE_NS, r, 0);
00094 }
00095 
00096 /* MX record */
00097 ldns_rdf *
00098 ldns_rr_mx_preference(const ldns_rr *r)
00099 {
00100         return ldns_rr_function(LDNS_RR_TYPE_MX, r, 0);
00101 }
00102 
00103 ldns_rdf *
00104 ldns_rr_mx_exchange(const ldns_rr *r)
00105 {
00106         return ldns_rr_function(LDNS_RR_TYPE_MX, r, 1);
00107 }
00108 
00109 /* RRSIG record */
00110 ldns_rdf *
00111 ldns_rr_rrsig_typecovered(const ldns_rr *r)
00112 {
00113         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 0);
00114 }
00115 
00116 bool
00117 ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f)
00118 {
00119         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 0);
00120 }
00121 
00122 ldns_rdf *
00123 ldns_rr_rrsig_algorithm(const ldns_rr *r)
00124 {
00125         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 1);
00126 }
00127 
00128 bool
00129 ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f)
00130 {
00131         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 1);
00132 }
00133 
00134 ldns_rdf *
00135 ldns_rr_rrsig_labels(const ldns_rr *r)
00136 {
00137         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 2);
00138 }
00139 
00140 bool
00141 ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f)
00142 {
00143         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 2);
00144 }
00145 
00146 ldns_rdf *
00147 ldns_rr_rrsig_origttl(const ldns_rr *r)
00148 {
00149         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 3);
00150 }
00151 
00152 bool
00153 ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f)
00154 {
00155         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 3);
00156 }
00157 
00158 ldns_rdf *
00159 ldns_rr_rrsig_expiration(const ldns_rr *r)
00160 {
00161         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 4);
00162 }
00163 
00164 bool
00165 ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f)
00166 {
00167         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 4);
00168 }
00169 
00170 ldns_rdf *
00171 ldns_rr_rrsig_inception(const ldns_rr *r)
00172 {
00173         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 5);
00174 }
00175 
00176 bool
00177 ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f)
00178 {
00179         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 5);
00180 }
00181 
00182 ldns_rdf *
00183 ldns_rr_rrsig_keytag(const ldns_rr *r)
00184 {
00185         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 6);
00186 }
00187 
00188 bool
00189 ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f)
00190 {
00191         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 6);
00192 }
00193 
00194 ldns_rdf *
00195 ldns_rr_rrsig_signame(const ldns_rr *r)
00196 {
00197         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 7);
00198 }
00199 
00200 bool
00201 ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f)
00202 {
00203         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 7);
00204 }
00205 
00206 ldns_rdf *
00207 ldns_rr_rrsig_sig(const ldns_rr *r)
00208 {
00209         return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 8);
00210 }
00211 
00212 bool
00213 ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f)
00214 {
00215         return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 8);
00216 }
00217 
00218 /* DNSKEY record */
00219 ldns_rdf *
00220 ldns_rr_dnskey_flags(const ldns_rr *r)
00221 {
00222         return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 0);
00223 }
00224 
00225 bool
00226 ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f)
00227 {
00228         return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 0);
00229 }
00230 
00231 ldns_rdf *
00232 ldns_rr_dnskey_protocol(const ldns_rr *r)
00233 {
00234         return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 1);
00235 }
00236 
00237 bool
00238 ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f)
00239 {
00240         return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 1);
00241 }
00242 
00243 ldns_rdf *
00244 ldns_rr_dnskey_algorithm(const ldns_rr *r)
00245 {
00246         return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 2);
00247 }
00248 
00249 bool
00250 ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f)
00251 {
00252         return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 2);
00253 }
00254 
00255 ldns_rdf *
00256 ldns_rr_dnskey_key(const ldns_rr *r)
00257 {
00258         return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 3);
00259 }
00260 
00261 bool
00262 ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f)
00263 {
00264         return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 3);
00265 }
00266 
00267 size_t
00268 ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
00269                             const size_t len,
00270                             const ldns_algorithm alg)
00271 {
00272         /* for DSA keys */
00273         uint8_t t;
00274         
00275         /* for RSA keys */
00276         uint16_t exp;
00277         uint16_t int16;
00278         
00279         switch ((ldns_signing_algorithm)alg) {
00280         case LDNS_SIGN_DSA:
00281         case LDNS_SIGN_DSA_NSEC3:
00282                 if (len > 0) {
00283                         t = keydata[0];
00284                         return (64 + t*8)*8;
00285                 } else {
00286                         return 0;
00287                 }
00288                 break;
00289         case LDNS_SIGN_RSAMD5:
00290         case LDNS_SIGN_RSASHA1:
00291         case LDNS_SIGN_RSASHA1_NSEC3:
00292 #ifdef USE_SHA2
00293         case LDNS_SIGN_RSASHA256:
00294         case LDNS_SIGN_RSASHA512:
00295 #endif
00296                 if (len > 0) {
00297                         if (keydata[0] == 0) {
00298                                 /* big exponent */
00299                                 if (len > 3) {
00300                                         memmove(&int16, keydata + 1, 2);
00301                                         exp = ntohs(int16);
00302                                         return (len - exp - 3)*8;
00303                                 } else {
00304                                         return 0;
00305                                 }
00306                         } else {
00307                                 exp = keydata[0];
00308                                 return (len-exp-1)*8;
00309                         }
00310                 } else {
00311                         return 0;
00312                 }
00313                 break;
00314 #ifdef USE_GOST
00315         case LDNS_SIGN_ECC_GOST:
00316                 return 512;
00317 #endif
00318 #ifdef USE_ECDSA
00319         case LDNS_SIGN_ECDSAP256SHA256:
00320                 return 256;
00321         case LDNS_SIGN_ECDSAP384SHA384:
00322                 return 384;
00323 #endif
00324         case LDNS_SIGN_HMACMD5:
00325                 return len;
00326         default:
00327                 return 0;
00328         }
00329 }
00330 
00331 size_t 
00332 ldns_rr_dnskey_key_size(const ldns_rr *key) 
00333 {
00334         if (!key || !ldns_rr_dnskey_key(key) 
00335                         || !ldns_rr_dnskey_algorithm(key)) {
00336                 return 0;
00337         }
00338         return ldns_rr_dnskey_key_size_raw((unsigned char*)ldns_rdf_data(ldns_rr_dnskey_key(key)),
00339                                            ldns_rdf_size(ldns_rr_dnskey_key(key)),
00340                                            ldns_rdf2native_int8(ldns_rr_dnskey_algorithm(key))
00341                                           );
00342 }
00343 
00344 uint32_t ldns_soa_serial_identity(uint32_t ATTR_UNUSED(unused), void *data)
00345 {
00346         return (uint32_t) (intptr_t) data;
00347 }
00348 
00349 uint32_t ldns_soa_serial_increment(uint32_t s, void *ATTR_UNUSED(unused))
00350 {
00351         return ldns_soa_serial_increment_by(s, (void *)1);
00352 }
00353 
00354 uint32_t ldns_soa_serial_increment_by(uint32_t s, void *data)
00355 {
00356         return s + (intptr_t) data;
00357 }
00358 
00359 uint32_t ldns_soa_serial_datecounter(uint32_t s, void *data)
00360 {
00361         struct tm tm;
00362         char s_str[11];
00363         int32_t new_s;
00364         time_t t = data ? (time_t) (intptr_t) data : ldns_time(NULL);
00365 
00366         (void) strftime(s_str, 11, "%Y%m%d00", localtime_r(&t, &tm));
00367         new_s = (int32_t) atoi(s_str);
00368         return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s);
00369 }
00370 
00371 uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data)
00372 {
00373         int32_t new_s = data ? (int32_t) (intptr_t) data 
00374                              : (int32_t) ldns_time(NULL);
00375         return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s);
00376 }
00377 
00378 void
00379 ldns_rr_soa_increment(ldns_rr *soa)
00380 {
00381         ldns_rr_soa_increment_func_data(soa, ldns_soa_serial_increment, NULL);
00382 }
00383 
00384 void
00385 ldns_rr_soa_increment_func(ldns_rr *soa, ldns_soa_serial_increment_func_t f)
00386 {
00387         ldns_rr_soa_increment_func_data(soa, f, NULL);
00388 }
00389 
00390 void
00391 ldns_rr_soa_increment_func_data(ldns_rr *soa, 
00392                 ldns_soa_serial_increment_func_t f, void *data)
00393 {
00394         ldns_rdf *prev_soa_serial_rdf;
00395         if ( !soa || !f || ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA 
00396                         || !ldns_rr_rdf(soa, 2)) {
00397                 return;
00398         }
00399         prev_soa_serial_rdf = ldns_rr_set_rdf(
00400                   soa
00401                 , ldns_native2rdf_int32(
00402                           LDNS_RDF_TYPE_INT32
00403                         , (*f)( ldns_rdf2native_int32(
00404                                         ldns_rr_rdf(soa, 2))
00405                               , data
00406                         )
00407                 )
00408                 , 2
00409         );
00410         LDNS_FREE(prev_soa_serial_rdf);
00411 }
00412 
00413 void
00414 ldns_rr_soa_increment_func_int(ldns_rr *soa, 
00415                 ldns_soa_serial_increment_func_t f, int data)
00416 {
00417         ldns_rr_soa_increment_func_data(soa, f, (void *) (intptr_t) data);
00418 }
00419 

Generated on Wed Dec 19 16:56:42 2012 for ldns by  doxygen 1.4.7