00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <ldns/config.h>
00014
00015 #include <ldns/rdata.h>
00016 #include <ldns/rr.h>
00017 #include <ldns/util.h>
00018 #include <strings.h>
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <sys/time.h>
00022 #include <time.h>
00023 #include <ctype.h>
00024
00025 #ifdef HAVE_SSL
00026 #include <openssl/rand.h>
00027 #endif
00028
00029 ldns_lookup_table *
00030 ldns_lookup_by_name(ldns_lookup_table *table, const char *name)
00031 {
00032 while (table->name != NULL) {
00033 if (strcasecmp(name, table->name) == 0)
00034 return table;
00035 table++;
00036 }
00037 return NULL;
00038 }
00039
00040 ldns_lookup_table *
00041 ldns_lookup_by_id(ldns_lookup_table *table, int id)
00042 {
00043 while (table->name != NULL) {
00044 if (table->id == id)
00045 return table;
00046 table++;
00047 }
00048 return NULL;
00049 }
00050
00051 int
00052 ldns_get_bit(uint8_t bits[], size_t index)
00053 {
00054
00055
00056
00057
00058 return (int) (bits[index / 8] & (1 << (7 - index % 8)));
00059 }
00060
00061 int
00062 ldns_get_bit_r(uint8_t bits[], size_t index)
00063 {
00064
00065
00066
00067
00068 return (int) bits[index / 8] & (1 << (index % 8));
00069 }
00070
00071 void
00072 ldns_set_bit(uint8_t *byte, int bit_nr, bool value)
00073 {
00074
00075
00076
00077
00078 if (bit_nr >= 0 && bit_nr < 8) {
00079 if (value) {
00080 *byte = *byte | (0x01 << bit_nr);
00081 } else {
00082 *byte = *byte & ~(0x01 << bit_nr);
00083 }
00084 }
00085 }
00086
00087 int
00088 ldns_hexdigit_to_int(char ch)
00089 {
00090 switch (ch) {
00091 case '0': return 0;
00092 case '1': return 1;
00093 case '2': return 2;
00094 case '3': return 3;
00095 case '4': return 4;
00096 case '5': return 5;
00097 case '6': return 6;
00098 case '7': return 7;
00099 case '8': return 8;
00100 case '9': return 9;
00101 case 'a': case 'A': return 10;
00102 case 'b': case 'B': return 11;
00103 case 'c': case 'C': return 12;
00104 case 'd': case 'D': return 13;
00105 case 'e': case 'E': return 14;
00106 case 'f': case 'F': return 15;
00107 default:
00108 return -1;
00109 }
00110 }
00111
00112 char
00113 ldns_int_to_hexdigit(int i)
00114 {
00115 switch (i) {
00116 case 0: return '0';
00117 case 1: return '1';
00118 case 2: return '2';
00119 case 3: return '3';
00120 case 4: return '4';
00121 case 5: return '5';
00122 case 6: return '6';
00123 case 7: return '7';
00124 case 8: return '8';
00125 case 9: return '9';
00126 case 10: return 'a';
00127 case 11: return 'b';
00128 case 12: return 'c';
00129 case 13: return 'd';
00130 case 14: return 'e';
00131 case 15: return 'f';
00132 default:
00133 abort();
00134 }
00135 }
00136
00137 int
00138 ldns_hexstring_to_data(uint8_t *data, const char *str)
00139 {
00140 size_t i;
00141
00142 if (!str || !data) {
00143 return -1;
00144 }
00145
00146 if (strlen(str) % 2 != 0) {
00147 return -2;
00148 }
00149
00150 for (i = 0; i < strlen(str) / 2; i++) {
00151 data[i] =
00152 16 * (uint8_t) ldns_hexdigit_to_int(str[i*2]) +
00153 (uint8_t) ldns_hexdigit_to_int(str[i*2 + 1]);
00154 }
00155
00156 return (int) i;
00157 }
00158
00159 const char *
00160 ldns_version(void)
00161 {
00162 return (char*)LDNS_VERSION;
00163 }
00164
00165
00166 static const int mdays[] = {
00167 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00168 };
00169
00170 #define LDNS_MOD(x,y) (((x) % (y) < 0) ? ((x) % (y) + (y)) : ((x) % (y)))
00171 #define LDNS_DIV(x,y) (((x) % (y) < 0) ? ((x) / (y) - 1 ) : ((x) / (y)))
00172
00173 static int
00174 is_leap_year(int year)
00175 {
00176 return LDNS_MOD(year, 4) == 0 && (LDNS_MOD(year, 100) != 0
00177 || LDNS_MOD(year, 400) == 0);
00178 }
00179
00180 static int
00181 leap_days(int y1, int y2)
00182 {
00183 --y1;
00184 --y2;
00185 return (LDNS_DIV(y2, 4) - LDNS_DIV(y1, 4)) -
00186 (LDNS_DIV(y2, 100) - LDNS_DIV(y1, 100)) +
00187 (LDNS_DIV(y2, 400) - LDNS_DIV(y1, 400));
00188 }
00189
00190
00191
00192
00193 time_t
00194 ldns_mktime_from_utc(const struct tm *tm)
00195 {
00196 int year = 1900 + tm->tm_year;
00197 time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year);
00198 time_t hours;
00199 time_t minutes;
00200 time_t seconds;
00201 int i;
00202
00203 for (i = 0; i < tm->tm_mon; ++i) {
00204 days += mdays[i];
00205 }
00206 if (tm->tm_mon > 1 && is_leap_year(year)) {
00207 ++days;
00208 }
00209 days += tm->tm_mday - 1;
00210
00211 hours = days * 24 + tm->tm_hour;
00212 minutes = hours * 60 + tm->tm_min;
00213 seconds = minutes * 60 + tm->tm_sec;
00214
00215 return seconds;
00216 }
00217
00218 time_t
00219 mktime_from_utc(const struct tm *tm)
00220 {
00221 return ldns_mktime_from_utc(tm);
00222 }
00223
00224 #if SIZEOF_TIME_T <= 4
00225
00226 static void
00227 ldns_year_and_yday_from_days_since_epoch(int64_t days, struct tm *result)
00228 {
00229 int year = 1970;
00230 int new_year;
00231
00232 while (days < 0 || days >= (int64_t) (is_leap_year(year) ? 366 : 365)) {
00233 new_year = year + (int) LDNS_DIV(days, 365);
00234 days -= (new_year - year) * 365;
00235 days -= leap_days(year, new_year);
00236 year = new_year;
00237 }
00238 result->tm_year = year;
00239 result->tm_yday = (int) days;
00240 }
00241
00242
00243 static const int leap_year_mdays[] = {
00244 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00245 };
00246
00247 static void
00248 ldns_mon_and_mday_from_year_and_yday(struct tm *result)
00249 {
00250 int idays = result->tm_yday;
00251 const int *mon_lengths = is_leap_year(result->tm_year) ?
00252 leap_year_mdays : mdays;
00253
00254 result->tm_mon = 0;
00255 while (idays >= mon_lengths[result->tm_mon]) {
00256 idays -= mon_lengths[result->tm_mon++];
00257 }
00258 result->tm_mday = idays + 1;
00259 }
00260
00261 static void
00262 ldns_wday_from_year_and_yday(struct tm *result)
00263 {
00264 result->tm_wday = 4
00265 + LDNS_MOD((result->tm_year - 1970), 7) * LDNS_MOD(365, 7)
00266 + leap_days(1970, result->tm_year)
00267 + result->tm_yday;
00268 result->tm_wday = LDNS_MOD(result->tm_wday, 7);
00269 if (result->tm_wday < 0) {
00270 result->tm_wday += 7;
00271 }
00272 }
00273
00274 static struct tm *
00275 ldns_gmtime64_r(int64_t clock, struct tm *result)
00276 {
00277 result->tm_isdst = 0;
00278 result->tm_sec = (int) LDNS_MOD(clock, 60);
00279 clock = LDNS_DIV(clock, 60);
00280 result->tm_min = (int) LDNS_MOD(clock, 60);
00281 clock = LDNS_DIV(clock, 60);
00282 result->tm_hour = (int) LDNS_MOD(clock, 24);
00283 clock = LDNS_DIV(clock, 24);
00284
00285 ldns_year_and_yday_from_days_since_epoch(clock, result);
00286 ldns_mon_and_mday_from_year_and_yday(result);
00287 ldns_wday_from_year_and_yday(result);
00288 result->tm_year -= 1900;
00289
00290 return result;
00291 }
00292
00293 #endif
00294
00295 static int64_t
00296 ldns_serial_arithmitics_time(int32_t time, time_t now)
00297 {
00298 int32_t offset = time - (int32_t) now;
00299 return (int64_t) now + offset;
00300 }
00301
00302
00303 struct tm *
00304 ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result)
00305 {
00306 #if SIZEOF_TIME_T <= 4
00307 int64_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
00308 return ldns_gmtime64_r(secs_since_epoch, result);
00309 #else
00310 time_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
00311 return gmtime_r(&secs_since_epoch, result);
00312 #endif
00313 }
00314
00326 int
00327 ldns_init_random(FILE *fd, unsigned int size)
00328 {
00329
00330
00331 FILE *rand_f;
00332 uint8_t *seed;
00333 size_t read = 0;
00334 unsigned int seed_i;
00335 struct timeval tv;
00336
00337
00338
00339 if (size < (unsigned int) sizeof(seed_i)){
00340 size = (unsigned int) sizeof(seed_i);
00341 }
00342
00343 seed = LDNS_XMALLOC(uint8_t, size);
00344 if(!seed) {
00345 return 1;
00346 }
00347
00348 if (!fd) {
00349 if ((rand_f = fopen("/dev/urandom", "r")) == NULL) {
00350
00351 if ((rand_f = fopen("/dev/random", "r")) == NULL) {
00352
00353
00354 for (read = 0; read < size; read++) {
00355 gettimeofday(&tv, NULL);
00356 seed[read] = (uint8_t) (tv.tv_usec % 256);
00357 }
00358 } else {
00359 read = fread(seed, 1, size, rand_f);
00360 }
00361 } else {
00362 read = fread(seed, 1, size, rand_f);
00363 }
00364 } else {
00365 rand_f = fd;
00366 read = fread(seed, 1, size, rand_f);
00367 }
00368
00369 if (read < size) {
00370 LDNS_FREE(seed);
00371 if (!fd) fclose(rand_f);
00372 return 1;
00373 } else {
00374 #ifdef HAVE_SSL
00375
00376
00377 RAND_seed(seed, (int) size);
00378 #else
00379
00380
00381
00382 memcpy(&seed_i, seed, sizeof(seed_i));
00383 srandom(seed_i);
00384 #endif
00385 LDNS_FREE(seed);
00386 }
00387
00388 if (!fd) {
00389 if (rand_f) fclose(rand_f);
00390 }
00391
00392 return 0;
00393 }
00394
00399 uint16_t
00400 ldns_get_random(void)
00401 {
00402 uint16_t rid = 0;
00403 #ifdef HAVE_SSL
00404 if (RAND_bytes((unsigned char*)&rid, 2) != 1) {
00405 rid = (uint16_t) random();
00406 }
00407 #else
00408 rid = (uint16_t) random();
00409 #endif
00410 return rid;
00411 }
00412
00413
00414
00415
00416
00417 char *
00418 ldns_bubblebabble(uint8_t *data, size_t len)
00419 {
00420 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
00421 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
00422 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
00423 size_t i, j = 0, rounds, seed = 1;
00424 char *retval;
00425
00426 rounds = (len / 2) + 1;
00427 retval = LDNS_XMALLOC(char, rounds * 6);
00428 if(!retval) return NULL;
00429 retval[j++] = 'x';
00430 for (i = 0; i < rounds; i++) {
00431 size_t idx0, idx1, idx2, idx3, idx4;
00432 if ((i + 1 < rounds) || (len % 2 != 0)) {
00433 idx0 = (((((size_t)(data[2 * i])) >> 6) & 3) +
00434 seed) % 6;
00435 idx1 = (((size_t)(data[2 * i])) >> 2) & 15;
00436 idx2 = ((((size_t)(data[2 * i])) & 3) +
00437 (seed / 6)) % 6;
00438 retval[j++] = vowels[idx0];
00439 retval[j++] = consonants[idx1];
00440 retval[j++] = vowels[idx2];
00441 if ((i + 1) < rounds) {
00442 idx3 = (((size_t)(data[(2 * i) + 1])) >> 4) & 15;
00443 idx4 = (((size_t)(data[(2 * i) + 1]))) & 15;
00444 retval[j++] = consonants[idx3];
00445 retval[j++] = '-';
00446 retval[j++] = consonants[idx4];
00447 seed = ((seed * 5) +
00448 ((((size_t)(data[2 * i])) * 7) +
00449 ((size_t)(data[(2 * i) + 1])))) % 36;
00450 }
00451 } else {
00452 idx0 = seed % 6;
00453 idx1 = 16;
00454 idx2 = seed / 6;
00455 retval[j++] = vowels[idx0];
00456 retval[j++] = consonants[idx1];
00457 retval[j++] = vowels[idx2];
00458 }
00459 }
00460 retval[j++] = 'x';
00461 retval[j++] = '\0';
00462 return retval;
00463 }
00464
00465
00466
00467
00468 #ifdef HAVE_B64_NTOP
00469 int ldns_b64_ntop(const uint8_t* src, size_t srclength,
00470 char *target, size_t targsize);
00471 {
00472 return b64_ntop(src, srclength, target, targsize);
00473 }
00474 #endif
00475
00476
00477
00478
00479 #ifdef HAVE_B64_PTON
00480 int ldns_b64_pton(const char* src, uint8_t *target, size_t targsize)
00481 {
00482 return b64_pton(src, target, targsize);
00483 }
00484 #endif
00485
00486
00487 static int
00488 ldns_b32_ntop_base(const uint8_t* src, size_t src_sz,
00489 char* dst, size_t dst_sz,
00490 bool extended_hex, bool add_padding)
00491 {
00492 size_t ret_sz;
00493 const char* b32 = extended_hex ? "0123456789abcdefghijklmnopqrstuv"
00494 : "abcdefghijklmnopqrstuvwxyz234567";
00495
00496 size_t c = 0;
00497
00498
00499
00500
00501 ret_sz = add_padding ? ldns_b32_ntop_calculate_size(src_sz)
00502 : ldns_b32_ntop_calculate_size_no_padding(src_sz);
00503
00504
00505 if (dst_sz < ret_sz + 1)
00506 return -1;
00507
00508
00509 dst[ret_sz] = '\0';
00510
00511
00512 while (src_sz >= 5) {
00513
00514 dst[0] = b32[(src[0] ) >> 3];
00515
00516
00517 dst[1] = b32[(src[0] & 0x07) << 2 | src[1] >> 6];
00518
00519
00520 dst[2] = b32[(src[1] & 0x3e) >> 1];
00521
00522
00523 dst[3] = b32[(src[1] & 0x01) << 4 | src[2] >> 4];
00524
00525
00526 dst[4] = b32[(src[2] & 0x0f) << 1 | src[3] >> 7];
00527
00528
00529 dst[5] = b32[(src[3] & 0x7c) >> 2];
00530
00531
00532 dst[6] = b32[(src[3] & 0x03) << 3 | src[4] >> 5];
00533
00534
00535 dst[7] = b32[(src[4] & 0x1f) ];
00536
00537 src_sz -= 5;
00538 src += 5;
00539 dst += 8;
00540 }
00541
00542 switch (src_sz) {
00543 case 4:
00544 dst[6] = b32[(src[3] & 0x03) << 3];
00545
00546
00547 dst[5] = b32[(src[3] & 0x7c) >> 2];
00548
00549
00550 c = src[3] >> 7 ;
00551 case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
00552
00553
00554 c = src[2] >> 4 ;
00555 case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c];
00556
00557
00558 dst[2] = b32[(src[1] & 0x3e) >> 1];
00559
00560
00561 c = src[1] >> 6 ;
00562 case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c];
00563
00564
00565 dst[0] = b32[ src[0] >> 3];
00566 }
00567
00568 if (add_padding) {
00569 switch (src_sz) {
00570 case 1: dst[2] = '=';
00571 dst[3] = '=';
00572 case 2: dst[4] = '=';
00573 case 3: dst[5] = '=';
00574 dst[6] = '=';
00575 case 4: dst[7] = '=';
00576 }
00577 }
00578 return (int)ret_sz;
00579 }
00580
00581 int
00582 ldns_b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz)
00583 {
00584 return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, false, true);
00585 }
00586
00587 int
00588 ldns_b32_ntop_extended_hex(const uint8_t* src, size_t src_sz,
00589 char* dst, size_t dst_sz)
00590 {
00591 return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, true, true);
00592 }
00593
00594 #ifndef HAVE_B32_NTOP
00595
00596 int
00597 b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz)
00598 {
00599 return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, false, true);
00600 }
00601
00602 int
00603 b32_ntop_extended_hex(const uint8_t* src, size_t src_sz,
00604 char* dst, size_t dst_sz)
00605 {
00606 return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, true, true);
00607 }
00608
00609 #endif
00610
00611 static int
00612 ldns_b32_pton_base(const char* src, size_t src_sz,
00613 uint8_t* dst, size_t dst_sz,
00614 bool extended_hex, bool check_padding)
00615 {
00616 size_t i = 0;
00617 char ch = '\0';
00618 uint8_t buf[8];
00619 uint8_t* start = dst;
00620
00621 while (src_sz) {
00622
00623 for (i = 0; i < 8; i++) {
00624
00625 do {
00626 ch = *src++;
00627 --src_sz;
00628
00629 } while (isspace(ch) && src_sz > 0);
00630
00631 if (ch == '=' || ch == '\0')
00632 break;
00633
00634 else if (extended_hex)
00635
00636 if (ch >= '0' && ch <= '9')
00637 buf[i] = (uint8_t)ch - '0';
00638 else if (ch >= 'a' && ch <= 'v')
00639 buf[i] = (uint8_t)ch - 'a' + 10;
00640 else if (ch >= 'A' && ch <= 'V')
00641 buf[i] = (uint8_t)ch - 'A' + 10;
00642 else
00643 return -1;
00644
00645 else if (ch >= 'a' && ch <= 'z')
00646 buf[i] = (uint8_t)ch - 'a';
00647 else if (ch >= 'A' && ch <= 'Z')
00648 buf[i] = (uint8_t)ch - 'A';
00649 else if (ch >= '2' && ch <= '7')
00650 buf[i] = (uint8_t)ch - '2' + 26;
00651 else
00652 return -1;
00653 }
00654
00655 if (i < 8)
00656 break;
00657
00658
00659 if (dst_sz < 5)
00660 return -1;
00661
00662
00663
00664 dst[0] = buf[0] << 3 | buf[1] >> 2;
00665
00666
00667
00668
00669 dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
00670
00671
00672
00673 dst[2] = buf[3] << 4 | buf[4] >> 1;
00674
00675
00676
00677
00678 dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
00679
00680
00681
00682 dst[4] = buf[6] << 5 | buf[7];
00683
00684 dst += 5;
00685 dst_sz -= 5;
00686 }
00687
00688 if (i > 0 && i < 8) {
00689
00690
00691 if (dst_sz < (i + 1) / 2)
00692 return -1;
00693
00694 switch (i) {
00695 case 7:
00696
00697
00698 dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
00699
00700 case 5:
00701
00702 dst[2] = buf[3] << 4 | buf[4] >> 1;
00703
00704 case 4:
00705
00706
00707 dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
00708
00709 case 2:
00710
00711 dst[0] = buf[0] << 3 | buf[1] >> 2;
00712
00713 break;
00714
00715 default:
00716 return -1;
00717 }
00718 dst += (i + 1) / 2;
00719
00720 if (check_padding) {
00721
00722 if (ch != '=')
00723 return -1;
00724
00725
00726 for (i = 8 - i - 1; i > 0; i--) {
00727
00728 do {
00729 if (src_sz == 0)
00730 return -1;
00731 ch = *src++;
00732 src_sz--;
00733
00734 } while (isspace(ch));
00735
00736 if (ch != '=')
00737 return -1;
00738 }
00739 }
00740 }
00741 return dst - start;
00742 }
00743
00744 int
00745 ldns_b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz)
00746 {
00747 return ldns_b32_pton_base(src, src_sz, dst, dst_sz, false, true);
00748 }
00749
00750 int
00751 ldns_b32_pton_extended_hex(const char* src, size_t src_sz,
00752 uint8_t* dst, size_t dst_sz)
00753 {
00754 return ldns_b32_pton_base(src, src_sz, dst, dst_sz, true, true);
00755 }
00756
00757 #ifndef HAVE_B32_PTON
00758
00759 int
00760 b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz)
00761 {
00762 return ldns_b32_pton_base(src, src_sz, dst, dst_sz, false, true);
00763 }
00764
00765 int
00766 b32_pton_extended_hex(const char* src, size_t src_sz,
00767 uint8_t* dst, size_t dst_sz)
00768 {
00769 return ldns_b32_pton_base(src, src_sz, dst, dst_sz, true, true);
00770 }
00771
00772 #endif
00773