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