zonec.c revision 1.1.1.2
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
50const dname_type *error_dname;
51domain_type *error_domain;
52
53static time_t startzonec = 0;
54static long int totalrrs = 0;
55
56extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE];
57extern 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 */
64static uint16_t *
65alloc_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
72uint16_t *
73alloc_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 */
84uint16_t *
85zparser_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 */
127uint16_t *
128zparser_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
168uint16_t *
169zparser_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
185uint16_t *
186zparser_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
248uint16_t *
249zparser_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
265uint16_t *
266zparser_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
284uint16_t *
285zparser_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
300uint16_t *
301zparser_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
316uint16_t *
317zparser_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
337uint16_t *
338zparser_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
359uint16_t *
360zparser_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
373uint16_t *
374zparser_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
388uint16_t *
389zparser_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
456static uint16_t *
457zparser_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
480static uint16_t *
481zparser_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
505uint16_t *
506zparser_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
545uint16_t *
546zparser_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] */
564uint16_t *
565zparser_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] */
577uint16_t *
578zparser_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
607uint16_t *
608zparser_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
619uint16_t *
620zparser_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
639uint16_t *
640zparser_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
659uint16_t *
660zparser_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
674uint16_t *
675zparser_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 */
696uint16_t *
697zparser_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. */
757static int
758parse_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 */
778static 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 */
786static uint8_t
787precsize_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		/* integer overflow possible for *100 */
809		mantissa = mval / poweroften[7];
810		exponent = 9; /* max */
811	}
812	else {
813		cmval = (mval * 100) + cmval;
814
815		for (exponent = 0; exponent < 9; exponent++)
816			if (cmval < poweroften[exponent+1])
817				break;
818
819		mantissa = cmval / poweroften[exponent];
820	}
821	if (mantissa > 9)
822		mantissa = 9;
823
824	retval = (mantissa << 4) | exponent;
825
826	if (*cp == 'm') cp++;
827
828	*endptr = cp;
829
830	return (retval);
831}
832
833/*
834 * Parses a specific part of rdata.
835 *
836 * Returns:
837 *
838 *	number of elements parsed
839 *	zero on error
840 *
841 */
842uint16_t *
843zparser_conv_loc(region_type *region, char *str)
844{
845	uint16_t *r;
846	uint32_t *p;
847	int i;
848	int deg, min, secs;	/* Secs is stored times 1000.  */
849	uint32_t lat = 0, lon = 0, alt = 0;
850	/* encoded defaults: version=0 sz=1m hp=10000m vp=10m */
851	uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13};
852	char *start;
853	double d;
854
855	for(;;) {
856		deg = min = secs = 0;
857
858		/* Degrees */
859		if (*str == '\0') {
860			zc_error_prev_line("unexpected end of LOC data");
861			return NULL;
862		}
863
864		if (!parse_int(str, &str, &deg, "degrees", 0, 180))
865			return NULL;
866		if (!isspace((unsigned char)*str)) {
867			zc_error_prev_line("space expected after degrees");
868			return NULL;
869		}
870		++str;
871
872		/* Minutes? */
873		if (isdigit((unsigned char)*str)) {
874			if (!parse_int(str, &str, &min, "minutes", 0, 60))
875				return NULL;
876			if (!isspace((unsigned char)*str)) {
877				zc_error_prev_line("space expected after minutes");
878				return NULL;
879			}
880			++str;
881		}
882
883		/* Seconds? */
884		if (isdigit((unsigned char)*str)) {
885			start = str;
886			if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
887				return NULL;
888			}
889
890			if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) {
891				return NULL;
892			}
893
894			if (!isspace((unsigned char)*str)) {
895				zc_error_prev_line("space expected after seconds");
896				return NULL;
897			}
898			/* No need for precision specifiers, it's a double */
899			if (sscanf(start, "%lf", &d) != 1) {
900				zc_error_prev_line("error parsing seconds");
901			}
902
903			if (d < 0.0 || d > 60.0) {
904				zc_error_prev_line("seconds not in range 0.0 .. 60.0");
905			}
906
907			secs = (int) (d * 1000.0 + 0.5);
908			++str;
909		}
910
911		switch(*str) {
912		case 'N':
913		case 'n':
914			lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
915			break;
916		case 'E':
917		case 'e':
918			lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
919			break;
920		case 'S':
921		case 's':
922			lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
923			break;
924		case 'W':
925		case 'w':
926			lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
927			break;
928		default:
929			zc_error_prev_line("invalid latitude/longtitude: '%c'", *str);
930			return NULL;
931		}
932		++str;
933
934		if (lat != 0 && lon != 0)
935			break;
936
937		if (!isspace((unsigned char)*str)) {
938			zc_error_prev_line("space expected after latitude/longitude");
939			return NULL;
940		}
941		++str;
942	}
943
944	/* Altitude */
945	if (*str == '\0') {
946		zc_error_prev_line("unexpected end of LOC data");
947		return NULL;
948	}
949
950	if (!isspace((unsigned char)*str)) {
951		zc_error_prev_line("space expected before altitude");
952		return NULL;
953	}
954	++str;
955
956	start = str;
957
958	/* Sign */
959	if (*str == '+' || *str == '-') {
960		++str;
961	}
962
963	/* Meters of altitude... */
964	if(strtol(str, &str, 10) == LONG_MAX) {
965		zc_error_prev_line("altitude too large, number overflow");
966		return NULL;
967	}
968	switch(*str) {
969	case ' ':
970	case '\0':
971	case 'm':
972		break;
973	case '.':
974		if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) {
975			return NULL;
976		}
977		if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') {
978			zc_error_prev_line("altitude fraction must be a number");
979			return NULL;
980		}
981		break;
982	default:
983		zc_error_prev_line("altitude must be expressed in meters");
984		return NULL;
985	}
986	if (!isspace((unsigned char)*str) && *str != '\0')
987		++str;
988
989	if (sscanf(start, "%lf", &d) != 1) {
990		zc_error_prev_line("error parsing altitude");
991	}
992
993	alt = (uint32_t) (10000000.0 + d * 100 + 0.5);
994
995	if (!isspace((unsigned char)*str) && *str != '\0') {
996		zc_error_prev_line("unexpected character after altitude");
997		return NULL;
998	}
999
1000	/* Now parse size, horizontal precision and vertical precision if any */
1001	for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) {
1002		vszhpvp[i] = precsize_aton(str + 1, &str);
1003
1004		if (!isspace((unsigned char)*str) && *str != '\0') {
1005			zc_error_prev_line("invalid size or precision");
1006			return NULL;
1007		}
1008	}
1009
1010	/* Allocate required space... */
1011	r = alloc_rdata(region, 16);
1012	p = (uint32_t *) (r + 1);
1013
1014	memmove(p, vszhpvp, 4);
1015	write_uint32(p + 1, lat);
1016	write_uint32(p + 2, lon);
1017	write_uint32(p + 3, alt);
1018
1019	return r;
1020}
1021
1022/*
1023 * Convert an APL RR RDATA element.
1024 */
1025uint16_t *
1026zparser_conv_apl_rdata(region_type *region, char *str)
1027{
1028	int negated = 0;
1029	uint16_t address_family;
1030	uint8_t prefix;
1031	uint8_t maximum_prefix;
1032	uint8_t length;
1033	uint8_t address[IP6ADDRLEN];
1034	char *colon = strchr(str, ':');
1035	char *slash = strchr(str, '/');
1036	int af;
1037	int rc;
1038	uint16_t rdlength;
1039	uint16_t *r;
1040	uint8_t *t;
1041	char *end;
1042	long p;
1043
1044	if (!colon) {
1045		zc_error("address family separator is missing");
1046		return NULL;
1047	}
1048	if (!slash) {
1049		zc_error("prefix separator is missing");
1050		return NULL;
1051	}
1052
1053	*colon = '\0';
1054	*slash = '\0';
1055
1056	if (*str == '!') {
1057		negated = 1;
1058		++str;
1059	}
1060
1061	if (strcmp(str, "1") == 0) {
1062		address_family = htons(1);
1063		af = AF_INET;
1064		length = sizeof(in_addr_t);
1065		maximum_prefix = length * 8;
1066	} else if (strcmp(str, "2") == 0) {
1067		address_family = htons(2);
1068		af = AF_INET6;
1069		length = IP6ADDRLEN;
1070		maximum_prefix = length * 8;
1071	} else {
1072		zc_error("invalid address family '%s'", str);
1073		return NULL;
1074	}
1075
1076	rc = inet_pton(af, colon + 1, address);
1077	if (rc == 0) {
1078		zc_error("invalid address '%s'", colon + 1);
1079		return NULL;
1080	} else if (rc == -1) {
1081		zc_error("inet_pton failed: %s", strerror(errno));
1082		return NULL;
1083	}
1084
1085	/* Strip trailing zero octets.	*/
1086	while (length > 0 && address[length - 1] == 0)
1087		--length;
1088
1089
1090	p = strtol(slash + 1, &end, 10);
1091	if (p < 0 || p > maximum_prefix) {
1092		zc_error("prefix not in the range 0 .. %d", maximum_prefix);
1093		return NULL;
1094	} else if (*end != '\0') {
1095		zc_error("invalid prefix '%s'", slash + 1);
1096		return NULL;
1097	}
1098	prefix = (uint8_t) p;
1099
1100	rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length)
1101		    + length);
1102	r = alloc_rdata(region, rdlength);
1103	t = (uint8_t *) (r + 1);
1104
1105	memcpy(t, &address_family, sizeof(address_family));
1106	t += sizeof(address_family);
1107	memcpy(t, &prefix, sizeof(prefix));
1108	t += sizeof(prefix);
1109	memcpy(t, &length, sizeof(length));
1110	if (negated) {
1111		*t |= APL_NEGATION_MASK;
1112	}
1113	t += sizeof(length);
1114	memcpy(t, address, length);
1115
1116	return r;
1117}
1118
1119/*
1120 * Below some function that also convert but not to wireformat
1121 * but to "normal" (int,long,char) types
1122 */
1123
1124uint32_t
1125zparser_ttl2int(const char *ttlstr, int* error)
1126{
1127	/* convert a ttl value to a integer
1128	 * return the ttl in a int
1129	 * -1 on error
1130	 */
1131
1132	uint32_t ttl;
1133	const char *t;
1134
1135	ttl = strtottl(ttlstr, &t);
1136	if (*t != 0) {
1137		zc_error_prev_line("invalid TTL value: %s",ttlstr);
1138		*error = 1;
1139	}
1140
1141	return ttl;
1142}
1143
1144
1145void
1146zadd_rdata_wireformat(uint16_t *data)
1147{
1148	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1149		zc_error_prev_line("too many rdata elements");
1150	} else {
1151		parser->current_rr.rdatas[parser->current_rr.rdata_count].data
1152			= data;
1153		++parser->current_rr.rdata_count;
1154	}
1155}
1156
1157/**
1158 * Used for TXT RR's to grow with undefined number of strings.
1159 */
1160void
1161zadd_rdata_txt_wireformat(uint16_t *data, int first)
1162{
1163	rdata_atom_type *rd;
1164	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1165		zc_error_prev_line("too many rdata txt elements");
1166		return;
1167	}
1168
1169	/* First STR in str_seq, allocate 65K in first unused rdata
1170	 * else find last used rdata */
1171	if (first) {
1172		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count];
1173		if ((rd->data = (uint16_t *) region_alloc(parser->rr_region,
1174			sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) {
1175			zc_error_prev_line("Could not allocate memory for TXT RR");
1176			return;
1177		}
1178		parser->current_rr.rdata_count++;
1179		rd->data[0] = 0;
1180	}
1181	else
1182		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1183
1184	if ((size_t)rd->data[0] + (size_t)data[0] > 65535) {
1185		zc_error_prev_line("too large rdata element");
1186		return;
1187	}
1188
1189	memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]);
1190	rd->data[0] += data[0];
1191}
1192
1193/**
1194 * Clean up after last call of zadd_rdata_txt_wireformat
1195 */
1196void
1197zadd_rdata_txt_clean_wireformat()
1198{
1199	uint16_t *tmp_data;
1200	rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1201	if(!rd || !rd->data)
1202		return; /* previous syntax failure */
1203	if ((tmp_data = (uint16_t *) region_alloc(parser->region,
1204		((size_t)rd->data[0]) + ((size_t)2))) != NULL) {
1205		memcpy(tmp_data, rd->data, rd->data[0] + 2);
1206		/* rd->data of u16+65535 freed when rr_region is freed */
1207		rd->data = tmp_data;
1208	}
1209	else {
1210		/* We could not get memory in non-volatile region */
1211		zc_error_prev_line("could not allocate memory for rdata");
1212		return;
1213	}
1214}
1215
1216void
1217zadd_rdata_domain(domain_type *domain)
1218{
1219	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1220		zc_error_prev_line("too many rdata elements");
1221	} else {
1222		parser->current_rr.rdatas[parser->current_rr.rdata_count].domain
1223			= domain;
1224		domain->usage ++; /* new reference to domain */
1225		++parser->current_rr.rdata_count;
1226	}
1227}
1228
1229void
1230parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
1231{
1232	buffer_type packet;
1233	uint16_t size;
1234	ssize_t rdata_count;
1235	ssize_t i;
1236	rdata_atom_type *rdatas;
1237
1238	if (wireformat) {
1239		size = *wireformat;
1240	} else {
1241		return;
1242	}
1243
1244	buffer_create_from(&packet, wireformat + 1, *wireformat);
1245	rdata_count = rdata_wireformat_to_rdata_atoms(parser->region,
1246						      parser->db->domains,
1247						      type,
1248						      size,
1249						      &packet,
1250						      &rdatas);
1251	if (rdata_count == -1) {
1252		zc_error_prev_line("bad unknown RDATA");
1253		return;
1254	}
1255
1256	for (i = 0; i < rdata_count; ++i) {
1257		if (rdata_atom_is_domain(type, i)) {
1258			zadd_rdata_domain(rdatas[i].domain);
1259		} else {
1260			zadd_rdata_wireformat(rdatas[i].data);
1261		}
1262	}
1263}
1264
1265
1266/*
1267 * Compares two rdata arrays.
1268 *
1269 * Returns:
1270 *
1271 *	zero if they are equal
1272 *	non-zero if not
1273 *
1274 */
1275static int
1276zrdatacmp(uint16_t type, rr_type *a, rr_type *b)
1277{
1278	int i = 0;
1279
1280	assert(a);
1281	assert(b);
1282
1283	/* One is shorter than another */
1284	if (a->rdata_count != b->rdata_count)
1285		return 1;
1286
1287	/* Compare element by element */
1288	for (i = 0; i < a->rdata_count; ++i) {
1289		if (rdata_atom_is_domain(type, i)) {
1290			if (rdata_atom_domain(a->rdatas[i])
1291			    != rdata_atom_domain(b->rdatas[i]))
1292			{
1293				return 1;
1294			}
1295		} else if(rdata_atom_is_literal_domain(type, i)) {
1296			if (rdata_atom_size(a->rdatas[i])
1297			    != rdata_atom_size(b->rdatas[i]))
1298				return 1;
1299			if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]),
1300				   rdata_atom_data(b->rdatas[i]),
1301				   rdata_atom_size(a->rdatas[i])))
1302				return 1;
1303		} else {
1304			if (rdata_atom_size(a->rdatas[i])
1305			    != rdata_atom_size(b->rdatas[i]))
1306			{
1307				return 1;
1308			}
1309			if (memcmp(rdata_atom_data(a->rdatas[i]),
1310				   rdata_atom_data(b->rdatas[i]),
1311				   rdata_atom_size(a->rdatas[i])) != 0)
1312			{
1313				return 1;
1314			}
1315		}
1316	}
1317
1318	/* Otherwise they are equal */
1319	return 0;
1320}
1321
1322/*
1323 *
1324 * Opens a zone file.
1325 *
1326 * Returns:
1327 *
1328 *	- pointer to the parser structure
1329 *	- NULL on error and errno set
1330 *
1331 */
1332static int
1333zone_open(const char *filename, uint32_t ttl, uint16_t klass,
1334	  const dname_type *origin)
1335{
1336	/* Open the zone file... */
1337	if (strcmp(filename, "-") == 0) {
1338		yyin = stdin;
1339		filename = "<stdin>";
1340	} else if (!(yyin = fopen(filename, "r"))) {
1341		return 0;
1342	}
1343
1344	zparser_init(filename, ttl, klass, origin);
1345
1346	return 1;
1347}
1348
1349
1350void
1351set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],
1352	    uint16_t index)
1353{
1354	/*
1355	 * The bits are counted from left to right, so bit #0 is the
1356	 * left most bit.
1357	 */
1358	uint8_t window = index / 256;
1359	uint8_t bit = index % 256;
1360
1361	bits[window][bit / 8] |= (1 << (7 - bit % 8));
1362}
1363
1364
1365static int
1366has_soa(domain_type* domain)
1367{
1368	rrset_type* p = NULL;
1369	if(!domain) return 0;
1370	for(p = domain->rrsets; p; p = p->next)
1371		if(rrset_rrtype(p) == TYPE_SOA)
1372			return 1;
1373	return 0;
1374}
1375
1376int
1377process_rr(void)
1378{
1379	zone_type *zone = parser->current_zone;
1380	rr_type *rr = &parser->current_rr;
1381	rrset_type *rrset;
1382	size_t max_rdlength;
1383	int i;
1384	rrtype_descriptor_type *descriptor
1385		= rrtype_descriptor_by_type(rr->type);
1386
1387	/* We only support IN class */
1388	if (rr->klass != CLASS_IN) {
1389		if(zone_is_slave(zone->opts))
1390			zc_warning_prev_line("only class IN is supported");
1391		else
1392			zc_error_prev_line("only class IN is supported");
1393		return 0;
1394	}
1395
1396	/* Make sure the maximum RDLENGTH does not exceed 65535 bytes.	*/
1397	max_rdlength = rdata_maximum_wireformat_size(
1398		descriptor, rr->rdata_count, rr->rdatas);
1399
1400	if (max_rdlength > MAX_RDLENGTH) {
1401		zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH);
1402		return 0;
1403	}
1404	/* we have the zone already */
1405	assert(zone);
1406	if (rr->type == TYPE_SOA) {
1407		if (rr->owner != zone->apex) {
1408			zc_error_prev_line(
1409				"SOA record with invalid domain name");
1410			return 0;
1411		}
1412		if(has_soa(rr->owner)) {
1413			if(zone_is_slave(zone->opts))
1414				zc_warning_prev_line("this SOA record was already encountered");
1415			else
1416				zc_error_prev_line("this SOA record was already encountered");
1417			return 0;
1418		}
1419		rr->owner->is_apex = 1;
1420	}
1421
1422	if (!domain_is_subdomain(rr->owner, zone->apex))
1423	{
1424		if(zone_is_slave(zone->opts))
1425			zc_warning_prev_line("out of zone data");
1426		else
1427			zc_error_prev_line("out of zone data");
1428		return 0;
1429	}
1430
1431	/* Do we have this type of rrset already? */
1432	rrset = domain_find_rrset(rr->owner, zone, rr->type);
1433	if (!rrset) {
1434		rrset = (rrset_type *) region_alloc(parser->region,
1435						    sizeof(rrset_type));
1436		rrset->zone = zone;
1437		rrset->rr_count = 1;
1438		rrset->rrs = (rr_type *) region_alloc(parser->region,
1439						      sizeof(rr_type));
1440		rrset->rrs[0] = *rr;
1441
1442		/* Add it */
1443		domain_add_rrset(rr->owner, rrset);
1444	} else {
1445		rr_type* o;
1446		if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) {
1447			zc_warning_prev_line(
1448				"%s TTL %u does not match the TTL %u of the %s RRset",
1449				domain_to_string(rr->owner), (unsigned)rr->ttl,
1450				(unsigned)rrset->rrs[0].ttl,
1451				rrtype_to_string(rr->type));
1452		}
1453
1454		/* Search for possible duplicates... */
1455		for (i = 0; i < rrset->rr_count; i++) {
1456			if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) {
1457				break;
1458			}
1459		}
1460
1461		/* Discard the duplicates... */
1462		if (i < rrset->rr_count) {
1463			return 0;
1464		}
1465		if(rrset->rr_count == 65535) {
1466			zc_error_prev_line("too many RRs for domain RRset");
1467			return 0;
1468		}
1469
1470		/* Add it... */
1471		o = rrset->rrs;
1472		rrset->rrs = (rr_type *) region_alloc_array(parser->region,
1473			(rrset->rr_count + 1), sizeof(rr_type));
1474		memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type));
1475		region_recycle(parser->region, o,
1476			(rrset->rr_count) * sizeof(rr_type));
1477		rrset->rrs[rrset->rr_count] = *rr;
1478		++rrset->rr_count;
1479	}
1480
1481	if(rr->type == TYPE_DNAME && rrset->rr_count > 1) {
1482		if(zone_is_slave(zone->opts))
1483			zc_warning_prev_line("multiple DNAMEs at the same name");
1484		else
1485			zc_error_prev_line("multiple DNAMEs at the same name");
1486	}
1487	if(rr->type == TYPE_CNAME && rrset->rr_count > 1) {
1488		if(zone_is_slave(zone->opts))
1489			zc_warning_prev_line("multiple CNAMEs at the same name");
1490		else
1491			zc_error_prev_line("multiple CNAMEs at the same name");
1492	}
1493	if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME))
1494	 ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) {
1495		if(zone_is_slave(zone->opts))
1496			zc_warning_prev_line("DNAME and CNAME at the same name");
1497		else
1498			zc_error_prev_line("DNAME and CNAME at the same name");
1499	}
1500	if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) &&
1501		domain_find_non_cname_rrset(rr->owner, zone)) {
1502		if(zone_is_slave(zone->opts))
1503			zc_warning_prev_line("CNAME and other data at the same name");
1504		else
1505			zc_error_prev_line("CNAME and other data at the same name");
1506	}
1507
1508	/* Check we have SOA */
1509	if(rr->owner == zone->apex)
1510		apex_rrset_checks(parser->db, rrset, rr->owner);
1511
1512	if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) {
1513		struct stat buf;
1514		startzonec = time(NULL);
1515		buf.st_size = 0;
1516		fstat(fileno(yyin), &buf);
1517		if(buf.st_size == 0) buf.st_size = 1;
1518		VERBOSITY(1, (LOG_INFO, "parse %s %d %%",
1519			parser->current_zone->opts->name,
1520			(int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size)));
1521	}
1522	++totalrrs;
1523	return 1;
1524}
1525
1526/*
1527 * Find rrset type for any zone
1528 */
1529static rrset_type*
1530domain_find_rrset_any(domain_type *domain, uint16_t type)
1531{
1532	rrset_type *result = domain->rrsets;
1533	while (result) {
1534		if (rrset_rrtype(result) == type) {
1535			return result;
1536		}
1537		result = result->next;
1538	}
1539	return NULL;
1540}
1541
1542/*
1543 * Check for DNAME type. Nothing is allowed below it
1544 */
1545static void
1546check_dname(zone_type* zone)
1547{
1548	domain_type* domain;
1549	for(domain = zone->apex; domain && domain_is_subdomain(domain,
1550		zone->apex); domain=domain_next(domain))
1551	{
1552		if(domain->is_existing) {
1553			/* there may not be DNAMEs above it */
1554			domain_type* parent = domain->parent;
1555#ifdef NSEC3
1556			if(domain_has_only_NSEC3(domain, NULL))
1557				continue;
1558#endif
1559			while(parent) {
1560				if(domain_find_rrset_any(parent, TYPE_DNAME)) {
1561					zc_error("While checking node %s,",
1562						domain_to_string(domain));
1563					zc_error("DNAME at %s has data below it. "
1564						"This is not allowed (rfc 2672).",
1565						domain_to_string(parent));
1566					return;
1567				}
1568				parent = parent->parent;
1569			}
1570		}
1571	}
1572}
1573
1574/*
1575 * Reads the specified zone into the memory
1576 * nsd_options can be NULL if no config file is passed.
1577 */
1578unsigned int
1579zonec_read(const char* name, const char* zonefile, zone_type* zone)
1580{
1581	const dname_type *dname;
1582
1583	totalrrs = 0;
1584	startzonec = time(NULL);
1585	parser->errors = 0;
1586
1587	dname = dname_parse(parser->rr_region, name);
1588	if (!dname) {
1589		zc_error("incorrect zone name '%s'", name);
1590		return 1;
1591	}
1592
1593#ifndef ROOT_SERVER
1594	/* Is it a root zone? Are we a root server then? Idiot proof. */
1595	if (dname->label_count == 1) {
1596		zc_error("not configured as a root server");
1597		return 1;
1598	}
1599#endif
1600
1601	/* Open the zone file */
1602	if (!zone_open(zonefile, 3600, CLASS_IN, dname)) {
1603		zc_error("cannot open '%s': %s", zonefile, strerror(errno));
1604		return 1;
1605	}
1606	parser->current_zone = zone;
1607
1608	/* Parse and process all RRs.  */
1609	yyparse();
1610
1611	/* remove origin if it was unused */
1612	if(parser->origin != error_domain)
1613		domain_table_deldomain(parser->db, parser->origin);
1614	/* rr_region has been emptied by now */
1615	dname = dname_parse(parser->rr_region, name);
1616
1617	/* check if zone file contained a correct SOA record */
1618	if (!parser->current_zone) {
1619		zc_error("zone configured as '%s' has no content.", name);
1620	} else if(!parser->current_zone->soa_rrset ||
1621		parser->current_zone->soa_rrset->rr_count == 0) {
1622		zc_error("zone configured as '%s' has no SOA record.", name);
1623	} else if(dname_compare(domain_dname(
1624		parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
1625		zc_error("zone configured as '%s', but SOA has owner '%s'.",
1626			name, domain_to_string(
1627			parser->current_zone->soa_rrset->rrs[0].owner));
1628	}
1629
1630	parser_flush();
1631	fclose(yyin);
1632	if(!zone_is_slave(zone->opts))
1633		check_dname(zone);
1634
1635	parser->filename = NULL;
1636	return parser->errors;
1637}
1638
1639
1640/*
1641 * setup parse
1642 */
1643void
1644zonec_setup_parser(namedb_type* db)
1645{
1646	region_type* rr_region = region_create(xalloc, free);
1647	parser = zparser_create(db->region, rr_region, db);
1648	assert(parser);
1649	/* Unique pointers used to mark errors.	 */
1650	error_dname = (dname_type *) region_alloc(db->region, 1);
1651	error_domain = (domain_type *) region_alloc(db->region, 1);
1652	/* Open the network database */
1653	setprotoent(1);
1654	setservent(1);
1655}
1656
1657/** desetup parse */
1658void
1659zonec_desetup_parser(void)
1660{
1661	if(parser) {
1662		endservent();
1663		endprotoent();
1664		region_destroy(parser->rr_region);
1665		/* removed when parser->region(=db->region) is destroyed:
1666		 * region_recycle(parser->region, (void*)error_dname, 1);
1667		 * region_recycle(parser->region, (void*)error_domain, 1); */
1668		/* clear memory for exit, but this is not portable to
1669		 * other versions of lex. yylex_destroy(); */
1670	}
1671}
1672
1673static domain_table_type* orig_domains = NULL;
1674static region_type* orig_region = NULL;
1675static region_type* orig_dbregion = NULL;
1676
1677/** setup for string parse */
1678void
1679zonec_setup_string_parser(region_type* region, domain_table_type* domains)
1680{
1681	assert(parser); /* global parser must be setup */
1682	orig_domains = parser->db->domains;
1683	orig_region = parser->region;
1684	orig_dbregion = parser->db->region;
1685	parser->region = region;
1686	parser->db->region = region;
1687	parser->db->domains = domains;
1688	zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root));
1689}
1690
1691/** desetup string parse */
1692void
1693zonec_desetup_string_parser(void)
1694{
1695	parser->region = orig_region;
1696	parser->db->domains = orig_domains;
1697	parser->db->region = orig_dbregion;
1698}
1699
1700/** parse a string into temporary storage */
1701int
1702zonec_parse_string(region_type* region, domain_table_type* domains,
1703	zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
1704{
1705	int errors;
1706	zonec_setup_string_parser(region, domains);
1707	parser->current_zone = zone;
1708	parser->errors = 0;
1709	totalrrs = 0;
1710	startzonec = time(NULL)+100000; /* disable */
1711	parser_push_stringbuf(str);
1712	yyparse();
1713	parser_pop_stringbuf();
1714	errors = parser->errors;
1715	*num_rrs = totalrrs;
1716	if(*num_rrs == 0)
1717		*parsed = NULL;
1718	else	*parsed = parser->prev_dname;
1719	/* remove origin if it was not used during the parse */
1720	if(parser->origin != error_domain)
1721		domain_table_deldomain(parser->db, parser->origin);
1722	zonec_desetup_string_parser();
1723	parser_flush();
1724	return errors;
1725}
1726