* packet-lua.h
authorlego <lego@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 28 Jan 2006 03:15:45 +0000 (03:15 +0000)
committerlego <lego@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 28 Jan 2006 03:15:45 +0000 (03:15 +0000)
  * SubTreeType (ett) was renamed as SubTree

* lua_tap.c
   - change the way the taps register (still to be finished so I won't comment)

* lua_tree.c
   * SubTree(ett) moved here, now it autoregisters all subtrees created at once. The user neither does need to create a SubTreeArray(eliminated) anymore nor to register it.

* lua_proto.c
   * SubTree moved out from here its "global" variables are used by lua_tree.c .
   * SubTreeArray was eliminated (now ett's "autoregister")
   * Created usertypes for
      - Pref a preference
      - Prefs all preferences of one protocol
      So far they are transparent to the user.
   * Proto has become a pseudo-table instead of a method based (registration in nicer)

* packet-lua.c
  * runtime errors go where they are meant to:
    - errors in dissector code go to the tree (a-la malformed)
    - errors in registration/handoff/init use reporte_failure()
  * no more Lua code to be compiled at runtime

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

plugins/lua/lua_proto.c
plugins/lua/lua_tap.c
plugins/lua/lua_tree.c
plugins/lua/packet-lua.c
plugins/lua/packet-lua.h

index 479e768b8501abc67dc979ae0ea9ef106adf632e..4a38c608f69ab46db41a9ff523521032a8737e32 100644 (file)
 
 #include "packet-lua.h"
 
-LUA_CLASS_DEFINE(Proto,PROTO,if (! *p) luaL_error(L,"null Proto"));
+#define PREFS "Prefs"
+#define PREF "Pref"
+typedef eth_pref_t* Pref;
+typedef eth_pref_t* Prefs;
+
 LUA_CLASS_DEFINE(ProtoField,PROTO_FIELD,if (! *p) luaL_error(L,"null ProtoField"));
 LUA_CLASS_DEFINE(ProtoFieldArray,PROTO_FIELD_ARRAY,if (! *p) luaL_error(L,"null ProtoFieldArray"));
-LUA_CLASS_DEFINE(SubTreeType,SUB_TREE_TYPE,NOP);
-LUA_CLASS_DEFINE(SubTreeTypeArray,SUB_TREE_TYPE_ARRAY,if (! *p) luaL_error(L,"null SubTreeTypeArray"));
 LUA_CLASS_DEFINE(Dissector,DISSECTOR,NOP);
 LUA_CLASS_DEFINE(DissectorTable,DISSECTOR_TABLE,NOP);
+LUA_CLASS_DEFINE(Pref,PREF,NOP);
+LUA_CLASS_DEFINE(Prefs,PREFS,NOP);
+LUA_CLASS_DEFINE(Proto,PROTO,NOP);
+
+static int new_pref(lua_State* L, pref_type_t type) {
+    const gchar* label = luaL_optstring(L,1,NULL);
+    const gchar* descr = luaL_optstring(L,3,"");
+    
+    Pref pref = g_malloc(sizeof(eth_pref_t));
+    pref->name = NULL;
+    pref->label = label ? g_strdup(label) : NULL;
+    pref->desc = g_strdup(descr);
+    pref->type = type;
+    pref->next = NULL;
+    pref->proto = NULL;
+    
+    switch(type) {
+        case PREF_BOOL: {
+            gboolean def = lua_toboolean(L,2);
+            pref->value.b = def;
+            break;
+        }
+        case PREF_UINT: {
+            guint32 def = (guint32)luaL_optnumber(L,2,0);
+            pref->value.u = def;
+            break;
+        }
+        case PREF_STRING: {
+            gchar* def = g_strdup(luaL_optstring(L,2,""));
+            pref->value.s = def;
+            break;
+        }
+        default:
+            g_assert_not_reached();
+            break;
+
+    }
+
+    pushPref(L,pref);
+    return 1;
+    
+}
+
+static int Pref_bool(lua_State* L) {
+    return new_pref(L,PREF_BOOL);
+}
+
+static int Pref_uint(lua_State* L) {
+    return new_pref(L,PREF_UINT);
+}
+
+static int Pref_string(lua_State* L) {
+    return new_pref(L,PREF_STRING);
+}
+
+static int Pref_gc(lua_State* L) {
+    Pref pref = checkPref(L,1);
+    
+    if (pref && ! pref->name) {
+        if (pref->label) g_free(pref->label);
+        if (pref->desc) g_free(pref->desc);
+        if (pref->type == PREF_STRING) g_free((void*)pref->value.s);
+        g_free(pref);
+    }
+    
+    return 0;
+}
+
+static const luaL_reg Pref_methods[] = {
+    {"bool",   Pref_bool},
+    {"uint",   Pref_uint},
+    {"string",   Pref_string},
+    {0,0}
+};
+
+static const luaL_reg Pref_meta[] = {
+    {"__gc",   Pref_gc},
+    {0,0}
+};
+
+
+static int Pref_register(lua_State* L) {
+    luaL_openlib(L, PREF, Pref_methods, 0);
+    luaL_newmetatable(L, PREF);
+    luaL_openlib(L, 0, Pref_meta, 0);
+    lua_pushliteral(L, "__index");
+    lua_pushvalue(L, -3);
+    lua_rawset(L, -3);
+    lua_pushliteral(L, "__metatable");
+    lua_pushvalue(L, -3);
+    lua_rawset(L, -3);
+    lua_pop(L, 1);
+    
+    return 1;
+};
+
+
+static int Prefs_newindex(lua_State* L) {
+    Pref prefs = checkPrefs(L,1);
+    const gchar* name = luaL_checkstring(L,2);
+    Pref pref = checkPref(L,3);
+    Pref p;
+    if (! ( name && prefs && pref) ) return 0;
+    
+    if (pref->name) {
+        luaL_error(L,"this preference has already been registered to another protocol");
+        return 0;
+    }
+    
+    p = prefs;
+    
+    do {
+        if ( p->name && g_str_equal(p->name,name) ) {
+            luaL_error(L,"a preference named %s exists already",name);
+            return 0;
+        }
+        
+        if ( ! p->next) {
+            p->next = pref;
+            
+            pref->name = g_strdup(name);
+            
+            if (!pref->label)
+                pref->label = g_strdup(name);
+
+            if (!prefs->proto->prefs_module) {
+                prefs->proto->prefs_module = prefs_register_protocol(prefs->proto->hfid, NULL);
+   
+            }
+            
+            switch(pref->type) {
+                case PREF_BOOL: 
+                    prefs_register_bool_preference(prefs->proto->prefs_module,
+                                                   pref->name,
+                                                   pref->label,
+                                                   pref->desc,
+                                                   &(pref->value.b));
+                    break;
+                case PREF_UINT:
+                    prefs_register_uint_preference(prefs->proto->prefs_module,
+                                                   pref->name,
+                                                   pref->label,
+                                                   pref->desc,
+                                                   BASE_DEC,
+                                                   &(pref->value.u));
+                    break;
+                case PREF_STRING:
+                    prefs_register_string_preference(prefs->proto->prefs_module, 
+                                                     pref->name,
+                                                     pref->label,
+                                                     pref->desc,
+                                                     &(pref->value.s));
+                    break;
+                default:
+                    g_assert_not_reached();
+                    break;
+            }
+            
+            pref->proto = p->proto;
+            
+            return 0;
+        }
+    } while (( p = p->next ));
+
+    g_assert_not_reached();
+    
+    return 0;
+}
+
+static int Prefs_index(lua_State* L) {
+    Pref prefs = checkPrefs(L,1);
+    const gchar* name = luaL_checkstring(L,2);
+    
+    if (! ( name && prefs ) ) return 0;
+    
+    prefs = prefs->next;
+    
+    do {
+        if ( g_str_equal(prefs->name,name) ) {
+            switch (prefs->type) {
+                case PREF_BOOL: lua_pushboolean(L, prefs->value.b); break;
+                case PREF_UINT: lua_pushnumber(L,(lua_Number)prefs->value.u); break;
+                case PREF_STRING: lua_pushstring(L,prefs->value.s); break;
+                default: g_assert_not_reached(); break;
+            }
+            return 1;
+        }
+    } while (( prefs = prefs->next ));
+
+    luaL_error(L,"no such preference `%s'",name);
+    lua_pushnil(L);
+    return 1;
+}
+
+static const luaL_reg Prefs_meta[] = {
+    {"__newindex",   Prefs_newindex},
+    {"__index",   Prefs_index},
+    {0,0}
+};
+
+static int Prefs_register(lua_State* L) {
+    luaL_newmetatable(L, PREFS);
+    luaL_openlib(L, NULL, Prefs_meta, 0);
+    
+    return 1;
+};
+
 
 
 /*
@@ -508,180 +717,6 @@ int ProtoFieldArray_register(lua_State* L) {
 
 
 
-/*
- * SubTreeType class
- */
-
-
-static int SubTreeType_new(lua_State* L) {
-    SubTreeType e = g_malloc(sizeof(int));
-    *e = -2;
-    pushSubTreeType(L,e);
-    
-    return 1;
-}
-
-static int SubTreeType_tostring(lua_State* L) {
-    SubTreeType e = checkSubTreeType(L,1);
-    gchar* s = g_strdup_printf("SubTreeType: %i",*e);
-    
-    lua_pushstring(L,s);
-    g_free(s);
-    
-    return 1;
-}
-
-
-static const luaL_reg SubTreeType_methods[] = {
-    {"new",   SubTreeType_new},
-    {0,0}
-};
-
-static const luaL_reg SubTreeType_meta[] = {
-    {"__tostring", SubTreeType_tostring},
-    {0, 0}
-};
-
-int SubTreeType_register(lua_State* L) {
-    luaL_openlib(L, SUB_TREE_TYPE, SubTreeType_methods, 0);
-    luaL_newmetatable(L, SUB_TREE_TYPE);
-    luaL_openlib(L, 0, SubTreeType_meta, 0);
-    lua_pushliteral(L, "__index");
-    lua_pushvalue(L, -3);
-    lua_rawset(L, -3);
-    lua_pushliteral(L, "__metatable");
-    lua_pushvalue(L, -3);
-    lua_rawset(L, -3);
-    lua_pop(L, 1);
-    
-    return 1;
-}
-
-
-
-
-
-/*
- * SubTreeTypeArray class
- */
-
-static int SubTreeTypeArray_new(lua_State* L) {
-    SubTreeTypeArray ea = g_array_new(TRUE,TRUE,sizeof(gint*));
-    guint i;
-    guint num_args = lua_gettop(L);
-    
-    for (i = 1; i <= num_args; i++) {
-        SubTreeType e = checkSubTreeType(L,i);
-        
-        if(*e != -2) {
-            luaL_argerror(L, i, "SubTree has already been added to an array");
-            return 0;
-        }
-        
-        *e = -1;
-        
-        g_array_append_val(ea,e);
-    }
-    
-    pushSubTreeTypeArray(L,ea);
-    return 1;
-}
-
-
-static int SubTreeTypeArray_add(lua_State* L) {
-    SubTreeTypeArray ea = checkSubTreeTypeArray(L,1);
-    guint i;
-    guint num_args = lua_gettop(L);
-    
-    for (i = 2; i <= num_args; i++) {
-        SubTreeType e = checkSubTreeType(L,i);
-        if(*e != -2) {
-            luaL_argerror(L, i, "SubTree has already been added to an array");
-            return 0;
-        }
-        
-        *e = -1;
-        
-        g_array_append_val(ea,e);
-    }
-    
-    return 0;
-}
-
-static int SubTreeTypeArray_tostring(lua_State* L) {
-    GString* s = g_string_new("SubTreeTypeArray:\n");
-    SubTreeTypeArray ea = checkSubTreeTypeArray(L,1);
-    unsigned i;
-    
-    for(i = 0; i< ea->len; i++) {
-        gint ett = *(((gint**)(ea->data))[i]);
-        g_string_sprintfa(s,"%i\n",ett);
-    };
-    
-    lua_pushstring(L,s->str);
-    g_string_free(s,TRUE);
-    
-    return 1;
-}
-
-static int SubTreeTypeArray_register_to_ethereal(lua_State* L) {
-    SubTreeTypeArray ea = checkSubTreeTypeArray(L,1);
-    
-    if (!ea->len) {
-        luaL_argerror(L,1,"empty array");
-        return 0;
-    }
-    
-    /* is last ett -1? */
-    if ( *(((gint *const *)ea->data)[ea->len -1])  != -1) {
-        luaL_argerror(L,1,"array has been registered already");
-        return 0;
-    }
-    
-    proto_register_subtree_array((gint *const *)ea->data, ea->len);
-    return 0;
-}
-
-static int SubTreeTypeArray_gc(lua_State* L) {
-    SubTreeTypeArray ea = checkSubTreeTypeArray(L,1);
-    
-    /* XXX - free the array if unregistered */
-    g_array_free(ea,FALSE);
-    
-    return 0;
-}
-
-
-static const luaL_reg SubTreeTypeArray_methods[] = {
-    {"new",   SubTreeTypeArray_new},
-    {"add",   SubTreeTypeArray_add},
-    {"register",   SubTreeTypeArray_register_to_ethereal},
-    {0,0}
-};
-
-static const luaL_reg SubTreeTypeArray_meta[] = {
-    {"__gc",       SubTreeTypeArray_gc},
-    {"__tostring", SubTreeTypeArray_tostring},
-    {0, 0}
-};
-
-int SubTreeTypeArray_register(lua_State* L) {
-    luaL_openlib(L, SUB_TREE_TYPE_ARRAY, SubTreeTypeArray_methods, 0);
-    luaL_newmetatable(L, SUB_TREE_TYPE_ARRAY);
-    luaL_openlib(L, 0, SubTreeTypeArray_meta, 0);
-    lua_pushliteral(L, "__index");
-    lua_pushvalue(L, -3);
-    lua_rawset(L, -3);
-    lua_pushliteral(L, "__metatable");
-    lua_pushvalue(L, -3);
-    lua_rawset(L, -3);
-    lua_pop(L, 1);
-    
-    return 1;
-}
-
-
-
 
 /*
  * Proto class
@@ -690,7 +725,7 @@ int SubTreeTypeArray_register(lua_State* L) {
 
 static int Proto_new(lua_State* L) {
     const gchar* name = luaL_checkstring(L,1);
-    const gchar* desc = luaL_optstring(L,2,"");
+    const gchar* desc = luaL_checkstring(L,2);
     
     if ( name ) {
         if ( proto_get_id_by_filter_name(name) > 0 ) { 
@@ -701,14 +736,18 @@ static int Proto_new(lua_State* L) {
             
             /* XXX - using the same name and filtername to have to deal just with one name */
             proto->name = g_strdup(name);
-            proto->filter = proto->name;
             proto->desc = g_strdup(desc);
             proto->hfarray = NULL;
             proto->prefs_module = NULL;
-            proto->prefs = NULL;
+            proto->prefs.name = NULL;
+            proto->prefs.label = NULL;
+            proto->prefs.desc = NULL;
+            proto->prefs.value.u = 0;
+            proto->prefs.next = NULL;
+            proto->prefs.proto = proto;
             proto->is_postdissector = FALSE;
-            proto->hfid = proto_register_protocol(proto->desc,proto->name,proto->filter);
-            proto->handle = create_dissector_handle(dissect_lua,proto->hfid);
+            proto->hfid = proto_register_protocol(proto->desc,proto->name,proto->name);
+            proto->handle = NULL;
             
             pushProto(L,proto);
             return 1;
@@ -719,15 +758,12 @@ static int Proto_new(lua_State* L) {
      }
 }
 
+
+
 static int Proto_register_field_array(lua_State* L) {
-    Proto proto = checkProto(L,1);
-    ProtoFieldArray fa = checkProtoFieldArray(L,2);
+    Proto proto = toProto(L,1);
+    ProtoFieldArray fa = checkProtoFieldArray(L,3);
     
-    if (!proto) {
-        luaL_argerror(L,1,"not a good proto");
-        return 0;
-    }
-
     if (! fa) {
         luaL_argerror(L,2,"not a good field_array");
         return 0;
@@ -752,209 +788,207 @@ static int Proto_register_field_array(lua_State* L) {
     return 0;
 }
 
-static int Proto_add_uint_pref(lua_State* L) {
+
+
+static int Proto_tostring(lua_State* L) { 
     Proto proto = checkProto(L,1);
-    gchar* abbr = g_strdup(luaL_checkstring(L,2));
-    guint def = (guint)luaL_optint(L,3,0);
-    guint base = (guint)luaL_optint(L,4,10);
-    gchar* name = g_strdup(luaL_optstring (L, 5, ""));
-    gchar* desc = g_strdup(luaL_optstring (L, 6, ""));
-    
-    eth_pref_t* pref = g_malloc(sizeof(eth_pref_t));
-    pref->name = abbr;
-    pref->type = PREF_UINT;
-    pref->value.u = def;
-    pref->next = NULL;
-    
-    if (! proto->prefs_module)
-        proto->prefs_module = prefs_register_protocol(proto->hfid, NULL);
+    gchar* s;
     
-    if (! proto->prefs) {
-        proto->prefs = pref;
-    } else {
-        eth_pref_t* p;
-        for (p = proto->prefs; p->next; p = p->next) ;
-        p->next = pref;
-    }
+    if (!proto) return 0;
     
-    prefs_register_uint_preference(proto->prefs_module, abbr,name,
-                                   desc, base, &(pref->value.u));
+    s = g_strdup_printf("Proto: %s",proto->name);
+    lua_pushstring(L,s);
+    g_free(s);
     
-    return 0;
+    return 1;
 }
 
-static int Proto_add_bool_pref(lua_State* L) {
+static int Proto_register_postdissector(lua_State* L) { 
     Proto proto = checkProto(L,1);
-    gchar* abbr = g_strdup(luaL_checkstring(L,2));
-    gboolean def = (gboolean)luaL_optint(L,3,FALSE);
-    gchar* name = g_strdup(luaL_optstring (L, 4, ""));
-    gchar* desc = g_strdup(luaL_optstring (L, 5, ""));
-    
-    eth_pref_t* pref = g_malloc(sizeof(eth_pref_t));
-    pref->name = abbr;
-    pref->type = PREF_BOOL;
-    pref->value.b = def;
-    pref->next = NULL;
-    
-    if (! proto->prefs_module)
-        proto->prefs_module = prefs_register_protocol(proto->hfid, NULL);
+    if (!proto) return 0;
     
-    if (! proto->prefs) {
-        proto->prefs = pref;
+    if(!proto->is_postdissector) {
+        if (! proto->handle) {
+            proto->handle = create_dissector_handle(dissect_lua, proto->hfid);
+        }
+        
+        register_postdissector(proto->handle);
     } else {
-        eth_pref_t* p;
-        for (p = proto->prefs; p->next; p = p->next) ;
-        p->next = pref;
+        luaL_argerror(L,1,"this protocol is already registered as postdissector");
     }
     
-    prefs_register_bool_preference(proto->prefs_module, abbr,name,
-                                   desc, &(pref->value.b));
-        
     return 0;
 }
 
-static int Proto_add_string_pref(lua_State* L) {
-    Proto proto = checkProto(L,1);
-    gchar* abbr = g_strdup(luaL_checkstring(L,2));
-    gchar* def = g_strdup(luaL_optstring (L, 3, ""));
-    gchar* name = g_strdup(luaL_optstring (L, 4, ""));
-    gchar* desc = g_strdup(luaL_optstring (L, 5, ""));
-    
-    eth_pref_t* pref = g_malloc(sizeof(eth_pref_t));
-    pref->name = abbr;
-    pref->type = PREF_STRING;
-    pref->value.s = def;
-    pref->next = NULL;
-    
-    if (! proto->prefs_module)
-        proto->prefs_module = prefs_register_protocol(proto->hfid, NULL);
+
+static int Proto_get_dissector(lua_State* L) { 
+    Proto proto = toProto(L,1);
     
-    if (! proto->prefs) {
-        proto->prefs = pref;
+    if (proto->handle) {
+        pushDissector(L,proto->handle);
+        return 1;
     } else {
-        eth_pref_t* p;
-        for (p = proto->prefs; p->next; p = p->next) ;
-        p->next = pref;
+        luaL_error(L,"The protocol hasn't been registered yet");
+        return 0;
     }
-    
-    prefs_register_string_preference(proto->prefs_module, abbr,name,
-                                     desc, &(pref->value.s));
-        
-    
-    return 0;
 }
 
-static int Proto_get_pref(lua_State* L) {
-    Proto proto = checkProto(L,1);
-    const gchar* abbr = luaL_checkstring(L,2);
 
-    if (!proto) {
-        luaL_argerror(L,1,"not a good proto");
-        return 0;
-    }
-    
-    if (!abbr) {
-        luaL_argerror(L,2,"not a good abbrev");
-        return 0;
-    }
+static int Proto_set_dissector(lua_State* L) { 
+    Proto proto = toProto(L,1);
     
-    if (proto->prefs) {
-        eth_pref_t* p;
-        for (p = proto->prefs; p; p = p->next) {
-            if (g_str_equal(p->name,abbr)) {
-                switch(p->type) {
-                    case PREF_BOOL:
-                        lua_pushboolean(L, p->value.b);
-                        break;
-                    case PREF_UINT:
-                        lua_pushnumber(L, (lua_Number)(p->value.u));
-                        break;
-                    case PREF_STRING:
-                        lua_pushstring(L, p->value.s);
-                        break;
-                }
-                return 1;
-            }
-        }
+    if (lua_isfunction(L,3)) {
+        /* insert the dissector into the dissectors table */
+       
+        lua_getglobal(L, LUA_DISSECTORS_TABLE);
+        lua_replace(L, 1);
+        lua_pushstring(L,proto->name);
+        lua_replace(L, 2);
+        lua_settable(L,1);
         
-        luaL_argerror(L,2,"no such preference for this protocol");
-        return 0;
+        proto->handle = create_dissector_handle(dissect_lua, proto->hfid);
         
+        return 0;
     } else {
-        luaL_error(L,"no preferences set for this protocol");
+        luaL_argerror(L,3,"The dissector of a protocol must be a function");
         return 0;
     }
 }
 
+static int Proto_get_prefs(lua_State* L) { 
+    Proto proto = toProto(L,1);
+    
+    pushPrefs(L,&proto->prefs);
+    return 1;
+}
 
-static int Proto_tostring(lua_State* L) { 
-    Proto proto = checkProto(L,1);
-    gchar* s;
+static int Proto_set_init(lua_State* L) { 
+    Proto proto = toProto(L,1);
     
-    if (!proto) return 0;
+    if (lua_isfunction(L,3)) {
+        /* insert the dissector into the dissectors table */
+        lua_getglobal(L, LUA_INIT_ROUTINES);
+        lua_replace(L, 1);
+        lua_pushstring(L,proto->name);
+        lua_replace(L, 2);
+        lua_settable(L,1);
+        
+        return 0;
+    }  else {
+        luaL_argerror(L,3,"The initializer of a protocol must be a function");
+        return 0;
+    } 
     
-    s = g_strdup_printf("Proto: %s",proto->name);
-    lua_pushstring(L,s);
-    g_free(s);
+}
+
+static int Proto_set_handoff(lua_State* L) { 
+    Proto proto = toProto(L,1);
+    
+    if (lua_isfunction(L,3)) {
+        /* insert the dissector into the dissectors table */
+        lua_getglobal(L, LUA_HANDOFF_ROUTINES);
+        lua_replace(L, 1);
+        lua_pushstring(L,proto->name);
+        lua_replace(L, 2);
+        lua_settable(L,1);
+        
+        return 0;
+    }  else {
+        luaL_argerror(L,3,"The handoff of a protocol must be a function");
+        return 0;
+    } 
     
+}
+
+static int Proto_get_name(lua_State* L) { 
+    Proto proto = toProto(L,1);
+
+    lua_pushstring(L,proto->name);
     return 1;
 }
 
-static int Proto_register_postdissector(lua_State* L) { 
+typedef struct {
+    gchar* name;
+    lua_CFunction get;
+    lua_CFunction set;
+} proto_actions_t;
+
+static const proto_actions_t proto_actions[] = {
+    {"dissector",Proto_get_dissector, Proto_set_dissector},
+    {"fields",NULL,Proto_register_field_array},
+    {"prefs",Proto_get_prefs,NULL},
+    {"init",NULL,Proto_set_init},
+    {"handoff",NULL,Proto_set_handoff},
+    {"name",Proto_get_name,NULL},
+    {NULL,NULL,NULL}
+};
+
+static int Proto_index(lua_State* L) {
     Proto proto = checkProto(L,1);
-    if (!proto) return 0;
+    const gchar* name = luaL_checkstring(L,2);
+    const proto_actions_t* pa;
     
-    if(!proto->is_postdissector) {
-        register_postdissector(proto->handle);
-    } else {
-        luaL_argerror(L,1,"this protocol is already registered as postdissector");
-    }
+    if (! (proto && name) ) return 0;
     
+    for (pa = proto_actions; pa->name; pa++) {
+        if ( g_str_equal(name,pa->name) ) {
+            if (pa->get) {
+                return pa->get(L);
+            } else {
+                luaL_error(L,"You cannot get the `%s' attribute of a protocol",name);
+                return 0;
+            }
+        }
+    }
+
+    luaL_error(L,"A protocol doesn't have a `%s' attribute",name);
     return 0;
 }
 
 
-static int Proto_get_dissector(lua_State* L) { 
+static int Proto_newindex(lua_State* L) {
     Proto proto = checkProto(L,1);
-    if (!proto) return 0;
+    const gchar* name = luaL_checkstring(L,2);
+    const proto_actions_t* pa;
     
-    if (proto->handle) {
-        pushDissector(L,proto->handle);
-        return 1;
-    } else {
-        luaL_error(L,"The protocol hasn't been registered yet");
-        return 0;
+    if (! (proto && name) ) return 0;
+    
+    for (pa = proto_actions; pa->name; pa++) {
+        if ( g_str_equal(name,pa->name) ) {
+            if (pa->set) {
+                return pa->set(L);
+            } else {
+                luaL_error(L,"You cannot set the `%s' attribute of a protocol",name);
+                return 0;
+            }
+        }
     }
+    
+    luaL_error(L,"A protocol doesn't have a `%s' attribute",name);
+    return 0;
 }
 
-static const luaL_reg Proto_methods[] = {
-    {"new",   Proto_new},
-    {"register_field_array",   Proto_register_field_array},
-    {"add_uint_pref",   Proto_add_uint_pref},
-    {"add_bool_pref",   Proto_add_bool_pref},
-    {"add_string_pref",   Proto_add_string_pref},
-    {"get_pref",   Proto_get_pref},
-    {"register_as_postdissector",   Proto_register_postdissector},
-    {"get_dissector",   Proto_get_dissector},
-    {0,0}
-};
-
 static const luaL_reg Proto_meta[] = {
     {"__tostring", Proto_tostring},
+    {"__index", Proto_index},
+    {"__newindex", Proto_newindex},
     {0, 0}
 };
 
 int Proto_register(lua_State* L) {
-    luaL_openlib(L, PROTO, Proto_methods, 0);
     luaL_newmetatable(L, PROTO);
-    luaL_openlib(L, 0, Proto_meta, 0);
-    lua_pushliteral(L, "__index");
-    lua_pushvalue(L, -3);
-    lua_rawset(L, -3);
-    lua_pushliteral(L, "__metatable");
-    lua_pushvalue(L, -3);
-    lua_rawset(L, -3);
-    lua_pop(L, 1);
+    luaL_openlib(L, NULL, Proto_meta, 0);
+    
+    lua_pushstring(L, "register_postdissector");
+    lua_pushcfunction(L, Proto_register_postdissector);
+    lua_settable(L, LUA_GLOBALSINDEX);
+
+    lua_pushstring(L, "new_protocol");
+    lua_pushcfunction(L, Proto_new);
+    lua_settable(L, LUA_GLOBALSINDEX);
+    
+    Pref_register(L);
+    Prefs_register(L);
     
     return 1;
 }
index 4586d7f1cb4e977fb626bb456820a24fc4a4e19a..005a8cc25e1f67f247a0f69dae346b3bc2b0eeea 100644 (file)
@@ -196,20 +196,21 @@ int Field_register(lua_State* L) {
 
 static int Tap_new(lua_State* L) {
     const gchar* name = luaL_checkstring(L,1);
+    const gchar* filter = luaL_optstring(L,2,NULL);
     Tap tap;
     
     if (!name) return 0;
     
-    if( find_tap_id(name) ) {
-        luaL_error(L,"a tap with this name exists already");
-        return 0;
-    }
-
     tap = g_malloc(sizeof(struct _eth_tap));
     
     tap->name = g_strdup(name);
-    tap->interesting_fields = g_ptr_array_new();
-    tap->filter = NULL;
+    tap->filter = g_strdup(filter);
+
+    if (!lua_taps)
+        lua_taps = g_ptr_array_new();
+    
+    g_ptr_array_add(lua_taps,tap);
+    
     
     pushTap(L,tap);
     return 1;
@@ -228,24 +229,7 @@ static int Tap_tostring(lua_State* L) {
     return 1;
 }
 
-static int Tap_set_filter(lua_State* L) {
-    Tap tap = checkTap(L,1);
-    const gchar* filter = luaL_checkstring(L,2);
-    
-    if (!(tap && filter)) return 0;
-    
-    if (tap->filter) {
-        luaL_error(L,"tap has filter already");
-        return 0;
-    }
-
-    tap->filter = g_strdup(filter);
-    
-    return 0;
-}
-
-
-GString* register_all_lua_taps(void) {
+GString* lua_register_all_taps(void) {
     
     if (!lua_taps || taps_registered) return NULL;
 
@@ -267,23 +251,8 @@ GString* register_all_lua_taps(void) {
     
 }
 
-static int Tap_register_to_ethereal(lua_State*L) {
-    Tap tap = checkTap(L,1);
-
-    if (!tap) return 0;
-
-    if (!lua_taps)
-        lua_taps = g_ptr_array_new();
-    
-    g_ptr_array_add(lua_taps,tap);
-    
-    return 0;
-}
-
 static const luaL_reg Tap_methods[] = {
     {"new", Tap_new},
-    {"set_filter", Tap_set_filter},
-    {"register", Tap_register_to_ethereal},
     {0,0}
 };
 
index 6a9fdb38a784b8ae482e904c88456145e20d708b..ac5c7f1e5a3e924467dac8e8bfb572f3b5ac6466 100644 (file)
 
 LUA_CLASS_DEFINE(ProtoTree,PROTO_TREE,NOP);
 LUA_CLASS_DEFINE(ProtoItem,ITEM,NOP);
+LUA_CLASS_DEFINE(SubTree,SUBTREE,NOP);
+
+
+/*
+ * SubTree class
+ */
+
+
+static GArray* lua_etts = NULL;
+static gint lua_ett = -1;
+
+void lua_register_subtrees(void) {
+    gint* ettp = &lua_ett;
+    g_array_append_val(lua_etts,ettp);
+    
+    proto_register_subtree_array((gint**)lua_etts->data,lua_etts->len);
+}
+
+static int SubTree_new(lua_State* L) {
+    SubTree e;
+    
+    if (lua_initialized)
+        luaL_error(L,"a SubTree can be created only before initialization");
+    
+    e = g_malloc(sizeof(gint));
+    *e = -1;
+    
+    if (!lua_etts) 
+        lua_etts = g_array_new(FALSE,FALSE,sizeof(gint*));
+    
+    g_array_append_val(lua_etts,e);
+    
+    pushSubTree(L,e);
+    
+    return 1;
+}
+
+static int SubTree_tostring(lua_State* L) {
+    SubTree e = checkSubTree(L,1);
+    gchar* s = g_strdup_printf("SubTree: %i",*e);
+    
+    lua_pushstring(L,s);
+    g_free(s);
+    
+    return 1;
+}
+
+
+static const luaL_reg SubTree_methods[] = {
+    {"new",   SubTree_new},
+    {0,0}
+};
+
+static const luaL_reg SubTree_meta[] = {
+    {"__tostring", SubTree_tostring},
+    {0, 0}
+};
+
+int SubTree_register(lua_State* L) {
+    luaL_openlib(L, SUBTREE, SubTree_methods, 0);
+    luaL_newmetatable(L, SUBTREE);
+    luaL_openlib(L, 0, SubTree_meta, 0);
+    lua_pushliteral(L, "__index");
+    lua_pushvalue(L, -3);
+    lua_rawset(L, -3);
+    lua_pushliteral(L, "__metatable");
+    lua_pushvalue(L, -3);
+    lua_rawset(L, -3);
+    lua_pop(L, 1);
+    
+    return 1;
+}
+
 
 /* ProtoTree class */
 
@@ -43,7 +116,6 @@ static int ProtoTree_add_item_any(lua_State *L, gboolean little_endian) {
      tree,tvb,text
      */
     ProtoTree tree = checkProtoTree(L,1);
-    ProtoField field;
     ProtoItem item = NULL;
     Tvb tvb;
     
@@ -81,7 +153,7 @@ static int ProtoTree_add_item_any(lua_State *L, gboolean little_endian) {
         } ENDTRY;
             
     } else if (( luaL_checkudata (L, 2, PROTO_FIELD) )) {
-        field = checkProtoField(L,2);
+        ProtoField field = checkProtoField(L,2);
         tvb = checkTvb(L,3);
 
         TRY {
@@ -136,6 +208,20 @@ static int ProtoTree_add_item_any(lua_State *L, gboolean little_endian) {
             return 0;
         } ENDTRY;
         
+    } else if (( luaL_checkudata (L, 2, PROTO) )) {
+        Proto proto = checkProto(L,2);
+        tvb = checkTvb(L,3);
+        
+        TRY {
+            int offset = luaL_checkint(L,4);
+            int len = luaL_checkint(L,5);
+            
+            item = proto_tree_add_item(tree,proto->hfid,tvb,offset,len,little_endian);
+        } CATCH(ReportedBoundsError) {
+            proto_tree_add_protocol_format(lua_tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" );
+            luaL_error(L,"Malformed Frame");
+            return 0;
+        } ENDTRY;
     } else {
         luaL_error(L,"First arg must be either TVB or ProtoField");
         return 0;
@@ -204,16 +290,15 @@ static int ProtoItem_tostring(lua_State *L) {
 
 static int ProtoItem_add_subtree(lua_State *L) {
     ProtoItem item = checkProtoItem(L,1);
-    SubTreeType ett;
     ProtoTree tree = NULL;
     
     if (item) {
-        ett = checkSubTreeType(L,2);
+        SubTree ett = checkSubTree(L,2);
         
-        if (ett && *ett >= 0) {
+        if (ett) {
             tree = proto_item_add_subtree(item,*ett);
         } else {
-            luaL_argerror(L,2,"bad ett");
+            tree = proto_item_add_subtree(item,lua_ett);
         }
     }
     
index ed38f7985a0f81c4209cca81239849a2afebc2a1..71bf1ede36727c8ea15c9ac083a90b2578f6d367 100644 (file)
@@ -29,6 +29,7 @@
 #include "packet-lua.h"
 #include <epan/nstime.h>
 #include <math.h>
+#include <epan/expert.h>
 
 static lua_State* L = NULL;
 
@@ -75,38 +76,129 @@ static int lua_report_failure(lua_State* LS) {
 int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data _U_) {
     Tap tap = tapdata;
     
-    lua_pushstring(L, "_ethereal_pinfo");
-    pushPinfo(L, pinfo);
-    lua_settable(L, LUA_GLOBALSINDEX);
+    lua_getglobal(L, LUA_TAP_PACKET);
+    
+    if (!lua_istable(L, -1)) {
+        g_warning("either `" LUA_TAP_PACKET "' does not exist or it is not a table!");
+        return 0;
+    }
     
-    lua_tree = edt->tree;
+    lua_pushstring(L, tap->name);
     
-    /* XXX in C */
-    lua_dostring(L,ep_strdup_printf("taps.%s(_ethereal_pinfo);",tap->name));
+    lua_gettable(L, -2);  
+    
+    lua_remove(L,1);
     
+    if (lua_isfunction(L,1)) {
+
+        lua_tree = edt->tree;
+        lua_pinfo = pinfo;
+        lua_tvb = NULL;
+        
+        pushPinfo(L, pinfo);
+        
+        switch ( lua_pcall(L,1,1,0) ) {
+            case 0:
+                /* OK */
+                break;
+            case LUA_ERRRUN:
+                g_warning("Runtime error while calling " LUA_TAP_PACKET ".%s() ",tap->name);
+                break;
+            case LUA_ERRMEM:
+                g_warning("Memory alloc error while calling " LUA_TAP_PACKET ".%s() ",tap->name);
+                break;
+            default:
+                g_assert_not_reached();
+                break;
+        }
+        
+    }
+
+    /* XXX - use the return value of the tap */
     return 1;
 }
 
 void lua_tap_reset(void *tapdata) {
     Tap tap = tapdata;
-    /* XXX in C */
-    lua_dostring(L,ep_strdup_printf("tap_resets.%s();",tap->name));
+
+    lua_getglobal(L, LUA_TAP_INIT);
+    
+    if (!lua_istable(L, -1)) {
+        g_warning("either `" LUA_TAP_INIT "' does not exist or it is not a table!");
+        return;
+    }
+    
+    lua_pushstring(L, tap->name);
+    
+    lua_gettable(L, -2);  
+    
+    lua_remove(L,1);
+    
+    if (lua_isfunction(L,1)) {
+        switch ( lua_pcall(L,1,0,0) ) {
+            case 0:
+                /* OK */
+                break;
+            case LUA_ERRRUN:
+                g_warning("Runtime error while calling " LUA_TAP_INIT ".%s() ",tap->name);
+                break;
+            case LUA_ERRMEM:
+                g_warning("Memory alloc error while calling " LUA_TAP_INIT ".%s() ",tap->name);
+                break;
+            default:
+                g_assert_not_reached();
+                break;
+        }
+    }
+
 }
 
 void lua_tap_draw(void *tapdata) {
     Tap tap = tapdata;
-    /* XXX in C */
-    lua_dostring(L,ep_strdup_printf("tap_draws.%s();",tap->name));
+    
+    lua_getglobal(L, LUA_TAP_DRAW);
+    
+    if (!lua_istable(L, -1)) {
+        g_warning("either `" LUA_TAP_DRAW "' does not exist or it is not a table!");
+        return;
+    }
+    
+    
+    lua_pushstring(L, tap->name);
+    
+    lua_gettable(L, -2);  
+    
+    lua_remove(L,1);
+    
+    if (lua_isfunction(L,1)) {
+        switch ( lua_pcall(L,1,0,0) ) {
+            case 0:
+                /* OK */
+                break;
+            case LUA_ERRRUN:
+                g_warning("Runtime error while calling " LUA_TAP_DRAW ".%s() ",tap->name);
+                break;
+            case LUA_ERRMEM:
+                g_warning("Memory alloc error while calling " LUA_TAP_DRAW ".%s() ",tap->name);
+                break;
+            default:
+                g_assert_not_reached();
+                break;
+        }
+    }
 }
 
+
+
 void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
     lua_pinfo = pinfo;
     lua_tree = tree;
     lua_tvb = tvb;
 
     /*
-     * equivalent to Lua:
+     * almost equivalent to Lua:
      * dissectors[current_proto](tvb,pinfo,tree)
+     * but it wont give an error if dissectors[current_proto] doesn't exist
      */
     
     lua_settop(L,0);
@@ -114,7 +206,8 @@ void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
     lua_getglobal(L, LUA_DISSECTORS_TABLE);
     
     if (!lua_istable(L, -1)) {
-        g_warning("either `" LUA_DISSECTORS_TABLE "' does not exist or it is not a table!");
+        proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua: either `" LUA_DISSECTORS_TABLE "' does not exist or it is not a table!");
+        expert_add_info_format(pinfo, pi, PI_DEBUG, PI_ERROR,"Lua Error");
 
         lua_pinfo = NULL;
         lua_tree = NULL;
@@ -131,99 +224,105 @@ void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
     lua_remove(L,1);
 
     
-    if (!lua_isfunction(L,1)) {
-        g_warning("`" LUA_DISSECTORS_TABLE ".%s' is not a function, is a %s",
-                  pinfo->current_proto,lua_typename(L,lua_type(L,1)));
-
-        lua_pinfo = NULL;
-        lua_tree = NULL;
-        lua_tvb = NULL;
+    if (lua_isfunction(L,1)) {
         
-        return;        
+        pushTvb(L,tvb);
+        pushPinfo(L,pinfo);
+        pushProtoTree(L,tree);
+        
+        if  ( lua_pcall(L,3,0,0) ) {
+            const gchar* error = lua_tostring(L,-1);
+            proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: %s",error);
+            expert_add_info_format(pinfo, pi, PI_DEBUG, PI_ERROR ,"Lua Error");
+        }
+    } else {
+        /* XXX */   
     }
     
-    pushTvb(L, tvb);
-    pushPinfo(L, pinfo);
-    pushProtoTree(L, tree);
-    
-    switch ( lua_pcall(L,3,0,0) ) {
-        case 0:
-            /* OK */
-            break;
-        case LUA_ERRRUN:
-            g_warning("Runtime error while calling " LUA_DISSECTORS_TABLE ".%s() ",pinfo->current_proto);
-            break;
-        case LUA_ERRMEM:
-            g_warning("Memory alloc error while calling " LUA_DISSECTORS_TABLE ".%s() ",pinfo->current_proto);
-            break;
-        default:
-            g_assert_not_reached();
-            break;
-    }
-
     lua_pinfo = NULL;
     lua_tree = NULL;
     lua_tvb = NULL;
+
 }
 
-static void init_lua(void) {
-    GString* tap_error = register_all_lua_taps();
+static void iter_table_and_call(lua_State* LS, const gchar* table_name, lua_CFunction error_handler) {
+    lua_settop(LS,0);
     
-    if ( tap_error ) {
-        report_failure("lua tap registration problem: %s",tap_error->str);
-        g_string_free(tap_error,TRUE);
+    lua_pushcfunction(LS,error_handler);
+    lua_getglobal(LS, table_name);
+
+    if (!lua_istable(LS, 2)) {
+        report_failure("Lua: either `%s' does not exist or it is not a table!\n",table_name);
+        lua_close(LS);
+        L = NULL;
+        return;
     }
+
+    lua_pushnil(LS);
     
-    
-    /* this should be called in a more appropriate place */
-    lua_prime_all_fields(NULL);
-    
-    if (L) {
-        lua_getglobal(L, LUA_INIT_ROUTINES);
+    while (lua_next(LS, 2)) {
+        const gchar* name = lua_tostring(L,-2);
 
-        if (!lua_istable(L, -1)) {
-            g_warning("either `" LUA_INIT_ROUTINES "' does not exist or it is not a table!");
-            return;
-        }
-        
-        lua_pushnil(L);
-        
-        while (lua_next(L, -2) != 0) {
-            const gchar* name = lua_tostring(L,-2);
-            if (!lua_isfunction(L,-1)) {
-                g_warning("`" LUA_INIT_ROUTINES ".%s' is not a function, is a %s",
-                          name,lua_typename(L,lua_type(L,-1)));
-                return;
-            }
-                        
-            switch ( lua_pcall(L,-1,0,0) ) {
-                case 0:
-                    /* OK */
-                    break;
-                case LUA_ERRRUN:
-                    g_warning("Runtime error while calling " LUA_INIT_ROUTINES ".%s() ",name);
-                    break;
-                case LUA_ERRMEM:
-                    g_warning("Memory alloc error while calling " LUA_INIT_ROUTINES ".%s() ",name);
-                    break;
-                default:
-                    g_assert_not_reached();
-                    break;
+        if (lua_isfunction(LS,-1)) {
+
+            if ( lua_pcall(LS,0,0,1) ) {
+                    lua_pop(LS,1);
             }
             
-            lua_pop(L, 1);
+        } else {
+            report_failure("Lua: Something not a function got its way into the %s.%s",table_name,name);
+            lua_close(LS);
+            L = NULL;
+            return;
         }
+    }
+
+    lua_settop(LS,0);
+}
+
+gboolean lua_initialized = FALSE;
+
+static int init_error_handler(lua_State* L) {
+    const gchar* error =  lua_tostring(L,1);
+    report_failure("Lua: Error During execution of Initialization:\n %s",error);
+    return 0;
+}
+
+static void init_lua(void) {
+    if ( ! lua_initialized ) {
+        GString* tap_error = lua_register_all_taps();
         
-        lua_pop(L, 1);
+        if ( tap_error ) {
+            report_failure("lua tap registration problem: %s",tap_error->str);
+            g_string_free(tap_error,TRUE);
+        }
+                
+        lua_prime_all_fields(NULL);
         
+        lua_register_subtrees();
+            
+        lua_initialized = TRUE;
+    }
+    
+    if (L) {
+        iter_table_and_call(L, LUA_INIT_ROUTINES,init_error_handler);
     }
+
+}
+
+static int handoff_error_handler(lua_State* L) {
+    const gchar* error =  lua_tostring(L,1);
+    report_failure("Lua: Error During execution of Handoff:\n %s",error);
+    return 0;
 }
 
 void proto_reg_handoff_lua(void) {
     lua_data_handle = find_dissector("data");
-    /* XXX in C */
-    if (L)
-        lua_dostring(L, "for k in handoff_routines do handoff_routines[k]() end ;");
+
+    if (L) {
+        iter_table_and_call(L, LUA_HANDOFF_ROUTINES,handoff_error_handler);
+    }
+
 }
 
 static const char *getF(lua_State *L _U_, void *ud, size_t *size)
@@ -235,6 +334,12 @@ static const char *getF(lua_State *L _U_, void *ud, size_t *size)
     return (*size>0) ? buff : NULL;
 }
 
+static int lua_main_error_handler(lua_State* LS) {
+    const gchar* error =  lua_tostring(LS,1);
+    report_failure("Lua: Error during registration:\n %s",error);
+    return 0;
+}
+
 void proto_register_lua(void)
 {
     FILE* file;
@@ -256,6 +361,8 @@ void proto_register_lua(void)
     
     L = lua_open();
     
+    lua_pushcfunction(L,lua_main_error_handler);
+
     luaopen_base(L);
     luaopen_table(L);
     luaopen_io(L);
@@ -263,8 +370,7 @@ void proto_register_lua(void)
 
     ProtoField_register(L);
     ProtoFieldArray_register(L);
-    SubTreeType_register(L);
-    SubTreeTypeArray_register(L);
+    SubTree_register(L);
     ByteArray_register(L);
     Tvb_register(L);
     Proto_register(L);
@@ -291,7 +397,7 @@ void proto_register_lua(void)
     lua_pushcfunction(L, lua_report_failure);
     lua_settable(L, LUA_GLOBALSINDEX);
             
-    lua_pushstring(L, "handoff_routines");
+    lua_pushstring(L, LUA_HANDOFF_ROUTINES);
     lua_newtable (L);
     lua_settable(L, LUA_GLOBALSINDEX);
     
@@ -303,21 +409,20 @@ void proto_register_lua(void)
     lua_newtable (L);
     lua_settable(L, LUA_GLOBALSINDEX);
     
-    lua_pushstring(L, "taps");
+    lua_pushstring(L, LUA_TAP_PACKET);
     lua_newtable (L);
     lua_settable(L, LUA_GLOBALSINDEX);
 
-    lua_pushstring(L, "tap_resets");
+    lua_pushstring(L, LUA_TAP_RESET);
     lua_newtable (L);
     lua_settable(L, LUA_GLOBALSINDEX);
 
-    lua_pushstring(L, "tap_draws");
+    lua_pushstring(L, LUA_TAP_DRAW);
     lua_newtable (L);
     lua_settable(L, LUA_GLOBALSINDEX);
     
-    if (lua_load(L,getF,file,filename) || lua_pcall(L,0,0,0))
-        fprintf(stderr,"%s\n",lua_tostring(L,-1));
-    
+    lua_load(L,getF,file,filename) || lua_pcall(L,0,0,1);
+
     fclose(file);
     
     lua_data_handle = NULL;
@@ -326,6 +431,7 @@ void proto_register_lua(void)
     lua_tvb = NULL;
     
     lua_malformed = proto_get_id_by_filter_name("malformed");
-    
+
 }
 
index 5bc177566939fce66212ee72e6eb8a5aa519e646..aa82898a3401497d17f230a8caf852f143d13d9f 100644 (file)
 
 #define LUA_DISSECTORS_TABLE "dissectors"
 #define LUA_INIT_ROUTINES "init_routines"
-
+#define LUA_HANDOFF_ROUTINES "handoff_routines"
+#define LUA_TAP_PACKET "taps"
+#define LUA_TAP_INIT "taps_init"
+#define LUA_TAP_DRAW "taps_draw"
+#define LUA_TAP_RESET "taps_reset"
 
 typedef struct _eth_field_t {
     int hfid;
@@ -63,47 +67,45 @@ typedef struct _eth_field_t {
     guint32 mask;
 } eth_field_t;
 
-typedef enum {PREF_BOOL,PREF_UINT,PREF_STRING} pref_type_t;
+typedef enum {PREF_NONE,PREF_BOOL,PREF_UINT,PREF_STRING} pref_type_t;
 
 typedef struct _eth_pref_t {
     gchar* name;
+    gchar* label;
+    gchar* desc;
     pref_type_t type;
     union {
         gboolean b;
         guint32 u;
-        gint32 i;
         const gchar* s;
     } value;
+    
     struct _eth_pref_t* next;
+    struct _eth_proto_t* proto;
 } eth_pref_t;
 
 typedef struct _eth_proto_t {
     int hfid;
     char* name;
-    char* filter;
     char* desc;
     hf_register_info* hfarray;
     gboolean hf_registered;
     module_t *prefs_module;
-    eth_pref_t* prefs;
+    eth_pref_t prefs;
     dissector_handle_t handle;
     gboolean is_postdissector;
 } eth_proto_t;
 
 typedef struct {const gchar* str; enum ftenum id; } eth_ft_types_t;
 
-
 #define PROTO_FIELD "ProtoField"
 typedef struct _eth_field_t* ProtoField;
 
 #define PROTO_FIELD_ARRAY "ProtoFieldArray"
 typedef GArray* ProtoFieldArray;
 
-#define SUB_TREE_TYPE "SubTreeType"
-typedef int* SubTreeType;
-
-#define SUB_TREE_TYPE_ARRAY "SubTreeTypeArray"
-typedef GArray* SubTreeTypeArray;
+#define SUBTREE "SubTree"
+typedef int* SubTree;
 
 #define PROTO "Proto"
 typedef struct _eth_proto_t* Proto;
@@ -150,7 +152,6 @@ typedef header_field_info* Field;
 #define TAP "Tap"
 typedef struct _eth_tap {
     const gchar* name;
-    GPtrArray* interesting_fields;
     gchar* filter;
     gboolean registered;
 }* Tap;
@@ -181,6 +182,8 @@ extern proto_tree* lua_tree;
 extern tvbuff_t* lua_tvb;
 extern int lua_malformed;
 extern dissector_handle_t lua_data_handle;
+extern gboolean lua_initialized;
+
 
 #define LUA_CLASS_DECLARE(C,CN) \
 extern C to##C(lua_State* L, int index); \
@@ -192,8 +195,7 @@ LUA_CLASS_DECLARE(Tap,TAP);
 LUA_CLASS_DECLARE(Field,FIELD);
 LUA_CLASS_DECLARE(ProtoField,PROTO_FIELD);
 LUA_CLASS_DECLARE(ProtoFieldArray,PROTO_FIELD_ARRAY);
-LUA_CLASS_DECLARE(SubTreeType,SUB_TREE_TYPE);
-LUA_CLASS_DECLARE(SubTreeTypeArray,SUB_TREE_TYPE_ARRAY);
+LUA_CLASS_DECLARE(SubTree,SUBTREE);
 LUA_CLASS_DECLARE(Proto,PROTO);
 LUA_CLASS_DECLARE(ByteArray,BYTE_ARRAY);
 LUA_CLASS_DECLARE(Tvb,TVB);
@@ -211,9 +213,12 @@ extern int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt
 extern void lua_tap_reset(void *tapdata);
 extern void lua_tap_draw(void *tapdata);
 
-extern GString* register_all_lua_taps(void);
+extern GString* lua_register_all_taps(void);
 extern void lua_prime_all_fields(proto_tree* tree);
+void lua_register_subtrees(void);
 
-#define WARNSTACK(s) {int i; for (i = 1; i <= lua_gettop(L); i++) g_warning("-%s-> %i %s",s,i , lua_typename(L,lua_type(L,i))); }
+#if 0
+#define WARNSTACK(s) {int i; for (i = 1; i <= lua_gettop(L); i++) if (lua_isstring(L,i)) printf("-%s-> %i `%s'\n",s,i , lua_tostring(L,i)); else printf("-%s-> %i %s\n",s,i , lua_typename(L,lua_type(L,i))); }
+#endif
 
 #endif