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