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