diff options
Diffstat (limited to 'src/zcompile/zparser.y')
-rw-r--r-- | src/zcompile/zparser.y | 1730 |
1 files changed, 1730 insertions, 0 deletions
diff --git a/src/zcompile/zparser.y b/src/zcompile/zparser.y new file mode 100644 index 0000000..6f081e5 --- /dev/null +++ b/src/zcompile/zparser.y @@ -0,0 +1,1730 @@ +%{ +/*! + * \file zparser.y + * + * \author modifications by Jan Kadlec <jan.kadlec@nic.cz>, + * notable changes: normal allocation, parser is reentrant. + * most of the code by NLnet Labs + * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. + * + * \brief yacc grammar for (DNS) zone files + * + * \addtogroup zoneparser + * @{ + */ + +/* + * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "common.h" + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "zcompile/parser-util.h" + +#include "libknot/libknot.h" +#include "zcompile/zcompile.h" +#include "zcompile/parser-descriptor.h" +#include "zcompile/zcompile-error.h" +#include "zparser.h" + +/* these need to be global, otherwise they cannot be used inside yacc */ +zparser_type *parser; + +#ifdef __cplusplus +extern "C" +#endif /* __cplusplus */ +int zp_wrap(void); + +/* this hold the nxt bits */ +static uint8_t nxtbits[16]; +static int dlv_warn = 1; + +/* 256 windows of 256 bits (32 bytes) */ +/* still need to reset the bastard somewhere */ +static uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]; + +/* hold the highest rcode seen in a NSEC rdata , BUG #106 */ +uint16_t nsec_highest_rcode; + +void zp_error(void *scanner, const char *message); +int zp_lex(YYSTYPE *lvalp, void *scanner); + +/* helper functions */ +void zc_error(const char *fmt, ...); +void zc_warning(const char *fmt, ...); +void zc_error_prev_line(const char *fmt, ...); +void zc_warning_prev_line(const char *fmt, ...); + +#define NSEC3 +#ifdef NSEC3 +/* parse nsec3 parameters and add the (first) rdata elements */ +static void +nsec3_add_params(const char* hash_algo_str, const char* flag_str, + const char* iter_str, const char* salt_str, int salt_len); +#endif /* NSEC3 */ + +knot_dname_t *error_dname; //XXX used to be const +knot_dname_t *error_domain; + +%} +%union { + knot_dname_t *domain; + knot_dname_t *dname; + struct lex_data data; + uint32_t ttl; + uint16_t rclass; + uint16_t type; + uint16_t *unknown; +} + +%pure-parser +%parse-param {void *scanner} +%lex-param {void *scanner} +%name-prefix = "zp_" + +/* + * Tokens to represent the known RR types of DNS. + */ +%token <type> T_A T_NS T_MX T_TXT T_CNAME T_AAAA T_PTR T_NXT T_KEY T_SOA T_SIG +%token <type> T_SRV T_CERT T_LOC T_MD T_MF T_MB T_MG T_MR T_NULL T_WKS T_HINFO +%token <type> T_MINFO T_RP T_AFSDB T_X25 T_ISDN T_RT T_NSAP T_NSAP_PTR T_PX +%token <type> T_GPOS T_EID T_NIMLOC T_ATMA T_NAPTR T_KX T_A6 T_DNAME T_SINK +%token <type> T_OPT T_APL T_UINFO T_UID T_GID T_UNSPEC T_TKEY T_TSIG T_IXFR +%token <type> T_AXFR T_MAILB T_MAILA T_DS T_DLV T_SSHFP T_RRSIG T_NSEC T_DNSKEY +%token <type> T_SPF T_NSEC3 T_IPSECKEY T_DHCID T_NSEC3PARAM + +/* other tokens */ +%token DOLLAR_TTL DOLLAR_ORIGIN NL SP NO_MEM +%token <data> STR PREV BITLAB +%token <ttl> T_TTL +%token <rclass> T_RRCLASS + +/* unknown RRs */ +%token URR +%token <type> T_UTYPE + +%type <type> type_and_rdata +%type <domain> owner dname abs_dname +%type <dname> rel_dname label +%type <data> wire_dname wire_abs_dname wire_rel_dname wire_label +%type <data> concatenated_str_seq str_sp_seq str_dot_seq dotted_str +%type <data> nxt_seq nsec_more +%type <unknown> rdata_unknown + +%% +lines: /* empty file */ + | lines line + ; + +line: NL + | sp NL + | NO_MEM { + zc_error_prev_line("Parser ran out of memory!"); + YYABORT; + } + | PREV NL {} /* Lines containing only whitespace. */ + | ttl_directive + { + parser->error_occurred = 0; + } + | origin_directive + { + parser->error_occurred = 0; + } + | rr + { /* rr should be fully parsed */ + if (!parser->error_occurred) { + /*!< \todo assign error to error occurred */ + /*! \todo Make sure this does not crash */ + if (parser->current_rrset->owner == NULL) { + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + knot_rdata_t *tmp_rdata = knot_rdata_new(); + if (tmp_rdata == NULL) { + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + + if (knot_rdata_set_items(tmp_rdata, + parser->temporary_items, + parser->rdata_count) != 0) { + knot_rdata_free(&tmp_rdata); + knot_rrset_deep_free(&(parser->current_rrset), 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), 1); + YYABORT; + } + + assert(parser->current_rrset->rdata == NULL); + if (knot_rrset_add_rdata(parser->current_rrset, tmp_rdata) + != 0) { + fprintf(stderr, "Could not add rdata!\n"); + } +// tmp_rdata->next = tmp_rdata; +// parser->current_rrset->rdata = tmp_rdata; + + if (!knot_dname_is_fqdn(parser->current_rrset->owner)) { + knot_dname_t *tmp_dname = + knot_dname_cat(parser->current_rrset->owner, + parser->root_domain); + if (tmp_dname == NULL) { + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } +// knot_rrset_set_owner(parser->current_rrset, tmp_dname); + } + + assert(parser->current_rrset->owner != NULL); + knot_dname_retain(parser->current_rrset->owner); + int ret = 0; + if ((ret = process_rr()) != 0) { + char *name = + knot_dname_to_str(parser->current_rrset->owner); + fprintf(stderr, "Error: could not process RRSet\n" + "owner: %s reason: %s\n", + name, + error_to_str(knot_zcompile_error_msgs, ret)); + free(name); + + /* If the owner is not already in the table, free it. */ +// if (dnslib_dname_table_find_dname(parser->dname_table, +// parser->current_rrset->owner) == NULL) { +// dnslib_dname_free(&parser-> +// current_rrset->owner); +// } /* This would never happen */ + + if (ret == KNOTDZCOMPILE_EBADSOA) { + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } else { + YYABORT; + /* Free rdata, it will not be added + * and hence cannot be + * freed with rest of the zone. */ +/* knot_rdata_deep_free(&tmp_rdata, + parser-> + current_rrset->type, + 0); */ + } + } + } else { + /* Error occured. This could either be lack of memory, or one + * of the converting function was not able to convert. */ + if (parser->error_occurred == KNOTDZCOMPILE_ENOMEM) { + /* Ran out of memory in converting functions. */ + fprintf(stderr, "Parser ran out " + "of memory, aborting!\n"); + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + } + +// printf("Current rrset name: %p (%s)\n", parser->current_rrset->owner->name, +// knot_dname_to_str(parser->current_rrset->owner)); +// getchar(); + +// knot_dname_release(parser->current_rrset->owner); + + parser->current_rrset->type = 0; + parser->rdata_count = 0; + parser->current_rrset->rdata = NULL; + parser->error_occurred = 0; + } + | error NL + ; + +/* needed to cope with ( and ) in arbitary places */ +sp: SP + | sp SP + ; + +trail: NL + | sp NL + ; + +ttl_directive: DOLLAR_TTL sp STR trail + { + parser->default_ttl = zparser_ttl2int($3.str, + &(parser->error_occurred)); + if (parser->error_occurred == 1) { + parser->default_ttl = DEFAULT_TTL; + parser->error_occurred = 0; + } + + free($3.str); + } + ; + + + +origin_directive: DOLLAR_ORIGIN sp abs_dname trail + { + knot_node_t *origin_node = knot_node_new($3 ,NULL, 0); + if (parser->origin != NULL) { +// knot_node_free(&parser->origin, 1); + } + parser->origin = origin_node; + } + | DOLLAR_ORIGIN sp rel_dname trail + { + zc_error_prev_line("$ORIGIN directive requires" + "absolute domain name"); + } + ; + +rr: owner classttl type_and_rdata + { + /* Save the pointer, it might get freed! */ + parser->current_rrset->owner = $1; +// parser->current_rrset->owner = $1; +// printf("new owner assigned: %p\n", $1); + parser->current_rrset->type = $3; + } + ; + +owner: dname sp + { +// char *name = knot_dname_to_str($1); +// printf("Totally new dname: %p %s\n", $1, +// name); +// free(name); + if (parser->prev_dname != NULL) { + // knot_dname_release(parser->prev_dname); + } + parser->prev_dname = $1;//knot_dname_deep_copy($1); +// knot_dname_retain(parser->prev_dname); + $$ = $1; + } + | PREV + { +// printf("Name from prev_dname!: %p %s\n", parser->prev_dname, +// knot_dname_to_str(parser->prev_dname)); + knot_dname_retain(parser->prev_dname); + $$ = parser->prev_dname;//knot_dname_deep_copy(parser->prev_dname); + } + ; + +classttl: /* empty - fill in the default, def. ttl and IN class */ + { + parser->current_rrset->ttl = parser->default_ttl; + parser->current_rrset->rclass = parser->default_class; + } + | T_RRCLASS sp /* no ttl */ + { + parser->current_rrset->ttl = parser->default_ttl; + parser->current_rrset->rclass = $1; + } + | T_TTL sp /* no class */ + { + parser->current_rrset->ttl = $1; + parser->current_rrset->rclass = parser->default_class; + } + | T_TTL sp T_RRCLASS sp /* the lot */ + { + parser->current_rrset->ttl = $1; + parser->current_rrset->rclass = $3; + } + | T_RRCLASS sp T_TTL sp /* the lot - reversed */ + { + parser->current_rrset->ttl = $3; + parser->current_rrset->rclass = $1; + } + ; + +dname: abs_dname + | rel_dname + { + if ($1 == error_dname) { + $$ = error_domain; + } else if ($1->size + parser->origin->owner->size - 1 > + MAXDOMAINLEN) { + zc_error("domain name exceeds %d character limit", + MAXDOMAINLEN); + $$ = error_domain; + } else { + $$ = knot_dname_cat($1, + parser->origin->owner); +// printf("leak: %s\n", knot_dname_to_str($$)); +// getchar(); + } + } + ; + +abs_dname: '.' + { + $$ = parser->root_domain; + /* TODO how about concatenation now? */ + } + | '@' + { + $$ = parser->origin->owner; + } + | rel_dname '.' + { + if ($1 != error_dname) { + $$ = $1; + } else { + $$ = error_domain; + } + } + ; + +label: STR + { + if ($1.len > MAXLABELLEN) { + zc_error("label exceeds %d character limit", MAXLABELLEN); + $$ = error_dname; + } else { +// printf("%s\n", $1.str); + $$ = knot_dname_new_from_str($1.str, $1.len, NULL); +// printf("Creating new (label): %s %p\n", $1.str, $$); +// printf("new: %p %s\n", $$, $1.str); + $$->ref.count = 0; + } + + free($1.str); + + } + | BITLAB + { + zc_error("bitlabels are not supported." + "RFC2673 has status experimental."); + $$ = error_dname; + } + ; + +rel_dname: label + | rel_dname '.' label + { + if ($1 == error_dname || $3 == error_dname) { + $$ = error_dname; + } else if ($1->size + $3->size - 1 > MAXDOMAINLEN) { + zc_error("domain name exceeds %d character limit", + MAXDOMAINLEN); + $$ = error_dname; + } else { + $$ = knot_dname_cat($1, $3); +// knot_dname_release($1); /*!< \todo check! */ + knot_dname_free(&$3); + } + } + ; + +/* + * Some dnames in rdata are handled as opaque blobs + */ + +wire_dname: wire_abs_dname + | wire_rel_dname + ; + +wire_abs_dname: '.' + { + char *result = malloc(2 * sizeof(char)); + if (result == NULL) { + ERR_ALLOC_FAILED; + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + result[0] = 0; + result[1] = '\0'; + $$.str = result; + $$.len = 1; + } + | wire_rel_dname '.' + { + char *result = malloc($1.len + 2 * sizeof(char)); + if (result == NULL) { + ERR_ALLOC_FAILED; + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + memcpy(result, $1.str, $1.len); + result[$1.len] = 0; + result[$1.len+1] = '\0'; + $$.str = result; + $$.len = $1.len + 1; + + free($1.str); +; + } + ; + +wire_label: STR + { + char *result = malloc($1.len + sizeof(char)); + if (result == NULL) { + ERR_ALLOC_FAILED; + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + + if ($1.len > MAXLABELLEN) + zc_error("label exceeds %d character limit", MAXLABELLEN); + + /* make label anyway */ + result[0] = $1.len; + memcpy(result+1, $1.str, $1.len); + + $$.str = result; + $$.len = $1.len + 1; + + free($1.str); + } + ; + +wire_rel_dname: wire_label + | wire_rel_dname '.' wire_label + { + if ($1.len + $3.len - 3 > MAXDOMAINLEN) + zc_error("domain name exceeds %d character limit", + MAXDOMAINLEN); + + /* make dname anyway */ + $$.len = $1.len + $3.len; + $$.str = malloc($$.len + sizeof(char)); + if ($$.str == NULL) { + ERR_ALLOC_FAILED; + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + memcpy($$.str, $1.str, $1.len); + memcpy($$.str + $1.len, $3.str, $3.len); + $$.str[$$.len] = '\0'; + + free($1.str); + free($3.str); + } + ; + + + +str_seq: STR + { + zadd_rdata_txt_wireformat(zparser_conv_text($1.str, $1.len), 1); + + free($1.str); + } + | str_seq sp STR + { + zadd_rdata_txt_wireformat(zparser_conv_text($3.str, $3.len), 0); +// zc_warning("multiple TXT entries are currently not supported!"); + + free($3.str); + } + ; + +/* + * Generate a single string from multiple STR tokens, separated by + * spaces or dots. + */ +concatenated_str_seq: STR + | '.' + { + $$.len = 1; + $$.str = strdup("."); + } + | concatenated_str_seq sp STR + { + $$.len = $1.len + $3.len + 1; + $$.str = malloc($$.len + 1); + if ($$.str == NULL) { + ERR_ALLOC_FAILED; + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + + memcpy($$.str, $1.str, $1.len); + memcpy($$.str + $1.len, " ", 1); + memcpy($$.str + $1.len + 1, $3.str, $3.len); + $$.str[$$.len] = '\0'; + + free($1.str); + free($3.str); + } + | concatenated_str_seq '.' STR + { + $$.len = $1.len + $3.len + 1; + $$.str = malloc($$.len + 1); + if ($$.str == NULL) { + ERR_ALLOC_FAILED; + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + memcpy($$.str, $1.str, $1.len); + memcpy($$.str + $1.len, ".", 1); + memcpy($$.str + $1.len + 1, $3.str, $3.len); + + free($1.str); + free($3.str); + + $$.str[$$.len] = '\0'; + } + ; + +/* used to convert a nxt list of types */ +nxt_seq: STR + { + uint16_t type = knot_rrtype_from_string($1.str); + if (type != 0 && type < 128) { + set_bit(nxtbits, type); + } else { + zc_error("bad type %d in NXT record", (int) type); + } + + free($1.str); + } + | nxt_seq sp STR + { + uint16_t type = knot_rrtype_from_string($3.str); + if (type != 0 && type < 128) { + set_bit(nxtbits, type); + } else { + zc_error("bad type %d in NXT record", (int) type); + } + + free($3.str); + } + ; + +nsec_more: SP nsec_more + { + } + | NL + { + } + | STR nsec_seq + { + uint16_t type = knot_rrtype_from_string($1.str); + if (type != 0) { + if (type > nsec_highest_rcode) { + nsec_highest_rcode = type; + } + set_bitnsec(nsecbits, type); + } else { + zc_error("bad type %d in NSEC record", (int) type); + } + + free($1.str); + } + ; + +nsec_seq: NL + | SP nsec_more + ; + +/* + * Sequence of STR tokens separated by spaces. The spaces are not + * preserved during concatenation. + */ +str_sp_seq: STR + | str_sp_seq sp STR + { + char *result = malloc($1.len + $3.len + 1); + if (result == NULL) { + ERR_ALLOC_FAILED; + fprintf(stderr, "Parser ran out of memory, aborting!\n"); + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + memcpy(result, $1.str, $1.len); + memcpy(result + $1.len, $3.str, $3.len); + $$.str = result; + $$.len = $1.len + $3.len; + $$.str[$$.len] = '\0'; + + free($1.str); + free($3.str); + } + ; + +/* + * Sequence of STR tokens separated by dots. The dots are not + * preserved during concatenation. + */ +str_dot_seq: STR + | str_dot_seq '.' STR + { + char *result = malloc($1.len + $3.len + 1); + if (result == NULL) { + ERR_ALLOC_FAILED; + fprintf(stderr, "Parser ran out of memory, aborting!\n"); + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + memcpy(result, $1.str, $1.len); + memcpy(result + $1.len, $3.str, $3.len); + $$.str = result; + $$.len = $1.len + $3.len; + $$.str[$$.len] = '\0'; + + free($1.str); + free($3.str); + } + ; + +/* + * A string that can contain dots. + */ +dotted_str: STR + | '.' + { + $$.str = "."; + $$.len = 1; + } + | dotted_str '.' + { + char *result = malloc($1.len + 2); + if (result == NULL) { + ERR_ALLOC_FAILED; + fprintf(stderr, "Parser ran out of memory, aborting!\n"); + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + memcpy(result, $1.str, $1.len); + result[$1.len] = '.'; + $$.str = result; + $$.len = $1.len + 1; + $$.str[$$.len] = '\0'; + + free($1.str); + } + | dotted_str '.' STR + { + char *result = malloc($1.len + $3.len + 2); + if (result == NULL) { + ERR_ALLOC_FAILED; + fprintf(stderr, "Parser ran out of memory, aborting!\n"); + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + memcpy(result, $1.str, $1.len); + result[$1.len] = '.'; + memcpy(result + $1.len + 1, $3.str, $3.len); + $$.str = result; + $$.len = $1.len + $3.len + 1; + $$.str[$$.len] = '\0'; + + + free($1.str); + free($3.str); + } + ; + +/* define what we can parse */ +type_and_rdata: + /* + * All supported RR types. We don't support NULL and types marked obsolete. + */ + T_A sp rdata_a + | T_A sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_NS sp rdata_domain_name + | T_NS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_MD sp rdata_domain_name { zc_warning_prev_line("MD is obsolete"); } + | T_MD sp rdata_unknown + { + zc_warning_prev_line("MD is obsolete"); + $$ = $1; parse_unknown_rdata($1, $3); + } + | T_MF sp rdata_domain_name { zc_warning_prev_line("MF is obsolete"); } + | T_MF sp rdata_unknown + { + zc_warning_prev_line("MF is obsolete"); + $$ = $1; + parse_unknown_rdata($1, $3); + } + | T_CNAME sp rdata_domain_name + | T_CNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_SOA sp rdata_soa + | T_SOA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_MB sp rdata_domain_name { zc_warning_prev_line("MB is obsolete"); } + | T_MB sp rdata_unknown + { + zc_warning_prev_line("MB is obsolete"); + $$ = $1; + parse_unknown_rdata($1, $3); + } + | T_MG sp rdata_domain_name + | T_MG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_MR sp rdata_domain_name + | T_MR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + /* NULL */ + | T_WKS sp rdata_wks + | T_WKS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_PTR sp rdata_domain_name + | T_PTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_HINFO sp rdata_hinfo + | T_HINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_MINFO sp rdata_minfo /* Experimental */ + | T_MINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_MX sp rdata_mx + | T_MX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_TXT sp rdata_txt + | T_TXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_SPF sp rdata_txt + | T_SPF sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_RP sp rdata_rp /* RFC 1183 */ + | T_RP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_AFSDB sp rdata_afsdb /* RFC 1183 */ + | T_AFSDB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_X25 sp rdata_x25 /* RFC 1183 */ + | T_X25 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_ISDN sp rdata_isdn /* RFC 1183 */ + | T_ISDN sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_IPSECKEY sp rdata_ipseckey /* RFC 4025 */ + | T_IPSECKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_DHCID sp rdata_dhcid + | T_DHCID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_RT sp rdata_rt /* RFC 1183 */ + | T_RT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_NSAP sp rdata_nsap /* RFC 1706 */ + | T_NSAP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_SIG sp rdata_rrsig + | T_SIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_KEY sp rdata_dnskey + | T_KEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_PX sp rdata_px /* RFC 2163 */ + | T_PX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_AAAA sp rdata_aaaa + | T_AAAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_LOC sp rdata_loc + | T_LOC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_NXT sp rdata_nxt + | T_NXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_SRV sp rdata_srv + | T_SRV sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_NAPTR sp rdata_naptr /* RFC 2915 */ + | T_NAPTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_KX sp rdata_kx /* RFC 2230 */ + | T_KX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_CERT sp rdata_cert /* RFC 2538 */ + | T_CERT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_DNAME sp rdata_domain_name /* RFC 2672 */ + | T_DNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_APL trail /* RFC 3123 */ + | T_APL sp rdata_apl /* RFC 3123 */ + | T_APL sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_DS sp rdata_ds + | T_DS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_DLV sp rdata_dlv + { + if (dlv_warn) { + dlv_warn = 0; + zc_warning_prev_line("DLV is experimental"); + } + } + | T_DLV sp rdata_unknown + { + if (dlv_warn) { + dlv_warn = 0; + zc_warning_prev_line("DLV is experimental"); + } + $$ = $1; + parse_unknown_rdata($1, $3); + } + | T_SSHFP sp rdata_sshfp + | T_SSHFP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_RRSIG sp rdata_rrsig + | T_RRSIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_NSEC sp rdata_nsec + | T_NSEC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_NSEC3 sp rdata_nsec3 + | T_NSEC3 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_NSEC3PARAM sp rdata_nsec3_param + | T_NSEC3PARAM sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_DNSKEY sp rdata_dnskey + | T_DNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + | T_UTYPE sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } + + | STR error NL + { + zc_error_prev_line("unrecognized RR type '%s'", $1.str); + free($1.str); + } + | NO_MEM + { + zc_error_prev_line("parser ran out of memory!"); + YYABORT; + } + ; + +/* + * + * below are all the definition for all the different rdata + * + */ + +rdata_a: dotted_str trail + { + zadd_rdata_wireformat(zparser_conv_a($1.str)); + free($1.str); + } + ; + +rdata_domain_name: dname trail + { + /* convert a single dname record */ + if ($1 != NULL) { + if (!knot_dname_is_fqdn($1)) { + knot_dname_cat($1, parser->root_domain); +// parser->current_rrset->owner = +// knot_dname_cat($1, parser->root_domain); + } + } + zadd_rdata_domain($1); + } + ; + +rdata_soa: dname sp dname sp STR sp STR sp STR sp STR sp STR trail + { + /* convert the soa data */ + if (!knot_dname_is_fqdn($1)) { + knot_dname_cat($1, parser->root_domain); +// parser->current_rrset->owner = +// knot_dname_cat($1, parser->root_domain); + + } + if (!knot_dname_is_fqdn($3)) { + knot_dname_cat($3, parser->root_domain); +// parser->current_rrset->owner = +// knot_dname_cat($3, parser->root_domain); + + } + zadd_rdata_domain($1); /* prim. ns */ + zadd_rdata_domain($3); /* email */ + zadd_rdata_wireformat(zparser_conv_serial($5.str)); /* serial */ + zadd_rdata_wireformat(zparser_conv_period($7.str)); /* refresh */ + zadd_rdata_wireformat(zparser_conv_period($9.str)); /* retry */ + zadd_rdata_wireformat(zparser_conv_period($11.str)); /* expire */ + zadd_rdata_wireformat(zparser_conv_period($13.str)); /* minimum */ + + free($5.str); + free($7.str); + free($9.str); + free($11.str); + free($13.str); + } + ; + +rdata_wks: dotted_str sp STR sp concatenated_str_seq trail + { + zadd_rdata_wireformat(zparser_conv_a($1.str)); /* address */ + zadd_rdata_wireformat(zparser_conv_services($3.str, $5.str)); + /* protocol and services */ + + free($1.str); + free($3.str); + free($5.str); + } + ; + +rdata_hinfo: STR sp STR trail + { + zadd_rdata_wireformat(zparser_conv_text($1.str, $1.len)); /* CPU */ + zadd_rdata_wireformat(zparser_conv_text($3.str, $3.len)); /* OS*/ + + free($1.str); + free($3.str); + } + ; + +rdata_minfo: dname sp dname trail + { + if (!knot_dname_is_fqdn($1)) { + + knot_dname_cat($1, parser->root_domain); + + } + if (!knot_dname_is_fqdn($3)) { + + knot_dname_cat($3, parser->root_domain); + + } + + /* convert a single dname record */ + zadd_rdata_domain($1); + zadd_rdata_domain($3); + } + ; + +rdata_mx: STR sp dname trail + { + if (!knot_dname_is_fqdn($3)) { + knot_dname_cat($3, parser->root_domain); + } + + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* priority */ + zadd_rdata_domain($3); /* MX host */ + + free($1.str); + } + ; + +rdata_txt: str_seq trail + { + ; //zadd_rdata_txt_clean_wireformat(); + } + ; + +/* RFC 1183 */ +rdata_rp: dname sp dname trail + { + if (!knot_dname_is_fqdn($1)) { + knot_dname_cat($1, parser->root_domain); + } + if (!knot_dname_is_fqdn($3)) { + knot_dname_cat($3, parser->root_domain); + } + + zadd_rdata_domain($1); /* mbox d-name */ + zadd_rdata_domain($3); /* txt d-name */ + } + ; + +/* RFC 1183 */ +rdata_afsdb: STR sp dname trail + { + if (!knot_dname_is_fqdn($3)) { + knot_dname_cat($3, parser->root_domain); + } + + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* subtype */ + zadd_rdata_domain($3); /* domain name */ + + free($1.str); + } + ; + +/* RFC 1183 */ +rdata_x25: STR trail + { + zadd_rdata_wireformat(zparser_conv_text($1.str, $1.len)); + /* X.25 address. */ + + free($1.str); + } + ; + +/* RFC 1183 */ +rdata_isdn: STR trail + { + zadd_rdata_wireformat(zparser_conv_text($1.str, $1.len)); + /* address */ + + free($1.str); + } + | STR sp STR trail + { + zadd_rdata_wireformat(zparser_conv_text($1.str, $1.len)); + /* address */ + zadd_rdata_wireformat(zparser_conv_text($3.str, $3.len)); + /* sub-address */ + + free($1.str); + free($3.str); + } + ; + +/* RFC 1183 */ +rdata_rt: STR sp dname trail + { + if (!knot_dname_is_fqdn($3)) { + knot_dname_cat($3, parser->root_domain); + } + + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* preference */ + zadd_rdata_domain($3); /* intermediate host */ + + free($1.str); + } + ; + +/* RFC 1706 */ +rdata_nsap: str_dot_seq trail + { + /* String must start with "0x" or "0X". */ + if (strncasecmp($1.str, "0x", 2) != 0) { + zc_error_prev_line("NSAP rdata must start with '0x'"); + } else { + zadd_rdata_wireformat(zparser_conv_hex($1.str + 2, + $1.len - 2)); + /* NSAP */ + } + + free($1.str); + } + ; + +/* RFC 2163 */ +rdata_px: STR sp dname sp dname trail + { + if (!knot_dname_is_fqdn($3)) { + knot_dname_cat($3, parser->root_domain); + } + if (!knot_dname_is_fqdn($5)) { + knot_dname_cat($5, parser->root_domain); + } + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* preference */ + zadd_rdata_domain($3); /* MAP822 */ + zadd_rdata_domain($5); /* MAPX400 */ + + free($1.str); + } + ; + +rdata_aaaa: dotted_str trail + { + zadd_rdata_wireformat(zparser_conv_aaaa($1.str)); + /* IPv6 address */ + + free($1.str); + } + ; + +rdata_loc: concatenated_str_seq trail + { + zadd_rdata_wireformat(zparser_conv_loc($1.str)); /* Location */ + + free($1.str); + } + ; + +rdata_nxt: dname sp nxt_seq trail + { + if (!knot_dname_is_fqdn($1)) { + knot_dname_cat($1, parser->root_domain); + } + zadd_rdata_domain($1); /* nxt name */ + zadd_rdata_wireformat(zparser_conv_nxt(nxtbits)); /* nxt bitlist */ + memset(nxtbits, 0, sizeof(nxtbits)); + } + ; + +rdata_srv: STR sp STR sp STR sp dname trail + { + if (!knot_dname_is_fqdn($7)) { + knot_dname_cat($7, parser->root_domain); + + } + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* prio */ + zadd_rdata_wireformat(zparser_conv_short($3.str)); /* weight */ + zadd_rdata_wireformat(zparser_conv_short($5.str)); /* port */ + zadd_rdata_domain($7); /* target name */ + + free($1.str); + free($3.str); + free($5.str); + } + ; + +/* RFC 2915 */ +rdata_naptr: STR sp STR sp STR sp STR sp STR sp dname trail + { + if (!knot_dname_is_fqdn($11)) { + knot_dname_cat($11, parser->root_domain); + + } + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* order */ + zadd_rdata_wireformat(zparser_conv_short($3.str)); /* preference */ + zadd_rdata_wireformat(zparser_conv_text($5.str, $5.len)); + /* flags */ + zadd_rdata_wireformat(zparser_conv_text($7.str, $7.len)); + /* service */ + zadd_rdata_wireformat(zparser_conv_text($9.str, $9.len)); + /* regexp */ + zadd_rdata_domain($11); /* target name */ + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + free($9.str); + } + ; + +/* RFC 2230 */ +rdata_kx: STR sp dname trail + { + if (!knot_dname_is_fqdn($3)) { + knot_dname_cat($3, parser->root_domain); + } + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* preference */ + zadd_rdata_domain($3); /* exchanger */ + + free($1.str); + } + ; + +/* RFC 2538 */ +rdata_cert: STR sp STR sp STR sp str_sp_seq trail + { + zadd_rdata_wireformat(zparser_conv_certificate_type($1.str)); + /* type */ + zadd_rdata_wireformat(zparser_conv_short($3.str)); /* key tag */ + zadd_rdata_wireformat(zparser_conv_algorithm($5.str)); + /* algorithm */ + zadd_rdata_wireformat(zparser_conv_b64($7.str)); + /* certificate or CRL */ + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + } + ; + +/* RFC 3123 */ +rdata_apl: rdata_apl_seq trail + ; + +rdata_apl_seq: dotted_str + { + zadd_rdata_wireformat(zparser_conv_apl_rdata($1.str)); + + free($1.str); + } + | rdata_apl_seq sp dotted_str + { + zadd_rdata_wireformat(zparser_conv_apl_rdata($3.str)); + + free($3.str); + } + ; + +rdata_ds: STR sp STR sp STR sp str_sp_seq trail + { + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* keytag */ + zadd_rdata_wireformat(zparser_conv_algorithm($3.str)); /* alg */ + zadd_rdata_wireformat(zparser_conv_byte($5.str)); /* type */ + zadd_rdata_wireformat(zparser_conv_hex($7.str, $7.len)); /* hash */ + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + } + ; + +rdata_dlv: STR sp STR sp STR sp str_sp_seq trail + { + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* keytag */ + zadd_rdata_wireformat(zparser_conv_algorithm($3.str)); /* alg */ + zadd_rdata_wireformat(zparser_conv_byte($5.str)); /* type */ + zadd_rdata_wireformat(zparser_conv_hex($7.str, $7.len)); /* hash */ + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + } + ; + +rdata_sshfp: STR sp STR sp str_sp_seq trail + { + zadd_rdata_wireformat(zparser_conv_byte($1.str)); /* alg */ + zadd_rdata_wireformat(zparser_conv_byte($3.str)); /* fp type */ + zadd_rdata_wireformat(zparser_conv_hex($5.str, $5.len)); /* hash */ + + free($1.str); + free($3.str); + free($5.str); + } + ; + +rdata_dhcid: str_sp_seq trail + { + zadd_rdata_wireformat(zparser_conv_b64($1.str)); /* data blob */ + + free($1.str); + } + ; + +rdata_rrsig: STR sp STR sp STR sp STR sp STR sp STR + sp STR sp wire_dname sp str_sp_seq trail + { + zadd_rdata_wireformat(zparser_conv_rrtype($1.str)); + /* rr covered */ + zadd_rdata_wireformat(zparser_conv_algorithm($3.str)); /* alg */ + zadd_rdata_wireformat(zparser_conv_byte($5.str)); /* # labels */ + zadd_rdata_wireformat(zparser_conv_period($7.str)); + /* # orig TTL */ + zadd_rdata_wireformat(zparser_conv_time($9.str)); /* sig exp */ + zadd_rdata_wireformat(zparser_conv_time($11.str)); /* sig inc */ + zadd_rdata_wireformat(zparser_conv_short($13.str)); /* key id */ +/* zadd_rdata_wireformat(zparser_conv_dns_name((const uint8_t*) + $15.str, + $15.len));*/ + knot_dname_t *dname = + knot_dname_new_from_wire((uint8_t *)$15.str, $15.len, NULL); + if (dname == NULL) { + parser->error_occurred = KNOTDZCOMPILE_ENOMEM; + } else { + knot_dname_cat(dname, parser->root_domain); + } + + zadd_rdata_domain(dname); + /* sig name */ + zadd_rdata_wireformat(zparser_conv_b64($17.str)); /* sig data */ + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + free($9.str); + free($11.str); + free($13.str); + free($15.str); + free($17.str); + } + ; + +rdata_nsec: wire_dname nsec_seq + { +/* zadd_rdata_wireformat(zparser_conv_dns_name((const uint8_t*) + $1.str, + $1.len));*/ + + knot_dname_t *dname = + knot_dname_new_from_wire((uint8_t *)$1.str, $1.len, NULL); + + free($1.str); + + knot_dname_cat(dname, parser->root_domain); + + zadd_rdata_domain(dname); + /* nsec name */ + zadd_rdata_wireformat(zparser_conv_nsec(nsecbits)); + /* nsec bitlist */ + memset(nsecbits, 0, sizeof(nsecbits)); + nsec_highest_rcode = 0; + } + ; + +rdata_nsec3: STR sp STR sp STR sp STR sp STR nsec_seq + { +#ifdef NSEC3 + nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len); + +/* knot_dname_t *dname = + knot_dname_new_from_str($9.str, $9.len, NULL); + + zadd_rdata_domain(dname); */ + + zadd_rdata_wireformat(zparser_conv_b32($9.str)); + /* next hashed name */ + zadd_rdata_wireformat(zparser_conv_nsec(nsecbits)); + /* nsec bitlist */ + memset(nsecbits, 0, sizeof(nsecbits)); + nsec_highest_rcode = 0; +#else + zc_error_prev_line("nsec3 not supported"); +#endif /* NSEC3 */ + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + free($9.str); + } + ; + +rdata_nsec3_param: STR sp STR sp STR sp STR trail + { +#ifdef NSEC3 + nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len); +#else + zc_error_prev_line("nsec3 not supported"); +#endif /* NSEC3 */ + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + } + ; + +rdata_dnskey: STR sp STR sp STR sp str_sp_seq trail + { + zadd_rdata_wireformat(zparser_conv_short($1.str)); /* flags */ + zadd_rdata_wireformat(zparser_conv_byte($3.str)); /* proto */ + zadd_rdata_wireformat(zparser_conv_algorithm($5.str)); /* alg */ + zadd_rdata_wireformat(zparser_conv_b64($7.str)); /* hash */ + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + } + ; + +rdata_ipsec_base: STR sp STR sp STR sp dotted_str + { + knot_dname_t* name = 0; + zadd_rdata_wireformat(zparser_conv_byte($1.str)); /* precedence */ + zadd_rdata_wireformat(zparser_conv_byte($3.str)); + /* gateway type */ + zadd_rdata_wireformat(zparser_conv_byte($5.str)); /* algorithm */ + switch(atoi($3.str)) { + case IPSECKEY_NOGATEWAY: + zadd_rdata_wireformat(alloc_rdata_init("", 0)); + break; + case IPSECKEY_IP4: + zadd_rdata_wireformat(zparser_conv_a($7.str)); + break; + case IPSECKEY_IP6: + zadd_rdata_wireformat(zparser_conv_aaaa($7.str)); + break; + case IPSECKEY_DNAME: + /* convert and insert the dname */ + if(strlen($7.str) == 0) + zc_error_prev_line("IPSECKEY must specify" + "gateway name"); + name = knot_dname_new_from_wire((uint8_t*)$7.str + 1, + strlen($7.str + 1), + NULL); + if(!name) { + zc_error_prev_line("IPSECKEY bad gateway" + "dname %s", $7.str); + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + if($7.str[strlen($7.str)-1] != '.') { + knot_dname_t* tmpd = + knot_dname_new_from_wire(name->name, + name->size, + NULL); + if (tmpd == NULL) { + zc_error_prev_line("Could not create dname!"); + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + name = knot_dname_cat(tmpd, + knot_node_parent(parser->origin, 0)->owner); + } + + free($1.str); + free($3.str); + free($5.str); + free($7.str); + + uint8_t* dncpy = malloc(sizeof(uint8_t) * name->size); + if (dncpy == NULL) { + ERR_ALLOC_FAILED; + knot_rrset_deep_free(&(parser->current_rrset), + 0, 0, 0); + knot_zone_deep_free(&(parser->current_zone), + 1); + YYABORT; + } + memcpy(dncpy, name->name, name->size); + zadd_rdata_wireformat((uint16_t *)dncpy); + //knot_dname_free(&name); + break; + default: + zc_error_prev_line("unknown IPSECKEY gateway type"); + } + } + ; + +rdata_ipseckey: rdata_ipsec_base sp str_sp_seq trail + { + zadd_rdata_wireformat(zparser_conv_b64($3.str)); /* public key */ + + free($3.str); + } + | rdata_ipsec_base trail + ; + +rdata_unknown: URR sp STR sp str_sp_seq trail + { + /* $2 is the number of octects, currently ignored */ + $$ = zparser_conv_hex($5.str, $5.len); + free($5.str); + free($3.str); + } + | URR sp STR trail + { + $$ = zparser_conv_hex("", 0); + free($3.str); + } + | URR error NL + { + $$ = zparser_conv_hex("", 0); + } + ; +%% + +int zp_wrap(void) +{ + return 1; +} + +/* + * Create the parser. + */ +zparser_type *zparser_create() +{ + zparser_type *result = malloc(sizeof(zparser_type)); + if (result == NULL) { + ERR_ALLOC_FAILED; + return NULL; + } + + result->temporary_items = malloc(MAXRDATALEN * + sizeof(knot_rdata_item_t)); + if (result->temporary_items == NULL) { + ERR_ALLOC_FAILED; + free(result); + return NULL; + } + + result->current_rrset = knot_rrset_new(NULL, 0, 0, 0); + if (result->current_rrset == NULL) { + ERR_ALLOC_FAILED; + free(result->temporary_items); + free(result); + return NULL; + } + + result->root_domain = knot_dname_new_from_str(".", 1, NULL); +// printf("THE NEW ROOT: %p\n", result->root_domain); + if (result->root_domain == NULL) { + ERR_ALLOC_FAILED; + free(result->temporary_items); + free(result->current_rrset); + free(result); + return NULL; + } + + return result; +} + +/* + * Initialize the parser for a new zone file. + */ +void +zparser_init(const char *filename, uint32_t ttl, uint16_t rclass, + knot_node_t *origin, knot_dname_t *origin_from_config) +{ + memset(nxtbits, 0, sizeof(nxtbits)); + memset(nsecbits, 0, sizeof(nsecbits)); + nsec_highest_rcode = 0; + + parser->current_zone = NULL; + parser->prev_dname = NULL; + + parser->default_ttl = ttl; + parser->default_class = rclass; + + parser->origin = origin; + parser->prev_dname = NULL;//parser->origin->owner; + + parser->default_apex = origin; + parser->error_occurred = 0; + parser->errors = 0; + parser->line = 1; + parser->filename = filename; + parser->rdata_count = 0; + parser->origin_from_config = origin_from_config; + + parser->last_node = origin; +// parser->root_domain = NULL; + + /* Create zone */ + parser->current_zone = knot_zone_new(origin, 0, 1); + + parser->node_rrsigs = NULL; + parser->rrsig_orphans = NULL; + parser->rrsig_orphan_count = 0; + + parser->current_rrset->rclass = parser->default_class; + parser->current_rrset->rdata = NULL; +} + + +void zparser_free() +{ +// knot_dname_release(parser->root_domain); +// knot_dname_release(parser->prev_dname); + knot_dname_free(&parser->origin_from_config); + free(parser->temporary_items); + if (parser->current_rrset != NULL) { + free(parser->current_rrset); + } + free(parser); +} + +void +yyerror(void *scanner, const char *message) +{ + zc_error("%s", message); +} + +static void +error_va_list(unsigned line, const char *fmt, va_list args) +{ + if (parser->filename) { + fprintf(stderr, "%s:%u: ", parser->filename, line); + } + fprintf(stderr, "error: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + + ++parser->errors; + parser->error_occurred = 1; +} + +/* the line counting sux, to say the least + * with this grose hack we try do give sane + * numbers back */ +void +zc_error_prev_line(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + error_va_list(parser->line - 1, fmt, args); + va_end(args); +} + +void +zc_error(const char *fmt, ...) +{ + /* send an error message to stderr */ + va_list args; + va_start(args, fmt); + error_va_list(parser->line, fmt, args); + va_end(args); +} + +static void +warning_va_list(unsigned line, const char *fmt, va_list args) +{ + if (parser->filename) { + fprintf(stderr, "%s:%u: ", parser->filename, line); + } + fprintf(stderr, "warning: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); +} + +void +zc_warning_prev_line(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + warning_va_list(parser->line - 1, fmt, args); + va_end(args); +} + +void +zc_warning(const char *fmt, ... ) +{ + va_list args; + va_start(args, fmt); + warning_va_list(parser->line, fmt, args); + va_end(args); +} + +#ifdef NSEC3 +static void +nsec3_add_params(const char* hashalgo_str, const char* flag_str, + const char* iter_str, const char* salt_str, int salt_len) +{ + zadd_rdata_wireformat(zparser_conv_byte(hashalgo_str)); + zadd_rdata_wireformat(zparser_conv_byte(flag_str)); + zadd_rdata_wireformat(zparser_conv_short(iter_str)); + + /* salt */ + if(strcmp(salt_str, "-") != 0) + zadd_rdata_wireformat(zparser_conv_hex_length(salt_str, + salt_len)); + else + zadd_rdata_wireformat(alloc_rdata_init("", 1)); + +} +#endif /* NSEC3 */ |