--- wslua_proto.c 2010-04-19 03:26:39.312418600 +1000 +++ wslua_proto_mod.c 2010-04-19 22:10:49.668167100 +1000 @@ -35,74 +35,74 @@ static range_t* get_range(lua_State *L, int idx_r, int idx_m) { - static range_t *ret; + static range_t *ret; range_convert_str(&ret,g_strdup(lua_tostring(L, idx_r)),(guint32)lua_tonumber(L, idx_m)); - return ret; + return ret; } static enum_val_t* get_enum(lua_State *L, int idx) { - double seq; - const gchar *str1, *str2; - enum_val_t *ret, last = {NULL, NULL, -1}; - GArray* es = g_array_new(TRUE,TRUE,sizeof(enum_val_t)); + double seq; + const gchar *str1, *str2; + enum_val_t *ret, last = {NULL, NULL, -1}; + GArray* es = g_array_new(TRUE,TRUE,sizeof(enum_val_t)); - luaL_checktype(L, idx, LUA_TTABLE); - lua_pushnil(L); /* first key */ + luaL_checktype(L, idx, LUA_TTABLE); + lua_pushnil(L); /* first key */ - while (lua_next(L, idx)) { - enum_val_t e = {NULL, NULL, -1}; + while (lua_next(L, idx)) { + enum_val_t e = {NULL, NULL, -1}; - luaL_checktype(L, -1, LUA_TTABLE); - lua_pushnil(L); - lua_next(L, -2); - if (! lua_isstring(L,-1)) { - luaL_argerror(L,idx,"First value of an enum table must be string"); - g_array_free(es,TRUE); - return NULL; - } - str1 = lua_tostring(L, -1); - - lua_pop(L, 1); - lua_next(L, -2); - if (! lua_isstring(L,-1)) { - luaL_argerror(L,idx,"Second value of an enum table must be string"); - g_array_free(es,TRUE); - return NULL; - } - str2 = lua_tostring(L, -1); - - lua_pop(L, 1); - lua_next(L, -2); - if (! lua_isnumber(L,-1)) { - luaL_argerror(L,idx,"Third value of an enum table must be an integer"); - g_array_free(es,TRUE); - return NULL; + luaL_checktype(L, -1, LUA_TTABLE); + lua_pushnil(L); + lua_next(L, -2); + if (! lua_isstring(L,-1)) { + luaL_argerror(L,idx,"First value of an enum table must be string"); + g_array_free(es,TRUE); + return NULL; + } + str1 = lua_tostring(L, -1); + + lua_pop(L, 1); + lua_next(L, -2); + if (! lua_isstring(L,-1)) { + luaL_argerror(L,idx,"Second value of an enum table must be string"); + g_array_free(es,TRUE); + return NULL; + } + str2 = lua_tostring(L, -1); + + lua_pop(L, 1); + lua_next(L, -2); + if (! lua_isnumber(L,-1)) { + luaL_argerror(L,idx,"Third value of an enum table must be an integer"); + g_array_free(es,TRUE); + return NULL; + } + seq = lua_tonumber(L, -1); + + e.name = g_strdup(str1); + e.description = g_strdup(str2); + e.value = (guint32)seq; + + g_array_append_val(es,e); + + lua_pop(L, 3); /* removes 'value'; keeps 'key' for next iteration */ } - seq = lua_tonumber(L, -1); - e.name = g_strdup(str1); - e.description = g_strdup(str2); - e.value = (guint32)seq; - - g_array_append_val(es,e); - - lua_pop(L, 3); /* removes 'value'; keeps 'key' for next iteration */ - } - - g_array_append_val(es,last); - - ret = (enum_val_t*)es->data; + g_array_append_val(es,last); + + ret = (enum_val_t*)es->data; - g_array_free(es,FALSE); + g_array_free(es,FALSE); - return ret; + return ret; } 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(wslua_pref_t)); pref->name = NULL; pref->label = label ? g_strdup(label) : NULL; @@ -110,7 +110,7 @@ pref->type = type; pref->next = NULL; pref->proto = NULL; - + switch(type) { case PREF_BOOL: { gboolean def = lua_toboolean(L,2); @@ -155,11 +155,10 @@ pushPref(L,pref); return 1; - } WSLUA_CONSTRUCTOR Pref_bool(lua_State* L) { - /* Creates a boolean preference to be added to a Protocol's prefs table. */ + /* Creates a boolean preference to be added to a Protocol's prefs table. */ #define WSLUA_ARG_Pref_bool_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */ #define WSLUA_ARG_Pref_bool_DEFAULT 2 /* The default value for this preference */ #define WSLUA_ARG_Pref_bool_DESCR 3 /* A description of what this preference is */ @@ -167,7 +166,7 @@ } WSLUA_CONSTRUCTOR Pref_uint(lua_State* L) { - /* Creates an (unsigned) integer preference to be added to a Protocol's prefs table. */ + /* Creates an (unsigned) integer preference to be added to a Protocol's prefs table. */ #define WSLUA_ARG_Pref_uint_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */ #define WSLUA_ARG_Pref_uint_DEFAULT 2 /* The default value for this preference */ #define WSLUA_ARG_Pref_uint_DESCR 3 /* A description of what this preference is */ @@ -175,7 +174,7 @@ } WSLUA_CONSTRUCTOR Pref_string(lua_State* L) { - /* Creates a string preference to be added to a Protocol's prefs table. */ + /* Creates a string preference to be added to a Protocol's prefs table. */ #define WSLUA_ARG_Pref_string_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */ #define WSLUA_ARG_Pref_string_DEFAULT 2 /* The default value for this preference */ #define WSLUA_ARG_Pref_string_DESCR 3 /* A description of what this preference is */ @@ -183,7 +182,7 @@ } WSLUA_CONSTRUCTOR Pref_enum(lua_State* L) { - /* Creates an enum preference to be added to a Protocol's prefs table. */ + /* Creates an enum preference to be added to a Protocol's prefs table. */ #define WSLUA_ARG_Pref_enum_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */ #define WSLUA_ARG_Pref_enum_DEFAULT 2 /* The default value for this preference */ #define WSLUA_ARG_Pref_enum_DESCR 3 /* A description of what this preference is */ @@ -193,7 +192,7 @@ } WSLUA_CONSTRUCTOR Pref_range(lua_State* L) { - /* Creates a range preference to be added to a Protocol's prefs table. */ + /* Creates a range preference to be added to a Protocol's prefs table. */ #define WSLUA_ARG_Pref_range_LABEL 1 /* The Label (text in the right side of the preference input) for this preference */ #define WSLUA_ARG_Pref_range_DEFAULT 2 /* The default value for this preference */ #define WSLUA_ARG_Pref_range_DESCR 3 /* A description of what this preference is */ @@ -203,7 +202,7 @@ } WSLUA_CONSTRUCTOR Pref_statictext(lua_State* L) { - /* Creates a static text preference to be added to a Protocol's prefs table. */ + /* Creates a static text preference to be added to a Protocol's prefs table. */ #define WSLUA_ARG_Pref_statictext_LABEL 1 /* The static text */ #define WSLUA_ARG_Pref_statictext_DESCR 2 /* The static text description */ return new_pref(L,PREF_STATIC_TEXT); @@ -211,7 +210,7 @@ static int Pref_gc(lua_State* L) { Pref pref = checkPref(L,1); - + if (pref && ! pref->name) { g_free(pref->label); g_free(pref->desc); @@ -219,7 +218,7 @@ g_free((void*)pref->value.s); g_free(pref); } - + return 0; } @@ -247,7 +246,7 @@ WSLUA_CLASS_DEFINE(Prefs,NOP,NOP); /* The table of preferences of a protocol */ WSLUA_METAMETHOD Prefs__newindex(lua_State* L) { - /* Creates a new preference */ + /* Creates a new preference */ #define WSLUA_ARG_Prefs__newindex_NAME 2 /* The abbreviation of this preference */ #define WSLUA_ARG_Prefs__newindex_PREF 3 /* A valid but still unassigned Pref object */ @@ -264,7 +263,7 @@ if (! pref ) WSLUA_ARG_ERROR(Prefs__newindex,PREF,"must be a valid Pref"); - + if (pref->name) WSLUA_ARG_ERROR(Prefs__newindex,NAME,"cannot change existing preference"); @@ -272,38 +271,36 @@ WSLUA_ARG_ERROR(Prefs__newindex,PREF,"cannot be added to more than one protocol"); p = prefs_p; - + do { if ( p->name && g_str_equal(p->name,name) ) { luaL_error(L,"a preference named %s exists already",name); return 0; } - /* + /* * Make sure that only lower-case ASCII letters, numbers, * underscores, and dots appear in the preference name. - */ - for (c = name; *c != '\0'; c++) { - if (!isascii((guchar)*c) || - (!islower((guchar)*c) && !isdigit((guchar)*c) && *c != '_' && *c != '.')) - { - luaL_error(L,"illegal preference name \"%s\", only lower-case ASCII letters, numbers, underscores and dots may be used",name); - return 0; - } - } - + */ + for (c = name; *c != '\0'; c++) { + if (!isascii((guchar)*c) || + (!islower((guchar)*c) && !isdigit((guchar)*c) && *c != '_' && *c != '.')) + { + luaL_error(L,"illegal preference name \"%s\", only lower-case ASCII letters, numbers, underscores and dots may be used",name); + return 0; + } + } + if ( ! p->next) { p->next = pref; - pref->name = g_strdup(name); - + if (!pref->label) pref->label = g_strdup(name); if (!prefs_p->proto->prefs_module) { prefs_p->proto->prefs_module = prefs_register_protocol(prefs_p->proto->hfid, NULL); - } - + switch(pref->type) { case PREF_BOOL: prefs_register_bool_preference(prefs_p->proto->prefs_module, @@ -353,29 +350,29 @@ default: WSLUA_ERROR(Prefs__newindex,"Unknow Pref type"); } - + pref->proto = p->proto; - + WSLUA_RETURN(0); } } while (( p = p->next )); luaL_error(L,"this should not happen!"); - + WSLUA_RETURN(0); } WSLUA_METAMETHOD Prefs__index(lua_State* L) { - /* Get the value of a preference setting */ + /* Get the value of a preference setting */ #define WSLUA_ARG_Prefs__index_NAME 2 /* The abbreviation of this preference */ Pref prefs_p = checkPrefs(L,1); const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__index_NAME); - + if (! ( name && prefs_p ) ) return 0; - + prefs_p = prefs_p->next; - + do { if ( g_str_equal(prefs_p->name,name) ) { switch (prefs_p->type) { @@ -405,36 +402,35 @@ return 1; } - WSLUA_CLASS_DEFINE(ProtoField,FAIL_ON_NULL("null ProtoField"),NOP); - /* A Protocol field (to be used when adding items to the dissection tree) */ + /* A Protocol field (to be used when adding items to the dissection tree) */ static const wslua_ft_types_t ftenums[] = { -{"FT_BOOLEAN",FT_BOOLEAN}, -{"FT_UINT8",FT_UINT8}, -{"FT_UINT16",FT_UINT16}, -{"FT_UINT24",FT_UINT24}, -{"FT_UINT32",FT_UINT32}, -{"FT_UINT64",FT_UINT64}, -{"FT_INT8",FT_INT8}, -{"FT_INT16",FT_INT16}, -{"FT_INT24",FT_INT24}, -{"FT_INT32",FT_INT32}, -{"FT_INT64",FT_INT64}, -{"FT_FLOAT",FT_FLOAT}, -{"FT_DOUBLE",FT_DOUBLE}, -{"FT_STRING",FT_STRING}, -{"FT_STRINGZ",FT_STRINGZ}, -{"FT_ETHER",FT_ETHER}, -{"FT_BYTES",FT_BYTES}, -{"FT_UINT_BYTES",FT_UINT_BYTES}, -{"FT_IPv4",FT_IPv4}, -{"FT_IPv6",FT_IPv6}, -{"FT_IPXNET",FT_IPXNET}, -{"FT_FRAMENUM",FT_FRAMENUM}, -{"FT_GUID",FT_GUID}, -{"FT_OID",FT_OID}, -{NULL,FT_NONE} + {"FT_BOOLEAN",FT_BOOLEAN}, + {"FT_UINT8",FT_UINT8}, + {"FT_UINT16",FT_UINT16}, + {"FT_UINT24",FT_UINT24}, + {"FT_UINT32",FT_UINT32}, + {"FT_UINT64",FT_UINT64}, + {"FT_INT8",FT_INT8}, + {"FT_INT16",FT_INT16}, + {"FT_INT24",FT_INT24}, + {"FT_INT32",FT_INT32}, + {"FT_INT64",FT_INT64}, + {"FT_FLOAT",FT_FLOAT}, + {"FT_DOUBLE",FT_DOUBLE}, + {"FT_STRING",FT_STRING}, + {"FT_STRINGZ",FT_STRINGZ}, + {"FT_ETHER",FT_ETHER}, + {"FT_BYTES",FT_BYTES}, + {"FT_UINT_BYTES",FT_UINT_BYTES}, + {"FT_IPv4",FT_IPv4}, + {"FT_IPv6",FT_IPv6}, + {"FT_IPXNET",FT_IPXNET}, + {"FT_FRAMENUM",FT_FRAMENUM}, + {"FT_GUID",FT_GUID}, + {"FT_OID",FT_OID}, + {NULL,FT_NONE} }; static enum ftenum get_ftenum(const gchar* type) { @@ -444,7 +440,6 @@ return ts->id; } } - return FT_NONE; } @@ -455,7 +450,6 @@ return ts->str; } } - return NULL; } @@ -471,6 +465,11 @@ {"BASE_OCT", BASE_OCT}, {"BASE_DEC_HEX", BASE_DEC_HEX}, {"BASE_HEX_DEC", BASE_HEX_DEC}, + /* for FT_BOOLEAN, how wide the parent bitfield is */ + {"8",8}, + {"16",16}, + {"24",24}, + {"32",32}, {NULL,0} }; @@ -495,7 +494,7 @@ static value_string* value_string_from_table(lua_State* L, int idx) { GArray* vs = g_array_new(TRUE,TRUE,sizeof(value_string)); value_string* ret; - + if(lua_isnil(L,idx)) { return NULL; } else if (!lua_istable(L,idx)) { @@ -503,97 +502,150 @@ g_array_free(vs,TRUE); return NULL; } - + lua_pushnil(L); - + while (lua_next(L, idx) != 0) { value_string v = {0,NULL}; - + if (! lua_isnumber(L,-2)) { - luaL_argerror(L,idx,"All keys of a table used as vaalue_string must be integers"); + luaL_argerror(L,idx,"All keys of a table used as value_string must be integers"); g_array_free(vs,TRUE); return NULL; } - + if (! lua_isstring(L,-1)) { - luaL_argerror(L,idx,"All values of a table used as vaalue_string must be strings"); + luaL_argerror(L,idx,"All values of a table used as value_string must be strings"); g_array_free(vs,TRUE); return NULL; } - + v.value = (guint32)lua_tonumber(L,-2); v.strptr = g_strdup(lua_tostring(L,-1)); - + g_array_append_val(vs,v); - + lua_pop(L, 1); } - + ret = (value_string*)vs->data; - + g_array_free(vs,FALSE); return ret; - -} +} + +static true_false_string* true_false_string_from_table(lua_State* L, int idx) { + GArray* tfs = g_array_new(TRUE,TRUE,sizeof(true_false_string)); + true_false_string* ret; + true_false_string tf = { "True", "False" }; + + if (lua_isnil(L,idx)) { + return NULL; + } else if (!lua_istable(L,idx)) { + luaL_argerror(L,idx,"must be a table"); + g_array_free(tfs,TRUE); + return NULL; + } + + lua_pushnil(L); + + while (lua_next(L, idx)) { + + if (! lua_isnumber(L,-2)) { + luaL_argerror(L,idx,"All keys of a table used as true_false_string must be integers"); + g_array_free(tfs,TRUE); + return NULL; + } + + if (! lua_isstring(L,-1)) { + luaL_argerror(L,idx,"All values of a table used as true_false_string must be strings"); + g_array_free(tfs,TRUE); + return NULL; + } + + /* arrays in LUA start with index number 1 */ + if ((guint32)lua_tonumber(L,-2) == 1) + tf.true_string = strdup(lua_tostring(L,-1)); + + if ((guint32)lua_tonumber(L,-2) == 2) + tf.false_string = strdup(lua_tostring(L,-1)); + + lua_pop(L, 1); + } + + g_array_append_val(tfs,tf); + + ret = (true_false_string*)tfs->data; + + g_array_free(tfs,FALSE); + + return ret; +} WSLUA_CONSTRUCTOR ProtoField_new(lua_State* L) { /* Creates a new field to be used in a protocol. */ #define WSLUA_ARG_ProtoField_new_NAME 1 /* Actual name of the field (the string that appears in the tree). */ #define WSLUA_ARG_ProtoField_new_ABBR 2 /* Filter name of the field (the string that is used in filters). */ #define WSLUA_ARG_ProtoField_new_TYPE 3 /* Field Type (FT_*). */ -#define WSLUA_OPTARG_ProtoField_new_VALUESTRING 4 /* A ValueString object. */ +#define WSLUA_OPTARG_ProtoField_new_VOIDSTRING 4 /* A VoidString object. */ #define WSLUA_OPTARG_ProtoField_new_BASE 5 /* The representation BASE_*. */ #define WSLUA_OPTARG_ProtoField_new_MASK 6 /* The bitmask to be used. */ #define WSLUA_OPTARG_ProtoField_new_DESCR 7 /* The description of the field. */ ProtoField f = g_malloc(sizeof(wslua_field_t)); value_string* vs; + true_false_string* tfs; const gchar *blob; - + /* 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->ett = -1; f->name = g_strdup(luaL_checkstring(L,WSLUA_ARG_ProtoField_new_NAME)); f->abbr = g_strdup(luaL_checkstring(L,WSLUA_ARG_ProtoField_new_ABBR)); f->type = get_ftenum(luaL_checkstring(L,WSLUA_ARG_ProtoField_new_TYPE)); - + /*XXX do it better*/ if (f->type == FT_NONE) { WSLUA_ARG_ERROR(ProtoField_new,TYPE,"invalid FT_type"); return 0; } - - if (! lua_isnil(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING) ) { - vs = value_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING); - + + if (! lua_isnil(L,WSLUA_OPTARG_ProtoField_new_VOIDSTRING) ) { + if (f->type == FT_BOOLEAN) { + tfs = true_false_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VOIDSTRING); + } + else { + vs = value_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VOIDSTRING); + } + if (vs) { - f->vs = vs; + f->vs = VALS(vs); + } else if (tfs) { + f->vs = TFS(tfs); } else { g_free(f); return 0; } - - + } else { f->vs = NULL; } - + /* XXX: need BASE_ERROR */ f->base = string_to_base(luaL_optstring(L, WSLUA_OPTARG_ProtoField_new_BASE, "BASE_NONE")); f->mask = luaL_optint(L, WSLUA_OPTARG_ProtoField_new_MASK, 0x0); blob = luaL_optstring(L,WSLUA_OPTARG_ProtoField_new_DESCR,NULL); if (blob && strcmp(blob, f->name) != 0) { - f->blob = g_strdup(blob); + f->blob = g_strdup(blob); } else { - f->blob = NULL; + f->blob = NULL; } pushProtoField(L,f); - + WSLUA_RETURN(1); /* The newly created ProtoField object */ } - static int ProtoField_integer(lua_State* L, enum ftenum type) { ProtoField f = g_malloc(sizeof(wslua_field_t)); const gchar* abbr = luaL_checkstring(L,1); @@ -614,17 +666,17 @@ f->name = g_strdup(name); f->abbr = g_strdup(abbr); f->type = type; - f->vs = vs; + f->vs = VALS(vs); f->base = base; f->mask = mask; if (blob && strcmp(blob, f->name) != 0) { - f->blob = g_strdup(blob); + f->blob = g_strdup(blob); } else { - f->blob = NULL; + f->blob = NULL; } - + pushProtoField(L,f); - + return 1; } @@ -740,12 +792,65 @@ PROTOFIELD_INTEGER(int64,FT_INT64) PROTOFIELD_INTEGER(framenum,FT_FRAMENUM) +static int ProtoField_boolean(lua_State* L, enum ftenum type) { + ProtoField f = g_malloc(sizeof(wslua_field_t)); + const gchar* abbr = luaL_checkstring(L,1); + const gchar* name = luaL_optstring(L,2,abbr); + base_display_e base = luaL_optint(L, 3, BASE_NONE); + true_false_string* tfs = (lua_gettop(L) > 3) ? true_false_string_from_table(L,4) : NULL; + int mask = luaL_optint(L, 5, 0x0); + const gchar* blob = luaL_optstring(L,6,""); + + if ((mask == 0x0 || mask == 0) && base != BASE_NONE) { + luaL_argerror(L,2,"Fieldbase (fielddisplay) must be BASE_NONE" + " if bitmask is 0x0 or 0."); + return 0; + } + + if ((mask != 0x0 || mask != 0) && (base < 1 || base > 64)) { + luaL_argerror(L,2,"Fieldbase (fielddisplay) must be between 1 and 64" + " if bitmask is non-zero (neither 0x0 nor 0)."); + return 0; + } + + f->hfid = -2; + f->ett = -1; + f->name = g_strdup(name); + f->abbr = g_strdup(abbr); + f->type = type; + f->vs = TFS(tfs); + f->base = base; + f->mask = mask; + if (blob && strcmp(blob, f->name) != 0) { + f->blob = g_strdup(blob); + } else { + f->blob = NULL; + } + + pushProtoField(L,f); + + return 1; +} + +#define PROTOFIELD_BOOL(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_boolean(L,FT); } +/* _WSLUA_CONSTRUCTOR_ ProtoField_bool */ +/* WSLUA_ARG_Protofield_bool_ABBR Abbreviated name of the field (the string used in filters) */ +/* WSLUA_OPTARG_Protofield_bool_NAME Actual name of the field (the string that appears in the tree) */ +/* WSLUA_OPTARG_Protofield_bool_DISPLAY how wide the parent bitfield is (BASE_NONE is used for NULL-value) */ +/* WSLUA_OPTARG_Protofield_bool_TRUE_FALSE_STRING A table containing the text that corresponds to the values */ +/* WSLUA_OPTARG_Protofield_bool_MASK Integer mask of this field */ +/* WSLUA_OPTARG_Protofield_bool_DESC Description of the field */ +/* _WSLUA_RETURNS_ A protofield item to be added to a ProtoFieldArray */ + +/* XXX: T/F strings */ +PROTOFIELD_BOOL(bool,FT_BOOLEAN) + static int ProtoField_other(lua_State* L,enum ftenum type) { ProtoField f = g_malloc(sizeof(wslua_field_t)); const gchar* abbr = luaL_checkstring(L,1); const gchar* name = luaL_optstring(L,2,abbr); const gchar* blob = luaL_optstring(L,3,NULL); - + f->hfid = -2; f->ett = -1; f->name = g_strdup(name); @@ -759,9 +864,9 @@ } else { f->blob = NULL; } - + pushProtoField(L,f); - + return 1; } @@ -851,17 +956,11 @@ PROTOFIELD_OTHER(guid,FT_GUID) PROTOFIELD_OTHER(oid,FT_OID) -/* XXX: T/F strings */ -PROTOFIELD_OTHER(bool,FT_BOOLEAN) - - WSLUA_METAMETHOD ProtoField_tostring(lua_State* L) { - /* Returns a string w/ info about a protofiled (for debugging purposes) */ + /* Returns a string w/ info about a protofiled (for debugging purposes) */ ProtoField f = checkProtoField(L,1); - gchar* s = ep_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),(void *)f->vs,f->mask,f->blob); - + gchar* s = ep_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); - return 1; } @@ -875,7 +974,7 @@ * 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() ?? */ @@ -885,11 +984,10 @@ g_free(f->blob); g_free(f); } - + return 0; } - static const luaL_reg ProtoField_methods[] = { {"new", ProtoField_new}, {"uint8",ProtoField_uint8}, @@ -927,7 +1025,6 @@ int ProtoField_register(lua_State* L) { WSLUA_REGISTER_CLASS(ProtoField); - return 1; } @@ -945,7 +1042,7 @@ #define WSLUA_ARG_Proto_new_DESC 2 /* A Long Text description of the protocol (usually lowercase) */ const gchar* name = luaL_checkstring(L,WSLUA_ARG_Proto_new_NAME); const gchar* desc = luaL_checkstring(L,WSLUA_ARG_Proto_new_DESC); - + if ( name ) { gchar* loname_a = ep_strdup(name); g_strdown(loname_a); @@ -964,29 +1061,29 @@ proto->hfid = proto_register_protocol(proto->desc,hiname,loname); proto->ett = -1; proto->is_postdissector = FALSE; - + lua_newtable (L); proto->fields = luaL_ref(L, LUA_REGISTRYINDEX); - + 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->prefs_module = NULL; proto->handle = NULL; - + lua_rawgeti(L, LUA_REGISTRYINDEX, protocols_table_ref); lua_pushstring(L,loname); pushProto(L,proto); lua_settable(L, -3); - + pushProto(L,proto); - + WSLUA_RETURN(1); /* The newly created protocol */ } } else { @@ -996,43 +1093,40 @@ return 0; } - - static int Proto_tostring(lua_State* L) { Proto proto = checkProto(L,1); gchar* s; - + if (!proto) return 0; - + s = ep_strdup_printf("Proto: %s",proto->name); lua_pushstring(L,s); - + return 1; } WSLUA_FUNCTION wslua_register_postdissector(lua_State* L) { - /* Make a protocol (with a dissector) a postdissector. It will be called for every frame after dissection */ + /* Make a protocol (with a dissector) a postdissector. It will be called for every frame after dissection */ #define WSLUA_ARG_register_postdissector_PROTO 1 /* the protocol to be used as postdissector */ Proto proto = checkProto(L,WSLUA_ARG_register_postdissector_PROTO); if (!proto) return 0; - + if(!proto->is_postdissector) { if (! proto->handle) { proto->handle = new_create_dissector_handle(dissect_lua, proto->hfid); } - + register_postdissector(proto->handle); } else { luaL_argerror(L,1,"this protocol is already registered as postdissector"); } - + return 0; } - static int Proto_get_dissector(lua_State* L) { Proto proto = toProto(L,1); - + if (proto->handle) { pushDissector(L,proto->handle); return 1; @@ -1042,7 +1136,6 @@ } } - static int Proto_set_dissector(lua_State* L) { Proto proto = toProto(L,1); @@ -1056,11 +1149,11 @@ lua_pushstring(L,proto->name); lua_replace(L, 2); lua_settable(L,1); - + proto->handle = new_create_dissector_handle(dissect_lua, proto->hfid); - + new_register_dissector(loname, dissect_lua, proto->hfid); - + return 0; } else { luaL_argerror(L,3,"The dissector of a protocol must be a function"); @@ -1070,14 +1163,13 @@ static int Proto_get_prefs(lua_State* L) { Proto proto = toProto(L,1); - pushPrefs(L,&proto->prefs); return 1; } static int Proto_set_init(lua_State* L) { Proto proto = toProto(L,1); - + if (lua_isfunction(L,3)) { /* insert the dissector into the dissectors table */ lua_pushstring(L, WSLUA_INIT_ROUTINES); @@ -1086,22 +1178,20 @@ 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; - } + } } static int Proto_get_name(lua_State* L) { Proto proto = toProto(L,1); - lua_pushstring(L,proto->name); return 1; } - static int Proto_get_fields(lua_State* L) { Proto proto = toProto(L,1); lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields); @@ -1126,7 +1216,6 @@ lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields); lua_replace(L,FIELDS_TABLE); - if( lua_istable(L,NEW_TABLE)) { for (lua_pushnil(L); lua_next(L, NEW_TABLE); ) { if (isProtoField(L,5)) { @@ -1142,14 +1231,12 @@ } else { return luaL_error(L,"either a ProtoField or an array of protofields"); } - + lua_pushvalue(L, 3); - + return 1; } - - typedef struct { gchar* name; lua_CFunction get; @@ -1157,19 +1244,19 @@ } proto_actions_t; static const proto_actions_t proto_actions[] = { - /* WSLUA_ATTRIBUTE Proto_dissector RW The protocol's dissector, a function you define */ + /* WSLUA_ATTRIBUTE Proto_dissector RW The protocol's dissector, a function you define */ {"dissector",Proto_get_dissector, Proto_set_dissector}, - /* WSLUA_ATTRIBUTE Proto_fields RO The Fields Table of this dissector */ + /* WSLUA_ATTRIBUTE Proto_fields RO The Fields Table of this dissector */ {"fields" ,Proto_get_fields, Proto_set_fields}, - - /* WSLUA_ATTRIBUTE Proto_prefs RO The preferences of this dissector */ + + /* WSLUA_ATTRIBUTE Proto_prefs RO The preferences of this dissector */ {"prefs",Proto_get_prefs,NULL}, - /* WSLUA_ATTRIBUTE Proto_init WO The init routine of this dissector, a function you define */ + /* WSLUA_ATTRIBUTE Proto_init WO The init routine of this dissector, a function you define */ {"init",NULL,Proto_set_init}, - /* WSLUA_ATTRIBUTE Proto_name RO The name given to this dissector */ + /* WSLUA_ATTRIBUTE Proto_name RO The name given to this dissector */ {"name",Proto_get_name,NULL}, {NULL,NULL,NULL} }; @@ -1178,9 +1265,9 @@ Proto proto = checkProto(L,1); const gchar* name = luaL_checkstring(L,2); const proto_actions_t* pa; - + if (! (proto && name) ) return 0; - + for (pa = proto_actions; pa->name; pa++) { if ( g_str_equal(name,pa->name) ) { if (pa->get) { @@ -1196,14 +1283,13 @@ return 0; } - static int Proto_newindex(lua_State* L) { Proto proto = checkProto(L,1); const gchar* name = luaL_checkstring(L,2); const proto_actions_t* pa; - + if (! (proto && name) ) return 0; - + for (pa = proto_actions; pa->name; pa++) { if ( g_str_equal(name,pa->name) ) { if (pa->set) { @@ -1214,7 +1300,7 @@ } } } - + luaL_error(L,"A protocol doesn't have a `%s' attribute",name); return 0; } @@ -1236,24 +1322,24 @@ lua_pushstring(L, "Proto"); lua_pushcfunction(L, Proto_new); lua_settable(L, LUA_GLOBALSINDEX); - + Pref_register(L); Prefs_register(L); - + return 1; } int Proto_commit(lua_State* L) { lua_settop(L,0); lua_rawgeti(L, LUA_REGISTRYINDEX, protocols_table_ref); - + for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 2)) { GArray* hfa = g_array_new(TRUE,TRUE,sizeof(hf_register_info)); GArray* etta = g_array_new(TRUE,TRUE,sizeof(gint*)); Proto proto; /* const gchar* proto_name = lua_tostring(L,2); */ proto = checkProto(L,3); - + lua_rawgeti(L, LUA_REGISTRYINDEX, proto->fields); for (lua_pushnil(L); lua_next(L, 4); lua_pop(L, 1)) { @@ -1264,49 +1350,45 @@ if (f->hfid != -2) { return luaL_error(L,"fields can be registered only once"); } - + f->hfid = -1; g_array_append_val(hfa,hfri); g_array_append_val(etta,ettp); } - + proto_register_field_array(proto->hfid,(hf_register_info*)hfa->data,hfa->len); proto_register_subtree_array((gint**)etta->data,etta->len); - + g_array_free(hfa,FALSE); g_array_free(etta,FALSE); } - + return 0; } - - WSLUA_CLASS_DEFINE(Dissector,NOP,NOP); /* A refererence to a dissector, used to call a dissector against a packet or a part of it. */ - WSLUA_CONSTRUCTOR Dissector_get (lua_State *L) { - /* Obtains a dissector reference by name */ + /* Obtains a dissector reference by name */ #define WSLUA_ARG_Dissector_get_NAME 1 /* The name of the dissector */ const gchar* name = luaL_checkstring(L,WSLUA_ARG_Dissector_get_NAME); Dissector d; - + if (!name) WSLUA_ARG_ERROR(Dissector_get,NAME,"must be a string"); - + if ((d = find_dissector(name))) { pushDissector(L, d); WSLUA_RETURN(1); /* The Dissector reference */ } else WSLUA_ARG_ERROR(Dissector_get,NAME,"No such dissector"); - } WSLUA_METHOD Dissector_call(lua_State* L) { - /* Calls a dissector against a given packet (or part of it) */ + /* Calls a dissector against a given packet (or part of it) */ #define WSLUA_ARG_Dissector_call_TVB 2 /* The buffer to dissect */ #define WSLUA_ARG_Dissector_call_PINFO 3 /* The packet info */ #define WSLUA_ARG_Dissector_call_TREE 4 /* The tree on which to add the protocol items */ @@ -1318,7 +1400,7 @@ char* error = NULL; if (! ( d && tvb && pinfo) ) return 0; - + TRY { call_dissector(d, tvb->ws_tvb, pinfo->ws_pinfo, ti->tree); /* XXX Are we sure about this??? is this the right/only thing to catch */ @@ -1332,7 +1414,6 @@ return 0; } - WSLUA_METAMETHOD Dissector_tostring(lua_State* L) { Dissector d = checkDissector(L,1); if (!d) return 0; @@ -1356,7 +1437,6 @@ return 1; } - WSLUA_CLASS_DEFINE(DissectorTable,NOP,NOP); /* A table of subdissectors of a particular protocol (e.g. TCP subdissectors like http, smtp, sip are added to table "tcp.port"). @@ -1364,7 +1444,7 @@ */ WSLUA_CONSTRUCTOR DissectorTable_new (lua_State *L) { - /* Creates a new DissectorTable for your dissector's use. */ + /* Creates a new DissectorTable for your dissector's use. */ #define WSLUA_ARG_DissectorTable_new_TABLENAME 1 /* The short name of the table. */ #define WSLUA_OPTARG_DissectorTable_new_UINAME 2 /* The name of the table in the User Interface (defaults to the name given). */ #define WSLUA_OPTARG_DissectorTable_new_TYPE 3 /* Either FT_UINT* or FT_STRING (defaults to FT_UINT32) */ @@ -1373,12 +1453,12 @@ gchar* ui_name = (void*)luaL_optstring(L,WSLUA_OPTARG_DissectorTable_new_UINAME,name); enum ftenum type = luaL_optint(L,WSLUA_OPTARG_DissectorTable_new_TYPE,FT_UINT32); base_display_e base = luaL_optint(L,WSLUA_OPTARG_DissectorTable_new_BASE,BASE_DEC); - + if(!(name && ui_name)) return 0; - + name = g_strdup(name); ui_name = g_strdup(ui_name); - + switch(type) { case FT_STRING: base = BASE_NONE; @@ -1388,7 +1468,7 @@ case FT_UINT32: { DissectorTable dt = g_malloc(sizeof(struct _wslua_distbl_t)); - + dt->table = register_dissector_table(name, ui_name, type, base); dt->name = name; pushDissectorTable(L, dt); @@ -1397,39 +1477,38 @@ default: WSLUA_OPTARG_ERROR(DissectorTable_new,TYPE,"must be FTUINT* or FT_STRING"); } - return 0; + return 0; } WSLUA_CONSTRUCTOR DissectorTable_get (lua_State *L) { - /* - Obtain a reference to an existing dissector table. - */ + /* + Obtain a reference to an existing dissector table. + */ #define WSLUA_ARG_DissectorTable_get_TABLENAME 1 /* The short name of the table. */ const gchar* name = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_TABLENAME); dissector_table_t table; - + if(!name) return 0; - + table = find_dissector_table(name); - + if (table) { DissectorTable dt = g_malloc(sizeof(struct _wslua_distbl_t)); dt->table = table; dt->name = g_strdup(name); - + pushDissectorTable(L, dt); - + WSLUA_RETURN(1); /* The DissectorTable */ } else WSLUA_ARG_ERROR(DissectorTable_get,TABLENAME,"no such dissector_table"); - -} +} WSLUA_METHOD DissectorTable_add (lua_State *L) { - /* - Add a dissector to a table. - */ + /* + Add a dissector to a table. + */ #define WSLUA_ARG_DissectorTable_add_PATTERN 2 /* The pattern to match (either an integer or a string depending on the table's type). */ #define WSLUA_ARG_DissectorTable_add_DISSECTOR 3 /* The dissector to add (either an Proto or a Dissector). */ @@ -1443,17 +1522,17 @@ Proto p; p = toProto(L,WSLUA_ARG_DissectorTable_add_DISSECTOR); handle = p->handle; - + if (! handle) WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"a Protocol that does not have a dissector cannot be added to a table"); - + } else if ( isDissector(L,WSLUA_ARG_DissectorTable_add_DISSECTOR) ) { handle = toDissector(L,WSLUA_ARG_DissectorTable_add_DISSECTOR); } else WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"must be either Proto or Dissector"); - + type = get_dissector_table_selector_type(dt->name); - + if (type == FT_STRING) { gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN)); dissector_add_string(dt->name, pattern,handle); @@ -1463,34 +1542,34 @@ } else { luaL_error(L,"Strange type %d for a DissectorTable",type); } - + return 0; } WSLUA_METHOD DissectorTable_remove (lua_State *L) { - /* - Remove a dissector from a table - */ + /* + Remove a dissector from a table + */ #define WSLUA_ARG_DissectorTable_remove_PATTERN 2 /* The pattern to match (either an integer or a string depending on the table's type). */ #define WSLUA_ARG_DissectorTable_remove_DISSECTOR 3 /* The dissector to add (either an Proto or a Dissector). */ DissectorTable dt = checkDissectorTable(L,1); ftenum_t type; Dissector handle; - + if (!dt) return 0; - + if( isProto(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR) ) { Proto p; p = toProto(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR); handle = p->handle; - + } else if ( isDissector(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR) ) { handle = toDissector(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR); } else WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"must be either Proto or Dissector"); - + 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,handle); @@ -1498,15 +1577,14 @@ int port = luaL_checkint(L, 2); dissector_delete(dt->name, port, handle); } - + return 0; } - WSLUA_METHOD DissectorTable_try (lua_State *L) { - /* - Try to call a dissector from a table - */ + /* + Try to call a dissector from a table + */ #define WSLUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */ #define WSLUA_ARG_DissectorTable_try_TVB 3 /* The buffer to dissect */ #define WSLUA_ARG_DissectorTable_try_PINFO 4 /* The packet info */ @@ -1519,31 +1597,31 @@ gchar* error = NULL; if (! (dt && tvb && tvb->ws_tvb && pinfo && ti) ) return 0; - + type = get_dissector_table_selector_type(dt->name); - + TRY { - + if (type == FT_STRING) { const gchar* pattern = luaL_checkstring(L,2); - + if (!pattern) return 0; - + if (dissector_try_string(dt->table,pattern,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree)) return 0; - + } 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->ws_tvb,pinfo->ws_pinfo,ti->tree)) return 0; - + } else { luaL_error(L,"No such type of dissector_table"); } - + call_dissector(lua_data_handle,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree); - + /* XXX Are we sure about this??? is this the right/only thing to catch */ } CATCH(ReportedBoundsError) { proto_tree_add_protocol_format(lua_tree->tree, lua_malformed, lua_tvb, 0, 0, "[Malformed Frame: Packet Length]" ); @@ -1556,19 +1634,19 @@ } WSLUA_METHOD DissectorTable_get_dissector (lua_State *L) { - /* - Try to obtain a dissector from a table. - */ + /* + Try to obtain a dissector from a table. + */ #define WSLUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */ DissectorTable dt = checkDissectorTable(L,1); ftenum_t type; dissector_handle_t handle = lua_data_handle; - + if (!dt) return 0; - + type = get_dissector_table_selector_type(dt->name); - + if (type == FT_STRING) { const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_try_PATTERN); @@ -1579,7 +1657,7 @@ int port = luaL_checkint(L, WSLUA_ARG_DissectorTable_try_PATTERN); handle = dissector_get_port_handle(dt->table,port); } - + if (handle) { pushDissector(L,handle); WSLUA_RETURN(1); /* The dissector handle if found */ @@ -1589,19 +1667,18 @@ } } - WSLUA_METAMETHOD DissectorTable_tostring(lua_State* L) { /**/ - /* XXX It would be nice to iterate and print which dissectors it has */ + /* XXX It would be nice to iterate and print which dissectors it has */ DissectorTable dt = checkDissectorTable(L,1); 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: { @@ -1620,7 +1697,7 @@ default: luaL_error(L,"Strange table type"); } - + lua_pushstring(L,s->str); g_string_free(s,TRUE); return 1; @@ -1645,7 +1722,3 @@ WSLUA_REGISTER_CLASS(DissectorTable); return 1; } - - - -