1 /* 2 * util.c -- set of various support routines. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #include "config.h" 11 12 #include <assert.h> 13 #include <ctype.h> 14 #include <errno.h> 15 #include <stdarg.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 #ifdef HAVE_SYSLOG_H 20 #include <syslog.h> 21 #endif /* HAVE_SYSLOG_H */ 22 #include <unistd.h> 23 24 #include "util.h" 25 #include "region-allocator.h" 26 #include "dname.h" 27 #include "namedb.h" 28 #include "rdata.h" 29 #include "zonec.h" 30 31 #ifdef USE_MMAP_ALLOC 32 #include <sys/mman.h> 33 34 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) 35 #define MAP_ANONYMOUS MAP_ANON 36 #elif defined(MAP_ANONYMOUS) && !defined(MAP_ANON) 37 #define MAP_ANON MAP_ANONYMOUS 38 #endif 39 40 #endif /* USE_MMAP_ALLOC */ 41 42 #ifndef NDEBUG 43 unsigned nsd_debug_facilities = 0xffff; 44 int nsd_debug_level = 0; 45 #endif 46 47 #define MSB_32 0x80000000 48 49 int verbosity = 0; 50 51 static const char *global_ident = NULL; 52 static log_function_type *current_log_function = log_file; 53 static FILE *current_log_file = NULL; 54 int log_time_asc = 1; 55 56 void 57 log_init(const char *ident) 58 { 59 global_ident = ident; 60 current_log_file = stderr; 61 } 62 63 void 64 log_open(int option, int facility, const char *filename) 65 { 66 #ifdef HAVE_SYSLOG_H 67 openlog(global_ident, option, facility); 68 #endif /* HAVE_SYSLOG_H */ 69 if (filename) { 70 FILE *file = fopen(filename, "a"); 71 if (!file) { 72 log_msg(LOG_ERR, "Cannot open %s for appending (%s), " 73 "logging to stderr", 74 filename, strerror(errno)); 75 } else { 76 current_log_file = file; 77 } 78 } 79 } 80 81 void 82 log_reopen(const char *filename, uint8_t verbose) 83 { 84 if (filename) { 85 FILE *file; 86 if(strcmp(filename, "/dev/stdout")==0 || strcmp(filename, "/dev/stderr")==0) 87 return; 88 file = fopen(filename, "a"); 89 if (!file) { 90 if (verbose) 91 VERBOSITY(2, (LOG_WARNING, 92 "Cannot reopen %s for appending (%s), " 93 "keeping old logfile", 94 filename, strerror(errno))); 95 } else { 96 if (current_log_file && current_log_file != stderr) 97 fclose(current_log_file); 98 current_log_file = file; 99 } 100 } 101 } 102 103 void 104 log_finalize(void) 105 { 106 #ifdef HAVE_SYSLOG_H 107 closelog(); 108 #endif /* HAVE_SYSLOG_H */ 109 if (current_log_file && current_log_file != stderr) { 110 fclose(current_log_file); 111 } 112 current_log_file = NULL; 113 } 114 115 static lookup_table_type log_priority_table[] = { 116 { LOG_ERR, "error" }, 117 { LOG_WARNING, "warning" }, 118 { LOG_NOTICE, "notice" }, 119 { LOG_INFO, "info" }, 120 { 0, NULL } 121 }; 122 123 void 124 log_file(int priority, const char *message) 125 { 126 size_t length; 127 lookup_table_type *priority_info; 128 const char *priority_text = "unknown"; 129 130 assert(global_ident); 131 assert(current_log_file); 132 133 priority_info = lookup_by_id(log_priority_table, priority); 134 if (priority_info) { 135 priority_text = priority_info->name; 136 } 137 138 /* Bug #104, add time_t timestamp */ 139 #if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R) 140 if(log_time_asc) { 141 struct timeval tv; 142 char tmbuf[32]; 143 tmbuf[0]=0; 144 tv.tv_usec = 0; 145 if(gettimeofday(&tv, NULL) == 0) { 146 struct tm tm; 147 time_t now = (time_t)tv.tv_sec; 148 strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", 149 localtime_r(&now, &tm)); 150 } 151 fprintf(current_log_file, "[%s.%3.3d] %s[%d]: %s: %s", 152 tmbuf, (int)tv.tv_usec/1000, 153 global_ident, (int) getpid(), priority_text, message); 154 } else 155 #endif /* have time functions */ 156 fprintf(current_log_file, "[%d] %s[%d]: %s: %s", 157 (int)time(NULL), global_ident, (int) getpid(), priority_text, message); 158 length = strlen(message); 159 if (length == 0 || message[length - 1] != '\n') { 160 fprintf(current_log_file, "\n"); 161 } 162 fflush(current_log_file); 163 } 164 165 void 166 log_syslog(int priority, const char *message) 167 { 168 #ifdef HAVE_SYSLOG_H 169 syslog(priority, "%s", message); 170 #endif /* !HAVE_SYSLOG_H */ 171 log_file(priority, message); 172 } 173 174 void 175 log_set_log_function(log_function_type *log_function) 176 { 177 current_log_function = log_function; 178 } 179 180 void 181 log_msg(int priority, const char *format, ...) 182 { 183 va_list args; 184 va_start(args, format); 185 log_vmsg(priority, format, args); 186 va_end(args); 187 } 188 189 void 190 log_vmsg(int priority, const char *format, va_list args) 191 { 192 char message[MAXSYSLOGMSGLEN]; 193 vsnprintf(message, sizeof(message), format, args); 194 current_log_function(priority, message); 195 } 196 197 void 198 set_bit(uint8_t bits[], size_t index) 199 { 200 /* 201 * The bits are counted from left to right, so bit #0 is the 202 * left most bit. 203 */ 204 bits[index / 8] |= (1 << (7 - index % 8)); 205 } 206 207 void 208 clear_bit(uint8_t bits[], size_t index) 209 { 210 /* 211 * The bits are counted from left to right, so bit #0 is the 212 * left most bit. 213 */ 214 bits[index / 8] &= ~(1 << (7 - index % 8)); 215 } 216 217 int 218 get_bit(uint8_t bits[], size_t index) 219 { 220 /* 221 * The bits are counted from left to right, so bit #0 is the 222 * left most bit. 223 */ 224 return bits[index / 8] & (1 << (7 - index % 8)); 225 } 226 227 lookup_table_type * 228 lookup_by_name(lookup_table_type *table, const char *name) 229 { 230 while (table->name != NULL) { 231 if (strcasecmp(name, table->name) == 0) 232 return table; 233 table++; 234 } 235 return NULL; 236 } 237 238 lookup_table_type * 239 lookup_by_id(lookup_table_type *table, int id) 240 { 241 while (table->name != NULL) { 242 if (table->id == id) 243 return table; 244 table++; 245 } 246 return NULL; 247 } 248 249 void * 250 xalloc(size_t size) 251 { 252 void *result = malloc(size); 253 254 if (!result) { 255 log_msg(LOG_ERR, "malloc failed: %s", strerror(errno)); 256 exit(1); 257 } 258 return result; 259 } 260 261 void * 262 xmallocarray(size_t num, size_t size) 263 { 264 void *result = reallocarray(NULL, num, size); 265 266 if (!result) { 267 log_msg(LOG_ERR, "reallocarray failed: %s", strerror(errno)); 268 exit(1); 269 } 270 return result; 271 } 272 273 void * 274 xalloc_zero(size_t size) 275 { 276 void *result = calloc(1, size); 277 if (!result) { 278 log_msg(LOG_ERR, "calloc failed: %s", strerror(errno)); 279 exit(1); 280 } 281 return result; 282 } 283 284 void * 285 xalloc_array_zero(size_t num, size_t size) 286 { 287 void *result = calloc(num, size); 288 if (!result) { 289 log_msg(LOG_ERR, "calloc failed: %s", strerror(errno)); 290 exit(1); 291 } 292 return result; 293 } 294 295 void * 296 xrealloc(void *ptr, size_t size) 297 { 298 ptr = realloc(ptr, size); 299 if (!ptr) { 300 log_msg(LOG_ERR, "realloc failed: %s", strerror(errno)); 301 exit(1); 302 } 303 return ptr; 304 } 305 306 #ifdef USE_MMAP_ALLOC 307 308 void * 309 mmap_alloc(size_t size) 310 { 311 void *base; 312 313 size += MMAP_ALLOC_HEADER_SIZE; 314 #ifdef HAVE_MMAP 315 base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 316 if (base == MAP_FAILED) { 317 log_msg(LOG_ERR, "mmap failed: %s", strerror(errno)); 318 exit(1); 319 } 320 #else /* !HAVE_MMAP */ 321 log_msg(LOG_ERR, "mmap failed: don't have mmap"); 322 exit(1); 323 #endif /* HAVE_MMAP */ 324 325 *((size_t*) base) = size; 326 return (void*)((uintptr_t)base + MMAP_ALLOC_HEADER_SIZE); 327 } 328 329 330 void 331 mmap_free(void *ptr) 332 { 333 void *base; 334 size_t size; 335 336 if (!ptr) return; 337 338 base = (void*)((uintptr_t)ptr - MMAP_ALLOC_HEADER_SIZE); 339 size = *((size_t*) base); 340 341 #ifdef HAVE_MUNMAP 342 if (munmap(base, size) == -1) { 343 log_msg(LOG_ERR, "munmap failed: %s", strerror(errno)); 344 exit(1); 345 } 346 #else /* !HAVE_MUNMAP */ 347 log_msg(LOG_ERR, "munmap failed: don't have munmap"); 348 exit(1); 349 #endif /* HAVE_MUNMAP */ 350 } 351 352 #endif /* USE_MMAP_ALLOC */ 353 354 int 355 write_data(FILE *file, const void *data, size_t size) 356 { 357 size_t result; 358 359 if (size == 0) 360 return 1; 361 362 result = fwrite(data, 1, size, file); 363 364 if (result == 0) { 365 log_msg(LOG_ERR, "write failed: %s", strerror(errno)); 366 return 0; 367 } else if (result < size) { 368 log_msg(LOG_ERR, "short write (disk full?)"); 369 return 0; 370 } else { 371 return 1; 372 } 373 } 374 375 int 376 write_socket(int s, const void *buf, size_t size) 377 { 378 const char* data = (const char*)buf; 379 size_t total_count = 0; 380 381 while (total_count < size) { 382 ssize_t count 383 = write(s, data + total_count, size - total_count); 384 if (count == -1) { 385 if (errno != EAGAIN && errno != EINTR) { 386 return 0; 387 } else { 388 continue; 389 } 390 } 391 total_count += count; 392 } 393 return 1; 394 } 395 396 void get_time(struct timespec* t) 397 { 398 struct timeval tv; 399 #ifdef HAVE_CLOCK_GETTIME 400 /* first try nanosecond precision */ 401 if(clock_gettime(CLOCK_REALTIME, t)>=0) { 402 return; /* success */ 403 } 404 log_msg(LOG_ERR, "clock_gettime: %s", strerror(errno)); 405 #endif 406 /* try millisecond precision */ 407 if(gettimeofday(&tv, NULL)>=0) { 408 t->tv_sec = tv.tv_sec; 409 t->tv_nsec = tv.tv_usec*1000; 410 return; /* success */ 411 } 412 log_msg(LOG_ERR, "gettimeofday: %s", strerror(errno)); 413 /* whole seconds precision */ 414 t->tv_sec = time(0); 415 t->tv_nsec = 0; 416 } 417 418 int 419 timespec_compare(const struct timespec *left, 420 const struct timespec *right) 421 { 422 /* Compare seconds. */ 423 if (left->tv_sec < right->tv_sec) { 424 return -1; 425 } else if (left->tv_sec > right->tv_sec) { 426 return 1; 427 } else { 428 /* Seconds are equal, compare nanoseconds. */ 429 if (left->tv_nsec < right->tv_nsec) { 430 return -1; 431 } else if (left->tv_nsec > right->tv_nsec) { 432 return 1; 433 } else { 434 return 0; 435 } 436 } 437 } 438 439 440 /* One second is 1e9 nanoseconds. */ 441 #define NANOSECONDS_PER_SECOND 1000000000L 442 443 void 444 timespec_add(struct timespec *left, 445 const struct timespec *right) 446 { 447 left->tv_sec += right->tv_sec; 448 left->tv_nsec += right->tv_nsec; 449 if (left->tv_nsec >= NANOSECONDS_PER_SECOND) { 450 /* Carry. */ 451 ++left->tv_sec; 452 left->tv_nsec -= NANOSECONDS_PER_SECOND; 453 } 454 } 455 456 void 457 timespec_subtract(struct timespec *left, 458 const struct timespec *right) 459 { 460 left->tv_sec -= right->tv_sec; 461 left->tv_nsec -= right->tv_nsec; 462 if (left->tv_nsec < 0L) { 463 /* Borrow. */ 464 --left->tv_sec; 465 left->tv_nsec += NANOSECONDS_PER_SECOND; 466 } 467 } 468 469 uint32_t 470 strtoserial(const char* nptr, const char** endptr) 471 { 472 uint32_t i = 0; 473 uint32_t serial = 0; 474 475 for(*endptr = nptr; **endptr; (*endptr)++) { 476 switch (**endptr) { 477 case ' ': 478 case '\t': 479 break; 480 case '0': 481 case '1': 482 case '2': 483 case '3': 484 case '4': 485 case '5': 486 case '6': 487 case '7': 488 case '8': 489 case '9': 490 i *= 10; 491 i += (**endptr - '0'); 492 break; 493 default: 494 break; 495 } 496 } 497 serial += i; 498 return serial; 499 } 500 501 uint32_t 502 strtottl(const char *nptr, const char **endptr) 503 { 504 uint32_t i = 0; 505 uint32_t seconds = 0; 506 507 for(*endptr = nptr; **endptr; (*endptr)++) { 508 switch (**endptr) { 509 case ' ': 510 case '\t': 511 break; 512 case 's': 513 case 'S': 514 seconds += i; 515 i = 0; 516 break; 517 case 'm': 518 case 'M': 519 seconds += i * 60; 520 i = 0; 521 break; 522 case 'h': 523 case 'H': 524 seconds += i * 60 * 60; 525 i = 0; 526 break; 527 case 'd': 528 case 'D': 529 seconds += i * 60 * 60 * 24; 530 i = 0; 531 break; 532 case 'w': 533 case 'W': 534 seconds += i * 60 * 60 * 24 * 7; 535 i = 0; 536 break; 537 case '0': 538 case '1': 539 case '2': 540 case '3': 541 case '4': 542 case '5': 543 case '6': 544 case '7': 545 case '8': 546 case '9': 547 i *= 10; 548 i += (**endptr - '0'); 549 break; 550 default: 551 seconds += i; 552 /** 553 * According to RFC2308, Section 8, the MSB 554 * (sign bit) should be set to zero. 555 * If we encounter a value larger than 2^31 -1, 556 * we fall back to the default TTL. 557 */ 558 if ((seconds & MSB_32)) { 559 seconds = DEFAULT_TTL; 560 } 561 return seconds; 562 } 563 } 564 seconds += i; 565 if ((seconds & MSB_32)) { 566 seconds = DEFAULT_TTL; 567 } 568 return seconds; 569 } 570 571 572 ssize_t 573 hex_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) 574 { 575 static char hexdigits[] = { 576 '0', '1', '2', '3', '4', '5', '6', '7', 577 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 578 }; 579 size_t i; 580 581 if (targsize < srclength * 2 + 1) { 582 return -1; 583 } 584 585 for (i = 0; i < srclength; ++i) { 586 *target++ = hexdigits[src[i] >> 4U]; 587 *target++ = hexdigits[src[i] & 0xfU]; 588 } 589 *target = '\0'; 590 return 2 * srclength; 591 } 592 593 ssize_t 594 hex_pton(const char* src, uint8_t* target, size_t targsize) 595 { 596 uint8_t *t = target; 597 if(strlen(src) % 2 != 0 || strlen(src)/2 > targsize) { 598 return -1; 599 } 600 while(*src) { 601 if(!isxdigit((unsigned char)src[0]) || 602 !isxdigit((unsigned char)src[1])) 603 return -1; 604 *t++ = hexdigit_to_int(src[0]) * 16 + 605 hexdigit_to_int(src[1]) ; 606 src += 2; 607 } 608 return t-target; 609 } 610 611 int 612 b32_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) 613 { 614 static char b32[]="0123456789abcdefghijklmnopqrstuv"; 615 char buf[9]; 616 ssize_t len=0; 617 618 while(srclength > 0) 619 { 620 int t; 621 memset(buf,'\0',sizeof buf); 622 623 /* xxxxx000 00000000 00000000 00000000 00000000 */ 624 buf[0]=b32[src[0] >> 3]; 625 626 /* 00000xxx xx000000 00000000 00000000 00000000 */ 627 t=(src[0]&7) << 2; 628 if(srclength > 1) 629 t+=src[1] >> 6; 630 buf[1]=b32[t]; 631 if(srclength == 1) 632 break; 633 634 /* 00000000 00xxxxx0 00000000 00000000 00000000 */ 635 buf[2]=b32[(src[1] >> 1)&0x1f]; 636 637 /* 00000000 0000000x xxxx0000 00000000 00000000 */ 638 t=(src[1]&1) << 4; 639 if(srclength > 2) 640 t+=src[2] >> 4; 641 buf[3]=b32[t]; 642 if(srclength == 2) 643 break; 644 645 /* 00000000 00000000 0000xxxx x0000000 00000000 */ 646 t=(src[2]&0xf) << 1; 647 if(srclength > 3) 648 t+=src[3] >> 7; 649 buf[4]=b32[t]; 650 if(srclength == 3) 651 break; 652 653 /* 00000000 00000000 00000000 0xxxxx00 00000000 */ 654 buf[5]=b32[(src[3] >> 2)&0x1f]; 655 656 /* 00000000 00000000 00000000 000000xx xxx00000 */ 657 t=(src[3]&3) << 3; 658 if(srclength > 4) 659 t+=src[4] >> 5; 660 buf[6]=b32[t]; 661 if(srclength == 4) 662 break; 663 664 /* 00000000 00000000 00000000 00000000 000xxxxx */ 665 buf[7]=b32[src[4]&0x1f]; 666 667 if(targsize < 8) 668 return -1; 669 670 src += 5; 671 srclength -= 5; 672 673 memcpy(target,buf,8); 674 target += 8; 675 targsize -= 8; 676 len += 8; 677 } 678 if(srclength) 679 { 680 if(targsize < strlen(buf)+1) 681 return -1; 682 strlcpy(target, buf, targsize); 683 len += strlen(buf); 684 } 685 else if(targsize < 1) 686 return -1; 687 else 688 *target='\0'; 689 return len; 690 } 691 692 int 693 b32_pton(const char *src, uint8_t *target, size_t tsize) 694 { 695 char ch; 696 size_t p=0; 697 698 memset(target,'\0',tsize); 699 while((ch = *src++)) { 700 uint8_t d; 701 size_t b; 702 size_t n; 703 704 if(p+5 >= tsize*8) 705 return -1; 706 707 if(isspace((unsigned char)ch)) 708 continue; 709 710 if(ch >= '0' && ch <= '9') 711 d=ch-'0'; 712 else if(ch >= 'A' && ch <= 'V') 713 d=ch-'A'+10; 714 else if(ch >= 'a' && ch <= 'v') 715 d=ch-'a'+10; 716 else 717 return -1; 718 719 b=7-p%8; 720 n=p/8; 721 722 if(b >= 4) 723 target[n]|=d << (b-4); 724 else { 725 target[n]|=d >> (4-b); 726 target[n+1]|=d << (b+4); 727 } 728 p+=5; 729 } 730 return (p+7)/8; 731 } 732 733 void 734 strip_string(char *str) 735 { 736 char *start = str; 737 char *end = str + strlen(str) - 1; 738 739 while (isspace((unsigned char)*start)) 740 ++start; 741 if (start > end) { 742 /* Completely blank. */ 743 str[0] = '\0'; 744 } else { 745 while (isspace((unsigned char)*end)) 746 --end; 747 *++end = '\0'; 748 749 if (str != start) 750 memmove(str, start, end - start + 1); 751 } 752 } 753 754 int 755 hexdigit_to_int(char ch) 756 { 757 switch (ch) { 758 case '0': return 0; 759 case '1': return 1; 760 case '2': return 2; 761 case '3': return 3; 762 case '4': return 4; 763 case '5': return 5; 764 case '6': return 6; 765 case '7': return 7; 766 case '8': return 8; 767 case '9': return 9; 768 case 'a': case 'A': return 10; 769 case 'b': case 'B': return 11; 770 case 'c': case 'C': return 12; 771 case 'd': case 'D': return 13; 772 case 'e': case 'E': return 14; 773 case 'f': case 'F': return 15; 774 default: 775 abort(); 776 } 777 } 778 779 /* Number of days per month (except for February in leap years). */ 780 static const int mdays[] = { 781 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 782 }; 783 784 static int 785 is_leap_year(int year) 786 { 787 return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); 788 } 789 790 static int 791 leap_days(int y1, int y2) 792 { 793 --y1; 794 --y2; 795 return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400); 796 } 797 798 /* 799 * Code adapted from Python 2.4.1 sources (Lib/calendar.py). 800 */ 801 time_t 802 mktime_from_utc(const struct tm *tm) 803 { 804 int year = 1900 + tm->tm_year; 805 time_t days = 365 * (year - 1970) + leap_days(1970, year); 806 time_t hours; 807 time_t minutes; 808 time_t seconds; 809 int i; 810 811 for (i = 0; i < tm->tm_mon; ++i) { 812 days += mdays[i]; 813 } 814 if (tm->tm_mon > 1 && is_leap_year(year)) { 815 ++days; 816 } 817 days += tm->tm_mday - 1; 818 819 hours = days * 24 + tm->tm_hour; 820 minutes = hours * 60 + tm->tm_min; 821 seconds = minutes * 60 + tm->tm_sec; 822 823 return seconds; 824 } 825 826 /* code to calculate CRC. Lifted from BSD 4.4 crc.c in cksum(1). BSD license. 827 http://www.tsfr.org/~orc/Code/bsd/bsd-current/cksum/crc.c. 828 or http://gobsd.com/code/freebsd/usr.bin/cksum/crc.c 829 The polynomial is 0x04c11db7L. */ 830 static u_long crctab[] = { 831 0x0, 832 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 833 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 834 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 835 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 836 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 837 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 838 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 839 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 840 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 841 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 842 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 843 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 844 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 845 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 846 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 847 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 848 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 849 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 850 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 851 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 852 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 853 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 854 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 855 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 856 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 857 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 858 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 859 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 860 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 861 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 862 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 863 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 864 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 865 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 866 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 867 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 868 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 869 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 870 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 871 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 872 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 873 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 874 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 875 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 876 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 877 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 878 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 879 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 880 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 881 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 882 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 883 }; 884 885 #define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)] 886 887 uint32_t 888 compute_crc(uint32_t crc, uint8_t* data, size_t len) 889 { 890 size_t i; 891 for(i=0; i<len; ++i) 892 COMPUTE(crc, data[i]); 893 return crc; 894 } 895 896 int 897 write_data_crc(FILE *file, const void *data, size_t size, uint32_t* crc) 898 { 899 int ret = write_data(file, data, size); 900 *crc = compute_crc(*crc, (uint8_t*)data, size); 901 return ret; 902 } 903 904 #define SERIAL_BITS 32 905 int 906 compare_serial(uint32_t a, uint32_t b) 907 { 908 const uint32_t cutoff = ((uint32_t) 1 << (SERIAL_BITS - 1)); 909 910 if (a == b) { 911 return 0; 912 } else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) { 913 return -1; 914 } else { 915 return 1; 916 } 917 } 918 919 uint16_t 920 qid_generate(void) 921 { 922 /* arc4random_uniform not needed because range is a power of 2 */ 923 #ifdef HAVE_ARC4RANDOM 924 return (uint16_t) arc4random(); 925 #else 926 return (uint16_t) random(); 927 #endif 928 } 929 930 int 931 random_generate(int max) 932 { 933 #ifdef HAVE_ARC4RANDOM_UNIFORM 934 return (int) arc4random_uniform(max); 935 #elif HAVE_ARC4RANDOM 936 return (int) (arc4random() % max); 937 #else 938 return (int) ((unsigned)random() % max); 939 #endif 940 } 941 942 void 943 cleanup_region(void *data) 944 { 945 region_type *region = (region_type *) data; 946 region_destroy(region); 947 } 948 949 struct state_pretty_rr* 950 create_pretty_rr(struct region* region) 951 { 952 struct state_pretty_rr* state = (struct state_pretty_rr*) 953 region_alloc(region, sizeof(struct state_pretty_rr)); 954 state->previous_owner_region = region_create(xalloc, free); 955 state->previous_owner = NULL; 956 state->previous_owner_origin = NULL; 957 region_add_cleanup(region, cleanup_region, 958 state->previous_owner_region); 959 return state; 960 } 961 962 static void 963 set_previous_owner(struct state_pretty_rr *state, const dname_type *dname) 964 { 965 region_free_all(state->previous_owner_region); 966 state->previous_owner = dname_copy(state->previous_owner_region, dname); 967 state->previous_owner_origin = dname_origin( 968 state->previous_owner_region, state->previous_owner); 969 } 970 971 int 972 print_rr(FILE *out, 973 struct state_pretty_rr *state, 974 rr_type *record, 975 region_type* rr_region, 976 buffer_type* output) 977 { 978 rrtype_descriptor_type *descriptor 979 = rrtype_descriptor_by_type(record->type); 980 int result; 981 const dname_type *owner = domain_dname(record->owner); 982 buffer_clear(output); 983 if (state) { 984 if (!state->previous_owner 985 || dname_compare(state->previous_owner, owner) != 0) { 986 const dname_type *owner_origin 987 = dname_origin(rr_region, owner); 988 int origin_changed = (!state->previous_owner_origin 989 || dname_compare(state->previous_owner_origin, 990 owner_origin) != 0); 991 if (origin_changed) { 992 buffer_printf(output, "$ORIGIN %s\n", 993 dname_to_string(owner_origin, NULL)); 994 } 995 996 set_previous_owner(state, owner); 997 buffer_printf(output, "%s", 998 dname_to_string(owner, 999 state->previous_owner_origin)); 1000 region_free_all(rr_region); 1001 } 1002 } else { 1003 buffer_printf(output, "%s", dname_to_string(owner, NULL)); 1004 } 1005 1006 buffer_printf(output, "\t%lu\t%s\t%s", 1007 (unsigned long) record->ttl, 1008 rrclass_to_string(record->klass), 1009 rrtype_to_string(record->type)); 1010 1011 result = print_rdata(output, descriptor, record); 1012 if (!result) { 1013 /* 1014 * Some RDATA failed to print, so print the record's 1015 * RDATA in unknown format. 1016 */ 1017 result = rdata_atoms_to_unknown_string(output, 1018 descriptor, record->rdata_count, record->rdatas); 1019 } 1020 1021 if (result) { 1022 buffer_printf(output, "\n"); 1023 buffer_flip(output); 1024 result = write_data(out, buffer_current(output), 1025 buffer_remaining(output)); 1026 } 1027 return result; 1028 } 1029 1030 const char* 1031 rcode2str(int rc) 1032 { 1033 switch(rc) { 1034 case RCODE_OK: 1035 return "NO ERROR"; 1036 case RCODE_FORMAT: 1037 return "FORMAT ERROR"; 1038 case RCODE_SERVFAIL: 1039 return "SERVFAIL"; 1040 case RCODE_NXDOMAIN: 1041 return "NAME ERROR"; 1042 case RCODE_IMPL: 1043 return "NOT IMPL"; 1044 case RCODE_REFUSE: 1045 return "REFUSED"; 1046 case RCODE_YXDOMAIN: 1047 return "YXDOMAIN"; 1048 case RCODE_YXRRSET: 1049 return "YXRRSET"; 1050 case RCODE_NXRRSET: 1051 return "NXRRSET"; 1052 case RCODE_NOTAUTH: 1053 return "SERVER NOT AUTHORITATIVE FOR ZONE"; 1054 case RCODE_NOTZONE: 1055 /* Name not contained in zone */ 1056 return "NOTZONE"; 1057 default: 1058 return "UNKNOWN ERROR"; 1059 } 1060 return NULL; /* ENOREACH */ 1061 } 1062 1063 void 1064 addr2str( 1065 #ifdef INET6 1066 struct sockaddr_storage *addr 1067 #else 1068 struct sockaddr_in *addr 1069 #endif 1070 , char* str, size_t len) 1071 { 1072 #ifdef INET6 1073 if (addr->ss_family == AF_INET6) { 1074 if (!inet_ntop(AF_INET6, 1075 &((struct sockaddr_in6 *)addr)->sin6_addr, str, len)) 1076 strlcpy(str, "[unknown ip6, inet_ntop failed]", len); 1077 return; 1078 } 1079 #endif 1080 if (!inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, 1081 str, len)) 1082 strlcpy(str, "[unknown ip4, inet_ntop failed]", len); 1083 } 1084