MATE has a grammar.
authorlego <lego@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 16 May 2005 13:28:35 +0000 (13:28 +0000)
committerlego <lego@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 16 May 2005 13:28:35 +0000 (13:28 +0000)
Although not yet fully implemented I want this version as a reference.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@14373 f5534014-38df-0310-8fa8-9805f1628bb7

plugins/mate/Makefile.am
plugins/mate/mate.h
plugins/mate/mate_grammar.lemon [new file with mode: 0644]
plugins/mate/mate_parser.l [new file with mode: 0644]
plugins/mate/mate_plugin.c
plugins/mate/mate_runtime.c
plugins/mate/mate_setup.c
plugins/mate/mate_util.c
plugins/mate/mate_util.h
plugins/mate/moduleinfo.h
plugins/mate/packet-mate.c

index 2b6fd02673f01a48478cc51a6eaa632693bb6404..266d308fa28f9f51076bcc8dae59e6131dcf9693 100644 (file)
@@ -27,7 +27,8 @@ INCLUDES = -I$(top_srcdir)
 plugindir = @plugindir@
 
 plugin_LTLIBRARIES = mate.la
-mate_la_SOURCES = moduleinfo.h mate.h  mate_util.h packet-mate.c mate_runtime.c mate_setup.c mate_util.c mate_plugin.c
+mate_la_SOURCES = moduleinfo.h mate.h  mate_util.h mate_grammar.h \
+                  packet-mate.c mate_runtime.c mate_setup.c mate_util.c mate_plugin.c mate_grammar.c mate_parser.c
 mate_la_LDFLAGS = -module -avoid-version
 mate_la_LIBADD = @PLUGIN_LIBS@
 
@@ -41,4 +42,17 @@ CLEANFILES = \
        *~
 
 EXTRA_DIST = \
+       mate_grammar.lemon \
+       mate_parser.l \
        Makefile.nmake
+
+mate_parser.c : mate_parser.l
+       $(LEX) -Pdf_ -omate_parser.c $(srcdir)/mate_parser.l
+
+LEMON = ../../tools/lemon
+
+mate_grammar.h : mate_grammar.c
+mate_grammar.c : mate_grammar.lemon mate.h mate_util.h
+       $(LEMON)/lemon t=$(srcdir)/$(LEMON)/lempar.c $(srcdir)/mate_grammar.lemon || \
+               (rm -f grammar.c grammar.h ; false)
+
index 266d57b8901b65bbbfc4b6d20ab67515c01e25ed..32a7b4ee75a46a9dfc1e3c0cea1b6c9498ae5d79 100644 (file)
 
 #define MATE_ITEM_ID_SIZE 24
 
-/* Config AVP Names */
-#define KEYWORD_ACTION "Action"
-#define KEYWORD_SETTINGS "Settings"
-#define KEYWORD_INCLUDE "Include"
-#define KEYWORD_TRANSFORM "Transform"
-#define KEYWORD_PDU "PduDef"
-#define KEYWORD_PDUCRITERIA "PduCriteria"
-#define KEYWORD_PDUEXTRA "PduExtra"
-#define KEYWORD_PDUTRANSFORM "PduTransform"
-#define KEYWORD_GOP "GopDef"
-#define KEYWORD_GOPSTART "GopStart"
-#define KEYWORD_GOPSTOP "GopStop"
-#define KEYWORD_GOPEXTRA "GopExtra"
-#define KEYWORD_GOPTRANSFORM "GopTransform"
-#define KEYWORD_GOGDEF "GogDef"
-#define KEYWORD_GOGKEY "GogKey"
-#define KEYWORD_GOGEXTRA "GogExtra"
-#define KEYWORD_GOGTRANSFORM "GogTransform"
-#define KEYWORD_NAME "Name"
-#define KEYWORD_ON "On"
-#define KEYWORD_FOR "For"
-#define KEYWORD_FROM "From"
-#define KEYWORD_TO "To"
-#define KEYWORD_MATCH "Match"
-#define KEYWORD_MODE "Mode"
-#define KEYWORD_FILENAME "Filename"
-#define KEYWORD_PROTO "Proto"
-#define KEYWORD_METHOD "Method"
-#define KEYWORD_TRANSPORT "Transport"
-#define KEYWORD_PAYLOAD "Payload"
-#define KEYWORD_STRICT "Strict"
-#define KEYWORD_LOOSE "Loose"
-#define KEYWORD_EVERY "Every"
-#define KEYWORD_REPLACE "Replace"
-#define KEYWORD_INSERT "Insert"
-#define KEYWORD_MAP "Map"
-#define KEYWORD_GOGEXPIRE "GogExpiration"
-#define KEYWORD_GOPTREE "GopTree"
-#define KEYWORD_DISCARDPDU "DiscardPduData"
-#define KEYWORD_LIBPATH "ThingLibPath"
-#define KEYWORD_SHOWPDUTREE "ShowPduTree"
-#define KEYWORD_SHOWGOPTIMES "ShowGopTimes"
-#define KEYWORD_STOP "Stop"
-#define KEYWORD_DROPGOP "DiscardUnassignedGop"
-#define KEYWORD_DROPPDU "DiscardUnassignedPdu"
-#define KEYWORD_LIB "Lib"
-#define KEYWORD_ACCEPT "Accept"
-#define KEYWORD_REJECT "Reject"
-#define KEYWORD_NOTREE "NoTree"
-#define KEYWORD_BASICTREE "BasicTree"
-#define KEYWORD_FULLTREE "FullTree"
-#define KEYWORD_PDUTREE "PduTree"
-#define KEYWORD_FRAMETREE "FrameTree"
-#define KEYWORD_GOPEXPIRATION "GopExpiration"
-#define KEYWORD_GOPIDLETIMEOUT "GopIdleTimeout"
-#define KEYWORD_GOPLIFETIME "GopLifetime"
-
-#define KEYWORD_DEBUGFILENAME "Debug_File"
-#define KEYWORD_DBG_GENERAL "Debug_General"
-#define KEYWORD_DBG_CFG "Debug_Cfg"
-#define KEYWORD_DBG_PDU "Debug_Pdu"
-#define KEYWORD_DBG_GOP "Debug_Gop"
-#define KEYWORD_DBG_GOG "Debug_Gog"
-#ifdef _AVP_DEBUGGING
-#define KEYWORD_DBG_AVPLIB "Debug_AVP_Lib"
-#define KEYWORD_DBG_AVP "Debug_AVP"
-#define KEYWORD_DBG_AVP_OP "Debug_AVP_Op"
-#define KEYWORD_DBG_AVPL "Debug_AVPL"
-#define KEYWORD_DBG_AVPL_OP "Debug_AVPL_Op"
-#endif
-
 #define VALUE_TOO ((void*)1)
 
