00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00060 ldns_rdf *
00061 ldns_rr_a_address(const ldns_rr *r)
00062 {
00063
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
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
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
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
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
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
00273 uint8_t t;
00274
00275
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
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(_), 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(_))
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 uint32_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 = (uint32_t) atoi(s_str);
00368 return new_s > s ? new_s : s+1;
00369 }
00370
00371 uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data)
00372 {
00373 uint32_t new_s = data ? (uint32_t) (intptr_t) data
00374 : (uint32_t) ldns_time(NULL);
00375 return new_s > s ? new_s : s+1;
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