xref: /openbsd-src/usr.sbin/nsd/zonec.c (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 /*
2  * zonec.c -- zone compiler.
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 <fcntl.h>
14 #include <ctype.h>
15 #include <errno.h>
16 #include <limits.h>
17 #include <stdio.h>
18 #include <string.h>
19 #ifdef HAVE_STRINGS_H
20 #include <strings.h>
21 #endif
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <time.h>
25 #ifdef HAVE_SYS_STAT_H
26 #include <sys/stat.h>
27 #endif
28 
29 #include <netinet/in.h>
30 
31 #ifdef HAVE_NETDB_H
32 #include <netdb.h>
33 #endif
34 
35 #include "zonec.h"
36 
37 #include "dname.h"
38 #include "dns.h"
39 #include "namedb.h"
40 #include "rdata.h"
41 #include "region-allocator.h"
42 #include "util.h"
43 #include "zparser.h"
44 #include "options.h"
45 #include "nsec3.h"
46 
47 #define ILNP_MAXDIGITS 4
48 #define ILNP_NUMGROUPS 4
49 
50 const dname_type *error_dname;
51 domain_type *error_domain;
52 
53 static time_t startzonec = 0;
54 static long int totalrrs = 0;
55 
56 extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE];
57 extern uint16_t nsec_highest_rcode;
58 
59 
60 /*
61  * Allocate SIZE+sizeof(uint16_t) bytes and store SIZE in the first
62  * element.  Return a pointer to the allocation.
63  */
64 static uint16_t *
65 alloc_rdata(region_type *region, size_t size)
66 {
67 	uint16_t *result = region_alloc(region, sizeof(uint16_t) + size);
68 	*result = size;
69 	return result;
70 }
71 
72 uint16_t *
73 alloc_rdata_init(region_type *region, const void *data, size_t size)
74 {
75 	uint16_t *result = region_alloc(region, sizeof(uint16_t) + size);
76 	*result = size;
77 	memcpy(result + 1, data, size);
78 	return result;
79 }
80 
81 /*
82  * These are parser function for generic zone file stuff.
83  */
84 uint16_t *
85 zparser_conv_hex(region_type *region, const char *hex, size_t len)
86 {
87 	/* convert a hex value to wireformat */
88 	uint16_t *r = NULL;
89 	uint8_t *t;
90 	int i;
91 
92 	if(len == 1 && hex[0] == '0') {
93 		/* single 0 represents empty buffer */
94 		return alloc_rdata(region, 0);
95 	}
96 	if (len % 2 != 0) {
97 		zc_error_prev_line("number of hex digits must be a multiple of 2");
98 	} else if (len > MAX_RDLENGTH * 2) {
99 		zc_error_prev_line("hex data exceeds maximum rdata length (%d)",
100 				   MAX_RDLENGTH);
101 	} else {
102 		/* the length part */
103 		r = alloc_rdata(region, len/2);
104 		t = (uint8_t *)(r + 1);
105 
106 		/* Now process octet by octet... */
107 		while (*hex) {
108 			*t = 0;
109 			for (i = 16; i >= 1; i -= 15) {
110 				if (isxdigit((unsigned char)*hex)) {
111 					*t += hexdigit_to_int(*hex) * i;
112 				} else {
113 					zc_error_prev_line(
114 						"illegal hex character '%c'",
115 						(int) *hex);
116 					return NULL;
117 				}
118 				++hex;
119 			}
120 			++t;
121 		}
122 	}
123 	return r;
124 }
125 
126 /* convert hex, precede by a 1-byte length */
127 uint16_t *
128 zparser_conv_hex_length(region_type *region, const char *hex, size_t len)
129 {
130 	uint16_t *r = NULL;
131 	uint8_t *t;
132 	int i;
133 	if (len % 2 != 0) {
134 		zc_error_prev_line("number of hex digits must be a multiple of 2");
135 	} else if (len > 255 * 2) {
136 		zc_error_prev_line("hex data exceeds 255 bytes");
137 	} else {
138 		uint8_t *l;
139 
140 		/* the length part */
141 		r = alloc_rdata(region, len/2+1);
142 		t = (uint8_t *)(r + 1);
143 
144 		l = t++;
145 		*l = '\0';
146 
147 		/* Now process octet by octet... */
148 		while (*hex) {
149 			*t = 0;
150 			for (i = 16; i >= 1; i -= 15) {
151 				if (isxdigit((unsigned char)*hex)) {
152 					*t += hexdigit_to_int(*hex) * i;
153 				} else {
154 					zc_error_prev_line(
155 						"illegal hex character '%c'",
156 						(int) *hex);
157 					return NULL;
158 				}
159 				++hex;
160 			}
161 			++t;
162 			++*l;
163 		}
164 	}
165 	return r;
166 }
167 
168 uint16_t *
169 zparser_conv_time(region_type *region, const char *time)
170 {
171 	/* convert a time YYHM to wireformat */
172 	uint16_t *r = NULL;
173 	struct tm tm;
174 
175 	/* Try to scan the time... */
176 	if (!strptime(time, "%Y%m%d%H%M%S", &tm)) {
177 		zc_error_prev_line("date and time is expected");
178 	} else {
179 		uint32_t l = htonl(mktime_from_utc(&tm));
180 		r = alloc_rdata_init(region, &l, sizeof(l));
181 	}
182 	return r;
183 }
184 
185 uint16_t *
186 zparser_conv_services(region_type *region, const char *protostr,
187 		      char *servicestr)
188 {
189 	/*
190 	 * Convert a protocol and a list of service port numbers
191 	 * (separated by spaces) in the rdata to wireformat
192 	 */
193 	uint16_t *r = NULL;
194 	uint8_t *p;
195 	uint8_t bitmap[65536/8];
196 	char sep[] = " ";
197 	char *word;
198 	int max_port = -8;
199 	/* convert a protocol in the rdata to wireformat */
200 	struct protoent *proto;
201 
202 	memset(bitmap, 0, sizeof(bitmap));
203 
204 	proto = getprotobyname(protostr);
205 	if (!proto) {
206 		proto = getprotobynumber(atoi(protostr));
207 	}
208 	if (!proto) {
209 		zc_error_prev_line("unknown protocol '%s'", protostr);
210 		return NULL;
211 	}
212 
213 	for (word = strtok(servicestr, sep); word; word = strtok(NULL, sep)) {
214 		struct servent *service;
215 		int port;
216 
217 		service = getservbyname(word, proto->p_name);
218 		if (service) {
219 			/* Note: ntohs not ntohl!  Strange but true.  */
220 			port = ntohs((uint16_t) service->s_port);
221 		} else {
222 			char *end;
223 			port = strtol(word, &end, 10);
224 			if (*end != '\0') {
225 				zc_error_prev_line("unknown service '%s' for protocol '%s'",
226 						   word, protostr);
227 				continue;
228 			}
229 		}
230 
231 		if (port < 0 || port > 65535) {
232 			zc_error_prev_line("bad port number %d", port);
233 		} else {
234 			set_bit(bitmap, port);
235 			if (port > max_port)
236 				max_port = port;
237 		}
238 	}
239 
240 	r = alloc_rdata(region, sizeof(uint8_t) + max_port / 8 + 1);
241 	p = (uint8_t *) (r + 1);
242 	*p = proto->p_proto;
243 	memcpy(p + 1, bitmap, *r-1);
244 
245 	return r;
246 }
247 
248 uint16_t *
249 zparser_conv_serial(region_type *region, const char *serialstr)
250 {
251 	uint16_t *r = NULL;
252 	uint32_t serial;
253 	const char *t;
254 
255 	serial = strtoserial(serialstr, &t);
256 	if (*t != '\0') {
257 		zc_error_prev_line("serial is expected or serial too big");
258 	} else {
259 		serial = htonl(serial);
260 		r = alloc_rdata_init(region, &serial, sizeof(serial));
261 	}
262 	return r;
263 }
264 
265 uint16_t *
266 zparser_conv_period(region_type *region, const char *periodstr)
267 {
268 	/* convert a time period (think TTL's) to wireformat) */
269 	uint16_t *r = NULL;
270 	uint32_t period;
271 	const char *end;
272 
273 	/* Allocate required space... */
274 	period = strtottl(periodstr, &end);
275 	if (*end != '\0') {
276 		zc_error_prev_line("time period is expected");
277 	} else {
278 		period = htonl(period);
279 		r = alloc_rdata_init(region, &period, sizeof(period));
280 	}
281 	return r;
282 }
283 
284 uint16_t *
285 zparser_conv_short(region_type *region, const char *text)
286 {
287 	uint16_t *r = NULL;
288 	uint16_t value;
289 	char *end;
290 
291 	value = htons((uint16_t) strtol(text, &end, 10));
292 	if (*end != '\0') {
293 		zc_error_prev_line("integer value is expected");
294 	} else {
295 		r = alloc_rdata_init(region, &value, sizeof(value));
296 	}
297 	return r;
298 }
299 
300 uint16_t *
301 zparser_conv_byte(region_type *region, const char *text)
302 {
303 	uint16_t *r = NULL;
304 	uint8_t value;
305 	char *end;
306 
307 	value = (uint8_t) strtol(text, &end, 10);
308 	if (*end != '\0') {
309 		zc_error_prev_line("integer value is expected");
310 	} else {
311 		r = alloc_rdata_init(region, &value, sizeof(value));
312 	}
313 	return r;
314 }
315 
316 uint16_t *
317 zparser_conv_algorithm(region_type *region, const char *text)
318 {
319 	const lookup_table_type *alg;
320 	uint8_t id;
321 
322 	alg = lookup_by_name(dns_algorithms, text);
323 	if (alg) {
324 		id = (uint8_t) alg->id;
325 	} else {
326 		char *end;
327 		id = (uint8_t) strtol(text, &end, 10);
328 		if (*end != '\0') {
329 			zc_error_prev_line("algorithm is expected");
330 			return NULL;
331 		}
332 	}
333 
334 	return alloc_rdata_init(region, &id, sizeof(id));
335 }
336 
337 uint16_t *
338 zparser_conv_certificate_type(region_type *region, const char *text)
339 {
340 	/* convert an algorithm string to integer */
341 	const lookup_table_type *type;
342 	uint16_t id;
343 
344 	type = lookup_by_name(dns_certificate_types, text);
345 	if (type) {
346 		id = htons((uint16_t) type->id);
347 	} else {
348 		char *end;
349 		id = htons((uint16_t) strtol(text, &end, 10));
350 		if (*end != '\0') {
351 			zc_error_prev_line("certificate type is expected");
352 			return NULL;
353 		}
354 	}
355 
356 	return alloc_rdata_init(region, &id, sizeof(id));
357 }
358 
359 uint16_t *
360 zparser_conv_a(region_type *region, const char *text)
361 {
362 	in_addr_t address;
363 	uint16_t *r = NULL;
364 
365 	if (inet_pton(AF_INET, text, &address) != 1) {
366 		zc_error_prev_line("invalid IPv4 address '%s'", text);
367 	} else {
368 		r = alloc_rdata_init(region, &address, sizeof(address));
369 	}
370 	return r;
371 }
372 
373 uint16_t *
374 zparser_conv_aaaa(region_type *region, const char *text)
375 {
376 	uint8_t address[IP6ADDRLEN];
377 	uint16_t *r = NULL;
378 
379 	if (inet_pton(AF_INET6, text, address) != 1) {
380 		zc_error_prev_line("invalid IPv6 address '%s'", text);
381 	} else {
382 		r = alloc_rdata_init(region, address, sizeof(address));
383 	}
384 	return r;
385 }
386 
387 
388 uint16_t *
389 zparser_conv_ilnp64(region_type *region, const char *text)
390 {
391 	uint16_t *r = NULL;
392 	int ngroups, num;
393 	unsigned long hex;
394 	const char *ch;
395 	char digits[ILNP_MAXDIGITS+1];
396 	unsigned int ui[ILNP_NUMGROUPS];
397 	uint16_t a[ILNP_NUMGROUPS];
398 
399 	ngroups = 1; /* Always at least one group */
400 	num = 0;
401 	for (ch = text; *ch != '\0'; ch++) {
402 		if (*ch == ':') {
403 			if (num <= 0) {
404 				zc_error_prev_line("ilnp64: empty group of "
405 					"digits is not allowed");
406 				return NULL;
407 			}
408 			digits[num] = '\0';
409 			hex = (unsigned long) strtol(digits, NULL, 16);
410 			num = 0;
411 			ui[ngroups - 1] = hex;
412 			if (ngroups >= ILNP_NUMGROUPS) {
413 				zc_error_prev_line("ilnp64: more than %d groups "
414 					"of digits", ILNP_NUMGROUPS);
415 				return NULL;
416 			}
417 			ngroups++;
418 		} else {
419 			/* Our grammar is stricter than the one accepted by
420 			 * strtol. */
421 			if (!isxdigit((unsigned char)*ch)) {
422 				zc_error_prev_line("ilnp64: invalid "
423 					"(non-hexadecimal) character %c", *ch);
424 				return NULL;
425 			}
426 			if (num >= ILNP_MAXDIGITS) {
427 				zc_error_prev_line("ilnp64: more than %d digits "
428 					"in a group", ILNP_MAXDIGITS);
429 				return NULL;
430 			}
431 			digits[num++] = *ch;
432 		}
433 	}
434 	if (num <= 0) {
435 		zc_error_prev_line("ilnp64: empty group of digits is not "
436 			"allowed");
437 		return NULL;
438 	}
439 	digits[num] = '\0';
440 	hex = (unsigned long) strtol(digits, NULL, 16);
441 	ui[ngroups - 1] = hex;
442 	if (ngroups < 4) {
443 		zc_error_prev_line("ilnp64: less than %d groups of digits",
444 			ILNP_NUMGROUPS);
445 		return NULL;
446 	}
447 
448 	a[0] = htons(ui[0]);
449 	a[1] = htons(ui[1]);
450 	a[2] = htons(ui[2]);
451 	a[3] = htons(ui[3]);
452 	r = alloc_rdata_init(region, a, sizeof(a));
453 	return r;
454 }
455 
456 static uint16_t *
457 zparser_conv_eui48(region_type *region, const char *text)
458 {
459 	uint8_t nums[6];
460 	uint16_t *r = NULL;
461 	unsigned int a, b, c, d, e, f;
462 	int l;
463 
464 	if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x%n",
465 		&a, &b, &c, &d, &e, &f, &l) != 6 ||
466 		l != (int)strlen(text)){
467 		zc_error_prev_line("eui48: invalid rr");
468 		return NULL;
469 	}
470 	nums[0] = (uint8_t)a;
471 	nums[1] = (uint8_t)b;
472 	nums[2] = (uint8_t)c;
473 	nums[3] = (uint8_t)d;
474 	nums[4] = (uint8_t)e;
475 	nums[5] = (uint8_t)f;
476 	r = alloc_rdata_init(region, nums, sizeof(nums));
477 	return r;
478 }
479 
480 static uint16_t *
481 zparser_conv_eui64(region_type *region, const char *text)
482 {
483 	uint8_t nums[8];
484 	uint16_t *r = NULL;
485 	unsigned int a, b, c, d, e, f, g, h;
486 	int l;
487 	if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n",
488 		&a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 ||
489 		l != (int)strlen(text)) {
490 		zc_error_prev_line("eui64: invalid rr");
491 		return NULL;
492 	}
493 	nums[0] = (uint8_t)a;
494 	nums[1] = (uint8_t)b;
495 	nums[2] = (uint8_t)c;
496 	nums[3] = (uint8_t)d;
497 	nums[4] = (uint8_t)e;
498 	nums[5] = (uint8_t)f;
499 	nums[6] = (uint8_t)g;
500 	nums[7] = (uint8_t)h;
501 	r = alloc_rdata_init(region, nums, sizeof(nums));
502 	return r;
503 }
504 
505 uint16_t *
506 zparser_conv_eui(region_type *region, const char *text, size_t len)
507 {
508 	uint16_t *r = NULL;
509 	int nnum, num;
510 	const char* ch;
511 
512 	nnum = len/8;
513 	num = 1;
514 	for (ch = text; *ch != '\0'; ch++) {
515 		if (*ch == '-') {
516 			num++;
517 		} else if (!isxdigit((unsigned char)*ch)) {
518 			zc_error_prev_line("eui%u: invalid (non-hexadecimal) "
519 				"character %c", (unsigned) len, *ch);
520 			return NULL;
521 		}
522 	}
523 	if (num != nnum) {
524 		zc_error_prev_line("eui%u: wrong number of hex numbers",
525 			(unsigned) len);
526 		return NULL;
527 	}
528 
529 	switch (len) {
530 		case 48:
531 			r = zparser_conv_eui48(region, text);
532 			break;
533 		case 64:
534 			r = zparser_conv_eui64(region, text);
535 		break;
536 		default:
537 			zc_error_prev_line("eui%u: invalid length",
538 				(unsigned) len);
539 			return NULL;
540 			break;
541 	}
542 	return r;
543 }
544 
545 uint16_t *
546 zparser_conv_text(region_type *region, const char *text, size_t len)
547 {
548 	uint16_t *r = NULL;
549 	uint8_t *p;
550 
551 	if (len > 255) {
552 		zc_error_prev_line("text string is longer than 255 characters,"
553 				   " try splitting it into multiple parts");
554 		len = 255;
555 	}
556 	r = alloc_rdata(region, len + 1);
557 	p = (uint8_t *) (r + 1);
558 	*p = len;
559 	memcpy(p + 1, text, len);
560 	return r;
561 }
562 
563 /* for CAA Value [RFC 6844] */
564 uint16_t *
565 zparser_conv_long_text(region_type *region, const char *text, size_t len)
566 {
567 	uint16_t *r = NULL;
568 	if (len > MAX_RDLENGTH) {
569 		zc_error_prev_line("text string is longer than max rdlen");
570 		return NULL;
571 	}
572 	r = alloc_rdata_init(region, text, len);
573 	return r;
574 }
575 
576 /* for CAA Tag [RFC 6844] */
577 uint16_t *
578 zparser_conv_tag(region_type *region, const char *text, size_t len)
579 {
580 	uint16_t *r = NULL;
581 	uint8_t *p;
582 	const char* ptr;
583 
584 	if (len < 1) {
585 		zc_error_prev_line("invalid tag: zero length");
586 		return NULL;
587 	}
588 	if (len > 15) {
589 		zc_error_prev_line("invalid tag %s: longer than 15 characters (%u)",
590 			text, (unsigned) len);
591 		return NULL;
592 	}
593 	for (ptr = text; *ptr; ptr++) {
594 		if (!isdigit((unsigned char)*ptr) && !islower((unsigned char)*ptr)) {
595 			zc_error_prev_line("invalid tag %s: contains invalid char %c",
596 				text, *ptr);
597 			return NULL;
598 		}
599 	}
600 	r = alloc_rdata(region, len + 1);
601 	p = (uint8_t *) (r + 1);
602 	*p = len;
603 	memmove(p + 1, text, len);
604 	return r;
605 }
606 
607 uint16_t *
608 zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len)
609 {
610 	uint16_t* r = NULL;
611 	uint8_t* p = NULL;
612 	r = alloc_rdata(region, len);
613 	p = (uint8_t *) (r + 1);
614 	memcpy(p, name, len);
615 
616 	return r;
617 }
618 
619 uint16_t *
620 zparser_conv_b32(region_type *region, const char *b32)
621 {
622 	uint8_t buffer[B64BUFSIZE];
623 	uint16_t *r = NULL;
624 	int i;
625 
626 	if(strcmp(b32, "-") == 0) {
627 		return alloc_rdata_init(region, "", 1);
628 	}
629 	i = b32_pton(b32, buffer+1, B64BUFSIZE-1);
630 	if (i == -1 || i > 255) {
631 		zc_error_prev_line("invalid base32 data");
632 	} else {
633 		buffer[0] = i; /* store length byte */
634 		r = alloc_rdata_init(region, buffer, i+1);
635 	}
636 	return r;
637 }
638 
639 uint16_t *
640 zparser_conv_b64(region_type *region, const char *b64)
641 {
642 	uint8_t buffer[B64BUFSIZE];
643 	uint16_t *r = NULL;
644 	int i;
645 
646 	if(strcmp(b64, "0") == 0) {
647 		/* single 0 represents empty buffer */
648 		return alloc_rdata(region, 0);
649 	}
650 	i = __b64_pton(b64, buffer, B64BUFSIZE);
651 	if (i == -1) {
652 		zc_error_prev_line("invalid base64 data");
653 	} else {
654 		r = alloc_rdata_init(region, buffer, i);
655 	}
656 	return r;
657 }
658 
659 uint16_t *
660 zparser_conv_rrtype(region_type *region, const char *text)
661 {
662 	uint16_t *r = NULL;
663 	uint16_t type = rrtype_from_string(text);
664 
665 	if (type == 0) {
666 		zc_error_prev_line("unrecognized RR type '%s'", text);
667 	} else {
668 		type = htons(type);
669 		r = alloc_rdata_init(region, &type, sizeof(type));
670 	}
671 	return r;
672 }
673 
674 uint16_t *
675 zparser_conv_nxt(region_type *region, uint8_t nxtbits[])
676 {
677 	/* nxtbits[] consists of 16 bytes with some zero's in it
678 	 * copy every byte with zero to r and write the length in
679 	 * the first byte
680 	 */
681 	uint16_t i;
682 	uint16_t last = 0;
683 
684 	for (i = 0; i < 16; i++) {
685 		if (nxtbits[i] != 0)
686 			last = i + 1;
687 	}
688 
689 	return alloc_rdata_init(region, nxtbits, last);
690 }
691 
692 
693 /* we potentially have 256 windows, each one is numbered. empty ones
694  * should be discarded
695  */
696 uint16_t *
697 zparser_conv_nsec(region_type *region,
698 		  uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE])
699 {
700 	/* nsecbits contains up to 64K of bits which represent the
701 	 * types available for a name. Walk the bits according to
702 	 * nsec++ draft from jakob
703 	 */
704 	uint16_t *r;
705 	uint8_t *ptr;
706 	size_t i,j;
707 	uint16_t window_count = 0;
708 	uint16_t total_size = 0;
709 	uint16_t window_max = 0;
710 
711 	/* The used windows.  */
712 	int used[NSEC_WINDOW_COUNT];
713 	/* The last byte used in each the window.  */
714 	int size[NSEC_WINDOW_COUNT];
715 
716 	window_max = 1 + (nsec_highest_rcode / 256);
717 
718 	/* used[i] is the i-th window included in the nsec
719 	 * size[used[0]] is the size of window 0
720 	 */
721 
722 	/* walk through the 256 windows */
723 	for (i = 0; i < window_max; ++i) {
724 		int empty_window = 1;
725 		/* check each of the 32 bytes */
726 		for (j = 0; j < NSEC_WINDOW_BITS_SIZE; ++j) {
727 			if (nsecbits[i][j] != 0) {
728 				size[i] = j + 1;
729 				empty_window = 0;
730 			}
731 		}
732 		if (!empty_window) {
733 			used[window_count] = i;
734 			window_count++;
735 		}
736 	}
737 
738 	for (i = 0; i < window_count; ++i) {
739 		total_size += sizeof(uint16_t) + size[used[i]];
740 	}
741 
742 	r = alloc_rdata(region, total_size);
743 	ptr = (uint8_t *) (r + 1);
744 
745 	/* now walk used and copy it */
746 	for (i = 0; i < window_count; ++i) {
747 		ptr[0] = used[i];
748 		ptr[1] = size[used[i]];
749 		memcpy(ptr + 2, &nsecbits[used[i]], size[used[i]]);
750 		ptr += size[used[i]] + 2;
751 	}
752 
753 	return r;
754 }
755 
756 /* Parse an int terminated in the specified range. */
757 static int
758 parse_int(const char *str,
759 	  char **end,
760 	  int *result,
761 	  const char *name,
762 	  int min,
763 	  int max)
764 {
765 	*result = (int) strtol(str, end, 10);
766 	if (*result < min || *result > max) {
767 		zc_error_prev_line("%s must be within the range [%d .. %d]",
768 				   name,
769 				   min,
770 				   max);
771 		return 0;
772 	} else {
773 		return 1;
774 	}
775 }
776 
777 /* RFC1876 conversion routines */
778 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
779 				1000000,10000000,100000000,1000000000};
780 
781 /*
782  * Converts ascii size/precision X * 10**Y(cm) to 0xXY.
783  * Sets the given pointer to the last used character.
784  *
785  */
786 static uint8_t
787 precsize_aton (char *cp, char **endptr)
788 {
789 	unsigned int mval = 0, cmval = 0;
790 	uint8_t retval = 0;
791 	int exponent;
792 	int mantissa;
793 
794 	while (isdigit((unsigned char)*cp))
795 		mval = mval * 10 + hexdigit_to_int(*cp++);
796 
797 	if (*cp == '.') {	/* centimeters */
798 		cp++;
799 		if (isdigit((unsigned char)*cp)) {
800 			cmval = hexdigit_to_int(*cp++) * 10;
801 			if (isdigit((unsigned char)*cp)) {
802 				cmval += hexdigit_to_int(*cp++);
803 			}
804 		}
805 	}
806 
807 	if(mval >= poweroften[7]) {
808 		assert(poweroften[7] != 0);
809 		/* integer overflow possible for *100 */
810 		mantissa = mval / poweroften[7];
811 		exponent = 9; /* max */
812 	}
813 	else {
814 		cmval = (mval * 100) + cmval;
815 
816 		for (exponent = 0; exponent < 9; exponent++)
817 			if (cmval < poweroften[exponent+1])
818 				break;
819 
820 		assert(poweroften[exponent] != 0);
821 		mantissa = cmval / poweroften[exponent];
822 	}
823 	if (mantissa > 9)
824 		mantissa = 9;
825 
826 	retval = (mantissa << 4) | exponent;
827 
828 	if (*cp == 'm') cp++;
829 
830 	*endptr = cp;
831 
832 	return (retval);
833 }
834 
835 /*
836  * Parses a specific part of rdata.
837  *
838  * Returns:
839  *
840  *	number of elements parsed
841  *	zero on error
842  *
843  */
844 uint16_t *
845 zparser_conv_loc(region_type *region, char *str)
846 {
847 	uint16_t *r;
848 	uint32_t *p;
849 	int i;
850 	int deg, min, secs;	/* Secs is stored times 1000.  */
851 	uint32_t lat = 0, lon = 0, alt = 0;
852 	/* encoded defaults: version=0 sz=1m hp=10000m vp=10m */
853 	uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13};
854 	char *start;
855 	double d;
856 
857 	for(;;) {
858 		deg = min = secs = 0;
859 
860 		/* Degrees */
861 		if (*str == '\0') {
862 			zc_error_prev_line("unexpected end of LOC data");
863 			return NULL;
864 		}
865 
866 		if (!parse_int(str, &str, &deg, "degrees", 0, 180))
867 			return NULL;
868 		if (!isspace((unsigned char)*str)) {
869 			zc_error_prev_line("space expected after degrees");
870 			return NULL;
871 		}
872 		++str;
873 
874 		/* Minutes? */
875 		if (isdigit((unsigned char)*str)) {
876 			if (!parse_int(str, &str, &min, "minutes", 0, 60))
877 				return NULL;
878 			if (!isspace((unsigned char)*str)) {
879 				zc_error_prev_line("space expected after minutes");
880 				return NULL;
881 			}
882 			++str;
883 		}
884 
885 		/* Seconds? */
886 		if (isdigit((unsigned char)*str)) {
887 			start = str;
888 			if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
889 				return NULL;
890 			}
891 
892 			if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) {
893 				return NULL;
894 			}
895 
896 			if (!isspace((unsigned char)*str)) {
897 				zc_error_prev_line("space expected after seconds");
898 				return NULL;
899 			}
900 			/* No need for precision specifiers, it's a double */
901 			if (sscanf(start, "%lf", &d) != 1) {
902 				zc_error_prev_line("error parsing seconds");
903 			}
904 
905 			if (d < 0.0 || d > 60.0) {
906 				zc_error_prev_line("seconds not in range 0.0 .. 60.0");
907 			}
908 
909 			secs = (int) (d * 1000.0 + 0.5);
910 			++str;
911 		}
912 
913 		switch(*str) {
914 		case 'N':
915 		case 'n':
916 			lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
917 			break;
918 		case 'E':
919 		case 'e':
920 			lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
921 			break;
922 		case 'S':
923 		case 's':
924 			lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
925 			break;
926 		case 'W':
927 		case 'w':
928 			lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
929 			break;
930 		default:
931 			zc_error_prev_line("invalid latitude/longtitude: '%c'", *str);
932 			return NULL;
933 		}
934 		++str;
935 
936 		if (lat != 0 && lon != 0)
937 			break;
938 
939 		if (!isspace((unsigned char)*str)) {
940 			zc_error_prev_line("space expected after latitude/longitude");
941 			return NULL;
942 		}
943 		++str;
944 	}
945 
946 	/* Altitude */
947 	if (*str == '\0') {
948 		zc_error_prev_line("unexpected end of LOC data");
949 		return NULL;
950 	}
951 
952 	if (!isspace((unsigned char)*str)) {
953 		zc_error_prev_line("space expected before altitude");
954 		return NULL;
955 	}
956 	++str;
957 
958 	start = str;
959 
960 	/* Sign */
961 	if (*str == '+' || *str == '-') {
962 		++str;
963 	}
964 
965 	/* Meters of altitude... */
966 	if(strtol(str, &str, 10) == LONG_MAX) {
967 		zc_error_prev_line("altitude too large, number overflow");
968 		return NULL;
969 	}
970 	switch(*str) {
971 	case ' ':
972 	case '\0':
973 	case 'm':
974 		break;
975 	case '.':
976 		if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) {
977 			return NULL;
978 		}
979 		if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') {
980 			zc_error_prev_line("altitude fraction must be a number");
981 			return NULL;
982 		}
983 		break;
984 	default:
985 		zc_error_prev_line("altitude must be expressed in meters");
986 		return NULL;
987 	}
988 	if (!isspace((unsigned char)*str) && *str != '\0')
989 		++str;
990 
991 	if (sscanf(start, "%lf", &d) != 1) {
992 		zc_error_prev_line("error parsing altitude");
993 	}
994 
995 	alt = (uint32_t) (10000000.0 + d * 100 + 0.5);
996 
997 	if (!isspace((unsigned char)*str) && *str != '\0') {
998 		zc_error_prev_line("unexpected character after altitude");
999 		return NULL;
1000 	}
1001 
1002 	/* Now parse size, horizontal precision and vertical precision if any */
1003 	for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) {
1004 		vszhpvp[i] = precsize_aton(str + 1, &str);
1005 
1006 		if (!isspace((unsigned char)*str) && *str != '\0') {
1007 			zc_error_prev_line("invalid size or precision");
1008 			return NULL;
1009 		}
1010 	}
1011 
1012 	/* Allocate required space... */
1013 	r = alloc_rdata(region, 16);
1014 	p = (uint32_t *) (r + 1);
1015 
1016 	memmove(p, vszhpvp, 4);
1017 	write_uint32(p + 1, lat);
1018 	write_uint32(p + 2, lon);
1019 	write_uint32(p + 3, alt);
1020 
1021 	return r;
1022 }
1023 
1024 /*
1025  * Convert an APL RR RDATA element.
1026  */
1027 uint16_t *
1028 zparser_conv_apl_rdata(region_type *region, char *str)
1029 {
1030 	int negated = 0;
1031 	uint16_t address_family;
1032 	uint8_t prefix;
1033 	uint8_t maximum_prefix;
1034 	uint8_t length;
1035 	uint8_t address[IP6ADDRLEN];
1036 	char *colon = strchr(str, ':');
1037 	char *slash = strchr(str, '/');
1038 	int af;
1039 	int rc;
1040 	uint16_t rdlength;
1041 	uint16_t *r;
1042 	uint8_t *t;
1043 	char *end;
1044 	long p;
1045 
1046 	if (!colon) {
1047 		zc_error("address family separator is missing");
1048 		return NULL;
1049 	}
1050 	if (!slash) {
1051 		zc_error("prefix separator is missing");
1052 		return NULL;
1053 	}
1054 
1055 	*colon = '\0';
1056 	*slash = '\0';
1057 
1058 	if (*str == '!') {
1059 		negated = 1;
1060 		++str;
1061 	}
1062 
1063 	if (strcmp(str, "1") == 0) {
1064 		address_family = htons(1);
1065 		af = AF_INET;
1066 		length = sizeof(in_addr_t);
1067 		maximum_prefix = length * 8;
1068 	} else if (strcmp(str, "2") == 0) {
1069 		address_family = htons(2);
1070 		af = AF_INET6;
1071 		length = IP6ADDRLEN;
1072 		maximum_prefix = length * 8;
1073 	} else {
1074 		zc_error("invalid address family '%s'", str);
1075 		return NULL;
1076 	}
1077 
1078 	rc = inet_pton(af, colon + 1, address);
1079 	if (rc == 0) {
1080 		zc_error("invalid address '%s'", colon + 1);
1081 		return NULL;
1082 	} else if (rc == -1) {
1083 		zc_error("inet_pton failed: %s", strerror(errno));
1084 		return NULL;
1085 	}
1086 
1087 	/* Strip trailing zero octets.	*/
1088 	while (length > 0 && address[length - 1] == 0)
1089 		--length;
1090 
1091 
1092 	p = strtol(slash + 1, &end, 10);
1093 	if (p < 0 || p > maximum_prefix) {
1094 		zc_error("prefix not in the range 0 .. %d", maximum_prefix);
1095 		return NULL;
1096 	} else if (*end != '\0') {
1097 		zc_error("invalid prefix '%s'", slash + 1);
1098 		return NULL;
1099 	}
1100 	prefix = (uint8_t) p;
1101 
1102 	rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length)
1103 		    + length);
1104 	r = alloc_rdata(region, rdlength);
1105 	t = (uint8_t *) (r + 1);
1106 
1107 	memcpy(t, &address_family, sizeof(address_family));
1108 	t += sizeof(address_family);
1109 	memcpy(t, &prefix, sizeof(prefix));
1110 	t += sizeof(prefix);
1111 	memcpy(t, &length, sizeof(length));
1112 	if (negated) {
1113 		*t |= APL_NEGATION_MASK;
1114 	}
1115 	t += sizeof(length);
1116 	memcpy(t, address, length);
1117 
1118 	return r;
1119 }
1120 
1121 /*
1122  * Below some function that also convert but not to wireformat
1123  * but to "normal" (int,long,char) types
1124  */
1125 
1126 uint32_t
1127 zparser_ttl2int(const char *ttlstr, int* error)
1128 {
1129 	/* convert a ttl value to a integer
1130 	 * return the ttl in a int
1131 	 * -1 on error
1132 	 */
1133 
1134 	uint32_t ttl;
1135 	const char *t;
1136 
1137 	ttl = strtottl(ttlstr, &t);
1138 	if (*t != 0) {
1139 		zc_error_prev_line("invalid TTL value: %s",ttlstr);
1140 		*error = 1;
1141 	}
1142 
1143 	return ttl;
1144 }
1145 
1146 
1147 void
1148 zadd_rdata_wireformat(uint16_t *data)
1149 {
1150 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1151 		zc_error_prev_line("too many rdata elements");
1152 	} else {
1153 		parser->current_rr.rdatas[parser->current_rr.rdata_count].data
1154 			= data;
1155 		++parser->current_rr.rdata_count;
1156 	}
1157 }
1158 
1159 /**
1160  * Used for TXT RR's to grow with undefined number of strings.
1161  */
1162 void
1163 zadd_rdata_txt_wireformat(uint16_t *data, int first)
1164 {
1165 	rdata_atom_type *rd;
1166 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1167 		zc_error_prev_line("too many rdata txt elements");
1168 		return;
1169 	}
1170 
1171 	/* First STR in str_seq, allocate 65K in first unused rdata
1172 	 * else find last used rdata */
1173 	if (first) {
1174 		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count];
1175 		if ((rd->data = (uint16_t *) region_alloc(parser->rr_region,
1176 			sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) {
1177 			zc_error_prev_line("Could not allocate memory for TXT RR");
1178 			return;
1179 		}
1180 		parser->current_rr.rdata_count++;
1181 		rd->data[0] = 0;
1182 	}
1183 	else
1184 		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1185 
1186 	if ((size_t)rd->data[0] + (size_t)data[0] > 65535) {
1187 		zc_error_prev_line("too large rdata element");
1188 		return;
1189 	}
1190 
1191 	memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]);
1192 	rd->data[0] += data[0];
1193 }
1194 
1195 /**
1196  * Clean up after last call of zadd_rdata_txt_wireformat
1197  */
1198 void
1199 zadd_rdata_txt_clean_wireformat()
1200 {
1201 	uint16_t *tmp_data;
1202 	rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1203 	if(!rd || !rd->data)
1204 		return; /* previous syntax failure */
1205 	if ((tmp_data = (uint16_t *) region_alloc(parser->region,
1206 		((size_t)rd->data[0]) + ((size_t)2))) != NULL) {
1207 		memcpy(tmp_data, rd->data, rd->data[0] + 2);
1208 		/* rd->data of u16+65535 freed when rr_region is freed */
1209 		rd->data = tmp_data;
1210 	}
1211 	else {
1212 		/* We could not get memory in non-volatile region */
1213 		zc_error_prev_line("could not allocate memory for rdata");
1214 		return;
1215 	}
1216 }
1217 
1218 void
1219 zadd_rdata_domain(domain_type *domain)
1220 {
1221 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1222 		zc_error_prev_line("too many rdata elements");
1223 	} else {
1224 		parser->current_rr.rdatas[parser->current_rr.rdata_count].domain
1225 			= domain;
1226 		domain->usage ++; /* new reference to domain */
1227 		++parser->current_rr.rdata_count;
1228 	}
1229 }
1230 
1231 void
1232 parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
1233 {
1234 	buffer_type packet;
1235 	uint16_t size;
1236 	ssize_t rdata_count;
1237 	ssize_t i;
1238 	rdata_atom_type *rdatas;
1239 
1240 	if (wireformat) {
1241 		size = *wireformat;
1242 	} else {
1243 		return;
1244 	}
1245 
1246 	buffer_create_from(&packet, wireformat + 1, *wireformat);
1247 	rdata_count = rdata_wireformat_to_rdata_atoms(parser->region,
1248 						      parser->db->domains,
1249 						      type,
1250 						      size,
1251 						      &packet,
1252 						      &rdatas);
1253 	if (rdata_count == -1) {
1254 		zc_error_prev_line("bad unknown RDATA");
1255 		return;
1256 	}
1257 
1258 	for (i = 0; i < rdata_count; ++i) {
1259 		if (rdata_atom_is_domain(type, i)) {
1260 			zadd_rdata_domain(rdatas[i].domain);
1261 		} else {
1262 			zadd_rdata_wireformat(rdatas[i].data);
1263 		}
1264 	}
1265 	region_recycle(parser->region, rdatas,
1266 		rdata_count*sizeof(rdata_atom_type));
1267 }
1268 
1269 
1270 /*
1271  * Compares two rdata arrays.
1272  *
1273  * Returns:
1274  *
1275  *	zero if they are equal
1276  *	non-zero if not
1277  *
1278  */
1279 static int
1280 zrdatacmp(uint16_t type, rr_type *a, rr_type *b)
1281 {
1282 	int i = 0;
1283 
1284 	assert(a);
1285 	assert(b);
1286 
1287 	/* One is shorter than another */
1288 	if (a->rdata_count != b->rdata_count)
1289 		return 1;
1290 
1291 	/* Compare element by element */
1292 	for (i = 0; i < a->rdata_count; ++i) {
1293 		if (rdata_atom_is_domain(type, i)) {
1294 			if (rdata_atom_domain(a->rdatas[i])
1295 			    != rdata_atom_domain(b->rdatas[i]))
1296 			{
1297 				return 1;
1298 			}
1299 		} else if(rdata_atom_is_literal_domain(type, i)) {
1300 			if (rdata_atom_size(a->rdatas[i])
1301 			    != rdata_atom_size(b->rdatas[i]))
1302 				return 1;
1303 			if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]),
1304 				   rdata_atom_data(b->rdatas[i]),
1305 				   rdata_atom_size(a->rdatas[i])))
1306 				return 1;
1307 		} else {
1308 			if (rdata_atom_size(a->rdatas[i])
1309 			    != rdata_atom_size(b->rdatas[i]))
1310 			{
1311 				return 1;
1312 			}
1313 			if (memcmp(rdata_atom_data(a->rdatas[i]),
1314 				   rdata_atom_data(b->rdatas[i]),
1315 				   rdata_atom_size(a->rdatas[i])) != 0)
1316 			{
1317 				return 1;
1318 			}
1319 		}
1320 	}
1321 
1322 	/* Otherwise they are equal */
1323 	return 0;
1324 }
1325 
1326 /*
1327  *
1328  * Opens a zone file.
1329  *
1330  * Returns:
1331  *
1332  *	- pointer to the parser structure
1333  *	- NULL on error and errno set
1334  *
1335  */
1336 static int
1337 zone_open(const char *filename, uint32_t ttl, uint16_t klass,
1338 	  const dname_type *origin)
1339 {
1340 	/* Open the zone file... */
1341 	if (strcmp(filename, "-") == 0) {
1342 		yyin = stdin;
1343 		filename = "<stdin>";
1344 		warn_if_directory("zonefile from stdin", yyin, filename);
1345 	} else {
1346 		if (!(yyin = fopen(filename, "r"))) {
1347 			return 0;
1348 		}
1349 		warn_if_directory("zonefile", yyin, filename);
1350 	}
1351 
1352 	zparser_init(filename, ttl, klass, origin);
1353 
1354 	return 1;
1355 }
1356 
1357 
1358 void
1359 set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],
1360 	    uint16_t index)
1361 {
1362 	/*
1363 	 * The bits are counted from left to right, so bit #0 is the
1364 	 * left most bit.
1365 	 */
1366 	uint8_t window = index / 256;
1367 	uint8_t bit = index % 256;
1368 
1369 	bits[window][bit / 8] |= (1 << (7 - bit % 8));
1370 }
1371 
1372 
1373 static int
1374 has_soa(domain_type* domain)
1375 {
1376 	rrset_type* p = NULL;
1377 	if(!domain) return 0;
1378 	for(p = domain->rrsets; p; p = p->next)
1379 		if(rrset_rrtype(p) == TYPE_SOA)
1380 			return 1;
1381 	return 0;
1382 }
1383 
1384 int
1385 process_rr(void)
1386 {
1387 	zone_type *zone = parser->current_zone;
1388 	rr_type *rr = &parser->current_rr;
1389 	rrset_type *rrset;
1390 	size_t max_rdlength;
1391 	int i;
1392 	rrtype_descriptor_type *descriptor
1393 		= rrtype_descriptor_by_type(rr->type);
1394 
1395 	/* We only support IN class */
1396 	if (rr->klass != CLASS_IN) {
1397 		if(zone_is_slave(zone->opts))
1398 			zc_warning_prev_line("only class IN is supported");
1399 		else
1400 			zc_error_prev_line("only class IN is supported");
1401 		return 0;
1402 	}
1403 
1404 	/* Make sure the maximum RDLENGTH does not exceed 65535 bytes.	*/
1405 	max_rdlength = rdata_maximum_wireformat_size(
1406 		descriptor, rr->rdata_count, rr->rdatas);
1407 
1408 	if (max_rdlength > MAX_RDLENGTH) {
1409 		zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH);
1410 		return 0;
1411 	}
1412 	/* we have the zone already */
1413 	assert(zone);
1414 	if (rr->type == TYPE_SOA) {
1415 		if (rr->owner != zone->apex) {
1416 			char s[MAXDOMAINLEN*5];
1417 			snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
1418 			zc_error_prev_line(
1419 				"SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s);
1420 			return 0;
1421 		}
1422 		if(has_soa(rr->owner)) {
1423 			if(zone_is_slave(zone->opts))
1424 				zc_warning_prev_line("this SOA record was already encountered");
1425 			else
1426 				zc_error_prev_line("this SOA record was already encountered");
1427 			return 0;
1428 		}
1429 		rr->owner->is_apex = 1;
1430 	}
1431 
1432 	if (!domain_is_subdomain(rr->owner, zone->apex))
1433 	{
1434 		char s[MAXDOMAINLEN*5];
1435 		snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
1436 		if(zone_is_slave(zone->opts))
1437 			zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
1438 		else
1439 			zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
1440 		return 0;
1441 	}
1442 
1443 	/* Do we have this type of rrset already? */
1444 	rrset = domain_find_rrset(rr->owner, zone, rr->type);
1445 	if (!rrset) {
1446 		rrset = (rrset_type *) region_alloc(parser->region,
1447 						    sizeof(rrset_type));
1448 		rrset->zone = zone;
1449 		rrset->rr_count = 1;
1450 		rrset->rrs = (rr_type *) region_alloc(parser->region,
1451 						      sizeof(rr_type));
1452 		rrset->rrs[0] = *rr;
1453 
1454 		/* Add it */
1455 		domain_add_rrset(rr->owner, rrset);
1456 	} else {
1457 		rr_type* o;
1458 		if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) {
1459 			zc_warning_prev_line(
1460 				"%s TTL %u does not match the TTL %u of the %s RRset",
1461 				domain_to_string(rr->owner), (unsigned)rr->ttl,
1462 				(unsigned)rrset->rrs[0].ttl,
1463 				rrtype_to_string(rr->type));
1464 		}
1465 
1466 		/* Search for possible duplicates... */
1467 		for (i = 0; i < rrset->rr_count; i++) {
1468 			if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) {
1469 				break;
1470 			}
1471 		}
1472 
1473 		/* Discard the duplicates... */
1474 		if (i < rrset->rr_count) {
1475 			/* add rdatas to recycle bin. */
1476 			size_t i;
1477 			for (i = 0; i < rr->rdata_count; i++) {
1478 				if(!rdata_atom_is_domain(rr->type, i))
1479 					region_recycle(parser->region, rr->rdatas[i].data,
1480 						rdata_atom_size(rr->rdatas[i])
1481 						+ sizeof(uint16_t));
1482 			}
1483 			region_recycle(parser->region, rr->rdatas,
1484 				sizeof(rdata_atom_type)*rr->rdata_count);
1485 			return 0;
1486 		}
1487 		if(rrset->rr_count == 65535) {
1488 			zc_error_prev_line("too many RRs for domain RRset");
1489 			return 0;
1490 		}
1491 
1492 		/* Add it... */
1493 		o = rrset->rrs;
1494 		rrset->rrs = (rr_type *) region_alloc_array(parser->region,
1495 			(rrset->rr_count + 1), sizeof(rr_type));
1496 		memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type));
1497 		region_recycle(parser->region, o,
1498 			(rrset->rr_count) * sizeof(rr_type));
1499 		rrset->rrs[rrset->rr_count] = *rr;
1500 		++rrset->rr_count;
1501 	}
1502 
1503 	if(rr->type == TYPE_DNAME && rrset->rr_count > 1) {
1504 		if(zone_is_slave(zone->opts))
1505 			zc_warning_prev_line("multiple DNAMEs at the same name");
1506 		else
1507 			zc_error_prev_line("multiple DNAMEs at the same name");
1508 	}
1509 	if(rr->type == TYPE_CNAME && rrset->rr_count > 1) {
1510 		if(zone_is_slave(zone->opts))
1511 			zc_warning_prev_line("multiple CNAMEs at the same name");
1512 		else
1513 			zc_error_prev_line("multiple CNAMEs at the same name");
1514 	}
1515 	if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME))
1516 	 ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) {
1517 		if(zone_is_slave(zone->opts))
1518 			zc_warning_prev_line("DNAME and CNAME at the same name");
1519 		else
1520 			zc_error_prev_line("DNAME and CNAME at the same name");
1521 	}
1522 	if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) &&
1523 		domain_find_non_cname_rrset(rr->owner, zone)) {
1524 		if(zone_is_slave(zone->opts))
1525 			zc_warning_prev_line("CNAME and other data at the same name");
1526 		else
1527 			zc_error_prev_line("CNAME and other data at the same name");
1528 	}
1529 
1530 	/* Check we have SOA */
1531 	if(rr->owner == zone->apex)
1532 		apex_rrset_checks(parser->db, rrset, rr->owner);
1533 
1534 	if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) {
1535 		struct stat buf;
1536 		startzonec = time(NULL);
1537 		buf.st_size = 0;
1538 		fstat(fileno(yyin), &buf);
1539 		if(buf.st_size == 0) buf.st_size = 1;
1540 		VERBOSITY(1, (LOG_INFO, "parse %s %d %%",
1541 			parser->current_zone->opts->name,
1542 			(int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size)));
1543 	}
1544 	++totalrrs;
1545 	return 1;
1546 }
1547 
1548 /*
1549  * Find rrset type for any zone
1550  */
1551 static rrset_type*
1552 domain_find_rrset_any(domain_type *domain, uint16_t type)
1553 {
1554 	rrset_type *result = domain->rrsets;
1555 	while (result) {
1556 		if (rrset_rrtype(result) == type) {
1557 			return result;
1558 		}
1559 		result = result->next;
1560 	}
1561 	return NULL;
1562 }
1563 
1564 /*
1565  * Check for DNAME type. Nothing is allowed below it
1566  */
1567 static void
1568 check_dname(zone_type* zone)
1569 {
1570 	domain_type* domain;
1571 	for(domain = zone->apex; domain && domain_is_subdomain(domain,
1572 		zone->apex); domain=domain_next(domain))
1573 	{
1574 		if(domain->is_existing) {
1575 			/* there may not be DNAMEs above it */
1576 			domain_type* parent = domain->parent;
1577 #ifdef NSEC3
1578 			if(domain_has_only_NSEC3(domain, NULL))
1579 				continue;
1580 #endif
1581 			while(parent) {
1582 				if(domain_find_rrset_any(parent, TYPE_DNAME)) {
1583 					zc_error("While checking node %s,",
1584 						domain_to_string(domain));
1585 					zc_error("DNAME at %s has data below it. "
1586 						"This is not allowed (rfc 2672).",
1587 						domain_to_string(parent));
1588 					return;
1589 				}
1590 				parent = parent->parent;
1591 			}
1592 		}
1593 	}
1594 }
1595 
1596 /*
1597  * Reads the specified zone into the memory
1598  * nsd_options can be NULL if no config file is passed.
1599  */
1600 unsigned int
1601 zonec_read(const char* name, const char* zonefile, zone_type* zone)
1602 {
1603 	const dname_type *dname;
1604 
1605 	totalrrs = 0;
1606 	startzonec = time(NULL);
1607 	parser->errors = 0;
1608 
1609 	dname = dname_parse(parser->rr_region, name);
1610 	if (!dname) {
1611 		zc_error("incorrect zone name '%s'", name);
1612 		return 1;
1613 	}
1614 
1615 #ifndef ROOT_SERVER
1616 	/* Is it a root zone? Are we a root server then? Idiot proof. */
1617 	if (dname->label_count == 1) {
1618 		zc_error("not configured as a root server");
1619 		return 1;
1620 	}
1621 #endif
1622 
1623 	/* Open the zone file */
1624 	if (!zone_open(zonefile, 3600, CLASS_IN, dname)) {
1625 		zc_error("cannot open '%s': %s", zonefile, strerror(errno));
1626 		return 1;
1627 	}
1628 	parser->current_zone = zone;
1629 
1630 	/* Parse and process all RRs.  */
1631 	yyparse();
1632 
1633 	/* remove origin if it was unused */
1634 	if(parser->origin != error_domain)
1635 		domain_table_deldomain(parser->db, parser->origin);
1636 	/* rr_region has been emptied by now */
1637 	dname = dname_parse(parser->rr_region, name);
1638 
1639 	/* check if zone file contained a correct SOA record */
1640 	if (!parser->current_zone) {
1641 		zc_error("zone configured as '%s' has no content.", name);
1642 	} else if(!parser->current_zone->soa_rrset ||
1643 		parser->current_zone->soa_rrset->rr_count == 0) {
1644 		zc_error("zone configured as '%s' has no SOA record.", name);
1645 	} else if(dname_compare(domain_dname(
1646 		parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
1647 		zc_error("zone configured as '%s', but SOA has owner '%s'.",
1648 			name, domain_to_string(
1649 			parser->current_zone->soa_rrset->rrs[0].owner));
1650 	}
1651 	region_free_all(parser->rr_region);
1652 
1653 	parser_flush();
1654 	fclose(yyin);
1655 	if(!zone_is_slave(zone->opts))
1656 		check_dname(zone);
1657 
1658 	parser->filename = NULL;
1659 	return parser->errors;
1660 }
1661 
1662 
1663 /*
1664  * setup parse
1665  */
1666 void
1667 zonec_setup_parser(namedb_type* db)
1668 {
1669 	region_type* rr_region = region_create(xalloc, free);
1670 	parser = zparser_create(db->region, rr_region, db);
1671 	assert(parser);
1672 	/* Unique pointers used to mark errors.	 */
1673 	error_dname = (dname_type *) region_alloc(db->region, 1);
1674 	error_domain = (domain_type *) region_alloc(db->region, 1);
1675 	/* Open the network database */
1676 	setprotoent(1);
1677 	setservent(1);
1678 }
1679 
1680 /** desetup parse */
1681 void
1682 zonec_desetup_parser(void)
1683 {
1684 	if(parser) {
1685 		endservent();
1686 		endprotoent();
1687 		region_destroy(parser->rr_region);
1688 		/* removed when parser->region(=db->region) is destroyed:
1689 		 * region_recycle(parser->region, (void*)error_dname, 1);
1690 		 * region_recycle(parser->region, (void*)error_domain, 1); */
1691 		/* clear memory for exit, but this is not portable to
1692 		 * other versions of lex. yylex_destroy(); */
1693 #ifdef MEMCLEAN /* OS collects memory pages */
1694 		yylex_destroy();
1695 #endif
1696 	}
1697 }
1698 
1699 static domain_table_type* orig_domains = NULL;
1700 static region_type* orig_region = NULL;
1701 static region_type* orig_dbregion = NULL;
1702 
1703 /** setup for string parse */
1704 void
1705 zonec_setup_string_parser(region_type* region, domain_table_type* domains)
1706 {
1707 	assert(parser); /* global parser must be setup */
1708 	orig_domains = parser->db->domains;
1709 	orig_region = parser->region;
1710 	orig_dbregion = parser->db->region;
1711 	parser->region = region;
1712 	parser->db->region = region;
1713 	parser->db->domains = domains;
1714 	zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root));
1715 }
1716 
1717 /** desetup string parse */
1718 void
1719 zonec_desetup_string_parser(void)
1720 {
1721 	parser->region = orig_region;
1722 	parser->db->domains = orig_domains;
1723 	parser->db->region = orig_dbregion;
1724 }
1725 
1726 /** parse a string into temporary storage */
1727 int
1728 zonec_parse_string(region_type* region, domain_table_type* domains,
1729 	zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
1730 {
1731 	int errors;
1732 	zonec_setup_string_parser(region, domains);
1733 	parser->current_zone = zone;
1734 	parser->errors = 0;
1735 	totalrrs = 0;
1736 	startzonec = time(NULL)+100000; /* disable */
1737 	parser_push_stringbuf(str);
1738 	yyparse();
1739 	parser_pop_stringbuf();
1740 	errors = parser->errors;
1741 	*num_rrs = totalrrs;
1742 	if(*num_rrs == 0)
1743 		*parsed = NULL;
1744 	else	*parsed = parser->prev_dname;
1745 	/* remove origin if it was not used during the parse */
1746 	if(parser->origin != error_domain)
1747 		domain_table_deldomain(parser->db, parser->origin);
1748 	region_free_all(parser->rr_region);
1749 	zonec_desetup_string_parser();
1750 	parser_flush();
1751 	return errors;
1752 }
1753 
1754 /** check SSHFP type for failures and emit warnings */
1755 void check_sshfp(void)
1756 {
1757 	uint8_t hash;
1758 	uint16_t size;
1759 	if(parser->current_rr.rdata_count < 3)
1760 		return; /* cannot check it, too few rdata elements */
1761 	if(!parser->current_rr.rdatas[0].data ||
1762 		!parser->current_rr.rdatas[1].data ||
1763 		!parser->current_rr.rdatas[2].data ||
1764 		!parser->current_rr.owner)
1765 		return; /* cannot check, NULLs (due to earlier errors) */
1766 	if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1)
1767 		return; /* wrong size of the hash type rdata element */
1768 	hash = rdata_atom_data(parser->current_rr.rdatas[1])[0];
1769 	size = rdata_atom_size(parser->current_rr.rdatas[2]);
1770 	if(hash == 1 && size != 20) {
1771 		zc_warning_prev_line("SSHFP %s of type SHA1 has hash of "
1772 			"wrong length, %d bytes, should be 20",
1773 			domain_to_string(parser->current_rr.owner),
1774 			(int)size);
1775 	} else if(hash == 2 && size != 32) {
1776 		zc_warning_prev_line("SSHFP %s of type SHA256 has hash of "
1777 			"wrong length, %d bytes, should be 32",
1778 			domain_to_string(parser->current_rr.owner),
1779 			(int)size);
1780 	}
1781 }
1782