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