aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2006-01-21 14:54:57 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2006-01-21 14:54:57 +0000
commit5ccce794e6f1595846b7926719aa50ae5366016d (patch)
tree190e43858cd2af311e36954c61f69dd128e70ad8
parent89a40818e25914828d43a90bba8598fc914c83eb (diff)
Another iteration, new things aren't tested yet.
Update README, to have a description of the classes svn path=/trunk/; revision=17067
-rw-r--r--plugins/lua/README103
-rw-r--r--plugins/lua/packet-lua.c1233
2 files changed, 1094 insertions, 242 deletions
diff --git a/plugins/lua/README b/plugins/lua/README
index 544f2cfd2e..ca86f646f7 100644
--- a/plugins/lua/README
+++ b/plugins/lua/README
@@ -1,18 +1,103 @@
-Starts to work so I check it in.
-
This is an interface to the Lua programming language.
http://www.lua.org
-I've already wrote a simple dissector that calls another dissectors.
+To get it to work you need to download lua-5.0.2.tar.gz into the plugin
+directory, uncompress it, cd to it and call make.
+
+The interface is buggy and far from finished, time will help on this.
-soon It will be able to register a tap and do something more.
+Interface:
-I did not checkin changes to the Makefiles so in order to use it you must change the
-makefiles.
-Other than that to get it to work you need to download lua-5.0.2.tar.gz into the plugin
-directory, uncompress it, cd to it and call make.
+ValueString -- a class to manage value_strings
+ .new() -- create a new empty Valuetring
+ :add(val,str) -- add a value-string pair to a ValueString
+ :match(val) -- a wrapper arroud val_to_str()
+
+ProtoField -- a class that represents registration info of fields.
+ .new(name,fieldname,FT_,value_str*,BASE_*,desc*)
+ -- declare a field (both the hfid and the registration info)
+
+ProtoFieldArr -- a class that represents the field_array of a protocol.
+ .new() -- creates an empty field array to start with
+ :add(field,field*,...) -- adds fields to the array
+
+SubTreeType -- a class to represent an ett
+ :new() -- create an ett
+
+SubTreeTypeArr -- a class that represents the ett array for a protocol
+ .new(subtree*,...) -- creates an array
+ :add(subtree*,...) -- adds Etts to the array
+ :register() -- registers the ett array with ethereal
+
+Proto -- a class that represents protocol info in ethereal
+ .new(name,filter_name,descr) -- creates and registers a new protocol
+ :register_field_array(field_array) -- registers a field array as this protocol's
+ :add_uint_pref(abbr,...) -- adds an uint preference to this protocol
+ :add_bool_pref(abbr,...) -- adds a string preference to this protocol
+ :add_string_pref(abbr,...) -- adds an bool preference to this protocol
+ :get_pref(abbr) -- fetches the value of a preference
+
+DissectorTable -- a class to intreface to dissector tables
+ .new(name,ui_name,type,opt_base) -- create a dissector table for others to register
+ .get(name) -- obtain a reference to another's dissector table
+ :add(pattern,proto) -- add a protocol to a table (*)
+ :try(pattern,tvb,pinfo,tree) -- try to invoke a dissector through a table
+
+Dissector -- a class that represent another dissector
+ .get(name) -- wraps find_dissector
+ :call(tvb,pinfo,tree) -- calls a dissector
+
+ByteArray -- a class to manage byte arrays
+ .new()
+ .new(string) -- like "00 01 22 2a" or "0129374AF5D"
+ :get_index(idx) -- gets the value of the idx byte from the array
+ :len() -- the length of the array
+
+
+Tvb -- a class that represents a tvb
+ .new(tvb,opt_offset,opt_len) -- creates a subset tvb
+ :get_* -- wrappers to tvb_get_* functions
+
+Pinfo -- a class that represents a packet_info structure
+ :number -- the frame number
+ :len -- the frame len
+ :caplen -- the frame capture len
+ :abs_ts -- absolute timestamp a floating number (s + ns/10^9)
+ :rel_ts -- relative timestamp
+ :delta_ts -- delta
+ :visited -- pinfo->fd->flags.visited
+ :src_address -- so far a string representing the address
+ :dst_address -- we need an adress class!
+ :dl_src
+ :dl_dst
+ :net_src
+ :net_dst
+ :ipproto
+ :circuit_id
+ :ptype
+ :match_port
+ :match_string
+ :curr_proto
+ :col -- colifo = pinfo:col(COL_INFO)
+
+Column -- a class that represents a column
+ :clear
+ :set
+ :append
+ :prepend
-the interface is buggy and far from finished, time will help on this.
+Tree -- a class that represents a proto_tree
+ :add_item -- overeloaded to accept many types of items, stil incomplete
+ :add_item_le -- same thing but little_endian
+ :get_parent -- yields the parent Item
+Item -- a class that represents a proto_item
+ :add_subtree
+ :set_text
+ :append_text
+ :set_len
+ :set_expert_flags
+ :set_generated
+ :set_hidden
diff --git a/plugins/lua/packet-lua.c b/plugins/lua/packet-lua.c
index 4e698f553a..74a2d8e41d 100644
--- a/plugins/lua/packet-lua.c
+++ b/plugins/lua/packet-lua.c
@@ -48,16 +48,16 @@
#define VALUE_STRING "ValueString"
typedef GArray* ValueString;
-#define FIELD "Field"
-typedef struct _eth_field_t* Field;
+#define PROTO_FIELD "ProtoField"
+typedef struct _eth_field_t* ProtoField;
-#define FIELD_ARRAY "FieldArray"
-typedef GArray* FieldArray;
+#define PROTO_FIELD_ARRAY "ProtoFieldArr"
+typedef GArray* ProtoFieldArray;
-#define ETT "Ett"
+#define ETT "SubTreeType"
typedef int* Ett;
-#define ETT_ARRAY "EttArray"
+#define ETT_ARRAY "SubTreeTypeArr"
typedef GArray* EttArray;
#define PROTO "Proto"
@@ -72,6 +72,9 @@ typedef struct _eth_distbl_t {
#define DISSECTOR "Dissector"
typedef dissector_handle_t Dissector;
+#define BYTE_ARRAY "ByteArray"
+typedef GByteArray* ByteArray;
+
#define TVB "Tvb"
typedef tvbuff_t* Tvb;
@@ -93,8 +96,22 @@ typedef proto_item* Item;
#define ADDRESS "Address"
typedef address* Address;
+#define INTERESTING "Interesting"
+typedef header_field_info* Interesting;
+
+#define TAP "Tap"
+typedef struct _eth_tap {
+ const gchar* name;
+ GPtrArray* interesting_fields;
+ gchar* filter;
+ gboolean registered;
+}* Tap;
+
static lua_State* L = NULL;
static dissector_handle_t data_handle = NULL;
+static packet_info* g_pinfo = NULL;
+static proto_tree* g_tree = NULL;
+
typedef struct _eth_field_t {
int hfid;
@@ -161,7 +178,7 @@ static int No_gc(lua_State *L _U_) { return 0; }
/*
* ValueString class
*/
-LUA_CLASS_OPS(ValueString,VALUE_STRING,if ( !p ) luaL_error(L,"null value_string"););
+LUA_CLASS_OPS(ValueString,VALUE_STRING,if ( !p ) luaL_error(L,"NULL ValueString"););
static int ValueString_new(lua_State* L) {
ValueString vs = g_array_new(TRUE,TRUE,sizeof(value_string));
@@ -203,7 +220,7 @@ static int ValueString_gc(lua_State* L) {
static int ValueString_tostring(lua_State* L) {
ValueString vs = checkValueString(L,1);
value_string* c = (value_string*)vs->data;
- GString* s = g_string_new("");
+ GString* s = g_string_new("ValueString:\n");
for(;c->strptr;c++) {
g_string_sprintfa(s,"\t%u\t%s\n",c->value,c->strptr);
@@ -250,7 +267,7 @@ static int ValueString_register(lua_State* L) {
/*
- * Field class
+ * ProtoField class
*/
static const eth_ft_types_t ftenums[] = {
@@ -337,19 +354,19 @@ static base_display_e string_to_base(const gchar* str) {
}
-LUA_CLASS_OPS(Field,FIELD,if (! *p) luaL_error(L,"null Field"));
+LUA_CLASS_OPS(ProtoField,PROTO_FIELD,if (! *p) luaL_error(L,"null ProtoField"));
-static int Field_new(lua_State* L) {
- Field f = g_malloc(sizeof(eth_field_t));
+static int ProtoField_new(lua_State* L) {
+ ProtoField f = g_malloc(sizeof(eth_field_t));
GArray* vs;
- f->hfid = -1;
+ f->hfid = -2;
f->name = g_strdup(luaL_checkstring(L,1));
f->abbr = g_strdup(luaL_checkstring(L,2));
f->type = get_ftenum(luaL_checkstring(L,3));
if (f->type == FT_NONE) {
- luaL_error(L,"invalid FT_type");
+ luaL_argerror(L, 3, "invalid FT_type");
return 0;
}
@@ -363,18 +380,19 @@ static int Field_new(lua_State* L) {
f->vs = NULL;
}
+ /* XXX: need BASE_ERROR */
f->base = string_to_base(luaL_optstring(L, 5, "BASE_NONE"));
f->mask = luaL_optint(L, 6, 0x0);
f->blob = g_strdup(luaL_optstring(L,7,""));
- pushField(L,f);
+ pushProtoField(L,f);
return 1;
}
-static int Field_tostring(lua_State* L) {
- Field f = checkField(L,1);
- gchar* s = g_strdup_printf("Field: %s %s %s %s %p %.8x %s\n",f->name,f->abbr,ftenum_to_string(f->type),base_to_string(f->base),f->vs,f->mask,f->blob);
+static int ProtoField_tostring(lua_State* L) {
+ ProtoField f = checkProtoField(L,1);
+ gchar* s = g_strdup_printf("ProtoField(%i): %s %s %s %s %p %.8x %s",f->hfid,f->name,f->abbr,ftenum_to_string(f->type),base_to_string(f->base),f->vs,f->mask,f->blob);
lua_pushstring(L,s);
g_free(s);
@@ -384,24 +402,24 @@ static int Field_tostring(lua_State* L) {
-static const luaL_reg Field_methods[] = {
- {"new", Field_new},
+static const luaL_reg ProtoField_methods[] = {
+ {"new", ProtoField_new},
{0,0}
};
-static const luaL_reg Field_meta[] = {
+static const luaL_reg ProtoField_meta[] = {
{"__gc", No_gc},
- {"__tostring", Field_tostring},
+ {"__tostring", ProtoField_tostring},
{0, 0}
};
-static int Field_register(lua_State* L) {
+static int ProtoField_register(lua_State* L) {
const eth_ft_types_t* ts;
const struct base_display_string_t* b;
- luaL_openlib(L, FIELD, Field_methods, 0);
- luaL_newmetatable(L, FIELD);
- luaL_openlib(L, 0, Field_meta, 0);
+ luaL_openlib(L, PROTO_FIELD, ProtoField_methods, 0);
+ luaL_newmetatable(L, PROTO_FIELD);
+ luaL_openlib(L, 0, ProtoField_meta, 0);
lua_pushliteral(L, "__index");
lua_pushvalue(L, -3);
lua_rawset(L, -3);
@@ -410,12 +428,14 @@ static int Field_register(lua_State* L) {
lua_rawset(L, -3);
lua_pop(L, 1);
+ /* add a global FT_* variable for each FT_ type */
for (ts = ftenums; ts->str; ts++) {
lua_pushstring(L, ts->str);
lua_pushstring(L, ts->str);
lua_settable(L, LUA_GLOBALSINDEX);
}
+ /* add a global BASE_* variable for each BASE_ */
for (b=base_displays;b->str;b++) {
lua_pushstring(L, b->str);
lua_pushstring(L, b->str);
@@ -429,32 +449,63 @@ static int Field_register(lua_State* L) {
/*
- * FieldArray class
+ * ProtoFieldArray class
*/
-LUA_CLASS_OPS(FieldArray,FIELD_ARRAY,if (! *p) luaL_error(L,"null FieldArray"));
+LUA_CLASS_OPS(ProtoFieldArray,PROTO_FIELD_ARRAY,if (! *p) luaL_error(L,"null ProtoFieldArray"));
+
+static int ProtoFieldArray_new(lua_State* L) {
+ ProtoFieldArray fa;
+ guint i;
+ guint num_args = lua_gettop(L);
-static int FieldArray_new(lua_State* L) {
- FieldArray fa = g_array_new(TRUE,TRUE,sizeof(hf_register_info));
- pushFieldArray(L,fa);
+ fa = g_array_new(TRUE,TRUE,sizeof(hf_register_info));
+
+ for ( i = 1; i <= num_args; i++) {
+ ProtoField f = checkProtoField(L,i);
+ hf_register_info hfri = { &(f->hfid), {f->name,f->abbr,f->type,f->base,VALS(f->vs),f->mask,f->blob,HFILL}};
+
+ if (f->hfid != -2) {
+ luaL_argerror(L, i, "field has already been added to an array");
+ return 0;
+ }
+
+ f->hfid = -1;
+
+ g_array_append_val(fa,hfri);
+ }
+
+ pushProtoFieldArray(L,fa);
return 1;
}
-static int FieldArray_add(lua_State* L) {
- FieldArray fa = checkFieldArray(L,1);
- Field f = checkField(L,2);
- hf_register_info hfri = { &(f->hfid), {f->name,f->abbr,f->type,f->base,VALS(f->vs),f->mask,f->blob,HFILL}};
-
- g_array_append_val(fa,hfri);
+static int ProtoFieldArray_add(lua_State* L) {
+ ProtoFieldArray fa = checkProtoFieldArray(L,1);
+ guint i;
+ guint num_args = lua_gettop(L);
+
+ for ( i = 2; i <= num_args; i++) {
+ ProtoField f = checkProtoField(L,i);
+ hf_register_info hfri = { &(f->hfid), {f->name,f->abbr,f->type,f->base,VALS(f->vs),f->mask,f->blob,HFILL}};
+
+ if (f->hfid != -2) {
+ luaL_argerror(L, i, "field has already been added to an array");
+ return 0;
+ }
+
+ f->hfid = -1;
+
+ g_array_append_val(fa,hfri);
+ }
return 0;
}
-static int FieldArray_tostring(lua_State* L) {
- GString* s = g_string_new("FieldArray:\n");
+static int ProtoFieldArray_tostring(lua_State* L) {
+ GString* s = g_string_new("ProtoFieldArray:\n");
hf_register_info* f;
- FieldArray fa = checkFieldArray(L,1);
+ ProtoFieldArray fa = checkProtoFieldArray(L,1);
unsigned i;
for(i = 0; i< fa->len; i++) {
@@ -468,8 +519,8 @@ static int FieldArray_tostring(lua_State* L) {
return 1;
}
-static int FieldArray_gc(lua_State* L) {
- FieldArray vs = checkValueString(L,1);
+static int ProtoFieldArray_gc(lua_State* L) {
+ ProtoFieldArray vs = checkValueString(L,1);
g_array_free(vs,TRUE);
@@ -477,22 +528,22 @@ static int FieldArray_gc(lua_State* L) {
}
-static const luaL_reg FieldArray_methods[] = {
- {"new", FieldArray_new},
- {"add", FieldArray_add},
+static const luaL_reg ProtoFieldArray_methods[] = {
+ {"new", ProtoFieldArray_new},
+ {"add", ProtoFieldArray_add},
{0,0}
};
-static const luaL_reg FieldArray_meta[] = {
- {"__gc", FieldArray_gc},
- {"__tostring", FieldArray_tostring},
+static const luaL_reg ProtoFieldArray_meta[] = {
+ {"__gc", ProtoFieldArray_gc},
+ {"__tostring", ProtoFieldArray_tostring},
{0, 0}
};
-static int FieldArray_register(lua_State* L) {
- luaL_openlib(L, FIELD_ARRAY, FieldArray_methods, 0);
- luaL_newmetatable(L, FIELD_ARRAY);
- luaL_openlib(L, 0, FieldArray_meta, 0);
+static int ProtoFieldArray_register(lua_State* L) {
+ luaL_openlib(L, PROTO_FIELD_ARRAY, ProtoFieldArray_methods, 0);
+ luaL_newmetatable(L, PROTO_FIELD_ARRAY);
+ luaL_openlib(L, 0, ProtoFieldArray_meta, 0);
lua_pushliteral(L, "__index");
lua_pushvalue(L, -3);
lua_rawset(L, -3);
@@ -515,7 +566,7 @@ LUA_CLASS_OPS(Ett,ETT,NOP);
static int Ett_new(lua_State* L) {
Ett e = g_malloc(sizeof(int));
- *e = -1;
+ *e = -2;
pushEtt(L,e);
return 1;
@@ -567,9 +618,24 @@ static int Ett_register(lua_State* L) {
*/
LUA_CLASS_OPS(EttArray,ETT_ARRAY,if (! *p) luaL_error(L,"null EttArray"));
-
static int EttArray_new(lua_State* L) {
EttArray ea = g_array_new(TRUE,TRUE,sizeof(gint*));
+ guint i;
+ guint num_args = lua_gettop(L);
+
+ for (i = 1; i <= num_args; i++) {
+ Ett e = checkEtt(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);
+ }
+
pushEttArray(L,ea);
return 1;
}
@@ -577,9 +643,20 @@ static int EttArray_new(lua_State* L) {
static int EttArray_add(lua_State* L) {
EttArray ea = checkEttArray(L,1);
- Ett e = checkEtt(L,2);
+ guint i;
+ guint num_args = lua_gettop(L);
- g_array_append_val(ea,e);
+ for (i = 2; i <= num_args; i++) {
+ Ett e = checkEtt(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;
}
@@ -602,6 +679,18 @@ static int EttArray_tostring(lua_State* L) {
static int EttArray_register_to_ethereal(lua_State* L) {
EttArray ea = checkEttArray(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;
}
@@ -666,7 +755,7 @@ static int Proto_new(lua_State* L) {
if (proto->name && proto->filter && proto->desc) {
if ( proto_get_id_by_filter_name(proto->filter) > 0 ) {
g_free(proto);
- luaL_error(L,"Protocol exists already");
+ luaL_argerror(L,2,"Protocol exists already");
return 0;
} else {
proto->hfid = proto_register_protocol(proto->desc,proto->name,proto->filter);
@@ -675,8 +764,17 @@ static int Proto_new(lua_State* L) {
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);
- luaL_error(L,"Missing Parameters");
+
return 0;
}
@@ -684,19 +782,29 @@ static int Proto_new(lua_State* L) {
static int Proto_register_field_array(lua_State* L) {
Proto proto = checkProto(L,1);
- FieldArray fa = checkFieldArray(L,2);
+ ProtoFieldArray fa = checkProtoFieldArray(L,2);
- if (proto && fa && fa->len) {
- if (proto->hfarray) {
- luaL_error(L,"field array already registered");
- }
-
- proto->hfarray = (hf_register_info*)(fa->data);
- proto_register_field_array(proto->hfid,proto->hfarray,fa->len);
-
- } else {
- luaL_error(L,"not a good field array");
+ 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;
+ }
+
+ if( ! fa->len ) {
+ luaL_argerror(L,2,"empty field_array");
+ return 0;
+ }
+
+ if (proto->hfarray) {
+ luaL_argerror(L,1,"field_array already registered for this protocol");
+ }
+
+ proto->hfarray = (hf_register_info*)(fa->data);
+ proto_register_field_array(proto->hfid,proto->hfarray,fa->len);
return 0;
}
@@ -709,31 +817,26 @@ static int Proto_add_uint_pref(lua_State* L) {
gchar* name = g_strdup(luaL_optstring (L, 5, ""));
gchar* desc = g_strdup(luaL_optstring (L, 6, ""));
- if (proto && abbr) {
- 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);
-
- if (! proto->prefs) {
- proto->prefs = pref;
- } else {
- eth_pref_t* p;
- for (p = proto->prefs; p->next; p = p->next) ;
- p->next = pref;
- }
-
- prefs_register_uint_preference(proto->prefs_module, abbr,name,
- desc, base, &(pref->value.u));
-
+ 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);
+
+ if (! proto->prefs) {
+ proto->prefs = pref;
} else {
- luaL_error(L,"missing a mandatory parameter");
+ eth_pref_t* p;
+ for (p = proto->prefs; p->next; p = p->next) ;
+ p->next = pref;
}
+ prefs_register_uint_preference(proto->prefs_module, abbr,name,
+ desc, base, &(pref->value.u));
+
return 0;
}
@@ -744,31 +847,26 @@ static int Proto_add_bool_pref(lua_State* L) {
gchar* name = g_strdup(luaL_optstring (L, 4, ""));
gchar* desc = g_strdup(luaL_optstring (L, 5, ""));
- if (proto && abbr) {
- 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->prefs) {
- proto->prefs = pref;
- } else {
- eth_pref_t* p;
- for (p = proto->prefs; p->next; p = p->next) ;
- p->next = pref;
- }
-
- prefs_register_bool_preference(proto->prefs_module, abbr,name,
- desc, &(pref->value.b));
-
+ 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->prefs) {
+ proto->prefs = pref;
} else {
- luaL_error(L,"missing a mandatory parameter");
+ eth_pref_t* p;
+ for (p = proto->prefs; p->next; p = p->next) ;
+ p->next = pref;
}
+ prefs_register_bool_preference(proto->prefs_module, abbr,name,
+ desc, &(pref->value.b));
+
return 0;
}
@@ -779,40 +877,42 @@ static int Proto_add_string_pref(lua_State* L) {
gchar* name = g_strdup(luaL_optstring (L, 4, ""));
gchar* desc = g_strdup(luaL_optstring (L, 5, ""));
- if (proto && abbr) {
- 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);
-
- if (! proto->prefs) {
- proto->prefs = pref;
- } else {
- eth_pref_t* p;
- for (p = proto->prefs; p->next; p = p->next) ;
- p->next = pref;
- }
-
- prefs_register_string_preference(proto->prefs_module, abbr,name,
- desc, &(pref->value.s));
-
+ 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);
+
+ if (! proto->prefs) {
+ proto->prefs = pref;
} else {
- luaL_error(L,"missing a mandatory parameter");
+ eth_pref_t* p;
+ for (p = proto->prefs; p->next; p = p->next) ;
+ p->next = pref;
}
+ 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);
- gchar* abbr = g_strdup(luaL_checkstring(L,2));
+ const gchar* abbr = luaL_checkstring(L,2);
+
+ if (!proto) {
+ luaL_argerror(L,1,"not a good proto");
+ return 0;
+ }
- if (! proto || ! abbr) {
+ if (!abbr) {
+ luaL_argerror(L,2,"not a good abbrev");
return 0;
}
@@ -835,60 +935,19 @@ static int Proto_get_pref(lua_State* L) {
}
}
- luaL_error(L,"no such preference");
+ luaL_argerror(L,2,"no such preference for this protocol");
return 0;
} else {
- luaL_error(L,"no preferences");
+ luaL_error(L,"no preferences set for this protocol");
return 0;
}
}
-static int Proto_set_pref(lua_State* L) {
- Proto proto = checkProto(L,1);
- gchar* abbr = g_strdup(luaL_checkstring(L,2));
-
- if (! proto || ! abbr) {
- return 0;
- }
-
- 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:
- if (lua_isnumber(L, 3)) {
- p->value.b = lua_toboolean(L, 3);
- } else {
- p->value.b = TRUE;
- }
- break;
- case PREF_UINT:
- p->value.u = (guint32)luaL_checkint(L, 3);
- break;
- case PREF_STRING:
- g_free((void*)p->value.s);
- p->value.s = lua_isstring(L, 3) ? g_strdup(lua_tostring(L,3)): g_strdup("");
- break;
- }
- return 0;
- }
- }
-
- luaL_error(L,"no such preference");
- return 0;
-
- } else {
- luaL_error(L,"no preferences");
- return 0;
- }
-}
-
static int Proto_tostring(lua_State* L) {
Proto proto = checkProto(L,1);
- gchar* s = g_strdup_printf("a Proto: %s",proto->name);
+ gchar* s = g_strdup_printf("Proto: %s",proto->name);
lua_pushstring(L,s);
g_free(s);
@@ -902,7 +961,6 @@ static const luaL_reg Proto_methods[] = {
{"add_bool_pref", Proto_add_bool_pref},
{"add_string_pref", Proto_add_string_pref},
{"get_pref", Proto_get_pref},
- {"set_pref", Proto_set_pref},
{0,0}
};
@@ -928,18 +986,291 @@ static int Proto_register(lua_State* L) {
}
+LUA_CLASS_OPS(ByteArray,BYTE_ARRAY,if (! *p) luaL_argerror(L,index,"null bytearray"));
+
+static int ByteArray_new(lua_State* L) {
+ GByteArray* ba = g_byte_array_new();
+
+ if (lua_gettop(L) == 1) {
+ const gchar* s = luaL_checkstring(L,1);
+
+ if (!s) {
+ luaL_argerror(L,1,"not a string");
+ return 0;
+ }
+
+ /* XXX: slow! */
+ int nibble[2];
+ int i = 0;
+ gchar c;
+
+ for (; (c = *s); s++) {
+ switch(c) {
+ case '0': case '1': case '2': case '3': case '4': case '5' : case '6' : case '7': case '8' : case '9' :
+ nibble[(i++)%2] = c - '0';
+ break;
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f' :
+ nibble[(i++)%2] = c - 'a' + 0xa;
+ break;
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F' :
+ nibble[(i++)%2] = c - 'A' + 0xa;
+ break;
+ default:
+ break;
+ }
+
+ if ( i == 2 ) {
+ guint8 b = (guint8)(nibble[0] * 16 + nibble[1]);
+ g_byte_array_append(ba,&b,1);
+ i = 0;
+ }
+ }
+ }
+
+ pushByteArray(L,ba);
+
+ return 1;
+}
+
+static int ByteArray_gc(lua_State* L) {
+ ByteArray ba = checkByteArray(L,1);
+
+ if (!ba) return 0;
+
+ g_byte_array_free(ba,TRUE);
+ return 0;
+}
+
+static int ByteArray_append(lua_State* L) {
+ ByteArray ba = checkByteArray(L,1);
+
+ if (luaL_checkudata (L, 2, BYTE_ARRAY)) {
+ ByteArray ba2 = checkByteArray(L,2);
+ g_byte_array_append(ba,ba2->data,ba2->len);
+ } else if (( lua_gettop(L) == 2 )) {
+ int i = luaL_checkint(L,2);
+ guint8 d;
+
+ if (i < 0 || i > 255) {
+ luaL_error(L,"Byte out of range");
+ return 0;
+ }
+
+ d = (guint8)i;
+ g_byte_array_append(ba,&d,1);
+ } else {
+ luaL_error(L,"ByteArray:append takes two arguments");
+ }
+ return 0;
+}
+
+static int ByteArray_preppend(lua_State* L) {
+ ByteArray ba = checkByteArray(L,1);
+
+ if (!ba) return 0;
+
+ if (luaL_checkudata (L, 2, BYTE_ARRAY)) {
+ ByteArray ba2 = checkByteArray(L,2);
+ g_byte_array_prepend(ba,ba2->data,ba2->len);
+ } else if (( lua_gettop(L) == 2 )) {
+ int i = luaL_checkint(L,2);
+ guint8 d;
+
+ if (i < 0 || i > 255) luaL_error(L,"Byte out of range");
+
+ d = (guint8)i;
+ g_byte_array_prepend(ba,&d,1);
+ } else {
+ luaL_error(L,"ByteArray:preppend takes two arguments");
+ }
+ return 0;
+}
+
+static int ByteArray_set_size(lua_State* L) {
+ ByteArray ba = checkByteArray(L,1);
+ int siz = luaL_checkint(L,2);
+
+ if (!ba) return 0;
+
+ g_byte_array_set_size(ba,siz);
+ return 0;
+}
+
+static int ByteArray_set_index(lua_State* L) {
+ ByteArray ba = checkByteArray(L,1);
+ int idx = luaL_checkint(L,2);
+ int v = luaL_checkint(L,3);
+
+ if (!ba) return 0;
+
+ if (idx < 0 || (guint)idx >= ba->len) {
+ luaL_argerror(L,2,"index out of range");
+ return 0;
+ }
+
+ if (v < 0 || v > 255) {
+ luaL_argerror(L,3,"Byte out of range");
+ return 0;
+ }
+
+ ba->data[idx] = (guint8)v;
+
+ return 0;
+}
+
+
+static int ByteArray_get_index(lua_State* L) {
+ ByteArray ba = checkByteArray(L,1);
+ int idx = luaL_checkint(L,2);
+
+ if (!ba) return 0;
+
+ if (idx < 0 || (guint)idx >= ba->len) {
+ luaL_argerror(L,2,"index out of range");
+ return 0;
+ }
+
+ lua_pushnumber(L,(lua_Number)ba->data[idx]);
+
+ return 1;
+}
+
+static int ByteArray_len(lua_State* L) {
+ ByteArray ba = checkByteArray(L,1);
+
+ if (!ba) return 0;
+
+ lua_pushnumber(L,(lua_Number)ba->len);
+
+ return 1;
+}
+
+static int ByteArray_subset(lua_State* L) {
+ ByteArray ba = checkByteArray(L,1);
+ int offset = luaL_checkint(L,2);
+ int len = luaL_checkint(L,3);
+ ByteArray ret;
+ guint i;
+
+ if (!ba) return 0;
+
+ if ((offset + len) > (int)ba->len) {
+ luaL_error(L,"out of bounds");
+ return 0;
+ }
+
+ ret = g_byte_array_sized_new(len);
+
+ for ( i=0 ; i < ba->len ; i++) {
+ (ret->data)[i] = (ba->data)[offset+i];
+ }
+
+ pushByteArray(L,ba);
+ return 1;
+}
+
+static int ByteArray_tostring(lua_State* L) {
+ static const gchar* byte_to_str[] = {
+ "00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
+ "10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
+ "20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
+ "30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
+ "40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
+ "50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
+ "60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
+ "70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
+ "80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
+ "90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
+ "A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
+ "B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
+ "C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
+ "D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
+ "E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
+ "F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF"
+ };
+ ByteArray ba = checkByteArray(L,1);
+ int i;
+ GString* s;
+
+ if (!ba) return 0;
+
+ s = g_string_new("ByteArray");
+
+ g_string_sprintfa(s,"(%u): ",ba->len);
+
+ for (i = 0; i < (int)ba->len; i++) {
+ g_string_append(s,byte_to_str[(ba->data)[i]]);
+ }
+
+ lua_pushstring(L,s->str);
+ g_string_free(s,TRUE);
+
+ return 1;
+}
+
+static const luaL_reg ByteArray_methods[] = {
+ {"new", ByteArray_new},
+ {"get_index", ByteArray_get_index},
+ {"len", ByteArray_len},
+ {"preppend", ByteArray_preppend},
+ {"append", ByteArray_append},
+ {"subset", ByteArray_subset},
+ {"set", ByteArray_set_index},
+ {"set_size", ByteArray_set_size},
+ {0,0}
+};
+
+static const luaL_reg ByteArray_meta[] = {
+ {"__gc", ByteArray_gc},
+ {"__tostring", ByteArray_tostring},
+ {"__concat", ByteArray_append},
+ {0, 0}
+};
+
+static int ByteArray_register(lua_State* L) {
+ luaL_openlib(L, BYTE_ARRAY, ByteArray_methods, 0);
+ luaL_newmetatable(L, BYTE_ARRAY);
+ luaL_openlib(L, 0, ByteArray_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;
+};
+
/*
* Tvb class
*/
-
LUA_CLASS_OPS(Tvb,TVB,if (! *p) luaL_error(L,"null tvb"));
static int Tvb_new (lua_State *L) {
- int len = luaL_optint(L, 3, -1);
- pushTvb(L, tvb_new_subset( checkTvb(L,1),luaL_optint(L, 2, 0),len, len) );
- return 1;
+ ByteArray ba;
+
+ if (!g_pinfo) {
+ /* XXX: for now tvb should only be used in the frame that created */
+ luaL_error(L,"Tvb can only be used in dissectors");
+ return 0;
+ }
+
+ if (( luaL_checkudata(L,1,BYTE_ARRAY) )) {
+ ba = toByteArray(L,1);
+ const gchar* name = luaL_optstring(L,2,"Unnamed") ;
+ /* XXX: what if the BA gets garbage collected? */
+ Tvb tvb = tvb_new_real_data(ba->data, ba->len,ba->len);
+ add_new_data_source(g_pinfo, tvb, name);
+ pushTvb(L,tvb);
+ return 1;
+ } else {
+ int len = luaL_optint(L, 3, -1);
+ pushTvb(L, tvb_new_subset( checkTvb(L,1),luaL_optint(L, 2, 0),len, len) );
+ return 1;
+ }
}
@@ -949,6 +1280,8 @@ static int Tvb_new (lua_State *L) {
#define DEFINE_TVBGET(type,len) static int TVBGET_FN(type) (lua_State *L) { \
tvbuff_t* tvb = checkTvb(L,1); \
int offset = luaL_checkint(L,2); \
+ if (!tvb) return 0; \
+ if (!g_pinfo) { luaL_error(L,"Tvb can only be used in dissectors"); return 0; } \
if (tvb_offset_exists(tvb, offset+len)) { \
lua_pushnumber(L, (lua_Number) tvb_get_ ## type(tvb,offset)); \
return 1; \
@@ -972,20 +1305,89 @@ DEFINE_TVBGET(letohl,3);
DEFINE_TVBGET(letohieee_float,4);
DEFINE_TVBGET(letohieee_double,8);
+static int Tvb_get_bytearray(lua_State* L) {
+ Tvb tvb = checkTvb(L,1);
+ int offset = 0;
+ int o_len;
+ int len;
+ ByteArray ba;
+
+ if (!tvb) return 0;
+
+ o_len = tvb_length(tvb);
+ len = o_len;
+
+ if (!g_pinfo) {
+ luaL_error(L,"Tvb can only be used in dissectors");
+ return 0;
+ }
+
+
+ switch( lua_gettop(L) ) {
+ case 3:
+ offset = luaL_checkint(L,2);
+ len = luaL_checkint(L,3);
+ break;
+ case 2:
+ offset = luaL_checkint(L,2);
+ len -= offset;
+ break;
+ case 1:
+ break;
+ default:
+ luaL_error(L,"too many arguments");
+ return 0;
+ }
+
+ if (len < 1 || offset+len > o_len) {
+ luaL_error(L,"off bounds");
+ return 0;
+
+ }
+
+ ba = g_byte_array_new();
+ g_byte_array_append(ba,ep_tvb_memdup(tvb,offset,len),len);
+
+ pushByteArray(L,ba);
+
+ return 1;
+}
static int Tvb_get_stringz(lua_State* L) {
- lua_pushstring(L,(gchar*)tvb_get_ephemeral_stringz(checkTvb(L,1),luaL_checkint(L,2),NULL));
+ Tvb tvb = checkTvb(L,1);
+
+ if (!tvb) return 0;
+
+ if (!g_pinfo) {
+ luaL_error(L,"Tvb can only be used in dissectors");
+ return 0;
+ }
+
+ lua_pushstring(L,(gchar*)tvb_get_ephemeral_stringz(tvb,luaL_checkint(L,2),NULL));
return 1;
}
static int Tvb_get_string(lua_State* L) {
- lua_pushstring(L,(gchar*)tvb_get_ephemeral_string(checkTvb(L,1),luaL_checkint(L,2),luaL_checkint(L,3)));
+ Tvb tvb = checkTvb(L,1);
+
+ if (!tvb) return 0;
+
+ if (!g_pinfo) {
+ luaL_error(L,"Tvb can only be used in dissectors");
+ return 0;
+ }
+
+ lua_pushstring(L,(gchar*)tvb_get_ephemeral_string(tvb,luaL_checkint(L,2),luaL_checkint(L,3)));
return 1;
}
static int Tvb_tostring(lua_State* L) {
Tvb tvb = checkTvb(L,1);
- int len = tvb_length(tvb);
+ int len;
+
+ if (!tvb) return 0;
+
+ len = tvb_length(tvb);
gchar* str = g_strdup_printf("TVB(%i) : %s",len,tvb_bytes_to_str(tvb,0,len));
lua_pushstring(L,str);
return 1;
@@ -995,6 +1397,14 @@ static int Tvb_tostring(lua_State* L) {
static int Tvb_len(lua_State* L) {
Tvb tvb = checkTvb(L,1);
+
+ if (!tvb) return 0;
+
+ if (!g_pinfo) {
+ luaL_error(L,"Tvb can only be used in dissectors");
+ return 0;
+ }
+
lua_pushnumber(L,tvb_length(tvb));
return 1;
}
@@ -1016,6 +1426,7 @@ static const luaL_reg Tvb_methods[] = {
{"get_letohdouble", TVBGET_FN(letohieee_double)},
{"get_stringz", Tvb_get_stringz },
{"get_string", Tvb_get_string },
+ {"get_bytearray",Tvb_get_bytearray},
{"len", Tvb_len},
{0,0}
};
@@ -1099,6 +1510,7 @@ static const struct col_names_t colnames[] = {
{NULL,0}
};
+#if 0
static gint col_name_to_id(const gchar* name) {
const struct col_names_t* cn;
for(cn = colnames; cn->name; cn++) {
@@ -1109,6 +1521,7 @@ static gint col_name_to_id(const gchar* name) {
return 0;
}
+#endif
static const gchar* col_id_to_name(gint id) {
const struct col_names_t* cn;
@@ -1124,15 +1537,24 @@ LUA_CLASS_OPS(Column,COLUMN,if (! *p) luaL_error(L,"null column"));
static int Column_tostring(lua_State *L) {
Column c = checkColumn(L,1);
- const gchar* name = col_id_to_name(c->col);
+ const gchar* name;
+
+ if (!c) return 0;
+
+ name = col_id_to_name(c->col);
+
lua_pushstring(L,name ? name : "Unknown Column");
return 1;
}
static int Column_clear(lua_State *L) {
Column c = checkColumn(L,1);
+
+ if (!c) return 0;
+
if (check_col(c->cinfo, c->col))
col_clear(c->cinfo, c->col);
+
return 0;
}
@@ -1140,6 +1562,8 @@ static int Column_set(lua_State *L) {
Column c = checkColumn(L,1);
const gchar* s = luaL_checkstring(L,2);
+ if (!c) return 0;
+
if (check_col(c->cinfo, c->col))
col_set_str(c->cinfo, c->col, s);
@@ -1150,6 +1574,8 @@ static int Column_append(lua_State *L) {
Column c = checkColumn(L,1);
const gchar* s = luaL_checkstring(L,2);
+ if (!(c && s)) return 0;
+
if (check_col(c->cinfo, c->col))
col_append_str(c->cinfo, c->col, s);
@@ -1159,6 +1585,8 @@ static int Column_preppend(lua_State *L) {
Column c = checkColumn(L,1);
const gchar* s = luaL_checkstring(L,2);
+ if (!(c && s)) return 0;
+
if (check_col(c->cinfo, c->col))
col_prepend_fstr(c->cinfo, c->col, "%s",s);
@@ -1167,6 +1595,7 @@ static int Column_preppend(lua_State *L) {
static int Column_gc(lua_State *L) {
Column c = checkColumn(L,1);
+ if (!c) return 0;
g_free(c);
return 0;
}
@@ -1203,7 +1632,7 @@ static int Column_register(lua_State *L) {
for(cn = colnames; cn->name; cn++) {
lua_pushstring(L, cn->name);
- lua_pushstring(L, cn->name);
+ lua_pushnumber(L,(lua_Number)cn->id);
lua_settable(L, LUA_GLOBALSINDEX);
}
@@ -1214,8 +1643,19 @@ static int Column_register(lua_State *L) {
LUA_CLASS_OPS(Pinfo,PINFO,if (! *p) luaL_error(L,"null pinfo"));
static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1; }
-#define PINFO_GET_NUMBER(name,val) static int name(lua_State *L) { Pinfo pinfo = checkPinfo(L,1); lua_pushnumber(L,(lua_Number)(val)); return 1; }
-#define PINFO_GET_STRING(name,val) static int name(lua_State *L) { Pinfo pinfo = checkPinfo(L,1); if (val) lua_pushstring(L,(const char*)(val)); else lua_pushnil(L); return 1; }
+#define PINFO_GET_NUMBER(name,val) static int name(lua_State *L) { \
+ Pinfo pinfo = checkPinfo(L,1); \
+ if (!pinfo) return 0;\
+ lua_pushnumber(L,(lua_Number)(val));\
+ return 1;\
+}
+
+#define PINFO_GET_STRING(name,val) static int name(lua_State *L) { \
+ Pinfo pinfo = checkPinfo(L,1); \
+ if (!pinfo) return 0; \
+ if (val) lua_pushstring(L,(const char*)(val)); else lua_pushnil(L); \
+ return 1; \
+}
PINFO_GET_NUMBER(Pinfo_number,pinfo->fd->num);
PINFO_GET_NUMBER(Pinfo_len,pinfo->fd->pkt_len);
@@ -1241,10 +1681,14 @@ PINFO_GET_STRING(Pinfo_curr_proto,pinfo->current_proto);
static int Pinfo_column(lua_State *L) {
Pinfo pinfo = checkPinfo(L,1);
- Column c = g_malloc(sizeof(*c));
+ Column c;
+
+ if (!pinfo) return 0;
+
+ c = g_malloc(sizeof(*c));
c->cinfo = pinfo->cinfo;
- c->col = col_name_to_id(luaL_checkstring(L,2));
+ c->col = luaL_checkint(L,2);
pushColumn(L,c);
return 1;
@@ -1308,7 +1752,7 @@ static int Tree_add_item_any(lua_State *L, gboolean little_endian) {
tree,tvb,text
*/
Tree tree = checkTree(L,1);
- Field field;
+ ProtoField field;
Item item;
Tvb tvb;
int offset;
@@ -1332,14 +1776,14 @@ static int Tree_add_item_any(lua_State *L, gboolean little_endian) {
len = 0;
str = lua_tostring(L,3);
} else {
- luaL_error(L,"First arg must be either TVB or Field");
+ luaL_error(L,"First arg must be either TVB or ProtoField");
return 0;
}
item = proto_tree_add_text(tree,tvb,offset,len,"%s",str);
- } else if (( luaL_checkudata (L, 2, FIELD) )) {
- field = checkField(L,2);
+ } else if (( luaL_checkudata (L, 2, PROTO_FIELD) )) {
+ field = checkProtoField(L,2);
tvb = checkTvb(L,3);
offset = luaL_checkint(L,4);
len = luaL_checkint(L,5);
@@ -1387,7 +1831,7 @@ static int Tree_add_item_any(lua_State *L, gboolean little_endian) {
item = proto_tree_add_item(tree,field->hfid,tvb,offset,len,little_endian);
}
} else {
- luaL_error(L,"First arg must be either TVB or Field");
+ luaL_error(L,"First arg must be either TVB or ProtoField");
return 0;
}
@@ -1400,7 +1844,7 @@ static int Tree_add_item_le(lua_State *L) { return Tree_add_item_any(L,TRUE); }
static int Tree_tostring(lua_State *L) {
Tree tree = checkTree(L,1);
- lua_pushstring(L,ep_strdup_printf("a Tree %p",tree));
+ lua_pushstring(L,ep_strdup_printf("Tree %p",tree));
return 1;
}
@@ -1449,23 +1893,25 @@ static int Tree_register(lua_State* L) {
/* Item class */
static int Item_tostring(lua_State *L) {
Item item = checkItem(L,1);
- lua_pushstring(L,ep_strdup_printf("an Item %p",item));
+ lua_pushstring(L,ep_strdup_printf("Item %p",item));
return 1;
}
static int Item_add_subtree(lua_State *L) {
Item item = checkItem(L,1);
Ett ett;
+ Tree tree = NULL;
- if (!item) {
- pushTree(L,NULL);
- return 1;
+ if (item) {
+ ett = checkEtt(L,2);
+
+ if (ett && *ett >= 0) {
+ tree = proto_item_add_subtree(item,*ett);
+ } else {
+ luaL_argerror(L,2,"bad ett");
+ }
}
- ett = checkEtt(L,2);
-
- Tree tree = proto_item_add_subtree(item,*ett);
-
pushTree(L,tree);
return 1;
}
@@ -1634,24 +2080,31 @@ LUA_CLASS_OPS(Dissector,DISSECTOR,NOP);
static int Dissector_get (lua_State *L) {
const gchar* name = luaL_checkstring(L,1);
- Dissector d = find_dissector(name);
+ Dissector d;
- if (d) {
+ if (!name) {
+ return 0;
+ }
+
+ if ((d = find_dissector(name))) {
pushDissector(L, d);
return 1;
} else {
- luaL_error(L,"No such dissector");
+ luaL_argerror(L,1,"No such dissector");
return 0;
}
}
-
static int Dissector_call(lua_State* L) {
Dissector d = checkDissector(L,1);
Tvb tvb = checkTvb(L,2);
Pinfo pinfo = checkPinfo(L,3);
Tree tree = checkTree(L,4);
+
+ if (!d) return 0;
+ if (!tvb) return 0;
+ if (!pinfo) return 0;
call_dissector(d, tvb, pinfo, tree);
return 0;
@@ -1660,6 +2113,7 @@ static int Dissector_call(lua_State* L) {
static int Dissector_tostring(lua_State* L) {
Dissector d = checkDissector(L,1);
+ if (!d) return 0;
lua_pushstring(L,dissector_handle_get_short_name(d));
return 1;
}
@@ -1703,14 +2157,21 @@ static int Dissector_register(lua_State* L) {
LUA_CLASS_OPS(DissectorTable,DISSECTOR_TABLE,NOP);
static int DissectorTable_new (lua_State *L) {
- gchar* name = g_strdup(luaL_checkstring(L,1));
- gchar* ui_name = g_strdup(luaL_optstring(L,2,name));
- enum ftenum type = get_ftenum(luaL_optstring(L,3,"FT_UINT32"));
- int base = luaL_optint(L,3,10);
+ gchar* name = (void*)luaL_checkstring(L,1);
+ gchar* ui_name = (void*)luaL_optstring(L,2,name);
+ const gchar* ftstr = luaL_optstring(L,3,"FT_UINT32");
+ enum ftenum type;
+ base_display_e base = luaL_optint(L,3,BASE_DEC);
+
+ if(!(name && ui_name && ftstr)) return 0;
+
+ name = g_strdup(name);
+ ui_name = g_strdup(ui_name);
+ type = get_ftenum(ftstr);
switch(type) {
case FT_STRING:
- base = 0;
+ base = BASE_NONE;
case FT_UINT32:
{
DissectorTable dt = g_malloc(sizeof(struct _eth_distbl_t));
@@ -1721,7 +2182,7 @@ static int DissectorTable_new (lua_State *L) {
}
return 1;
default:
- luaL_error(L,"Invalid ft_type");
+ luaL_argerror(L,3,"Invalid ft_type");
return 0;
}
@@ -1729,7 +2190,11 @@ static int DissectorTable_new (lua_State *L) {
static int DissectorTable_get (lua_State *L) {
const gchar* name = luaL_checkstring(L,1);
- dissector_table_t table = find_dissector_table(name);
+ dissector_table_t table;
+
+ if(!name) return 0;
+
+ table = find_dissector_table(name);
if (table) {
DissectorTable dt = g_malloc(sizeof(struct _eth_distbl_t));
@@ -1750,8 +2215,12 @@ static int DissectorTable_get (lua_State *L) {
static int DissectorTable_add (lua_State *L) {
DissectorTable dt = checkDissectorTable(L,1);
Proto p = checkProto(L,3);
- ftenum_t type = get_dissector_table_selector_type(dt->name);
+ 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_add_string(dt->name, pattern,p->handle);
@@ -1769,10 +2238,17 @@ static int DissectorTable_try (lua_State *L) {
Tvb tvb = checkTvb(L,3);
Pinfo pinfo = checkPinfo(L,4);
Tree tree = checkTree(L,5);
- ftenum_t type = get_dissector_table_selector_type(dt->name);
+ ftenum_t type;
+
+ if (! (dt && tvb && pinfo && tree) ) return 0;
+
+ type = get_dissector_table_selector_type(dt->name);
if (type == FT_STRING) {
const gchar* pattern = luaL_checkstring(L,2);
+
+ if (!pattern) return 0;
+
if (dissector_try_string(dt->table,pattern,tvb,pinfo,tree))
return 0;
} else if ( type == FT_UINT32 ) {
@@ -1787,12 +2263,15 @@ static int DissectorTable_try (lua_State *L) {
return 0;
}
-
static int DissectorTable_get_dissector (lua_State *L) {
DissectorTable dt = checkDissectorTable(L,1);
- ftenum_t type = get_dissector_table_selector_type(dt->name);
+ ftenum_t type;
dissector_handle_t handle = data_handle;
+ if (!dt) return 0;
+
+ type = get_dissector_table_selector_type(dt->name);
+
if (type == FT_STRING) {
const gchar* pattern = luaL_checkstring(L,2);
handle = dissector_get_string_handle(dt->table,pattern);
@@ -1810,8 +2289,13 @@ static int DissectorTable_get_dissector (lua_State *L) {
static int DissectorTable_tostring(lua_State* L) {
DissectorTable dt = checkDissectorTable(L,1);
- GString* s = g_string_new("DissectorTable ");
- ftenum_t type = get_dissector_table_selector_type(dt->name);
+ GString* s;
+ ftenum_t type;
+
+ if (!dt) return 0;
+
+ type = get_dissector_table_selector_type(dt->name);
+ s = g_string_new("DissectorTable ");
switch(type) {
case FT_STRING:
@@ -1832,7 +2316,6 @@ static int DissectorTable_tostring(lua_State* L) {
lua_pushstring(L,s->str);
g_string_free(s,TRUE);
return 1;
-
}
static const luaL_reg DissectorTable_methods[] = {
@@ -1867,6 +2350,264 @@ static int DissectorTable_register(lua_State* L) {
+
+LUA_CLASS_OPS(Interesting,INTERESTING,NOP);
+
+static int Interesting_get (lua_State *L) {
+ const gchar* name = luaL_checkstring(L,1);
+ Interesting i;
+
+ if (!name) return 0;
+
+ i = proto_registrar_get_byname(name);
+
+ if (!i) {
+ luaL_error(L,"Could not find field `%s'",name);
+ return 0;
+ }
+
+ pushInteresting(L,i);
+ return 1;
+}
+
+static int Interesting_fetch (lua_State* L) {
+ Interesting in = checkInteresting(L,1);
+ int items_found = 0;
+
+ for (;in;in = in->same_name_next) {
+ GPtrArray* found = proto_find_finfo(g_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;
+ }
+ }
+ }
+
+ return items_found;
+
+}
+
+static int Interesting_tostring (lua_State* L) {
+ Interesting in = checkInteresting(L,1);
+
+ lua_pushfstring(L,"Interesting: %s",in->abbrev);
+ return 1;
+}
+
+static const luaL_reg Interesting_methods[] = {
+ {"get", Interesting_get},
+ {"fetch", Interesting_fetch },
+ {0,0}
+};
+
+static const luaL_reg Interesting_meta[] = {
+ {"__gc", No_gc},
+ {"__tostring", Interesting_tostring},
+ {0, 0}
+};
+
+static int Interesting_register(lua_State* L) {
+ luaL_openlib(L, INTERESTING, Interesting_methods, 0);
+ luaL_newmetatable(L, INTERESTING);
+ luaL_openlib(L, 0, Interesting_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;
+};
+
+LUA_CLASS_OPS(Tap,TAP,NOP);
+
+static int Tap_new(lua_State* L) {
+ const gchar* name = luaL_checkstring(L,1);
+ Tap tap;
+
+ if (!tap) return 0;
+
+ tap = g_malloc(sizeof(struct _eth_tap));
+
+ tap->name = g_strdup(name);
+ tap->interesting_fields = g_ptr_array_new();
+ tap->filter = NULL;
+
+ pushTap(L,tap);
+ return 1;
+}
+
+static int Tap_add(lua_State* L) {
+ Tap tap = checkTap(L,1);
+ Interesting in = checkInteresting(L,2);
+
+ if (!(tap && in)) return 0;
+
+ g_ptr_array_add(tap->interesting_fields,in);
+
+ return 0;
+}
+
+static int Tap_tostring(lua_State* L) {
+ Tap tap = checkTap(L,1);
+ gchar* str;
+
+ if (!tap) return 0;
+
+ str = g_strdup_printf("Tap->%s filter: %s",tap->name, tap->filter ? tap->filter : "NONE");
+ lua_pushstring(L,str);
+ g_free(str);
+
+ 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;
+}
+
+static 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);
+
+ g_tree = edt->tree;
+
+ lua_dostring(L,ep_strdup_printf("taps.%s(_ethereal_pinfo);",tap->name));
+}
+
+static void lua_tap_reset(void *tapdata) {
+ Tap tap = tapdata;
+ lua_dostring(L,ep_strdup_printf("tap_resets.%s();",tap->name));
+}
+
+static void lua_tap_draw(void *tapdata) {
+ Tap tap = tapdata;
+ lua_dostring(L,ep_strdup_printf("tap_draws.%s();",tap->name));
+}
+
+static int Tap_register_to_ethereal(lua_State*L) {
+ Tap tap = checkTap(L,1);
+ GString* filter_s;
+ GString* error;
+ GPtrArray* ins;
+ guint i;
+
+ if (!tap) return 0;
+
+ if (tap->registered) {
+ luaL_error(L,"tap already registered");
+ return 0;
+ }
+
+ tap->registered = TRUE;
+
+ filter_s = g_string_new("");
+ g_string_sprintfa(filter_s,"( %s ) && frame ",tap->filter);
+ g_free(tap->filter);
+
+ ins = tap->interesting_fields;
+
+ for (i=0; i < ins->len; i++) {
+ Interesting 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(tap->name, 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);
+ }
+
+ return 0;
+}
+
+static const luaL_reg Tap_methods[] = {
+ {"new", Tap_new},
+ {"add", Tap_add},
+ {"set_filter", Tap_set_filter},
+ {"register", Tap_register_to_ethereal},
+ {0,0}
+};
+
+static const luaL_reg Tap_meta[] = {
+ {"__gc", No_gc},
+ {"__tostring", Tap_tostring},
+ {0, 0}
+};
+
+static int Tap_register(lua_State* L) {
+ luaL_openlib(L, TAP, Tap_methods, 0);
+ luaL_newmetatable(L, TAP);
+ luaL_openlib(L, 0, Tap_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;
+};
+
/* ethereal uses lua */
static void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
@@ -1883,8 +2624,11 @@ static void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
pushTree(L, tree);
lua_settable(L, LUA_GLOBALSINDEX);
+ g_pinfo = pinfo;
+
lua_dostring(L,ep_strdup_printf("dissectors.%s(_ethereal_tvb,_ethereal_pinfo,_ethereal_tree);",pinfo->current_proto));
+ g_pinfo = NULL;
}
static void init_lua(void) {
@@ -1908,13 +2652,14 @@ static const char *getF(lua_State *L _U_, void *ud, size_t *size)
return (*size>0) ? buff : NULL;
}
-static void functions_defined_but_unused(void) {
+extern void lua_functions_defined_but_unused(void) {
toValueString(L,1);
- toField(L,1);
- toFieldArray(L,1);
+ toProtoField(L,1);
+ toProtoFieldArray(L,1);
toEtt(L,1);
toEttArray(L,1);
toProto(L,1);
+ toByteArray(L,1);
toTvb(L,1);
toColumn(L,1);
toPinfo(L,1);
@@ -1922,6 +2667,8 @@ static void functions_defined_but_unused(void) {
toItem(L,1);
toDissector(L,1);
toDissectorTable(L,1);
+ toInteresting(L,1);
+ toTap(L,1);
}
void proto_register_lua(void)
@@ -1929,6 +2676,12 @@ void proto_register_lua(void)
FILE* file;
gchar* filename = getenv("ETHEREAL_LUA_INIT");
+ /* TODO:
+ disable if not running with the right credentials
+
+ if (euid == 0 && euid != ruid) return;
+ */
+
if (!filename) filename = get_persconffile_path("init.lua", FALSE);
file = fopen(filename,"r");
@@ -1943,10 +2696,11 @@ void proto_register_lua(void)
luaopen_io(L);
luaopen_string(L);
ValueString_register(L);
- Field_register(L);
- FieldArray_register(L);
+ ProtoField_register(L);
+ ProtoFieldArray_register(L);
Ett_register(L);
EttArray_register(L);
+ ByteArray_register(L);
Tvb_register(L);
Proto_register(L);
Column_register(L);
@@ -1955,7 +2709,8 @@ void proto_register_lua(void)
Item_register(L);
Dissector_register(L);
DissectorTable_register(L);
-
+ Interesting_register(L);
+ Tap_register(L);
lua_pushstring(L, "handoff_routines");
lua_newtable (L);
lua_settable(L, LUA_GLOBALSINDEX);
@@ -1968,6 +2723,18 @@ void proto_register_lua(void)
lua_newtable (L);
lua_settable(L, LUA_GLOBALSINDEX);
+ lua_pushstring(L, "taps");
+ lua_newtable (L);
+ lua_settable(L, LUA_GLOBALSINDEX);
+
+ lua_pushstring(L, "tap_resets");
+ lua_newtable (L);
+ lua_settable(L, LUA_GLOBALSINDEX);
+
+ lua_pushstring(L, "tap_draws");
+ 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));