aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mate/mate_grammar.lemon
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mate/mate_grammar.lemon')
-rw-r--r--plugins/mate/mate_grammar.lemon1175
1 files changed, 1175 insertions, 0 deletions
diff --git a/plugins/mate/mate_grammar.lemon b/plugins/mate/mate_grammar.lemon
new file mode 100644
index 0000000000..6b71a53fa6
--- /dev/null
+++ b/plugins/mate/mate_grammar.lemon
@@ -0,0 +1,1175 @@
+%include {
+
+/* mate_grammar.lemon
+* MATE's configuration language grammar
+*
+* Copyright 2005, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
+*
+* $Id $
+*
+* Ethereal - Network traffic analyzer
+* By Gerald Combs <gerald@ethereal.com>
+* Copyright 1998 Gerald Combs
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "mate.h"
+
+#define DUMMY void*
+
+typedef struct _extraction {
+ gchar* as;
+ header_field_info* hfi;
+ struct _extraction* next;
+ struct _extraction* last;
+} extraction_t;
+
+typedef struct _pdu_flags {
+ gboolean drop_unassigned;
+ gboolean discard;
+ gboolean last_extracted;
+} pdu_flags_t;
+
+typedef struct _pdu_criteria_t {
+ AVPL* criterium_avpl;
+ avpl_match_mode criterium_match_mode;
+ accept_mode_t criterium_accept_mode;
+} pdu_criteria_t;
+
+typedef struct _pdu_statement {
+ GPtrArray* payload;
+ pdu_flags_t* flags;
+ extraction_t* extraction;
+ pdu_criteria_t* criteria;
+ GPtrArray* transforms;
+} pdu_statement_t;
+
+typedef struct _gop_tree_statement {
+ gop_tree_mode_t pdu_tree_mode;
+ gboolean drop_unassigned;
+ gboolean show_times;
+} gop_tree_statement;
+
+typedef struct _gop_timer_statement {
+ float expiration;
+ float idle_timeout;
+ float lifetime;
+} gop_timer_statement;
+
+typedef struct _gop_option_statement {
+ gop_timer_statement* timer_sts;
+ gop_tree_statement* tree_sts;
+} gop_option_statement;
+
+typedef struct _gop_control_statement {
+ AVPL* start;
+ AVPL* stop;
+ AVPL* extras;
+} gop_control_statement;
+
+typedef struct _gop_statement {
+ gop_control_statement* control;
+ gop_option_statement* options;
+ GPtrArray* transforms;
+} gop_statement;
+
+typedef struct _gog_statements {
+ float expiration;
+ gop_tree_mode_t gop_tree_mode;
+ GPtrArray* transform_list;
+ AVPL* extras;
+ LoAL* current_gogkeys;
+} gog_statement_t;
+
+static void configuration_error(mate_config* mc, gchar* fmt, ...) {
+ static gchar error_buffer[256];
+ gchar* incl;
+ gint i;
+ mate_config_frame* current_frame;
+ va_list list;
+
+ va_start( list, fmt );
+ g_vsnprintf(error_buffer,sizeof(error_buffer),fmt,list);
+ va_end( list );
+
+ i = (gint) mc->config_stack->len;
+
+ while (i--) {
+
+ if (i>0) {
+ incl = "\n included from: ";
+ } else {
+ incl = " ";
+ }
+
+ current_frame = g_ptr_array_index(mc->config_stack,(guint)i);
+
+ g_string_sprintfa(mc->config_error,"%s%s at line %u",incl, current_frame->filename, current_frame->linenum);
+ }
+
+ g_string_sprintfa(mc->config_error,": %s\n",error_buffer);
+
+ THROW(MateConfigError);
+
+}
+
+static AVPL_Transf* new_transform_elem(AVPL* match, AVPL* replace, avpl_match_mode match_mode, avpl_replace_mode replace_mode) {
+ AVPL_Transf* t = g_malloc(sizeof(AVPL_Transf));
+
+ t->name = NULL;
+ t->match = match;
+ t->replace = replace;
+ t->match_mode = match_mode;
+ t->replace_mode = replace_mode;
+
+ t->map = NULL;
+ t->next = NULL;
+
+ return t;
+}
+
+static pdu_statement_t* do_pdu_statements(GPtrArray* payload, pdu_flags_t* flags, extraction_t* extraction, pdu_criteria_t* criteria, GPtrArray* transforms) {
+ pdu_statement_t* s = g_malloc(sizeof(pdu_statement_t));
+
+ s->payload = payload;
+ s->flags = flags;
+ s->extraction = extraction;
+ s->criteria = criteria;
+ s->transforms = transforms;
+
+ return s;
+}
+
+static gchar* recolonize(mate_config* mc, gchar* s) {
+ GString* str = g_string_new("");
+ gchar** vec;
+ gchar* r;
+ guint i,v;
+ gchar c;
+
+ vec = g_strsplit(s,":",0);
+
+ for (i = 0; vec[i]; i++) {
+ g_strdown(vec[i]);
+
+ v = 0;
+ switch ( strlen(vec[i]) ) {
+ case 2:
+ c = vec[i][1];
+ vec[i][1] = vec[i][0];
+ vec[i][0] = c;
+ if (vec[i][0] >= '0' && vec[i][0] <= '9') {
+ v += (vec[i][1] - '0' )*16;
+ } else {
+ v += (vec[i][1] - 'a' + 10)*16;
+ }
+ case 1:
+ if (vec[i][0] >= '0' && vec[i][0] <= '9') {
+ v += (vec[i][0] - '0' );
+ } else {
+ v += (vec[i][0] - 'a' + 10);
+ }
+ case 0:
+ break;
+ default:
+ configuration_error(mc,"bad token %s",s);
+ }
+
+ g_string_sprintfa(str,":%.2X",v);
+ }
+
+ g_strfreev(vec);
+
+ g_string_erase(str,0,1);
+
+ r = str->str;
+
+ g_string_free(str,FALSE);
+
+ return r;
+}
+
+}
+
+%name MateParser
+
+%token_prefix TOKEN_
+
+%token_type { gchar* }
+%token_destructor { if ($$) g_free($$); }
+
+%extra_argument { mate_config* mc }
+
+%syntax_error {
+ configuration_error(mc,"Syntax Error before %s",yyminor);
+}
+
+%parse_failure {
+ configuration_error(mc,"Parse Error");
+}
+
+%type transform_decl { AVPL_Transf* }
+%type transform_body { AVPL_Transf* }
+%type transform_statements { AVPL_Transf* }
+%type transform_statement { AVPL_Transf* }
+%type transform_blks { AVPL_Transf* }
+%type transform_blk { AVPL_Transf* }
+%type match_mode { avpl_match_mode }
+%type action_mode { avpl_replace_mode }
+
+%type gop_name { gchar* }
+%type time_value { float }
+%type pdu_name { gchar* }
+%type gop_tree_mode { gop_tree_mode_t }
+%type true_false { gboolean }
+
+%type pdu_setup { pdu_statement_t* }
+%type pdu_statements { pdu_statement_t* }
+
+%type pdu_criteria_statement { pdu_criteria_t* }
+%type pdu_flag_statements { pdu_flags_t* }
+%type accept_mode { accept_mode_t }
+%type drop_unassigned_statement { gboolean }
+%type discard_pdu_data_statement { gboolean }
+%type last_extracted_statement { gboolean }
+
+%type extraction_statement {extraction_t*}
+%type extraction_statements {extraction_t*}
+
+%type gop_setup { gop_statement* }
+%type gop_statements { gop_statement* }
+%type gop_control_statements { gop_control_statement* }
+%type gop_option_statements { gop_option_statement* }
+%type gop_timer_statements { gop_timer_statement* }
+%type gop_tree_statements { gop_tree_statement* }
+
+%type gop_start_statement { AVPL* }
+%type gop_stop_statement { AVPL* }
+%type extra_statement { AVPL* }
+%type show_goptree_statement { gop_tree_mode_t }
+%type show_times_statement { gboolean }
+%type expiration_statement { float }
+%type idle_timeout_statement { float }
+%type lifetime_statement { float }
+
+%type gog_statements { gog_statement_t* }
+%type gog_goptree_statement { gop_tree_mode_t }
+%type gog_key_statements { LoAL* }
+%type gog_key_statement { AVPL* }
+%type transform_list_statement { GPtrArray* }
+%type transform { AVPL_Transf* }
+%type gop_tree_type { gop_tree_mode_t }
+
+%type payload_statement { GPtrArray* }
+%type proto_stack { GPtrArray* }
+%type field { header_field_info* }
+%type transform_list { GPtrArray* }
+%type avpl { AVPL* }
+%type avps { AVPL* }
+%type avp { AVP* }
+%type value { gchar* }
+%type avp_oneoff { gchar* }
+
+
+mate_config ::= decls DONE_KW SEMICOLON.
+
+decls ::= decls decl.
+decls ::= decl.
+
+decl ::= pdu_decl.
+decl ::= gop_decl.
+decl ::= gog_decl.
+decl ::= transform_decl.
+
+/******************************************* TRANSFORM
+*/
+
+transform_decl(A) ::= TRANSFORM_KW NAME(B) transform_body(C) SEMICOLON. {
+ AVPL_Transf* c;
+
+ if ( g_hash_table_lookup(mc->transfs,B) ) {
+ configuration_error(mc,"A transformation called '%s' exists already",B);
+ }
+
+ for ( c = C; c; c = c->next )
+ c->name = g_strdup(B);
+
+ g_hash_table_insert(mc->transfs,C->name,C);
+
+ A = NULL;
+}
+
+transform_body(A) ::= OPEN_BRACE transform_blks(B) CLOSE_BRACE. { A = B; }
+
+transform_blks(A) ::= transform_blks(C) transform_blk(B). {
+ AVPL_Transf* c;
+
+ for ( c = C; c->next; c = c->next ) ;
+ c->next = B;
+ A = C;
+}
+
+transform_blks(A) ::= transform_blk(B). { A = B; }
+
+transform_blk(A) ::= MATCH_KW match_mode(B) avpl(C) action_mode(D) avpl(E) SEMICOLON. {
+ A = new_transform_elem(C,E,B,D);
+}
+
+transform_blk(A) ::= MATCH_KW match_mode(B) avpl(C) SEMICOLON. {
+ A = new_transform_elem(C,new_avpl(""),B,AVPL_INSERT);
+}
+
+transform_blk(A) ::= MATCH_KW avpl(B) action_mode(C) avpl(D) SEMICOLON. {
+ A = new_transform_elem(B,D,AVPL_STRICT,C);
+}
+
+transform_blk(A) ::= action_mode(B) avpl(C) SEMICOLON. {
+ A = new_transform_elem(new_avpl(""),C,AVPL_NO_MATCH,B);
+}
+
+transform_blk(A) ::= MATCH_KW avpl(B) SEMICOLON. {
+ A = new_transform_elem(B,new_avpl(""),AVPL_STRICT,AVPL_INSERT);
+}
+
+match_mode(A) ::= STRICT_KW. { A = AVPL_STRICT; }
+match_mode(A) ::= EVERY_KW. { A = AVPL_EVERY; }
+match_mode(A) ::= LOOSE_KW. { A = AVPL_LOOSE; }
+
+action_mode(A) ::= REPLACE_KW. { A = AVPL_REPLACE; }
+action_mode(A) ::= INSERT_KW. { A = AVPL_INSERT; }
+
+/******************************************* PDU
+*/
+
+pdu_decl ::= PDU_KW NAME(NAME) PROTO_KW field(FIELD) TRANSPORT_KW proto_stack(STACK) pdu_setup(SETUP) SEMICOLON. {
+ mate_cfg_pdu* cfg = new_pducfg(NAME);
+ extraction_t *extraction, *next_extraction;
+
+ if (! cfg ) configuration_error(mc,"could not create Pdu %s.",NAME);
+
+ cfg->hfid_proto = FIELD->id;
+
+ cfg->last_extracted = (SETUP->flags) ? SETUP->flags->last_extracted : mc->defaults.pdu.last_extracted;
+ cfg->discard = (SETUP->flags) ? SETUP->flags->discard : mc->defaults.pdu.discard;
+ cfg->drop_unassigned = (SETUP->flags) ? SETUP->flags->drop_unassigned : mc->defaults.pdu.drop_unassigned;
+
+ g_string_sprintfa(mc->protos_filter,"||%s",FIELD->abbrev);
+
+ cfg->transport_ranges = STACK;
+ cfg->payload_ranges = SETUP->payload;
+
+ if (SETUP->criteria) {
+ cfg->criterium = SETUP->criteria->criterium_avpl;
+ cfg->criterium_match_mode = SETUP->criteria->criterium_match_mode;
+ cfg->criterium_accept_mode = SETUP->criteria->criterium_accept_mode;
+ }
+
+ cfg->transforms = SETUP->transforms ? SETUP->transforms : g_ptr_array_new();
+
+ for (extraction = SETUP->extraction; extraction; extraction = next_extraction) {
+ next_extraction = extraction->next;
+
+ if ( ! add_hfid(extraction->hfi, extraction->as, cfg->hfids_attr) ) {
+ configuration_error(mc,"MATE: failed to create extraction rule '%s'",extraction->as);
+ }
+
+ g_free(extraction);
+ }
+}
+
+pdu_setup(A) ::= OPEN_BRACE pdu_statements(B) CLOSE_BRACE. { A = B; }
+
+
+pdu_statements(A) ::= payload_statement(B) pdu_flag_statements(C) extraction_statements(D) pdu_criteria_statement(E) transform_list_statement(F). { A = do_pdu_statements(B,C,D,E,F); }
+pdu_statements(A) ::= payload_statement(B) pdu_flag_statements(C) extraction_statements(D) pdu_criteria_statement(E). { A = do_pdu_statements(B,C,D,E,NULL); }
+pdu_statements(A) ::= payload_statement(B) pdu_flag_statements(C) extraction_statements(D) transform_list_statement(F). { A = do_pdu_statements(B,C,D,NULL,F); }
+pdu_statements(A) ::= payload_statement(B) pdu_flag_statements(C) extraction_statements(D). { A = do_pdu_statements(B,C,D,NULL,NULL); }
+pdu_statements(A) ::= payload_statement(B) extraction_statements(D) pdu_criteria_statement(E) transform_list_statement(F). { A = do_pdu_statements(B,NULL,D,E,F); }
+pdu_statements(A) ::= payload_statement(B) extraction_statements(D) pdu_criteria_statement(E). { A = do_pdu_statements(B,NULL,D,E,NULL); }
+pdu_statements(A) ::= payload_statement(B) extraction_statements(D) transform_list_statement(F). { A = do_pdu_statements(B,NULL,D,NULL,F); }
+pdu_statements(A) ::= payload_statement(B) extraction_statements(D). { A = do_pdu_statements(B,NULL,D,NULL,NULL); }
+pdu_statements(A) ::= pdu_flag_statements(C) extraction_statements(D) pdu_criteria_statement(E) transform_list_statement(F). { A = do_pdu_statements(NULL,C,D,E,F); }
+pdu_statements(A) ::= pdu_flag_statements(C) extraction_statements(D) pdu_criteria_statement(E). { A = do_pdu_statements(NULL,C,D,E,NULL); }
+pdu_statements(A) ::= pdu_flag_statements(C) extraction_statements(D) transform_list_statement(F). { A = do_pdu_statements(NULL,C,D,NULL,F); }
+pdu_statements(A) ::= pdu_flag_statements(C) extraction_statements(D). { A = do_pdu_statements(NULL,C,D,NULL,NULL); }
+pdu_statements(A) ::= extraction_statements(D) pdu_criteria_statement(E) transform_list_statement(F). { A = do_pdu_statements(NULL,NULL,D,E,F); }
+pdu_statements(A) ::= extraction_statements(D) pdu_criteria_statement(E). { A = do_pdu_statements(NULL,NULL,D,E,NULL); }
+pdu_statements(A) ::= extraction_statements(D) transform_list_statement(F). { A = do_pdu_statements(NULL,NULL,D,NULL,F); }
+pdu_statements(A) ::= extraction_statements(D). { A = do_pdu_statements(NULL,NULL,D,NULL,NULL); }
+
+pdu_flag_statements(A) ::= drop_unassigned_statement(B) discard_pdu_data_statement(C) last_extracted_statement(D). {
+ A = g_malloc(sizeof(pdu_flags_t));
+
+ A->drop_unassigned = B;
+ A->discard = C;
+ A->last_extracted = D;
+}
+
+pdu_flag_statements(A) ::= drop_unassigned_statement(B) discard_pdu_data_statement(C). {
+ A = g_malloc(sizeof(pdu_flags_t));
+
+ A->drop_unassigned = B;
+ A->discard = C;
+ A->last_extracted = mc->defaults.pdu.last_extracted;
+}
+
+pdu_flag_statements(A) ::= drop_unassigned_statement(B) last_extracted_statement(D). {
+ A = g_malloc(sizeof(pdu_flags_t));
+
+ A->drop_unassigned = B;
+ A->discard = mc->defaults.pdu.discard;
+ A->last_extracted = D;
+}
+
+pdu_flag_statements(A) ::= discard_pdu_data_statement(C) last_extracted_statement(D). {
+ A = g_malloc(sizeof(pdu_flags_t));
+
+ A->drop_unassigned = mc->defaults.pdu.drop_unassigned;
+ A->discard = C;
+ A->last_extracted = D;
+}
+
+pdu_flag_statements(A) ::= last_extracted_statement(D). {
+ A = g_malloc(sizeof(pdu_flags_t));
+
+ A->drop_unassigned = mc->defaults.pdu.drop_unassigned;
+ A->discard = mc->defaults.pdu.discard;
+ A->last_extracted = D;
+}
+
+pdu_flag_statements(A) ::= discard_pdu_data_statement(C). {
+ A = g_malloc(sizeof(pdu_flags_t));
+
+ A->drop_unassigned = mc->defaults.pdu.drop_unassigned;
+ A->discard = C;
+ A->last_extracted = mc->defaults.pdu.last_extracted;
+}
+
+pdu_flag_statements(A) ::= drop_unassigned_statement(B). {
+ A = g_malloc(sizeof(pdu_flags_t));
+
+ A->drop_unassigned = B;
+ A->discard = mc->defaults.pdu.discard;
+ A->last_extracted = mc->defaults.pdu.last_extracted;
+}
+
+
+payload_statement(A) ::= PAYLOAD_KW proto_stack(B) SEMICOLON. { A = B; }
+
+pdu_criteria_statement(A) ::= CRITERIA_KW accept_mode(B) match_mode(C) avpl(D) SEMICOLON. {
+ A = g_malloc(sizeof(pdu_criteria_t));
+ A->criterium_avpl = D;
+ A->criterium_match_mode = C;
+ A->criterium_accept_mode = B;
+}
+
+accept_mode(A) ::= ACCEPT_KW. { A = ACCEPT_MODE; }
+accept_mode(A) ::= REJECT_KW. { A = REJECT_MODE; }
+
+extraction_statements(A) ::= extraction_statements(B) extraction_statement(C). {
+ A = B;
+ A->last->next = C;
+ A->last = C;
+}
+
+extraction_statements(A) ::= extraction_statement(B). {
+ A = B;
+ A->last = A;
+}
+
+extraction_statement(A) ::= EXTRACT_KW NAME(NAME) FROM_KW field(FIELD) SEMICOLON. {
+ A = g_malloc(sizeof(extraction_t));
+ A->as = NAME;
+ A->hfi = FIELD;
+ A->next = A->last = NULL;
+}
+
+
+drop_unassigned_statement(A) ::= DROP_UNASSIGNED_KW true_false(B) SEMICOLON. { A = B; }
+
+discard_pdu_data_statement(A) ::= DISCARD_PDU_DATA_KW true_false(B) SEMICOLON. { A = B; }
+
+last_extracted_statement(A) ::= LAST_PDU_KW true_false(B) SEMICOLON. { A = B; }
+
+proto_stack(A) ::= proto_stack(B) SLASH field(C). {
+ int* hfidp = g_malloc(sizeof(int));
+
+ g_string_sprintfa(mc->fields_filter,"||%s",C->abbrev);
+
+ *hfidp = C->id;
+ g_ptr_array_add(B,hfidp);
+ A = B;
+}
+
+proto_stack(A) ::= field(B). {
+ int* hfidp = g_malloc(sizeof(int));
+ *hfidp = B->id;
+
+ g_string_sprintfa(mc->fields_filter,"||%s",B->abbrev);
+
+ A = g_ptr_array_new();
+ g_ptr_array_add(A,hfidp);
+}
+
+field(A) ::= NAME(B). {
+ A = proto_registrar_get_byname(B);
+}
+
+
+
+/******************************************* GOP
+*/
+
+gop_decl(A) ::= GOP_KW NAME(B) ON_KW pdu_name(C) MATCH_KW avpl(D) gop_setup(E) SEMICOLON. {
+ mate_cfg_gop* cfg;
+
+ if (g_hash_table_lookup(mc->gopcfgs,B)) configuration_error(mc,"A Gop Named '%s' exists already.",B);
+ if (g_hash_table_lookup(mc->gops_by_pduname,C) ) configuration_error(mc,"Gop for Pdu '%s' exists already",C);
+
+ cfg = new_gopcfg(B);
+ g_hash_table_insert(mc->gops_by_pduname,C,cfg);
+ g_hash_table_insert(mc->gopcfgs,cfg->name,cfg);
+ cfg->on_pdu = C;
+
+ cfg->drop_unassigned = (E->options && E->options->tree_sts) ? E->options->tree_sts->drop_unassigned : mc->defaults.gop.drop_unassigned;
+ cfg->show_times = (E->options && E->options->tree_sts) ? E->options->tree_sts->show_times : mc->defaults.gop.show_times;
+ cfg->pdu_tree_mode = (E->options && E->options->tree_sts) ? E->options->tree_sts->pdu_tree_mode : mc->defaults.gop.pdu_tree_mode;
+
+ cfg->expiration = (E->options && E->options->timer_sts) ? E->options->timer_sts->expiration : mc->defaults.gop.expiration;
+ cfg->idle_timeout = (E->options && E->options->timer_sts) ? E->options->timer_sts->idle_timeout : mc->defaults.gop.idle_timeout;
+ cfg->lifetime = (E->options && E->options->timer_sts) ? E->options->timer_sts->lifetime : mc->defaults.gop.lifetime;
+
+ cfg->start = E->control ? E->control->start : NULL;
+ cfg->stop = E->control ? E->control->stop : NULL;
+ cfg->key = D;
+
+ cfg->transforms = (E->transforms) ? E->transforms : g_ptr_array_new();
+
+ if (E->control && E->control->extras) {
+ merge_avpl(cfg->extra,E->control->extras,TRUE);
+ delete_avpl(E->control->extras,TRUE);
+ }
+
+ if (E->control) g_free(E->control);
+
+ if (E->options) {
+ if (E->options->tree_sts) g_free(E->options->tree_sts);
+ if (E->options->timer_sts) g_free(E->options->timer_sts);
+ if (E->options) g_free(E->options);
+ }
+
+ g_free(E);
+}
+
+
+gop_decl(A) ::= GOP_KW NAME(B) ON_KW pdu_name(C) MATCH_KW avpl(D) SEMICOLON. {
+ mate_cfg_gop* cfg;
+
+ if (g_hash_table_lookup(mc->gopcfgs,B)) configuration_error(mc,"A Gop Named '%s' exists already.",B);
+ if (g_hash_table_lookup(mc->gops_by_pduname,C) ) configuration_error(mc,"Gop for Pdu '%s' exists already",C);
+
+ cfg = new_gopcfg(B);
+ g_hash_table_insert(mc->gops_by_pduname,C,cfg);
+ g_hash_table_insert(mc->gopcfgs,cfg->name,cfg);
+
+ cfg->drop_unassigned = mc->defaults.gop.drop_unassigned;
+ cfg->show_times = mc->defaults.gop.show_times;
+ cfg->pdu_tree_mode = mc->defaults.gop.pdu_tree_mode;
+
+ cfg->expiration = mc->defaults.gop.expiration;
+ cfg->idle_timeout = mc->defaults.gop.idle_timeout;
+ cfg->lifetime = mc->defaults.gop.lifetime;
+
+ cfg->start = NULL;
+ cfg->stop = NULL;
+ cfg->key = D;
+
+ cfg->transforms = g_ptr_array_new();
+}
+
+gop_setup(A) ::= OPEN_BRACE gop_statements(B) CLOSE_BRACE. {
+ A = B;
+}
+
+gop_statements(A) ::= gop_control_statements(B) gop_option_statements(C) transform_list_statement(E). {
+ A = g_malloc(sizeof(gop_statement));
+
+ A->control = B;
+ A->options = C;
+ A->transforms = E;
+}
+
+gop_statements(A) ::= gop_option_statements(C) transform_list_statement(E). {
+ A = g_malloc(sizeof(gop_statement));
+
+ A->control = NULL;
+ A->options = C;
+ A->transforms = E;
+}
+
+gop_statements(A) ::= gop_control_statements(B) transform_list_statement(E). {
+ A = g_malloc(sizeof(gop_statement));
+
+ A->control = B;
+ A->options = NULL;
+ A->transforms = E;
+}
+
+gop_statements(A) ::= gop_control_statements(B) gop_option_statements(C). {
+ A = g_malloc(sizeof(gop_statement));
+
+ A->control = B;
+ A->options = C;
+ A->transforms = NULL;
+}
+
+
+gop_statements(A) ::= gop_option_statements(C). {
+ A = g_malloc(sizeof(gop_statement));
+
+ A->control = NULL;
+ A->options = C;
+ A->transforms = NULL;
+}
+
+gop_statements(A) ::= gop_control_statements(B). {
+ A = g_malloc(sizeof(gop_statement));
+
+ A->control = B;
+ A->options = NULL;
+ A->transforms = NULL;
+}
+
+gop_statements(A) ::= transform_list_statement(E). {
+ A = g_malloc(sizeof(gop_statement));
+
+ A->control = NULL;
+ A->options = NULL;
+ A->transforms = E;
+}
+
+
+
+
+gop_control_statements(A) ::= gop_start_statement(B) gop_stop_statement(C) extra_statement(D).{
+ A = g_malloc(sizeof(gop_control_statement));
+
+ A->start = B;
+ A->stop = C;
+ A->extras = D;
+}
+
+
+gop_control_statements(A) ::= gop_stop_statement(C) extra_statement(D).{
+ A = g_malloc(sizeof(gop_control_statement));
+
+ A->start = NULL;
+ A->stop = C;
+ A->extras = D;
+}
+
+gop_control_statements(A) ::= gop_start_statement(B) extra_statement(D).{
+ A = g_malloc(sizeof(gop_control_statement));
+
+ A->start = B;
+ A->stop = NULL;
+ A->extras = D;
+}
+
+gop_control_statements(A) ::= gop_start_statement(B) gop_stop_statement(C).{
+ A = g_malloc(sizeof(gop_control_statement));
+
+ A->start = B;
+ A->stop = C;
+ A->extras = NULL;
+}
+
+
+gop_control_statements(A) ::= gop_start_statement(B).{
+ A = g_malloc(sizeof(gop_control_statement));
+
+ A->start = B;
+ A->stop = NULL;
+ A->extras = NULL;
+}
+
+gop_control_statements(A) ::= gop_stop_statement(C).{
+ A = g_malloc(sizeof(gop_control_statement));
+
+ A->start = NULL;
+ A->stop = C;
+ A->extras = NULL;
+}
+
+gop_control_statements(A) ::= extra_statement(D). {
+ A = g_malloc(sizeof(gop_control_statement));
+
+ A->start = NULL;
+ A->stop = NULL;
+ A->extras = D;
+}
+
+
+
+
+gop_option_statements(A) ::= gop_timer_statements(B) gop_tree_statements(C). {
+ A = g_malloc(sizeof(gop_control_statement));
+
+ A->timer_sts = B;
+ A->tree_sts = C;
+}
+
+gop_option_statements(A) ::= gop_timer_statements(B). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->timer_sts = B;
+ A->tree_sts = NULL;
+
+}
+
+gop_option_statements(A) ::= gop_tree_statements(C). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->tree_sts = C;
+ A->timer_sts = NULL;
+
+}
+
+
+
+gop_timer_statements(A) ::= expiration_statement(B) idle_timeout_statement(C) lifetime_statement(D). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->expiration = B;
+ A->idle_timeout = C;
+ A->lifetime = D;
+}
+
+
+gop_timer_statements(A) ::= expiration_statement(B) idle_timeout_statement(C). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->expiration = B;
+ A->idle_timeout = C;
+ A->lifetime = mc->defaults.gop.lifetime;
+}
+
+gop_timer_statements(A) ::= expiration_statement(B) lifetime_statement(D). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->expiration = B;
+ A->idle_timeout = mc->defaults.gop.lifetime;
+ A->lifetime = D;
+}
+
+gop_timer_statements(A) ::= idle_timeout_statement(C) lifetime_statement(D). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->expiration = mc->defaults.gop.lifetime;
+ A->idle_timeout = C;
+ A->lifetime = D;
+}
+
+gop_timer_statements(A) ::= expiration_statement(B). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->expiration = B;
+ A->idle_timeout = mc->defaults.gop.lifetime;
+ A->lifetime = mc->defaults.gop.lifetime;
+}
+
+gop_timer_statements(A) ::= idle_timeout_statement(C). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->expiration = mc->defaults.gop.lifetime;
+ A->idle_timeout = C;
+ A->lifetime = mc->defaults.gop.lifetime;
+}
+
+gop_timer_statements(A) ::= lifetime_statement(D). {
+ A = g_malloc(sizeof(gop_timer_statement));
+
+ A->expiration = mc->defaults.gop.lifetime;
+ A->idle_timeout = mc->defaults.gop.lifetime;
+ A->lifetime = D;
+}
+
+
+
+
+gop_tree_statements(A) ::= drop_unassigned_statement(B) show_goptree_statement(C) show_times_statement(D). {
+ A = g_malloc(sizeof(gop_tree_statement));
+
+ A->drop_unassigned = B;
+ A->pdu_tree_mode = C;
+ A->show_times = D;
+}
+
+gop_tree_statements(A) ::= drop_unassigned_statement(B) show_goptree_statement(C). {
+ A = g_malloc(sizeof(gop_tree_statement));
+
+ A->drop_unassigned = B;
+ A->pdu_tree_mode = C;
+ A->show_times = mc->defaults.gop.show_times;
+}
+
+gop_tree_statements(A) ::= drop_unassigned_statement(B) show_times_statement(D). {
+ A = g_malloc(sizeof(gop_tree_statement));
+
+ A->drop_unassigned = B;
+ A->pdu_tree_mode = mc->defaults.gop.pdu_tree_mode;
+ A->show_times = D;
+}
+
+gop_tree_statements(A) ::= show_goptree_statement(C) show_times_statement(D). {
+ A = g_malloc(sizeof(gop_tree_statement));
+
+ A->drop_unassigned = mc->defaults.gop.drop_unassigned;
+ A->pdu_tree_mode = C;
+ A->show_times = D;
+}
+
+gop_tree_statements(A) ::= drop_unassigned_statement(B). {
+ A = g_malloc(sizeof(gop_tree_statement));
+
+ A->drop_unassigned = B;
+ A->pdu_tree_mode = mc->defaults.gop.pdu_tree_mode;
+ A->show_times = mc->defaults.gop.show_times;
+}
+
+gop_tree_statements(A) ::= show_goptree_statement(C). {
+ A = g_malloc(sizeof(gop_tree_statement));
+
+ A->drop_unassigned = mc->defaults.gop.drop_unassigned;
+ A->pdu_tree_mode = C;
+ A->show_times = mc->defaults.gop.show_times;
+}
+
+gop_tree_statements(A) ::= show_times_statement(D). {
+ A = g_malloc(sizeof(gop_tree_statement));
+
+ A->drop_unassigned = mc->defaults.gop.drop_unassigned;
+ A->pdu_tree_mode = mc->defaults.gop.pdu_tree_mode;
+ A->show_times = D;
+}
+
+
+gop_start_statement(A) ::= START_KW avpl(B) SEMICOLON. { A = B; }
+
+gop_stop_statement(A) ::= STOP_KW avpl(B) SEMICOLON. { A = B; }
+
+show_goptree_statement(A) ::= SHOW_TREE_KW gop_tree_mode(B) SEMICOLON. { A = B; }
+
+show_times_statement(A) ::= SHOW_TIMES_KW true_false(B) SEMICOLON. { A = B; }
+
+expiration_statement(A) ::= EXPIRATION_KW time_value(B) SEMICOLON. { A = B; }
+
+idle_timeout_statement(A) ::= IDLE_TIMEOUT_KW time_value(B) SEMICOLON. { A = B; }
+
+lifetime_statement(A) ::= LIFETIME_KW time_value(B) SEMICOLON. { A = B; }
+
+gop_tree_mode(A) ::= NO_TREE_KW. { A = GOP_NO_TREE; }
+gop_tree_mode(A) ::= PDU_TREE_KW. { A = GOP_PDU_TREE; }
+gop_tree_mode(A) ::= FRAME_TREE_KW. { A = GOP_FRAME_TREE; }
+gop_tree_mode(A) ::= BASIC_TREE_KW. { A = GOP_BASIC_PDU_TREE; }
+
+true_false(A) ::= TRUE_KW. { A = TRUE; }
+true_false(A) ::= FALSE_KW. { A = FALSE; }
+
+pdu_name(A) ::= NAME(B). {
+ mate_cfg_pdu* c;
+ if (( c = g_hash_table_lookup(mc->pducfgs,B) )) {
+ A = c->name;
+ } else {
+ configuration_error(mc,"No such Pdu: '%s'",B);
+ }
+}
+
+
+time_value(A) ::= FLOATING(B). {
+ A = (float) strtod(B,NULL);
+}
+
+time_value(A) ::= INTEGER(B). {
+ A = (float) strtod(B,NULL);
+}
+
+/************* GOG
+*/
+
+gog_decl ::= GOG_KW NAME(A) OPEN_BRACE gog_statements(B) CLOSE_BRACE SEMICOLON. {
+ mate_cfg_gog* cfg = NULL;
+
+ if ( g_hash_table_lookup(mc->gogcfgs,A) ) {
+ configuration_error(mc,"Gog '%s' exists already ",A);
+ }
+
+ cfg = new_gogcfg(A);
+
+ cfg->expiration = B->expiration;
+ cfg->gop_tree_mode = B->gop_tree_mode;
+ cfg->transforms = B->transform_list ? B->transform_list : g_ptr_array_new();
+ cfg->keys = B->current_gogkeys;
+
+ if (B->extras) {
+ merge_avpl(cfg->extra,B->extras,TRUE);
+ delete_avpl(B->extras,TRUE);
+ }
+
+ g_free(B);
+}
+
+gog_statements(A) ::= expiration_statement(B) gog_goptree_statement(C) gog_key_statements(D) extra_statement(E) transform_list_statement(F). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = B;
+ A->gop_tree_mode = C;
+ A->current_gogkeys = D;
+ A->extras = E;
+ A->transform_list = F;
+}
+
+gog_statements(A) ::= expiration_statement(B) gog_goptree_statement(C) gog_key_statements(D) transform_list_statement(F). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = B;
+ A->gop_tree_mode = C;
+ A->current_gogkeys = D;
+ A->extras = new_avpl("");
+ A->transform_list = F;
+}
+
+gog_statements(A) ::= expiration_statement(B) gog_key_statements(D) extra_statement(E) transform_list_statement(F). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = B;
+ A->gop_tree_mode = mc->defaults.gog.gop_tree_mode;
+ A->current_gogkeys = D;
+ A->extras = E;
+ A->transform_list = F;
+}
+
+gog_statements(A) ::= expiration_statement(B) gog_key_statements(D) transform_list_statement(F). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = B;
+ A->gop_tree_mode = mc->defaults.gog.gop_tree_mode;
+ A->current_gogkeys = D;
+ A->extras = new_avpl("");
+ A->transform_list = F;
+}
+
+gog_statements(A) ::= gog_goptree_statement(C) gog_key_statements(D) extra_statement(E) transform_list_statement(F). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = mc->defaults.gog.expiration;
+ A->gop_tree_mode = C;
+ A->current_gogkeys = D;
+ A->extras = E;
+ A->transform_list = F;
+}
+
+gog_statements(A) ::= gog_goptree_statement(C) gog_key_statements(D) transform_list_statement(F). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = mc->defaults.gog.expiration;
+ A->gop_tree_mode = C;
+ A->current_gogkeys = D;
+ A->extras = new_avpl("");
+ A->transform_list = F;
+}
+
+gog_statements(A) ::= gog_key_statements(D) extra_statement(E) transform_list_statement(F). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = mc->defaults.gog.expiration;
+ A->gop_tree_mode = mc->defaults.gog.gop_tree_mode;
+ A->current_gogkeys = D;
+ A->extras = E;
+ A->transform_list = F;
+}
+
+gog_statements(A) ::= gog_key_statements(D) transform_list_statement(F). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = mc->defaults.gog.expiration;
+ A->gop_tree_mode = mc->defaults.gog.gop_tree_mode;
+ A->current_gogkeys = D;
+ A->extras = new_avpl("");
+ A->transform_list = F;
+}
+
+
+gog_statements(A) ::= expiration_statement(B) gog_goptree_statement(C) gog_key_statements(D) extra_statement(E). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = B;
+ A->gop_tree_mode = C;
+ A->current_gogkeys = D;
+ A->extras = E;
+ A->transform_list = NULL;
+}
+
+gog_statements(A) ::= expiration_statement(B) gog_goptree_statement(C) gog_key_statements(D). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = B;
+ A->gop_tree_mode = C;
+ A->current_gogkeys = D;
+ A->extras = new_avpl("");
+ A->transform_list = NULL;
+}
+
+gog_statements(A) ::= expiration_statement(B) gog_key_statements(D) extra_statement(E). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = B;
+ A->gop_tree_mode = mc->defaults.gog.gop_tree_mode;
+ A->current_gogkeys = D;
+ A->extras = E;
+ A->transform_list = NULL;
+}
+
+gog_statements(A) ::= expiration_statement(B) gog_key_statements(D). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = B;
+ A->gop_tree_mode = mc->defaults.gog.gop_tree_mode;
+ A->current_gogkeys = D;
+ A->extras = new_avpl("");
+ A->transform_list = NULL;
+}
+
+
+gog_statements(A) ::= gog_goptree_statement(C) gog_key_statements(D) extra_statement(E). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = mc->defaults.gog.expiration;
+ A->gop_tree_mode = C;
+ A->current_gogkeys = D;
+ A->extras = E;
+ A->transform_list = NULL;
+}
+
+gog_statements(A) ::= gog_goptree_statement(C) gog_key_statements(D). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = mc->defaults.gog.expiration;
+ A->gop_tree_mode = C;
+ A->current_gogkeys = D;
+ A->extras = new_avpl("");
+ A->transform_list = NULL;
+}
+
+gog_statements(A) ::= gog_key_statements(D) extra_statement(E). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = mc->defaults.gog.expiration;
+ A->gop_tree_mode = mc->defaults.gog.gop_tree_mode;
+ A->current_gogkeys = D;
+ A->extras = E;
+ A->transform_list = NULL;
+}
+
+gog_statements(A) ::= gog_key_statements(D). {
+ A = g_malloc(sizeof(gog_statement_t));
+
+ A->expiration = mc->defaults.gog.expiration;
+ A->gop_tree_mode = mc->defaults.gog.gop_tree_mode;
+ A->current_gogkeys = D;
+ A->extras = new_avpl("");
+ A->transform_list = NULL;
+}
+
+gog_goptree_statement(A) ::= GOP_TREE_KW gop_tree_type(B) SEMICOLON. { A = B; }
+
+gop_tree_type(A) ::= NULL_TREE. { A = GOP_NULL_TREE; }
+gop_tree_type(A) ::= FULL_TREE. { A = GOP_FULL_TREE; }
+gop_tree_type(A) ::= BASIC_TREE. { A = GOP_BASIC_TREE; }
+
+
+gog_key_statements(A) ::= gog_key_statements(B) gog_key_statement(C). {
+ loal_append(B,C);
+ A = B;
+}
+
+gog_key_statements(A) ::= gog_key_statement(B). {
+ A = new_loal("");
+ loal_append(A,B);
+}
+
+
+gog_key_statement(A) ::= MEMBER_KW gop_name(B) avpl(C) SEMICOLON. {
+ rename_avpl(C,B);
+ A = C;
+}
+
+gop_name(A) ::= NAME(B). {
+ mate_cfg_gop* c;
+ if (( c = g_hash_table_lookup(mc->gopcfgs,B) )) {
+ A = c->name;
+ } else {
+ configuration_error(mc,"No Gop called '%s' has been already declared",B);
+ }
+}
+/******************************************** GENERAL
+*/
+
+
+extra_statement(A) ::= EXTRA_KW avpl(B) SEMICOLON. { A = B; }
+
+transform_list_statement(A) ::= TRANSFORM_KW transform_list(B) SEMICOLON. { A = B; }
+
+transform_list(A) ::= transform_list(B) COMMA transform(C). {
+ A = B;
+ g_ptr_array_add(B,C);
+}
+
+transform_list(A) ::= transform(B). {
+ A = g_ptr_array_new();
+ g_ptr_array_add(A,B);
+}
+
+transform(A) ::= NAME(B). {
+ AVPL_Transf* t;
+
+ if (( t = g_hash_table_lookup(mc->transfs,B) )) {
+ A = t;
+ } else {
+ configuration_error(mc,"There's no such Transformation: %s",B);
+ }
+}
+
+avpl(A) ::= OPEN_PARENS avps(B) CLOSE_PARENS. { A = B; }
+avpl(A) ::= OPEN_PARENS CLOSE_PARENS. { A = new_avpl(""); }
+
+avps(A) ::= avps(B) COMMA avp(C). { A = B; if ( ! insert_avp(B,C) ) delete_avp(C); }
+avps(A) ::= avp(B). { A = new_avpl(""); if ( ! insert_avp(A,B) ) delete_avp(B); }
+
+avp(A) ::= NAME(B) AVP_OPERATOR(C) value(D). { A = new_avp(B,D,*C); }
+avp(A) ::= NAME(B). { A = new_avp(B,"",'?'); }
+avp(A) ::= NAME(B) OPEN_BRACE avp_oneoff(C) CLOSE_BRACE. { A = new_avp(B,C,'|'); }
+
+avp_oneoff(A) ::= avp_oneoff(B) PIPE value(C). { A = g_strdup_printf("%s|%s",B,C); }
+avp_oneoff(A) ::= value(B). { A = g_strdup(B); }
+
+value(A) ::= QUOTED(B). { A = g_strdup(B); }
+value(A) ::= NAME(B). { A = g_strdup(B); }
+value(A) ::= FLOATING(B). { A = g_strdup(B); }
+value(A) ::= INTEGER(B). { A = g_strdup(B); }
+value(A) ::= DOTED_IP(B). { A = g_strdup(B); }
+value(A) ::= COLONIZED(B). { A = recolonize(mc,B); }
+