xref: /openbsd-src/usr.sbin/nsd/zonec.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
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((int)*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((int)*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 a algoritm 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 	int c;
392 	char digits[ILNP_MAXDIGITS+1];
393 	unsigned int ui[ILNP_NUMGROUPS];
394 	uint16_t a[ILNP_NUMGROUPS];
395 
396 	ngroups = 1; /* Always at least one group */
397 	num = 0;
398 	for (ch = text; *ch != '\0'; ch++) {
399 		if (*ch == ':') {
400 			if (num <= 0) {
401 				zc_error_prev_line("ilnp64: empty group of "
402 					"digits is not allowed");
403 				return NULL;
404 			}
405 			digits[num] = '\0';
406 			hex = (unsigned long) strtol(digits, NULL, 16);
407 			num = 0;
408 			ui[ngroups - 1] = hex;
409 			if (ngroups >= ILNP_NUMGROUPS) {
410 				zc_error_prev_line("ilnp64: more than %d groups "
411 					"of digits", ILNP_NUMGROUPS);
412 				return NULL;
413 			}
414 			ngroups++;
415 		} else {
416 			/* Our grammar is stricter than the one accepted by
417 			 * strtol. */
418 			c = (int) *ch;
419 			if (!isxdigit(c)) {
420 				zc_error_prev_line("ilnp64: invalid "
421 					"(non-hexadecimal) character %c", c);
422 				return NULL;
423 			}
424 			if (num >= ILNP_MAXDIGITS) {
425 				zc_error_prev_line("ilnp64: more than %d digits "
426 					"in a group", ILNP_MAXDIGITS);
427 				return NULL;
428 			}
429 			digits[num++] = *ch;
430 		}
431 	}
432 	if (num <= 0) {
433 		zc_error_prev_line("ilnp64: empty group of digits is not "
434 			"allowed");
435 		return NULL;
436 	}
437 	digits[num] = '\0';
438 	hex = (unsigned long) strtol(digits, NULL, 16);
439 	ui[ngroups - 1] = hex;
440 	if (ngroups < 4) {
441 		zc_error_prev_line("ilnp64: less than %d groups of digits",
442 			ILNP_NUMGROUPS);
443 		return NULL;
444 	}
445 
446 	a[0] = htons(ui[0]);
447 	a[1] = htons(ui[1]);
448 	a[2] = htons(ui[2]);
449 	a[3] = htons(ui[3]);
450 	r = alloc_rdata_init(region, a, sizeof(a));
451 	return r;
452 }
453 
454 static uint16_t *
455 zparser_conv_eui48(region_type *region, const char *text)
456 {
457 	uint8_t nums[6];
458 	uint16_t *r = NULL;
459 	unsigned int a, b, c, d, e, f;
460 	int l;
461 
462 	if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x%n",
463 		&a, &b, &c, &d, &e, &f, &l) != 6 ||
464 		l != (int)strlen(text)){
465 		zc_error_prev_line("eui48: invalid rr");
466 		return NULL;
467 	}
468 	nums[0] = (uint8_t)a;
469 	nums[1] = (uint8_t)b;
470 	nums[2] = (uint8_t)c;
471 	nums[3] = (uint8_t)d;
472 	nums[4] = (uint8_t)e;
473 	nums[5] = (uint8_t)f;
474 	r = alloc_rdata_init(region, nums, sizeof(nums));
475 	return r;
476 }
477 
478 static uint16_t *
479 zparser_conv_eui64(region_type *region, const char *text)
480 {
481 	uint8_t nums[8];
482 	uint16_t *r = NULL;
483 	unsigned int a, b, c, d, e, f, g, h;
484 	int l;
485 	if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n",
486 		&a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 ||
487 		l != (int)strlen(text)) {
488 		zc_error_prev_line("eui64: invalid rr");
489 		return NULL;
490 	}
491 	nums[0] = (uint8_t)a;
492 	nums[1] = (uint8_t)b;
493 	nums[2] = (uint8_t)c;
494 	nums[3] = (uint8_t)d;
495 	nums[4] = (uint8_t)e;
496 	nums[5] = (uint8_t)f;
497 	nums[6] = (uint8_t)g;
498 	nums[7] = (uint8_t)h;
499 	r = alloc_rdata_init(region, nums, sizeof(nums));
500 	return r;
501 }
502 
503 uint16_t *
504 zparser_conv_eui(region_type *region, const char *text, size_t len)
505 {
506 	uint16_t *r = NULL;
507 	int nnum, num;
508 	const char* ch;
509 
510 	nnum = len/8;
511 	num = 1;
512 	for (ch = text; *ch != '\0'; ch++) {
513 		int c = (int) *ch;
514 		if (*ch == '-') {
515 			num++;
516 		} else if (!isxdigit(c)) {
517 			zc_error_prev_line("eui%u: invalid (non-hexadecimal) "
518 				"character %c", (unsigned) len, c);
519 			return NULL;
520 		}
521 	}
522 	if (num != nnum) {
523 		zc_error_prev_line("eui%u: wrong number of hex numbers",
524 			(unsigned) len);
525 		return NULL;
526 	}
527 
528 	switch (len) {
529 		case 48:
530 			r = zparser_conv_eui48(region, text);
531 			break;
532 		case 64:
533 			r = zparser_conv_eui64(region, text);
534 		break;
535 		default:
536 			zc_error_prev_line("eui%u: invalid length",
537 				(unsigned) len);
538 			return NULL;
539 			break;
540 	}
541 	return r;
542 }
543 
544 uint16_t *
545 zparser_conv_text(region_type *region, const char *text, size_t len)
546 {
547 	uint16_t *r = NULL;
548 	uint8_t *p;
549 
550 	if (len > 255) {
551 		zc_error_prev_line("text string is longer than 255 characters,"
552 				   " try splitting it into multiple parts");
553 		len = 255;
554 	}
555 	r = alloc_rdata(region, len + 1);
556 	p = (uint8_t *) (r + 1);
557 	*p = len;
558 	memcpy(p + 1, text, len);
559 	return r;
560 }
561 
562 /* for CAA Value [RFC 6844] */
563 uint16_t *
564 zparser_conv_long_text(region_type *region, const char *text, size_t len)
565 {
566 	uint16_t *r = NULL;
567 	if (len > MAX_RDLENGTH) {
568 		zc_error_prev_line("text string is longer than max rdlen");
569 		return NULL;
570 	}
571 	r = alloc_rdata_init(region, text, len);
572 	return r;
573 }
574 
575 /* for CAA Tag [RFC 6844] */
576 uint16_t *
577 zparser_conv_tag(region_type *region, const char *text, size_t len)
578 {
579 	uint16_t *r = NULL;
580 	uint8_t *p;
581 	const char* ptr;
582 
583 	if (len < 1) {
584 		zc_error_prev_line("invalid tag: zero length");
585 		return NULL;
586 	}
587 	if (len > 15) {
588 		zc_error_prev_line("invalid tag %s: longer than 15 characters (%u)",
589 			text, (unsigned) len);
590 		return NULL;
591 	}
592 	for (ptr = text; *ptr; ptr++) {
593 		if (!isdigit(*ptr) && !islower(*ptr)) {
594 			zc_error_prev_line("invalid tag %s: contains invalid char %c",
595 				text, *ptr);
596 			return NULL;
597 		}
598 	}
599 	r = alloc_rdata(region, len + 1);
600 	p = (uint8_t *) (r + 1);
601 	*p = len;
602 	memmove(p + 1, text, len);
603 	return r;
604 }
605 
606 uint16_t *
607 zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len)
608 {
609 	uint16_t* r = NULL;
610 	uint8_t* p = NULL;
611 	r = alloc_rdata(region, len);
612 	p = (uint8_t *) (r + 1);
613 	memcpy(p, name, len);
614 
615 	return r;
616 }
617 
618 uint16_t *
619 zparser_conv_b32(region_type *region, const char *b32)
620 {
621 	uint8_t buffer[B64BUFSIZE];
622 	uint16_t *r = NULL;
623 	int i;
624 
625 	if(strcmp(b32, "-") == 0) {
626 		return alloc_rdata_init(region, "", 1);
627 	}
628 	i = b32_pton(b32, buffer+1, B64BUFSIZE-1);
629 	if (i == -1 || i > 255) {
630 		zc_error_prev_line("invalid base32 data");
631 	} else {
632 		buffer[0] = i; /* store length byte */
633 		r = alloc_rdata_init(region, buffer, i+1);
634 	}
635 	return r;
636 }
637 
638 uint16_t *
639 zparser_conv_b64(region_type *region, const char *b64)
640 {
641 	uint8_t buffer[B64BUFSIZE];
642 	uint16_t *r = NULL;
643 	int i;
644 
645 	i = b64_pton(b64, buffer, B64BUFSIZE);
646 	if (i == -1) {
647 		zc_error_prev_line("invalid base64 data");
648 	} else {
649 		r = alloc_rdata_init(region, buffer, i);
650 	}
651 	return r;
652 }
653 
654 uint16_t *
655 zparser_conv_rrtype(region_type *region, const char *text)
656 {
657 	uint16_t *r = NULL;
658 	uint16_t type = rrtype_from_string(text);
659 
660 	if (type == 0) {
661 		zc_error_prev_line("unrecognized RR type '%s'", text);
662 	} else {
663 		type = htons(type);
664 		r = alloc_rdata_init(region, &type, sizeof(type));
665 	}
666 	return r;
667 }
668 
669 uint16_t *
670 zparser_conv_nxt(region_type *region, uint8_t nxtbits[])
671 {
672 	/* nxtbits[] consists of 16 bytes with some zero's in it
673 	 * copy every byte with zero to r and write the length in
674 	 * the first byte
675 	 */
676 	uint16_t i;
677 	uint16_t last = 0;
678 
679 	for (i = 0; i < 16; i++) {
680 		if (nxtbits[i] != 0)
681 			last = i + 1;
682 	}
683 
684 	return alloc_rdata_init(region, nxtbits, last);
685 }
686 
687 
688 /* we potentially have 256 windows, each one is numbered. empty ones
689  * should be discarded
690  */
691 uint16_t *
692 zparser_conv_nsec(region_type *region,
693 		  uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE])
694 {
695 	/* nsecbits contains up to 64K of bits which represent the
696 	 * types available for a name. Walk the bits according to
697 	 * nsec++ draft from jakob
698 	 */
699 	uint16_t *r;
700 	uint8_t *ptr;
701 	size_t i,j;
702 	uint16_t window_count = 0;
703 	uint16_t total_size = 0;
704 	uint16_t window_max = 0;
705 
706 	/* The used windows.  */
707 	int used[NSEC_WINDOW_COUNT];
708 	/* The last byte used in each the window.  */
709 	int size[NSEC_WINDOW_COUNT];
710 
711 	window_max = 1 + (nsec_highest_rcode / 256);
712 
713 	/* used[i] is the i-th window included in the nsec
714 	 * size[used[0]] is the size of window 0
715 	 */
716 
717 	/* walk through the 256 windows */
718 	for (i = 0; i < window_max; ++i) {
719 		int empty_window = 1;
720 		/* check each of the 32 bytes */
721 		for (j = 0; j < NSEC_WINDOW_BITS_SIZE; ++j) {
722 			if (nsecbits[i][j] != 0) {
723 				size[i] = j + 1;
724 				empty_window = 0;
725 			}
726 		}
727 		if (!empty_window) {
728 			used[window_count] = i;
729 			window_count++;
730 		}
731 	}
732 
733 	for (i = 0; i < window_count; ++i) {
734 		total_size += sizeof(uint16_t) + size[used[i]];
735 	}
736 
737 	r = alloc_rdata(region, total_size);
738 	ptr = (uint8_t *) (r + 1);
739 
740 	/* now walk used and copy it */
741 	for (i = 0; i < window_count; ++i) {
742 		ptr[0] = used[i];
743 		ptr[1] = size[used[i]];
744 		memcpy(ptr + 2, &nsecbits[used[i]], size[used[i]]);
745 		ptr += size[used[i]] + 2;
746 	}
747 
748 	return r;
749 }
750 
751 /* Parse an int terminated in the specified range. */
752 static int
753 parse_int(const char *str,
754 	  char **end,
755 	  int *result,
756 	  const char *name,
757 	  int min,
758 	  int max)
759 {
760 	*result = (int) strtol(str, end, 10);
761 	if (*result < min || *result > max) {
762 		zc_error_prev_line("%s must be within the range [%d .. %d]",
763 				   name,
764 				   min,
765 				   max);
766 		return 0;
767 	} else {
768 		return 1;
769 	}
770 }
771 
772 /* RFC1876 conversion routines */
773 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
774 				1000000,10000000,100000000,1000000000};
775 
776 /*
777  * Converts ascii size/precision X * 10**Y(cm) to 0xXY.
778  * Sets the given pointer to the last used character.
779  *
780  */
781 static uint8_t
782 precsize_aton (char *cp, char **endptr)
783 {
784 	unsigned int mval = 0, cmval = 0;
785 	uint8_t retval = 0;
786 	int exponent;
787 	int mantissa;
788 
789 	while (isdigit((int)*cp))
790 		mval = mval * 10 + hexdigit_to_int(*cp++);
791 
792 	if (*cp == '.') {	/* centimeters */
793 		cp++;
794 		if (isdigit((int)*cp)) {
795 			cmval = hexdigit_to_int(*cp++) * 10;
796 			if (isdigit((int)*cp)) {
797 				cmval += hexdigit_to_int(*cp++);
798 			}
799 		}
800 	}
801 
802 	if(mval >= poweroften[7]) {
803 		/* integer overflow possible for *100 */
804 		mantissa = mval / poweroften[7];
805 		exponent = 9; /* max */
806 	}
807 	else {
808 		cmval = (mval * 100) + cmval;
809 
810 		for (exponent = 0; exponent < 9; exponent++)
811 			if (cmval < poweroften[exponent+1])
812 				break;
813 
814 		mantissa = cmval / poweroften[exponent];
815 	}
816 	if (mantissa > 9)
817 		mantissa = 9;
818 
819 	retval = (mantissa << 4) | exponent;
820 
821 	if (*cp == 'm') cp++;
822 
823 	*endptr = cp;
824 
825 	return (retval);
826 }
827 
828 /*
829  * Parses a specific part of rdata.
830  *
831  * Returns:
832  *
833  *	number of elements parsed
834  *	zero on error
835  *
836  */
837 uint16_t *
838 zparser_conv_loc(region_type *region, char *str)
839 {
840 	uint16_t *r;
841 	uint32_t *p;
842 	int i;
843 	int deg, min, secs;	/* Secs is stored times 1000.  */
844 	uint32_t lat = 0, lon = 0, alt = 0;
845 	/* encoded defaults: version=0 sz=1m hp=10000m vp=10m */
846 	uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13};
847 	char *start;
848 	double d;
849 
850 	for(;;) {
851 		deg = min = secs = 0;
852 
853 		/* Degrees */
854 		if (*str == '\0') {
855 			zc_error_prev_line("unexpected end of LOC data");
856 			return NULL;
857 		}
858 
859 		if (!parse_int(str, &str, &deg, "degrees", 0, 180))
860 			return NULL;
861 		if (!isspace((int)*str)) {
862 			zc_error_prev_line("space expected after degrees");
863 			return NULL;
864 		}
865 		++str;
866 
867 		/* Minutes? */
868 		if (isdigit((int)*str)) {
869 			if (!parse_int(str, &str, &min, "minutes", 0, 60))
870 				return NULL;
871 			if (!isspace((int)*str)) {
872 				zc_error_prev_line("space expected after minutes");
873 				return NULL;
874 			}
875 			++str;
876 		}
877 
878 		/* Seconds? */
879 		if (isdigit((int)*str)) {
880 			start = str;
881 			if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
882 				return NULL;
883 			}
884 
885 			if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) {
886 				return NULL;
887 			}
888 
889 			if (!isspace((int)*str)) {
890 				zc_error_prev_line("space expected after seconds");
891 				return NULL;
892 			}
893 			/* No need for precision specifiers, it's a double */
894 			if (sscanf(start, "%lf", &d) != 1) {
895 				zc_error_prev_line("error parsing seconds");
896 			}
897 
898 			if (d < 0.0 || d > 60.0) {
899 				zc_error_prev_line("seconds not in range 0.0 .. 60.0");
900 			}
901 
902 			secs = (int) (d * 1000.0 + 0.5);
903 			++str;
904 		}
905 
906 		switch(*str) {
907 		case 'N':
908 		case 'n':
909 			lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
910 			break;
911 		case 'E':
912 		case 'e':
913 			lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
914 			break;
915 		case 'S':
916 		case 's':
917 			lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
918 			break;
919 		case 'W':
920 		case 'w':
921 			lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
922 			break;
923 		default:
924 			zc_error_prev_line("invalid latitude/longtitude: '%c'", *str);
925 			return NULL;
926 		}
927 		++str;
928 
929 		if (lat != 0 && lon != 0)
930 			break;
931 
932 		if (!isspace((int)*str)) {
933 			zc_error_prev_line("space expected after latitude/longitude");
934 			return NULL;
935 		}
936 		++str;
937 	}
938 
939 	/* Altitude */
940 	if (*str == '\0') {
941 		zc_error_prev_line("unexpected end of LOC data");
942 		return NULL;
943 	}
944 
945 	if (!isspace((int)*str)) {
946 		zc_error_prev_line("space expected before altitude");
947 		return NULL;
948 	}
949 	++str;
950 
951 	start = str;
952 
953 	/* Sign */
954 	if (*str == '+' || *str == '-') {
955 		++str;
956 	}
957 
958 	/* Meters of altitude... */
959 	(void) strtol(str, &str, 10);
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((int)*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((int)*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((int)*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((int)*str) && i <= 3; i++) {
994 		vszhpvp[i] = precsize_aton(str + 1, &str);
995 
996 		if (!isspace((int)*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 
1157 	/* First STR in str_seq, allocate 65K in first unused rdata
1158 	 * else find last used rdata */
1159 	if (first) {
1160 		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count];
1161 		if ((rd->data = (uint16_t *) region_alloc(parser->rr_region,
1162 			sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) {
1163 			zc_error_prev_line("Could not allocate memory for TXT RR");
1164 			return;
1165 		}
1166 		parser->current_rr.rdata_count++;
1167 		rd->data[0] = 0;
1168 	}
1169 	else
1170 		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1171 
1172 	if ((size_t)rd->data[0] + (size_t)data[0] > 65535) {
1173 		zc_error_prev_line("too large rdata element");
1174 		return;
1175 	}
1176 
1177 	memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]);
1178 	rd->data[0] += data[0];
1179 }
1180 
1181 /**
1182  * Clean up after last call of zadd_rdata_txt_wireformat
1183  */
1184 void
1185 zadd_rdata_txt_clean_wireformat()
1186 {
1187 	uint16_t *tmp_data;
1188 	rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1189 	if ((tmp_data = (uint16_t *) region_alloc(parser->region,
1190 		rd->data[0] + 2)) != NULL) {
1191 		memcpy(tmp_data, rd->data, rd->data[0] + 2);
1192 		/* rd->data of u16+65535 freed when rr_region is freed */
1193 		rd->data = tmp_data;
1194 	}
1195 	else {
1196 		/* We could not get memory in non-volatile region */
1197 		zc_error_prev_line("could not allocate memory for rdata");
1198 		return;
1199 	}
1200 }
1201 
1202 void
1203 zadd_rdata_domain(domain_type *domain)
1204 {
1205 	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1206 		zc_error_prev_line("too many rdata elements");
1207 	} else {
1208 		parser->current_rr.rdatas[parser->current_rr.rdata_count].domain
1209 			= domain;
1210 		domain->usage ++; /* new reference to domain */
1211 		++parser->current_rr.rdata_count;
1212 	}
1213 }
1214 
1215 void
1216 parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
1217 {
1218 	buffer_type packet;
1219 	uint16_t size;
1220 	ssize_t rdata_count;
1221 	ssize_t i;
1222 	rdata_atom_type *rdatas;
1223 
1224 	if (wireformat) {
1225 		size = *wireformat;
1226 	} else {
1227 		return;
1228 	}
1229 
1230 	buffer_create_from(&packet, wireformat + 1, *wireformat);
1231 	rdata_count = rdata_wireformat_to_rdata_atoms(parser->region,
1232 						      parser->db->domains,
1233 						      type,
1234 						      size,
1235 						      &packet,
1236 						      &rdatas);
1237 	if (rdata_count == -1) {
1238 		zc_error_prev_line("bad unknown RDATA");
1239 		return;
1240 	}
1241 
1242 	for (i = 0; i < rdata_count; ++i) {
1243 		if (rdata_atom_is_domain(type, i)) {
1244 			zadd_rdata_domain(rdatas[i].domain);
1245 		} else {
1246 			zadd_rdata_wireformat(rdatas[i].data);
1247 		}
1248 	}
1249 }
1250 
1251 
1252 /*
1253  * Compares two rdata arrays.
1254  *
1255  * Returns:
1256  *
1257  *	zero if they are equal
1258  *	non-zero if not
1259  *
1260  */
1261 static int
1262 zrdatacmp(uint16_t type, rr_type *a, rr_type *b)
1263 {
1264 	int i = 0;
1265 
1266 	assert(a);
1267 	assert(b);
1268 
1269 	/* One is shorter than another */
1270 	if (a->rdata_count != b->rdata_count)
1271 		return 1;
1272 
1273 	/* Compare element by element */
1274 	for (i = 0; i < a->rdata_count; ++i) {
1275 		if (rdata_atom_is_domain(type, i)) {
1276 			if (rdata_atom_domain(a->rdatas[i])
1277 			    != rdata_atom_domain(b->rdatas[i]))
1278 			{
1279 				return 1;
1280 			}
1281 		} else if(rdata_atom_is_literal_domain(type, i)) {
1282 			if (rdata_atom_size(a->rdatas[i])
1283 			    != rdata_atom_size(b->rdatas[i]))
1284 				return 1;
1285 			if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]),
1286 				   rdata_atom_data(b->rdatas[i]),
1287 				   rdata_atom_size(a->rdatas[i])))
1288 				return 1;
1289 		} else {
1290 			if (rdata_atom_size(a->rdatas[i])
1291 			    != rdata_atom_size(b->rdatas[i]))
1292 			{
1293 				return 1;
1294 			}
1295 			if (memcmp(rdata_atom_data(a->rdatas[i]),
1296 				   rdata_atom_data(b->rdatas[i]),
1297 				   rdata_atom_size(a->rdatas[i])) != 0)
1298 			{
1299 				return 1;
1300 			}
1301 		}
1302 	}
1303 
1304 	/* Otherwise they are equal */
1305 	return 0;
1306 }
1307 
1308 /*
1309  *
1310  * Opens a zone file.
1311  *
1312  * Returns:
1313  *
1314  *	- pointer to the parser structure
1315  *	- NULL on error and errno set
1316  *
1317  */
1318 static int
1319 zone_open(const char *filename, uint32_t ttl, uint16_t klass,
1320 	  const dname_type *origin)
1321 {
1322 	/* Open the zone file... */
1323 	if (strcmp(filename, "-") == 0) {
1324 		yyin = stdin;
1325 		filename = "<stdin>";
1326 	} else if (!(yyin = fopen(filename, "r"))) {
1327 		return 0;
1328 	}
1329 
1330 	zparser_init(filename, ttl, klass, origin);
1331 
1332 	return 1;
1333 }
1334 
1335 
1336 void
1337 set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],
1338 	    uint16_t index)
1339 {
1340 	/*
1341 	 * The bits are counted from left to right, so bit #0 is the
1342 	 * left most bit.
1343 	 */
1344 	uint8_t window = index / 256;
1345 	uint8_t bit = index % 256;
1346 
1347 	bits[window][bit / 8] |= (1 << (7 - bit % 8));
1348 }
1349 
1350 
1351 static int
1352 has_soa(domain_type* domain)
1353 {
1354 	rrset_type* p = NULL;
1355 	if(!domain) return 0;
1356 	for(p = domain->rrsets; p; p = p->next)
1357 		if(rrset_rrtype(p) == TYPE_SOA)
1358 			return 1;
1359 	return 0;
1360 }
1361 
1362 int
1363 process_rr(void)
1364 {
1365 	zone_type *zone = parser->current_zone;
1366 	rr_type *rr = &parser->current_rr;
1367 	rrset_type *rrset;
1368 	size_t max_rdlength;
1369 	int i;
1370 	rrtype_descriptor_type *descriptor
1371 		= rrtype_descriptor_by_type(rr->type);
1372 
1373 	/* We only support IN class */
1374 	if (rr->klass != CLASS_IN) {
1375 		if(zone_is_slave(zone->opts))
1376 			zc_warning_prev_line("only class IN is supported");
1377 		else
1378 			zc_error_prev_line("only class IN is supported");
1379 		return 0;
1380 	}
1381 
1382 	/* Make sure the maximum RDLENGTH does not exceed 65535 bytes.	*/
1383 	max_rdlength = rdata_maximum_wireformat_size(
1384 		descriptor, rr->rdata_count, rr->rdatas);
1385 
1386 	if (max_rdlength > MAX_RDLENGTH) {
1387 		zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH);
1388 		return 0;
1389 	}
1390 	/* we have the zone already */
1391 	assert(zone);
1392 	if (rr->type == TYPE_SOA) {
1393 		if (rr->owner != zone->apex) {
1394 			zc_error_prev_line(
1395 				"SOA record with invalid domain name");
1396 			return 0;
1397 		}
1398 		if(has_soa(rr->owner)) {
1399 			if(zone_is_slave(zone->opts))
1400 				zc_warning_prev_line("this SOA record was already encountered");
1401 			else
1402 				zc_error_prev_line("this SOA record was already encountered");
1403 			return 0;
1404 		}
1405 		rr->owner->is_apex = 1;
1406 	}
1407 
1408 	if (!domain_is_subdomain(rr->owner, zone->apex))
1409 	{
1410 		if(zone_is_slave(zone->opts))
1411 			zc_warning_prev_line("out of zone data");
1412 		else
1413 			zc_error_prev_line("out of zone data");
1414 		return 0;
1415 	}
1416 
1417 	/* Do we have this type of rrset already? */
1418 	rrset = domain_find_rrset(rr->owner, zone, rr->type);
1419 	if (!rrset) {
1420 		rrset = (rrset_type *) region_alloc(parser->region,
1421 						    sizeof(rrset_type));
1422 		rrset->zone = zone;
1423 		rrset->rr_count = 1;
1424 		rrset->rrs = (rr_type *) region_alloc(parser->region,
1425 						      sizeof(rr_type));
1426 		rrset->rrs[0] = *rr;
1427 
1428 		/* Add it */
1429 		domain_add_rrset(rr->owner, rrset);
1430 	} else {
1431 		rr_type* o;
1432 		if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) {
1433 			zc_warning_prev_line(
1434 				"TTL does not match the TTL of the RRset");
1435 		}
1436 
1437 		/* Search for possible duplicates... */
1438 		for (i = 0; i < rrset->rr_count; i++) {
1439 			if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) {
1440 				break;
1441 			}
1442 		}
1443 
1444 		/* Discard the duplicates... */
1445 		if (i < rrset->rr_count) {
1446 			return 0;
1447 		}
1448 
1449 		/* Add it... */
1450 		o = rrset->rrs;
1451 		rrset->rrs = (rr_type *) region_alloc(parser->region,
1452 			(rrset->rr_count + 1) * sizeof(rr_type));
1453 		memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type));
1454 		region_recycle(parser->region, o,
1455 			(rrset->rr_count) * sizeof(rr_type));
1456 		rrset->rrs[rrset->rr_count] = *rr;
1457 		++rrset->rr_count;
1458 	}
1459 
1460 	if(rr->type == TYPE_DNAME && rrset->rr_count > 1) {
1461 		if(zone_is_slave(zone->opts))
1462 			zc_warning_prev_line("multiple DNAMEs at the same name");
1463 		else
1464 			zc_error_prev_line("multiple DNAMEs at the same name");
1465 	}
1466 	if(rr->type == TYPE_CNAME && rrset->rr_count > 1) {
1467 		if(zone_is_slave(zone->opts))
1468 			zc_warning_prev_line("multiple CNAMEs at the same name");
1469 		else
1470 			zc_error_prev_line("multiple CNAMEs at the same name");
1471 	}
1472 	if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME))
1473 	 ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) {
1474 		if(zone_is_slave(zone->opts))
1475 			zc_warning_prev_line("DNAME and CNAME at the same name");
1476 		else
1477 			zc_error_prev_line("DNAME and CNAME at the same name");
1478 	}
1479 	if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) &&
1480 		domain_find_non_cname_rrset(rr->owner, zone)) {
1481 		if(zone_is_slave(zone->opts))
1482 			zc_warning_prev_line("CNAME and other data at the same name");
1483 		else
1484 			zc_error_prev_line("CNAME and other data at the same name");
1485 	}
1486 
1487 	/* Check we have SOA */
1488 	if(rr->owner == zone->apex)
1489 		apex_rrset_checks(parser->db, rrset, rr->owner);
1490 
1491 	if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) {
1492 		struct stat buf;
1493 		startzonec = time(NULL);
1494 		buf.st_size = 0;
1495 		fstat(fileno(yyin), &buf);
1496 		if(buf.st_size == 0) buf.st_size = 1;
1497 		VERBOSITY(1, (LOG_INFO, "parse %s %d %%",
1498 			parser->current_zone->opts->name,
1499 			(int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size)));
1500 	}
1501 	++totalrrs;
1502 	return 1;
1503 }
1504 
1505 /*
1506  * Find rrset type for any zone
1507  */
1508 static rrset_type*
1509 domain_find_rrset_any(domain_type *domain, uint16_t type)
1510 {
1511 	rrset_type *result = domain->rrsets;
1512 	while (result) {
1513 		if (rrset_rrtype(result) == type) {
1514 			return result;
1515 		}
1516 		result = result->next;
1517 	}
1518 	return NULL;
1519 }
1520 
1521 /*
1522  * Check for DNAME type. Nothing is allowed below it
1523  */
1524 static void
1525 check_dname(zone_type* zone)
1526 {
1527 	domain_type* domain;
1528 	for(domain = zone->apex; domain && domain_is_subdomain(domain,
1529 		zone->apex); domain=domain_next(domain))
1530 	{
1531 		if(domain->is_existing) {
1532 			/* there may not be DNAMEs above it */
1533 			domain_type* parent = domain->parent;
1534 #ifdef NSEC3
1535 			if(domain_has_only_NSEC3(domain, NULL))
1536 				continue;
1537 #endif
1538 			while(parent) {
1539 				if(domain_find_rrset_any(parent, TYPE_DNAME)) {
1540 					zc_error("While checking node %s,",
1541 						domain_to_string(domain));
1542 					zc_error("DNAME at %s has data below it. "
1543 						"This is not allowed (rfc 2672).",
1544 						domain_to_string(parent));
1545 					return;
1546 				}
1547 				parent = parent->parent;
1548 			}
1549 		}
1550 	}
1551 }
1552 
1553 /*
1554  * Reads the specified zone into the memory
1555  * nsd_options can be NULL if no config file is passed.
1556  */
1557 unsigned int
1558 zonec_read(const char* name, const char* zonefile, zone_type* zone)
1559 {
1560 	const dname_type *dname;
1561 
1562 	totalrrs = 0;
1563 	startzonec = time(NULL);
1564 	parser->errors = 0;
1565 
1566 	dname = dname_parse(parser->rr_region, name);
1567 	if (!dname) {
1568 		zc_error("incorrect zone name '%s'", name);
1569 		return 0;
1570 	}
1571 
1572 #ifndef ROOT_SERVER
1573 	/* Is it a root zone? Are we a root server then? Idiot proof. */
1574 	if (dname->label_count == 1) {
1575 		zc_error("not configured as a root server");
1576 		return 0;
1577 	}
1578 #endif
1579 
1580 	/* Open the zone file */
1581 	if (!zone_open(zonefile, 3600, CLASS_IN, dname)) {
1582 		zc_error("cannot open '%s': %s", zonefile, strerror(errno));
1583 		return 0;
1584 	}
1585 	parser->current_zone = zone;
1586 
1587 	/* Parse and process all RRs.  */
1588 	yyparse();
1589 
1590 	/* remove origin if it was unused */
1591 	domain_table_deldomain(parser->db, parser->origin);
1592 	/* rr_region has been emptied by now */
1593 	dname = dname_parse(parser->rr_region, name);
1594 
1595 	/* check if zone file contained a correct SOA record */
1596 	if (!parser->current_zone) {
1597 		zc_error("zone configured as '%s' has no content.", name);
1598 	} else if(!parser->current_zone->soa_rrset ||
1599 		parser->current_zone->soa_rrset->rr_count == 0) {
1600 		zc_error("zone configured as '%s' has no SOA record.", name);
1601 	} else if(dname_compare(domain_dname(
1602 		parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
1603 		zc_error("zone configured as '%s', but SOA has owner '%s'.",
1604 			name, domain_to_string(
1605 			parser->current_zone->soa_rrset->rrs[0].owner));
1606 	}
1607 
1608 	fclose(yyin);
1609 	if(!zone_is_slave(zone->opts))
1610 		check_dname(zone);
1611 
1612 	parser->filename = NULL;
1613 	return parser->errors;
1614 }
1615 
1616 
1617 /*
1618  * setup parse
1619  */
1620 void
1621 zonec_setup_parser(namedb_type* db)
1622 {
1623 	region_type* rr_region = region_create(xalloc, free);
1624 	parser = zparser_create(db->region, rr_region, db);
1625 	assert(parser);
1626 	/* Unique pointers used to mark errors.	 */
1627 	error_dname = (dname_type *) region_alloc(db->region, 1);
1628 	error_domain = (domain_type *) region_alloc(db->region, 1);
1629 	/* Open the network database */
1630 	setprotoent(1);
1631 	setservent(1);
1632 }
1633 
1634 /** desetup parse */
1635 void
1636 zonec_desetup_parser(void)
1637 {
1638 	if(parser) {
1639 		endservent();
1640 		endprotoent();
1641 		region_destroy(parser->rr_region);
1642 		/* removed when parser->region(=db->region) is destroyed:
1643 		 * region_recycle(parser->region, (void*)error_dname, 1);
1644 		 * region_recycle(parser->region, (void*)error_domain, 1); */
1645 		/* clear memory for exit, but this is not portable to
1646 		 * other versions of lex. yylex_destroy(); */
1647 	}
1648 }
1649 
1650 static domain_table_type* orig_domains = NULL;
1651 static region_type* orig_region = NULL;
1652 static region_type* orig_dbregion = NULL;
1653 
1654 /** setup for string parse */
1655 void
1656 zonec_setup_string_parser(region_type* region, domain_table_type* domains)
1657 {
1658 	assert(parser); /* global parser must be setup */
1659 	orig_domains = parser->db->domains;
1660 	orig_region = parser->region;
1661 	orig_dbregion = parser->db->region;
1662 	parser->region = region;
1663 	parser->db->region = region;
1664 	parser->db->domains = domains;
1665 	zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root));
1666 }
1667 
1668 /** desetup string parse */
1669 void
1670 zonec_desetup_string_parser(void)
1671 {
1672 	parser->region = orig_region;
1673 	parser->db->domains = orig_domains;
1674 	parser->db->region = orig_dbregion;
1675 }
1676 
1677 /** parse a string into temporary storage */
1678 int
1679 zonec_parse_string(region_type* region, domain_table_type* domains,
1680 	zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
1681 {
1682 	int errors;
1683 	zonec_setup_string_parser(region, domains);
1684 	parser->current_zone = zone;
1685 	parser->errors = 0;
1686 	totalrrs = 0;
1687 	startzonec = time(NULL)+100000; /* disable */
1688 	parser_push_stringbuf(str);
1689 	yyparse();
1690 	parser_pop_stringbuf();
1691 	errors = parser->errors;
1692 	*num_rrs = totalrrs;
1693 	if(*num_rrs == 0)
1694 		*parsed = NULL;
1695 	else	*parsed = parser->prev_dname;
1696 	/* remove origin if it was not used during the parse */
1697 	domain_table_deldomain(parser->db, parser->origin);
1698 	zonec_desetup_string_parser();
1699 	return errors;
1700 }
1701