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