1 %{ 2 /* 3 * zyparser.y -- yacc grammar for (DNS) zone files 4 * 5 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 6 * 7 * See LICENSE for the license. 8 * 9 */ 10 11 #include "config.h" 12 13 #include <stdarg.h> 14 #include <stdio.h> 15 #include <string.h> 16 17 #include "dname.h" 18 #include "namedb.h" 19 #include "zonec.h" 20 21 /* these need to be global, otherwise they cannot be used inside yacc */ 22 zparser_type *parser; 23 24 #ifdef __cplusplus 25 extern "C" 26 #endif /* __cplusplus */ 27 int yywrap(void); 28 29 /* this hold the nxt bits */ 30 static uint8_t nxtbits[16]; 31 static int dlv_warn = 1; 32 33 /* 256 windows of 256 bits (32 bytes) */ 34 /* still need to reset the bastard somewhere */ 35 static uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]; 36 37 /* hold the highest rcode seen in a NSEC rdata , BUG #106 */ 38 uint16_t nsec_highest_rcode; 39 40 void yyerror(const char *message); 41 42 #ifdef NSEC3 43 /* parse nsec3 parameters and add the (first) rdata elements */ 44 static void 45 nsec3_add_params(const char* hash_algo_str, const char* flag_str, 46 const char* iter_str, const char* salt_str, int salt_len); 47 #endif /* NSEC3 */ 48 49 %} 50 %union { 51 domain_type *domain; 52 const dname_type *dname; 53 struct lex_data data; 54 uint32_t ttl; 55 uint16_t klass; 56 uint16_t type; 57 uint16_t *unknown; 58 } 59 60 /* 61 * Tokens to represent the known RR types of DNS. 62 */ 63 %token <type> T_A T_NS T_MX T_TXT T_CNAME T_AAAA T_PTR T_NXT T_KEY T_SOA T_SIG 64 %token <type> T_SRV T_CERT T_LOC T_MD T_MF T_MB T_MG T_MR T_NULL T_WKS T_HINFO 65 %token <type> T_MINFO T_RP T_AFSDB T_X25 T_ISDN T_RT T_NSAP T_NSAP_PTR T_PX 66 %token <type> T_GPOS T_EID T_NIMLOC T_ATMA T_NAPTR T_KX T_A6 T_DNAME T_SINK 67 %token <type> T_OPT T_APL T_UINFO T_UID T_GID T_UNSPEC T_TKEY T_TSIG T_IXFR 68 %token <type> T_AXFR T_MAILB T_MAILA T_DS T_DLV T_SSHFP T_RRSIG T_NSEC T_DNSKEY 69 %token <type> T_SPF T_NSEC3 T_IPSECKEY T_DHCID T_NSEC3PARAM T_TLSA T_URI 70 %token <type> T_NID T_L32 T_L64 T_LP T_EUI48 T_EUI64 T_CAA T_CDS T_CDNSKEY 71 %token <type> T_CSYNC 72 73 /* other tokens */ 74 %token DOLLAR_TTL DOLLAR_ORIGIN NL SP 75 %token <data> STR PREV BITLAB 76 %token <ttl> T_TTL 77 %token <klass> T_RRCLASS 78 79 /* unknown RRs */ 80 %token URR 81 %token <type> T_UTYPE 82 83 %type <type> type_and_rdata 84 %type <domain> owner dname abs_dname 85 %type <dname> rel_dname label 86 %type <data> wire_dname wire_abs_dname wire_rel_dname wire_label 87 %type <data> concatenated_str_seq str_sp_seq str_dot_seq dotted_str 88 %type <data> nxt_seq nsec_more 89 %type <unknown> rdata_unknown 90 91 %% 92 lines: /* empty file */ 93 | lines line 94 ; 95 96 line: NL 97 | sp NL 98 | PREV NL {} /* Lines containing only whitespace. */ 99 | ttl_directive 100 { 101 region_free_all(parser->rr_region); 102 parser->current_rr.type = 0; 103 parser->current_rr.rdata_count = 0; 104 parser->current_rr.rdatas = parser->temporary_rdatas; 105 parser->error_occurred = 0; 106 } 107 | origin_directive 108 { 109 region_free_all(parser->rr_region); 110 parser->current_rr.type = 0; 111 parser->current_rr.rdata_count = 0; 112 parser->current_rr.rdatas = parser->temporary_rdatas; 113 parser->error_occurred = 0; 114 } 115 | rr 116 { /* rr should be fully parsed */ 117 if (!parser->error_occurred) { 118 parser->current_rr.rdatas 119 =(rdata_atom_type *)region_alloc_array_init( 120 parser->region, 121 parser->current_rr.rdatas, 122 parser->current_rr.rdata_count, 123 sizeof(rdata_atom_type)); 124 125 process_rr(); 126 } 127 128 region_free_all(parser->rr_region); 129 130 parser->current_rr.type = 0; 131 parser->current_rr.rdata_count = 0; 132 parser->current_rr.rdatas = parser->temporary_rdatas; 133 parser->error_occurred = 0; 134 } 135 | error NL 136 ; 137 138 /* needed to cope with ( and ) in arbitrary places */ 139 sp: SP 140 | sp SP 141 ; 142 143 trail: NL 144 | sp NL 145 ; 146 147 ttl_directive: DOLLAR_TTL sp STR trail 148 { 149 parser->default_ttl = zparser_ttl2int($3.str, &(parser->error_occurred)); 150 if (parser->error_occurred == 1) { 151 parser->default_ttl = DEFAULT_TTL; 152 parser->error_occurred = 0; 153 } 154 } 155 ; 156 157 origin_directive: DOLLAR_ORIGIN sp abs_dname trail 158 { 159 /* if previous origin is unused, remove it, do not leak it */ 160 if(parser->origin != error_domain && parser->origin != $3) { 161 /* protect $3 from deletion, because deldomain walks up */ 162 $3->usage ++; 163 domain_table_deldomain(parser->db, parser->origin); 164 $3->usage --; 165 } 166 parser->origin = $3; 167 } 168 | DOLLAR_ORIGIN sp rel_dname trail 169 { 170 zc_error_prev_line("$ORIGIN directive requires absolute domain name"); 171 } 172 ; 173 174 rr: owner classttl type_and_rdata 175 { 176 parser->current_rr.owner = $1; 177 parser->current_rr.type = $3; 178 } 179 ; 180 181 owner: dname sp 182 { 183 parser->prev_dname = $1; 184 $$ = $1; 185 } 186 | PREV 187 { 188 $$ = parser->prev_dname; 189 } 190 ; 191 192 classttl: /* empty - fill in the default, def. ttl and IN class */ 193 { 194 parser->current_rr.ttl = parser->default_ttl; 195 parser->current_rr.klass = parser->default_class; 196 } 197 | T_RRCLASS sp /* no ttl */ 198 { 199 parser->current_rr.ttl = parser->default_ttl; 200 parser->current_rr.klass = $1; 201 } 202 | T_TTL sp /* no class */ 203 { 204 parser->current_rr.ttl = $1; 205 parser->current_rr.klass = parser->default_class; 206 } 207 | T_TTL sp T_RRCLASS sp /* the lot */ 208 { 209 parser->current_rr.ttl = $1; 210 parser->current_rr.klass = $3; 211 } 212 | T_RRCLASS sp T_TTL sp /* the lot - reversed */ 213 { 214 parser->current_rr.ttl = $3; 215 parser->current_rr.klass = $1; 216 } 217 ; 218 219 dname: abs_dname 220 | rel_dname 221 { 222 if ($1 == error_dname) { 223 $$ = error_domain; 224 } else if(parser->origin == error_domain) { 225 zc_error("cannot concatenate origin to domain name, because origin failed to parse"); 226 $$ = error_domain; 227 } else if ($1->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) { 228 zc_error("domain name exceeds %d character limit", MAXDOMAINLEN); 229 $$ = error_domain; 230 } else { 231 $$ = domain_table_insert( 232 parser->db->domains, 233 dname_concatenate( 234 parser->rr_region, 235 $1, 236 domain_dname(parser->origin))); 237 } 238 } 239 ; 240 241 abs_dname: '.' 242 { 243 $$ = parser->db->domains->root; 244 } 245 | '@' 246 { 247 $$ = parser->origin; 248 } 249 | rel_dname '.' 250 { 251 if ($1 != error_dname) { 252 $$ = domain_table_insert(parser->db->domains, $1); 253 } else { 254 $$ = error_domain; 255 } 256 } 257 ; 258 259 label: STR 260 { 261 if ($1.len > MAXLABELLEN) { 262 zc_error("label exceeds %d character limit", MAXLABELLEN); 263 $$ = error_dname; 264 } else if ($1.len <= 0) { 265 zc_error("zero label length"); 266 $$ = error_dname; 267 } else { 268 $$ = dname_make_from_label(parser->rr_region, 269 (uint8_t *) $1.str, 270 $1.len); 271 } 272 } 273 | BITLAB 274 { 275 zc_error("bitlabels are now deprecated. RFC2673 is obsoleted."); 276 $$ = error_dname; 277 } 278 ; 279 280 rel_dname: label 281 | rel_dname '.' label 282 { 283 if ($1 == error_dname || $3 == error_dname) { 284 $$ = error_dname; 285 } else if ($1->name_size + $3->name_size - 1 > MAXDOMAINLEN) { 286 zc_error("domain name exceeds %d character limit", 287 MAXDOMAINLEN); 288 $$ = error_dname; 289 } else { 290 $$ = dname_concatenate(parser->rr_region, $1, $3); 291 } 292 } 293 ; 294 295 /* 296 * Some dnames in rdata are handled as opaque blobs 297 */ 298 299 wire_dname: wire_abs_dname 300 | wire_rel_dname 301 ; 302 303 wire_abs_dname: '.' 304 { 305 char *result = (char *) region_alloc(parser->rr_region, 2); 306 result[0] = 0; 307 result[1] = '\0'; 308 $$.str = result; 309 $$.len = 1; 310 } 311 | wire_rel_dname '.' 312 { 313 char *result = (char *) region_alloc(parser->rr_region, 314 $1.len + 2); 315 memcpy(result, $1.str, $1.len); 316 result[$1.len] = 0; 317 result[$1.len+1] = '\0'; 318 $$.str = result; 319 $$.len = $1.len + 1; 320 } 321 ; 322 323 wire_label: STR 324 { 325 char *result = (char *) region_alloc(parser->rr_region, 326 $1.len + 1); 327 328 if ($1.len > MAXLABELLEN) 329 zc_error("label exceeds %d character limit", MAXLABELLEN); 330 331 /* make label anyway */ 332 result[0] = $1.len; 333 memcpy(result+1, $1.str, $1.len); 334 335 $$.str = result; 336 $$.len = $1.len + 1; 337 } 338 ; 339 340 wire_rel_dname: wire_label 341 | wire_rel_dname '.' wire_label 342 { 343 if ($1.len + $3.len - 3 > MAXDOMAINLEN) 344 zc_error("domain name exceeds %d character limit", 345 MAXDOMAINLEN); 346 347 /* make dname anyway */ 348 $$.len = $1.len + $3.len; 349 $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1); 350 memcpy($$.str, $1.str, $1.len); 351 memcpy($$.str + $1.len, $3.str, $3.len); 352 $$.str[$$.len] = '\0'; 353 } 354 ; 355 356 str_seq: dotted_str 357 { 358 zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1); 359 } 360 | str_seq sp dotted_str 361 { 362 zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0); 363 } 364 ; 365 366 /* 367 * Generate a single string from multiple STR tokens, separated by 368 * spaces or dots. 369 */ 370 concatenated_str_seq: STR 371 | '.' 372 { 373 $$.len = 1; 374 $$.str = region_strdup(parser->rr_region, "."); 375 } 376 | concatenated_str_seq sp STR 377 { 378 $$.len = $1.len + $3.len + 1; 379 $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1); 380 memcpy($$.str, $1.str, $1.len); 381 memcpy($$.str + $1.len, " ", 1); 382 memcpy($$.str + $1.len + 1, $3.str, $3.len); 383 $$.str[$$.len] = '\0'; 384 } 385 | concatenated_str_seq '.' STR 386 { 387 $$.len = $1.len + $3.len + 1; 388 $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1); 389 memcpy($$.str, $1.str, $1.len); 390 memcpy($$.str + $1.len, ".", 1); 391 memcpy($$.str + $1.len + 1, $3.str, $3.len); 392 $$.str[$$.len] = '\0'; 393 } 394 ; 395 396 /* used to convert a nxt list of types */ 397 nxt_seq: STR 398 { 399 uint16_t type = rrtype_from_string($1.str); 400 if (type != 0 && type < 128) { 401 set_bit(nxtbits, type); 402 } else { 403 zc_error("bad type %d in NXT record", (int) type); 404 } 405 } 406 | nxt_seq sp STR 407 { 408 uint16_t type = rrtype_from_string($3.str); 409 if (type != 0 && type < 128) { 410 set_bit(nxtbits, type); 411 } else { 412 zc_error("bad type %d in NXT record", (int) type); 413 } 414 } 415 ; 416 417 nsec_more: SP nsec_more 418 { 419 } 420 | NL 421 { 422 } 423 | STR nsec_seq 424 { 425 uint16_t type = rrtype_from_string($1.str); 426 if (type != 0) { 427 if (type > nsec_highest_rcode) { 428 nsec_highest_rcode = type; 429 } 430 set_bitnsec(nsecbits, type); 431 } else { 432 zc_error("bad type %d in NSEC record", (int) type); 433 } 434 } 435 ; 436 437 nsec_seq: NL 438 | SP nsec_more 439 ; 440 441 /* 442 * Sequence of STR tokens separated by spaces. The spaces are not 443 * preserved during concatenation. 444 */ 445 str_sp_seq: STR 446 | str_sp_seq sp STR 447 { 448 char *result = (char *) region_alloc(parser->rr_region, 449 $1.len + $3.len + 1); 450 memcpy(result, $1.str, $1.len); 451 memcpy(result + $1.len, $3.str, $3.len); 452 $$.str = result; 453 $$.len = $1.len + $3.len; 454 $$.str[$$.len] = '\0'; 455 } 456 ; 457 458 /* 459 * Sequence of STR tokens separated by dots. The dots are not 460 * preserved during concatenation. 461 */ 462 str_dot_seq: STR 463 | str_dot_seq '.' STR 464 { 465 char *result = (char *) region_alloc(parser->rr_region, 466 $1.len + $3.len + 1); 467 memcpy(result, $1.str, $1.len); 468 memcpy(result + $1.len, $3.str, $3.len); 469 $$.str = result; 470 $$.len = $1.len + $3.len; 471 $$.str[$$.len] = '\0'; 472 } 473 ; 474 475 /* 476 * A string that can contain dots. 477 */ 478 dotted_str: STR 479 | '.' 480 { 481 $$.str = "."; 482 $$.len = 1; 483 } 484 | dotted_str '.' 485 { 486 char *result = (char *) region_alloc(parser->rr_region, 487 $1.len + 2); 488 memcpy(result, $1.str, $1.len); 489 result[$1.len] = '.'; 490 $$.str = result; 491 $$.len = $1.len + 1; 492 $$.str[$$.len] = '\0'; 493 } 494 | dotted_str '.' STR 495 { 496 char *result = (char *) region_alloc(parser->rr_region, 497 $1.len + $3.len + 2); 498 memcpy(result, $1.str, $1.len); 499 result[$1.len] = '.'; 500 memcpy(result + $1.len + 1, $3.str, $3.len); 501 $$.str = result; 502 $$.len = $1.len + $3.len + 1; 503 $$.str[$$.len] = '\0'; 504 } 505 ; 506 507 /* define what we can parse */ 508 type_and_rdata: 509 /* 510 * All supported RR types. We don't support NULL and types marked obsolete. 511 */ 512 T_A sp rdata_a 513 | T_A sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 514 | T_NS sp rdata_domain_name 515 | T_NS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 516 | T_MD sp rdata_domain_name { zc_warning_prev_line("MD is obsolete"); } 517 | T_MD sp rdata_unknown 518 { 519 zc_warning_prev_line("MD is obsolete"); 520 $$ = $1; parse_unknown_rdata($1, $3); 521 } 522 | T_MF sp rdata_domain_name { zc_warning_prev_line("MF is obsolete"); } 523 | T_MF sp rdata_unknown 524 { 525 zc_warning_prev_line("MF is obsolete"); 526 $$ = $1; 527 parse_unknown_rdata($1, $3); 528 } 529 | T_CNAME sp rdata_domain_name 530 | T_CNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 531 | T_SOA sp rdata_soa 532 | T_SOA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 533 | T_MB sp rdata_domain_name { zc_warning_prev_line("MB is obsolete"); } 534 | T_MB sp rdata_unknown 535 { 536 zc_warning_prev_line("MB is obsolete"); 537 $$ = $1; 538 parse_unknown_rdata($1, $3); 539 } 540 | T_MG sp rdata_domain_name 541 | T_MG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 542 | T_MR sp rdata_domain_name 543 | T_MR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 544 /* NULL */ 545 | T_WKS sp rdata_wks 546 | T_WKS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 547 | T_PTR sp rdata_domain_name 548 | T_PTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 549 | T_HINFO sp rdata_hinfo 550 | T_HINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 551 | T_MINFO sp rdata_minfo /* Experimental */ 552 | T_MINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 553 | T_MX sp rdata_mx 554 | T_MX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 555 | T_TXT sp rdata_txt 556 | T_TXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 557 | T_SPF sp rdata_txt 558 | T_SPF sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 559 | T_RP sp rdata_rp /* RFC 1183 */ 560 | T_RP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 561 | T_AFSDB sp rdata_afsdb /* RFC 1183 */ 562 | T_AFSDB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 563 | T_X25 sp rdata_x25 /* RFC 1183 */ 564 | T_X25 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 565 | T_ISDN sp rdata_isdn /* RFC 1183 */ 566 | T_ISDN sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 567 | T_IPSECKEY sp rdata_ipseckey /* RFC 4025 */ 568 | T_IPSECKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 569 | T_DHCID sp rdata_dhcid 570 | T_DHCID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 571 | T_RT sp rdata_rt /* RFC 1183 */ 572 | T_RT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 573 | T_NSAP sp rdata_nsap /* RFC 1706 */ 574 | T_NSAP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 575 | T_SIG sp rdata_rrsig 576 | T_SIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 577 | T_KEY sp rdata_dnskey 578 | T_KEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 579 | T_PX sp rdata_px /* RFC 2163 */ 580 | T_PX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 581 | T_AAAA sp rdata_aaaa 582 | T_AAAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 583 | T_LOC sp rdata_loc 584 | T_LOC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 585 | T_NXT sp rdata_nxt 586 | T_NXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 587 | T_SRV sp rdata_srv 588 | T_SRV sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 589 | T_NAPTR sp rdata_naptr /* RFC 2915 */ 590 | T_NAPTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 591 | T_KX sp rdata_kx /* RFC 2230 */ 592 | T_KX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 593 | T_CERT sp rdata_cert /* RFC 2538 */ 594 | T_CERT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 595 | T_DNAME sp rdata_domain_name /* RFC 2672 */ 596 | T_DNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 597 | T_APL trail /* RFC 3123 */ 598 | T_APL sp rdata_apl /* RFC 3123 */ 599 | T_APL sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 600 | T_DS sp rdata_ds 601 | T_DS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 602 | T_DLV sp rdata_dlv { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } } 603 | T_DLV sp rdata_unknown { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } $$ = $1; parse_unknown_rdata($1, $3); } 604 | T_SSHFP sp rdata_sshfp 605 | T_SSHFP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 606 | T_RRSIG sp rdata_rrsig 607 | T_RRSIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 608 | T_NSEC sp rdata_nsec 609 | T_NSEC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 610 | T_NSEC3 sp rdata_nsec3 611 | T_NSEC3 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 612 | T_NSEC3PARAM sp rdata_nsec3_param 613 | T_NSEC3PARAM sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 614 | T_DNSKEY sp rdata_dnskey 615 | T_DNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 616 | T_TLSA sp rdata_tlsa 617 | T_TLSA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 618 | T_NID sp rdata_nid 619 | T_NID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 620 | T_L32 sp rdata_l32 621 | T_L32 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 622 | T_L64 sp rdata_l64 623 | T_L64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 624 | T_LP sp rdata_lp 625 | T_LP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 626 | T_EUI48 sp rdata_eui48 627 | T_EUI48 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 628 | T_EUI64 sp rdata_eui64 629 | T_EUI64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 630 | T_CAA sp rdata_caa 631 | T_CAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 632 | T_CDS sp rdata_ds 633 | T_CDS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 634 | T_CDNSKEY sp rdata_dnskey 635 | T_CDNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 636 | T_CSYNC sp rdata_csync 637 | T_CSYNC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 638 | T_URI sp rdata_uri 639 | T_URI sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 640 | T_UTYPE sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } 641 | STR error NL 642 { 643 zc_error_prev_line("unrecognized RR type '%s'", $1.str); 644 } 645 ; 646 647 /* 648 * 649 * below are all the definition for all the different rdata 650 * 651 */ 652 653 rdata_a: dotted_str trail 654 { 655 zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); 656 } 657 ; 658 659 rdata_domain_name: dname trail 660 { 661 /* convert a single dname record */ 662 zadd_rdata_domain($1); 663 } 664 ; 665 666 rdata_soa: dname sp dname sp STR sp STR sp STR sp STR sp STR trail 667 { 668 /* convert the soa data */ 669 zadd_rdata_domain($1); /* prim. ns */ 670 zadd_rdata_domain($3); /* email */ 671 zadd_rdata_wireformat(zparser_conv_serial(parser->region, $5.str)); /* serial */ 672 zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* refresh */ 673 zadd_rdata_wireformat(zparser_conv_period(parser->region, $9.str)); /* retry */ 674 zadd_rdata_wireformat(zparser_conv_period(parser->region, $11.str)); /* expire */ 675 zadd_rdata_wireformat(zparser_conv_period(parser->region, $13.str)); /* minimum */ 676 } 677 ; 678 679 rdata_wks: dotted_str sp STR sp concatenated_str_seq trail 680 { 681 zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); /* address */ 682 zadd_rdata_wireformat(zparser_conv_services(parser->region, $3.str, $5.str)); /* protocol and services */ 683 } 684 ; 685 686 rdata_hinfo: STR sp STR trail 687 { 688 zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* CPU */ 689 zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* OS*/ 690 } 691 ; 692 693 rdata_minfo: dname sp dname trail 694 { 695 /* convert a single dname record */ 696 zadd_rdata_domain($1); 697 zadd_rdata_domain($3); 698 } 699 ; 700 701 rdata_mx: STR sp dname trail 702 { 703 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */ 704 zadd_rdata_domain($3); /* MX host */ 705 } 706 ; 707 708 rdata_txt: str_seq trail 709 { 710 zadd_rdata_txt_clean_wireformat(); 711 } 712 ; 713 714 /* RFC 1183 */ 715 rdata_rp: dname sp dname trail 716 { 717 zadd_rdata_domain($1); /* mbox d-name */ 718 zadd_rdata_domain($3); /* txt d-name */ 719 } 720 ; 721 722 /* RFC 1183 */ 723 rdata_afsdb: STR sp dname trail 724 { 725 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* subtype */ 726 zadd_rdata_domain($3); /* domain name */ 727 } 728 ; 729 730 /* RFC 1183 */ 731 rdata_x25: STR trail 732 { 733 zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* X.25 address. */ 734 } 735 ; 736 737 /* RFC 1183 */ 738 rdata_isdn: STR trail 739 { 740 zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */ 741 } 742 | STR sp STR trail 743 { 744 zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */ 745 zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* sub-address */ 746 } 747 ; 748 749 /* RFC 1183 */ 750 rdata_rt: STR sp dname trail 751 { 752 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ 753 zadd_rdata_domain($3); /* intermediate host */ 754 } 755 ; 756 757 /* RFC 1706 */ 758 rdata_nsap: str_dot_seq trail 759 { 760 /* String must start with "0x" or "0X". */ 761 if (strncasecmp($1.str, "0x", 2) != 0) { 762 zc_error_prev_line("NSAP rdata must start with '0x'"); 763 } else { 764 zadd_rdata_wireformat(zparser_conv_hex(parser->region, $1.str + 2, $1.len - 2)); /* NSAP */ 765 } 766 } 767 ; 768 769 /* RFC 2163 */ 770 rdata_px: STR sp dname sp dname trail 771 { 772 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ 773 zadd_rdata_domain($3); /* MAP822 */ 774 zadd_rdata_domain($5); /* MAPX400 */ 775 } 776 ; 777 778 rdata_aaaa: dotted_str trail 779 { 780 zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $1.str)); /* IPv6 address */ 781 } 782 ; 783 784 rdata_loc: concatenated_str_seq trail 785 { 786 zadd_rdata_wireformat(zparser_conv_loc(parser->region, $1.str)); /* Location */ 787 } 788 ; 789 790 rdata_nxt: dname sp nxt_seq trail 791 { 792 zadd_rdata_domain($1); /* nxt name */ 793 zadd_rdata_wireformat(zparser_conv_nxt(parser->region, nxtbits)); /* nxt bitlist */ 794 memset(nxtbits, 0, sizeof(nxtbits)); 795 } 796 ; 797 798 rdata_srv: STR sp STR sp STR sp dname trail 799 { 800 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* prio */ 801 zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */ 802 zadd_rdata_wireformat(zparser_conv_short(parser->region, $5.str)); /* port */ 803 zadd_rdata_domain($7); /* target name */ 804 } 805 ; 806 807 /* RFC 2915 */ 808 rdata_naptr: STR sp STR sp STR sp STR sp STR sp dname trail 809 { 810 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* order */ 811 zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* preference */ 812 zadd_rdata_wireformat(zparser_conv_text(parser->region, $5.str, $5.len)); /* flags */ 813 zadd_rdata_wireformat(zparser_conv_text(parser->region, $7.str, $7.len)); /* service */ 814 zadd_rdata_wireformat(zparser_conv_text(parser->region, $9.str, $9.len)); /* regexp */ 815 zadd_rdata_domain($11); /* target name */ 816 } 817 ; 818 819 /* RFC 2230 */ 820 rdata_kx: STR sp dname trail 821 { 822 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ 823 zadd_rdata_domain($3); /* exchanger */ 824 } 825 ; 826 827 /* RFC 2538 */ 828 rdata_cert: STR sp STR sp STR sp str_sp_seq trail 829 { 830 zadd_rdata_wireformat(zparser_conv_certificate_type(parser->region, $1.str)); /* type */ 831 zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* key tag */ 832 zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* algorithm */ 833 zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* certificate or CRL */ 834 } 835 ; 836 837 /* RFC 3123 */ 838 rdata_apl: rdata_apl_seq trail 839 ; 840 841 rdata_apl_seq: dotted_str 842 { 843 zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $1.str)); 844 } 845 | rdata_apl_seq sp dotted_str 846 { 847 zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $3.str)); 848 } 849 ; 850 851 rdata_ds: STR sp STR sp STR sp str_sp_seq trail 852 { 853 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */ 854 zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */ 855 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */ 856 zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */ 857 } 858 ; 859 860 rdata_dlv: STR sp STR sp STR sp str_sp_seq trail 861 { 862 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */ 863 zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */ 864 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */ 865 zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */ 866 } 867 ; 868 869 rdata_sshfp: STR sp STR sp str_sp_seq trail 870 { 871 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* alg */ 872 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* fp type */ 873 zadd_rdata_wireformat(zparser_conv_hex(parser->region, $5.str, $5.len)); /* hash */ 874 } 875 ; 876 877 rdata_dhcid: str_sp_seq trail 878 { 879 zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str)); /* data blob */ 880 } 881 ; 882 883 rdata_rrsig: STR sp STR sp STR sp STR sp STR sp STR sp STR sp wire_dname sp str_sp_seq trail 884 { 885 zadd_rdata_wireformat(zparser_conv_rrtype(parser->region, $1.str)); /* rr covered */ 886 zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */ 887 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* # labels */ 888 zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* # orig TTL */ 889 zadd_rdata_wireformat(zparser_conv_time(parser->region, $9.str)); /* sig exp */ 890 zadd_rdata_wireformat(zparser_conv_time(parser->region, $11.str)); /* sig inc */ 891 zadd_rdata_wireformat(zparser_conv_short(parser->region, $13.str)); /* key id */ 892 zadd_rdata_wireformat(zparser_conv_dns_name(parser->region, 893 (const uint8_t*) $15.str,$15.len)); /* sig name */ 894 zadd_rdata_wireformat(zparser_conv_b64(parser->region, $17.str)); /* sig data */ 895 } 896 ; 897 898 rdata_nsec: wire_dname nsec_seq 899 { 900 zadd_rdata_wireformat(zparser_conv_dns_name(parser->region, 901 (const uint8_t*) $1.str, $1.len)); /* nsec name */ 902 zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */ 903 memset(nsecbits, 0, sizeof(nsecbits)); 904 nsec_highest_rcode = 0; 905 } 906 ; 907 908 rdata_nsec3: STR sp STR sp STR sp STR sp STR nsec_seq 909 { 910 #ifdef NSEC3 911 nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len); 912 913 zadd_rdata_wireformat(zparser_conv_b32(parser->region, $9.str)); /* next hashed name */ 914 zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */ 915 memset(nsecbits, 0, sizeof(nsecbits)); 916 nsec_highest_rcode = 0; 917 #else 918 zc_error_prev_line("nsec3 not supported"); 919 #endif /* NSEC3 */ 920 } 921 ; 922 923 rdata_nsec3_param: STR sp STR sp STR sp STR trail 924 { 925 #ifdef NSEC3 926 nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len); 927 #else 928 zc_error_prev_line("nsec3 not supported"); 929 #endif /* NSEC3 */ 930 } 931 ; 932 933 rdata_tlsa: STR sp STR sp STR sp str_sp_seq trail 934 { 935 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */ 936 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */ 937 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */ 938 zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */ 939 } 940 ; 941 942 rdata_dnskey: STR sp STR sp STR sp str_sp_seq trail 943 { 944 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* flags */ 945 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* proto */ 946 zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* alg */ 947 zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* hash */ 948 } 949 ; 950 951 rdata_ipsec_base: STR sp STR sp STR sp dotted_str 952 { 953 const dname_type* name = 0; 954 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* precedence */ 955 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* gateway type */ 956 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* algorithm */ 957 switch(atoi($3.str)) { 958 case IPSECKEY_NOGATEWAY: 959 zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 0)); 960 break; 961 case IPSECKEY_IP4: 962 zadd_rdata_wireformat(zparser_conv_a(parser->region, $7.str)); 963 break; 964 case IPSECKEY_IP6: 965 zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $7.str)); 966 break; 967 case IPSECKEY_DNAME: 968 /* convert and insert the dname */ 969 if(strlen($7.str) == 0) 970 zc_error_prev_line("IPSECKEY must specify gateway name"); 971 if(!(name = dname_parse(parser->region, $7.str))) 972 zc_error_prev_line("IPSECKEY bad gateway dname %s", $7.str); 973 if($7.str[strlen($7.str)-1] != '.') { 974 if(parser->origin == error_domain) { 975 zc_error("cannot concatenate origin to domain name, because origin failed to parse"); 976 break; 977 } 978 name = dname_concatenate(parser->rr_region, name, 979 domain_dname(parser->origin)); 980 } 981 zadd_rdata_wireformat(alloc_rdata_init(parser->region, 982 dname_name(name), name->name_size)); 983 break; 984 default: 985 zc_error_prev_line("unknown IPSECKEY gateway type"); 986 } 987 } 988 ; 989 990 rdata_ipseckey: rdata_ipsec_base sp str_sp_seq trail 991 { 992 zadd_rdata_wireformat(zparser_conv_b64(parser->region, $3.str)); /* public key */ 993 } 994 | rdata_ipsec_base trail 995 ; 996 997 /* RFC 6742 */ 998 rdata_nid: STR sp dotted_str trail 999 { 1000 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ 1001 zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str)); /* NodeID */ 1002 } 1003 ; 1004 1005 rdata_l32: STR sp dotted_str trail 1006 { 1007 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ 1008 zadd_rdata_wireformat(zparser_conv_a(parser->region, $3.str)); /* Locator32 */ 1009 } 1010 ; 1011 1012 rdata_l64: STR sp dotted_str trail 1013 { 1014 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ 1015 zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str)); /* Locator64 */ 1016 } 1017 ; 1018 1019 rdata_lp: STR sp dname trail 1020 { 1021 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ 1022 zadd_rdata_domain($3); /* FQDN */ 1023 } 1024 ; 1025 1026 rdata_eui48: STR trail 1027 { 1028 zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 48)); 1029 } 1030 ; 1031 1032 rdata_eui64: STR trail 1033 { 1034 zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 64)); 1035 } 1036 ; 1037 1038 /* RFC7553 */ 1039 rdata_uri: STR sp STR sp STR trail 1040 { 1041 zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */ 1042 zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */ 1043 zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* target */ 1044 } 1045 ; 1046 1047 /* RFC 6844 */ 1048 rdata_caa: STR sp STR sp STR trail 1049 { 1050 zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* Flags */ 1051 zadd_rdata_wireformat(zparser_conv_tag(parser->region, $3.str, $3.len)); /* Tag */ 1052 zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* Value */ 1053 } 1054 ; 1055 1056 /* RFC7477 */ 1057 rdata_csync: STR sp STR nsec_seq 1058 { 1059 zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str)); 1060 zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); 1061 zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */ 1062 memset(nsecbits, 0, sizeof(nsecbits)); 1063 nsec_highest_rcode = 0; 1064 } 1065 ; 1066 1067 rdata_unknown: URR sp STR sp str_sp_seq trail 1068 { 1069 /* $2 is the number of octets, currently ignored */ 1070 $$ = zparser_conv_hex(parser->region, $5.str, $5.len); 1071 1072 } 1073 | URR sp STR trail 1074 { 1075 $$ = zparser_conv_hex(parser->region, "", 0); 1076 } 1077 | URR error NL 1078 { 1079 $$ = zparser_conv_hex(parser->region, "", 0); 1080 } 1081 ; 1082 %% 1083 1084 int 1085 yywrap(void) 1086 { 1087 return 1; 1088 } 1089 1090 /* 1091 * Create the parser. 1092 */ 1093 zparser_type * 1094 zparser_create(region_type *region, region_type *rr_region, namedb_type *db) 1095 { 1096 zparser_type *result; 1097 1098 result = (zparser_type *) region_alloc(region, sizeof(zparser_type)); 1099 result->region = region; 1100 result->rr_region = rr_region; 1101 result->db = db; 1102 1103 result->filename = NULL; 1104 result->current_zone = NULL; 1105 result->origin = NULL; 1106 result->prev_dname = NULL; 1107 result->default_apex = NULL; 1108 1109 result->temporary_rdatas = (rdata_atom_type *) region_alloc_array( 1110 result->region, MAXRDATALEN, sizeof(rdata_atom_type)); 1111 1112 return result; 1113 } 1114 1115 /* 1116 * Initialize the parser for a new zone file. 1117 */ 1118 void 1119 zparser_init(const char *filename, uint32_t ttl, uint16_t klass, 1120 const dname_type *origin) 1121 { 1122 memset(nxtbits, 0, sizeof(nxtbits)); 1123 memset(nsecbits, 0, sizeof(nsecbits)); 1124 nsec_highest_rcode = 0; 1125 1126 parser->default_ttl = ttl; 1127 parser->default_class = klass; 1128 parser->current_zone = NULL; 1129 parser->origin = domain_table_insert(parser->db->domains, origin); 1130 parser->prev_dname = parser->origin; 1131 parser->default_apex = parser->origin; 1132 parser->error_occurred = 0; 1133 parser->errors = 0; 1134 parser->line = 1; 1135 parser->filename = filename; 1136 parser->current_rr.rdata_count = 0; 1137 parser->current_rr.rdatas = parser->temporary_rdatas; 1138 } 1139 1140 void 1141 yyerror(const char *message) 1142 { 1143 zc_error("%s", message); 1144 } 1145 1146 static void 1147 error_va_list(unsigned line, const char *fmt, va_list args) 1148 { 1149 if (parser->filename) { 1150 char message[MAXSYSLOGMSGLEN]; 1151 vsnprintf(message, sizeof(message), fmt, args); 1152 log_msg(LOG_ERR, "%s:%u: %s", parser->filename, line, message); 1153 } 1154 else log_vmsg(LOG_ERR, fmt, args); 1155 1156 ++parser->errors; 1157 parser->error_occurred = 1; 1158 } 1159 1160 /* the line counting sux, to say the least 1161 * with this grose hack we try do give sane 1162 * numbers back */ 1163 void 1164 zc_error_prev_line(const char *fmt, ...) 1165 { 1166 va_list args; 1167 va_start(args, fmt); 1168 error_va_list(parser->line - 1, fmt, args); 1169 va_end(args); 1170 } 1171 1172 void 1173 zc_error(const char *fmt, ...) 1174 { 1175 /* send an error message to stderr */ 1176 va_list args; 1177 va_start(args, fmt); 1178 error_va_list(parser->line, fmt, args); 1179 va_end(args); 1180 } 1181 1182 static void 1183 warning_va_list(unsigned line, const char *fmt, va_list args) 1184 { 1185 if (parser->filename) { 1186 char m[MAXSYSLOGMSGLEN]; 1187 vsnprintf(m, sizeof(m), fmt, args); 1188 log_msg(LOG_WARNING, "%s:%u: %s", parser->filename, line, m); 1189 } 1190 else log_vmsg(LOG_WARNING, fmt, args); 1191 } 1192 1193 void 1194 zc_warning_prev_line(const char *fmt, ...) 1195 { 1196 va_list args; 1197 va_start(args, fmt); 1198 warning_va_list(parser->line - 1, fmt, args); 1199 va_end(args); 1200 } 1201 1202 void 1203 zc_warning(const char *fmt, ... ) 1204 { 1205 va_list args; 1206 va_start(args, fmt); 1207 warning_va_list(parser->line, fmt, args); 1208 va_end(args); 1209 } 1210 1211 #ifdef NSEC3 1212 static void 1213 nsec3_add_params(const char* hashalgo_str, const char* flag_str, 1214 const char* iter_str, const char* salt_str, int salt_len) 1215 { 1216 zadd_rdata_wireformat(zparser_conv_byte(parser->region, hashalgo_str)); 1217 zadd_rdata_wireformat(zparser_conv_byte(parser->region, flag_str)); 1218 zadd_rdata_wireformat(zparser_conv_short(parser->region, iter_str)); 1219 1220 /* salt */ 1221 if(strcmp(salt_str, "-") != 0) 1222 zadd_rdata_wireformat(zparser_conv_hex_length(parser->region, 1223 salt_str, salt_len)); 1224 else 1225 zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 1)); 1226 } 1227 #endif /* NSEC3 */ 1228