From af8041a316caa43265926cf92ba2c550b93d8d1e Mon Sep 17 00:00:00 2001 From: Lars Roland Date: Thu, 16 Dec 2004 19:36:23 +0000 Subject: [PATCH] Patch for Mate Plugin. From Luis Ontanon: - moves mate configuration from proto_register to proto_register_handoff - add the config file protocol preference - every item (gop,gog,pdu) has it's own ett - the tap doesn't do nothing, it just primes the tree - analyze_frame() what once was the tap now is called by the dissector - should work with tethereal now (to be tested) svn path=/trunk/; revision=12763 --- plugins/mate/Makefile.am | 8 +-- plugins/mate/Makefile.nmake | 6 +- plugins/mate/mate.h | 11 +++- plugins/mate/mate_runtime.c | 84 ++++++++++++------------- plugins/mate/mate_setup.c | 43 +++++++++++++ plugins/mate/matelib/isup.mate | 22 ++++++- plugins/mate/packet-mate.c | 108 ++++++++++----------------------- 7 files changed, 151 insertions(+), 131 deletions(-) diff --git a/plugins/mate/Makefile.am b/plugins/mate/Makefile.am index 70b028b308..2b6fd02673 100644 --- a/plugins/mate/Makefile.am +++ b/plugins/mate/Makefile.am @@ -26,10 +26,10 @@ INCLUDES = -I$(top_srcdir) plugindir = @plugindir@ -plugin_LTLIBRARIES = zzmate.la -zzmate_la_SOURCES = moduleinfo.h mate.h mate_util.h packet-mate.c mate_runtime.c mate_setup.c mate_util.c mate_plugin.c -zzmate_la_LDFLAGS = -module -avoid-version -zzmate_la_LIBADD = @PLUGIN_LIBS@ +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_LDFLAGS = -module -avoid-version +mate_la_LIBADD = @PLUGIN_LIBS@ # Libs must be cleared, or else libtool won't create a shared module. # If your module needs to be linked against any particular libraries, diff --git a/plugins/mate/Makefile.nmake b/plugins/mate/Makefile.nmake index df83e85079..e627b24a5b 100644 --- a/plugins/mate/Makefile.nmake +++ b/plugins/mate/Makefile.nmake @@ -20,11 +20,11 @@ LINK_PLUGIN_WITH=..\plugin_api.obj OBJECTS=packet-mate.obj mate_setup.obj mate_runtime.obj mate_util.obj mate_plugin.obj -zzmate.dll zzmate.exp zzmate.lib : $(OBJECTS) $(LINK_PLUGIN_WITH) - link -dll /out:zzmate.dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \ +mate.dll mate.exp mate.lib : $(OBJECTS) $(LINK_PLUGIN_WITH) + link -dll /out:mate.dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \ $(GLIB_LIBS) clean: - rm -f $(OBJECTS) zzmate.dll zzmate.exp zzmate.lib *.pdb + rm -f $(OBJECTS) mate.dll mate.exp mate.lib *.pdb distclean: clean diff --git a/plugins/mate/mate.h b/plugins/mate/mate.h index f8d09968a8..a6a2d9d3d7 100644 --- a/plugins/mate/mate.h +++ b/plugins/mate/mate.h @@ -153,6 +153,10 @@ typedef struct _mate_cfg_item { int hfid; 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; @@ -224,6 +228,8 @@ typedef struct _mate_config { GHashTable* gogs_by_gopname; /* k=gopname v=loal where avpl->name == matchedgop->name */ GArray* hfrs; + gint ett_root; + GArray* ett; } mate_config; typedef struct _mate_runtime_data { @@ -291,9 +297,10 @@ struct _mate_item { }; /* from mate_runtime.c */ -extern void init_mate_runtime_data(void); +extern void initialize_mate_runtime(void); extern mate_pdu* mate_get_pdus(guint32 framenum); -extern int mate_packet(void *prs _U_, packet_info *pinfo, epan_dissect_t *edt, void *dummy _U_); +extern void analyze_frame(packet_info *pinfo, proto_tree* tree); +extern int mate_packet(void* _U_, proto_tree* _U_, epan_dissect_t* _U_, void* _U_); /* from mate_setup.c */ extern mate_config* mate_make_config(guint8* filename); diff --git a/plugins/mate/mate_runtime.c b/plugins/mate/mate_runtime.c index cb4bb28935..cbe70c1c2d 100644 --- a/plugins/mate/mate_runtime.c +++ b/plugins/mate/mate_runtime.c @@ -91,22 +91,36 @@ static void delete_mate_runtime_data(mate_runtime_data* rdat) { } -extern void init_mate_runtime_data(void) { +extern void initialize_mate_runtime(void) { - if (rd) { - delete_mate_runtime_data(rd); + if (( mc = mate_cfg() )) { + if (rd) { + delete_mate_runtime_data(rd); + } + + rd = g_malloc(sizeof(mate_runtime_data)); + + mc = mate_cfg(); + + rd->current_items = 0; + rd->now = -1.0; + rd->frames = g_hash_table_new(g_direct_hash,g_direct_equal); + rd->gops = g_hash_table_new(g_str_hash,g_str_equal); + rd->gogs = g_hash_table_new(g_str_hash,g_str_equal); + rd->mate_items = g_mem_chunk_new("mate_items",sizeof(mate_item),1024,G_ALLOC_AND_FREE); + rd->highest_analyzed_frame = 0; + + /* this will be called when the mate's dissector is initialized */ + dbg_print (dbg,5,dbg_facility,"initialize_mate: entering"); + + + dbg_pdu = &(mc->dbg_pdu_lvl); + dbg_gop = &(mc->dbg_gop_lvl); + dbg_gog = &(mc->dbg_gog_lvl); + + } else { + rd = NULL; } - - rd = g_malloc(sizeof(mate_runtime_data)); - - mc = mate_cfg(); - - rd->current_items = 0; - rd->now = -1.0; - rd->frames = g_hash_table_new(g_direct_hash,g_direct_equal); - rd->gops = g_hash_table_new(g_str_hash,g_str_equal); - rd->gogs = g_hash_table_new(g_str_hash,g_str_equal); - rd->mate_items = g_mem_chunk_new("mate_items",sizeof(mate_item),1024,G_ALLOC_AND_FREE); } static mate_item* new_mate_item(mate_cfg_item* cfg) { @@ -651,21 +665,24 @@ static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto, return pdu; } -extern int mate_packet(void *prs _U_, packet_info *pinfo, epan_dissect_t *edt, void *dummy _U_) { - mate_pdu* pdu = NULL; - mate_pdu* last = NULL; - proto_tree* tree = edt->tree; +extern int mate_packet(void *prs _U_, proto_tree* tree _U_, epan_dissect_t *edt _U_, void *dummy _U_) { + /* nothing to do yet */ +} + +extern void analyze_frame(packet_info *pinfo, proto_tree* tree) { mate_cfg_pdu* cfg; GPtrArray* protos; field_info* proto; guint i,j; AVPL* criterium_match; + mate_pdu* pdu = NULL; + mate_pdu* last = NULL; + rd->now = (((float)pinfo->fd->rel_secs) + (((float)pinfo->fd->rel_usecs) / 1000000) ); - dbg_print (dbg,3,dbg_facility,"mate_packet: got frame number: %i at %d\n",pinfo->fd->num,rd->now); - - if ( tree->tree_data && tree->tree_data->interesting_hfids ) { + if ( tree->tree_data && tree->tree_data->interesting_hfids + && rd->highest_analyzed_frame < pinfo->fd->num ) { for ( i = 0; i < mc->pducfglist->len; i++ ) { cfg = g_ptr_array_index(mc->pducfglist,i); @@ -725,15 +742,8 @@ extern int mate_packet(void *prs _U_, packet_info *pinfo, epan_dissect_t *edt, v } } - + rd->highest_analyzed_frame = pinfo->fd->num; } - - - rd->highest_analyzed_frame = pinfo->fd->num; - - dbg_print (dbg,6,dbg_facility,"do_mate: make_pdus done\n"); - - return 0; } extern mate_pdu* mate_get_pdus(guint32 framenum) { @@ -745,21 +755,5 @@ extern mate_pdu* mate_get_pdus(guint32 framenum) { } } -/* this will be called when the mate's dissector is initialized */ -extern void initialize_mate_runtime(void) { - dbg_print (dbg,5,dbg_facility,"initialize_mate: entering"); - - if (( mc = mate_cfg() )) { - - dbg_pdu = &(mc->dbg_pdu_lvl); - dbg_gop = &(mc->dbg_gop_lvl); - dbg_gog = &(mc->dbg_gog_lvl); - - } else { - return; - } - - return; -} diff --git a/plugins/mate/mate_setup.c b/plugins/mate/mate_setup.c index b81c9f033a..004dbecac6 100644 --- a/plugins/mate/mate_setup.c +++ b/plugins/mate/mate_setup.c @@ -138,6 +138,11 @@ static mate_cfg_item* new_mate_cfg_item(guint8* name) { new->hfid_gog_num_of_gops = -1; new->hfid_gog_gop = -1; + new->ett = -1; + new->ett_attr = -1; + new->ett_times = -1; + new->ett_children = -1; + return new; } @@ -1173,6 +1178,7 @@ static void analyze_transform_hfrs(mate_cfg_item* cfg) { static void analyze_pdu_config(mate_cfg_pdu* cfg) { hf_register_info hfri = { NULL, {NULL, NULL, FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL}}; + gint* ett; hfri.p_id = &(cfg->hfid); hfri.hfinfo.name = g_strdup_printf("%s",cfg->name); @@ -1194,6 +1200,12 @@ static void analyze_pdu_config(mate_cfg_pdu* cfg) { g_hash_table_foreach(cfg->hfids_attr,analyze_pdu_hfids,cfg); + ett = &cfg->ett; + g_array_append_val(matecfg->ett,ett); + + ett = &cfg->ett_attr; + g_array_append_val(matecfg->ett,ett); + analyze_transform_hfrs(cfg); } @@ -1201,6 +1213,7 @@ static void analyze_gop_config(gpointer k _U_, gpointer v, gpointer p _U_) { mate_cfg_gop* cfg = v; void* cookie = NULL; AVP* avp; + gint* ett; hf_register_info hfri = { NULL, {NULL, NULL, FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL}}; hfri.p_id = &(cfg->hfid); @@ -1279,6 +1292,19 @@ static void analyze_gop_config(gpointer k _U_, gpointer v, gpointer p _U_) { } analyze_transform_hfrs(cfg); + + ett = &cfg->ett; + g_array_append_val(matecfg->ett,ett); + + ett = &cfg->ett_attr; + g_array_append_val(matecfg->ett,ett); + + ett = &cfg->ett_times; + g_array_append_val(matecfg->ett,ett); + + ett = &cfg->ett_children; + g_array_append_val(matecfg->ett,ett); + } @@ -1289,6 +1315,7 @@ static void analyze_gog_config(gpointer k _U_, gpointer v, gpointer p _U_) { AVP* avp; AVPL* avpl; hf_register_info hfri = { NULL, {NULL, NULL, FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL}}; + gint* ett; hfri.p_id = &(cfg->hfid); hfri.hfinfo.name = g_strdup_printf("%s",cfg->name); @@ -1335,6 +1362,16 @@ static void analyze_gog_config(gpointer k _U_, gpointer v, gpointer p _U_) { } analyze_transform_hfrs(cfg); + + ett = &cfg->ett; + g_array_append_val(matecfg->ett,ett); + + ett = &cfg->ett_attr; + g_array_append_val(matecfg->ett,ett); + + ett = &cfg->ett_children; + g_array_append_val(matecfg->ett,ett); + } static size_t analyze_config() { @@ -1467,6 +1504,7 @@ extern mate_config* mate_cfg() { } extern mate_config* mate_make_config(guint8* filename) { + gint* ett; avp_init(); @@ -1500,6 +1538,11 @@ extern mate_config* mate_make_config(guint8* filename) { 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; + + ett = &matecfg->ett_root; + g_array_append_val(matecfg->ett,ett); dbg = &matecfg->dbg_lvl; diff --git a/plugins/mate/matelib/isup.mate b/plugins/mate/matelib/isup.mate index 698cc318a9..d7bafa497b 100644 --- a/plugins/mate/matelib/isup.mate +++ b/plugins/mate/matelib/isup.mate @@ -1,7 +1,25 @@ # isup.mate # $Id$ + +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=1; .isup_IAM=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=2; .isup_SAM=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=3; .isup_INR=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=4; .isup_INF=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=5; .isup_COT=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=6; .isup_ACM=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=7; .isup_CON=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=8; .isup_FOT=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=9; .isup_ANM=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=12; .isup_REL=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=13; .isup_SUS=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=14; .isup_RES=; +Action=Transform; Name=isup_msg_type; Mode=Insert; Match=Strict; isup_msg=16; .isup_RLC=; + Action=PduDef; Name=isup_pdu; Proto=isup; Transport=mtp3; mtp3pc=mtp3.dpc; mtp3pc=mtp3.opc; cic=isup.cic; isup_msg=isup.message_type; +Action=PduTransform; For=isup_pdu; Name=isup_msg_type; + Action=GopDef; Name=isup_leg; On=isup_pdu; ShowPduTree=TRUE; mtp3pc; mtp3pc; cic; -Action=GopStart; For=isup_leg; isup_msg=1; -Action=GopStop; For=isup_leg; isup_msg=16; +Action=GopStart; For=isup_leg; isup_IAM; +Action=GopStop; For=isup_leg; isup_RLC; + diff --git a/plugins/mate/packet-mate.c b/plugins/mate/packet-mate.c index 6247f0baf7..2d28f53888 100644 --- a/plugins/mate/packet-mate.c +++ b/plugins/mate/packet-mate.c @@ -37,20 +37,6 @@ static mate_config* mc = NULL; static int proto_mate = -1; -static gint ett_mate = -1; -static gint ett_mate_pdu = -1; -static gint ett_mate_pdu_attr = -1; - -static gint ett_mate_gop = -1; -static gint ett_mate_gop_attr = -1; -static gint ett_mate_gop_pdus = -1; -static gint ett_mate_gop_times = -1; - -static gint ett_mate_gog = -1; -static gint ett_mate_gog_attr = -1; -static gint ett_mate_gog_gops = -1; -static gint ett_mate_gop_in_gog = -1; - static char* pref_mate_config_filename = "config.mate"; static proto_item *mate_i = NULL; @@ -61,25 +47,8 @@ void attrs_tree(proto_tree* tree, tvbuff_t *tvb,mate_item* item) { proto_tree *avpl_t; int* hfi_p; - gint our_ett; - - switch (item->cfg->type) { - case MATE_PDU_TYPE: - our_ett = ett_mate_pdu_attr; - break; - case MATE_GOP_TYPE: - our_ett = ett_mate_pdu_attr; - break; - case MATE_GOG_TYPE: - our_ett = ett_mate_pdu_attr; - break; - default: - our_ett = ett_mate; - break; - } - avpl_i = proto_tree_add_text(tree,tvb,0,0,"%s Attributes",item->cfg->name); - avpl_t = proto_item_add_subtree(avpl_i, our_ett); + avpl_t = proto_item_add_subtree(avpl_i, item->cfg->ett_attr); for ( c = item->avpl->null.next; c->avp; c = c->next) { hfi_p = g_hash_table_lookup(item->cfg->my_hfids,c->avp->n); @@ -93,7 +62,7 @@ void attrs_tree(proto_tree* tree, tvbuff_t *tvb,mate_item* item) { } } -void mate_gop_tree(proto_tree* pdu_tree, tvbuff_t *tvb, mate_gop* gop, gint ett); +void mate_gop_tree(proto_tree* pdu_tree, tvbuff_t *tvb, mate_gop* gop); void mate_gog_tree(proto_tree* tree, tvbuff_t *tvb, mate_gog* gog, mate_gop* gop) { proto_item *gog_item; @@ -108,19 +77,19 @@ void mate_gog_tree(proto_tree* tree, tvbuff_t *tvb, mate_gog* gog, mate_gop* gop #endif gog_item = proto_tree_add_uint(tree,gog->cfg->hfid,tvb,0,0,gog->id); - gog_tree = proto_item_add_subtree(gog_item,ett_mate_gog); + gog_tree = proto_item_add_subtree(gog_item,gog->cfg->ett); attrs_tree(gog_tree,tvb,gog); gog_gop_item = proto_tree_add_uint(gog_tree, gog->cfg->hfid_gog_num_of_gops, tvb, 0, 0, gog->num_of_gops); - gog_gop_tree = proto_item_add_subtree(gog_gop_item, ett_mate_gog_gops); + gog_gop_tree = proto_item_add_subtree(gog_gop_item, gog->cfg->ett_children); for (gog_gops = gog->gops; gog_gops; gog_gops = gog_gops->next) { if (gop != gog_gops) { - mate_gop_tree(gog_gop_tree, tvb, gog_gops, ett_mate_gop_in_gog); + mate_gop_tree(gog_gop_tree, tvb, gog_gops); } else { proto_tree_add_uint_format(gog_gop_tree,gop->cfg->hfid,tvb,0,0,gop->id,"%s of current frame: %d",gop->cfg->name,gop->id); } @@ -128,7 +97,7 @@ void mate_gog_tree(proto_tree* tree, tvbuff_t *tvb, mate_gog* gog, mate_gop* gop } -void mate_gop_tree(proto_tree* tree, tvbuff_t *tvb, mate_gop* gop, gint gop_ett) { +void mate_gop_tree(proto_tree* tree, tvbuff_t *tvb, mate_gop* gop) { proto_item *gop_item; proto_tree *gop_time_tree; proto_item *gop_time_item; @@ -140,7 +109,7 @@ void mate_gop_tree(proto_tree* tree, tvbuff_t *tvb, mate_gop* gop, gint gop_ett) float gop_time; gop_item = proto_tree_add_uint(tree,gop->cfg->hfid,tvb,0,0,gop->id); - gop_tree = proto_item_add_subtree(gop_item, gop_ett); + gop_tree = proto_item_add_subtree(gop_item, gop->cfg->ett); if (gop->gop_key) proto_tree_add_text(gop_tree,tvb,0,0,"GOP Key: %s",gop->gop_key); @@ -148,7 +117,7 @@ void mate_gop_tree(proto_tree* tree, tvbuff_t *tvb, mate_gop* gop, gint gop_ett) if (gop->cfg->show_gop_times) { gop_time_item = proto_tree_add_text(gop_tree,tvb,0,0,"%s Times",gop->cfg->name); - gop_time_tree = proto_item_add_subtree(gop_time_item, ett_mate_gop_times); + gop_time_tree = proto_item_add_subtree(gop_time_item, gop->cfg->ett_times); proto_tree_add_float(gop_time_tree, gop->cfg->hfid_gop_start_time, tvb, 0, 0, gop->start_time); @@ -165,7 +134,7 @@ void mate_gop_tree(proto_tree* tree, tvbuff_t *tvb, mate_gop* gop, gint gop_ett) rel_time = gop_time = gop->start_time; gop_pdu_item = proto_tree_add_uint(gop_tree, gop->cfg->hfid_gop_num_pdus, tvb, 0, 0,gop->num_of_pdus); - gop_pdu_tree = proto_item_add_subtree(gop_pdu_item, ett_mate_gop_pdus); + gop_pdu_tree = proto_item_add_subtree(gop_pdu_item, gop->cfg->ett_children); if (gop->cfg->show_pdu_tree) { for (gop_pdus = gop->pdus; gop_pdus; gop_pdus = gop_pdus->next) { @@ -227,11 +196,11 @@ void mate_pdu_tree(mate_pdu *pdu, tvbuff_t *tvb, proto_tree* tree) { len = pdu->end - pdu->start; pdu_item = proto_tree_add_uint(tree,pdu->cfg->hfid,tvb,pdu->start,len,pdu->id); - pdu_tree = proto_item_add_subtree(pdu_item, ett_mate_pdu); + pdu_tree = proto_item_add_subtree(pdu_item, pdu->cfg->ett); proto_tree_add_float(pdu_tree,pdu->cfg->hfid_pdu_rel_time, tvb, 0, 0, pdu->rel_time); if (pdu->gop) { - mate_gop_tree(pdu_tree,tvb,pdu->gop,ett_mate_gop); + mate_gop_tree(pdu_tree,tvb,pdu->gop); if (pdu->gop->gog) mate_gog_tree(pdu_tree,tvb,pdu->gop->gog,pdu->gop); @@ -246,13 +215,15 @@ extern void mate_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { mate_pdu* pdus; proto_tree *mate_t; - if (! tree ) return; + if ( ! (tree && mc) ) return; + + analyze_frame(pinfo,tree); if (( pdus = mate_get_pdus(pinfo->fd->num) )) { mate_i = proto_tree_add_text(tree,tvb,0,0,"mate"); - mate_t = proto_item_add_subtree(mate_i, ett_mate); + mate_t = proto_item_add_subtree(mate_i, mc->ett_root); for ( ; pdus; pdus = pdus->next_in_frame) { mate_pdu_tree(pdus,tvb,mate_t); @@ -278,49 +249,36 @@ static void init_mate(void) { mate_tap_data = 1; } - init_mate_runtime_data(); + initialize_mate_runtime(); } extern void proto_reg_handoff_mate(void) { + mc = mate_make_config(pref_mate_config_filename); + + if (mc) { + 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); + } + } extern void proto_register_mate(void) -{ - static gint *ett[] = { - &ett_mate, - &ett_mate_pdu, - &ett_mate_pdu_attr, - &ett_mate_gop, - &ett_mate_gop_attr, - &ett_mate_gop_times, - &ett_mate_gop_pdus, - &ett_mate_gog, - &ett_mate_gog_gops, - &ett_mate_gog_attr, - &ett_mate_gop_in_gog - }; +{ + module_t *mate_module; - mc = mate_make_config(pref_mate_config_filename); - - if (mc) { - - proto_mate = proto_register_protocol("Meta Analysis Tracing Engine", "mate", "mate"); - - - proto_register_field_array(proto_mate, (hf_register_info*) mc->hfrs->data, mc->hfrs->len ); - - proto_register_subtree_array(ett, array_length(ett)); - - register_dissector("mate",mate_tree,proto_mate); - - register_init_routine(init_mate); - - } + proto_mate = proto_register_protocol("Meta Analysis Tracing Engine", "mate", "mate"); + register_dissector("mate",mate_tree,proto_mate); + mate_module = prefs_register_protocol(proto_mate, proto_reg_handoff_mate); + prefs_register_string_preference(mate_module, "config_filename", + "Configuration Filename", + "The name of the file containing the mate module's configuration", + &pref_mate_config_filename); }