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, °, "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