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