-typedef enum _mate_item_type {
-       MATE_UNK_TYPE,
-       MATE_PDU_TYPE,
-       MATE_GOP_TYPE,
-       MATE_GOG_TYPE
-} mate_item_type;
-
-typedef struct _mate_cfg_item mate_cfg_pdu;
-typedef struct _mate_cfg_item mate_cfg_gop;
-typedef struct _mate_cfg_item mate_cfg_gog;
-
-typedef struct _mate_item mate_item;
-typedef struct _mate_item mate_pdu;
-typedef struct _mate_item mate_gop;
-typedef struct _mate_item mate_gog;
-
-typedef struct _mate_cfg_item {
-       guint8* name;
-       mate_item_type type; 
-       GPtrArray* transforms; /* transformations to be applied */
-       AVPL* extra; /* attributes to be added */
+#define MateConfigError 65535
+
+typedef enum _gop_tree_mode_t {
+       GOP_NULL_TREE,
+       GOP_BASIC_TREE,
+       GOP_FULL_TREE
+} gop_tree_mode_t;
+
+typedef enum _gop_pdu_tree {
+       GOP_NO_TREE,
+       GOP_PDU_TREE,
+       GOP_FRAME_TREE,
+       GOP_BASIC_PDU_TREE
+} gop_pdu_tree_t;
+
+typedef enum _accept_mode_t {
+       ACCEPT_MODE,
+       REJECT_MODE
+} accept_mode_t;
+
+
+typedef struct _mate_cfg_pdu {
+       gchar* name;
        guint last_id; /* keeps the last id given to an item of this kind */
+
+       GHashTable* items; /* all the items of this type */
+       GPtrArray* transforms; /* transformations to be applied */
+       
        int hfid;
+       
+       int hfid_proto;
+       int hfid_pdu_rel_time;
+       int hfid_pdu_time_in_gop;
+
        GHashTable* my_hfids; /* for creating register info */
-       GHashTable* items; /* all the items of this type */
+       
        gint ett;
        gint ett_attr;
-       gint ett_times;
-       gint ett_children;
-               
-       /* pdu */
-       gboolean discard_pdu_attributes;
-       gboolean last_to_be_created;
-       int hfid_proto;
+       
+       GHashTable* hfids_attr; /* k=hfid v=avp_name */
+
+       gboolean discard;
+       gboolean last_extracted;
+       gboolean drop_unassigned;
+
        GPtrArray* transport_ranges; /* hfids of candidate transport ranges from which to extract attributes */
        GPtrArray* payload_ranges; /* hfids of candidate payload ranges from which to extract attributes */
-       GHashTable* hfids_attr; /* k=hfid v=avp_name */
-       gboolean drop_pdu;
-       avpl_match_mode criterium_match_mode;
-       AVPL* criterium; /* must match to be created */
-       int hfid_pdu_rel_time;
-       int hfid_pdu_time_in_gop;
        
+       avpl_match_mode criterium_match_mode;
+       accept_mode_t criterium_accept_mode;
+       AVPL* criterium;
+} mate_cfg_pdu;
+
+
+typedef struct _mate_cfg_gop {
+       gchar* name;
+       guint last_id; /* keeps the last id given to an item of this kind */
+       GHashTable* items; /* all the items of this type */
+
+       GPtrArray* transforms; /* transformations to be applied */
+       gchar* on_pdu;
+
+       AVPL* key; /* key candidate avpl */
+       AVPL* start; /* start candidate avpl */
+       AVPL* stop;  /* stop candidate avpl */
+       AVPL* extra; /* attributes to be added */
        
-       /* common to gop and gog */
        float expiration;
+       float idle_timeout;
+       float lifetime;
+       
+       gboolean drop_unassigned;
+       gop_pdu_tree_t pdu_tree_mode;
+       gboolean show_times;
+       
+       GHashTable* my_hfids; /* for creating register info */
+       int hfid;
        int hfid_start_time;
        int hfid_stop_time;
        int hfid_last_time;
-       
-       /* gop */
-       AVPL* start; /* start candidate avpl */
-       AVPL* stop;  /* stop candidate avpl */
-       AVPL* key; /* key candidate avpl */
-       guint8* show_pdu_tree;
-       gboolean show_times;
-       gboolean drop_gop; 
-       float idle_timeout;
-       float lifetime; 
        int hfid_gop_pdu;
        int hfid_gop_num_pdus;
        
+       gint ett;
+       gint ett_attr;
+       gint ett_times;
+       gint ett_children;
+       
        GHashTable* gop_index;
        GHashTable* gog_index;
+} mate_cfg_gop;
+
+
+typedef struct _mate_cfg_gog {
+       gchar* name;
+
+       GHashTable* items; /* all the items of this type */
+       guint last_id; /* keeps the last id given to an item of this kind */
        
-       /* gog */
-       guint8* gop_as_subtree;
+       GPtrArray* transforms; /* transformations to be applied */
+
        LoAL* keys;
+       AVPL* extra; /* attributes to be added */
+
+       float expiration;
+       gop_tree_mode_t gop_tree_mode;
+       gboolean show_times;
+       
+       GHashTable* my_hfids; /* for creating register info */
+       int hfid;
        int hfid_gog_num_of_gops;
        int hfid_gog_gop;
        int hfid_gog_gopstart;
        int hfid_gog_gopstop;   
+       int hfid_start_time;
+       int hfid_stop_time;
+       int hfid_last_time;
+       gint ett;
+       gint ett_attr;
+       gint ett_times;
+       gint ett_children;
        gint ett_gog_gop;
-       
-} mate_cfg_item;
+} mate_cfg_gog;
 
 typedef struct _mate_config {
-       /* current defaults */
-       float gog_expiration; /* default expirations for gogs if undefined in gog */
-       gboolean discard_pdu_attributes; /* destroy the pdu's avpl once analyzed */
-       gboolean drop_pdu; /* destroy the pdu if not assign to a gop */
-       gboolean drop_gop; /* destroy the gop if not assign to a gog */
-       guint8* mate_lib_path; /* where to look for "Include" files first */
-       guint8* show_pdu_tree;
-       gboolean show_times;
-       gboolean last_to_be_created;
-       avpl_match_mode match_mode;
-       avpl_replace_mode replace_mode;
-       guint8* gop_as_subtree;
+       gchar* mate_config_file; /* name of the config file */
+
        int hfid_mate;
        
-       float gop_expiration;
-       float gop_idle_timeout;
-       float gop_lifetime;
+       GString* fields_filter; /* "ip.addr || dns.id || ... " for the tap */
+       GString* protos_filter; /* "dns || ftp || ..." for the tap */
+       gchar* tap_filter;
        
-       /* text "constants" */
-       guint8* accept;
-       guint8* reject;
-       guint8* no_tree;
-       guint8* frame_tree;
-       guint8* pdu_tree;
-       guint8* full_tree;
-       guint8* basic_tree;
+       FILE* dbg_facility; /* where to dump dbgprint output g_message if null */
        
-       /* what to dbgprint */
-       int dbg_lvl;    
-       int dbg_cfg_lvl;
-       int dbg_pdu_lvl;
-       int dbg_gop_lvl;
-       int dbg_gog_lvl;
+       gchar* mate_lib_path; /* where to look for "Include" files first */
        
-       guint8* mate_config_file; /* name of the config file */
-       GString* mate_attrs_filter; /* "ip.addr || dns.id || ... " for the tap */
-       GString* mate_protos_filter; /* "dns || ftp || ..." for the tap */
-       FILE* dbg_facility; /* where to dump dbgprint output g_message if null */
-       guint8* tap_filter;
-                       
        GHashTable* pducfgs; /* k=pducfg->name v=pducfg */
        GHashTable* gopcfgs; /* k=gopcfg->name v=gopcfg */
        GHashTable* gogcfgs; /* k=gogcfg->name v=gogcfg */
@@ -266,12 +215,58 @@ typedef struct _mate_config {
        GPtrArray* pducfglist; /* pducfgs in order of "execution" */
        GHashTable* gops_by_pduname; /* k=pducfg->name v=gopcfg */
        GHashTable* gogs_by_gopname; /* k=gopname v=loal where avpl->name == matchedgop->name */
-
+       
        GArray* hfrs;
        gint ett_root;
        GArray* ett;
+       
+       /* defaults */
+       struct _mate_cfg_defaults {
+               struct _pdu_defaults {
+                       avpl_match_mode match_mode;
+                       avpl_replace_mode replace_mode;
+                       gboolean last_extracted;
+                       
+                       gboolean drop_unassigned;
+                       gboolean discard;
+               } pdu;
+               
+               struct _gop_defaults {
+                       float expiration;
+                       float idle_timeout;
+                       float lifetime;
+                       
+                       gop_pdu_tree_t pdu_tree_mode;
+                       gboolean show_times;
+                       gboolean drop_unassigned;
+
+               } gop;
+               
+               struct _gog_defaults {
+                       float expiration;
+                       
+                       gop_tree_mode_t gop_tree_mode;
+               } gog;
+       } defaults;
+       
+       /* what to dbgprint */
+       int dbg_lvl;    
+       int dbg_pdu_lvl;
+       int dbg_gop_lvl;
+       int dbg_gog_lvl;
+       
+       GPtrArray* config_stack;
+       GString* config_error;
+       
 } mate_config;
 
+
+typedef struct _mate_config_frame {
+       gchar* filename;
+       guint  linenum;
+} mate_config_frame;
+
+
 typedef struct _mate_runtime_data {
        guint current_items; /* a count of items */
        GMemChunk* mate_items;
@@ -282,70 +277,113 @@ typedef struct _mate_runtime_data {
        
 } mate_runtime_data;
 
+typedef struct _mate_pdu mate_pdu;
+typedef struct _mate_gop mate_gop;
+typedef struct _mate_gog mate_gog;
+
 /* these are used to contain information regarding pdus, gops and gogs */
-struct _mate_item {
-       /* all three of them */
+struct _mate_pdu {
        guint32 id; /* 1:1 -> saving a g_malloc */
-       mate_cfg_item* cfg; /* the type of this item */
+       mate_cfg_pdu* cfg; /* the type of this item */
+
+       AVPL* avpl;
+       
+       guint32 frame; /* wich frame I belog to? */
+       mate_pdu* next_in_frame; /* points to the next pdu in this frame */
+       float rel_time; /* time since start of capture  */
+       
+       mate_gop* gop; /* the gop the pdu belongs to (if any) */
+       mate_pdu* next; /* next in gop */
+       float time_in_gop; /* time since gop start */
+       
+       gboolean first; /* is this the first pdu in this frame? */
+       gboolean is_start; /* this is the start pdu for this gop */
+       gboolean is_stop; /* this is the stop pdu for this gop */
+       gboolean after_release; /* this pdu comes after the stop */
+       
+};
+
 
+struct _mate_gop {
+       guint32 id;
+       mate_cfg_gop* cfg; 
+       
+       guint8* gop_key;
        AVPL* avpl; /* the attributes of the pdu/gop/gog */
-               
-       mate_item* next; /* in pdu: next in gop; in gop: next in gog; in gog this doesn't make any sense yet */
+       guint last_n;
+       
+       mate_gog* gog; /* the gog of a gop */
+       mate_gop* next; /* next in gog; */
        
        float expiration; /* when will it expire after release (all gops releases if gog)? */
        float idle_expiration; /* when will it expire if no new pdus are assigned to it */
+       float time_to_die;
+       float time_to_timeout;
        
-       /* on gop and gog: */
        float start_time; /* time of start */
        float release_time; /* when this gop/gog was released */
        float last_time; /* the rel_time at which the last pdu has been added (to gop or gog's gop) */
+
+
+       int num_of_pdus; /* how many gops a gog has? */
+       int num_of_after_release_pdus;  /* how many pdus have arrived since it's been released */
+       mate_pdu* pdus; /* pdus that belong to a gop (NULL in gog) */
+       mate_pdu* last_pdu; /* last pdu in pdu's list */
        
-       /* union _payload { */
-               /* struct _pdu { */
-                       guint32 frame; /* wich frame I belog to? */
-                       mate_gop* gop; /* the gop the pdu belongs to (if any) */
-                       gboolean first; /* is this the first pdu in this frame? */
-                       gboolean is_start; /* this is the start pdu for this gop */
-                       gboolean is_stop; /* this is the stop pdu for this gop */
-                       gboolean after_release; /* this pdu comes after the stop */
-                       float rel_time; /* time since start of capture  */
-                       float time_in_gop; /* time since gop start */
-                       mate_pdu* next_in_frame; /* points to the next pdu in this frame */
-               /* } pdu; */
-               
-               /* struct _gop { */
-                       /* membership* gogs; */
-                       mate_gog* gog; /* the gog of a gop */
-                       mate_pdu* pdus; /* pdus that belong to a gop (NULL in gog) */
-                       gboolean released; /* has this gop been released? */
-                       int num_of_pdus; /* how many gops a gog has? */
-                       int num_of_after_release_pdus;  /* how many pdus have arrived since it's been released */
-                       guint8* gop_key; /* used by gop */
-                       mate_pdu* last_pdu; /* last pdu in pdu's list */
-                       float time_to_die;
-                       float time_to_timeout;
-               /* } gop; */
-               
-               /* struct _gog { */
-                       /* membership* gops; */
-                       mate_gop* gops; /* gops that belong to a gog (NULL in gop) */
-                       int num_of_gops; /* how many gops a gog has? */
-                       int num_of_counting_gops;  /* how many of them count for gog release */
-                       int num_of_released_gops;  /* how many of them have already been released */
-                       guint last_n; /* the number of attributes the avpl had the last time we checked */
-                       GPtrArray* gog_keys; /* the keys under which this gog is stored in the gogs hash */
-                       mate_gop* last_gop; /* last gop in gop's list */
-               /* } gog; */
-       /* } o; */
+       gboolean released; /* has this gop been released? */
 };
 
+
+struct _mate_gog {
+       guint32 id;
+       mate_cfg_gog* cfg; 
+       
+       AVPL* avpl; /* the attributes of the pdu/gop/gog */
+       guint last_n; /* the number of attributes the avpl had the last time we checked */
+       
+       gboolean released; /* has this gop been released? */
+       
+       float expiration; /* when will it expire after release (all gops releases if gog)? */
+       float idle_expiration; /* when will it expire if no new pdus are assigned to it */
+       
+       /* on gop and gog: */
+       float start_time; /* time of start */
+       float release_time; /* when this gog was released */
+       float last_time; /* the rel_time at which the last pdu has been added */
+       
+       mate_gop* gops; /* gops that belong to a gog (NULL in gop) */
+       mate_gop* last_gop; /* last gop in gop's list */
+       
+       int num_of_gops; /* how many gops a gog has? */
+       int num_of_counting_gops;  /* how many of them count for gog release */
+       int num_of_released_gops;  /* how many of them have already been released */
+       GPtrArray* gog_keys; /* the keys under which this gog is stored in the gogs hash */
+};
+
+typedef union _mate_max_size {
+       mate_pdu pdu;
+       mate_gop gop;
+       mate_gog gog;
+} mate_max_size;
+
 /* from mate_runtime.c */
 extern void initialize_mate_runtime(void);
 extern mate_pdu* mate_get_pdus(guint32 framenum);
 extern void mate_analyze_frame(packet_info *pinfo, proto_tree* tree);
 
 /* from mate_setup.c */
-extern mate_config* mate_make_config(guint8* filename, int mate_hfid);
+extern mate_config* mate_make_config(gchar* filename, int mate_hfid);
+
 extern mate_config* mate_cfg(void);
+extern mate_cfg_pdu* new_pducfg(gchar* name);
+extern mate_cfg_gop* new_gopcfg(gchar* name);
+extern mate_cfg_gog* new_gogcfg(gchar* name);
+
+extern gboolean add_hfid(header_field_info*  hfi, gchar* as, GHashTable* where);
+extern gchar* add_ranges(gchar* range, GPtrArray* range_ptr_arr);
+
+
+/* from mate_parser.l */
+extern gboolean mate_load_config(gchar* filename, mate_config* mc);
 
 #endif
diff --git a/plugins/mate/mate_grammar.lemon b/plugins/mate/mate_grammar.lemon
new file mode 100644 (file)
index 0000000..6b71a53
--- /dev/null
@@ -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); }
+
diff --git a/plugins/mate/mate_parser.l b/plugins/mate/mate_parser.l
new file mode 100644 (file)
index 0000000..c7a5001
--- /dev/null
@@ -0,0 +1,296 @@
+%option noyywrap
+%option nounput 
+%option never-interactive
+%option prefix="Mate"
+
+%{
+
+       /* mate_parser.l
+       * lexical analyzer for MATE configuration files
+       *
+       * Copyright 2004, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
+       *
+       * $Id: packet-xml.c 13427 2005-02-18 22:33:16Z lego $
+       *
+       * 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"      
+#include "mate_grammar.h"
+       
+       void MateParser(void*,int, gchar*, mate_config* matecfg);
+       void *MateParserAlloc(void *(*)(gulong));
+       void MateParserFree( void*, void(*)(void*) );
+       void MateParseTrace(FILE*,char*);
+       
+#define MAX_INCLUDE_DEPTH 10
+       YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+       int include_stack_ptr = 0;
+       
+       void* pParser;
+       mate_config_frame* current_frame;
+       
+       mate_config* mc;
+       
+#define MATE_PARSE(token_type) MateParser(pParser, (token_type), g_strdup(yytext), mc );
+
+%}
+
+pdu_kw                         Pdu
+gop_kw                         Gop
+gog_kw                         Gog
+transform_kw           Transform
+match_kw                       Match
+always_kw                      Always
+strict_kw                      Strict
+every_kw                       Every
+loose_kw                       Loose
+replace_kw                     Replace
+insert_kw                      Insert
+gop_tree_kw                    GopTree
+member_kw                      Member
+on_kw                          On
+start_kw                       Start
+stop_kw                                Stop
+extra_kw                       Extra
+show_tree_kw           ShowTree
+show_times_kw          ShowTimes
+expiration_kw          Expiration
+idle_timeout_kw                IdleTimeout
+lifetime_kw                    Lifetime
+no_tree_kw                     NoTree
+pdu_tree_kw                    PduTree
+frame_tree_kw          FrameTree
+basic_tree_kw          BasicTree
+true_kw                                [Tt][Rr][Uu][Ee]
+false_kw                       [Ff][Aa][Ll][Ss][Ee]
+proto_kw                       Proto
+payload_kw          Payload
+transport_kw           Transport
+criteria_kw                    Criteria
+accept_kw                      Accept
+reject_kw                      Reject
+extract_kw                     Extract
+from_kw                                From
+drop_unassigned_kw  DropUnassigned
+discard_pdu_data_kw DiscardPduData
+last_pdu_kw                    LastPdu
+done_kw                                Done
+
+
+
+open_parens                    "("
+close_parens           ")"
+open_brace                     "{"
+close_brace                    "}"
+comma                          ","
+semicolon                      ";"
+slash                          "/"
+pipe                           "|"
+
+integer                                [0-9]+
+floating                       ([0-9]+\.[0-9]+)
+doted_ip                       [0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?
+colonized                      [0-9A-Fa-f:]*[:][0-9A-Fa-f:]*
+
+name                           [a-z][-\.a-zA-Z0-9_]*
+avp_operator           [$^~=<>!]
+quote                          ["]
+not_quoted                     [^"]*
+
+include                        "#include"
+filename               [-A-Za-z0-9_/.]+
+
+whitespace             [[:blank:]\r]+
+newline                        \n
+
+comment                        "//"[^\n]*\n
+
+blk_cmnt_start  "/*"
+cmnt_char              .
+blk_cmnt_stop  "*/"
+%START OUT QUOTED INCLUDING COMMENT
+%%
+
+{newline}                                              current_frame->linenum++; 
+{whitespace}                                   ;
+
+<OUT>{include}                                 BEGIN INCLUDING;
+
+<INCLUDING>{filename}                  {
+       if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
+               g_error("dtd_preparse: include files nested to deeply");
+       
+       include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
+       yyin = fopen( yytext, "r" );
+
+       if (!yyin) {
+               yy_delete_buffer( YY_CURRENT_BUFFER );
+               
+               yy_switch_to_buffer(include_stack[--include_stack_ptr] );
+               
+               if (errno)
+                       g_string_sprintfa(mc->config_error, "Mate parser: Could not open file: '%s': %s", yytext, strerror(errno) );
+               
+       } else {
+               
+               current_frame = g_malloc(sizeof(mate_config_frame));
+               current_frame->filename = g_strdup(yytext);
+               current_frame->linenum = 1;
+               
+               g_ptr_array_add(mc->config_stack,current_frame);
+
+               yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
+       }
+       
+       BEGIN OUT;
+}
+
+<<EOF>>        {       
+       if ( --include_stack_ptr < 0 ) {
+               yyterminate();
+       } else {
+               yy_delete_buffer( YY_CURRENT_BUFFER );
+               yy_switch_to_buffer( include_stack[include_stack_ptr] );
+               
+               g_free(current_frame->filename);
+               g_free(current_frame);
+               current_frame = g_ptr_array_remove_index(mc->config_stack,mc->config_stack->len-1);
+       }
+}                              
+
+<OUT>{comment}                                 ;
+
+<OUT>{blk_cmnt_start}                  BEGIN COMMENT;
+<COMMENT>{cmnt_char}                   ;
+<COMMENT>{blk_cmnt_stop}               BEGIN OUT;
+
+<OUT>{pdu_kw}                                  MATE_PARSE(TOKEN_PDU_KW);
+<OUT>{gop_kw}                                  MATE_PARSE(TOKEN_GOP_KW);
+<OUT>{gog_kw}                                  MATE_PARSE(TOKEN_GOG_KW);
+<OUT>{transform_kw}                            MATE_PARSE(TOKEN_TRANSFORM_KW);
+<OUT>{match_kw}                                        MATE_PARSE(TOKEN_MATCH_KW);
+<OUT>{strict_kw}                               MATE_PARSE(TOKEN_STRICT_KW);
+<OUT>{every_kw}                                        MATE_PARSE(TOKEN_EVERY_KW);
+<OUT>{loose_kw}                                        MATE_PARSE(TOKEN_LOOSE_KW);
+<OUT>{replace_kw}                              MATE_PARSE(TOKEN_REPLACE_KW);
+<OUT>{insert_kw}                               MATE_PARSE(TOKEN_INSERT_KW);
+<OUT>{gop_tree_kw}                             MATE_PARSE(TOKEN_GOP_TREE_KW);
+<OUT>{member_kw}                               MATE_PARSE(TOKEN_MEMBER_KW);
+<OUT>{on_kw}                                   MATE_PARSE(TOKEN_ON_KW);
+<OUT>{start_kw}                                        MATE_PARSE(TOKEN_START_KW);
+<OUT>{stop_kw}                                 MATE_PARSE(TOKEN_STOP_KW);
+<OUT>{extra_kw}                                        MATE_PARSE(TOKEN_EXTRA_KW);
+<OUT>{show_tree_kw}                            MATE_PARSE(TOKEN_SHOW_TREE_KW);
+<OUT>{show_times_kw}                   MATE_PARSE(TOKEN_SHOW_TIMES_KW);
+<OUT>{expiration_kw}                   MATE_PARSE(TOKEN_EXPIRATION_KW);
+<OUT>{idle_timeout_kw}                 MATE_PARSE(TOKEN_IDLE_TIMEOUT_KW);
+<OUT>{lifetime_kw}                             MATE_PARSE(TOKEN_LIFETIME_KW);
+<OUT>{no_tree_kw}                              MATE_PARSE(TOKEN_NO_TREE_KW);
+<OUT>{pdu_tree_kw}                             MATE_PARSE(TOKEN_PDU_TREE_KW);
+<OUT>{frame_tree_kw}                   MATE_PARSE(TOKEN_FRAME_TREE_KW);
+<OUT>{basic_tree_kw}                   MATE_PARSE(TOKEN_BASIC_TREE_KW);
+<OUT>{true_kw}                                 MATE_PARSE(TOKEN_TRUE_KW);
+<OUT>{false_kw}                                        MATE_PARSE(TOKEN_FALSE_KW);
+<OUT>{proto_kw}                                        MATE_PARSE(TOKEN_PROTO_KW);
+<OUT>{payload_kw}                              MATE_PARSE(TOKEN_PAYLOAD_KW);
+<OUT>{transport_kw}                            MATE_PARSE(TOKEN_TRANSPORT_KW);
+<OUT>{criteria_kw}                             MATE_PARSE(TOKEN_CRITERIA_KW);
+<OUT>{accept_kw}                               MATE_PARSE(TOKEN_ACCEPT_KW);
+<OUT>{reject_kw}                               MATE_PARSE(TOKEN_REJECT_KW);
+<OUT>{extract_kw}                              MATE_PARSE(TOKEN_EXTRACT_KW);
+<OUT>{from_kw}                                 MATE_PARSE(TOKEN_FROM_KW);
+<OUT>{drop_unassigned_kw}              MATE_PARSE(TOKEN_DROP_UNASSIGNED_KW);
+<OUT>{discard_pdu_data_kw}             MATE_PARSE(TOKEN_DISCARD_PDU_DATA_KW);
+<OUT>{last_pdu_kw}                             MATE_PARSE(TOKEN_LAST_PDU_KW);
+<OUT>{done_kw}                                 MATE_PARSE(TOKEN_DONE_KW);
+
+<OUT>{open_parens}                             MATE_PARSE(TOKEN_OPEN_PARENS);
+<OUT>{close_parens}                            MATE_PARSE(TOKEN_CLOSE_PARENS);
+<OUT>{open_brace}                              MATE_PARSE(TOKEN_OPEN_BRACE);
+<OUT>{close_brace}                             MATE_PARSE(TOKEN_CLOSE_BRACE);
+<OUT>{comma}                                   MATE_PARSE(TOKEN_COMMA);
+<OUT>{semicolon}                               MATE_PARSE(TOKEN_SEMICOLON);
+<OUT>{slash}                                   MATE_PARSE(TOKEN_SLASH);
+<OUT>{pipe}                                            MATE_PARSE(TOKEN_PIPE);
+
+<OUT>{integer}                                 MATE_PARSE(TOKEN_INTEGER);
+<OUT>{floating}                                        MATE_PARSE(TOKEN_FLOATING);
+<OUT>{doted_ip}                                        MATE_PARSE(TOKEN_DOTED_IP);
+<OUT>{colonized}                               MATE_PARSE(TOKEN_COLONIZED);
+<OUT>{name}                                            MATE_PARSE(TOKEN_NAME);
+<OUT>{avp_operator}                            MATE_PARSE(TOKEN_AVP_OPERATOR);
+
+
+<OUT>{quote}                                   BEGIN QUOTED;
+<QUOTED>{not_quoted}                   MATE_PARSE(TOKEN_QUOTED);
+<QUOTED>{quote}                                        BEGIN OUT;
+
+%%
+
+extern gboolean mate_load_config(gchar* filename, mate_config* matecfg) {
+       gboolean state;
+       mc = matecfg;
+
+       yyin = fopen(filename,"r");
+       
+       if (!yyin) {
+               g_string_sprintfa(mc->config_error,"Mate parser: Could not open file: '%s', error: %s", filename, strerror(errno) );
+               return FALSE;
+       }
+       
+       mc->config_stack = g_ptr_array_new();
+       
+       current_frame = g_malloc(sizeof(mate_config_frame));
+       current_frame->filename = g_strdup(filename);
+       current_frame->linenum = 1;
+       
+       g_ptr_array_add(mc->config_stack,current_frame);
+
+       pParser = MateParserAlloc(g_malloc);
+       
+       /* MateParserTrace(stdout,""); */
+       
+       TRY {
+               BEGIN OUT;
+
+               yylex();
+
+               MateParser(pParser, 0, NULL,mc);
+
+               yyrestart(NULL);
+       
+               MateParserFree(pParser, g_free );
+       
+               g_free(current_frame->filename);
+               g_free(current_frame);
+       
+               g_ptr_array_free(mc->config_stack,FALSE);
+               state = TRUE;
+       } CATCH(MateConfigError) {
+               state = FALSE;
+       } CATCH_ALL {
+               state = FALSE;          
+               g_string_sprintfa(mc->config_error,"An unexpected error occurred");
+       }
+       ENDTRY;
+       
+       return state;
+}
index 4111c76c293574889811c989e772c3bb8e966cc4..d8009854efc3b461fd2581092cd4c986c29b6ae6 100644 (file)
@@ -24,7 +24,7 @@
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
-/* this file is used temporarily to buid it as a plugin */
+/* this file is used temporarily to buid MATE as a plugin */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -40,6 +40,8 @@
 /* these two are in packet-mate.c */
 void proto_register_mate(void);
 void proto_reg_handoff_mate(void);
+
+
 static gboolean initialized = FALSE;
 
 #ifndef ENABLE_STATIC
@@ -47,8 +49,9 @@ G_MODULE_EXPORT const gchar version[] = VERSION;
 
 G_MODULE_EXPORT void plugin_register(void) {
        
-       /* register the new protocol, protocol fields, and subtrees */
-       if (! initialized ) { /* execute protocol initialization only once */
+       g_message("---");
+
+       if (! initialized ) {
                proto_register_mate();
                initialized = 1;
        }
index 1f8284671bd918cbba4f8b64212fe27781f54e08..3475807330e3596dc09df99e8431f35d612ae979 100644 (file)
@@ -42,7 +42,7 @@ typedef struct _tmp_pdu_data {
 
 
 typedef struct _gogkey {
-       guint8* key;
+       gchar* key;
        mate_cfg_gop* cfg; 
 } gogkey;
 
@@ -58,28 +58,45 @@ static int* dbg_gop = &zero;
 static int* dbg_gog = &zero;
 static FILE* dbg_facility = NULL;
 
-static void gog_remove_keys (mate_gog* gog);
+static gboolean destroy_mate_pdus(gpointer k _U_, gpointer v, gpointer p _U_) {
+       mate_pdu* pdu = (mate_pdu*) v;
+       if (pdu->avpl) delete_avpl(pdu->avpl,TRUE);
+       g_mem_chunk_free(rd->mate_items,pdu);
+       return TRUE;
+}
 
-static gboolean destroy_mate_items(gpointer k _U_, gpointer v, gpointer p _U_) {
-       mate_item* mi = (mate_item*) v;
+static gboolean destroy_mate_gops(gpointer k _U_, gpointer v, gpointer p _U_) {
+       mate_gop* gop = (mate_gop*) v;
        
-       if (mi->avpl) delete_avpl(mi->avpl,TRUE);
-
-       if (mi->gop_key) {
-               if (g_hash_table_lookup(mi->cfg->gop_index,mi->gop_key) == mi) {
-                       g_hash_table_remove(mi->cfg->gop_index,mi->gop_key);
+       if (gop->avpl) delete_avpl(gop->avpl,TRUE);
+       
+       if (gop->gop_key) {
+               if (g_hash_table_lookup(gop->cfg->gop_index,gop->gop_key) == gop) {
+                       g_hash_table_remove(gop->cfg->gop_index,gop->gop_key);
                }
                
-               g_free(mi->gop_key);
+               g_free(gop->gop_key);
        }
+       
+       g_mem_chunk_free(rd->mate_items,gop);
+       
+       return TRUE;
+}
+
+
+static void gog_remove_keys (mate_gog* gog);
 
+static gboolean destroy_mate_gogs(gpointer k _U_, gpointer v, gpointer p _U_) {
+       mate_gog* gog = (mate_gog*) v;
+       
+       if (gog->avpl) delete_avpl(gog->avpl,TRUE);
 
-       if (mi->gog_keys) {
-               gog_remove_keys(mi);
-               g_ptr_array_free(mi->gog_keys,FALSE);
+       if (gog->gog_keys) {
+               gog_remove_keys(gog);
+               g_ptr_array_free(gog->gog_keys,FALSE);
        }
        
-       g_mem_chunk_free(rd->mate_items,mi);
+       g_mem_chunk_free(rd->mate_items,gog);
 
        return TRUE;
 }
@@ -88,27 +105,33 @@ static gboolean return_true(gpointer k _U_, gpointer v _U_, gpointer p _U_) {
        return TRUE;
 }
 
-static void destroy_items_in_cfg(gpointer k _U_, gpointer v, gpointer p _U_) {
-       mate_cfg_item* c =  v;
+static void destroy_pdus_in_cfg(gpointer k _U_, gpointer v, gpointer p _U_) {
+       mate_cfg_pdu* c =  v;
+       g_hash_table_foreach_remove(c->items,destroy_mate_pdus,NULL);
+       c->last_id = 0;
+}
+
+
+static void destroy_gops_in_cfg(gpointer k _U_, gpointer v, gpointer p _U_) {
+       mate_cfg_gop* c =  v;
        
-       if (c->gop_index) { 
-               g_hash_table_foreach_remove(c->gop_index,return_true,NULL);
-               g_hash_table_destroy(c->gop_index);     
-               c->gop_index = g_hash_table_new(g_str_hash,g_str_equal);
-       }
-               
-       if (c->gog_index) {
-               g_hash_table_foreach_remove(c->gog_index,return_true,NULL);
-               g_hash_table_destroy(c->gog_index);     
-               c->gog_index = g_hash_table_new(g_str_hash,g_str_equal);
-       }
+       g_hash_table_foreach_remove(c->gop_index,return_true,NULL);
+       g_hash_table_destroy(c->gop_index);     
+       c->gop_index = g_hash_table_new(g_str_hash,g_str_equal);
        
-       g_hash_table_foreach_remove(c->items,destroy_mate_items,NULL);
-
-       c->last_id = 0;
+       g_hash_table_foreach_remove(c->gog_index,return_true,NULL);
+       g_hash_table_destroy(c->gog_index);     
+       c->gog_index = g_hash_table_new(g_str_hash,g_str_equal);
        
+       g_hash_table_foreach_remove(c->items,destroy_mate_gops,NULL);
+       c->last_id = 0;
 }
 
+static void destroy_gogs_in_cfg(gpointer k _U_, gpointer v, gpointer p _U_) {
+       mate_cfg_gog* c =  v;
+       g_hash_table_foreach_remove(c->items,destroy_mate_gogs,NULL);
+       c->last_id = 0;
+}
 
 extern void initialize_mate_runtime(void) {
        
@@ -117,11 +140,11 @@ extern void initialize_mate_runtime(void) {
        if (( mc = mate_cfg() )) {
                if (rd == NULL ) {                      
                        rd = g_malloc(sizeof(mate_runtime_data));
-                       rd->mate_items = g_mem_chunk_new("mate_items",sizeof(mate_item),1024,G_ALLOC_AND_FREE);
+                       rd->mate_items = g_mem_chunk_new("mate_items",sizeof(mate_max_size),1024,G_ALLOC_AND_FREE);
                } else {
-                       g_hash_table_foreach(mc->pducfgs,destroy_items_in_cfg,NULL);
-                       g_hash_table_foreach(mc->gopcfgs,destroy_items_in_cfg,NULL);
-                       g_hash_table_foreach(mc->gogcfgs,destroy_items_in_cfg,NULL);
+                       g_hash_table_foreach(mc->pducfgs,destroy_pdus_in_cfg,NULL);
+                       g_hash_table_foreach(mc->gopcfgs,destroy_gops_in_cfg,NULL);
+                       g_hash_table_foreach(mc->gogcfgs,destroy_gogs_in_cfg,NULL);
                        
                        g_hash_table_destroy(rd->frames);                       
                }
@@ -141,68 +164,37 @@ extern void initialize_mate_runtime(void) {
        }
 }
 
-static mate_item* new_mate_item(mate_cfg_item* cfg) {
-       mate_item* it = g_mem_chunk_alloc(rd->mate_items);
 
-       cfg->last_id++;
-       
-       it->id = cfg->last_id;
-       it->cfg = cfg;
-       
-       it->avpl  = NULL ;
-       
-       it->next  = NULL ;
+static mate_gop* new_gop(mate_cfg_gop* cfg, mate_pdu* pdu, gchar* key) {
+       mate_gop* gop = g_mem_chunk_alloc(rd->mate_items);
 
-       it->expiration = 0.0;
-       it->idle_expiration = 0.0;
+       gop->id = ++(cfg->last_id);
+       gop->cfg = cfg;
 
-       it->start_time = 0.0;
-       it->release_time = 0.0;
-       it->last_time = 0.0;
+       dbg_print (dbg_gop,1,dbg_facility,"new_gop: %s: ``%s:%d''",gop->cfg->name,gop->id,key);
 
-       it->frame  = 0 ;
-       it->gop = NULL;
-       it->first = FALSE;
-       it->is_start = FALSE;
-       it->is_stop = FALSE;
-       it->after_release = FALSE;
-       it->rel_time = 0.0;
-       it->time_in_gop = -1.0;
-       it->next_in_frame = NULL;
-       
-       it->gog = NULL;
-       it->pdus = NULL;
-       it->released  = FALSE ;
-       it->num_of_pdus = 0;
-       it->num_of_after_release_pdus = 0;
-       it->gop_key = NULL;
+       gop->gop_key = key;
+       gop->avpl = new_avpl(cfg->name);
+       gop->last_n = 0;
        
-       it->gops = NULL;
-       it->num_of_gops = 0;
-       it->num_of_counting_gops = 0;
-       it->num_of_released_gops = 0;
-       it->last_n = 0;
-       it->gog_keys = NULL;
-       it->last_gop = NULL;
+       gop->gog = NULL;
+       gop->next = NULL;
        
-       rd->current_items++;
-
-       g_hash_table_insert(cfg->items,GUINT_TO_POINTER(it->id),it);
-       return it;
-}
-
-static mate_gop* new_gop(mate_cfg_gop* cfg, mate_pdu* pdu, guint8* key) {
-       mate_gop* gop = new_mate_item(cfg);
+       gop->expiration = 0.0;
+       gop->idle_expiration = 0.0;
+       gop->time_to_die = cfg->lifetime > 0.0 ? cfg->lifetime + rd->now : (float) -1.0 ;
+       gop->time_to_timeout = 0.0;
 
-       dbg_print (dbg_gop,1,dbg_facility,"new_gop: %s: ``%s:%d''",gop->cfg->name,gop->id,key);
+       gop->last_time = gop->start_time = rd->now;
+       gop->release_time = 0.0;
        
-       gop->avpl = new_avpl(cfg->name);
+       gop->num_of_pdus = 1;
+       gop->num_of_after_release_pdus = 0;
        
        gop->pdus = pdu;
        gop->last_pdu = pdu;
-       gop->gop_key = key;
-       gop->start_time = rd->now;
-       gop->time_to_die = cfg->lifetime > 0.0 ? cfg->lifetime + rd->now : (float) -1.0 ;
+       
+       
        pdu->gop = gop;
        pdu->next = NULL;
        pdu->is_start = TRUE;
@@ -211,7 +203,6 @@ static mate_gop* new_gop(mate_cfg_gop* cfg, mate_pdu* pdu, guint8* key) {
        return gop;
 }
 
-
 static void adopt_gop(mate_gog* gog, mate_gop* gop) {
        dbg_print (dbg_gog,5,dbg_facility,"adopt_gop: gog=%X gop=%X",gog,gop);
 
@@ -237,43 +228,55 @@ static void adopt_gop(mate_gog* gog, mate_gop* gop) {
 }
 
 static mate_gog* new_gog(mate_cfg_gog* cfg, mate_gop* gop) {
-       mate_gog* gog = new_mate_item(cfg);
+       mate_gog* gog = g_mem_chunk_alloc(rd->mate_items);
        
+       gog->id = ++(cfg->last_id);
+       gog->cfg = cfg;
+               
        dbg_print (dbg_gog,1,dbg_facility,"new_gog: %s:%u for %s:%u",gog->cfg->name,gog->id,gop->cfg->name,gop->id);
 
        gog->avpl = new_avpl(cfg->name);
+       gog->last_n = 0;
+       
+       gog->expiration = 0.0;
+       gog->idle_expiration = 0.0;
        
-       gog->gog_keys = g_ptr_array_new();
        gog->start_time = rd->now;
+       gog->release_time = 0.0;
+       gog->last_time = 0.0;
+       
+       gog->gops = NULL;
+       gog->last_gop = NULL;
+       
+       gog->num_of_gops = 0;
+       gog->num_of_counting_gops = 0;
+       gog->num_of_released_gops = 0;
+       
+       gog->gog_keys = g_ptr_array_new();
        
        adopt_gop(gog,gop);
        
        return gog;
 }
-static void apply_transforms(mate_item* item) {
+
+static void apply_transforms(GPtrArray* transforms, AVPL* avpl) {
        AVPL_Transf* transform = NULL;
        guint i;
                
-       for (i = 0; i < item->cfg->transforms->len; i++) {
-               transform = g_ptr_array_index(item->cfg->transforms,i);
-               avpl_transform(item->avpl, transform);
+       for (i = 0; i < transforms->len; i++) {
+               transform = g_ptr_array_index(transforms,i);
+               avpl_transform(avpl, transform);
        }
 }
 
 
 /* applies the extras for which type to what avpl */
-static void apply_extras(AVPL* from, AVPL* to,  mate_cfg_item* cfg) {
-       AVPL* our_extras = NULL;
-       
-       if (cfg->extra) {
-               dbg_print (dbg,3,dbg_facility,"apply_extras: entering: from='%s' to='%s' for='%s'",from->name,to->name,cfg->name);
-               
-               our_extras = new_avpl_loose_match("",from, cfg->extra, FALSE) ;
-                               
-               if (our_extras) {
-                       merge_avpl(to,our_extras,TRUE);
-                       delete_avpl(our_extras,FALSE);
-               }
+static void apply_extras(AVPL* from, AVPL* to,  AVPL* extras) {
+       AVPL* our_extras = new_avpl_loose_match("",from, extras, FALSE) ;
+                                       
+       if (our_extras) {
+               merge_avpl(to,our_extras,TRUE);
+               delete_avpl(our_extras,FALSE);
        }
 }
 
@@ -308,11 +311,17 @@ static void reanalyze_gop(mate_gop* gop) {
        
        dbg_print (dbg_gog,1,dbg_facility,"reanalize_gop: %s:%d",gop->cfg->name,gop->id);
        
-       apply_extras(gop->avpl,gog->avpl,gog->cfg);
+       apply_extras(gop->avpl,gog->avpl,gog->cfg->extra);
+       
+       /* XXX: Instead of using the length of the avpl to check if an avpl has changed,
+                       which is not accurate at all,  we should have apply_extras,
+                       apply_transformations and other functions that can modify the avpl
+                   to flag the avpl if it has changed, then we'll check for the flag
+                   and clear it after analysis */
        
        if (gog->last_n != gog->avpl->len) {
                
-               dbg_print (dbg_gog,2,dbg_facility,"analize_gop: gog has new attributes let's look for new keys");
+               dbg_print (dbg_gog,2,dbg_facility,"reanalize_gop: gog has new attributes let's look for new keys");
                
                gog_keys = gog->cfg->keys;
                
@@ -335,7 +344,9 @@ static void reanalyze_gop(mate_gop* gop) {
                                } 
                                
                                if (! gog_key ) {
-                                       /* TODO: try mergeing the gogs */
+                                       /* XXX: since these gogs actually share key info
+                                                       we should try to merge (non released) gogs
+                                               that happen to have equal keys */
                                } else {
                                        dbg_print (dbg_gog,1,dbg_facility,"analize_gop: new key for gog=%s:%d : %s",gog->cfg->name,gog->id,gog_key->key);
                                        g_ptr_array_add(gog->gog_keys,gog_key);
@@ -363,7 +374,7 @@ static void analize_gop(mate_gop* gop) {
        void* cookie = NULL;
        AVPL* gogkey_match = NULL;
        mate_gog* gog = NULL;
-       guint8* key = NULL;
+       gchar* key = NULL;
        
        if ( ! ( gog = gop->gog ) ) {
                /* no gog, let's either find one or create it if due */
@@ -376,14 +387,11 @@ static void analize_gop(mate_gop* gop) {
                        return;
                }
                
-               /* We'll look for any matching gogkeys */
+               /* We have gog_keys! look for matching gogkeys */
                
                dbg_print (dbg_gog,1,dbg_facility,"analize_gop: got gog_keys: %s",gog_keys->name) ;
                
                while (( curr_gogkey = get_next_avpl(gog_keys,&cookie) )) {
-                       
-                       dbg_print (dbg_gog,2,dbg_facility,"analize_gop: about to match");
-                       
                        if (( gogkey_match = new_avpl_exact_match(gop->cfg->name,gop->avpl,curr_gogkey,TRUE) )) {
                                
                                key = avpl_to_str(gogkey_match);
@@ -404,8 +412,6 @@ static void analize_gop(mate_gop* gop) {
                                        } else {
                                                dbg_print (dbg_gog,1,dbg_facility,"analize_gop: this is our gog");
                                                
-                                               g_free(key);
-                                               
                                                if (! gop->gog ) adopt_gop(gog,gop);
                                                
                                                break;
@@ -430,13 +436,19 @@ static void analize_gop(mate_gop* gop) {
                                        break;
                                }
                                
+                               
                                delete_avpl(gogkey_match,TRUE);
                                gogkey_match = NULL;
                        }
                        
+                       if (key) g_free(key);
+                       key = NULL;
+
                        dbg_print (dbg_gog,1,dbg_facility,"analize_gop: no gogkey_match: %s",key);
                }
                
+               if (key) g_free(key);
+
                if (gogkey_match) delete_avpl(gogkey_match,TRUE);
                
                reanalyze_gop(gop);
@@ -452,55 +464,27 @@ static void analize_pdu(mate_pdu* pdu) {
        */
        mate_cfg_gop* cfg = NULL;
        mate_gop* gop = NULL;
-       guint8* gop_key;
-       guint8* orig_gop_key = NULL;
-       AVPL* candidate_gop_key_match = NULL;
+       gchar* gop_key;
+       gchar* orig_gop_key = NULL;
        AVPL* candidate_start = NULL;
        AVPL* candidate_stop = NULL;
        AVPL* is_start = NULL;
        AVPL* is_stop = NULL;
        AVPL* gopkey_match = NULL;
-       guint8* avpl_str = NULL;
        LoAL* gog_keys = NULL;
        AVPL* curr_gogkey = NULL;
        void* cookie = NULL;
        AVPL* gogkey_match = NULL;
-       guint8* gogkey = NULL;
+       gchar* gogkey = NULL;
        
        dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: %s",pdu->cfg->name);
 
-       apply_transforms(pdu);
-
-       /* is there a gop type for this pdu type? */
-       cfg = g_hash_table_lookup(mc->gops_by_pduname,pdu->cfg->name);
-       
-       if (!cfg) return;
-       
-       candidate_gop_key_match = cfg->key;
-       
-       if (! candidate_gop_key_match) return;
-       
-       dbg_print (dbg_gop,3,dbg_facility,"analize_pdu: got candidate key");
-       
-       /* does the pdu matches the prematch candidate key for the gop type? */
-       
-       gopkey_match = new_avpl_exact_match("gop_key_match",pdu->avpl,candidate_gop_key_match, TRUE);
-       
-       if (gopkey_match) {
-               gop_key = avpl_to_str(gopkey_match);
-               
-               candidate_start = cfg->start;
-               
-               if (candidate_start) {
-                       dbg_print (dbg_gop,2,dbg_facility,"analize_pdu: got candidate start");
-                       is_start = new_avpl_exact_match("",pdu->avpl, candidate_start, FALSE);
-               }
-               
-               if (is_start) {
-                       dbg_print (dbg_gop,2,dbg_facility,"analize_pdu: got start match");
-                       delete_avpl(is_start,FALSE);    
-               }
+       if (! (cfg = g_hash_table_lookup(mc->gops_by_pduname,pdu->cfg->name)) )
+               return;
                
+       if ((gopkey_match = new_avpl_exact_match("gop_key_match",pdu->avpl,cfg->key, TRUE))) {
+               gop_key = avpl_to_str(gopkey_match);
+                       
                g_hash_table_lookup_extended(cfg->gop_index,(gconstpointer)gop_key,(gpointer*)&orig_gop_key,(gpointer*)&gop);
                
                if ( gop ) {
@@ -521,15 +505,22 @@ static void analize_pdu(mate_pdu* pdu) {
                        
                        dbg_print (dbg_gop,2,dbg_facility,"analize_pdu: got gop: %s",gop_key);
                        
-                       if (is_start) {
-                               if ( gop->released ) {
-                                       dbg_print (dbg_gop,3,dbg_facility,"analize_pdu: start on released gop, a new gop");
-                                       g_hash_table_remove(cfg->gop_index,gop_key);
-                                       gop->gop_key = NULL;
-                                       gop = new_gop(cfg,pdu,gop_key);
-                                       g_hash_table_insert(cfg->gop_index,gop_key,gop);
-                               } else {
-                                       dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: duplicate start on gop");
+                       if (( candidate_start = cfg->start )) {
+                               
+                               dbg_print (dbg_gop,2,dbg_facility,"analize_pdu: got candidate start");
+                               
+                               if (( is_start = new_avpl_exact_match("",pdu->avpl, candidate_start, FALSE) )) {
+                                       delete_avpl(is_start,FALSE); 
+                                       if ( gop->released ) {
+                                               dbg_print (dbg_gop,3,dbg_facility,"analize_pdu: start on released gop, let's create a new gop");
+                                               
+                                               g_hash_table_remove(cfg->gop_index,gop_key);
+                                               gop->gop_key = NULL;
+                                               gop = new_gop(cfg,pdu,gop_key);
+                                               g_hash_table_insert(cfg->gop_index,gop_key,gop);
+                                       } else {
+                                               dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: duplicate start on gop");
+                                       }                                       
                                }
                        }
                        
@@ -545,25 +536,21 @@ static void analize_pdu(mate_pdu* pdu) {
                } else {
 
                        dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: no gop already");
-
-                       if (is_start) {
+                       
+                       if ( ! cfg->start ) {
+                               /* there is no GopStart, we'll check for matching GogKeys
+                               if we have one we'll create the Gop */
                                
-                               gop = new_gop(cfg,pdu,gop_key);
-                               g_hash_table_insert(cfg->gop_index,gop_key,gop);
+                               apply_extras(pdu->avpl,gopkey_match,cfg->extra);
                                
-                       } else if (! candidate_start) {
-                               /* there is no GopStart, we'll check for matching GogKeys
-                                  if we have one we'll create the Gop */
-
-                               apply_extras(pdu->avpl,gopkey_match,cfg);
-
                                gog_keys = g_hash_table_lookup(mc->gogs_by_gopname,cfg->name);
-
+                               
                                if (gog_keys) {
                                        
                                        while (( curr_gogkey = get_next_avpl(gog_keys,&cookie) )) {
                                                if (( gogkey_match = new_avpl_exact_match(cfg->name,gopkey_match,curr_gogkey,FALSE) )) {
                                                        gogkey = avpl_to_str(gogkey_match);
+                                                       
                                                        if (g_hash_table_lookup(cfg->gog_index,gogkey)) {
                                                                gop = new_gop(cfg,pdu,gop_key);
                                                                g_hash_table_insert(cfg->gop_index,gop_key,gop);
@@ -601,12 +588,8 @@ static void analize_pdu(mate_pdu* pdu) {
                        }
                }
                
-               if ( gop ) {
-                       gop->num_of_pdus++;
-                       gop->time_to_timeout = cfg->idle_timeout > 0.0 ? cfg->idle_timeout + rd->now : (float) -1.0 ;
-               } else {
-                       g_error("No GOP at this point is simply wrong!");
-               }
+               gop->num_of_pdus++;
+               gop->time_to_timeout = cfg->idle_timeout > 0.0 ? cfg->idle_timeout + rd->now : (float) -1.0 ;
                
                dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: merge with key");
 
@@ -615,18 +598,14 @@ static void analize_pdu(mate_pdu* pdu) {
                
                dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: apply extras");
 
-               apply_extras(pdu->avpl,gop->avpl,gop->cfg);
-               
-               avpl_str = avpl_to_str(gop->avpl);
-               dbg_print (dbg_gop,1,dbg_facility,"analize_pdu: Gop Attributes: %s",avpl_str);
-               g_free(avpl_str);
-               
+               apply_extras(pdu->avpl,gop->avpl,gop->cfg->extra);
+                               
                gop->last_time = pdu->rel_time;
                
                if ( ! gop->released) {
                        candidate_stop = cfg->stop;
+                       
                        if (candidate_stop) {
-                               dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: got candidate stop");
                                is_stop = new_avpl_exact_match("",pdu->avpl, candidate_stop,FALSE);
                        } else {
                                is_stop = new_avpl("");
@@ -642,14 +621,12 @@ static void analize_pdu(mate_pdu* pdu) {
                                        if (gop->gog && gop->cfg->start) gop->gog->num_of_released_gops++;
                                }
                                
-                               if (candidate_stop) pdu->is_stop = TRUE;
+                               pdu->is_stop = TRUE;
                                
-                       } else {
-                               dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: is not a stop");
                        }
                }
                        
-               if (gop->last_n != gop->avpl->len) apply_transforms(gop);
+               if (gop->last_n != gop->avpl->len) apply_transforms(gop->cfg->transforms,gop->avpl);
                
                gop->last_n = gop->avpl->len;
                                
@@ -660,7 +637,7 @@ static void analize_pdu(mate_pdu* pdu) {
                }
                
        } else {
-               dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: no gop_key");
+               dbg_print (dbg_gop,4,dbg_facility,"analize_pdu: no match for this pdu");
                
                pdu->gop = NULL;
        }
@@ -668,7 +645,7 @@ static void analize_pdu(mate_pdu* pdu) {
 
 static void get_pdu_fields(gpointer k, gpointer v, gpointer p) {
        int hfid = *((int*) k);
-       guint8* name = (guint8*) v;
+       gchar* name = (gchar*) v;
        tmp_pdu_data* data = (tmp_pdu_data*) p;
        GPtrArray* fis;
        field_info* fi;
@@ -677,11 +654,9 @@ static void get_pdu_fields(gpointer k, gpointer v, gpointer p) {
        guint start;
        guint end;
        AVP* avp;
-       guint8* s;
-       
-       /* no warning */
-       k = p;
-       
+       gchar* s;
+               
+
        fis = (GPtrArray*) g_hash_table_lookup(data->interesting,(gpointer) hfid);
        
        if (fis) {
@@ -692,20 +667,18 @@ static void get_pdu_fields(gpointer k, gpointer v, gpointer p) {
                        start = fi->start;
                        end = fi->start + fi->length;
                        
-                       dbg_print(dbg_pdu,6,dbg_facility,"get_pdu_fields: found field %i-%i",start,end);
+                       dbg_print(dbg_pdu,5,dbg_facility,"get_pdu_fields: found field %i-%i",start,end);
                        
                        for (j = 0; j < data->ranges->len; j++) {
                                
                                curr_range = (mate_range*) g_ptr_array_index(data->ranges,j);
                                
-                               dbg_print(dbg_pdu,6,dbg_facility,"get_pdu_fields: check if in range %i-%i",curr_range->start,curr_range->end);
-                               
                                if (curr_range->end >= end && curr_range->start <= start) {
                                        avp = new_avp_from_finfo(name, fi);
                                        
                                        if (*dbg_pdu > 4) {
                                                s = avp_to_str(avp);
-                                               dbg_print(dbg_pdu,5,dbg_facility,"get_pdu_fields: got %s",s);
+                                               dbg_print(dbg_pdu,0,dbg_facility,"get_pdu_fields: got %s",s);
                                                g_free(s);
                                        }
                                        
@@ -720,7 +693,7 @@ static void get_pdu_fields(gpointer k, gpointer v, gpointer p) {
 }
 
 static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto, GHashTable* interesting) {
-       mate_pdu* pdu = new_mate_item(cfg);
+       mate_pdu* pdu = g_mem_chunk_alloc(rd->mate_items);
        field_info* cfi;
        GPtrArray* ptrs;
        mate_range* range;
@@ -734,19 +707,25 @@ static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto,
        gint32 curr_end;
        int hfid;
 
-       dbg_print (dbg_pdu,2,dbg_facility,"new_pdu: type=%s framenum=%i",cfg->name,framenum);
-               
+       dbg_print (dbg_pdu,1,dbg_facility,"new_pdu: type=%s framenum=%i",cfg->name,framenum);
+       
+       pdu->id = ++(cfg->last_id);
+       pdu->cfg = cfg;
+       
        pdu->avpl = new_avpl(cfg->name);
-       pdu->gop = NULL;
+       
+       pdu->frame = framenum;
        pdu->next_in_frame = NULL;
+       pdu->rel_time = rd->now;
+
+       pdu->gop = NULL;
        pdu->next = NULL;
+       pdu->time_in_gop = -1.0;
+       
        pdu->first = FALSE;
        pdu->is_start = FALSE;
        pdu->is_stop = FALSE;
        pdu->after_release = FALSE;
-       pdu->frame = framenum;
-       pdu->rel_time = rd->now;
-       pdu->time_in_gop = -1.0;
        
        data.ranges = g_ptr_array_new();
        data.pdu  = pdu;
@@ -762,8 +741,8 @@ static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto,
        
        last_start = proto_range->start;
        
-       /* first we move forward in the tranport */
-       for (i = 0; i < cfg->transport_ranges->len; i++) {
+       /* we move forward in the tranport */
+       for (i = cfg->transport_ranges->len; i--; ) {
                hfid = *((int*)g_ptr_array_index(cfg->transport_ranges,i));
                ptrs = (GPtrArray*) g_hash_table_lookup(interesting,GINT_TO_POINTER(hfid));
                min_dist = 99999;
@@ -799,7 +778,7 @@ static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto,
 
                first_end = proto_range->end;
                
-               for (i = cfg->payload_ranges->len - 1 ; i+1; i--) {
+               for (i = 0 ; i < cfg->payload_ranges->len; i++) {
                        hfid = *((int*)g_ptr_array_index(cfg->payload_ranges,i));
                        ptrs = (GPtrArray*) g_hash_table_lookup(interesting,GINT_TO_POINTER(hfid));
                        min_dist = 99999;
@@ -826,7 +805,7 @@ static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto,
                                        dbg_print(dbg_pdu,3,dbg_facility,"new_pdu: payload(%i) range %i-%i",hfid,range->start,range->end);
                                } else {
                                        /* we missed a range  */
-                                       dbg_print(dbg_pdu,6,dbg_facility,"new_pdu: payload(%i) missed",hfid);
+                                       dbg_print(dbg_pdu,5,dbg_facility,"new_pdu: payload(%i) missed",hfid);
                                }
                                
                        }
@@ -835,17 +814,14 @@ static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto,
 
        g_hash_table_foreach(cfg->hfids_attr,get_pdu_fields,&data);
        
+       apply_transforms(pdu->cfg->transforms,pdu->avpl);
+
        g_ptr_array_free(data.ranges,TRUE);
        
        return pdu;
 }      
 
 
-static void delete_mate_pdu(mate_pdu* pdu) {
-       if (pdu->avpl) delete_avpl(pdu->avpl,TRUE);
-       g_mem_chunk_free(rd->mate_items,pdu);   
-}
-
 extern void mate_analyze_frame(packet_info *pinfo, proto_tree* tree) {
        mate_cfg_pdu* cfg;
        GPtrArray* protos;
@@ -879,28 +855,32 @@ extern void mate_analyze_frame(packet_info *pinfo, proto_tree* tree) {
                                        
                                        if (cfg->criterium) {
                                                criterium_match = new_avpl_from_match(cfg->criterium_match_mode,"",pdu->avpl,cfg->criterium,FALSE);
+                                               
                                                if (criterium_match) {
                                                        delete_avpl(criterium_match,FALSE);
                                                }
                                                
-                                               if ( (criterium_match && cfg->criterium->name == mc->reject ) 
-                                                        || ( ! criterium_match && cfg->criterium->name == mc->accept )) {
-                                                       delete_mate_pdu(pdu);
+                                               if ( (criterium_match && cfg->criterium_accept_mode == REJECT_MODE ) 
+                                                        || ( ! criterium_match && cfg->criterium_accept_mode == ACCEPT_MODE )) {
+                                                       
+                                                       delete_avpl(pdu->avpl,TRUE);
+                                                       g_mem_chunk_free(rd->mate_items,pdu);   
                                                        pdu = NULL;
+                                                       
                                                        continue;
                                                }
                                        }
                                                                                
                                        analize_pdu(pdu);
                                        
-                                       if ( ! pdu->gop && cfg->drop_pdu) {
+                                       if ( ! pdu->gop && cfg->drop_unassigned) {
                                                delete_avpl(pdu->avpl,TRUE);
                                                g_mem_chunk_free(rd->mate_items,pdu);
                                                pdu = NULL;
                                                continue;
                                        }
                                        
-                                       if ( cfg->discard_pdu_attributes ) {
+                                       if ( cfg->discard ) {
                                                delete_avpl(pdu->avpl,TRUE);
                                                pdu->avpl = NULL;
                                        }
@@ -915,7 +895,7 @@ extern void mate_analyze_frame(packet_info *pinfo, proto_tree* tree) {
                                        
                                }
                                
-                               if ( pdu && cfg->last_to_be_created ) break;
+                               if ( pdu && cfg->last_extracted ) break;
                        }
                }
                
index dd3fe7ad5f16f86cf7984c964903c90062bbc36a..41e3470c5e98db6083ed192b0a1a69eb56908bb1 100644 (file)
 
 #include "mate.h"
 
-static int* dbg;
-
-static int dbg_cfg_lvl = 0;
-static int* dbg_cfg = &dbg_cfg_lvl;
-
-FILE* dbg_facility;
-
-typedef gboolean config_action(AVPL* avpl);
-
 /* the current mate_config */
 static mate_config* matecfg = NULL;
 
-/* key: the name of the action
-value: a pointer to an config_action */
-static GHashTable* actions = NULL;
-
-/* aestetics: I like keywords separated from user attributes */
-static AVPL* all_keywords = NULL;
-
-/* configuration error */
-GString* config_error;
-
-static void report_error(guint8* fmt, ...) {
-       static guint8 error_buffer[DEBUG_BUFFER_SIZE];
+/* appends the formatted string to the current error log */
+static void report_error(gchar* fmt, ...) {
+       static gchar error_buffer[DEBUG_BUFFER_SIZE];
 
        va_list list;
        
@@ -57,283 +39,120 @@ static void report_error(guint8* fmt, ...) {
        g_vsnprintf(error_buffer,DEBUG_BUFFER_SIZE,fmt,list);
        va_end( list );
        
-       g_string_append(config_error,error_buffer);
-       g_string_append_c(config_error,'\n');
+       g_string_append(matecfg->config_error,error_buffer);
+       g_string_append_c(matecfg->config_error,'\n');
        
 }
 
-/* use as:  setting = extract_named_xxx(avpl,keyword,default_value); */
-static int extract_named_int(AVPL* avpl, guint8* keyword, int value) {
-       AVP* avp = NULL;
-
-       if(( avp = extract_avp_by_name(avpl,keyword) )) {
-               value = strtol(avp->v,NULL,10);
-       }
-
-       return value;
-}
-
-static float extract_named_float(AVPL* avpl, guint8* keyword, float value) {
-       AVP* avp = NULL;
-
-       if(( avp = extract_avp_by_name(avpl,keyword) )) {
-               value = (float) strtod(avp->v,NULL);
-       }
-
-       return value;
-}
-
-static gboolean extract_named_bool(AVPL* avpl, guint8* keyword, gboolean value) {
-       AVP* avp = NULL;
-       if(( avp = extract_avp_by_name(avpl,keyword) )) {
-               value = ((g_strcasecmp(avp->v,"TRUE") == 0) ? TRUE : FALSE);
-       }
-
-       return value;
-}
-
-static guint8* extract_named_str(AVPL* avpl, guint8* keyword, guint8* value) {
-       AVP* avp = NULL;
-
-       if(( avp = extract_avp_by_name(avpl,keyword) )) {
-               value = avp->v;
-       }
-
-       return value;
-}
-
-/* lookups for the string value of the given named attribute from a given hash  */
-static gpointer lookup_using_index_avp(AVPL* avpl, guint8* keyword, GHashTable* table, guint8** avp_value) {
-       AVP* avp = extract_avp_by_name(avpl,keyword);
-
-       if (avp) {
-               *avp_value = avp->v;
-               return g_hash_table_lookup(table,avp->v);
-       } else {
-               *avp_value = NULL;
-               return NULL;
-       }
-}
-
-
-/* creates and initializes a mate_cfg_item */
-static mate_cfg_item* new_mate_cfg_item(guint8* name) {
-       mate_cfg_pdu* new = g_malloc(sizeof(mate_cfg_item));
-
-       new->name = g_strdup(name);
-       new->type = MATE_UNK_TYPE;
-       new->transforms = g_ptr_array_new();
-       new->extra = new_avpl(name);
-       new->last_id = 0;
-       new->hfid = -1;
-       new->my_hfids = g_hash_table_new(g_str_hash,g_str_equal);
-       new->items = g_hash_table_new(g_direct_hash,g_direct_equal);
-       new->ett = -1;
-       new->ett_attr = -1;
-       new->ett_times = -1;
-       new->ett_children = -1;
-       
-       new->discard_pdu_attributes = matecfg->discard_pdu_attributes;
-       new->last_to_be_created = matecfg->last_to_be_created;
-       new->hfid_proto = -1;
-       new->transport_ranges = NULL;
-       new->payload_ranges = NULL;
-       new->hfids_attr = NULL;
-       new->drop_pdu = matecfg->drop_pdu;
-       new->criterium_match_mode = AVPL_NO_MATCH;
-       new->criterium = NULL;
-       new->hfid_pdu_rel_time = -1;
-       new->hfid_pdu_time_in_gop = -1;
-
-       new->expiration = -1.0;
-       new->hfid_start_time = -1;
-       new->hfid_stop_time = -1;
-       new->hfid_last_time = -1;
-       
-       new->start = NULL;
-       new->stop = NULL;
-       new->key = NULL;
-       new->show_pdu_tree = matecfg->show_pdu_tree;
-       new->show_times = matecfg->show_times;
-       new->drop_gop = matecfg->drop_gop;
-       new->idle_timeout = -1.0;
-       new->lifetime = -1.0;
-       new->hfid_gop_pdu = -1;
-       new->hfid_gop_num_pdus = -1;
-       new->ett_gog_gop = -1;
-       new->hfid_gog_gopstart = -1;
-       
-       new->gop_index = NULL;
-       new->gog_index = NULL;
-
-       new->gop_as_subtree = NULL;
-       new->keys = NULL;
-       new->hfid_gog_num_of_gops = -1;
-       new->hfid_gog_gop = -1;
-       
-       return new;
-}
-
-/* for cleaning hashes */
-static gboolean free_both(gpointer k, gpointer v, gpointer p) {
-       g_free(k);
-       if (p) g_free(v);
-       return TRUE;
-}
-
-static void delete_mate_cfg_item(mate_cfg_item* cfg, gboolean avp_items_too) {
-
-       g_free(cfg->name);
+/* creates a blank pdu config
+     is going to be called only by the grammar
+        which will set all those elements that aren't set here */
+extern mate_cfg_pdu* new_pducfg(gchar* name) {
+       mate_cfg_pdu* cfg = g_malloc(sizeof(mate_cfg_pdu));
 
-       if (avp_items_too) {
-               if (cfg->extra) delete_avpl(cfg->extra,TRUE);
-               if (cfg->start) delete_avpl(cfg->start,TRUE);
-               if (cfg->stop)  delete_avpl(cfg->stop,TRUE);
-               if (cfg->key)  delete_avpl(cfg->key,TRUE);
-               if (cfg->criterium)  delete_avpl(cfg->criterium,TRUE);
-               if (cfg->keys) delete_loal(cfg->keys,TRUE,TRUE);
-       }
+       cfg->name = g_strdup(name);
+       cfg->last_id = 0;
 
-       if (cfg->transforms) g_ptr_array_free(cfg->transforms,TRUE);
+       cfg->items = g_hash_table_new(g_direct_hash,g_direct_equal);
+       cfg->transforms = NULL;
 
-       if (cfg->transport_ranges)
-               g_ptr_array_free(cfg->transport_ranges,TRUE);
+       cfg->hfid = -1;
        
-       if (cfg->payload_ranges)
-               g_ptr_array_free(cfg->payload_ranges,TRUE);
-
-       if (cfg->hfids_attr)
-               g_hash_table_foreach_remove(cfg->hfids_attr,free_both, VALUE_TOO );
-
-}
+       cfg->hfid_pdu_rel_time = -1;
+       cfg->hfid_pdu_time_in_gop = -1;
+       
+       cfg->my_hfids = g_hash_table_new(g_str_hash,g_str_equal);
 
-static mate_cfg_pdu* new_pducfg(guint8* name) {
-       mate_cfg_pdu* new = new_mate_cfg_item(name);
+       cfg->ett = -1;
+       cfg->ett_attr = -1;     
 
-       new->type = MATE_PDU_TYPE;
-       new->transport_ranges = g_ptr_array_new();
+       cfg->criterium = NULL;
+       cfg->criterium_match_mode = AVPL_NO_MATCH;
+       cfg->criterium_accept_mode = ACCEPT_MODE;
        
-       new->hfids_attr = g_hash_table_new(g_int_hash,g_int_equal);
+       g_ptr_array_add(matecfg->pducfglist,(gpointer) cfg);
+       g_hash_table_insert(matecfg->pducfgs,(gpointer) cfg->name,(gpointer) cfg);
 
-       g_ptr_array_add(matecfg->pducfglist,(gpointer) new);
+       cfg->hfids_attr = g_hash_table_new(g_int_hash,g_int_equal);
 
-       g_hash_table_insert(matecfg->pducfgs,(gpointer) new->name,(gpointer) new);
-
-       return new;
+       return cfg;
 }
 
-static mate_cfg_gop* new_gopcfg(guint8* name) {
-       mate_cfg_gop* new = new_mate_cfg_item(name);
+extern mate_cfg_gop* new_gopcfg(gchar* name) {
+       mate_cfg_gop* cfg = g_malloc(sizeof(mate_cfg_gop));
        
-       new->type = MATE_GOP_TYPE;
-       new->expiration = matecfg->gop_expiration;
-       new->idle_timeout = matecfg->gop_idle_timeout;
-       new->lifetime = matecfg->gop_lifetime;
-       new->show_pdu_tree = matecfg->show_pdu_tree;
-       new->show_times = matecfg->show_times;
-       new->drop_gop = matecfg->drop_gop;
+       cfg->name = g_strdup(name);
+       cfg->last_id = 0;
        
-       g_hash_table_insert(matecfg->gopcfgs,(gpointer) new->name, (gpointer) new);
-
-       new->gop_index = g_hash_table_new(g_str_hash,g_str_equal);
-       new->gog_index = g_hash_table_new(g_str_hash,g_str_equal);
+       cfg->items = g_hash_table_new(g_direct_hash,g_direct_equal);
+       cfg->transforms = NULL;
        
-       return new;
-}
-
-static mate_cfg_gog* new_gogcfg(guint8* name) {
-       mate_cfg_gog* new = new_mate_cfg_item(name);
-       new->type = MATE_GOG_TYPE;
-
-       new->keys = new_loal(name);
-       new->expiration = matecfg->gog_expiration;
+       cfg->extra = new_avpl("extra");
        
-       g_hash_table_insert(matecfg->gogcfgs,new->name,new);
-
-       return new;
-}
-
-static gboolean free_cfgs(gpointer k _U_, gpointer v, gpointer p) {
-       delete_mate_cfg_item((mate_cfg_item*)v,(gboolean) p);
-       return TRUE;
-}
-
-extern void destroy_mate_config(mate_config* mc , gboolean avplib_too) {
-       if (mc->dbg_facility) fclose(mc->dbg_facility);
-       if (mc->mate_lib_path) g_free(mc->mate_lib_path);
-       if (mc->mate_config_file) g_free(mc->mate_config_file);
-       if (mc->mate_attrs_filter) g_string_free(mc->mate_attrs_filter,TRUE);
-       if (mc->mate_protos_filter) g_string_free(mc->mate_protos_filter,TRUE);
-       if (mc->pducfglist) g_ptr_array_free(mc->pducfglist,FALSE);
-
-       if (mc->gogs_by_gopname) {
-               g_hash_table_destroy(mc->gogs_by_gopname);
-       }
+       cfg->hfid = -1;
+       
+       cfg->ett = -1;
+       cfg->ett_attr = -1;
+       cfg->ett_times = -1;
+       cfg->ett_children = -1;
 
-       if (mc->pducfgs) {
-               g_hash_table_foreach_remove(mc->pducfgs,free_cfgs,(gpointer) avplib_too);
-               g_hash_table_destroy(mc->pducfgs);
-       }
+       cfg->hfid_start_time = -1;
+       cfg->hfid_stop_time = -1;
+       cfg->hfid_last_time = -1;
 
-       if (mc->gopcfgs) {
-               g_hash_table_foreach_remove(mc->gopcfgs,free_cfgs,(gpointer) avplib_too);
-               g_hash_table_destroy(mc->gopcfgs);
-       }
+       cfg->hfid_gop_pdu = -1;
+       cfg->hfid_gop_num_pdus = -1;
 
-       if (mc->gogcfgs) {
-               g_hash_table_foreach_remove(mc->gogcfgs,free_cfgs,(gpointer) avplib_too);
-               g_hash_table_destroy(mc->gogcfgs);
-       }
+       cfg->my_hfids = g_hash_table_new(g_str_hash,g_str_equal);
 
-       if (mc->tap_filter)     g_free(mc->tap_filter);
+       cfg->gop_index = g_hash_table_new(g_str_hash,g_str_equal);
+       cfg->gog_index = g_hash_table_new(g_str_hash,g_str_equal);
 
-       if (mc->hfrs) g_array_free(mc->hfrs,TRUE);
-       g_free(mc);
+       g_hash_table_insert(matecfg->gopcfgs,(gpointer) cfg->name, (gpointer) cfg);
 
+       return cfg;
 }
 
-static gboolean mate_load_config(guint8* filename) {
-       LoAL* loal = loal_from_file(filename);
-       AVPL* avpl;
-       config_action* action;
-       guint8* name;
+extern mate_cfg_gog* new_gogcfg(gchar* name) {
+       mate_cfg_gog* cfg = g_malloc(sizeof(mate_cfg_gop));
+       
+       cfg->name = g_strdup(name);
+       cfg->last_id = 0;
+       
+       cfg->items = g_hash_table_new(g_direct_hash,g_direct_equal);
+       cfg->transforms = NULL;
+       
+       cfg->extra = new_avpl("extra");
+       
+       cfg->my_hfids = g_hash_table_new(g_str_hash,g_str_equal);
+       cfg->hfid = -1;
+       
+       cfg->ett = -1;
+       cfg->ett_attr = -1;
+       cfg->ett_times = -1;
+       cfg->ett_children = -1;
+       cfg->ett_gog_gop = -1;
+       
+       cfg->hfid_gog_num_of_gops = -1;
+       cfg->hfid_gog_gop = -1;
+       cfg->hfid_gog_gopstart = -1;
+       
+       cfg->hfid_start_time = -1;
+       cfg->hfid_stop_time = -1;
+       cfg->hfid_last_time = -1;
        
-       /* FIXME: we are leaking the config avpls to avoid unsubscribed strings left arround */ 
+       g_hash_table_insert(matecfg->gogcfgs,(gpointer) cfg->name, (gpointer) cfg);
 
-       if (loal->len) {
-               while(( avpl = extract_first_avpl(loal) )) {
-                       dbg_print (dbg_cfg,3,dbg_facility,"mate_make_config: current line: %s",avpl->name);
-                       
-                       action = lookup_using_index_avp(avpl, KEYWORD_ACTION, actions,&name);
-                       
-                       if (action) {
-                               if ( ! action(avpl) ) {
-                                       report_error("MATE: Error on: %s",avpl->name);
-                                       return FALSE;
-                               }
-                       } else {
-                               report_error("MATE: action '%s' unknown in: %s",name,avpl->name);
-                               return FALSE;
-                       }
-               }
-               
-               return TRUE;
-       } else {
-               report_error("MATE: error reading config file: %s",loal->name);
-               return FALSE;
-       }
+       return cfg;
 }
 
-static gboolean add_hfid(guint8* what, guint8* how, GHashTable* where) {
-       header_field_info*  hfi = NULL;
+extern gboolean add_hfid(header_field_info*  hfi, gchar* how, GHashTable* where) {
        header_field_info*  first_hfi = NULL;
        gboolean exists = FALSE;
-       guint8* as;
-       guint8* h;
+       gchar* as;
+       gchar* h;
        int* ip;
 
-       hfi = proto_registrar_get_byname(what);
-
        while(hfi) {
                first_hfi = hfi;
                hfi = hfi->same_name_prev;
@@ -351,15 +170,12 @@ static gboolean add_hfid(guint8* what, guint8* how, GHashTable* where) {
                        g_free(ip);
                        if (! g_str_equal(as,how)) {
                                report_error("MATE Error: add field to Pdu: attempt to add %s(%i) as %s"
-                                                 " failed: field already added as '%s'",what,hfi->id,how,as);
+                                                 " failed: field already added as '%s'",hfi->abbrev,hfi->id,how,as);
                                return FALSE;
                        }
                } else {
                        h = g_strdup(how);
                        g_hash_table_insert(where,ip,h);
-
-
-                       dbg_print (dbg,5,dbg_facility,"add_hfid: added hfid %s(%i) as %s",what,*ip,how);
                }
 
                hfi = hfi->same_name_next;
@@ -367,13 +183,12 @@ static gboolean add_hfid(guint8* what, guint8* how, GHashTable* where) {
        }
 
        if (! exists) {
-               report_error("MATE Error: cannot find field %s",what);
-       }
-
+               report_error("MATE Error: cannot find field %s",hfi->abbrev);
+       }       
        return exists;
 }
 
-static guint8* add_ranges(guint8* range,GPtrArray* range_ptr_arr) {
+extern gchar* add_ranges(gchar* range,GPtrArray* range_ptr_arr) {
        gchar**  ranges;
        guint i;
        header_field_info* hfi;
@@ -388,7 +203,7 @@ static guint8* add_ranges(guint8* range,GPtrArray* range_ptr_arr) {
                                hfidp = g_malloc(sizeof(int));
                                *hfidp = hfi->id;
                                g_ptr_array_add(range_ptr_arr,(gpointer)hfidp);
-                               g_string_sprintfa(matecfg->mate_attrs_filter, "||%s",ranges[i]);
+                               g_string_sprintfa(matecfg->fields_filter, "||%s",ranges[i]);
                        } else {
                                g_strfreev(ranges);
                                return g_strdup_printf("no such proto: '%s'",ranges[i]);;
@@ -397,586 +212,14 @@ static guint8* add_ranges(guint8* range,GPtrArray* range_ptr_arr) {
                
                g_strfreev(ranges);
        }
-       
-       return NULL;
-}
-
-
-static gboolean config_pdu(AVPL* avpl) {
-       guint8* name = NULL;
-       guint8* transport = extract_named_str(avpl,KEYWORD_TRANSPORT,NULL);
-       guint8* payload = extract_named_str(avpl,KEYWORD_PAYLOAD,NULL);
-       guint8* proto = extract_named_str(avpl,KEYWORD_PROTO,"no_protocol");
-       mate_cfg_pdu* cfg = lookup_using_index_avp(avpl,KEYWORD_NAME,matecfg->pducfgs,&name);
-       header_field_info* hfi;
-       guint8* range_err;
-       AVP* attr_avp;
-
-       if (! name ) {
-               report_error("MATE: PduDef: No Name in: %s",avpl->name);
-               return FALSE;           
-       }
-       
-       if (! cfg) {
-               cfg = new_pducfg(name);
-       } else {
-               report_error("MATE: PduDef: No such PDU: '%s' in: %s",cfg->name,avpl->name);
-               return FALSE;
-       }
-
-       cfg->last_to_be_created = extract_named_bool(avpl,KEYWORD_STOP,matecfg->last_to_be_created);
-       cfg->discard_pdu_attributes = extract_named_bool(avpl,KEYWORD_DISCARDPDU,matecfg->discard_pdu_attributes);
-       cfg->drop_pdu = extract_named_bool(avpl,KEYWORD_DROPPDU,matecfg->drop_pdu);
-
-       hfi = proto_registrar_get_byname(proto);
-
-       if (hfi) {
-               cfg->hfid_proto = hfi->id;
-       } else {
-               report_error("MATE: PduDef: no such proto: '%s' in: %s",proto,avpl->name);
-               return FALSE;
-       }
-
-       g_string_sprintfa(matecfg->mate_protos_filter,"||%s",proto);
-
-       if ( transport ) {
-               if (( range_err = add_ranges(transport,cfg->transport_ranges) )) {
-                       report_error("MATE: PduDef: %s in Transport for '%s' in: %s",range_err, cfg->name,avpl->name);
-                       g_free(range_err);
-                       return FALSE;                   
-               }
-       } else {
-               report_error("MATE: PduDef: no Transport for '%s' in: %s",cfg->name,avpl->name);
-               return FALSE;
-       }
-
-       if ( payload ) {
-               cfg->payload_ranges = g_ptr_array_new();
-               if (( range_err = add_ranges(payload,cfg->payload_ranges) )) {
-                       report_error("MATE: PduDef: %s in Payload for '%s' in: %s",range_err, cfg->name,avpl->name);
-                       g_free(range_err);
-                       return FALSE;                   
-               }
-       }
-       
-       while (( attr_avp = extract_first_avp(avpl) )) {
-               if ( ! add_hfid(attr_avp->v,attr_avp->n,cfg->hfids_attr) ) {
-                       report_error("MATE: PduDef: failed to set PDU attribute '%s' in: %s",attr_avp->n,avpl->name);
-                       return FALSE;
-               }
-               g_string_sprintfa(matecfg->mate_attrs_filter, "||%s",attr_avp->v);
-       }
-
-       return TRUE;
-}
-
-static gboolean config_pduextra(AVPL* avpl) {
-       guint8* name;
-       AVP* attr_avp;
-       mate_cfg_pdu* cfg = lookup_using_index_avp(avpl,KEYWORD_FOR,matecfg->pducfgs,&name);
-
-       if (! name ) {
-               report_error("MATE: PduExtra: No For in: %s",avpl->name);
-               return FALSE;           
-       }
-
-       if (! cfg) {
-               report_error("MATE: PduExtra: no such Pdu '%s' in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       cfg->last_to_be_created = extract_named_bool(avpl,KEYWORD_STOP,cfg->last_to_be_created);
-       cfg->discard_pdu_attributes = extract_named_bool(avpl,KEYWORD_DISCARDPDU,cfg->discard_pdu_attributes);
-       cfg->drop_pdu = extract_named_bool(avpl,KEYWORD_DROPPDU,cfg->drop_pdu);
-
-       while (( attr_avp = extract_first_avp(avpl) )) {
-               if ( ! add_hfid(attr_avp->v,attr_avp->n,cfg->hfids_attr) ) {
-                       report_error("MATE: PduExtra: failed to set attr '%s' in: %s",attr_avp->n,avpl->name);
-                       delete_avp(attr_avp);
-                       return FALSE;
-               }
-               g_string_sprintfa(matecfg->mate_attrs_filter, "||%s",attr_avp->v);
-       }
-
-       delete_avpl(avpl,TRUE);
-       return TRUE;
-
-}
-
-
-static gboolean config_pducriteria(AVPL* avpl) {
-       guint8* name;
-       mate_cfg_gop* cfg = lookup_using_index_avp(avpl, KEYWORD_FOR,matecfg->pducfgs,&name);
-       guint8* match = extract_named_str(avpl, KEYWORD_MATCH, NULL);
-       avpl_match_mode match_mode = AVPL_STRICT;
-       guint8* mode = extract_named_str(avpl, KEYWORD_MODE, NULL);
-
-       if (! name ) {
-               report_error("MATE: PduCriteria: No For in: %s",avpl->name);
-               return FALSE;           
-       }
-       
-       if (!cfg) {
-               report_error("MATE: PduCriteria: Pdu '%s' does not exist in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       if ( mode ) {
-               if ( g_strcasecmp(mode,KEYWORD_ACCEPT) == 0 ) {
-                       mode = matecfg->accept;
-               } else if ( g_strcasecmp(mode,KEYWORD_REJECT) == 0 ) {
-                       mode = matecfg->reject;
-               } else {
-                       report_error("MATE: PduCriteria: no such criteria mode: '%s' in %s",mode,avpl->name);
-                       return FALSE;
-               }
-       } else {
-               mode = matecfg->accept;
-       }
-
-       rename_avpl(avpl,mode);
-
-       if ( match ) {
-               if ( g_strcasecmp(match,KEYWORD_LOOSE) == 0 ) {
-                       match_mode = AVPL_LOOSE;
-               } else if ( g_strcasecmp(match,KEYWORD_EVERY) == 0 ) {
-                       match_mode = AVPL_EVERY;
-               } else if ( g_strcasecmp(match,KEYWORD_STRICT) == 0 ) {
-                       match_mode = AVPL_STRICT;
-               } else {
-                       report_error("MATE: PduCriteria: Config error: no such match mode '%s' in: %s",match,avpl->name);
-                       return FALSE;
-               }
-       }
-
-       cfg->criterium_match_mode = match_mode;
-
-       if (cfg->criterium) {
-               /* FEATURE: more criteria */
-               report_error("MATE: PduCriteria: PduCriteria alredy exists for '%s' in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-
-       cfg->criterium = avpl;
-
-       return TRUE;
-}
-
-
-static gboolean config_include(AVPL* avpl) {
-       guint8* filename = extract_named_str(avpl,KEYWORD_FILENAME,NULL);
-       guint8* lib = extract_named_str(avpl,KEYWORD_LIB,NULL);
-
-       if ( ! filename && ! lib ) {
-               report_error("MATE: Include: no Filename or Lib given in: %s",avpl->name);
-               return FALSE;
-       }
-
-       if ( filename && lib ) {
-               report_error("MATE: Include: use either Filename or Lib, not both. in: %s",avpl->name);
-               return FALSE;
-       }
-
-       if (lib) {
-               filename = g_strdup_printf("%s%s.mate",matecfg->mate_lib_path,lib);
-       }
-
-       /* FIXME: stop recursion */
-       if ( ! mate_load_config(filename) ) {
-               report_error("MATE: Include: Error Loading '%s' in: %s",filename,avpl->name);
-               if (lib) g_free(filename);
-               return FALSE;
-       }
-
-       if (lib) g_free(filename);
-
-       return TRUE;
-}
-
-
-static gboolean config_settings(AVPL*avpl) {
-       AVP* avp;
-
-#ifdef _AVP_DEBUGGING
-       int debug_avp = 0;
-       int dbg_avp = 0;
-       int dbg_avp_op = 0;
-       int dbg_avpl = 0;
-       int dbg_avpl_op = 0;
-#endif
-
-
-       matecfg->gog_expiration = extract_named_float(avpl, KEYWORD_GOGEXPIRE,matecfg->gog_expiration);
-       matecfg->gop_expiration = extract_named_float(avpl, KEYWORD_GOPEXPIRATION,matecfg->gop_expiration);
-       matecfg->gop_idle_timeout = extract_named_float(avpl, KEYWORD_GOPIDLETIMEOUT,matecfg->gop_idle_timeout);
-       matecfg->gop_lifetime = extract_named_float(avpl, KEYWORD_GOPLIFETIME,matecfg->gop_lifetime);
-       matecfg->discard_pdu_attributes = extract_named_bool(avpl, KEYWORD_DISCARDPDU,matecfg->discard_pdu_attributes);
-       matecfg->drop_pdu = extract_named_bool(avpl, KEYWORD_DROPPDU,matecfg->drop_pdu);
-       matecfg->drop_gop = extract_named_bool(avpl, KEYWORD_DROPGOP,matecfg->drop_gop);
-       matecfg->show_pdu_tree = extract_named_str(avpl, KEYWORD_SHOWPDUTREE,matecfg->show_pdu_tree);
-       matecfg->show_times = extract_named_bool(avpl, KEYWORD_SHOWGOPTIMES,matecfg->show_times);
-
-       if(( avp = extract_avp_by_name(avpl,KEYWORD_DEBUGFILENAME) )) {
-               matecfg->dbg_facility = dbg_facility = fopen(avp->v,"w");
-               delete_avp(avp);
-               avp = NULL;
-       }
-
-       matecfg->dbg_lvl = extract_named_int(avpl, KEYWORD_DBG_GENERAL,0);
-       matecfg->dbg_cfg_lvl = extract_named_int(avpl, KEYWORD_DBG_CFG,0);
-       matecfg->dbg_pdu_lvl = extract_named_int(avpl, KEYWORD_DBG_PDU,0);
-       matecfg->dbg_gop_lvl = extract_named_int(avpl, KEYWORD_DBG_GOP,0);
-       matecfg->dbg_gog_lvl = extract_named_int(avpl, KEYWORD_DBG_GOG,0);
-
-#ifdef _AVP_DEBUGGING
-        setup_avp_debug(dbg_facility,
-                                        extract_named_int(avpl, KEYWORD_DBG_AVPLIB,0),
-                                        extract_named_int(avpl, KEYWORD_DBG_AVP,0),
-                                        extract_named_int(avpl, KEYWORD_DBG_AVP_OP,0),
-                                        extract_named_int(avpl, KEYWORD_DBG_AVPL,0),
-                                        extract_named_int(avpl, KEYWORD_DBG_AVPL_OP,0));
-#endif
-
-       dbg_cfg_lvl = matecfg->dbg_cfg_lvl;
-
-       return TRUE;
-}
-
-static gboolean config_transform(AVPL* avpl) {
-       guint8* name = extract_named_str(avpl, KEYWORD_NAME, NULL);
-       guint8* match = extract_named_str(avpl, KEYWORD_MATCH, NULL);
-       guint8* mode = extract_named_str(avpl, KEYWORD_MODE, NULL);
-       avpl_match_mode match_mode;
-       avpl_replace_mode replace_mode;
-       AVPL_Transf* t;
-       AVPL_Transf* last;
-
-       if ( match ) {
-               if ( g_strcasecmp(match,KEYWORD_LOOSE) == 0 ) {
-                       match_mode = AVPL_LOOSE;
-               } else if ( g_strcasecmp(match,KEYWORD_EVERY) == 0 ) {
-                       match_mode = AVPL_EVERY;
-               } else if ( g_strcasecmp(match,KEYWORD_STRICT) == 0 ) {
-                       match_mode = AVPL_STRICT;
-               } else {
-                       report_error("MATE: Transform: no such match mode: '%s' in: %s",match,avpl->name);
-                       return FALSE;
-               }
-       } else {
-               match_mode = matecfg->match_mode;
-       }
-
-       if ( mode ) {
-               if ( g_strcasecmp(mode,KEYWORD_INSERT) == 0 ) {
-                       replace_mode = AVPL_INSERT;
-               } else if ( g_strcasecmp(mode,KEYWORD_REPLACE) == 0 ) {
-                       replace_mode = AVPL_REPLACE;
-               } else {
-                       report_error("MATE: Transform: no such replace mode: '%s' in: %s",mode,avpl->name);
-                       return FALSE;
-               }
-
-       } else {
-               replace_mode = matecfg->replace_mode;
-       }
-
-       if (! name) {
-               report_error("MATE: Transform: no Name in: %s",avpl->name);
-               return FALSE;
-       }
-
-       t = new_avpl_transform(name,avpl, match_mode, replace_mode);
-
-       if (( last = g_hash_table_lookup(matecfg->transfs,name) )) {
-               while (last->next) last = last->next;
-               last->next = t;
-       } else {
-               g_hash_table_insert(matecfg->transfs,t->name,t);
-       }
-
-       return TRUE;
-}
-
-static gboolean config_xxx_transform(AVPL* avpl, GHashTable* hash, guint8* keyword) {
-       guint8* cfg_name;
-       guint8* name;
-       AVPL_Transf* transf = lookup_using_index_avp(avpl,KEYWORD_NAME,matecfg->transfs,&name);
-       mate_cfg_pdu* cfg = lookup_using_index_avp(avpl,KEYWORD_FOR,hash,&cfg_name);;
-       
-       if (! name ) {
-               report_error("MATE: %s: no Name in: %s",keyword,avpl->name);
-               return FALSE;
-       }
-
-       if (! cfg_name ) {
-               report_error("MATE: %s: no For in: %s",keyword,avpl->name);
-               return FALSE;
-       }
-
-       if (! cfg ) {
-               report_error("MATE: %s: '%s' doesn't exist in: %s",keyword,cfg_name,avpl->name);
-               return FALSE;
-       }
-
-       if (!transf) {
-               report_error("MATE: %s: Transform '%s' doesn't exist in: %s",keyword,name,avpl->name);
-               return FALSE;
-       }
-
-       g_ptr_array_add(cfg->transforms,transf);
-
-       return TRUE;
-}
-
-static gboolean config_pdu_transform(AVPL* avpl) {
-       return config_xxx_transform(avpl, matecfg->pducfgs, KEYWORD_PDUTRANSFORM);
-}
-
-static gboolean config_gop_transform(AVPL* avpl) {
-       return config_xxx_transform(avpl, matecfg->gopcfgs, KEYWORD_GOPTRANSFORM);
-}
-
-static gboolean config_gog_transform(AVPL* avpl) {
-       return config_xxx_transform(avpl, matecfg->gogcfgs, KEYWORD_GOPTRANSFORM);
-}
-
-static gboolean config_gop(AVPL* avpl) {
-       guint8* name = NULL;
-       mate_cfg_gop* cfg = lookup_using_index_avp(avpl, KEYWORD_NAME,matecfg->gopcfgs,&name);
-       guint8* on = extract_named_str(avpl,KEYWORD_ON,NULL);
-
-       if (! name ) {
-               report_error("MATE: GopDef: no Name in: %s",avpl->name);
-               return FALSE;
-       }
-       
-       if (!cfg) {
-               cfg = new_gopcfg(name);
-       } else {
-               report_error("MATE: GopDef: Gop '%s' exists already in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       if (! on ) {
-               report_error("MATE: GopDef: no On in: %s",avpl->name);
-               return FALSE;
-       }
-       
-       if (g_hash_table_lookup(matecfg->pducfgs,on) == NULL ) {
-               report_error("MATE: GopDef: Pdu '%s' does not exist in: %s",on,avpl->name);
-               return FALSE;           
-       }
-
-       if (g_hash_table_lookup(matecfg->gops_by_pduname,on) ) {
-               report_error("MATE: GopDef: Gop for Pdu '%s' exists already in: %s",on,avpl->name);
-               return FALSE;
-       } else {
-               g_hash_table_insert(matecfg->gops_by_pduname,on,cfg);
-       }
-
-       cfg->drop_gop = extract_named_bool(avpl, KEYWORD_DROPGOP,matecfg->drop_gop);
-       cfg->show_pdu_tree = extract_named_str(avpl, KEYWORD_SHOWPDUTREE, matecfg->show_pdu_tree);
-       cfg->show_times = extract_named_bool(avpl, KEYWORD_SHOWGOPTIMES,matecfg->show_times);
-       cfg->expiration = extract_named_float(avpl, KEYWORD_GOPEXPIRATION,matecfg->gop_expiration);
-       cfg->idle_timeout = extract_named_float(avpl, KEYWORD_GOPIDLETIMEOUT,matecfg->gop_idle_timeout);
-       cfg->lifetime = extract_named_float(avpl, KEYWORD_GOPLIFETIME,matecfg->gop_lifetime);
-       
-       cfg->key = avpl;
-
-       return TRUE;
-}
-
-static gboolean config_start(AVPL* avpl) {
-       guint8* name;
-       mate_cfg_gop* cfg = lookup_using_index_avp(avpl, KEYWORD_FOR,matecfg->gopcfgs,&name);;
-
-       if (! name ) {
-               report_error("MATE: GopStart: no For in: %s",avpl->name);
-               return FALSE;
-       }
-       
-       if (!cfg) {
-               report_error("MATE: GopStart: Gop '%s' doesn't exist in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       if (cfg->start) {
-               /* FEATURE: more start conditions */
-               report_error("MATE: GopStart: GopStart for '%s' exists already in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       cfg->start = avpl;
-
-       return TRUE;
-}
-
-static gboolean config_stop(AVPL* avpl) {
-       guint8* name;
-       mate_cfg_gop* cfg = lookup_using_index_avp(avpl, KEYWORD_FOR,matecfg->gopcfgs,&name);;
-       
-       if (! name ) {
-               report_error("MATE: GopStop: no For in: %s",avpl->name);
-               return FALSE;
-       }
-       
-       if (!cfg) {
-               report_error("MATE: GopStop: Gop '%s' doesn't exist in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       if (cfg->stop) {
-               report_error("MATE: GopStop: GopStop alredy exists for '%s' in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       cfg->stop = avpl;
-
-       return TRUE;
-}
-
-static gboolean config_gopextra(AVPL* avpl) {
-       guint8* name;
-       mate_cfg_gop* cfg = lookup_using_index_avp(avpl, KEYWORD_FOR,matecfg->gopcfgs,&name);;
-
-       if (! name ) {
-               report_error("MATE: GopExtra: no For in: %s",avpl->name);
-               return FALSE;
-       }
-       
-       if (!cfg) {
-               report_error("MATE: GopExtra: Gop '%s' does not exist in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       cfg->drop_gop = extract_named_bool(avpl, KEYWORD_DROPGOP,cfg->drop_gop);
-       cfg->show_pdu_tree = extract_named_str(avpl, KEYWORD_SHOWPDUTREE, cfg->show_pdu_tree);
-       cfg->show_times = extract_named_bool(avpl, KEYWORD_SHOWGOPTIMES,cfg->show_times);
-       cfg->expiration = extract_named_float(avpl, KEYWORD_GOPEXPIRATION,cfg->expiration);
-       cfg->idle_timeout = extract_named_float(avpl, KEYWORD_GOPIDLETIMEOUT,cfg->idle_timeout);
-       cfg->lifetime = extract_named_float(avpl, KEYWORD_GOPLIFETIME,cfg->lifetime);
-       
-       merge_avpl(cfg->extra,avpl,TRUE);
-
-       return TRUE;
-}
-
-static gboolean config_gog(AVPL* avpl) {
-       guint8* name = extract_named_str(avpl, KEYWORD_NAME,NULL);
-       mate_cfg_gog* cfg = NULL;
-
-       if (! name ) {
-               report_error("MATE: GogDef: no Name in: %s",avpl->name);
-               return FALSE;
-       }
-       
-       if ( g_hash_table_lookup(matecfg->gogcfgs,name) ) {
-               report_error("MATE: GogDef: Gog '%s' exists already in: %s",name,avpl->name);
-               return FALSE;
-       }
-
-       cfg = new_gogcfg(name);
-
-       cfg->expiration = extract_named_float(avpl, KEYWORD_GOGEXPIRE,matecfg->gog_expiration);
-       cfg->gop_as_subtree = extract_named_str(avpl, KEYWORD_GOPTREE,matecfg->gop_as_subtree);
-       
-       return TRUE;
-}
-
-static gboolean config_gogkey(AVPL* avpl) {
-       guint8* name;
-       mate_cfg_gog* cfg = lookup_using_index_avp(avpl, KEYWORD_FOR,matecfg->gogcfgs,&name);
-       AVPL* reverse_avpl;
-       LoAL* gogkeys;
-       guint8* on = extract_named_str(avpl,KEYWORD_ON,NULL);
-
-       if ( ! name || ! cfg ) {
-               if ( ! name )
-                       report_error("MATE: GogKey: no For in %s",avpl->name);
-               else
-                       report_error("MATE: GogKey: no such Gop '%s' in %s",name,avpl->name);
-
-               return FALSE;
-       }
-
-       if (! on ) {
-               report_error("MATE: GogKey: no On in %s",avpl->name);
-               return FALSE;
-       }
-
-       if (! g_hash_table_lookup(matecfg->gopcfgs,on) ) {
-               report_error("MATE: GogKey: no such Gop %s in On",on);
-               return FALSE;
-       }
-       
-       rename_avpl(avpl,name);
-
-       gogkeys = (LoAL*) g_hash_table_lookup(matecfg->gogs_by_gopname,on);
-
-       if (! gogkeys) {
-               gogkeys = new_loal("straight");
-               g_hash_table_insert(matecfg->gogs_by_gopname,g_strdup(on),gogkeys);
-       }
-
-       loal_append(gogkeys,avpl);
-
-       reverse_avpl = new_avpl_from_avpl(on,avpl,TRUE);
-
-       loal_append(cfg->keys,reverse_avpl);
-
-       return TRUE;
-}
-
-static gboolean config_gogextra(AVPL* avpl) {
-       guint8* name;
-       mate_cfg_gop* cfg = lookup_using_index_avp(avpl, KEYWORD_FOR,matecfg->gogcfgs,&name);
-
-       if ( ! name || ! cfg ) {
-               if ( ! name )
-                       report_error("MATE: GogExtra: no Name in %s",avpl->name);
-               else
-                       report_error("MATE: GogExtra: no such Gop '%s' in %s",name,avpl->name);
-
-               return FALSE;
-       }
-
-       cfg->expiration = extract_named_float(avpl, KEYWORD_GOGEXPIRE,cfg->expiration);
-       cfg->gop_as_subtree = extract_named_str(avpl, KEYWORD_GOPTREE,cfg->gop_as_subtree);
-
-       merge_avpl(cfg->extra,avpl,TRUE);
-
-       return TRUE;
-}
-
-#define true_false_str(v) ((v) ? "TRUE" : "FALSE")
-
-static void print_xxx_transforms(mate_cfg_item* cfg) {
-       guint8* tr_name;
-       guint8* cfg_name;
-       guint i;
-
-       switch (cfg->type) {
-               case MATE_PDU_TYPE:
-                       cfg_name = "PduTransform";
-                       break;
-               case MATE_GOP_TYPE:
-                       cfg_name = "GopTransform";
-                       break;
-               case MATE_GOG_TYPE:
-                       cfg_name = "GogTransform";
-                       break;
-               default:
-                       cfg_name = "UnknownTransform";
-                       break;
-       }
+       
+       return NULL;
+}
 
-       for (i=0; i < cfg->transforms->len; i++) {
-               tr_name = ((AVPL_Transf*) g_ptr_array_index(cfg->transforms,i))->name;
-               dbg_print (dbg_cfg,0,dbg_facility,"Action=%s; For=%s; Name=%s;",cfg_name,cfg->name,tr_name);
-       }
 
-}
+#if 0
+#define true_false_str(v) ((v) ? "TRUE" : "FALSE")
+
 
 static void print_gog_config(gpointer k _U_, gpointer v, gpointer p _U_) {
        mate_cfg_gop* cfg = (mate_cfg_gop*) v;
@@ -1053,133 +296,6 @@ static void print_gop_config(gpointer k _U_ , gpointer v, gpointer p _U_) {
 
 }
 
-static guint8* my_protoname(int proto_id) {
-       if (proto_id) {
-               return proto_registrar_get_abbrev(proto_id);
-       } else {
-               return "*";
-       }
-}
-
-static void print_hfid_hash(gpointer k, gpointer v, gpointer p _U_) {
-       g_string_sprintfa((GString*)p," %s=%s;",(guint8*)v,my_protoname(*(int*)k));
-}
-
-
-static void print_transforms(gpointer k, gpointer v, gpointer p _U_) {
-       AVPL_Transf* t = NULL;
-       guint8* match;
-       guint8* mode;
-       guint8* match_s;
-       guint8* replace_s;
-
-       for (t = v; t; t = t->next) {
-               match_s =  avpl_to_str(t->match);
-               replace_s = avpl_to_dotstr(t->replace);
-
-               switch (t->match_mode) {
-                       case AVPL_STRICT:
-                               match = "Strict";
-                               break;
-                       case AVPL_LOOSE:
-                               match = "Loose";
-                               break;
-                       case AVPL_EVERY:
-                               match = "Every";
-                               break;
-                       default:
-                               match = "None";
-                               break;
-               }
-
-               switch (t->replace_mode) {
-                       case AVPL_INSERT:
-                               mode = "Insert";
-                               break;
-                       case AVPL_REPLACE:
-                               mode = "Replace";
-                               break;
-                       default:
-                               mode = "None";
-                               break;
-               }
-
-               dbg_print (dbg,0,dbg_facility,"\tAction=Transform; Name=%s; Match=%s; Mode=%s; %s %s",(guint8*) k,match,mode,match_s,replace_s);
-
-               g_free(match_s);
-               g_free(replace_s);
-       }
-}
-
-static void print_pdu_config(mate_cfg_pdu* cfg) {
-       guint i;
-       int hfid;
-       guint8* discard;
-       guint8* stop;
-       guint8* criterium_match = NULL;
-       guint8* criterium;
-       GString* s = g_string_new("Action=PduDef; ");
-
-       discard = cfg->discard_pdu_attributes ? "TRUE": "FALSE";
-       stop = cfg->last_to_be_created ? "TRUE" : "FALSE";
-
-       g_string_sprintfa(s, "Name=%s; Proto=%s; DiscartAttribs=%s; Stop=%s;  Transport=",
-                                         cfg->name,my_protoname(cfg->hfid_proto),discard,stop);
-
-       for (i = 0; i < cfg->transport_ranges->len; i++) {
-               hfid = *((int*) g_ptr_array_index(cfg->transport_ranges,i));
-               g_string_sprintfa(s,"%s/",my_protoname(hfid));
-       }
-
-       *(s->str + s->len - 1) = ';';
-
-       if (cfg->payload_ranges) {
-               g_string_sprintfa(s, " Payload=");
-               
-               for (i = 0; i < cfg->payload_ranges->len; i++) {
-                       hfid = *((int*) g_ptr_array_index(cfg->payload_ranges,i));
-                       g_string_sprintfa(s,"%s/",my_protoname(hfid));
-               }
-               
-               *(s->str + s->len - 1) = ';';
-
-       }
-       
-       g_hash_table_foreach(cfg->hfids_attr,print_hfid_hash,s);
-
-       dbg_print(dbg_cfg,0,dbg_facility,"%s",s->str);
-
-       if (cfg->criterium) {
-               switch(cfg->criterium_match_mode) {
-                       case AVPL_NO_MATCH:
-                               criterium_match = "None";
-                               break;
-                       case AVPL_STRICT:
-                               criterium_match = "Strict";
-                               break;
-                       case AVPL_LOOSE:
-                               criterium_match = "Loose";
-                               break;
-                       case AVPL_EVERY:
-                               criterium_match = "Every";
-                               break;
-               }
-
-               criterium = avpl_to_str(cfg->criterium);
-
-               dbg_print(dbg_cfg,0,dbg_facility,
-                                 "Action=PduCriteria; For=%s; Match=%s; Mode=%s;  %s",
-                                 cfg->name,criterium_match,cfg->criterium->name,criterium);
-
-               g_free(criterium);
-       }
-
-       print_xxx_transforms(cfg);
-
-       g_string_free(s,TRUE);
-}
-
-
 
 static void print_gogs_by_gopname(gpointer k, gpointer v, gpointer p _U_) {
        void* cookie = NULL;
@@ -1227,9 +343,9 @@ static void print_config(void) {
                g_hash_table_foreach(matecfg->gogs_by_gopname,print_gogs_by_gopname,NULL);
        }
 }
+#endif
 
-
-static void new_attr_hfri(mate_cfg_item* cfg, guint8* name) {
+static void new_attr_hfri(gchar* item_name, GHashTable* hfids, gchar* name) {
        int* p_id = g_malloc(sizeof(int));
 
        hf_register_info hfri;
@@ -1237,35 +353,46 @@ static void new_attr_hfri(mate_cfg_item* cfg, guint8* name) {
        memset(&hfri, 0, sizeof hfri);
        hfri.p_id = p_id;
        hfri.hfinfo.name = g_strdup_printf("%s",name);
-       hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.%s",cfg->name,name);
+       hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.%s",item_name,name);
        hfri.hfinfo.type = FT_STRING;
        hfri.hfinfo.display = BASE_NONE;
        hfri.hfinfo.strings = NULL;
        hfri.hfinfo.bitmask = 0;
-       hfri.hfinfo.blurb = g_strdup_printf("%s attribute of %s",name,cfg->name);
+       hfri.hfinfo.blurb = g_strdup_printf("%s attribute of %s",name,item_name);
 
        *p_id = -1;
-       g_hash_table_insert(cfg->my_hfids,name,p_id);
+       g_hash_table_insert(hfids,name,p_id);
        g_array_append_val(matecfg->hfrs,hfri);
 
 }
 
-static void analyze_pdu_hfids(gpointer k _U_, gpointer v, gpointer p) {
-       new_attr_hfri((mate_cfg_pdu*) p,(guint8*) v);
+static gchar* my_protoname(int proto_id) {
+       if (proto_id) {
+               return proto_registrar_get_abbrev(proto_id);
+       } else {
+               return "*";
+       }
+}
+
+static void analyze_pdu_hfids(gpointer k, gpointer v, gpointer p) {
+       mate_cfg_pdu* cfg = p;
+       new_attr_hfri(cfg->name,cfg->my_hfids,(gchar*) v);
+
+       g_string_sprintfa(matecfg->fields_filter,"||%s",my_protoname(*(int*)k));
 }
 
-static void analyze_transform_hfrs(mate_cfg_item* cfg) {
+static void analyze_transform_hfrs(gchar* name, GPtrArray* transforms, GHashTable* hfids) {
        guint i;
        void* cookie = NULL;
        AVPL_Transf* t;
        AVP* avp;
 
-       for (i=0; i < cfg->transforms->len;i++) {
-               for (t = g_ptr_array_index(cfg->transforms,i); t; t=t->next ) {
+       for (i=0; i < transforms->len;i++) {
+               for (t = g_ptr_array_index(transforms,i); t; t=t->next ) {
                        cookie = NULL;
                        while(( avp = get_next_avp(t->replace,&cookie) )) {
-                               if (! g_hash_table_lookup(cfg->my_hfids,avp->n))  {
-                                       new_attr_hfri(cfg,avp->n);
+                               if (! g_hash_table_lookup(hfids,avp->n))  {
+                                       new_attr_hfri(name,hfids,avp->n);
                                }
                        }
                }
@@ -1311,7 +438,7 @@ static void analyze_pdu_config(mate_cfg_pdu* cfg) {
        ett = &cfg->ett_attr;
        g_array_append_val(matecfg->ett,ett);
 
-       analyze_transform_hfrs(cfg);
+       analyze_transform_hfrs(cfg->name,cfg->transforms,cfg->my_hfids);
 }
 
 static void analyze_gop_config(gpointer k _U_, gpointer v, gpointer p _U_) {
@@ -1366,19 +493,19 @@ static void analyze_gop_config(gpointer k _U_, gpointer v, gpointer p _U_) {
        hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.Pdu",cfg->name);
        hfri.hfinfo.blurb = g_strdup_printf("A PDU assigned to this %s",cfg->name);
 
-       if (cfg->show_pdu_tree == matecfg->frame_tree) {
+       if (cfg->pdu_tree_mode == GOP_FRAME_TREE) {
                hfri.hfinfo.type = FT_FRAMENUM;
                g_array_append_val(matecfg->hfrs,hfri);
-       } else  if (cfg->show_pdu_tree == matecfg->pdu_tree) {
+       } else  if (cfg->pdu_tree_mode == GOP_PDU_TREE) {
                hfri.hfinfo.type = FT_UINT32;
                g_array_append_val(matecfg->hfrs,hfri);
        } else {
-               cfg->show_pdu_tree = matecfg->no_tree;
+               cfg->pdu_tree_mode = GOP_NO_TREE;
        }
 
        while(( avp = get_next_avp(cfg->key,&cookie) )) {
                if (! g_hash_table_lookup(cfg->my_hfids,avp->n))  {
-                       new_attr_hfri(cfg,avp->n);
+                       new_attr_hfri(cfg->name,cfg->my_hfids,avp->n);
                }
        }
 
@@ -1386,7 +513,7 @@ static void analyze_gop_config(gpointer k _U_, gpointer v, gpointer p _U_) {
                cookie = NULL;
                while(( avp = get_next_avp(cfg->start,&cookie) )) {
                        if (! g_hash_table_lookup(cfg->my_hfids,avp->n))  {
-                               new_attr_hfri(cfg,avp->n);
+                               new_attr_hfri(cfg->name,cfg->my_hfids,avp->n);
                        }
                }
        }
@@ -1395,7 +522,7 @@ static void analyze_gop_config(gpointer k _U_, gpointer v, gpointer p _U_) {
                cookie = NULL;
                while(( avp = get_next_avp(cfg->stop,&cookie) )) {
                        if (! g_hash_table_lookup(cfg->my_hfids,avp->n))  {
-                               new_attr_hfri(cfg,avp->n);
+                               new_attr_hfri(cfg->name,cfg->my_hfids,avp->n);
                        }
                }
        }
@@ -1403,11 +530,11 @@ static void analyze_gop_config(gpointer k _U_, gpointer v, gpointer p _U_) {
        cookie = NULL;
        while(( avp = get_next_avp(cfg->extra,&cookie) )) {
                if (! g_hash_table_lookup(cfg->my_hfids,avp->n))  {
-                       new_attr_hfri(cfg,avp->n);
+                       new_attr_hfri(cfg->name,cfg->my_hfids,avp->n);
                }
        }
 
-       analyze_transform_hfrs(cfg);
+       analyze_transform_hfrs(cfg->name,cfg->transforms,cfg->my_hfids);
 
        ett = &cfg->ett;
        g_array_append_val(matecfg->ett,ett);
@@ -1425,7 +552,7 @@ static void analyze_gop_config(gpointer k _U_, gpointer v, gpointer p _U_) {
 
 
 static void analyze_gog_config(gpointer k _U_, gpointer v, gpointer p _U_) {
-       mate_cfg_gop* cfg = v;
+       mate_cfg_gog* cfg = v;
        void* avp_cookie;
        void* avpl_cookie;
        AVP* avp;
@@ -1502,7 +629,7 @@ static void analyze_gog_config(gpointer k _U_, gpointer v, gpointer p _U_) {
                avp_cookie = NULL;
                while (( avp = get_next_avp(avpl,&avp_cookie) )) {
                        if (! g_hash_table_lookup(cfg->my_hfids,avp->n))  {
-                               new_attr_hfri(cfg,avp->n);
+                               new_attr_hfri(cfg->name,cfg->my_hfids,avp->n);
                                insert_avp(key_avps,avp);
                        }
                }
@@ -1511,13 +638,13 @@ static void analyze_gog_config(gpointer k _U_, gpointer v, gpointer p _U_) {
        avp_cookie = NULL;
        while (( avp = get_next_avp(cfg->extra,&avp_cookie) )) {
                if (! g_hash_table_lookup(cfg->my_hfids,avp->n))  {
-                       new_attr_hfri(cfg,avp->n);
+                       new_attr_hfri(cfg->name,cfg->my_hfids,avp->n);
                }
        }
        
        merge_avpl(cfg->extra,key_avps,TRUE);
        
-       analyze_transform_hfrs(cfg);
+       analyze_transform_hfrs(cfg->name,cfg->transforms,cfg->my_hfids);
 
        ett = &cfg->ett;
        g_array_append_val(matecfg->ett,ett);
@@ -1539,7 +666,7 @@ static void analyze_gog_config(gpointer k _U_, gpointer v, gpointer p _U_) {
 static void analyze_config(void) {
        guint i;
 
-       for (i=0; i<matecfg->pducfglist->len; i++) {
+       for (i=0; i < matecfg->pducfglist->len; i++) {
                analyze_pdu_config((mate_cfg_pdu*) g_ptr_array_index(matecfg->pducfglist,i));
        }
 
@@ -1548,204 +675,378 @@ static void analyze_config(void) {
 
 }
 
-static void new_action(guint8* name, config_action* action) {
-       g_hash_table_insert(actions,name,action);
-
+extern mate_config* mate_cfg() {
+       return matecfg;
 }
 
-static void init_actions(void) {
+static void append_avpl(GString* str, AVPL* avpl) {
+       void* cookie = NULL;
        AVP* avp;
+       gchar** vec;
+       guint i;
+       
+       g_string_sprintfa(str,"( ");
+       
+       while(( avp = get_next_avp(avpl,&cookie) )) {
+               switch (avp->o) {
+                       case '|' :
+                               g_string_sprintfa(str," %s {",avp->n);
+                               
+                               vec = g_strsplit(avp->v,"|",0);
+                               
+                               for (i = 0; vec[i]; i++) {
+                                       g_string_sprintfa(str," \"%s\" |",vec[i]);                                      
+                               }
+                                       
+                               g_strfreev(vec);
+                               
+                               g_string_erase(str,str->len-1,1);
+                               g_string_sprintfa(str,"}, ");
+                               break;
+                       case '?':
+                               g_string_sprintfa(str,"%s, ",avp->n);
+                               break;
+                       default:
+                               g_string_sprintfa(str,"%s %c \"%s\", ",avp->n,avp->o,avp->v);
+                               break;                          
+               }
+       }
+       
+       g_string_erase(str,str->len-2,1);
+       g_string_sprintfa(str,")");
+}
 
-       all_keywords = new_avpl("all_keywords");
-
-       insert_avp(all_keywords,new_avp(KEYWORD_ACTION,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_SETTINGS,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_INCLUDE,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_TRANSFORM,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_PDU,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_PDUCRITERIA,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_PDUEXTRA,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_PDUTRANSFORM,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOP,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOPSTART,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOPSTOP,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOPEXTRA,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOPTRANSFORM,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOGDEF,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOGKEY,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOGEXTRA,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOGTRANSFORM,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_NAME,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_ON,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_FOR,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_FROM,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_TO,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_MATCH,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_MODE,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_FILENAME,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_PROTO,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_METHOD,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_TRANSPORT,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_METHOD,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_STRICT,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_LOOSE,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_EVERY,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_REPLACE,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_INSERT,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_MAP,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_GOGEXPIRE,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DISCARDPDU,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_LIBPATH,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_SHOWPDUTREE,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_SHOWGOPTIMES,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_STOP,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DROPPDU,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DROPGOP,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_LIB,"",'='));
-
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_GENERAL,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_CFG,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_PDU,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_GOP,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_GOG,"",'='));
-
-#ifdef _AVP_DEBUGGING
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_AVPLIB,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_AVP,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_AVP_OP,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_AVPL,"",'='));
-       insert_avp(all_keywords,new_avp(KEYWORD_DBG_AVPL_OP,"",'='));
-#endif
+static void print_transforms(gpointer k, gpointer v, gpointer p) {
+       AVPL_Transf* t;
+       GString* str = p;
+       
+       g_string_sprintfa(str,"Transform %s {\n",(gchar*)k);
+       
+       for (t = v; t; t = t->next) {
+
+               if (t->match->len) {
+                       g_string_sprintfa(str,"\tMatch ");
+                       
+                       switch (t->match_mode) {
+                               case AVPL_STRICT:
+                                       g_string_sprintfa(str,"Strict ");
+                                       break;
+                               case AVPL_LOOSE:
+                                       g_string_sprintfa(str,"Loose ");
+                                       break;
+                               case AVPL_EVERY:
+                                       g_string_sprintfa(str,"Every ");
+                                       break;
+                               default:
+                                       g_string_sprintfa(str,"None ");
+                                       break;
+                       }
+                       
+                       append_avpl(str,t->match);
+               }
+               
+               if (t->replace->len) {
+                       switch (t->replace_mode) {
+                               case AVPL_INSERT:
+                                       g_string_sprintfa(str," Insert ");
+                                       break;
+                               case AVPL_REPLACE:
+                                       g_string_sprintfa(str," Replace ");
+                                       break;
+                               default:
+                                       g_string_sprintfa(str," None ");
+                                       break;
+                       }
+                       
+                       append_avpl(str,t->replace);
+               }
+               
+               g_string_sprintfa(str,";\n");
+       }
+
+       g_string_sprintfa(str,"};\n\n");
+}
+
+static void append_transforms(GString* s, GPtrArray* ts) {
+       guint i;
+       
+       if ( !ts || !ts->len ) return;
+       
+       g_string_sprintfa(s,"\tTransform ");
+
+       for (i=0; i < ts->len; i++) {
+               g_string_sprintfa(s,"%s, ",((AVPL_Transf*) g_ptr_array_index(ts,i))->name);
+       }
+
+       if (i>0) g_string_erase(s, s->len-2, 2);
+       g_string_sprintfa(s,";\n");
 
-       avp = new_avp(KEYWORD_ACCEPT,"",'=');
-       matecfg->accept = avp->n;
-       insert_avp(all_keywords,avp);
+}
 
-       avp = new_avp(KEYWORD_REJECT,"",'=');
-       matecfg->reject = avp->n;
-       insert_avp(all_keywords,avp);
+static void print_hfid_hash(gpointer k, gpointer v, gpointer p _U_) {
+       g_string_sprintfa((GString*)p,"\tExtract %s From %s;\n",(guint8*)v,my_protoname(*(int*)k));
+}
 
-       avp = new_avp(KEYWORD_NOTREE,"",'=');
-       matecfg->no_tree = avp->n;
-       insert_avp(all_keywords,avp);
+static void print_pdu_config(mate_cfg_pdu* cfg, GString* s) {
+       guint i;
+       int hfid;
+       gchar* discard;
+       gchar* stop;
+       
+       discard = cfg->discard ? "TRUE": "FALSE";
+       stop = cfg->last_extracted ? "TRUE" : "FALSE";
+       
+       g_string_sprintfa(s, "Pdu %s Proto %s Transport ",
+                                         cfg->name,my_protoname(cfg->hfid_proto));
+       
+       for (i = 0; i < cfg->transport_ranges->len; i++) {
+               hfid = *((int*) g_ptr_array_index(cfg->transport_ranges,i));
+               g_string_sprintfa(s,"%s/",my_protoname(hfid));
+       }
+       
+       g_string_erase(s, s->len-1, 1);
+       g_string_sprintfa(s," {\n");
+       
+       if (cfg->payload_ranges) {
+               g_string_sprintfa(s, "\tPayload ");
+               
+               for (i = 0; i < cfg->payload_ranges->len; i++) {
+                       hfid = *((int*) g_ptr_array_index(cfg->payload_ranges,i));
+                       g_string_sprintfa(s,"%s/",my_protoname(hfid));
+               }
+               
+               if (i > 0) g_string_erase(s, s->len-1, 1);
+               
+               g_string_sprintfa(s,";\n");
+               
+       }
+       
+       g_hash_table_foreach(cfg->hfids_attr,print_hfid_hash,s);
+               
+       if (cfg->criterium) {
 
-       avp = new_avp(KEYWORD_FRAMETREE,"",'=');
-       matecfg->frame_tree = avp->n;
-       insert_avp(all_keywords,avp);
+               g_string_sprintfa(s,"Criteria ");
 
-       avp = new_avp(KEYWORD_PDUTREE,"",'=');
-       matecfg->pdu_tree = avp->n;
-       insert_avp(all_keywords,avp);
+               switch (cfg->criterium_accept_mode) {
+                       case ACCEPT_MODE:
+                               g_string_sprintfa(s,"Accept ");
+                               break;
+                       case REJECT_MODE:
+                               g_string_sprintfa(s,"Reject ");
+                               break;
+               }
+               
+               switch(cfg->criterium_match_mode) {
+                       case AVPL_NO_MATCH:
+                               g_string_sprintfa(s,"None ");
+                               break;
+                       case AVPL_STRICT:
+                               g_string_sprintfa(s,"Strict ");
+                               break;
+                       case AVPL_LOOSE:
+                               g_string_sprintfa(s,"Loose ");
+                               break;
+                       case AVPL_EVERY:
+                               g_string_sprintfa(s,"Every ");
+                               break;
+               }
+               
+               append_avpl(s, cfg->criterium);
+       }
        
-       avp = new_avp(KEYWORD_BASICTREE,"",'=');
-       matecfg->basic_tree = avp->n;
-       insert_avp(all_keywords,avp);
+       append_transforms(s,cfg->transforms);
+       
+       g_string_sprintfa(s,"};\n\n");
+}
 
-       avp = new_avp(KEYWORD_FULLTREE,"",'=');
-       matecfg->full_tree = avp->n;
-       insert_avp(all_keywords,avp);
+static void print_gop_config(gchar* name _U_,mate_cfg_gop* cfg, GString* s) {
+
+       g_string_sprintfa(s, "Gop %s On %s Match ",
+                                         cfg->name,cfg->on_pdu);
+       
+       append_avpl(s, cfg->key);
        
-       if (actions) {
-               g_hash_table_destroy(actions);
+       g_string_sprintfa(s," {\n");
+
+       if (cfg->start) {
+               g_string_sprintfa(s,"\tStart ");
+               append_avpl(s, cfg->start);             
+               g_string_sprintfa(s,";\n");
+       }
+               
+       if (cfg->stop) {
+               g_string_sprintfa(s,"\tStop ");
+               append_avpl(s, cfg->stop);              
+               g_string_sprintfa(s,";\n");
+       }
+
+       if (cfg->extra) {
+               g_string_sprintfa(s,"\tExtra ");
+               append_avpl(s, cfg->extra);             
+               g_string_sprintfa(s,";\n");
        }
 
-       actions = g_hash_table_new(g_str_hash,g_str_equal);
-
-       new_action(KEYWORD_SETTINGS,config_settings);
-       new_action(KEYWORD_PDU,config_pdu);
-       new_action(KEYWORD_PDUEXTRA,config_pduextra);
-       new_action(KEYWORD_PDUCRITERIA,config_pducriteria);
-       new_action(KEYWORD_GOP,config_gop);
-       new_action(KEYWORD_GOGDEF,config_gog);
-       new_action(KEYWORD_GOGKEY,config_gogkey);
-       new_action(KEYWORD_GOPSTART,config_start);
-       new_action(KEYWORD_GOPSTOP,config_stop);
-       new_action(KEYWORD_GOPEXTRA,config_gopextra);
-       new_action(KEYWORD_GOGEXTRA,config_gogextra);
-       new_action(KEYWORD_INCLUDE,config_include);
-       new_action(KEYWORD_TRANSFORM,config_transform);
-       new_action(KEYWORD_PDUTRANSFORM,config_pdu_transform);
-       new_action(KEYWORD_GOPTRANSFORM,config_gop_transform);
-       new_action(KEYWORD_GOGTRANSFORM,config_gog_transform);
+       g_string_sprintfa(s,"\tDropUnassigned %s;\n",cfg->drop_unassigned ? "TRUE" : "FALSE");
+       g_string_sprintfa(s,"\tShowTimes %s;\n",cfg->show_times ? "TRUE" : "FALSE");
+       
+       switch (cfg->pdu_tree_mode) {
+               case GOP_NO_TREE:
+                       g_string_sprintfa(s,"\tShowTree NoTree;\n");
+                       break;
+               case GOP_PDU_TREE:
+                       g_string_sprintfa(s,"\tShowTree PduTree;\n");
+                       break;
+               case GOP_FRAME_TREE:
+                       g_string_sprintfa(s,"\tShowTree FrameTree;\n");
+                       break;
+               case GOP_BASIC_PDU_TREE:
+                       break;
+       }
+       
+       if (cfg->lifetime > 0) g_string_sprintfa(s,"\tLifetime %f;\n",cfg->lifetime);
+       if (cfg->idle_timeout > 0) g_string_sprintfa(s,"\tIdleTimeout %f;\n",cfg->idle_timeout);
+       if (cfg->expiration > 0) g_string_sprintfa(s,"\tExpiration %f;\n",cfg->expiration);
+       
+       append_transforms(s,cfg->transforms);
 
+       g_string_sprintfa(s,"};\n\n");
 }
 
-extern mate_config* mate_cfg() {
-       return matecfg;
+static void print_gog_config(gchar* name _U_,mate_cfg_gog* cfg, GString* s) {
+       void* cookie = NULL;
+       AVPL* avpl;
+       
+       g_string_sprintfa(s, "Gog %s  {\n",cfg->name);
+       
+       if (cfg->extra) {
+               g_string_sprintfa(s,"\tExtra ");
+               append_avpl(s, cfg->extra);             
+               g_string_sprintfa(s,";\n");
+       }
+       
+       g_string_sprintfa(s,"\tShowTimes %s;\n",cfg->show_times ? "TRUE" : "FALSE");
+       
+       while (( avpl = get_next_avpl(cfg->keys,&cookie) )) {
+               g_string_sprintfa(s,"\tMember %s ",avpl->name);
+               append_avpl(s, avpl);           
+               g_string_sprintfa(s,";\n");
+       }
+       
+       switch (cfg->gop_tree_mode) {
+               case GOP_NULL_TREE:
+                       g_string_sprintfa(s,"\tGopTree NullTree;\n");
+                       break;
+               case GOP_BASIC_TREE:
+                       break;
+               case GOP_FULL_TREE:
+                       g_string_sprintfa(s,"\tGopTree FullTree;\n");
+                       break;
+       }
+       
+       if (cfg->expiration > 0) g_string_sprintfa(s,"\tExpiration %f;\n",cfg->expiration);
+       
+       append_transforms(s,cfg->transforms);
+       
+       g_string_sprintfa(s,"};\n\n");
 }
 
-extern mate_config* mate_make_config(guint8* filename, int mate_hfid) {
+extern mate_config* mate_make_config(gchar* filename, int mate_hfid) {
        gint* ett;
-
+       GString* config_text;
        avp_init();
 
        matecfg = g_malloc(sizeof(mate_config));
 
-       matecfg->gog_expiration = DEFAULT_GOG_EXPIRATION;
-       matecfg->discard_pdu_attributes = FALSE;
-       matecfg->drop_pdu = FALSE;
-       matecfg->drop_gop = FALSE;
-       matecfg->show_times = TRUE;
-       matecfg->last_to_be_created = FALSE;
-       matecfg->match_mode = AVPL_STRICT;
-       matecfg->replace_mode = AVPL_INSERT;
-       matecfg->mate_lib_path = g_strdup_printf("%s%c%s%c",get_datafile_dir(),DIR_SEP,DEFAULT_MATE_LIB_PATH,DIR_SEP);
-       matecfg->mate_config_file = g_strdup(filename);
-       matecfg->mate_attrs_filter = g_string_new("");
-       matecfg->mate_protos_filter = g_string_new("");
+       matecfg->hfid_mate = mate_hfid;
+       
+       matecfg->fields_filter = g_string_new("");
+       matecfg->protos_filter = g_string_new(""); 
+       
        matecfg->dbg_facility = NULL;
-       matecfg->dbg_lvl = 0;
-       matecfg->dbg_cfg_lvl = 0;
-       matecfg->dbg_pdu_lvl = 0;
-       matecfg->dbg_gop_lvl = 0;
-       matecfg->dbg_gog_lvl = 0;
-       matecfg->pducfglist = g_ptr_array_new();
+       
+       matecfg->mate_lib_path = g_strdup_printf("%s%c%s%c",get_datafile_dir(),DIR_SEP,DEFAULT_MATE_LIB_PATH,DIR_SEP);;
+       
        matecfg->pducfgs = g_hash_table_new(g_str_hash,g_str_equal);
        matecfg->gopcfgs = g_hash_table_new(g_str_hash,g_str_equal);
        matecfg->gogcfgs = g_hash_table_new(g_str_hash,g_str_equal);
        matecfg->transfs = g_hash_table_new(g_str_hash,g_str_equal);
+       
+       matecfg->pducfglist = g_ptr_array_new();
        matecfg->gops_by_pduname = g_hash_table_new(g_str_hash,g_str_equal);
        matecfg->gogs_by_gopname = g_hash_table_new(g_str_hash,g_str_equal);
-
-       matecfg->hfrs = g_array_new(FALSE,TRUE,sizeof(hf_register_info));
-       matecfg->ett = g_array_new(FALSE,TRUE,sizeof(gint*));
-       matecfg->ett_root = -1;
-       matecfg->hfid_mate = mate_hfid;
        
-       ett = &matecfg->ett_root;
-       g_array_append_val(matecfg->ett,ett);
-
-       dbg = &matecfg->dbg_lvl;
+       matecfg->ett_root = -1;
 
-       init_actions();
+       matecfg->hfrs = g_array_new(FALSE,FALSE,sizeof(hf_register_info));
+       matecfg->ett  = g_array_new(FALSE,FALSE,sizeof(gint*));
+       
+       matecfg->defaults.pdu.drop_unassigned = FALSE;
+       matecfg->defaults.pdu.discard = FALSE;
+       matecfg->defaults.pdu.last_extracted = FALSE;
+       matecfg->defaults.pdu.match_mode = AVPL_STRICT;
+       matecfg->defaults.pdu.replace_mode = AVPL_INSERT;
+       
+       matecfg->defaults.gop.expiration = -1.0;
+       matecfg->defaults.gop.idle_timeout = -1.0;
+       matecfg->defaults.gop.lifetime = -1.0;
+       matecfg->defaults.gop.pdu_tree_mode = GOP_FRAME_TREE;
+       matecfg->defaults.gop.show_times = TRUE;
+       matecfg->defaults.gop.drop_unassigned = FALSE;
+       
+               /* gop prefs */
+       matecfg->defaults.gog.expiration = 5.0;
+       matecfg->defaults.gog.gop_tree_mode = GOP_BASIC_TREE;
 
-       matecfg->show_pdu_tree = matecfg->frame_tree;
-       matecfg->gop_as_subtree = matecfg->basic_tree;
+       /* what to dbgprint */
+       matecfg->dbg_lvl = 0;   
+       matecfg->dbg_pdu_lvl = 0;
+       matecfg->dbg_gop_lvl = 0;
+       matecfg->dbg_gog_lvl = 0;
        
-       config_error = g_string_new("");
+       matecfg->config_error = g_string_new("");
+       
+       ett = &matecfg->ett_root;
+       g_array_append_val(matecfg->ett,ett);
        
-       if ( mate_load_config(filename) ) {
+       if ( mate_load_config(filename,matecfg) ) {
+               guint i;
+
+               /* if (dbg_cfg_lvl > 0) { */
+                       config_text = g_string_new("\n");
+                       g_hash_table_foreach(matecfg->transfs,print_transforms,config_text);
+                       
+                       for (i=0; i < matecfg->pducfglist->len; i++) {
+                               print_pdu_config((mate_cfg_pdu*) g_ptr_array_index(matecfg->pducfglist,i),config_text);
+                       }
+                       
+                       g_hash_table_foreach(matecfg->gopcfgs,(GHFunc)print_gop_config,config_text);
+                       g_hash_table_foreach(matecfg->gogcfgs,(GHFunc)print_gog_config,config_text);
+                       
+                       g_message("Current configuration\n%s\nDone;\n",config_text->str);
+               /* } */
+               
                analyze_config();
-               dbg_print (dbg_cfg,3,dbg_facility,"mate_make_config: OK");
-               if (dbg_cfg_lvl > 0) print_config();
+               /* dbg_print (dbg_cfg,3,dbg_facility,"mate_make_config: OK"); */
        } else {
-               report_failure("%s",config_error->str);
-               g_string_free(config_error,TRUE);
-               if (matecfg) destroy_mate_config(matecfg,FALSE);
+               report_failure("MATE failed to configue!\n"
+                                          "it is recomended that you fix your config and restart ethereal.\n"
+                                          "The reported error is:\n%s\n",matecfg->config_error->str);
+               
+               /* if (matecfg) destroy_mate_config(matecfg,FALSE); */
                matecfg = NULL;
                return NULL;
        }
 
-       if (matecfg->mate_attrs_filter->len > 1) {
-               g_string_erase(matecfg->mate_attrs_filter,0,2);
-               g_string_erase(matecfg->mate_protos_filter,0,2);
+       if (matecfg->fields_filter->len > 1) {
+               g_string_erase(matecfg->fields_filter,0,2);
+               g_string_erase(matecfg->protos_filter,0,2);
        } else {
-               destroy_mate_config(matecfg,FALSE);
+               /*destroy_mate_config(matecfg,FALSE);*/
                matecfg = NULL;
                return NULL;
        }
 
-       matecfg->tap_filter = g_strdup_printf("(%s) && (%s)",matecfg->mate_protos_filter->str,matecfg->mate_attrs_filter->str);
+       matecfg->tap_filter = g_strdup_printf("(%s) && (%s)",matecfg->protos_filter->str,matecfg->fields_filter->str);
 
        return matecfg;
 }
index 6001732535a4946b1920c8eaeb934b0ab4256b5d..9de22c8ca789e033d50fc87faad5059adb3f9c36 100644 (file)
@@ -40,8 +40,8 @@
  * fmt, ...: what to print
  */
 
-void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... ) {
-       static guint8 debug_buffer[DEBUG_BUFFER_SIZE];
+void dbg_print(const gint* which, gint how, FILE* where, gchar* fmt, ... ) {
+       static gchar debug_buffer[DEBUG_BUFFER_SIZE];
        va_list list;
 
        if ( ! which || *which < how ) return;
@@ -130,8 +130,8 @@ extern SCS_collection* scs_init(void) {
  *
  * Return value: a pointer to the subscribed string.
  **/
-guint8* scs_subscribe(SCS_collection* c, guint8* s) {
-       guint8* orig = NULL;
+gchar* scs_subscribe(SCS_collection* c, gchar* s) {
+       gchar* orig = NULL;
        guint* ip = NULL;
        size_t len = 0;
        GMemChunk* chunk = NULL;
@@ -181,8 +181,8 @@ guint8* scs_subscribe(SCS_collection* c, guint8* s) {
  * decreases the count of subscribers, if zero frees the internal copy of
  * the string.
  **/
-void scs_unsubscribe(SCS_collection* c, guint8* s) {
-       guint8* orig = NULL;
+void scs_unsubscribe(SCS_collection* c, gchar* s) {
+       gchar* orig = NULL;
        guint* ip = NULL;
        size_t len = 0xffff;
        GMemChunk* chunk = NULL;
@@ -225,9 +225,9 @@ void scs_unsubscribe(SCS_collection* c, guint8* s) {
  * Return value: the stored copy of the formated string.
  *
  **/
-extern guint8* scs_subscribe_printf(SCS_collection* c, guint8* fmt, ...) {
+extern gchar* scs_subscribe_printf(SCS_collection* c, gchar* fmt, ...) {
        va_list list;
-       static guint8 buf[SCS_HUGE_SIZE];
+       static gchar buf[SCS_HUGE_SIZE];
        
        va_start( list, fmt );
        g_vsnprintf(buf, SCS_HUGE_SIZE-1 ,fmt, list);
@@ -236,16 +236,16 @@ extern guint8* scs_subscribe_printf(SCS_collection* c, guint8* fmt, ...) {
        return scs_subscribe(c,buf);
 }
 
-extern guint8* scs_subscribe_int(SCS_collection* c, int i) {
-       static guint8 buf[SCS_SMALL_SIZE];
+extern gchar* scs_subscribe_int(SCS_collection* c, int i) {
+       static gchar buf[SCS_SMALL_SIZE];
        
        g_snprintf(buf, SCS_SMALL_SIZE-1 ,"%i", i);
        
        return scs_subscribe(c,buf);
 }
 
-extern guint8* scs_subscribe_float(SCS_collection* c, float f) {
-       static guint8 buf[SCS_SMALL_SIZE];
+extern gchar* scs_subscribe_float(SCS_collection* c, float f) {
+       static gchar buf[SCS_SMALL_SIZE];
        
        g_snprintf(buf, SCS_SMALL_SIZE-1 ,"%f", f);
        
@@ -346,9 +346,9 @@ extern void avp_init(void) {
  * Return value: a pointer to the newly created avp.
  *
  **/
-extern AVP* new_avp_from_finfo(guint8* name, field_info* finfo) {
+extern AVP* new_avp_from_finfo(gchar* name, field_info* finfo) {
        AVP* new = g_mem_chunk_alloc(avp_chunk);
-       guint8* value;
+       gchar* value;
        
        new->n = scs_subscribe(avp_strings, name);
 
@@ -397,7 +397,7 @@ extern AVP* new_avp_from_finfo(guint8* name, field_info* finfo) {
  * Return value: a pointer to the newly created avp.
  *
  **/
-extern AVP* new_avp(guint8* name, guint8* value, guint8 o) {
+extern AVP* new_avp(gchar* name, gchar* value, gchar o) {
        AVP* new = g_mem_chunk_alloc(avp_chunk);
 
        new->n = scs_subscribe(avp_strings, name);
@@ -453,8 +453,8 @@ extern AVP* avp_copy(AVP* from) {
 }
 
 
-extern void rename_avp(AVP* avp, guint8* name) {
-       guint8* s = avp->n;
+extern void rename_avp(AVP* avp, gchar* name) {
+       gchar* s = avp->n;
        avp->n = scs_subscribe(avp_strings,name);
        scs_unsubscribe(avp_strings,s);
 }
@@ -468,14 +468,14 @@ extern void rename_avp(AVP* avp, guint8* name) {
  * Return value: a pointer to the newly created avpl.
  *
  **/
-extern AVPL* new_avpl(guint8* name) {
+extern AVPL* new_avpl(gchar* name) {
        AVPL* new_avpl = g_mem_chunk_alloc(avp_chunk);
 
 #ifdef _AVP_DEBUGGING
        dbg_print(dbg_avpl_op,7,dbg_fp,"new_avpl: %X name=%s",new_avpl,name);
 #endif
 
-       new_avpl->name = scs_subscribe(avp_strings, name);
+       new_avpl->name = name ? scs_subscribe(avp_strings, name) : scs_subscribe(avp_strings, "");
        new_avpl->len = 0;
        new_avpl->null.avp = NULL;
        new_avpl->null.next = &new_avpl->null;
@@ -485,7 +485,7 @@ extern AVPL* new_avpl(guint8* name) {
        return new_avpl;
 }
 
-extern void rename_avpl(AVPL* avpl, guint8* name) {
+extern void rename_avpl(AVPL* avpl, gchar* name) {
        scs_unsubscribe(avp_strings,avpl->name);
        avpl->name = scs_subscribe(avp_strings,name);
 }
@@ -568,7 +568,7 @@ extern gboolean insert_avp(AVPL* avpl, AVP* avp) {
  * Return value: a pointer to the next matching avp if there's one, else NULL.
  *
  **/
-extern AVP* get_avp_by_name(AVPL* avpl, guint8* name, void** cookie) {
+extern AVP* get_avp_by_name(AVPL* avpl, gchar* name, void** cookie) {
        AVPN* curr;
        AVPN* start = (AVPN*) *cookie;
 
@@ -607,7 +607,7 @@ extern AVP* get_avp_by_name(AVPL* avpl, guint8* name, void** cookie) {
  * Return value: a pointer to extracted avp if there's one, else NULL.
  *
  **/
-extern AVP* extract_avp_by_name(AVPL* avpl, guint8* name) {
+extern AVP* extract_avp_by_name(AVPL* avpl, gchar* name) {
        AVPN* curr;
        AVP* avp = NULL;
 
@@ -794,11 +794,11 @@ extern AVP* get_next_avp(AVPL* avpl, void** cookie) {
  * Return value: a pointer to the newly allocated string.
  *
  **/
-guint8* avpl_to_str(AVPL* avpl) {
+gchar* avpl_to_str(AVPL* avpl) {
        AVPN* c;
        GString* s = g_string_new("");
-       guint8* avp_s;
-       guint8* r;
+       gchar* avp_s;
+       gchar* r;
 
        for(c=avpl->null.next; c->avp; c = c->next) {
                avp_s = avp_to_str(c->avp);
@@ -813,11 +813,11 @@ guint8* avpl_to_str(AVPL* avpl) {
        return r;
 }
 
-extern guint8* avpl_to_dotstr(AVPL* avpl) {
+extern gchar* avpl_to_dotstr(AVPL* avpl) {
        AVPN* c;
        GString* s = g_string_new("");
-       guint8* avp_s;
-       guint8* r;
+       gchar* avp_s;
+       gchar* r;
 
        for(c=avpl->null.next; c->avp; c = c->next) {
                avp_s = avp_to_str(c->avp);
@@ -913,7 +913,7 @@ extern void merge_avpl(AVPL* dst, AVPL* src, gboolean copy_avps) {
  * Return value: a pointer to the newly allocated string.
  *
  **/
-extern AVPL* new_avpl_from_avpl(guint8* name, AVPL* avpl, gboolean copy_avps) {
+extern AVPL* new_avpl_from_avpl(gchar* name, AVPL* avpl, gboolean copy_avps) {
        AVPL* newavpl = new_avpl(name);
        void* cookie = NULL;
        AVP* avp;
@@ -1043,7 +1043,7 @@ extern AVP* match_avp(AVP* src, AVP* op) {
  * Return value: a pointer to the newly created avpl containing the
  *                              matching avps.
  **/
-extern AVPL* new_avpl_loose_match(guint8* name,
+extern AVPL* new_avpl_loose_match(gchar* name,
                                                                  AVPL* src,
                                                                  AVPL* op,
                                                                  gboolean copy_avps) {
@@ -1121,19 +1121,26 @@ extern AVPL* new_avpl_loose_match(guint8* name,
  * Return value: a pointer to the newly created avpl containing the
  *                              matching avps.
  **/
-extern AVPL* new_avpl_every_match(guint8* name, AVPL* src, AVPL* op, gboolean copy_avps) {
-       AVPL* newavpl = new_avpl(scs_subscribe(avp_strings, name));
+extern AVPL* new_avpl_every_match(gchar* name, AVPL* src, AVPL* op, gboolean copy_avps) {
+       AVPL* newavpl;
        AVPN* co = NULL;
        AVPN* cs = NULL;
        gint c;
        AVP* m;
        AVP* copy;
-
+       gboolean matches;
+       
 #ifdef _AVP_DEBUGGING
        dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_every_match: %X src=%X op=%X name='%s'",newavpl,src,op,name);
 #endif
-
-       gboolean matches = TRUE;
+       if (src->len == 0) return NULL;
+       
+       newavpl = new_avpl(scs_subscribe(avp_strings, name));
+       
+       if (op->len == 0)
+               return newavpl;
+       
+       matches = TRUE;
 
        cs = src->null.next;
        co = op->null.next;
@@ -1205,7 +1212,7 @@ extern AVPL* new_avpl_every_match(guint8* name, AVPL* src, AVPL* op, gboolean co
  * Return value: a pointer to the newly created avpl containing the
  *                              matching avps.
  **/
-extern AVPL* new_avpl_exact_match(guint8* name,AVPL* src, AVPL* op, gboolean copy_avps) {
+extern AVPL* new_avpl_exact_match(gchar* name,AVPL* src, AVPL* op, gboolean copy_avps) {
        AVPL* newavpl = new_avpl(name);
        AVPN* co = NULL;
        AVPN* cs = NULL;
@@ -1219,7 +1226,12 @@ extern AVPL* new_avpl_exact_match(guint8* name,AVPL* src, AVPL* op, gboolean cop
 
        if (op->len == 0)
                return newavpl;
-               
+       
+       if (src->len == 0) {
+               delete_avpl(newavpl,FALSE);
+               return NULL;
+       }
+
        cs = src->null.next;
        co = op->null.next;
        while(1) {
@@ -1271,7 +1283,7 @@ extern AVPL* new_avpl_exact_match(guint8* name,AVPL* src, AVPL* op, gboolean cop
        return NULL;
 }
 
-extern AVPL* new_avpl_from_match(avpl_match_mode mode, guint8* name,AVPL* src, AVPL* op, gboolean copy_avps) {
+extern AVPL* new_avpl_from_match(avpl_match_mode mode, gchar* name,AVPL* src, AVPL* op, gboolean copy_avps) {
        AVPL* avpl = NULL;
        
        switch (mode) {
@@ -1300,7 +1312,7 @@ extern AVPL* new_avpl_from_match(avpl_match_mode mode, guint8* name,AVPL* src, A
  *
  * Return value: a pointer to the newly created avpl transformation
  **/
-extern AVPL_Transf* new_avpl_transform(guint8* name, AVPL* mixed, avpl_match_mode match_mode, avpl_replace_mode replace_mode) {
+extern AVPL_Transf* new_avpl_transform(gchar* name, AVPL* mixed, avpl_match_mode match_mode, avpl_replace_mode replace_mode) {
        AVPL_Transf* t = g_malloc(sizeof(AVPL_Transf));
        AVP* avp;
 
@@ -1423,7 +1435,7 @@ extern void avpl_transform(AVPL* src, AVPL_Transf* op) {
  *
  * Return value: a pointer to the newly created loal.
  **/
-extern LoAL* new_loal(guint8* name) {
+extern LoAL* new_loal(gchar* name) {
        LoAL* new_loal = g_mem_chunk_alloc(avp_chunk);
 
        if (! name) {
@@ -1602,11 +1614,11 @@ extern void delete_loal(LoAL* loal, gboolean avpls_too, gboolean avps_too) {
  * load_loal_error:
  * Used by loal_from_file to handle errors while loading.
  **/
-LoAL* load_loal_error(FILE* fp, LoAL* loal, AVPL* curr, int linenum, guint8* fmt, ...) {
+LoAL* load_loal_error(FILE* fp, LoAL* loal, AVPL* curr, int linenum, gchar* fmt, ...) {
        va_list list;
-       guint8* desc;
+       gchar* desc;
        LoAL* ret = NULL;
-       guint8* err;
+       gchar* err;
        
        va_start( list, fmt );
        desc = g_strdup_vprintf(fmt, list);
@@ -1652,15 +1664,15 @@ case '7': case '8': case '9': case '.'
  * Return value: if successful a pointer to the new populated loal, else NULL.
  *
  **/
-extern LoAL* loal_from_file(guint8* filename) {
+extern LoAL* loal_from_file(gchar* filename) {
        FILE *fp = NULL;
-       guint8 c;
+       gchar c;
        int i = 0;
        guint32 linenum = 1;
-       guint8 linenum_buf[MAX_ITEM_LEN];
-       guint8 name[MAX_ITEM_LEN];
-       guint8 value[MAX_ITEM_LEN];
-       guint8 op = '?';
+       gchar linenum_buf[MAX_ITEM_LEN];
+       gchar name[MAX_ITEM_LEN];
+       gchar value[MAX_ITEM_LEN];
+       gchar op = '?';
        LoAL *loal = new_loal(filename);
        AVPL* curr = NULL;
        AVP* avp;
@@ -1682,7 +1694,7 @@ extern LoAL* loal_from_file(guint8* filename) {
        state = START;
 
        if (( fp = fopen(filename,"r") )) {
-               while(( c = (guint8) fgetc(fp) )){
+               while(( c = (gchar) fgetc(fp) )){
 
                        if ( feof(fp) ) {
                                if ( ferror(fp) ) {
index 2b586064a565b9b2e446de3d7c188b670901de44..a8963e22eb0cf6565e2fae0186b42e501a869045 100644 (file)
@@ -38,7 +38,7 @@
 
 /******* dbg_print *********/
 #define DEBUG_BUFFER_SIZE 4096
-extern void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... );
+extern void dbg_print(const gint* which, gint how, FILE* where, gchar* fmt, ... );
 
 
 /******* single copy strings *********/
@@ -56,9 +56,9 @@ typedef struct _scs_collection SCS_collection;
 
 extern void destroy_scs_collection(SCS_collection* c);
 extern SCS_collection* scs_init(void);
-extern guint8* scs_subscribe(SCS_collection* collection, guint8* s);
-extern void scs_unsubscribe(SCS_collection* collection, guint8* s);
-extern guint8* scs_subscribe_printf(SCS_collection* collection, guint8* fmt, ...);
+extern gchar* scs_subscribe(SCS_collection* collection, gchar* s);
+extern void scs_unsubscribe(SCS_collection* collection, gchar* s);
+extern gchar* scs_subscribe_printf(SCS_collection* collection, gchar* fmt, ...);
 
 /******* AVPs & Co. *********/
 #define AVP_CHUNK_SIZE 4096
@@ -78,9 +78,9 @@ extern guint8* scs_subscribe_printf(SCS_collection* collection, guint8* fmt, ...
 
 /* an avp is an object made of a name a value and an operator */
 typedef struct _avp {
-       guint8* n;
-       guint8* v;
-       guint8 o;
+       gchar* n;
+       gchar* v;
+       gchar o;
 } AVP;
 
 /* avp nodes are used in avp lists */
@@ -92,7 +92,7 @@ typedef struct _avp_node {
 
 /* an avp list is a sorted set of avps */
 typedef struct _avp_list {
-       guint8* name;
+       gchar* name;
        guint32 len;
        AVPN null;
 } AVPL;
@@ -116,7 +116,7 @@ typedef enum _avpl_replace_mode {
 typedef struct _avpl_transf AVPL_Transf;
 
 struct _avpl_transf {
-       guint8* name;
+       gchar* name;
 
        AVPL* match;
        AVPL* replace;
@@ -138,7 +138,7 @@ typedef struct _loal_node {
 
 /* a loal is a list of avp lists */
 typedef struct _loal {
-       guint8* name;
+       gchar* name;
        guint len;
        LoALnode null;
 } LoAL;
@@ -157,13 +157,13 @@ extern void setup_avp_debug(FILE* fp, int* general, int* avp, int* avp_op, int*
  */
 
 /* creates a new avp */
-extern AVP* new_avp(guint8* name, guint8* value, guint8 op);
+extern AVP* new_avp(gchar* name, gchar* value, gchar op);
 
 /* creates a copy od an avp */
 extern AVP* avp_copy(AVP* from);
 
 /* creates an avp from a field_info record */
-extern AVP* new_avp_from_finfo(guint8* name, field_info* finfo);
+extern AVP* new_avp_from_finfo(gchar* name, field_info* finfo);
 
 /*
  * avp destructor
@@ -185,26 +185,26 @@ extern AVP* match_avp(AVP* src, AVP* op);
  */
 
 /* creates an empty avp list */
-extern AVPL* new_avpl(guint8* name);
+extern AVPL* new_avpl(gchar* name);
 
 
 /* creates a copy of an avp list */
-extern AVPL* new_avpl_from_avpl(guint8* name, AVPL* avpl, gboolean copy_avps);
+extern AVPL* new_avpl_from_avpl(gchar* name, AVPL* avpl, gboolean copy_avps);
 
 /* creates an avp list containing any avps in src matching any avps in op
    it will eventually create an empty list in none match */
-extern AVPL* new_avpl_loose_match(guint8* name,AVPL* src, AVPL* op, gboolean copy_avps);
+extern AVPL* new_avpl_loose_match(gchar* name,AVPL* src, AVPL* op, gboolean copy_avps);
 
 /* creates an avp list containing any avps in src matching every avp in op
   it will not create a list if there is not a match for every attribute in op */
-extern AVPL* new_avpl_every_match(guint8* name,AVPL* src, AVPL* op, gboolean copy_avps);
+extern AVPL* new_avpl_every_match(gchar* name,AVPL* src, AVPL* op, gboolean copy_avps);
 
 /* creates an avp list containing every avp in src matching every avp in op
    it will not create a list unless every avp in op is matched only once to avery avp in op */
-extern AVPL* new_avpl_exact_match(guint8* name,AVPL* src, AVPL* op, gboolean copy_avps);
+extern AVPL* new_avpl_exact_match(gchar* name,AVPL* src, AVPL* op, gboolean copy_avps);
 
 /* uses mode to call one of the former matches. NO_MATCH = merge(merge(copy(src),op)) */
-extern AVPL* new_avpl_from_match(avpl_match_mode mode, guint8* name,AVPL* src, AVPL* op, gboolean copy_avps);
+extern AVPL* new_avpl_from_match(avpl_match_mode mode, gchar* name,AVPL* src, AVPL* op, gboolean copy_avps);
 
 
 
@@ -221,14 +221,14 @@ extern void delete_avpl(AVPL* avpl, gboolean avps_too);
 extern gboolean insert_avp(AVPL* avpl, AVP* avp);
 
 /* renames an avpl */
-extern void rename_avpl(AVPL* avpl, guint8* name);
+extern void rename_avpl(AVPL* avpl, gchar* name);
 
 /* it will add all the avps in src which don't match(*) any attribute in dest */
 extern void merge_avpl(AVPL* dest, AVPL* src, gboolean copy);
 
 /* it will return the first avp in an avpl whose name matches the given name.
   will return NULL if there is not anyone matching */
-extern AVP* get_avp_by_name(AVPL* avpl, guint8* name, void** cookie);
+extern AVP* get_avp_by_name(AVPL* avpl, gchar* name, void** cookie);
 
 /* it will get the next avp from an avpl, using cookie to keep state */
 extern AVP* get_next_avp(AVPL* avpl, void** cookie);
@@ -241,11 +241,11 @@ extern AVP* extract_last_avp(AVPL* avpl);
 
 /* it will extract the first avp in an avpl whose name matches the given name.
    it will not extract any and  return NULL if there is not anyone matching */
-extern AVP* extract_avp_by_name(AVPL* avpl, guint8* name);
+extern AVP* extract_avp_by_name(AVPL* avpl, gchar* name);
 
 /* returns a newly allocated string containing a representation of the avp list */
-extern guint8* avpl_to_str(AVPL* avpl);
-extern guint8* avpl_to_dotstr(AVPL*);
+extern gchar* avpl_to_str(AVPL* avpl);
+extern gchar* avpl_to_dotstr(AVPL*);
 
 /* deletes an avp list  and eventually it's contents */
 extern void delete_avpl(AVPL* avpl, gboolean avps_too);
@@ -253,7 +253,6 @@ extern void delete_avpl(AVPL* avpl, gboolean avps_too);
 /*
  *  AVPL transformations
  */
-extern AVPL_Transf* new_avpl_transform(guint8* name, AVPL* mixed, avpl_match_mode match_mode, avpl_replace_mode replace_mode);
 extern void delete_avpl_transform(AVPL_Transf* it);
 extern void avpl_transform(AVPL* src, AVPL_Transf* op);
 
@@ -263,11 +262,11 @@ extern void avpl_transform(AVPL* src, AVPL_Transf* op);
  */
 
 /* creates an empty list of avp lists */
-extern LoAL* new_loal(guint8* name);
+extern LoAL* new_loal(gchar* name);
 
 /* given a file loads all the avpls contained in it
    every line is formatted as it is the output of avplist_to_string */
-extern LoAL* loal_from_file(guint8* filename);
+extern LoAL* loal_from_file(gchar* filename);
 
 /* inserts an avplist into a LoAL */
 extern void loal_append(LoAL* loal, AVPL* avpl);
index d0f33f0e41270516c69d0769b76fc96f79df817f..4be748ef793b4807cac2503ced4323d52c341749 100644 (file)
@@ -12,5 +12,5 @@
 #endif
 
 /* Version number of package */
-#define VERSION "0.0.4"
+#define VERSION "1.0.0a"
 
index d13524b1170828617e9181053fba35cbf2c4e7ed..879bafd3508577184dea8cf608268bbd4647321e 100644 (file)
@@ -37,27 +37,69 @@ static mate_config* mc = NULL;
 
 static int proto_mate = -1;
 
-static char* pref_mate_config_filename = "";
-static char* current_mate_config_filename = NULL;
+static gchar* pref_mate_config_filename = "";
+static gchar* current_mate_config_filename = NULL;
 
 static proto_item *mate_i = NULL;
 
-void attrs_tree(proto_tree* tree, tvbuff_t *tvb, mate_item* item) {
+void pdu_attrs_tree(proto_tree* tree, tvbuff_t *tvb, mate_pdu* pdu) {
        AVPN* c;
        proto_item *avpl_i;
        proto_tree *avpl_t;
        int* hfi_p;
        
-       avpl_i = proto_tree_add_text(tree,tvb,0,0,"%s Attributes",item->cfg->name);
-       avpl_t = proto_item_add_subtree(avpl_i, item->cfg->ett_attr);
+       avpl_i = proto_tree_add_text(tree,tvb,0,0,"%s Attributes",pdu->cfg->name);
+       avpl_t = proto_item_add_subtree(avpl_i, pdu->cfg->ett_attr);
+       
+       for ( c = pdu->avpl->null.next; c->avp; c = c->next) {
+               hfi_p = g_hash_table_lookup(pdu->cfg->my_hfids,(char*)c->avp->n);
+               
+               if (hfi_p) {
+                       proto_tree_add_string(avpl_t,*hfi_p,tvb,0,0,c->avp->v);
+               } else {
+                       g_warning("MATE: error: undefined attribute: mate.%s.%s",pdu->cfg->name,c->avp->n);
+                       proto_tree_add_text(avpl_t,tvb,0,0,"Undefined attribute: %s=%s",c->avp->n, c->avp->v);
+               }
+       }
+}
 
-       for ( c = item->avpl->null.next; c->avp; c = c->next) {
-               hfi_p = g_hash_table_lookup(item->cfg->my_hfids,(char*)c->avp->n);
+void gop_attrs_tree(proto_tree* tree, tvbuff_t *tvb, mate_gop* gop) {
+       AVPN* c;
+       proto_item *avpl_i;
+       proto_tree *avpl_t;
+       int* hfi_p;
+       
+       avpl_i = proto_tree_add_text(tree,tvb,0,0,"%s Attributes",gop->cfg->name);
+       avpl_t = proto_item_add_subtree(avpl_i, gop->cfg->ett_attr);
+       
+       for ( c = gop->avpl->null.next; c->avp; c = c->next) {
+               hfi_p = g_hash_table_lookup(gop->cfg->my_hfids,(char*)c->avp->n);
+               
+               if (hfi_p) {
+                       proto_tree_add_string(avpl_t,*hfi_p,tvb,0,0,c->avp->v);
+               } else {
+                       g_warning("MATE: error: undefined attribute: mate.%s.%s",gop->cfg->name,c->avp->n);
+                       proto_tree_add_text(avpl_t,tvb,0,0,"Undefined attribute: %s=%s",c->avp->n, c->avp->v);
+               }
+       }
+}
 
+void gog_attrs_tree(proto_tree* tree, tvbuff_t *tvb, mate_gog* gog) {
+       AVPN* c;
+       proto_item *avpl_i;
+       proto_tree *avpl_t;
+       int* hfi_p;
+       
+       avpl_i = proto_tree_add_text(tree,tvb,0,0,"%s Attributes",gog->cfg->name);
+       avpl_t = proto_item_add_subtree(avpl_i, gog->cfg->ett_attr);
+       
+       for ( c = gog->avpl->null.next; c->avp; c = c->next) {
+               hfi_p = g_hash_table_lookup(gog->cfg->my_hfids,(char*)c->avp->n);
+               
                if (hfi_p) {
                        proto_tree_add_string(avpl_t,*hfi_p,tvb,0,0,c->avp->v);
                } else {
-                       g_warning("MATE: error: undefined attribute: mate.%s.%s",item->cfg->name,c->avp->n);
+                       g_warning("MATE: error: undefined attribute: mate.%s.%s",gog->cfg->name,c->avp->n);
                        proto_tree_add_text(avpl_t,tvb,0,0,"Undefined attribute: %s=%s",c->avp->n, c->avp->v);
                }
        }
@@ -86,7 +128,7 @@ void mate_gog_tree(proto_tree* tree, tvbuff_t *tvb, mate_gog* gog, mate_gop* gop
        gog_item = proto_tree_add_uint(tree,gog->cfg->hfid,tvb,0,0,gog->id);
        gog_tree = proto_item_add_subtree(gog_item,gog->cfg->ett);
                        
-       attrs_tree(gog_tree,tvb,gog);
+       gog_attrs_tree(gog_tree,tvb,gog);
        
        if (gog->cfg->show_times) {
                gog_time_item = proto_tree_add_text(gog_tree,tvb,0,0,"%s Times",gog->cfg->name);
@@ -104,12 +146,12 @@ void mate_gog_tree(proto_tree* tree, tvbuff_t *tvb, mate_gog* gog, mate_gop* gop
        for (gog_gops = gog->gops; gog_gops; gog_gops = gog_gops->next) {
                
                if (gop != gog_gops) {
-                       if (gog->cfg->gop_as_subtree == mc->full_tree) {
+                       if (gog->cfg->gop_tree_mode == GOP_FULL_TREE) {
                                mate_gop_tree(gog_gops_tree, tvb, gog_gops);
                        } else {
                                gog_gop_item = proto_tree_add_uint(gog_gops_tree,gog_gops->cfg->hfid,tvb,0,0,gog_gops->id);
                                
-                               if (gog->cfg->gop_as_subtree == mc->basic_tree) {
+                               if (gog->cfg->gop_tree_mode == GOP_BASIC_TREE) {
                                        gog_gop_tree = proto_item_add_subtree(gog_gop_item, gog->cfg->ett_gog_gop);
                                        
                                        proto_tree_add_text(gog_gop_tree, tvb,0,0, "Started at: %f", gog_gops->start_time);
@@ -124,7 +166,7 @@ void mate_gog_tree(proto_tree* tree, tvbuff_t *tvb, mate_gog* gog, mate_gop* gop
                                        
                                        proto_tree_add_text(gog_gop_tree, tvb,0,0, "Number of Pdus: %u",gog_gops->num_of_pdus);
                                        
-                                       if (gop->pdus && gop->cfg->show_pdu_tree == mc->frame_tree) {
+                                       if (gop->pdus && gop->cfg->pdu_tree_mode != GOP_NO_TREE) {
                                                proto_tree_add_uint(gog_gop_tree,gog->cfg->hfid_gog_gopstart,tvb,0,0,gog_gops->pdus->frame);
                                                
                                                for (pdu = gog_gops->pdus->next ; pdu; pdu = pdu->next) {
@@ -163,7 +205,7 @@ void mate_gop_tree(proto_tree* tree, tvbuff_t *tvb, mate_gop* gop) {
        
        if (gop->gop_key) proto_tree_add_text(gop_tree,tvb,0,0,"GOP Key: %s",gop->gop_key);
        
-       attrs_tree(gop_tree,tvb,gop);
+       gop_attrs_tree(gop_tree,tvb,gop);
        
        if (gop->cfg->show_times) {
                gop_time_item = proto_tree_add_text(gop_tree,tvb,0,0,"%s Times",gop->cfg->name);
@@ -181,17 +223,17 @@ void mate_gop_tree(proto_tree* tree, tvbuff_t *tvb, mate_gop* gop) {
        
        gop_pdu_item = proto_tree_add_uint(gop_tree, gop->cfg->hfid_gop_num_pdus, tvb, 0, 0,gop->num_of_pdus);
 
-       if (gop->cfg->show_pdu_tree != mc->no_tree) {
+       if (gop->cfg->pdu_tree_mode != GOP_NO_TREE) {
                
                gop_pdu_tree = proto_item_add_subtree(gop_pdu_item, gop->cfg->ett_children);
 
                rel_time = gop_time = gop->start_time;
 
-               type_str = (gop->cfg->show_pdu_tree == mc->frame_tree ) ? "in frame:" : "id:";
+               type_str = (gop->cfg->pdu_tree_mode == GOP_FRAME_TREE ) ? "in frame:" : "id:";
                
                for (gop_pdus = gop->pdus; gop_pdus; gop_pdus = gop_pdus->next) {
 
-                       pdu_item = (gop->cfg->show_pdu_tree == mc->frame_tree ) ? gop_pdus->frame : gop_pdus->id;
+                       pdu_item = (gop->cfg->pdu_tree_mode == GOP_FRAME_TREE ) ? gop_pdus->frame : gop_pdus->id;
 
                        if (gop_pdus->is_start) {
                                pdu_str = "Start ";
@@ -249,7 +291,7 @@ void mate_pdu_tree(mate_pdu *pdu, tvbuff_t *tvb, proto_tree* tree) {
        }
        
        if (pdu->avpl) {
-               attrs_tree(pdu_tree,tvb,pdu);
+               pdu_attrs_tree(pdu_tree,tvb,pdu);
        }
 }
 
@@ -275,52 +317,47 @@ static int mate_packet(void *prs _U_,  packet_info* tree _U_, epan_dissect_t *ed
        return 0;
 }
 
-static void init_mate(void) {
-       GString* tap_error = NULL;
-
-       if ( ! mate_tap_data ) {
-               tap_error = register_tap_listener("frame", &mate_tap_data,
-                                                                                 (char*) mc->tap_filter,
-                                                                                 (tap_reset_cb) NULL,
-                                                                                 mate_packet,
-                                                                                 (tap_draw_cb) NULL);
-       }
-       
-       if ( tap_error ) {
-               g_warning("mate: couldn't (re)register tap: %s",tap_error->str);
-               g_string_free(tap_error, TRUE);
-               mate_tap_data = 0;
-               return;
-       } else {
-               mate_tap_data = 1;
-       }
-       
-       initialize_mate_runtime();
-}
-
 extern
 void
 proto_reg_handoff_mate(void)
 {
+       GString* tap_error = NULL;
+       
        if ( *pref_mate_config_filename != '\0' ) {
                
                if (current_mate_config_filename) {
                        report_failure("Mate cannot reconfigure itself.\n"
-                                                  "for changes to be applied you have to save the preferences and restart ethereal\n");
+                                                  "for changes to be applied you have to restart ethereal\n");
                        return;
                } 
                
                if (!mc) { 
-                       mc = mate_make_config((char*)pref_mate_config_filename,proto_mate);
+                       mc = mate_make_config(pref_mate_config_filename,proto_mate);
                        
                        if (mc) {
                                /* XXX: alignment warnings, what do they mean? */
                                proto_register_field_array(proto_mate, (hf_register_info*) mc->hfrs->data, mc->hfrs->len );
                                proto_register_subtree_array((gint**) mc->ett->data, mc->ett->len);
-                               register_init_routine(init_mate);
-                               if (current_mate_config_filename == NULL) initialize_mate_runtime();
+                               register_init_routine(initialize_mate_runtime);
+                               
+                               g_warning("filter: %s",mc->tap_filter);
+                               
+                               tap_error = register_tap_listener("frame", &mate_tap_data,
+                                                                                                 (char*) mc->tap_filter,
+                                                                                                 (tap_reset_cb) NULL,
+                                                                                                 mate_packet,
+                                                                                                 (tap_draw_cb) NULL);
+                               
+                               if ( tap_error ) {
+                                       g_warning("mate: couldn't (re)register tap: %s",tap_error->str);
+                                       g_string_free(tap_error, TRUE);
+                                       mate_tap_data = 0;
+                                       return;
+                               }                                       
+                               
+                               initialize_mate_runtime();
                        }
-                       
+
                        current_mate_config_filename = pref_mate_config_filename;
 
                }