xref: /openbsd-src/usr.sbin/nsd/util.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
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