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
00024 #ifdef HAVE_SSL
00025 #include <openssl/rand.h>
00026 #endif
00027
00028
00029 void
00030 xprintf_rdf(ldns_rdf *rd)
00031 {
00032
00033 fprintf(stderr, "size\t:%u\n", (unsigned int)ldns_rdf_size(rd));
00034 fprintf(stderr, "type\t:%u\n", (unsigned int)ldns_rdf_get_type(rd));
00035 fprintf(stderr, "data\t:[%.*s]\n", (int)ldns_rdf_size(rd),
00036 (char*)ldns_rdf_data(rd));
00037 }
00038
00039 void
00040 xprintf_rr(ldns_rr *rr)
00041 {
00042
00043 uint16_t count, i;
00044
00045 count = ldns_rr_rd_count(rr);
00046
00047 for(i = 0; i < count; i++) {
00048 fprintf(stderr, "print rd %u\n", (unsigned int) i);
00049 xprintf_rdf(rr->_rdata_fields[i]);
00050 }
00051 }
00052
00053 void xprintf_hex(uint8_t *data, size_t len)
00054 {
00055 size_t i;
00056 for (i = 0; i < len; i++) {
00057 if (i > 0 && i % 20 == 0) {
00058 printf("\t; %u - %u\n", (unsigned int) i - 19, (unsigned int) i);
00059 }
00060 printf("%02x ", (unsigned int) data[i]);
00061 }
00062 printf("\n");
00063 }
00064
00065 ldns_lookup_table *
00066 ldns_lookup_by_name(ldns_lookup_table *table, const char *name)
00067 {
00068 while (table->name != NULL) {
00069 if (strcasecmp(name, table->name) == 0)
00070 return table;
00071 table++;
00072 }
00073 return NULL;
00074 }
00075
00076 ldns_lookup_table *
00077 ldns_lookup_by_id(ldns_lookup_table *table, int id)
00078 {
00079 while (table->name != NULL) {
00080 if (table->id == id)
00081 return table;
00082 table++;
00083 }
00084 return NULL;
00085 }
00086
00087 int
00088 ldns_get_bit(uint8_t bits[], size_t index)
00089 {
00090
00091
00092
00093
00094 return (int) (bits[index / 8] & (1 << (7 - index % 8)));
00095 }
00096
00097 int
00098 ldns_get_bit_r(uint8_t bits[], size_t index)
00099 {
00100
00101
00102
00103
00104 return (int) bits[index / 8] & (1 << (index % 8));
00105 }
00106
00107 void
00108 ldns_set_bit(uint8_t *byte, int bit_nr, bool value)
00109 {
00110 if (bit_nr >= 0 && bit_nr < 8) {
00111 if (value) {
00112 *byte = *byte | (0x01 << bit_nr);
00113 } else {
00114 *byte = *byte & ~(0x01 << bit_nr);
00115 }
00116 }
00117 }
00118
00119 int
00120 ldns_hexdigit_to_int(char ch)
00121 {
00122 switch (ch) {
00123 case '0': return 0;
00124 case '1': return 1;
00125 case '2': return 2;
00126 case '3': return 3;
00127 case '4': return 4;
00128 case '5': return 5;
00129 case '6': return 6;
00130 case '7': return 7;
00131 case '8': return 8;
00132 case '9': return 9;
00133 case 'a': case 'A': return 10;
00134 case 'b': case 'B': return 11;
00135 case 'c': case 'C': return 12;
00136 case 'd': case 'D': return 13;
00137 case 'e': case 'E': return 14;
00138 case 'f': case 'F': return 15;
00139 default:
00140 return -1;
00141 }
00142 }
00143
00144 char
00145 ldns_int_to_hexdigit(int i)
00146 {
00147 switch (i) {
00148 case 0: return '0';
00149 case 1: return '1';
00150 case 2: return '2';
00151 case 3: return '3';
00152 case 4: return '4';
00153 case 5: return '5';
00154 case 6: return '6';
00155 case 7: return '7';
00156 case 8: return '8';
00157 case 9: return '9';
00158 case 10: return 'a';
00159 case 11: return 'b';
00160 case 12: return 'c';
00161 case 13: return 'd';
00162 case 14: return 'e';
00163 case 15: return 'f';
00164 default:
00165 abort();
00166 }
00167 }
00168
00169 int
00170 ldns_hexstring_to_data(uint8_t *data, const char *str)
00171 {
00172 size_t i;
00173
00174 if (!str || !data) {
00175 return -1;
00176 }
00177
00178 if (strlen(str) % 2 != 0) {
00179 return -2;
00180 }
00181
00182 for (i = 0; i < strlen(str) / 2; i++) {
00183 data[i] =
00184 16 * (uint8_t) ldns_hexdigit_to_int(str[i*2]) +
00185 (uint8_t) ldns_hexdigit_to_int(str[i*2 + 1]);
00186 }
00187
00188 return (int) i;
00189 }
00190
00191 const char *
00192 ldns_version(void)
00193 {
00194 return (char*)LDNS_VERSION;
00195 }
00196
00197
00198 static const int mdays[] = {
00199 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00200 };
00201
00202 #define LDNS_MOD(x,y) (((x) % (y) < 0) ? ((x) % (y) + (y)) : ((x) % (y)))
00203 #define LDNS_DIV(x,y) (((x) % (y) < 0) ? ((x) / (y) - 1 ) : ((x) / (y)))
00204
00205 static int
00206 is_leap_year(int year)
00207 {
00208 return LDNS_MOD(year, 4) == 0 && (LDNS_MOD(year, 100) != 0
00209 || LDNS_MOD(year, 400) == 0);
00210 }
00211
00212 static int
00213 leap_days(int y1, int y2)
00214 {
00215 --y1;
00216 --y2;
00217 return (LDNS_DIV(y2, 4) - LDNS_DIV(y1, 4)) -
00218 (LDNS_DIV(y2, 100) - LDNS_DIV(y1, 100)) +
00219 (LDNS_DIV(y2, 400) - LDNS_DIV(y1, 400));
00220 }
00221
00222
00223
00224
00225 time_t
00226 mktime_from_utc(const struct tm *tm)
00227 {
00228 int year = 1900 + tm->tm_year;
00229 time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year);
00230 time_t hours;
00231 time_t minutes;
00232 time_t seconds;
00233 int i;
00234
00235 for (i = 0; i < tm->tm_mon; ++i) {
00236 days += mdays[i];
00237 }
00238 if (tm->tm_mon > 1 && is_leap_year(year)) {
00239 ++days;
00240 }
00241 days += tm->tm_mday - 1;
00242
00243 hours = days * 24 + tm->tm_hour;
00244 minutes = hours * 60 + tm->tm_min;
00245 seconds = minutes * 60 + tm->tm_sec;
00246
00247 return seconds;
00248 }
00249
00250 #if SIZEOF_TIME_T <= 4
00251
00252 static void
00253 ldns_year_and_yday_from_days_since_epoch(int64_t days, struct tm *result)
00254 {
00255 int year = 1970;
00256 int new_year;
00257
00258 while (days < 0 || days >= (int64_t) (is_leap_year(year) ? 366 : 365)) {
00259 new_year = year + (int) LDNS_DIV(days, 365);
00260 days -= (new_year - year) * 365;
00261 days -= leap_days(year, new_year);
00262 year = new_year;
00263 }
00264 result->tm_year = year;
00265 result->tm_yday = (int) days;
00266 }
00267
00268
00269 static const int leap_year_mdays[] = {
00270 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00271 };
00272
00273 static void
00274 ldns_mon_and_mday_from_year_and_yday(struct tm *result)
00275 {
00276 int idays = result->tm_yday;
00277 const int *mon_lengths = is_leap_year(result->tm_year) ?
00278 leap_year_mdays : mdays;
00279
00280 result->tm_mon = 0;
00281 while (idays >= mon_lengths[result->tm_mon]) {
00282 idays -= mon_lengths[result->tm_mon++];
00283 }
00284 result->tm_mday = idays + 1;
00285 }
00286
00287 static void
00288 ldns_wday_from_year_and_yday(struct tm *result)
00289 {
00290 result->tm_wday = 4
00291 + LDNS_MOD((result->tm_year - 1970), 7) * LDNS_MOD(365, 7)
00292 + leap_days(1970, result->tm_year)
00293 + result->tm_yday;
00294 result->tm_wday = LDNS_MOD(result->tm_wday, 7);
00295 if (result->tm_wday < 0) {
00296 result->tm_wday += 7;
00297 }
00298 }
00299
00300 static struct tm *
00301 ldns_gmtime64_r(int64_t clock, struct tm *result)
00302 {
00303 result->tm_isdst = 0;
00304 result->tm_sec = (int) LDNS_MOD(clock, 60);
00305 clock = LDNS_DIV(clock, 60);
00306 result->tm_min = (int) LDNS_MOD(clock, 60);
00307 clock = LDNS_DIV(clock, 60);
00308 result->tm_hour = (int) LDNS_MOD(clock, 24);
00309 clock = LDNS_DIV(clock, 24);
00310
00311 ldns_year_and_yday_from_days_since_epoch(clock, result);
00312 ldns_mon_and_mday_from_year_and_yday(result);
00313 ldns_wday_from_year_and_yday(result);
00314 result->tm_year -= 1900;
00315
00316 return result;
00317 }
00318
00319 #endif
00320
00321 static int64_t
00322 ldns_serial_arithmitics_time(int32_t time, time_t now)
00323 {
00324 int32_t offset = time - (int32_t) now;
00325 return (int64_t) now + offset;
00326 }
00327
00328
00329 struct tm *
00330 ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result)
00331 {
00332 #if SIZEOF_TIME_T <= 4
00333 int64_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
00334 return ldns_gmtime64_r(secs_since_epoch, result);
00335 #else
00336 time_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
00337 return gmtime_r(&secs_since_epoch, result);
00338 #endif
00339 }
00340
00352 int
00353 ldns_init_random(FILE *fd, unsigned int size)
00354 {
00355
00356
00357 FILE *rand_f;
00358 uint8_t *seed;
00359 size_t read = 0;
00360 unsigned int seed_i;
00361 struct timeval tv;
00362
00363
00364
00365 if (size < (unsigned int) sizeof(seed_i)){
00366 size = (unsigned int) sizeof(seed_i);
00367 }
00368
00369 seed = LDNS_XMALLOC(uint8_t, size);
00370 if(!seed) {
00371 return 1;
00372 }
00373
00374 if (!fd) {
00375 if ((rand_f = fopen("/dev/urandom", "r")) == NULL) {
00376
00377 if ((rand_f = fopen("/dev/random", "r")) == NULL) {
00378
00379
00380 for (read = 0; read < size; read++) {
00381 gettimeofday(&tv, NULL);
00382 seed[read] = (uint8_t) (tv.tv_usec % 256);
00383 }
00384 } else {
00385 read = fread(seed, 1, size, rand_f);
00386 }
00387 } else {
00388 read = fread(seed, 1, size, rand_f);
00389 }
00390 } else {
00391 rand_f = fd;
00392 read = fread(seed, 1, size, rand_f);
00393 }
00394
00395 if (read < size) {
00396 LDNS_FREE(seed);
00397 return 1;
00398 } else {
00399 #ifdef HAVE_SSL
00400
00401
00402 RAND_seed(seed, (int) size);
00403 #else
00404
00405
00406
00407 memcpy(&seed_i, seed, sizeof(seed_i));
00408 srandom(seed_i);
00409 #endif
00410 LDNS_FREE(seed);
00411 }
00412
00413 if (!fd) {
00414 if (rand_f) fclose(rand_f);
00415 }
00416
00417 return 0;
00418 }
00419
00424 uint16_t
00425 ldns_get_random(void)
00426 {
00427 uint16_t rid = 0;
00428 #ifdef HAVE_SSL
00429 if (RAND_bytes((unsigned char*)&rid, 2) != 1) {
00430 rid = (uint16_t) random();
00431 }
00432 #else
00433 rid = (uint16_t) random();
00434 #endif
00435 return rid;
00436 }
00437
00438
00439
00440
00441
00442 char *
00443 ldns_bubblebabble(uint8_t *data, size_t len)
00444 {
00445 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
00446 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
00447 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
00448 size_t i, j = 0, rounds, seed = 1;
00449 char *retval;
00450
00451 rounds = (len / 2) + 1;
00452 retval = LDNS_XMALLOC(char, rounds * 6);
00453 if(!retval) return NULL;
00454 retval[j++] = 'x';
00455 for (i = 0; i < rounds; i++) {
00456 size_t idx0, idx1, idx2, idx3, idx4;
00457 if ((i + 1 < rounds) || (len % 2 != 0)) {
00458 idx0 = (((((size_t)(data[2 * i])) >> 6) & 3) +
00459 seed) % 6;
00460 idx1 = (((size_t)(data[2 * i])) >> 2) & 15;
00461 idx2 = ((((size_t)(data[2 * i])) & 3) +
00462 (seed / 6)) % 6;
00463 retval[j++] = vowels[idx0];
00464 retval[j++] = consonants[idx1];
00465 retval[j++] = vowels[idx2];
00466 if ((i + 1) < rounds) {
00467 idx3 = (((size_t)(data[(2 * i) + 1])) >> 4) & 15;
00468 idx4 = (((size_t)(data[(2 * i) + 1]))) & 15;
00469 retval[j++] = consonants[idx3];
00470 retval[j++] = '-';
00471 retval[j++] = consonants[idx4];
00472 seed = ((seed * 5) +
00473 ((((size_t)(data[2 * i])) * 7) +
00474 ((size_t)(data[(2 * i) + 1])))) % 36;
00475 }
00476 } else {
00477 idx0 = seed % 6;
00478 idx1 = 16;
00479 idx2 = seed / 6;
00480 retval[j++] = vowels[idx0];
00481 retval[j++] = consonants[idx1];
00482 retval[j++] = vowels[idx2];
00483 }
00484 }
00485 retval[j++] = 'x';
00486 retval[j++] = '\0';
00487 return retval;
00488 }