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