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 if((i*10)/10 != i) 491 /* number too large, return i 492 * with *endptr != 0 as a failure*/ 493 return i; 494 i *= 10; 495 i += (**endptr - '0'); 496 break; 497 default: 498 break; 499 } 500 } 501 serial += i; 502 return serial; 503 } 504 505 uint32_t 506 strtottl(const char *nptr, const char **endptr) 507 { 508 uint32_t i = 0; 509 uint32_t seconds = 0; 510 511 for(*endptr = nptr; **endptr; (*endptr)++) { 512 switch (**endptr) { 513 case ' ': 514 case '\t': 515 break; 516 case 's': 517 case 'S': 518 seconds += i; 519 i = 0; 520 break; 521 case 'm': 522 case 'M': 523 seconds += i * 60; 524 i = 0; 525 break; 526 case 'h': 527 case 'H': 528 seconds += i * 60 * 60; 529 i = 0; 530 break; 531 case 'd': 532 case 'D': 533 seconds += i * 60 * 60 * 24; 534 i = 0; 535 break; 536 case 'w': 537 case 'W': 538 seconds += i * 60 * 60 * 24 * 7; 539 i = 0; 540 break; 541 case '0': 542 case '1': 543 case '2': 544 case '3': 545 case '4': 546 case '5': 547 case '6': 548 case '7': 549 case '8': 550 case '9': 551 i *= 10; 552 i += (**endptr - '0'); 553 break; 554 default: 555 seconds += i; 556 /** 557 * According to RFC2308, Section 8, the MSB 558 * (sign bit) should be set to zero. 559 * If we encounter a value larger than 2^31 -1, 560 * we fall back to the default TTL. 561 */ 562 if ((seconds & MSB_32)) { 563 seconds = DEFAULT_TTL; 564 } 565 return seconds; 566 } 567 } 568 seconds += i; 569 if ((seconds & MSB_32)) { 570 seconds = DEFAULT_TTL; 571 } 572 return seconds; 573 } 574 575 576 ssize_t 577 hex_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) 578 { 579 static char hexdigits[] = { 580 '0', '1', '2', '3', '4', '5', '6', '7', 581 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 582 }; 583 size_t i; 584 585 if (targsize < srclength * 2 + 1) { 586 return -1; 587 } 588 589 for (i = 0; i < srclength; ++i) { 590 *target++ = hexdigits[src[i] >> 4U]; 591 *target++ = hexdigits[src[i] & 0xfU]; 592 } 593 *target = '\0'; 594 return 2 * srclength; 595 } 596 597 ssize_t 598 hex_pton(const char* src, uint8_t* target, size_t targsize) 599 { 600 uint8_t *t = target; 601 if(strlen(src) % 2 != 0 || strlen(src)/2 > targsize) { 602 return -1; 603 } 604 while(*src) { 605 if(!isxdigit((unsigned char)src[0]) || 606 !isxdigit((unsigned char)src[1])) 607 return -1; 608 *t++ = hexdigit_to_int(src[0]) * 16 + 609 hexdigit_to_int(src[1]) ; 610 src += 2; 611 } 612 return t-target; 613 } 614 615 int 616 b32_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) 617 { 618 static char b32[]="0123456789abcdefghijklmnopqrstuv"; 619 char buf[9]; 620 ssize_t len=0; 621 622 while(srclength > 0) 623 { 624 int t; 625 memset(buf,'\0',sizeof buf); 626 627 /* xxxxx000 00000000 00000000 00000000 00000000 */ 628 buf[0]=b32[src[0] >> 3]; 629 630 /* 00000xxx xx000000 00000000 00000000 00000000 */ 631 t=(src[0]&7) << 2; 632 if(srclength > 1) 633 t+=src[1] >> 6; 634 buf[1]=b32[t]; 635 if(srclength == 1) 636 break; 637 638 /* 00000000 00xxxxx0 00000000 00000000 00000000 */ 639 buf[2]=b32[(src[1] >> 1)&0x1f]; 640 641 /* 00000000 0000000x xxxx0000 00000000 00000000 */ 642 t=(src[1]&1) << 4; 643 if(srclength > 2) 644 t+=src[2] >> 4; 645 buf[3]=b32[t]; 646 if(srclength == 2) 647 break; 648 649 /* 00000000 00000000 0000xxxx x0000000 00000000 */ 650 t=(src[2]&0xf) << 1; 651 if(srclength > 3) 652 t+=src[3] >> 7; 653 buf[4]=b32[t]; 654 if(srclength == 3) 655 break; 656 657 /* 00000000 00000000 00000000 0xxxxx00 00000000 */ 658 buf[5]=b32[(src[3] >> 2)&0x1f]; 659 660 /* 00000000 00000000 00000000 000000xx xxx00000 */ 661 t=(src[3]&3) << 3; 662 if(srclength > 4) 663 t+=src[4] >> 5; 664 buf[6]=b32[t]; 665 if(srclength == 4) 666 break; 667 668 /* 00000000 00000000 00000000 00000000 000xxxxx */ 669 buf[7]=b32[src[4]&0x1f]; 670 671 if(targsize < 8) 672 return -1; 673 674 src += 5; 675 srclength -= 5; 676 677 memcpy(target,buf,8); 678 target += 8; 679 targsize -= 8; 680 len += 8; 681 } 682 if(srclength) 683 { 684 if(targsize < strlen(buf)+1) 685 return -1; 686 strlcpy(target, buf, targsize); 687 len += strlen(buf); 688 } 689 else if(targsize < 1) 690 return -1; 691 else 692 *target='\0'; 693 return len; 694 } 695 696 int 697 b32_pton(const char *src, uint8_t *target, size_t tsize) 698 { 699 char ch; 700 size_t p=0; 701 702 memset(target,'\0',tsize); 703 while((ch = *src++)) { 704 uint8_t d; 705 size_t b; 706 size_t n; 707 708 if(p+5 >= tsize*8) 709 return -1; 710 711 if(isspace((unsigned char)ch)) 712 continue; 713 714 if(ch >= '0' && ch <= '9') 715 d=ch-'0'; 716 else if(ch >= 'A' && ch <= 'V') 717 d=ch-'A'+10; 718 else if(ch >= 'a' && ch <= 'v') 719 d=ch-'a'+10; 720 else 721 return -1; 722 723 b=7-p%8; 724 n=p/8; 725 726 if(b >= 4) 727 target[n]|=d << (b-4); 728 else { 729 target[n]|=d >> (4-b); 730 target[n+1]|=d << (b+4); 731 } 732 p+=5; 733 } 734 return (p+7)/8; 735 } 736 737 void 738 strip_string(char *str) 739 { 740 char *start = str; 741 char *end = str + strlen(str) - 1; 742 743 while (isspace((unsigned char)*start)) 744 ++start; 745 if (start > end) { 746 /* Completely blank. */ 747 str[0] = '\0'; 748 } else { 749 while (isspace((unsigned char)*end)) 750 --end; 751 *++end = '\0'; 752 753 if (str != start) 754 memmove(str, start, end - start + 1); 755 } 756 } 757 758 int 759 hexdigit_to_int(char ch) 760 { 761 switch (ch) { 762 case '0': return 0; 763 case '1': return 1; 764 case '2': return 2; 765 case '3': return 3; 766 case '4': return 4; 767 case '5': return 5; 768 case '6': return 6; 769 case '7': return 7; 770 case '8': return 8; 771 case '9': return 9; 772 case 'a': case 'A': return 10; 773 case 'b': case 'B': return 11; 774 case 'c': case 'C': return 12; 775 case 'd': case 'D': return 13; 776 case 'e': case 'E': return 14; 777 case 'f': case 'F': return 15; 778 default: 779 abort(); 780 } 781 } 782 783 /* Number of days per month (except for February in leap years). */ 784 static const int mdays[] = { 785 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 786 }; 787 788 static int 789 is_leap_year(int year) 790 { 791 return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); 792 } 793 794 static int 795 leap_days(int y1, int y2) 796 { 797 --y1; 798 --y2; 799 return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400); 800 } 801 802 /* 803 * Code adapted from Python 2.4.1 sources (Lib/calendar.py). 804 */ 805 time_t 806 mktime_from_utc(const struct tm *tm) 807 { 808 int year = 1900 + tm->tm_year; 809 time_t days = 365 * (year - 1970) + leap_days(1970, year); 810 time_t hours; 811 time_t minutes; 812 time_t seconds; 813 int i; 814 815 for (i = 0; i < tm->tm_mon; ++i) { 816 days += mdays[i]; 817 } 818 if (tm->tm_mon > 1 && is_leap_year(year)) { 819 ++days; 820 } 821 days += tm->tm_mday - 1; 822 823 hours = days * 24 + tm->tm_hour; 824 minutes = hours * 60 + tm->tm_min; 825 seconds = minutes * 60 + tm->tm_sec; 826 827 return seconds; 828 } 829 830 /* code to calculate CRC. Lifted from BSD 4.4 crc.c in cksum(1). BSD license. 831 http://www.tsfr.org/~orc/Code/bsd/bsd-current/cksum/crc.c. 832 or http://gobsd.com/code/freebsd/usr.bin/cksum/crc.c 833 The polynomial is 0x04c11db7L. */ 834 static u_long crctab[] = { 835 0x0, 836 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 837 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 838 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 839 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 840 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 841 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 842 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 843 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 844 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 845 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 846 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 847 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 848 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 849 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 850 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 851 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 852 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 853 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 854 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 855 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 856 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 857 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 858 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 859 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 860 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 861 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 862 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 863 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 864 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 865 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 866 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 867 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 868 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 869 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 870 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 871 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 872 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 873 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 874 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 875 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 876 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 877 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 878 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 879 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 880 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 881 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 882 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 883 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 884 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 885 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 886 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 887 }; 888 889 #define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)] 890 891 uint32_t 892 compute_crc(uint32_t crc, uint8_t* data, size_t len) 893 { 894 size_t i; 895 for(i=0; i<len; ++i) 896 COMPUTE(crc, data[i]); 897 return crc; 898 } 899 900 int 901 write_data_crc(FILE *file, const void *data, size_t size, uint32_t* crc) 902 { 903 int ret = write_data(file, data, size); 904 *crc = compute_crc(*crc, (uint8_t*)data, size); 905 return ret; 906 } 907 908 #define SERIAL_BITS 32 909 int 910 compare_serial(uint32_t a, uint32_t b) 911 { 912 const uint32_t cutoff = ((uint32_t) 1 << (SERIAL_BITS - 1)); 913 914 if (a == b) { 915 return 0; 916 } else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) { 917 return -1; 918 } else { 919 return 1; 920 } 921 } 922 923 uint16_t 924 qid_generate(void) 925 { 926 /* arc4random_uniform not needed because range is a power of 2 */ 927 #ifdef HAVE_ARC4RANDOM 928 return (uint16_t) arc4random(); 929 #else 930 return (uint16_t) random(); 931 #endif 932 } 933 934 int 935 random_generate(int max) 936 { 937 #ifdef HAVE_ARC4RANDOM_UNIFORM 938 return (int) arc4random_uniform(max); 939 #elif HAVE_ARC4RANDOM 940 return (int) (arc4random() % max); 941 #else 942 return (int) ((unsigned)random() % max); 943 #endif 944 } 945 946 void 947 cleanup_region(void *data) 948 { 949 region_type *region = (region_type *) data; 950 region_destroy(region); 951 } 952 953 struct state_pretty_rr* 954 create_pretty_rr(struct region* region) 955 { 956 struct state_pretty_rr* state = (struct state_pretty_rr*) 957 region_alloc(region, sizeof(struct state_pretty_rr)); 958 state->previous_owner_region = region_create(xalloc, free); 959 state->previous_owner = NULL; 960 state->previous_owner_origin = NULL; 961 region_add_cleanup(region, cleanup_region, 962 state->previous_owner_region); 963 return state; 964 } 965 966 static void 967 set_previous_owner(struct state_pretty_rr *state, const dname_type *dname) 968 { 969 region_free_all(state->previous_owner_region); 970 state->previous_owner = dname_copy(state->previous_owner_region, dname); 971 state->previous_owner_origin = dname_origin( 972 state->previous_owner_region, state->previous_owner); 973 } 974 975 int 976 print_rr(FILE *out, 977 struct state_pretty_rr *state, 978 rr_type *record, 979 region_type* rr_region, 980 buffer_type* output) 981 { 982 rrtype_descriptor_type *descriptor 983 = rrtype_descriptor_by_type(record->type); 984 int result; 985 const dname_type *owner = domain_dname(record->owner); 986 buffer_clear(output); 987 if (state) { 988 if (!state->previous_owner 989 || dname_compare(state->previous_owner, owner) != 0) { 990 const dname_type *owner_origin 991 = dname_origin(rr_region, owner); 992 int origin_changed = (!state->previous_owner_origin 993 || dname_compare(state->previous_owner_origin, 994 owner_origin) != 0); 995 if (origin_changed) { 996 buffer_printf(output, "$ORIGIN %s\n", 997 dname_to_string(owner_origin, NULL)); 998 } 999 1000 set_previous_owner(state, owner); 1001 buffer_printf(output, "%s", 1002 dname_to_string(owner, 1003 state->previous_owner_origin)); 1004 region_free_all(rr_region); 1005 } 1006 } else { 1007 buffer_printf(output, "%s", dname_to_string(owner, NULL)); 1008 } 1009 1010 buffer_printf(output, "\t%lu\t%s\t%s", 1011 (unsigned long) record->ttl, 1012 rrclass_to_string(record->klass), 1013 rrtype_to_string(record->type)); 1014 1015 result = print_rdata(output, descriptor, record); 1016 if (!result) { 1017 /* 1018 * Some RDATA failed to print, so print the record's 1019 * RDATA in unknown format. 1020 */ 1021 result = rdata_atoms_to_unknown_string(output, 1022 descriptor, record->rdata_count, record->rdatas); 1023 } 1024 1025 if (result) { 1026 buffer_printf(output, "\n"); 1027 buffer_flip(output); 1028 result = write_data(out, buffer_current(output), 1029 buffer_remaining(output)); 1030 } 1031 return result; 1032 } 1033 1034 const char* 1035 rcode2str(int rc) 1036 { 1037 switch(rc) { 1038 case RCODE_OK: 1039 return "NO ERROR"; 1040 case RCODE_FORMAT: 1041 return "FORMAT ERROR"; 1042 case RCODE_SERVFAIL: 1043 return "SERVFAIL"; 1044 case RCODE_NXDOMAIN: 1045 return "NAME ERROR"; 1046 case RCODE_IMPL: 1047 return "NOT IMPL"; 1048 case RCODE_REFUSE: 1049 return "REFUSED"; 1050 case RCODE_YXDOMAIN: 1051 return "YXDOMAIN"; 1052 case RCODE_YXRRSET: 1053 return "YXRRSET"; 1054 case RCODE_NXRRSET: 1055 return "NXRRSET"; 1056 case RCODE_NOTAUTH: 1057 return "SERVER NOT AUTHORITATIVE FOR ZONE"; 1058 case RCODE_NOTZONE: 1059 /* Name not contained in zone */ 1060 return "NOTZONE"; 1061 default: 1062 return "UNKNOWN ERROR"; 1063 } 1064 return NULL; /* ENOREACH */ 1065 } 1066 1067 void 1068 addr2str( 1069 #ifdef INET6 1070 struct sockaddr_storage *addr 1071 #else 1072 struct sockaddr_in *addr 1073 #endif 1074 , char* str, size_t len) 1075 { 1076 #ifdef INET6 1077 if (addr->ss_family == AF_INET6) { 1078 if (!inet_ntop(AF_INET6, 1079 &((struct sockaddr_in6 *)addr)->sin6_addr, str, len)) 1080 strlcpy(str, "[unknown ip6, inet_ntop failed]", len); 1081 return; 1082 } 1083 #endif 1084 if (!inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, 1085 str, len)) 1086 strlcpy(str, "[unknown ip4, inet_ntop failed]", len); 1087 } 1088 1089 void 1090 addrport2str( 1091 #ifdef INET6 1092 struct sockaddr_storage *addr 1093 #else 1094 struct sockaddr_in *addr 1095 #endif 1096 , char* str, size_t len) 1097 { 1098 char ip[256]; 1099 #ifdef INET6 1100 if (addr->ss_family == AF_INET6) { 1101 if (!inet_ntop(AF_INET6, 1102 &((struct sockaddr_in6 *)addr)->sin6_addr, ip, sizeof(ip))) 1103 strlcpy(ip, "[unknown ip6, inet_ntop failed]", sizeof(ip)); 1104 /* append port number */ 1105 snprintf(str, len, "%s@%u", ip, 1106 (unsigned)ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); 1107 return; 1108 } else 1109 #endif 1110 if (!inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, 1111 ip, sizeof(ip))) 1112 strlcpy(ip, "[unknown ip4, inet_ntop failed]", sizeof(ip)); 1113 /* append port number */ 1114 snprintf(str, len, "%s@%u", ip, 1115 (unsigned)ntohs(((struct sockaddr_in *)addr)->sin_port)); 1116 } 1117 1118 void 1119 append_trailing_slash(const char** dirname, region_type* region) 1120 { 1121 int l = strlen(*dirname); 1122 if (l>0 && (*dirname)[l-1] != '/' && l < 0xffffff) { 1123 char *dirname_slash = region_alloc(region, l+2); 1124 memcpy(dirname_slash, *dirname, l+1); 1125 strlcat(dirname_slash, "/", l+2); 1126 /* old dirname is leaked, this is only used for chroot, once */ 1127 *dirname = dirname_slash; 1128 } 1129 } 1130 1131 int 1132 file_inside_chroot(const char* fname, const char* chr) 1133 { 1134 /* true if filename starts with chroot or is not absolute */ 1135 return ((fname && fname[0] && strncmp(fname, chr, strlen(chr)) == 0) || 1136 (fname && fname[0] != '/')); 1137 } 1138 1139 /* 1140 * Something went wrong, give error messages and exit. 1141 */ 1142 void 1143 error(const char *format, ...) 1144 { 1145 va_list args; 1146 va_start(args, format); 1147 log_vmsg(LOG_ERR, format, args); 1148 va_end(args); 1149 exit(1); 1150 } 1151 1152