rr_functions.c revision 238104
1/* 2 * rr_function.c 3 * 4 * function that operate on specific rr types 5 * 6 * (c) NLnet Labs, 2004-2006 7 * See the file LICENSE for the license 8 */ 9 10/* 11 * These come strait from perldoc Net::DNS::RR::xxx 12 * first the read variant, then the write. This is 13 * not complete. 14 */ 15 16#include <ldns/config.h> 17 18#include <ldns/ldns.h> 19 20#include <limits.h> 21#include <strings.h> 22 23/** 24 * return a specific rdf 25 * \param[in] type type of RR 26 * \param[in] rr the rr itself 27 * \param[in] pos at which postion to get it 28 * \return the rdf sought 29 */ 30static ldns_rdf * 31ldns_rr_function(ldns_rr_type type, const ldns_rr *rr, size_t pos) 32{ 33 if (!rr || ldns_rr_get_type(rr) != type) { 34 return NULL; 35 } 36 return ldns_rr_rdf(rr, pos); 37} 38 39/** 40 * set a specific rdf 41 * \param[in] type type of RR 42 * \param[in] rr the rr itself 43 * \param[in] rdf the rdf to set 44 * \param[in] pos at which postion to set it 45 * \return true or false 46 */ 47static bool 48ldns_rr_set_function(ldns_rr_type type, ldns_rr *rr, ldns_rdf *rdf, size_t pos) 49{ 50 ldns_rdf *pop; 51 if (!rr || ldns_rr_get_type(rr) != type) { 52 return false; 53 } 54 pop = ldns_rr_set_rdf(rr, rdf, pos); 55 ldns_rdf_deep_free(pop); 56 return true; 57} 58 59/* A/AAAA records */ 60ldns_rdf * 61ldns_rr_a_address(const ldns_rr *r) 62{ 63 /* 2 types to check, cannot use the macro */ 64 if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A && 65 ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) { 66 return NULL; 67 } 68 return ldns_rr_rdf(r, 0); 69} 70 71bool 72ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f) 73{ 74 /* 2 types to check, cannot use the macro... */ 75 ldns_rdf *pop; 76 if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A && 77 ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) { 78 return false; 79 } 80 pop = ldns_rr_set_rdf(r, f, 0); 81 if (pop) { 82 LDNS_FREE(pop); 83 return true; 84 } else { 85 return false; 86 } 87} 88 89/* NS record */ 90ldns_rdf * 91ldns_rr_ns_nsdname(const ldns_rr *r) 92{ 93 return ldns_rr_function(LDNS_RR_TYPE_NS, r, 0); 94} 95 96/* MX record */ 97ldns_rdf * 98ldns_rr_mx_preference(const ldns_rr *r) 99{ 100 return ldns_rr_function(LDNS_RR_TYPE_MX, r, 0); 101} 102 103ldns_rdf * 104ldns_rr_mx_exchange(const ldns_rr *r) 105{ 106 return ldns_rr_function(LDNS_RR_TYPE_MX, r, 1); 107} 108 109/* RRSIG record */ 110ldns_rdf * 111ldns_rr_rrsig_typecovered(const ldns_rr *r) 112{ 113 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 0); 114} 115 116bool 117ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f) 118{ 119 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 0); 120} 121 122ldns_rdf * 123ldns_rr_rrsig_algorithm(const ldns_rr *r) 124{ 125 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 1); 126} 127 128bool 129ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f) 130{ 131 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 1); 132} 133 134ldns_rdf * 135ldns_rr_rrsig_labels(const ldns_rr *r) 136{ 137 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 2); 138} 139 140bool 141ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f) 142{ 143 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 2); 144} 145 146ldns_rdf * 147ldns_rr_rrsig_origttl(const ldns_rr *r) 148{ 149 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 3); 150} 151 152bool 153ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f) 154{ 155 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 3); 156} 157 158ldns_rdf * 159ldns_rr_rrsig_expiration(const ldns_rr *r) 160{ 161 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 4); 162} 163 164bool 165ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f) 166{ 167 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 4); 168} 169 170ldns_rdf * 171ldns_rr_rrsig_inception(const ldns_rr *r) 172{ 173 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 5); 174} 175 176bool 177ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f) 178{ 179 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 5); 180} 181 182ldns_rdf * 183ldns_rr_rrsig_keytag(const ldns_rr *r) 184{ 185 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 6); 186} 187 188bool 189ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f) 190{ 191 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 6); 192} 193 194ldns_rdf * 195ldns_rr_rrsig_signame(const ldns_rr *r) 196{ 197 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 7); 198} 199 200bool 201ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f) 202{ 203 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 7); 204} 205 206ldns_rdf * 207ldns_rr_rrsig_sig(const ldns_rr *r) 208{ 209 return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 8); 210} 211 212bool 213ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f) 214{ 215 return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 8); 216} 217 218/* DNSKEY record */ 219ldns_rdf * 220ldns_rr_dnskey_flags(const ldns_rr *r) 221{ 222 return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 0); 223} 224 225bool 226ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f) 227{ 228 return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 0); 229} 230 231ldns_rdf * 232ldns_rr_dnskey_protocol(const ldns_rr *r) 233{ 234 return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 1); 235} 236 237bool 238ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f) 239{ 240 return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 1); 241} 242 243ldns_rdf * 244ldns_rr_dnskey_algorithm(const ldns_rr *r) 245{ 246 return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 2); 247} 248 249bool 250ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f) 251{ 252 return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 2); 253} 254 255ldns_rdf * 256ldns_rr_dnskey_key(const ldns_rr *r) 257{ 258 return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 3); 259} 260 261bool 262ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f) 263{ 264 return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 3); 265} 266 267size_t 268ldns_rr_dnskey_key_size_raw(const unsigned char* keydata, 269 const size_t len, 270 const ldns_algorithm alg) 271{ 272 /* for DSA keys */ 273 uint8_t t; 274 275 /* for RSA keys */ 276 uint16_t exp; 277 uint16_t int16; 278 279 switch ((ldns_signing_algorithm)alg) { 280 case LDNS_SIGN_DSA: 281 case LDNS_SIGN_DSA_NSEC3: 282 if (len > 0) { 283 t = keydata[0]; 284 return (64 + t*8)*8; 285 } else { 286 return 0; 287 } 288 break; 289 case LDNS_SIGN_RSAMD5: 290 case LDNS_SIGN_RSASHA1: 291 case LDNS_SIGN_RSASHA1_NSEC3: 292#ifdef USE_SHA2 293 case LDNS_SIGN_RSASHA256: 294 case LDNS_SIGN_RSASHA512: 295#endif 296 if (len > 0) { 297 if (keydata[0] == 0) { 298 /* big exponent */ 299 if (len > 3) { 300 memmove(&int16, keydata + 1, 2); 301 exp = ntohs(int16); 302 return (len - exp - 3)*8; 303 } else { 304 return 0; 305 } 306 } else { 307 exp = keydata[0]; 308 return (len-exp-1)*8; 309 } 310 } else { 311 return 0; 312 } 313 break; 314#ifdef USE_GOST 315 case LDNS_SIGN_ECC_GOST: 316 return 512; 317#endif 318#ifdef USE_ECDSA 319 case LDNS_SIGN_ECDSAP256SHA256: 320 return 256; 321 case LDNS_SIGN_ECDSAP384SHA384: 322 return 384; 323#endif 324 case LDNS_SIGN_HMACMD5: 325 return len; 326 default: 327 return 0; 328 } 329} 330 331size_t 332ldns_rr_dnskey_key_size(const ldns_rr *key) 333{ 334 if (!key || !ldns_rr_dnskey_key(key) 335 || !ldns_rr_dnskey_algorithm(key)) { 336 return 0; 337 } 338 return ldns_rr_dnskey_key_size_raw((unsigned char*)ldns_rdf_data(ldns_rr_dnskey_key(key)), 339 ldns_rdf_size(ldns_rr_dnskey_key(key)), 340 ldns_rdf2native_int8(ldns_rr_dnskey_algorithm(key)) 341 ); 342} 343 344uint32_t ldns_soa_serial_identity(uint32_t ATTR_UNUSED(unused), void *data) 345{ 346 return (uint32_t) (intptr_t) data; 347} 348 349uint32_t ldns_soa_serial_increment(uint32_t s, void *ATTR_UNUSED(unused)) 350{ 351 return ldns_soa_serial_increment_by(s, (void *)1); 352} 353 354uint32_t ldns_soa_serial_increment_by(uint32_t s, void *data) 355{ 356 return s + (intptr_t) data; 357} 358 359uint32_t ldns_soa_serial_datecounter(uint32_t s, void *data) 360{ 361 struct tm tm; 362 char s_str[11]; 363 int32_t new_s; 364 time_t t = data ? (time_t) (intptr_t) data : ldns_time(NULL); 365 366 (void) strftime(s_str, 11, "%Y%m%d00", localtime_r(&t, &tm)); 367 new_s = (int32_t) atoi(s_str); 368 return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s); 369} 370 371uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data) 372{ 373 int32_t new_s = data ? (int32_t) (intptr_t) data 374 : (int32_t) ldns_time(NULL); 375 return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s); 376} 377 378void 379ldns_rr_soa_increment(ldns_rr *soa) 380{ 381 ldns_rr_soa_increment_func_data(soa, ldns_soa_serial_increment, NULL); 382} 383 384void 385ldns_rr_soa_increment_func(ldns_rr *soa, ldns_soa_serial_increment_func_t f) 386{ 387 ldns_rr_soa_increment_func_data(soa, f, NULL); 388} 389 390void 391ldns_rr_soa_increment_func_data(ldns_rr *soa, 392 ldns_soa_serial_increment_func_t f, void *data) 393{ 394 ldns_rdf *prev_soa_serial_rdf; 395 if ( !soa || !f || ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA 396 || !ldns_rr_rdf(soa, 2)) { 397 return; 398 } 399 prev_soa_serial_rdf = ldns_rr_set_rdf( 400 soa 401 , ldns_native2rdf_int32( 402 LDNS_RDF_TYPE_INT32 403 , (*f)( ldns_rdf2native_int32( 404 ldns_rr_rdf(soa, 2)) 405 , data 406 ) 407 ) 408 , 2 409 ); 410 LDNS_FREE(prev_soa_serial_rdf); 411} 412 413void 414ldns_rr_soa_increment_func_int(ldns_rr *soa, 415 ldns_soa_serial_increment_func_t f, int data) 416{ 417 ldns_rr_soa_increment_func_data(soa, f, (void *) (intptr_t) data); 418} 419 420