One step at a time

several fixes and additions


svn path=/trunk/; revision=17103
This commit is contained in:
Luis Ontanon 2006-01-25 22:39:07 +00:00
parent 84794a9bc3
commit 3cbb83e490
6 changed files with 189 additions and 106 deletions

View File

@ -300,10 +300,11 @@ static int Column_tostring(lua_State *L) {
Column c = checkColumn(L,1);
const gchar* name;
if (!(c && c->cinfo)) {
lua_pushstring(L,"Bad Column");
return 1;
if (!(c)) {
luaL_error(L,"Bad column");
return 0;
} else {
/* TODO: format the column */
name = col_id_to_name(c->col);
lua_pushstring(L,name ? name : "Unknown Column");
}
@ -433,18 +434,18 @@ static int Columns_newindex(lua_State *L) {
static int Columns_index(lua_State *L) {
Columns cols = checkColumns(L,1);
const struct col_names_t* cn;
const char* colname;
const char* colname = luaL_checkstring(L,2);
if (!cols) {
Column c = g_malloc(sizeof(struct _eth_col_info));
c->cinfo = NULL;
c->col = 0;
c->col = col_name_to_id(colname);
pushColumn(L,c);
return 1;
}
colname = luaL_checkstring(L,2);
if (!colname) return 0;

View File

@ -131,6 +131,7 @@ static int ProtoField_new(lua_State* L) {
ProtoField f = g_malloc(sizeof(eth_field_t));
GArray* vs;
/* will be using -2 as far as the field has not been added to an array then it will turn -1 */
f->hfid = -2;
f->name = g_strdup(luaL_checkstring(L,1));
f->abbr = g_strdup(luaL_checkstring(L,2));
@ -246,6 +247,30 @@ static int ProtoField_tostring(lua_State* L) {
return 1;
}
static int ProtoField_gc(lua_State* L) {
ProtoField f = checkProtoField(L,1);
/*
* A garbage collector for ProtoFields makes little sense.
* Even if This cannot be used anymore because it has gone out of scope,
* we can destroy the ProtoField only if it is not part of a ProtoFieldArray,
* if it actualy belongs to one we need to preserve it as it is pointed by
* a field array that may be registered afterwards causing a crash or memory corruption.
*/
if (!f) {
luaL_argerror(L,1,"BUG: ProtoField_gc called for something not ProtoField");
/* g_assert() ?? */
} else if (f->hfid == -2) {
g_free(f->name);
g_free(f->abbr);
g_free(f->blob);
g_free(f);
}
return 0;
}
static const luaL_reg ProtoField_methods[] = {
{"new", ProtoField_new},
@ -277,7 +302,8 @@ static const luaL_reg ProtoField_methods[] = {
};
static const luaL_reg ProtoField_meta[] = {
{"__tostring", ProtoField_tostring},
{"__gc", ProtoField_gc },
{"__tostring", ProtoField_tostring },
{0, 0}
};
@ -385,9 +411,20 @@ static int ProtoFieldArray_tostring(lua_State* L) {
}
static int ProtoFieldArray_gc(lua_State* L) {
ProtoFieldArray vs = checkValueString(L,1);
ProtoFieldArray fa = checkValueString(L,1);
gboolean free_it = FALSE;
g_array_free(vs,TRUE);
/* we'll keep the data if the array was registered to a protocol */
if (fa->len) {
hf_register_info* f = (hf_register_info*)fa->data;
if ( *(f->p_id) == -2)
free_it = TRUE;
} else {
free_it = TRUE;
}
g_array_free(fa,free_it);
return 0;
}
@ -560,6 +597,7 @@ static int SubTreeTypeArray_register_to_ethereal(lua_State* L) {
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;
@ -603,51 +641,34 @@ int SubTreeTypeArray_register(lua_State* L) {
static int Proto_new(lua_State* L) {
Proto proto;
const gchar* name = luaL_checkstring(L,1);
const gchar* filter = luaL_checkstring(L,2);
const gchar* desc = luaL_checkstring(L,3);
const gchar* desc = luaL_optstring(L,2,"");
if (! (name && filter && desc) ) return 0;
proto = g_malloc(sizeof(eth_proto_t));
proto->hfid = -1;
proto->name = g_strdup(name);
proto->filter = g_strdup(filter);
proto->desc = g_strdup(desc);
proto->hfarray = NULL;
proto->prefs_module = NULL;
proto->prefs = NULL;
proto->handle = NULL;
proto->is_postdissector = FALSE;
if (proto->name && proto->filter && proto->desc) {
if ( proto_get_id_by_filter_name(proto->filter) > 0 ) {
g_free(proto);
luaL_argerror(L,2,"Protocol exists already");
if ( name ) {
if ( proto_get_id_by_filter_name(name) > 0 ) {
luaL_argerror(L,1,"Protocol exists already");
return 0;
} else {
Proto proto = g_malloc(sizeof(eth_proto_t));
/* 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->is_postdissector = FALSE;
proto->hfid = proto_register_protocol(proto->desc,proto->name,proto->filter);
proto->handle = create_dissector_handle(dissect_lua,proto->hfid);
pushProto(L,proto);
return 1;
}
} else {
if (! proto->name )
luaL_argerror(L,1,"missing name");
if (! proto->filter )
luaL_argerror(L,2,"missing filter");
if (! proto->desc )
luaL_argerror(L,3,"missing desc");
g_free(proto);
return 0;
luaL_argerror(L,1,"missing name");
return 0;
}
}
static int Proto_register_field_array(lua_State* L) {
@ -672,6 +693,10 @@ static int Proto_register_field_array(lua_State* L) {
if (proto->hfarray) {
luaL_argerror(L,1,"field_array already registered for this protocol");
}
if ( *(((hf_register_info*)(fa->data))->p_id) != -1 ) {
luaL_argerror(L,1,"this field_array has been already registered to another protocol");
}
proto->hfarray = (hf_register_info*)(fa->data);
proto_register_field_array(proto->hfid,proto->hfarray,fa->len);
@ -771,7 +796,6 @@ static int Proto_add_string_pref(lua_State* L) {
return 0;
}
static int Proto_get_pref(lua_State* L) {
Proto proto = checkProto(L,1);
const gchar* abbr = luaL_checkstring(L,2);
@ -975,6 +999,9 @@ static int DissectorTable_new (lua_State *L) {
switch(type) {
case FT_STRING:
base = BASE_NONE;
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
{
DissectorTable dt = g_malloc(sizeof(struct _eth_distbl_t));
@ -1027,7 +1054,7 @@ static int DissectorTable_add (lua_State *L) {
if (type == FT_STRING) {
gchar* pattern = g_strdup(luaL_checkstring(L,2));
dissector_add_string(dt->name, pattern,p->handle);
} else if ( type == FT_UINT32 ) {
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = luaL_checkint(L, 2);
dissector_add(dt->name, port, p->handle);
}
@ -1035,6 +1062,26 @@ static int DissectorTable_add (lua_State *L) {
return 0;
}
static int DissectorTable_remove (lua_State *L) {
DissectorTable dt = checkDissectorTable(L,1);
Proto p = checkProto(L,3);
ftenum_t type;
if (!(dt && p)) return 0;
type = get_dissector_table_selector_type(dt->name);
if (type == FT_STRING) {
gchar* pattern = g_strdup(luaL_checkstring(L,2));
dissector_delete_string(dt->name, pattern,p->handle);
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = luaL_checkint(L, 2);
dissector_delete(dt->name, port, p->handle);
}
return 0;
}
static int DissectorTable_try (lua_State *L) {
DissectorTable dt = checkDissectorTable(L,1);
@ -1054,7 +1101,7 @@ static int DissectorTable_try (lua_State *L) {
if (dissector_try_string(dt->table,pattern,tvb,pinfo,tree))
return 0;
} else if ( type == FT_UINT32 ) {
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = luaL_checkint(L, 2);
if (dissector_try_port(dt->table,port,tvb,pinfo,tree))
return 0;
@ -1078,7 +1125,7 @@ static int DissectorTable_get_dissector (lua_State *L) {
if (type == FT_STRING) {
const gchar* pattern = luaL_checkstring(L,2);
handle = dissector_get_string_handle(dt->table,pattern);
} else if ( type == FT_UINT32 ) {
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = luaL_checkint(L, 2);
handle = dissector_get_port_handle(dt->table,port);
}
@ -1106,6 +1153,9 @@ static int DissectorTable_tostring(lua_State* L) {
g_string_sprintfa(s,"%s String:\n",dt->name);
break;
}
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
{
int base = get_dissector_table_base(dt->name);
@ -1122,9 +1172,10 @@ static int DissectorTable_tostring(lua_State* L) {
}
static const luaL_reg DissectorTable_methods[] = {
{"new", DissectorTable_new},
{"get", DissectorTable_get},
{"new", DissectorTable_new },
{"get", DissectorTable_get },
{"add", DissectorTable_add },
{"remove", DissectorTable_remove },
{"try", DissectorTable_try },
{"get_dissector", DissectorTable_get_dissector },
{0,0}

View File

@ -33,18 +33,18 @@ LUA_CLASS_DEFINE(Field,FIELD,NOP);
static int Field_get (lua_State *L) {
const gchar* name = luaL_checkstring(L,1);
Field i;
Field f;
if (!name) return 0;
i = proto_registrar_get_byname(name);
f = proto_registrar_get_byname(name);
if (!i) {
if (!f) {
luaL_error(L,"Could not find field `%s'",name);
return 0;
}
pushField(L,i);
pushField(L,f);
return 1;
}
@ -55,50 +55,51 @@ static int Field_fetch (lua_State* L) {
for (;in;in = in->same_name_next) {
GPtrArray* found = proto_find_finfo(lua_tree, in->id);
guint i;
for (i=0; i<found->len; i++) {
field_info* fi = g_ptr_array_index(found,i);
switch(fi->hfinfo->type) {
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
case FT_FRAMENUM:
case FT_INT8:
case FT_INT16:
case FT_INT24:
case FT_INT32:
lua_pushnumber(L,(lua_Number)fvalue_get_integer(&(fi->value)));
items_found++;
break;
case FT_FLOAT:
case FT_DOUBLE:
lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value)));
items_found++;
break;
case FT_UINT64:
case FT_INT64:
/* XXX: get them as strings for now */
case FT_STRING:
case FT_STRINGZ:
case FT_ETHER:
case FT_BYTES:
case FT_UINT_BYTES:
case FT_IPv4:
case FT_IPv6:
case FT_IPXNET:
case FT_GUID:
case FT_OID:
lua_pushstring(L,fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL));
items_found++;
break;
default:
luaL_error(L,"FT_ not yet supported");
return items_found;
if (found) {
for (i=0; i<found->len; i++) {
field_info* fi = g_ptr_array_index(found,i);
switch(fi->hfinfo->type) {
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
case FT_FRAMENUM:
case FT_INT8:
case FT_INT16:
case FT_INT24:
case FT_INT32:
lua_pushnumber(L,(lua_Number)fvalue_get_integer(&(fi->value)));
items_found++;
break;
case FT_FLOAT:
case FT_DOUBLE:
lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value)));
items_found++;
break;
case FT_UINT64:
case FT_INT64:
/* XXX: get them as strings for now */
case FT_ETHER:
case FT_IPv4:
case FT_IPv6:
case FT_IPXNET:
/* XXX -> Address */
case FT_STRING:
case FT_STRINGZ:
case FT_BYTES:
case FT_UINT_BYTES:
case FT_GUID:
case FT_OID:
lua_pushstring(L,fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL));
items_found++;
break;
default:
luaL_error(L,"FT_ not yet supported");
return items_found;
}
}
}
}
return items_found;
}
@ -198,10 +199,33 @@ static int Tap_set_filter(lua_State* L) {
return 0;
}
GPtrArray* lua_taps = NULL;
gboolean taps_registered = FALSE;
GString* register_all_lua_taps(void) {
if (!lua_taps || taps_registered) return NULL;
while (lua_taps->len) {
Tap tap = g_ptr_array_remove_index(lua_taps,0);
GString* error;
error = register_tap_listener("frame", tap, tap->filter, lua_tap_reset, lua_tap_packet, lua_tap_draw);
if (error) {
return error;
}
taps_registered = TRUE;
}
return NULL;
}
static int Tap_register_to_ethereal(lua_State*L) {
Tap tap = checkTap(L,1);
GString* filter_s;
GString* error;
GPtrArray* ins;
guint i;
@ -211,25 +235,26 @@ static int Tap_register_to_ethereal(lua_State*L) {
if (tap->filter)
g_string_sprintfa(filter_s,"( %s ) && frame ",tap->filter);
else
g_string_sprintfa(filter_s,"frame ");
g_free(tap->filter);
ins = tap->interesting_fields;
for (i=0; i < ins->len; i++) {
Field in = g_ptr_array_index(ins,i);
g_string_sprintfa(filter_s," ||%s",in->abbrev);
}
tap->filter = filter_s->str;
g_string_free(filter_s,FALSE);
error = register_tap_listener("frame", tap, tap->filter, lua_tap_reset, lua_tap_packet, lua_tap_draw);
if (error) {
luaL_error(L,"tap registration error: %s",error);
g_string_free(error,TRUE);
}
if (!lua_taps)
lua_taps = g_ptr_array_new();
g_ptr_array_add(lua_taps,tap);
return 0;
}

View File

@ -237,9 +237,7 @@ static int ByteArray_tostring(lua_State* L) {
if (!ba) return 0;
s = g_string_new("ByteArray");
g_string_sprintfa(s,"(%u): ",ba->len);
s = g_string_new("");
for (i = 0; i < (int)ba->len; i++) {
g_string_append(s,byte_to_str[(ba->data)[i]]);

View File

@ -119,6 +119,12 @@ void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
}
static void init_lua(void) {
GString* tap_error = register_all_lua_taps();
if ( tap_error ) {
report_failure("lua tap registration problem: %s",tap_error->str);
}
/* XXX in C */
if (L)
lua_dostring(L, "for k in init_routines do init_routines[k]() end;");

View File

@ -209,4 +209,6 @@ 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);
#endif