Move the Lua interface into epan... (not a plugin anymore).
- Rename Tap into Listener - add a mechanism to pass protocols' tap data to the Listener svn path=/trunk/; revision=19319
This commit is contained in:
parent
299469d48d
commit
6462d05044
14
Makefile.am
14
Makefile.am
|
@ -187,12 +187,6 @@ include Makefile.common
|
|||
|
||||
if HAVE_PLUGINS
|
||||
|
||||
if HAVE_LIBLUA
|
||||
lua_lib = plugins/lua/lua.la
|
||||
else # HAVE_LIBLUA
|
||||
lua_lib =
|
||||
endif # HAVE_LIBLUA
|
||||
|
||||
plugin_libs = \
|
||||
plugins/acn/acn.la \
|
||||
plugins/agentx/agentx.la \
|
||||
|
@ -205,7 +199,6 @@ plugin_libs = \
|
|||
plugins/giop/coseventcomm.la \
|
||||
plugins/gryphon/gryphon.la \
|
||||
plugins/irda/irda.la \
|
||||
$(lua_lib) \
|
||||
plugins/lwres/lwres.la \
|
||||
plugins/mate/mate.la \
|
||||
plugins/megaco/megaco.la \
|
||||
|
@ -226,12 +219,6 @@ plugin_ldadd = $(plugin_libs)
|
|||
|
||||
else # ENABLE_STATIC
|
||||
|
||||
if HAVE_LIBLUA
|
||||
lua_ldadd = "-dlopen" plugins/lua/lua.la
|
||||
else # HAVE_LIBLUA
|
||||
lua_ldadd =
|
||||
endif # HAVE_LIBLUA
|
||||
|
||||
plugin_ldadd = \
|
||||
"-dlopen" self \
|
||||
"-dlopen" plugins/acn/acn.la \
|
||||
|
@ -246,7 +233,6 @@ plugin_ldadd = \
|
|||
"-dlopen" plugins/gryphon/gryphon.la \
|
||||
"-dlopen" plugins/h223/h223.la \
|
||||
"-dlopen" plugins/irda/irda.la \
|
||||
$(lua_ldadd) \
|
||||
"-dlopen" plugins/lwres/lwres.la \
|
||||
"-dlopen" plugins/mate/mate.la \
|
||||
"-dlopen" plugins/megaco/megaco.la \
|
||||
|
|
|
@ -1347,6 +1347,7 @@ AC_OUTPUT(
|
|||
epan/dfilter/Makefile
|
||||
epan/dissectors/Makefile
|
||||
epan/ftypes/Makefile
|
||||
epan/wslua/Makefile
|
||||
codecs/Makefile
|
||||
gtk/Makefile
|
||||
gtk/doxygen.cfg
|
||||
|
@ -1371,7 +1372,6 @@ AC_OUTPUT(
|
|||
plugins/gryphon/Makefile
|
||||
plugins/h223/Makefile
|
||||
plugins/irda/Makefile
|
||||
plugins/lua/Makefile
|
||||
plugins/lwres/Makefile
|
||||
plugins/mate/Makefile
|
||||
plugins/megaco/Makefile
|
||||
|
|
|
@ -22,7 +22,17 @@
|
|||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
SUBDIRS = ftypes dfilter dissectors
|
||||
|
||||
if HAVE_LIBLUA
|
||||
wslua_lib = wslua/libwslua.la
|
||||
wslua_dir = wslua
|
||||
else # HAVE_LIBLUA
|
||||
wslua_lib =
|
||||
wslua_dir =
|
||||
endif # HAVE_LIBLUA
|
||||
|
||||
|
||||
SUBDIRS = ftypes dfilter dissectors $(wslua_dir)
|
||||
|
||||
# EPAN will eventually be a shared library. While I move source code around,
|
||||
# however, it is an archive library.
|
||||
|
@ -34,7 +44,7 @@ libwireshark_la_LDFLAGS = -version-info 0:1:0
|
|||
|
||||
include Makefile.common
|
||||
|
||||
INCLUDES = -I$(srcdir)/.. -I$(srcdir)/$(LEMON) \
|
||||
INCLUDES = -I$(srcdir)/.. -I$(srcdir)/$(LEMON) @LUA_INCLUDES@ \
|
||||
$(LIBGNUTLS_CFLAGS) $(LIBGCRYPT_CFLAGS)
|
||||
|
||||
libwireshark_la_SOURCES = \
|
||||
|
@ -82,11 +92,12 @@ MAINTAINERCLEANFILES = \
|
|||
Makefile.in \
|
||||
sminmpec.c
|
||||
|
||||
|
||||
#
|
||||
# Add the object files for missing routines, if any.
|
||||
#
|
||||
libwireshark_la_LIBADD = @G_ASCII_STRTOULL_LO@ @INET_ATON_LO@ @INET_PTON_LO@ @INET_NTOP_LO@ dfilter/libdfilter.la ftypes/libftypes.la dissectors/libdissectors.la @ADNS_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @KRB5_LIBS@ @SNMP_LIBS@ @SSL_LIBS@ -lm
|
||||
libwireshark_la_DEPENDENCIES = @G_ASCII_STRTOULL_LO@ @INET_ATON_LO@ @INET_PTON_LO@ @INET_NTOP_LO@ dfilter/libdfilter.la ftypes/libftypes.la dissectors/libdissectors.la
|
||||
libwireshark_la_LIBADD = @G_ASCII_STRTOULL_LO@ @INET_ATON_LO@ @INET_PTON_LO@ @INET_NTOP_LO@ dfilter/libdfilter.la ftypes/libftypes.la dissectors/libdissectors.la $(wslua_lib) @ADNS_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @KRB5_LIBS@ @SNMP_LIBS@ @SSL_LIBS@ -lm
|
||||
libwireshark_la_DEPENDENCIES = @G_ASCII_STRTOULL_LO@ @INET_ATON_LO@ @INET_PTON_LO@ @INET_NTOP_LO@ dfilter/libdfilter.la ftypes/libftypes.la dissectors/libdissectors.la $(wslua_lib)
|
||||
|
||||
tvbtest: tvbtest.o tvbuff.o except.o strutil.o
|
||||
$(LINK) $^ $(GLIB_LIBS) -lz
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
#include "emem.h"
|
||||
#include "expert.h"
|
||||
|
||||
#ifdef HAVE_LUA_5_1
|
||||
#include <epan/wslua/wslua.h>
|
||||
#endif
|
||||
|
||||
static void (*report_failure_func)(const char *, va_list);
|
||||
static void (*report_open_failure_func)(const char *, int, gboolean);
|
||||
static void (*report_read_failure_func)(const char *, int);
|
||||
|
@ -93,6 +97,10 @@ epan_init(const char *plugin_dir, void (*register_all_protocols)(void),
|
|||
final_registration_all_protocols();
|
||||
host_name_lookup_init();
|
||||
expert_init();
|
||||
#ifdef HAVE_LUA_5_1
|
||||
wslua_init(NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
# Makefile.am
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 1998 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
|
||||
INCLUDES = -I$(top_srcdir) @LUA_INCLUDES@
|
||||
|
||||
noinst_LTLIBRARIES = libwslua.la
|
||||
|
||||
wslua_modules = \
|
||||
wslua_tvb.c \
|
||||
wslua_proto.c \
|
||||
wslua_tree.c \
|
||||
wslua_pinfo.c \
|
||||
wslua_listener.c \
|
||||
wslua_gui.c \
|
||||
wslua_util.c \
|
||||
wslua_field.c \
|
||||
wslua_dumper.c
|
||||
|
||||
libwslua_la_SOURCES = \
|
||||
$(wslua_modules) \
|
||||
init_wslua.c \
|
||||
wslua.h
|
||||
|
||||
libwslua_la_LIBADD = @LUA_LIBS@
|
||||
|
||||
BUILT_SOURCES = \
|
||||
wslua_register.h
|
||||
|
||||
pkgdata_DATA = init.lua
|
||||
|
||||
CLEANFILES = \
|
||||
*~
|
||||
|
||||
DISTCLEANFILES = \
|
||||
dummy
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
doc/*.pod \
|
||||
wslua_register.h \
|
||||
taps.c-inc \
|
||||
taps.txt \
|
||||
init.lua
|
||||
|
||||
EXTRA_DIST = \
|
||||
wslua_register.h \
|
||||
taps \
|
||||
make-reg.pl \
|
||||
make-doc.pl \
|
||||
template-init.lua \
|
||||
make-init-lua.pl \
|
||||
make-taps.pl \
|
||||
Makefile.nmake
|
||||
|
||||
taps_used = \
|
||||
../dissectors/packet-http.h \
|
||||
../dissectors/packet-ip.h \
|
||||
../dissectors/packet-udp.h \
|
||||
../dissectors/packet-h225.h
|
||||
|
||||
taps: $(taps_used)
|
||||
touch taps
|
||||
|
||||
taps.c-inc: make-taps.pl taps
|
||||
$(PERL) make-taps.pl taps taps.c-inc taps.txt
|
||||
|
||||
taps.txt: taps.c-inc
|
||||
|
||||
wslua.h: wslua_register.h
|
||||
|
||||
# do not do not unnecessarilly modify the old file in order avoid recompiling every module every time
|
||||
wslua_register.h: make-reg.pl $(lua_modules) taps.c-inc
|
||||
$(PERL) make-reg.pl \
|
||||
wslua_tvb.c \
|
||||
wslua_proto.c \
|
||||
wslua_tree.c \
|
||||
wslua_pinfo.c \
|
||||
wslua_listener.c \
|
||||
wslua_gui.c \
|
||||
wslua_util.c \
|
||||
wslua_field.c \
|
||||
wslua_dumper.c > wslua_register.h.new ;\
|
||||
if diff wslua_register.h.new wslua_register.h >/dev/null; then rm wslua_register.h.new; else mv wslua_register.h.new wslua_register.h; fi
|
||||
|
||||
doc: make-doc.pl $(lua_modules)
|
||||
$(PERL) make-doc.pl \
|
||||
wslua_tvb.c \
|
||||
wslua_proto.c \
|
||||
wslua_tree.c \
|
||||
wslua_pinfo.c \
|
||||
wslua_listener.c \
|
||||
wslua_gui.c \
|
||||
wslua_util.c \
|
||||
wslua_field.c \
|
||||
wslua_dumper.c
|
||||
|
||||
dummy:
|
||||
touch dummy
|
||||
|
||||
init.lua: template-init.lua make-init-lua.pl ../ftypes/ftypes.h ../../wiretap/wtap.h ../proto.h
|
||||
$(PERL) make-init-lua.pl template-init.lua > init.lua
|
|
@ -0,0 +1,69 @@
|
|||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
include ..\..\config.nmake
|
||||
|
||||
############### no need to modify below this line #########
|
||||
|
||||
CFLAGS=/DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) $(LUA_CFLAGS)\
|
||||
/I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
|
||||
|
||||
LDFLAGS = /NOLOGO /INCREMENTAL:no /MACHINE:I386 $(LOCAL_LDFLAGS)
|
||||
|
||||
!IFDEF LUA_DIR
|
||||
!IFDEF ENABLE_LIBWIRESHARK
|
||||
LINK_PLUGIN_WITH=..\..\epan\libwireshark.lib
|
||||
CFLAGS=/DHAVE_WIN32_LIBWIRESHARK_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS)
|
||||
|
||||
MODULES= \
|
||||
elua_dumper.c \
|
||||
elua_field.c \
|
||||
elua_gui.c \
|
||||
elua_pinfo.c \
|
||||
elua_proto.c \
|
||||
elua_tap.c \
|
||||
elua_tree.c \
|
||||
elua_tvb.c \
|
||||
elua_util.c
|
||||
|
||||
OBJECTS= \
|
||||
elua.obj \
|
||||
elua_dumper.obj \
|
||||
elua_field.obj \
|
||||
elua_gui.obj \
|
||||
elua_pinfo.obj \
|
||||
elua_plugin.obj \
|
||||
elua_proto.obj \
|
||||
elua_tap.obj \
|
||||
elua_tree.obj \
|
||||
elua_tvb.obj \
|
||||
elua_util.obj
|
||||
|
||||
lua.dll lua.exp lua.lib : $(OBJECTS) $(LINK_PLUGIN_WITH)
|
||||
link -dll /out:lua.dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \
|
||||
$(GLIB_LIBS) $(LUA_LIBS) ..\..\wiretap\wiretap-$(WTAP_VERSION).lib
|
||||
|
||||
|
||||
elua_register.h: elua_makereg.pl $(MODULES)
|
||||
$(PERL) elua_makereg.pl $(MODULES) > elua_register.h
|
||||
|
||||
elua.c: elua_register.h
|
||||
|
||||
doc: $(MODULES)
|
||||
$(PERL) elua_makedoc.pl $(MODULES)
|
||||
|
||||
#elua.c: $(LUA_LIBS)
|
||||
|
||||
init.lua: template-init.lua make-init-lua.pl ../../epan/ftypes/ftypes.h ../../wiretap/wtap.h ../../epan/proto.h
|
||||
$(PERL) make-init-lua.pl template-init.lua > init.lua
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) lua.dll lua.exp lua.lib *.pdb init.lua
|
||||
|
||||
distclean: clean
|
||||
|
||||
maintainer-clean: distclean
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* packet-lua.c
|
||||
*
|
||||
* Wireshark's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
#include <epan/nstime.h>
|
||||
#include <math.h>
|
||||
#include <epan/expert.h>
|
||||
#include <epan/ex-opt.h>
|
||||
#include <epan/privileges.h>
|
||||
|
||||
static lua_State* L = NULL;
|
||||
|
||||
packet_info* lua_pinfo;
|
||||
struct _wslua_treeitem* lua_tree;
|
||||
tvbuff_t* lua_tvb;
|
||||
int lua_malformed;
|
||||
int lua_dissectors_table_ref;
|
||||
|
||||
dissector_handle_t lua_data_handle;
|
||||
|
||||
|
||||
static int wslua_not_register_menu(lua_State* LS) {
|
||||
luaL_error(LS,"too late to register a menu");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
|
||||
lua_pinfo = pinfo;
|
||||
lua_tvb = tvb;
|
||||
|
||||
lua_tree = ep_alloc(sizeof(struct _wslua_treeitem));
|
||||
lua_tree->tree = tree;
|
||||
lua_tree->item = proto_tree_add_text(tree,tvb,0,0,"lua fake item");
|
||||
PROTO_ITEM_SET_HIDDEN(lua_tree->item);
|
||||
|
||||
/*
|
||||
* almost equivalent to Lua:
|
||||
* dissectors[current_proto](tvb,pinfo,tree)
|
||||
*/
|
||||
|
||||
lua_settop(L,0);
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref);
|
||||
|
||||
lua_pushstring(L, pinfo->current_proto);
|
||||
lua_gettable(L, -2);
|
||||
|
||||
lua_remove(L,1);
|
||||
|
||||
|
||||
if (lua_isfunction(L,1)) {
|
||||
|
||||
push_Tvb(L,tvb);
|
||||
push_Pinfo(L,pinfo);
|
||||
push_TreeItem(L,lua_tree);
|
||||
|
||||
if ( lua_pcall(L,3,0,0) ) {
|
||||
const gchar* error = lua_tostring(L,-1);
|
||||
|
||||
proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: %s",error);
|
||||
expert_add_info_format(pinfo, pi, PI_DEBUG, PI_ERROR ,"Lua Error");
|
||||
}
|
||||
} else {
|
||||
proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: did not find the %s dissector"
|
||||
" in the dissectors table",pinfo->current_proto);
|
||||
|
||||
expert_add_info_format(pinfo, pi, PI_DEBUG, PI_ERROR ,"Lua Error");
|
||||
}
|
||||
|
||||
clear_outstanding_tvbs();
|
||||
clear_outstanding_pinfos();
|
||||
clear_outstanding_trees();
|
||||
|
||||
|
||||
lua_pinfo = NULL;
|
||||
lua_tree = NULL;
|
||||
lua_tvb = NULL;
|
||||
|
||||
}
|
||||
|
||||
static void iter_table_and_call(lua_State* LS, int env, const gchar* table_name, lua_CFunction error_handler) {
|
||||
lua_settop(LS,0);
|
||||
|
||||
lua_pushcfunction(LS,error_handler);
|
||||
lua_pushstring(LS, table_name);
|
||||
lua_gettable(LS, env);
|
||||
|
||||
if (!lua_istable(LS, 2)) {
|
||||
report_failure("Lua: either `%s' does not exist or it is not a table!\n",table_name);
|
||||
lua_close(LS);
|
||||
L = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
lua_pushnil(LS);
|
||||
|
||||
while (lua_next(LS, 2)) {
|
||||
const gchar* name = lua_tostring(L,-2);
|
||||
|
||||
if (lua_isfunction(LS,-1)) {
|
||||
|
||||
if ( lua_pcall(LS,0,0,1) ) {
|
||||
lua_pop(LS,1);
|
||||
}
|
||||
|
||||
} else {
|
||||
report_failure("Lua: Something not a function got its way into the %s.%s",table_name,name);
|
||||
lua_close(LS);
|
||||
L = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lua_settop(LS,0);
|
||||
}
|
||||
|
||||
|
||||
static int init_error_handler(lua_State* LS) {
|
||||
const gchar* error = lua_tostring(LS,1);
|
||||
report_failure("Lua: Error During execution of Initialization:\n %s",error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void wslua_init_routine(void) {
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if ( ! initialized ) {
|
||||
lua_prime_all_fields(NULL);
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
if (L) {
|
||||
iter_table_and_call(L, LUA_GLOBALSINDEX, WSLUA_INIT_ROUTINES,init_error_handler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static const char *getF(lua_State *L _U_, void *ud, size_t *size)
|
||||
{
|
||||
FILE *f=(FILE *)ud;
|
||||
static char buff[512];
|
||||
if (feof(f)) return NULL;
|
||||
*size=fread(buff,1,sizeof(buff),f);
|
||||
return (*size>0) ? buff : NULL;
|
||||
}
|
||||
|
||||
static int lua_main_error_handler(lua_State* LS) {
|
||||
const gchar* error = lua_tostring(LS,1);
|
||||
report_failure("Lua: Error during loading:\n %s",error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lua_load_script(const gchar* filename) {
|
||||
FILE* file;
|
||||
|
||||
if (! ( file = fopen(filename,"r")) ) {
|
||||
report_open_failure(filename,errno,FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
lua_settop(L,0);
|
||||
|
||||
lua_pushcfunction(L,lua_main_error_handler);
|
||||
|
||||
switch (lua_load(L,getF,file,filename)) {
|
||||
case 0:
|
||||
lua_pcall(L,0,0,1);
|
||||
fclose(file);
|
||||
return;
|
||||
case LUA_ERRSYNTAX: {
|
||||
report_failure("Lua: syntax error during precompilation of `%s':\n%s",filename,lua_tostring(L,-1));
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
case LUA_ERRMEM:
|
||||
report_failure("Lua: memory allocation error during execution of %s",filename);
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void basic_logger(const gchar *log_domain _U_,
|
||||
GLogLevelFlags log_level _U_,
|
||||
const gchar *message,
|
||||
gpointer user_data _U_) {
|
||||
fputs(message,stderr);
|
||||
}
|
||||
|
||||
static int wslua_panic(lua_State* LS) {
|
||||
g_error("LUA PANIC: %s",lua_tostring(LS,-1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wslua_init(lua_State* LS) {
|
||||
const gchar* filename;
|
||||
const funnel_ops_t* ops = funnel_get_funnel_ops();
|
||||
gboolean run_anyway = FALSE;
|
||||
|
||||
/* set up the logger */
|
||||
g_log_set_handler(LOG_DOMAIN_LUA, G_LOG_LEVEL_CRITICAL|
|
||||
G_LOG_LEVEL_WARNING|
|
||||
G_LOG_LEVEL_MESSAGE|
|
||||
G_LOG_LEVEL_INFO|
|
||||
G_LOG_LEVEL_DEBUG,
|
||||
ops ? ops->logger : basic_logger, NULL);
|
||||
|
||||
if (!L) {
|
||||
if (LS)
|
||||
L = LS;
|
||||
else
|
||||
L = luaL_newstate();
|
||||
}
|
||||
|
||||
WSLUA_INIT(L);
|
||||
|
||||
lua_atpanic(L,wslua_panic);
|
||||
|
||||
/* the init_routines table (accessible by the user) */
|
||||
lua_pushstring(L, WSLUA_INIT_ROUTINES);
|
||||
lua_newtable (L);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
/* the dissectors table goes in the registry (not accessible) */
|
||||
lua_newtable (L);
|
||||
lua_dissectors_table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
/* set running_superuser variable to it's propper value */
|
||||
WSLUA_REG_GLOBAL_BOOL(L,"running_superuser",started_with_special_privs());
|
||||
|
||||
/* load system's init.lua */
|
||||
filename = get_datafile_path("init.lua");
|
||||
|
||||
if (( file_exists(filename))) {
|
||||
lua_load_script(filename);
|
||||
}
|
||||
|
||||
/* check if lua is to be disabled */
|
||||
lua_pushstring(L,"lua_disabled");
|
||||
lua_gettable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
if (lua_isboolean(L,-1) && lua_toboolean(L,-1)) {
|
||||
/* disable lua */
|
||||
lua_close(L);
|
||||
L = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* check whether we should run other scripts even if running superuser */
|
||||
lua_pushstring(L,"run_user_scripts_when_superuser");
|
||||
lua_gettable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
if (lua_isboolean(L,-1) && lua_toboolean(L,-1)) {
|
||||
run_anyway = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* if we are indeed superuser run user scripts only if told to do so */
|
||||
if ( (!started_with_special_privs()) || run_anyway ) {
|
||||
filename = get_persconffile_path("init.lua", FALSE);
|
||||
|
||||
if (( file_exists(filename))) {
|
||||
lua_load_script(filename);
|
||||
}
|
||||
|
||||
while((filename = ex_opt_get_next("lua_script"))) {
|
||||
lua_load_script(filename);
|
||||
}
|
||||
}
|
||||
|
||||
/* at this point we're set up so register the init routine */
|
||||
register_init_routine(wslua_init_routine);
|
||||
|
||||
/*
|
||||
* after this point it is too late to register a menu
|
||||
* disable the function to avoid weirdness
|
||||
*/
|
||||
lua_pushstring(L, "register_menu");
|
||||
lua_pushcfunction(L, wslua_not_register_menu);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
/* set up some essential globals */
|
||||
lua_pinfo = NULL;
|
||||
lua_tree = NULL;
|
||||
lua_tvb = NULL;
|
||||
|
||||
lua_data_handle = find_dissector("data");
|
||||
lua_malformed = proto_get_id_by_filter_name("malformed");
|
||||
|
||||
Proto_commit(L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_State* wslua_state() { return L; }
|
||||
|
|
@ -0,0 +1,385 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# make-doc.pl
|
||||
# WSLUA's Reference Manual Generator
|
||||
#
|
||||
# (c) 2006, Luis E. Garcia Onatnon <luis.ontanon@gmail.com>
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 1998 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# (-: I don't even think writing this in Lua :-)
|
||||
|
||||
use strict;
|
||||
#use V2P;
|
||||
|
||||
sub deb {
|
||||
# warn $_[0];
|
||||
}
|
||||
|
||||
sub gorolla {
|
||||
# a gorilla stays to a chimp like ... stays to chomp
|
||||
# but this one returns the shrugged string.
|
||||
my $s = shift;
|
||||
$s =~ s/^([\n]|\s)*//ms;
|
||||
$s =~ s/([\n]|\s)*$//ms;
|
||||
$s;
|
||||
}
|
||||
|
||||
my $class;
|
||||
my %classes;
|
||||
my $function;
|
||||
my @functions;
|
||||
|
||||
my %template = %{{
|
||||
class_header => "= %s =\n",
|
||||
class_desc => "%s\n",
|
||||
class_constructors_header => "== %s constructors ==\n",
|
||||
class_methods_header => "== %s methods ==\n",
|
||||
class_attributes_header => "== %s Attributes ==\n",
|
||||
class_attr_header => "=== %s ===\n",
|
||||
class_attr_descr => "%s\n",
|
||||
function_header => "=== %s ===\n",
|
||||
function_descr => "%s\n",
|
||||
function_arg_header => "==== %s ====\n",
|
||||
function_arg_descr => "%s\n",
|
||||
function_argerrors_header => "'''Errors:'''\n",
|
||||
function_argerror => " * %s\n",
|
||||
function_returns_header => "==== returns ====\n",
|
||||
function_returns => " * %s\n",
|
||||
function_errors_header => "==== errors ====\n",
|
||||
function_errors => " * %s\n",
|
||||
non_method_functions_header => "= Non method functions =\n",
|
||||
}};
|
||||
|
||||
|
||||
my %metamethods = %{{
|
||||
__tostring => "tostring(__)",
|
||||
__index => "__[]",
|
||||
__newindex => "__[] = ",
|
||||
__add => "__ + __",
|
||||
__sub => "__ - __",
|
||||
__mul => "__ * __",
|
||||
__div => "__ / __",
|
||||
__mod => "__ % __",
|
||||
__pow => "__ ^ __",
|
||||
__unm => "-___",
|
||||
__concat => "__ .. __",
|
||||
__len => "#__",
|
||||
__call => "()",
|
||||
__eq => "__ == __",
|
||||
__lt => "__ < __",
|
||||
__le => "__ <= __",
|
||||
}};
|
||||
|
||||
# It's said that only perl can parse perl... my editor isn't perl...
|
||||
# if unencoded this causes my editor's autoindent to bail out so I encoded in octal
|
||||
# XXX: support \" within ""
|
||||
my $QUOTED_RE = "\042\050\133^\042\135*\051\042";
|
||||
|
||||
my $TRAILING_COMMENT_RE = '((\s*|[\n\r]*)/\*(.*?)\*/)?';
|
||||
|
||||
my @control =
|
||||
(
|
||||
# This will be scanned in order trying to match the re if it matches
|
||||
# the body will be executed immediatelly after.
|
||||
|
||||
[ 'WSLUA_CLASS_DEFINE\050\s*([A-Z][a-zA-Z]+)\s*,.*?\051' . $TRAILING_COMMENT_RE,
|
||||
sub {
|
||||
deb ">c=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
$class = {
|
||||
name => $1,
|
||||
descr=> gorolla($4),
|
||||
constructors => [],
|
||||
methods => [],
|
||||
metamethods => [],
|
||||
attributes => []
|
||||
};
|
||||
$classes{$1} = $class;
|
||||
}],
|
||||
|
||||
[ 'WSLUA_FUNCTION\s+wslua_([a-z_]+)[^\173]*\173' . $TRAILING_COMMENT_RE,
|
||||
sub {
|
||||
deb ">f=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
$function = {
|
||||
returns => [],
|
||||
arglist => [],
|
||||
args => {},
|
||||
name => $1,
|
||||
descr => gorolla($4),
|
||||
type => 'standalone'
|
||||
};
|
||||
push @functions, $function;
|
||||
} ] ,
|
||||
|
||||
[ 'WSLUA_CONSTRUCTOR\s+([A-Za-z]+)_([a-z_]+).*?\173' . $TRAILING_COMMENT_RE,
|
||||
sub {
|
||||
deb ">cc=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
$function = {
|
||||
returns => [],
|
||||
arglist => [],
|
||||
args => {},
|
||||
name => "$1.$2",
|
||||
descr => gorolla($5),
|
||||
type => 'constructor'
|
||||
};
|
||||
push @{${$class}{constructors}}, $function;
|
||||
} ] ,
|
||||
|
||||
[ 'WSLUA_METHOD\s+([A-Za-z]+)_([a-z_]+)[^\173]*\173' . $TRAILING_COMMENT_RE,
|
||||
sub {
|
||||
deb ">cm=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
$function = {
|
||||
returns => [],
|
||||
arglist => [],
|
||||
args => {},
|
||||
name => "$1:$2",
|
||||
descr => gorolla($5),
|
||||
type => 'method'
|
||||
};
|
||||
push @{${$class}{methods}}, $function;
|
||||
} ] ,
|
||||
|
||||
[ 'WSLUA_METAMETHOD\s+([A-Za-z]+)(__[a-z]+)[^\173]*\173' . $TRAILING_COMMENT_RE,
|
||||
sub {
|
||||
deb ">cm=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
my $name = $metamethods{$2};
|
||||
my ($c,$d) = ($1,$5);
|
||||
$name =~ s/__/$c/g;
|
||||
$function = {
|
||||
returns => [],
|
||||
arglist => [],
|
||||
args => {},
|
||||
name => $name,
|
||||
descr => gorolla($d),
|
||||
type => 'metamethod'
|
||||
};
|
||||
push @{${$class}{metamethods}}, $function;
|
||||
} ] ,
|
||||
|
||||
[ '#define WSLUA_(OPT)?ARG_([a-z_]+)_([A-Z0-9]+)\s+\d+' . $TRAILING_COMMENT_RE,
|
||||
sub {
|
||||
deb ">a=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
push @{${$function}{arglist}} , $3;
|
||||
${${$function}{args}}{$3} = {descr=>$6}
|
||||
} ],
|
||||
|
||||
[ '#define WSLUA_(OPT)?ARG_([A-Za-z]+)_([a-z_]+)_([A-Z0-9]+)\s+\d+' . $TRAILING_COMMENT_RE,
|
||||
sub {
|
||||
deb ">ca=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
push @{${$function}{arglist}} , $4;
|
||||
${${$function}{args}}{$4} = {descr=>$7}
|
||||
} ],
|
||||
|
||||
[ '/\052\s+WSLUA_ATTRIBUTE\s+([A-Za-z]+)_([a-z_]+)\s+([A-Z]*)\s*(.*?)\052/',
|
||||
sub {
|
||||
deb ">at=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
push @{${$class}{attributes}}, { name => $2, descr => gorolla($4), mode=>$3 };
|
||||
} ],
|
||||
|
||||
[ '/\052\s+WSLUA_MOREARGS\s+([A-Za-z_]+)\s+(.*?)\052/',
|
||||
sub {
|
||||
deb ">ma=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
push @{${$function}{arglist}} , "...";
|
||||
${${$function}{args}}{"..."} = {descr=>gorolla($2)}
|
||||
} ],
|
||||
|
||||
[ 'WSLUA_(FINAL_)?RETURN\050\s*.*?\s*\051\s*;' . $TRAILING_COMMENT_RE,
|
||||
sub {
|
||||
deb ">fr=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
push @{${$function}{returns}} , gorolla($4) if $4 ne '';
|
||||
} ],
|
||||
|
||||
[ 'WSLUA_ERROR\s*\050\s*(([A-Z][A-Za-z]+)_)?([a-z_]+),' . $QUOTED_RE ,
|
||||
sub {
|
||||
deb ">e=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
my $errors;
|
||||
unless (exists ${$function}{errors}) {
|
||||
$errors = ${$function}{errors} = [];
|
||||
} else {
|
||||
$errors = ${$function}{errors};
|
||||
}
|
||||
|
||||
push @{$errors}, gorolla($4);
|
||||
} ],
|
||||
|
||||
[ 'WSLUA_(OPT)?ARG_ERROR\s*\050\s*(([A-Z][A-Za-z]+)_)?([a-z_]+)\s*,\s*([A-Z0-9]+)\s*,\s*' . $QUOTED_RE,
|
||||
sub {
|
||||
deb ">ae=$1=$2=$3=$4=$5=$6=$7=\n";
|
||||
my $errors;
|
||||
unless (exists ${${${$function}{args}}{$5}}{errors}) {
|
||||
$errors = ${${${$function}{args}}{$5}}{errors} = [];
|
||||
} else {
|
||||
$errors = ${${${$function}{args}}{$5}}{errors};
|
||||
}
|
||||
|
||||
push @{$errors}, gorolla($6);
|
||||
} ] ,
|
||||
);
|
||||
|
||||
my $anymatch = '(^ThIsWiLlNeVeRmAtCh$';
|
||||
for (@control) {
|
||||
$anymatch .= "|${$_}[0]";
|
||||
}
|
||||
$anymatch .= ')';
|
||||
|
||||
# for each file given in the command line args
|
||||
my $file;
|
||||
while ( $file = shift) {
|
||||
|
||||
next unless -f $file;
|
||||
|
||||
my $docfile = $file;
|
||||
$docfile =~ s/\.c$/.pod/;
|
||||
|
||||
open C, "< $file";
|
||||
open D, "> doc/$docfile";
|
||||
|
||||
my $b = '';
|
||||
$b .= $_ while (<C>);
|
||||
|
||||
while ($b =~ /$anymatch/ms ) {
|
||||
my $match = $1;
|
||||
# print "\n-----\n$match\n-----\n";
|
||||
for (@control) {
|
||||
my ($re,$f) = @{$_};
|
||||
if ( $match =~ /$re/ms) {
|
||||
&{$f}();
|
||||
$b =~ s/.*?$re//ms;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for my $cname (sort keys %classes) {
|
||||
my $cl = $classes{$cname};
|
||||
printf D $template{class_header}, $cname;
|
||||
printf D $template{class_desc} , ${$cl}{descr} if ${$cl}{descr};
|
||||
|
||||
if ( $#{${$cl}{constructors}} >= 0) {
|
||||
printf D $template{class_constructors_header}, $cname;
|
||||
|
||||
for my $c (@{${$cl}{constructors}}) {
|
||||
function_descr($c);
|
||||
}
|
||||
|
||||
printf D $template{class_constructors_footer}, $cname;
|
||||
}
|
||||
|
||||
if ( $#{${$cl}{methods}} >= 0) {
|
||||
printf D $template{class_methods_header}, $cname;
|
||||
|
||||
for my $m (@{${$cl}{methods}}) {
|
||||
function_descr($m);
|
||||
}
|
||||
|
||||
printf D $template{class_methods_footer}, $cname;
|
||||
}
|
||||
|
||||
if ( $#{${$cl}{metamethods}} >= 0) {
|
||||
printf D $template{class_metamethods_header}, $cname;
|
||||
|
||||
for my $m (@{${$cl}{metamethods}}) {
|
||||
function_descr($m,${$m}{name});
|
||||
}
|
||||
|
||||
printf D $template{class_metamethods_footer}, $cname;
|
||||
}
|
||||
|
||||
if ( $#{${$cl}{attributes}} >= 0) {
|
||||
printf D $template{class_attributes_header}, $cname;
|
||||
|
||||
for my $a (@{${$cl}{attributes}}) {
|
||||
printf D $template{class_attr_header}, ${$a}{name};
|
||||
printf D $template{class_attr_descr}, ${$a}{descr} if ${$a}{descr};
|
||||
printf D $template{class_attr_footer}, ${$a}{name};
|
||||
|
||||
}
|
||||
|
||||
printf D $template{class_attributes_footer}, $cname;
|
||||
}
|
||||
}
|
||||
|
||||
if ($#functions >= 0) {
|
||||
print D $template{non_method_functions_header};
|
||||
|
||||
for my $f (@functions) {
|
||||
function_descr($f);
|
||||
}
|
||||
}
|
||||
|
||||
%classes = ();
|
||||
$class = undef;
|
||||
$function = undef;
|
||||
@functions = ();
|
||||
close C;
|
||||
close D;
|
||||
}
|
||||
|
||||
sub function_descr {
|
||||
my $f = $_[0];
|
||||
my $label = $_[1];
|
||||
|
||||
if (defined $label ) {
|
||||
printf D $template{function_header}, $label;
|
||||
} else {
|
||||
my $arglist = '';
|
||||
|
||||
for (@{ ${$f}{arglist} }) {
|
||||
my $a = $_;
|
||||
$a =~ tr/A-Z/a-z/;
|
||||
$arglist .= "$a, ";
|
||||
}
|
||||
|
||||
$arglist =~ s/, $//;
|
||||
|
||||
printf D $template{function_header}, "${$f}{name}($arglist)";
|
||||
}
|
||||
|
||||
printf D $template{function_descr}, ${$f}{descr} if ${$f}{descr};
|
||||
|
||||
for my $argname (@{${$f}{arglist}}) {
|
||||
my $arg = ${${$f}{args}}{$argname};
|
||||
$argname =~ tr/A-Z/a-z/;
|
||||
|
||||
printf D $template{function_arg_header}, $argname;
|
||||
printf D $template{function_arg_descr}, ${$arg}{descr} if ${$arg}{descr};
|
||||
|
||||
if ( $#{${$arg}{errors}} >= 0) {
|
||||
printf D $template{function_argerrors_header}, $argname;
|
||||
printf D $template{function_argerror}, $_ for @{${$arg}{errors}};
|
||||
printf D $template{function_argerrors_footer}, $argname;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( $#{${$f}{returns}} >= 0) {
|
||||
printf D $template{function_returns_header}, ${$f}{name};
|
||||
printf D $template{function_returns}, $_ for @{${$f}{returns}};
|
||||
printf D $template{function_returns_footer}, ${$f}{name};
|
||||
}
|
||||
|
||||
if ( $#{${$f}{errors}} >= 0) {
|
||||
printf D $template{function_errors_header}, ${$f}{name};
|
||||
printf D $template{function_errors}, $_ for @{${$f}{errors}};
|
||||
printf D $template{function_errors_footer}, ${$f}{name};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# make-init-lua.pl
|
||||
#
|
||||
# create the init.lua file based on a template (stdin)
|
||||
#
|
||||
# (c) 2006, Luis E. Garcia Onatnon <luis.ontanon@gmail.com>
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 2004 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
use strict;
|
||||
|
||||
my $WSROOT = "../..";
|
||||
|
||||
my $wtap_encaps_table = '';
|
||||
my $ft_types_table = '';
|
||||
my $bases_table = '';
|
||||
my $expert_pi = '';
|
||||
|
||||
my %replacements = %{{
|
||||
WTAP_ENCAPS => \$wtap_encaps_table,
|
||||
FT_TYPES => \$ft_types_table,
|
||||
BASES => \$bases_table,
|
||||
EXPERT => \$expert_pi,
|
||||
}};
|
||||
|
||||
|
||||
#
|
||||
# load template
|
||||
#
|
||||
my $template = '';
|
||||
$template .= $_ while(<>);
|
||||
|
||||
|
||||
#
|
||||
# make wiretap encapusulation table
|
||||
#
|
||||
|
||||
$wtap_encaps_table = "-- Wiretap encapsulations\nwtap = {\n";
|
||||
|
||||
open WTAP_H, "< $WSROOT/wiretap/wtap.h";
|
||||
|
||||
while(<WTAP_H>) {
|
||||
if ( /^#define WTAP_ENCAP_([A-Z0-9_]+)\s+(\d+)/ ) {
|
||||
$wtap_encaps_table .= "\t[\"$1\"] = $2,\n";
|
||||
}
|
||||
}
|
||||
|
||||
$wtap_encaps_table =~ s/,\n$/\n}\n/msi;
|
||||
|
||||
#
|
||||
# enum fttype
|
||||
#
|
||||
|
||||
$ft_types_table = " -- Field Types\nftypes = {\n";
|
||||
|
||||
my $ftype_num = 0;
|
||||
|
||||
open FTYPES_H, "< $WSROOT/epan/ftypes/ftypes.h";
|
||||
while(<FTYPES_H>) {
|
||||
if ( /^\s+FT_([A-Z0-9a-z_]+)\s*,/ ) {
|
||||
$ft_types_table .= "\t[\"$1\"] = $ftype_num,\n";
|
||||
$ftype_num++;
|
||||
}
|
||||
}
|
||||
close FTYPES_H;
|
||||
|
||||
$ft_types_table =~ s/,\n$/\n}\n/msi;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# enum base
|
||||
#
|
||||
|
||||
$bases_table = "-- Display Bases\n base = {\n";
|
||||
$expert_pi = "-- Expert flags and facilities\n";
|
||||
|
||||
my $base_num = 0;
|
||||
|
||||
open PROTO_H, "< $WSROOT/epan/proto.h";
|
||||
while(<PROTO_H>) {
|
||||
if (/^\s+BASE_([A-Z_]+),/ ) {
|
||||
$bases_table .= "\t[\"$1\"] = $base_num,\n";
|
||||
$base_num++;
|
||||
}
|
||||
|
||||
if ( /^.define\s+(PI_[A-Z_]+)\s+((0x)?[0-9A-Fa-f]+)/ ) {
|
||||
my ($name, $value) = ($1, hex($2));
|
||||
$expert_pi .= "$name = $value\n";
|
||||
}
|
||||
}
|
||||
close PROTO_H;
|
||||
|
||||
$bases_table .= "}\n\n";
|
||||
$expert_pi .= "\n\n";
|
||||
|
||||
for my $key (keys %replacements) {
|
||||
$template =~ s/%$key%/${$replacements{$key}}/msig;
|
||||
}
|
||||
|
||||
|
||||
print $template;
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# make-reg.pl
|
||||
# Registration Macros Generator
|
||||
#
|
||||
# (c) 2006, Luis E. Garcia Onatnon <luis.ontanon@gmail.com>
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 1998 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
use strict;
|
||||
|
||||
my @classes = ();
|
||||
my @functions = ();
|
||||
|
||||
while (<>) {
|
||||
push @classes, $1 if /WSLUA_CLASS_DEFINE\050\s*([A-Za-z]+)/;
|
||||
push @functions, $1 if /WSLUA_FUNCTION\s+wslua_([a-z_]+)/;
|
||||
}
|
||||
|
||||
print "/* This file is automatically genrated by elua_makereg.pl do not edit */\n\n";
|
||||
|
||||
print "#define WSLUA_DECLARE_CLASSES() \\\n";
|
||||
for (@classes) {
|
||||
print "\tWSLUA_CLASS_DECLARE($_);\\\n"
|
||||
}
|
||||
print "\n\n";
|
||||
|
||||
print "#define WSLUA_REGISTER_CLASSES() { \\\n";
|
||||
for (@classes) {
|
||||
print "\t${_}_register(L);\\\n"
|
||||
}
|
||||
print "}\n\n";
|
||||
|
||||
print "#define WSLUA_DECLARE_FUNCTIONS() \\\n";
|
||||
for (@functions) {
|
||||
print "\tWSLUA_FUNCTION wslua_$_(lua_State* L);\\\n"
|
||||
}
|
||||
print "\n\n";
|
||||
|
||||
print "#define WSLUA_REGISTER_FUNCTIONS() {\\\n";
|
||||
for (@functions) {
|
||||
print "\t WSLUA_REGISTER_FUNCTION($_); \\\n"
|
||||
}
|
||||
print "}\n\n";
|
|
@ -0,0 +1,206 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# make-taps.pl
|
||||
# Extract structs from C headers to generate a function that
|
||||
# pushes a lua table into the stack containing the elements of
|
||||
# the struct.
|
||||
#
|
||||
# (c) 2006 Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 2006 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
use strict;
|
||||
|
||||
my %types = %{{
|
||||
'gchar[]' => 'lua_pushstring(L,(char*)v->%s);',
|
||||
'gchar*' => 'lua_pushstring(L,(char*)v->%s);',
|
||||
'guint' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'guint8' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'guint16' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'guint32' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'gint' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'gint8' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'gint16' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'gint32' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'gboolean' => 'lua_pushboolean(L,(int)v->%s);',
|
||||
'address' => '{ Address a = g_malloc(sizeof(address)); COPY_ADDRESS(a, &(v->%s)); pushAddress(L,a); }',
|
||||
'address*' => '{ Address a = g_malloc(sizeof(address)); COPY_ADDRESS(a, v->%s); pushAddress(L,a); }',
|
||||
'int' => 'lua_pushnumber(L,(lua_Number)v->%s);',
|
||||
'nstime_t' => '{lua_Number t = v->%s.secs; t += v->%s.nsecs * 1e-9; lua_pushnumber(L,t); }',
|
||||
'nstime_t*' => '{lua_Number t = v->%s->secs; t += v->%s->nsecs * 1e-9; lua_pushnumber(L,t); }',
|
||||
}};
|
||||
|
||||
my %comments = %{{
|
||||
'gchar[]' => 'string',
|
||||
'gchar*' => 'string',
|
||||
'guint' => 'number',
|
||||
'guint8' => 'number',
|
||||
'guint16' => 'number',
|
||||
'guint32' => 'number',
|
||||
'gint' => 'number',
|
||||
'gint8' => 'number',
|
||||
'gint16' => 'number',
|
||||
'gint32' => 'number',
|
||||
'gboolean' => 'boolean',
|
||||
'address' => 'Address',
|
||||
'address*' => 'Address',
|
||||
'int' => 'number',
|
||||
'nstime_t' => 'number (seconds, since 1-1-1970 if absolute)',
|
||||
'nstime_t*' => 'number (seconds, since 1-1-1970 if absolute)',
|
||||
}};
|
||||
|
||||
|
||||
my %functs = ();
|
||||
|
||||
my %enums = ();
|
||||
|
||||
sub dotap {
|
||||
my ($tname,$fname,$sname,@enums) = @_;
|
||||
my $buf = '';
|
||||
|
||||
open FILE, "< $fname";
|
||||
while(<FILE>) {
|
||||
$buf .= $_;
|
||||
}
|
||||
close FILE;
|
||||
|
||||
$buf =~ s@/\*.*?\*/@@;
|
||||
|
||||
for my $ename (@enums) {
|
||||
$enums{$ename} = [];
|
||||
my $a = $enums{$ename};
|
||||
|
||||
my $enumre = "typedef\\s+enum[^{]*{([^}]*)}[\\s\\n]*${ename}[\\s\\n]*;";
|
||||
if ($buf =~ s/$enumre//ms ) {
|
||||
$types{$ename} = "/*$ename*/ lua_pushnumber(L,(lua_Number)v->%s);";
|
||||
my $ebody = $1;
|
||||
$ebody =~ s/\s+//msg;
|
||||
$comments{$ename} = "$ename: { $ebody }";
|
||||
$comments{$ename} =~ s/,/|/g;
|
||||
for (split /,/, $ebody) {
|
||||
push @{$a}, $_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $re = "typedef\\s+struct.*?{([^}]*)}[\\s\\n]*($sname)[\\s\\n]*;";
|
||||
my $body;
|
||||
|
||||
while ($buf =~ s/$re//ms) {
|
||||
$body = $1;
|
||||
}
|
||||
|
||||
die "could not find typedef $sname in $fname" if not defined $body and $sname ne "void";
|
||||
|
||||
my %elems = ();
|
||||
|
||||
while($body =~ s/\s*(.*?)([\w\d_]+)\s*\[\s*\d+\s*\]\s*;//) {
|
||||
my ($k,$v) = ($2,$1 . "[]");
|
||||
$v =~ s/\s+//g;
|
||||
$elems{$k} = $v;
|
||||
}
|
||||
|
||||
while($body =~ s/\s*(.*?)([\w\d_]+)\s*;//) {
|
||||
my ($k,$v) = ($2,$1);
|
||||
$v =~ s/\s+//g;
|
||||
$elems{$k} = $v;
|
||||
}
|
||||
|
||||
my $code = "void wslua_${tname}_to_table(lua_State* L, const void* p) { $sname* v = (void*)p; lua_newtable(L);\n";
|
||||
my $doc = "Tap: $tname\n";
|
||||
|
||||
for my $n (sort keys %elems) {
|
||||
my $fmt = $types{$elems{$n}};
|
||||
|
||||
if ($fmt) {
|
||||
$code .= "\tlua_pushstring(L,\"$n\"); ";
|
||||
$code .= sprintf($fmt,$n,$n) . " lua_settable(L,-3);\n";
|
||||
$doc .= "\t$n: $comments{$elems{$n}}\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$code .= "}\n\n";
|
||||
$doc .= "\n";
|
||||
|
||||
$functs{$tname} = "wslua_${tname}_to_table";
|
||||
|
||||
return ($code,$doc);
|
||||
}
|
||||
|
||||
|
||||
open TAPSFILE, "< $ARGV[0]";
|
||||
open CFILE, "> $ARGV[1]";
|
||||
open DOCFILE, "> $ARGV[2]";
|
||||
|
||||
print CFILE <<"HEADER";
|
||||
/* This file is autogenerated from ./taps by ./make-taps.pl */
|
||||
/* DO NOT EDIT! */
|
||||
|
||||
HEADER
|
||||
|
||||
print DOCFILE "\n";
|
||||
|
||||
while (<TAPSFILE>) {
|
||||
s@#.*@@;
|
||||
next if /^\s*$/;
|
||||
my ($tname,$fname,$sname,@enums) = split /\s+/;
|
||||
my ($c,$doc) = dotap($tname,$fname,$sname,@enums);
|
||||
print CFILE "#include \"$fname\"\n";
|
||||
print CFILE $c;
|
||||
print DOCFILE $doc;
|
||||
}
|
||||
|
||||
print CFILE <<"TBLHDR";
|
||||
tappable_t tappables[] = {
|
||||
TBLHDR
|
||||
|
||||
for my $tname (sort keys %functs) {
|
||||
print CFILE <<"TBLELEM";
|
||||
{"$tname", $functs{$tname} },
|
||||
TBLELEM
|
||||
}
|
||||
|
||||
print CFILE <<"TBLFTR";
|
||||
{"frame",NULL},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
void set_enums(lua_State* L) {
|
||||
TBLFTR
|
||||
|
||||
|
||||
for my $ename (sort keys %enums) {
|
||||
print CFILE "\n\t/*\n\t * $ename\n\t */\n\tlua_pushstring(L,\"$ename\"); lua_newtable(L);\n";
|
||||
for my $a (@{$enums{$ename}}) {
|
||||
print CFILE <<"ENUMELEM";
|
||||
lua_pushstring(L,"$a"); lua_pushnumber(L,(lua_Number)$a); lua_settable(L,LUA_GLOBALSINDEX);
|
||||
lua_pushnumber(L,(lua_Number)$a); lua_pushstring(L,"$a"); lua_settable(L,-3);
|
||||
ENUMELEM
|
||||
}
|
||||
print CFILE "\tlua_settable(L,LUA_GLOBALSINDEX);\n";
|
||||
}
|
||||
|
||||
print CFILE "};\n";
|
||||
exit 0;
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
# taps
|
||||
# instructions for make-taps.pl to generate the taps.c file
|
||||
#
|
||||
# (c) 2006 Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 2006 Gerald Combs
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# Each line is a tap type (the data structure passed by dissectors).
|
||||
# Elements are separated by whitespace.
|
||||
# tapname source_file_for_struct typedef_name_of_struct an_enum_name another_enum_name ...
|
||||
#
|
||||
# Note: Make sure you update the taps_used variable in Makefile.am
|
||||
# every time you add a new file to the list
|
||||
|
||||
#frame ../dissectors/packet_frame.h void
|
||||
|
||||
ip ../dissectors/packet-ip.h e_ip
|
||||
udp ../dissectors/packet-udp.h e_udphdr
|
||||
http ../dissectors/packet-http.h http_info_value_t
|
||||
h225 ../dissectors/packet-h225.h h225_packet_info h225_msg_type h225_cs_type
|
||||
|
||||
#actrace
|
||||
#afp
|
||||
#ansi_a
|
||||
#ansi_map
|
||||
#bootp
|
||||
#dcerpc
|
||||
#dccp
|
||||
#dtls
|
||||
#epl
|
||||
#eth
|
||||
#fc
|
||||
#fddi
|
||||
#gsm_a
|
||||
#gsm_map
|
||||
#h245
|
||||
#h245dg
|
||||
#wlan
|
||||
#ipx
|
||||
#isup
|
||||
#jxta
|
||||
#ldap
|
||||
#mtp3
|
||||
#ncp_srt
|
||||
#ncp_hdr
|
||||
#ntlmssp
|
||||
#q931
|
||||
#rpc
|
||||
#rsvp
|
||||
#rtpevent
|
||||
#rtp
|
||||
#scsi
|
||||
#sctp
|
||||
#sdp
|
||||
#sip
|
||||
#smb
|
||||
#smb2
|
||||
#ssl
|
||||
#t38
|
||||
#tcp
|
||||
#teredo
|
||||
#tr
|
||||
#wsp
|
|
@ -0,0 +1,61 @@
|
|||
-- init.lua
|
||||
--
|
||||
-- initilaize ethereal's lua
|
||||
--
|
||||
-- This file is going to be executed before any other lua script.
|
||||
-- It can be used to load libraries, disable functions and more.
|
||||
--
|
||||
-- $Id$
|
||||
--
|
||||
-- Wireshark - Network traffic analyzer
|
||||
-- By Gerald Combs <gerald@wireshark.org>
|
||||
-- Copyright 1998 Gerald Combs
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- as published by the Free Software Foundation; either version 2
|
||||
-- of the License, or (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
-- If lua is to be disabled even if it was installed uncomment the following
|
||||
-- line.
|
||||
-- disable_lua = true; do return end;
|
||||
|
||||
|
||||
-- If set and we are running with special privileges this setting
|
||||
-- tells whether scripts other than this one are to be run.
|
||||
run_user_scripts_when_superuser = false
|
||||
|
||||
-- disable potentialy harmful lua functions when running superuser
|
||||
if running_superuser then
|
||||
dofile = function() error("dofile has been disabled") end
|
||||
loadfile = function() error("loadfile has been disabled") end
|
||||
loadlib = function() error("loadlib has been disabled") end
|
||||
require = function() error("require has been disabled") end
|
||||
os = {}
|
||||
io = {}
|
||||
file = {}
|
||||
end
|
||||
|
||||
-- to avoid output to stdout which can caause problems lua's print ()
|
||||
-- has been suppresed so that it yields an error.
|
||||
-- have print() call info() instead.
|
||||
print = info
|
||||
|
||||
-- %WTAP_ENCAPS%
|
||||
|
||||
-- %FT_TYPES%
|
||||
|
||||
-- %BASES%
|
||||
|
||||
-- %EXPERT%
|
||||
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* wslua.h
|
||||
*
|
||||
* Wireshark's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua.h 18231 2006-05-28 16:32:49Z etxrab $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _PACKET_LUA_H
|
||||
#define _PACKET_LUA_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include <wiretap/wtap.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/strutil.h>
|
||||
#include <epan/prefs.h>
|
||||
#include <epan/proto.h>
|
||||
#include <epan/epan_dissect.h>
|
||||
#include <epan/tap.h>
|
||||
#include <epan/filesystem.h>
|
||||
#include <epan/report_err.h>
|
||||
#include <epan/emem.h>
|
||||
#include <epan/funnel.h>
|
||||
#include <epan/tvbparse.h>
|
||||
#include <epan/epan.h>
|
||||
|
||||
#include "wslua_register.h"
|
||||
|
||||
#define WSLUA_INIT_ROUTINES "init_routines"
|
||||
#define LOG_DOMAIN_LUA "wslua"
|
||||
|
||||
struct _wslua_tvbrange {
|
||||
tvbuff_t* tvb;
|
||||
int offset;
|
||||
int len;
|
||||
};
|
||||
|
||||
typedef struct _wslua_field_t {
|
||||
int hfid;
|
||||
int ett;
|
||||
char* name;
|
||||
char* abbr;
|
||||
char* blob;
|
||||
enum ftenum type;
|
||||
base_display_e base;
|
||||
value_string* vs;
|
||||
guint32 mask;
|
||||
} wslua_field_t;
|
||||
|
||||
typedef enum {PREF_NONE,PREF_BOOL,PREF_UINT,PREF_STRING} pref_type_t;
|
||||
|
||||
typedef struct _wslua_pref_t {
|
||||
gchar* name;
|
||||
gchar* label;
|
||||
gchar* desc;
|
||||
pref_type_t type;
|
||||
union {
|
||||
gboolean b;
|
||||
guint u;
|
||||
const gchar* s;
|
||||
void* p;
|
||||
} value;
|
||||
|
||||
struct _wslua_pref_t* next;
|
||||
struct _wslua_proto_t* proto;
|
||||
} wslua_pref_t;
|
||||
|
||||
typedef struct _wslua_proto_t {
|
||||
gchar* name;
|
||||
gchar* desc;
|
||||
int hfid;
|
||||
int ett;
|
||||
wslua_pref_t prefs;
|
||||
int fields;
|
||||
module_t *prefs_module;
|
||||
dissector_handle_t handle;
|
||||
gboolean is_postdissector;
|
||||
} wslua_proto_t;
|
||||
|
||||
struct _wslua_distbl_t {
|
||||
dissector_table_t table;
|
||||
gchar* name;
|
||||
};
|
||||
|
||||
struct _wslua_col_info {
|
||||
column_info* cinfo;
|
||||
gint col;
|
||||
};
|
||||
|
||||
struct _wslua_treeitem {
|
||||
proto_item* item;
|
||||
proto_tree* tree;
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct _wslua_main {
|
||||
capture_options capture_opts;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef void (*tap_extractor_t)(lua_State*,const void*);
|
||||
|
||||
typedef struct { const char* name; tap_extractor_t extractor; } tappable_t;
|
||||
|
||||
typedef struct {const gchar* str; enum ftenum id; } wslua_ft_types_t;
|
||||
|
||||
typedef wslua_pref_t* Pref;
|
||||
typedef wslua_pref_t* Prefs;
|
||||
typedef struct _wslua_field_t* ProtoField;
|
||||
typedef struct _wslua_proto_t* Proto;
|
||||
typedef struct _wslua_distbl_t* DissectorTable;
|
||||
typedef dissector_handle_t Dissector;
|
||||
typedef GByteArray* ByteArray;
|
||||
typedef tvbuff_t* Tvb;
|
||||
typedef struct _wslua_tvbrange* TvbRange;
|
||||
typedef struct _wslua_col_info* Column;
|
||||
typedef column_info* Columns;
|
||||
typedef packet_info* Pinfo;
|
||||
typedef struct _wslua_treeitem* TreeItem;
|
||||
typedef address* Address;
|
||||
typedef header_field_info** Field;
|
||||
typedef field_info* FieldInfo;
|
||||
typedef struct _wslua_tap* Listener;
|
||||
typedef funnel_text_window_t* TextWindow;
|
||||
typedef wtap_dumper* Dumper;
|
||||
typedef struct lua_pseudo_header* PseudoHeader;
|
||||
typedef tvbparse_t* Parser;
|
||||
typedef tvbparse_wanted_t* Rule;
|
||||
typedef tvbparse_elem_t* Node;
|
||||
typedef tvbparse_action_t* Shortcut;
|
||||
typedef struct _wslua_main* WireShark;
|
||||
|
||||
/*
|
||||
* toXxx(L,idx) gets a Xxx from an index (Lua Error if fails)
|
||||
* checkXxx(L,idx) gets a Xxx from an index after calling check_code (No Lua Error if it fails)
|
||||
* pushXxx(L,xxx) pushes an Xxx into the stack
|
||||
* isXxx(L,idx) tests whether we have an Xxx at idx
|
||||
*
|
||||
* LUA_CLASS_DEFINE must be used without trailing ';'
|
||||
*/
|
||||
#define WSLUA_CLASS_DEFINE(C,check_code,push_code) \
|
||||
C to##C(lua_State* L, int index) { \
|
||||
C* v = (C*)lua_touserdata (L, index); \
|
||||
if (!v) luaL_typerror(L,index,#C); \
|
||||
return *v; \
|
||||
} \
|
||||
C check##C(lua_State* L, int index) { \
|
||||
C* p; \
|
||||
luaL_checktype(L,index,LUA_TUSERDATA); \
|
||||
p = (C*)luaL_checkudata(L, index, #C); \
|
||||
check_code; \
|
||||
return p ? *p : NULL; \
|
||||
} \
|
||||
C* push##C(lua_State* L, C v) { \
|
||||
C* p = lua_newuserdata(L,sizeof(C)); *p = v; \
|
||||
luaL_getmetatable(L, #C); lua_setmetatable(L, -2); \
|
||||
push_code; \
|
||||
return p; \
|
||||
}\
|
||||
gboolean is##C(lua_State* L,int i) { \
|
||||
void *p; \
|
||||
if(!lua_isuserdata(L,i)) return FALSE; \
|
||||
p = lua_touserdata(L, i); \
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, #C); \
|
||||
if (p == NULL || !lua_getmetatable(L, i) || !lua_rawequal(L, -1, -2)) p=NULL; \
|
||||
lua_pop(L, 2); \
|
||||
return p ? TRUE : FALSE; \
|
||||
} \
|
||||
C shift##C(lua_State* L,int i) { \
|
||||
C* p; \
|
||||
if(!lua_isuserdata(L,i)) return NULL; \
|
||||
p = lua_touserdata(L, i); \
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, #C); \
|
||||
if (p == NULL || !lua_getmetatable(L, i) || !lua_rawequal(L, -1, -2)) p=NULL; \
|
||||
lua_pop(L, 2); \
|
||||
if (p) { lua_remove(L,i); return *p; }\
|
||||
else return NULL;\
|
||||
} \
|
||||
int dummy##C
|
||||
|
||||
#ifdef HAVE_LUA_5_1
|
||||
|
||||
#define WSLUA_REGISTER_CLASS(C) { \
|
||||
luaL_register (L, #C, C ## _methods); \
|
||||
luaL_newmetatable (L, #C); \
|
||||
luaL_register (L, NULL, C ## _meta); \
|
||||
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); \
|
||||
}
|
||||
|
||||
#define WSLUA_REGISTER_META(C) luaL_newmetatable (L, #C); luaL_register (L, NULL, C ## _meta);
|
||||
|
||||
#define WSLUA_INIT(L) \
|
||||
L = luaL_newstate(); \
|
||||
luaL_openlibs(L); \
|
||||
WSLUA_REGISTER_CLASSES(); \
|
||||
WSLUA_REGISTER_FUNCTIONS();
|
||||
|
||||
|
||||
#else /* Lua 5.0 */
|
||||
|
||||
#define WSLUA_REGISTER_CLASS(C) { \
|
||||
luaL_openlib(L, #C, C ## _methods, 0); \
|
||||
luaL_newmetatable(L, #C); \
|
||||
luaL_openlib(L, 0, C ## _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); \
|
||||
}
|
||||
|
||||
#define WSLUA_REGISTER_META(C) luaL_newmetatable (L, #C); luaL_openlib (L, NULL, C ## _meta, 0);
|
||||
|
||||
#define WSLUA_INIT(L) \
|
||||
if ( ! L) L = lua_open(); \
|
||||
luaopen_base(L); \
|
||||
luaopen_table(L); \
|
||||
luaopen_io(L); \
|
||||
luaopen_string(L); \
|
||||
WSLUA_REGISTER_CLASSES(); \
|
||||
WSLUA_REGISTER_FUNCTIONS();
|
||||
|
||||
#endif
|
||||
|
||||
#define WSLUA_FUNCTION extern int
|
||||
#define WSLUA_REGISTER_FUNCTION(name) { lua_pushstring(L, #name); lua_pushcfunction(L, wslua_## name); lua_settable(L, LUA_GLOBALSINDEX); }
|
||||
#define WSLUA_REGISTER extern int
|
||||
|
||||
#define WSLUA_METHOD static int
|
||||
#define WSLUA_CONSTRUCTOR static int
|
||||
#define WSLUA_ATTR_SET static int
|
||||
#define WSLUA_ATTR_GET static int
|
||||
#define WSLUA_METAMETHOD static int
|
||||
|
||||
#define WSLUA_METHODS static const luaL_reg
|
||||
#define WSLUA_META static const luaL_reg
|
||||
#define WSLUA_CLASS_FNREG(class,name) { #name, class##_##name }
|
||||
|
||||
#define WSLUA_ERROR(name,error) { luaL_error(L, #name ": " error); return 0; }
|
||||
#define WSLUA_ARG_ERROR(name,attr,error) { luaL_argerror(L,WSLUA_ARG_ ## name ## _ ## attr, #name ": " error); return 0; }
|
||||
#define WSLUA_OPTARG_ERROR(name,attr,error) { luaL_argerror(L,WSLUA_OPTARG_##name##_ ##attr, #name ": " error); return 0; }
|
||||
|
||||
#define WSLUA_REG_GLOBAL_BOOL(L,n,v) { lua_pushstring(L,n); lua_pushboolean(L,v); lua_settable(L, LUA_GLOBALSINDEX); }
|
||||
#define WSLUA_REG_GLOBAL_STRING(n,v) { lua_pushstring(L,n); lua_pushstring(L,v); lua_settable(L, LUA_GLOBALSINDEX); }
|
||||
#define WSLUA_REG_GLOBAL_NUMBER(n,v) { lua_pushstring(L,n); lua_pushnumber(L,v); lua_settable(L, LUA_GLOBALSINDEX); }
|
||||
|
||||
#define WSLUA_RETURN(i) return (i);
|
||||
|
||||
#define WSLUA_API extern
|
||||
|
||||
#define NOP
|
||||
#define FAIL_ON_NULL(s) if (! *p) luaL_argerror(L,index,s)
|
||||
|
||||
|
||||
|
||||
#define WSLUA_CLASS_DECLARE(C) \
|
||||
extern C to##C(lua_State* L, int index); \
|
||||
extern C check##C(lua_State* L, int index); \
|
||||
extern C* push##C(lua_State* L, C v); \
|
||||
extern int C##_register(lua_State* L); \
|
||||
extern gboolean is##C(lua_State* L,int i); \
|
||||
extern C shift##C(lua_State* L,int i)
|
||||
|
||||
|
||||
extern packet_info* lua_pinfo;
|
||||
extern TreeItem lua_tree;
|
||||
extern tvbuff_t* lua_tvb;
|
||||
extern int lua_malformed;
|
||||
extern dissector_handle_t lua_data_handle;
|
||||
extern gboolean lua_initialized;
|
||||
extern int lua_dissectors_table_ref;
|
||||
|
||||
WSLUA_DECLARE_CLASSES()
|
||||
WSLUA_DECLARE_FUNCTIONS()
|
||||
|
||||
extern lua_State* wslua_state(void);
|
||||
|
||||
extern const gchar* lua_shiftstring(lua_State* L,int idx);
|
||||
extern void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree);
|
||||
|
||||
extern void proto_register_lua(void);
|
||||
extern GString* lua_register_all_taps(void);
|
||||
extern void lua_prime_all_fields(proto_tree* tree);
|
||||
|
||||
extern int Proto_commit(lua_State* L);
|
||||
|
||||
extern void* push_Tvb(lua_State* L, Tvb tvb);
|
||||
extern void clear_outstanding_tvbs(void);
|
||||
|
||||
extern void* push_Pinfo(lua_State* L, Pinfo p);
|
||||
extern void clear_outstanding_pinfos(void);
|
||||
|
||||
extern void* push_TreeItem(lua_State* L, TreeItem ti);
|
||||
extern void clear_outstanding_trees(void);
|
||||
|
||||
extern void wslua_print_stack(char* s, lua_State* L);
|
||||
|
||||
extern int wslua_init(lua_State* L);
|
||||
|
||||
extern int luaopen_libwireshark(lua_State* L);
|
||||
#endif
|
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
* lua_dumper.c
|
||||
*
|
||||
* Wireshark's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua_dumper.c 18231 2006-05-28 16:32:49Z etxrab $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
#include <math.h>
|
||||
|
||||
WSLUA_CLASS_DEFINE(PseudoHeader,NOP,NOP);
|
||||
/*
|
||||
A pseudoheader to be used to save captured frames.
|
||||
*/
|
||||
|
||||
enum lua_pseudoheader_type {
|
||||
PHDR_NONE,
|
||||
PHDR_ETH,
|
||||
PHDR_X25,
|
||||
PHDR_ISDN,
|
||||
PHDR_ATM,
|
||||
PHDR_ASCEND,
|
||||
PHDR_P2P,
|
||||
PHDR_WIFI,
|
||||
PHDR_COSINE,
|
||||
PHDR_IRDA,
|
||||
PHDR_NETTL,
|
||||
PHDR_MTP2,
|
||||
PHDR_K12
|
||||
};
|
||||
|
||||
struct lua_pseudo_header {
|
||||
enum lua_pseudoheader_type type;
|
||||
union wtap_pseudo_header* wph;
|
||||
};
|
||||
|
||||
WSLUA_CONSTRUCTOR PseudoHeader_none(lua_State* L) {
|
||||
/*
|
||||
Creates a "no" pseudoheader.
|
||||
|
||||
*/
|
||||
PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
|
||||
ph->type = PHDR_NONE;
|
||||
ph->wph = NULL;
|
||||
|
||||
pushPseudoHeader(L,ph);
|
||||
|
||||
WSLUA_RETURN(1);
|
||||
/* A null pseudoheader */
|
||||
}
|
||||
|
||||
WSLUA_CONSTRUCTOR PseudoHeader_eth(lua_State* L) {
|
||||
/*
|
||||
Creates an ethernet pseudoheader
|
||||
*/
|
||||
|
||||
#define WSLUA_OPTARG_PseudoHeader_eth_FCSLEN 1 /* the fcs lenght */
|
||||
|
||||
PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
|
||||
ph->type = PHDR_ETH;
|
||||
ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
|
||||
ph->wph->eth.fcs_len = luaL_optint(L,1,-1);
|
||||
|
||||
pushPseudoHeader(L,ph);
|
||||
|
||||
WSLUA_RETURN(1); /* The ethernet pseudoheader */
|
||||
}
|
||||
|
||||
WSLUA_CONSTRUCTOR PseudoHeader_atm(lua_State* L) {
|
||||
/*
|
||||
Creates an ATM pseudoheader
|
||||
*/
|
||||
#define WSLUA_OPTARG_PseudoHeader_atm_AAL 1 /* AAL number */
|
||||
#define WSLUA_OPTARG_PseudoHeader_atm_VPI 2 /* VPI */
|
||||
#define WSLUA_OPTARG_PseudoHeader_atm_VCI 3 /* VCI */
|
||||
#define WSLUA_OPTARG_PseudoHeader_atm_CHANNEL 4 /* Channel */
|
||||
#define WSLUA_OPTARG_PseudoHeader_atm_CELLS 5 /* Number of cells in the PDU */
|
||||
#define WSLUA_OPTARG_PseudoHeader_atm_AAL5U2U 6 /* AAL5 User to User indicator */
|
||||
#define WSLUA_OPTARG_PseudoHeader_atm_AAL5LEN 7 /* AAL5 Len */
|
||||
|
||||
PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
|
||||
ph->type = PHDR_ATM;
|
||||
ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
|
||||
ph->wph->atm.aal = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_AAL,5);
|
||||
ph->wph->atm.vpi = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_VPI,1);
|
||||
ph->wph->atm.vci = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_VCI,1);
|
||||
ph->wph->atm.channel = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_CHANNEL,0);
|
||||
ph->wph->atm.cells = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_CELLS,1);
|
||||
ph->wph->atm.aal5t_u2u = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_AAL5U2U,1);
|
||||
ph->wph->atm.aal5t_len = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_AAL5LEN,0);
|
||||
|
||||
pushPseudoHeader(L,ph);
|
||||
WSLUA_RETURN(1);
|
||||
/* The ATM pseudoheader */
|
||||
}
|
||||
|
||||
WSLUA_CONSTRUCTOR PseudoHeader_mtp2(lua_State* L) {
|
||||
/* Creates an MTP2 PseudoHeader */
|
||||
#define WSLUA_OPTARG_PseudoHeader_mtp2_SENT 1 /* True if the packet is sent, False if received. */
|
||||
#define WSLUA_OPTARG_PseudoHeader_mtp2_ANNEXA 2 /* True if annex A is used */
|
||||
#define WSLUA_OPTARG_PseudoHeader_mtp2_LINKNUM 3 /* Link Number */
|
||||
PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
|
||||
ph->type = PHDR_MTP2;
|
||||
ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
|
||||
ph->wph->mtp2.sent = luaL_optint(L,1,0);
|
||||
ph->wph->mtp2.annex_a_used = luaL_optint(L,2,0);
|
||||
ph->wph->mtp2.link_number = luaL_optint(L,3,0);
|
||||
|
||||
pushPseudoHeader(L,ph);
|
||||
WSLUA_RETURN(1); /* The MTP2 pseudoheader */
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int PseudoHeader_x25(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_isdn(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_ascend(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_wifi(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_cosine(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_irda(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_nettl(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
static int PseudoHeader_k12(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
|
||||
#endif
|
||||
|
||||
WSLUA_METHODS PseudoHeader_methods[] = {
|
||||
WSLUA_CLASS_FNREG(PseudoHeader,mtp2),
|
||||
WSLUA_CLASS_FNREG(PseudoHeader,atm),
|
||||
WSLUA_CLASS_FNREG(PseudoHeader,eth),
|
||||
WSLUA_CLASS_FNREG(PseudoHeader,none),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
WSLUA_META PseudoHeader_meta[] = {
|
||||
{0,0}
|
||||
};
|
||||
|
||||
int PseudoHeader_register(lua_State* L) {
|
||||
WSLUA_REGISTER_CLASS(PseudoHeader)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_CLASS_DEFINE(Dumper,FAIL_ON_NULL("Dumper already closed"),NOP);
|
||||
|
||||
static GHashTable* dumper_encaps = NULL;
|
||||
#define DUMPER_ENCAP(d) GPOINTER_TO_INT(g_hash_table_lookup(dumper_encaps,d))
|
||||
|
||||
WSLUA_CONSTRUCTOR Dumper_new(lua_State* L) {
|
||||
/*
|
||||
Creates a file to write packets.
|
||||
Dumper:new_for_current() will probably be a better choice.
|
||||
*/
|
||||
#define WSLUA_ARG_Dumper_new_FILENAME 1 /* The name of the capture file to be created */
|
||||
#define WSLUA_OPTARG_Dumper_new_FILETYPE 2 /* The type of the file to be created */
|
||||
#define WSLUA_OPTARG_Dumper_new_ENCAP 3 /* The encapsulation to be used in the file to be created */
|
||||
Dumper d;
|
||||
const char* filename = luaL_checkstring(L,1);
|
||||
int filetype = luaL_optint(L,2,WTAP_FILE_PCAP);
|
||||
int encap = luaL_optint(L,3,WTAP_ENCAP_ETHERNET);
|
||||
int err = 0;
|
||||
|
||||
if (! filename) return 0;
|
||||
|
||||
if (!wtap_dump_can_write_encap(filetype, encap))
|
||||
WSLUA_ERROR(Dumper_new,"not every filetype handles every encap");
|
||||
|
||||
d = wtap_dump_open(filename, filetype, encap,0 , FALSE, &err);
|
||||
|
||||
if (! d ) {
|
||||
/* WSLUA_ERROR("error while opening file for writing"); */
|
||||
luaL_error(L,"error while opening `%s': %s",
|
||||
filename,
|
||||
wtap_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_hash_table_insert(dumper_encaps,d,GINT_TO_POINTER(encap));
|
||||
|
||||
pushDumper(L,d);
|
||||
WSLUA_RETURN(1);
|
||||
/* The newly created Dumper object */
|
||||
}
|
||||
|
||||
WSLUA_METHOD Dumper_close(lua_State* L) {
|
||||
/* Closes a dumper */
|
||||
Dumper* dp = (Dumper*)luaL_checkudata(L, 1, "Dumper");
|
||||
int err;
|
||||
|
||||
if (! *dp)
|
||||
WSLUA_ERROR(Dumper_close,"Cannot operate on a closed dumper");
|
||||
|
||||
g_hash_table_remove(dumper_encaps,*dp);
|
||||
|
||||
if (!wtap_dump_close(*dp, &err)) {
|
||||
luaL_error(L,"error closing: %s",
|
||||
wtap_strerror(err));
|
||||
}
|
||||
|
||||
/* this way if we close a dumper any attempt to use it (for everything but GC) will yield an error */
|
||||
dp = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD Dumper_flush(lua_State* L) {
|
||||
/*
|
||||
Writes all unsaved data of a dumper to the disk.
|
||||
*/
|
||||
Dumper d = checkDumper(L,1);
|
||||
|
||||
if (!d) return 0;
|
||||
|
||||
wtap_dump_flush(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD Dumper_dump(lua_State* L) {
|
||||
/*
|
||||
Dumps an arbitrary packet.
|
||||
Note: Dumper:dump_current() will fit best in most cases.
|
||||
*/
|
||||
#define WSLUA_ARG_Dumper_dump_TIMESTAMP 2 /* The absolute timestamp the packet will have */
|
||||
#define WSLUA_ARG_Dumper_dump_PSEUDOHEADER 3 /* The Pseudoheader to use. */
|
||||
#define WSLUA_ARG_Dumper_dump_BYTEARRAY 4 /* the data to be saved */
|
||||
|
||||
Dumper d = checkDumper(L,1);
|
||||
PseudoHeader ph;
|
||||
ByteArray ba;
|
||||
struct wtap_pkthdr pkthdr;
|
||||
double ts;
|
||||
int err;
|
||||
|
||||
if (!d) return 0;
|
||||
|
||||
ts = luaL_checknumber(L,WSLUA_ARG_Dumper_dump_TIMESTAMP);
|
||||
ph = checkPseudoHeader(L,WSLUA_ARG_Dumper_dump_PSEUDOHEADER);
|
||||
|
||||
if (!ph) WSLUA_ARG_ERROR(Dumper_dump,TIMESTAMP,"need a PseudoHeader");
|
||||
|
||||
ba = checkByteArray(L,WSLUA_ARG_Dumper_dump_BYTEARRAY);
|
||||
|
||||
if (! ba) WSLUA_ARG_ERROR(Dumper_dump,BYTEARRAY,"must be a ByteArray");
|
||||
|
||||
pkthdr.ts.secs = (int)floor(ts);
|
||||
pkthdr.ts.nsecs = (int)floor(ts - pkthdr.ts.secs) * 1000000000;
|
||||
pkthdr.len = ba->len;
|
||||
pkthdr.caplen = ba->len;
|
||||
pkthdr.pkt_encap = DUMPER_ENCAP(d);
|
||||
|
||||
if (! wtap_dump(d, &pkthdr, ph->wph, ba->data, &err)) {
|
||||
luaL_error(L,"error while dumping: %s",
|
||||
wtap_strerror(err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
WSLUA_METHOD Dumper_new_for_current(lua_State* L) {
|
||||
/*
|
||||
Creates a capture file using the same encapsulation as the one of the cuurrent packet
|
||||
*/
|
||||
#define WSLUA_OPTARG_Dumper_new_for_current_FILETYPE 2 /* The file type. Defaults to pcap. */
|
||||
Dumper d;
|
||||
const char* filename = luaL_checkstring(L,1);
|
||||
int filetype = luaL_optint(L,2,WTAP_FILE_PCAP);
|
||||
int encap;
|
||||
int err = 0;
|
||||
|
||||
if (! lua_pinfo )
|
||||
WSLUA_ERROR(Dumper_new_for_current,"cannot be used outside a tap or a dissector");
|
||||
|
||||
encap = lua_pinfo->fd->lnk_t;
|
||||
|
||||
if (!wtap_dump_can_write_encap(filetype, encap)) {
|
||||
luaL_error(L,"Cannot write encap %s in filetype %s",
|
||||
wtap_encap_short_string(encap),
|
||||
wtap_file_type_string(filetype));
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = wtap_dump_open(filename, filetype, encap, 0 , FALSE, &err);
|
||||
|
||||
if (! d ) {
|
||||
luaL_error(L,"error while opening `%s': %s",
|
||||
filename,
|
||||
wtap_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
pushDumper(L,d);
|
||||
WSLUA_RETURN(1); /* The newly created Dumper Object */
|
||||
|
||||
}
|
||||
|
||||
WSLUA_METHOD Dumper_dump_current(lua_State* L) {
|
||||
/*
|
||||
Dumps the current packet as it is.
|
||||
*/
|
||||
Dumper d = checkDumper(L,1);
|
||||
struct wtap_pkthdr pkthdr;
|
||||
const guchar* data;
|
||||
tvbuff_t* data_src;
|
||||
int err = 0;
|
||||
|
||||
if (!d) return 0;
|
||||
|
||||
if (! lua_pinfo ) WSLUA_ERROR(Dumper_new_for_current,"cannot be used outside a tap or a dissector");
|
||||
|
||||
data_src = ((data_source*)(lua_pinfo->data_src->data))->tvb;
|
||||
|
||||
pkthdr.ts.secs = lua_pinfo->fd->abs_ts.secs;
|
||||
pkthdr.ts.nsecs = lua_pinfo->fd->abs_ts.nsecs;
|
||||
pkthdr.len = tvb_reported_length(data_src);
|
||||
pkthdr.caplen = tvb_length(data_src);
|
||||
pkthdr.pkt_encap = lua_pinfo->fd->lnk_t;
|
||||
|
||||
data = ep_tvb_memdup(data_src,0,pkthdr.caplen);
|
||||
|
||||
if (! wtap_dump(d, &pkthdr, lua_pinfo->pseudo_header, data, &err)) {
|
||||
luaL_error(L,"error while dumping: %s",
|
||||
wtap_strerror(err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Dumper__gc(lua_State* L) {
|
||||
Dumper* dp = (Dumper*)luaL_checkudata(L, 1, "Dumper");
|
||||
int err;
|
||||
|
||||
/* If we are Garbage Collected it means the Dumper is no longer usable. Close it */
|
||||
|
||||
if (! *dp)
|
||||
return 0; /* already closed, nothing to do! */
|
||||
|
||||
g_hash_table_remove(dumper_encaps,*dp);
|
||||
|
||||
if (!wtap_dump_close(*dp, &err)) {
|
||||
luaL_error(L,"error closing: %s",
|
||||
wtap_strerror(err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_METHODS Dumper_methods[] = {
|
||||
{"new", Dumper_new},
|
||||
{"new_for_current", Dumper_new_for_current},
|
||||
{"close", Dumper_close},
|
||||
{"flush", Dumper_flush},
|
||||
{"dump", Dumper_dump},
|
||||
{"dump_current", Dumper_dump_current},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
WSLUA_META Dumper_meta[] = {
|
||||
{"__gc", Dumper__gc},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int Dumper_register(lua_State* L) {
|
||||
dumper_encaps = g_hash_table_new(g_direct_hash,g_direct_equal);
|
||||
WSLUA_REGISTER_CLASS(Dumper);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,445 @@
|
|||
/*
|
||||
* wslua_field.c
|
||||
*
|
||||
* Wireshark's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua_field.c 18231 2006-05-28 16:32:49Z etxrab $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
|
||||
WSLUA_CLASS_DEFINE(FieldInfo,NOP,NOP);
|
||||
/*
|
||||
An extracted Field
|
||||
*/
|
||||
|
||||
WSLUA_METAMETHOD FieldInfo__len(lua_State* L) {
|
||||
/*
|
||||
The Length of the field
|
||||
*/
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
lua_pushnumber(L,fi->length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD FieldInfo__unm(lua_State* L) {
|
||||
/*
|
||||
The Offset of the field
|
||||
*/
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
lua_pushnumber(L,fi->start);
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
|
||||
/*
|
||||
The Value of the field
|
||||
*/
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
|
||||
switch(fi->hfinfo->type) {
|
||||
case FT_NONE:
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
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)));
|
||||
return 1;
|
||||
case FT_FLOAT:
|
||||
case FT_DOUBLE:
|
||||
lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value)));
|
||||
return 1;
|
||||
case FT_INT64:
|
||||
case FT_UINT64:
|
||||
/*
|
||||
* XXX: double has 53 bits integer precision, n > 2^22 will cause a loss in precision
|
||||
*/
|
||||
lua_pushnumber(L,(lua_Number)(gint64)fvalue_get_integer64(&(fi->value)));
|
||||
return 1;
|
||||
case FT_ETHER: {
|
||||
Address eth = g_malloc(sizeof(address));
|
||||
eth->type = AT_ETHER;
|
||||
eth->len = fi->length;
|
||||
eth->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
|
||||
pushAddress(L,eth);
|
||||
return 1;
|
||||
}
|
||||
case FT_IPv4:{
|
||||
Address ipv4 = g_malloc(sizeof(address));
|
||||
ipv4->type = AT_IPv4;
|
||||
ipv4->len = fi->length;
|
||||
ipv4->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
|
||||
pushAddress(L,ipv4);
|
||||
return 1;
|
||||
}
|
||||
case FT_IPv6: {
|
||||
Address ipv6 = g_malloc(sizeof(address));
|
||||
ipv6->type = AT_IPv6;
|
||||
ipv6->len = fi->length;
|
||||
ipv6->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
|
||||
pushAddress(L,ipv6);
|
||||
return 1;
|
||||
}
|
||||
case FT_IPXNET:{
|
||||
Address ipx = g_malloc(sizeof(address));
|
||||
ipx->type = AT_IPX;
|
||||
ipx->len = fi->length;
|
||||
ipx->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
|
||||
pushAddress(L,ipx);
|
||||
return 1;
|
||||
}
|
||||
case FT_STRING:
|
||||
case FT_STRINGZ:
|
||||
lua_pushstring(L,fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL));
|
||||
return 1;
|
||||
case FT_BYTES:
|
||||
case FT_UINT_BYTES:
|
||||
case FT_GUID:
|
||||
case FT_OID: {
|
||||
ByteArray ba = g_byte_array_new();
|
||||
g_byte_array_append(ba, ep_tvb_memdup(fi->ds_tvb,fi->start,fi->length),fi->length);
|
||||
pushByteArray(L,ba);
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
luaL_error(L,"FT_ not yet supported");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD FieldInfo__tostring(lua_State* L) {
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
if (fi) {
|
||||
lua_pushstring(L,fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_ATTR_GET FieldInfo_get_data_source(lua_State* L) {
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
pushTvb(L,fi->ds_tvb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_ATTR_GET FieldInfo_get_range(lua_State* L) {
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
TvbRange r = ep_alloc(sizeof(struct _wslua_tvbrange));
|
||||
|
||||
r->tvb = fi->ds_tvb;
|
||||
r->offset = fi->start;
|
||||
r->len = fi->length;
|
||||
|
||||
pushTvbRange(L,r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_ATTR_GET FieldInfo_get_hidden(lua_State* L) {
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
lua_pushboolean(L,FI_GET_FLAG(fi, FI_HIDDEN));
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_ATTR_GET FieldInfo_get_generated(lua_State* L) {
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
lua_pushboolean(L,FI_GET_FLAG(fi, FI_GENERATED));
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_ATTR_GET FieldInfo_get_name(lua_State* L) {
|
||||
FieldInfo fi = checkFieldInfo(L,1);
|
||||
lua_pushstring(L,fi->hfinfo->abbrev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_reg FieldInfo_get[] = {
|
||||
{"data_source", FieldInfo_get_data_source },
|
||||
{"range", FieldInfo_get_range},
|
||||
{"hidden", FieldInfo_get_hidden},
|
||||
{"generated", FieldInfo_get_generated},
|
||||
{"name", FieldInfo_get_name},
|
||||
{"label", FieldInfo__tostring},
|
||||
{"value", FieldInfo__call},
|
||||
{"len", FieldInfo__len},
|
||||
{"offset", FieldInfo__unm},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
WSLUA_METAMETHOD FieldInfo__index(lua_State* L) {
|
||||
/*
|
||||
Other attributes:
|
||||
*/
|
||||
const gchar* index = luaL_checkstring(L,2);
|
||||
const luaL_reg* r;
|
||||
|
||||
checkFieldInfo(L,1);
|
||||
|
||||
for (r = FieldInfo_get; r->name; r++) {
|
||||
if (g_str_equal(r->name, index)) {
|
||||
return r->func(L);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD FieldInfo__eq(lua_State* L) {
|
||||
FieldInfo l = checkFieldInfo(L,1);
|
||||
FieldInfo r = checkFieldInfo(L,2);
|
||||
|
||||
if (l->ds_tvb != r->ds_tvb)
|
||||
WSLUA_ERROR(FieldInfo__eq,"data source must be the same for both fields");
|
||||
|
||||
if (l->start <= r->start && r->start + r->length <= l->start + r->length) {
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD FieldInfo__le(lua_State* L) {
|
||||
FieldInfo l = checkFieldInfo(L,1);
|
||||
FieldInfo r = checkFieldInfo(L,2);
|
||||
|
||||
if (l->ds_tvb != r->ds_tvb)
|
||||
WSLUA_ERROR(FieldInfo__eq,"data source must be the same for both fields");
|
||||
|
||||
if (r->start + r->length <= l->start + r->length) {
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD FieldInfo__lt(lua_State* L) {
|
||||
FieldInfo l = checkFieldInfo(L,1);
|
||||
FieldInfo r = checkFieldInfo(L,2);
|
||||
|
||||
if (l->ds_tvb != r->ds_tvb)
|
||||
WSLUA_ERROR(FieldInfo__eq,"data source must be the same for both fields");
|
||||
|
||||
if ( r->start + r->length < l->start ) {
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const luaL_reg FieldInfo_meta[] = {
|
||||
{"__tostring", FieldInfo__tostring},
|
||||
{"__call", FieldInfo__call},
|
||||
{"__index", FieldInfo__index},
|
||||
{"__len", FieldInfo__len},
|
||||
{"__unm", FieldInfo__unm},
|
||||
{"__eq", FieldInfo__eq},
|
||||
{"__le", FieldInfo__le},
|
||||
{"__lt", FieldInfo__lt},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int FieldInfo_register(lua_State* L) {
|
||||
WSLUA_REGISTER_META(FieldInfo);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_FUNCTION wslua_all_field_infos(lua_State* L) {
|
||||
GPtrArray* found = lua_tree->tree ? proto_all_finfos(lua_tree->tree) : NULL;
|
||||
int items_found = 0;
|
||||
guint i;
|
||||
|
||||
if (found) {
|
||||
for (i=0; i<found->len; i++) {
|
||||
pushFieldInfo(L,g_ptr_array_index(found,i));
|
||||
items_found++;
|
||||
}
|
||||
|
||||
g_ptr_array_free(found,TRUE);
|
||||
}
|
||||
|
||||
return items_found;
|
||||
}
|
||||
|
||||
WSLUA_CLASS_DEFINE(Field,NOP,NOP);
|
||||
/*
|
||||
A Field extractor to to obtain field values.
|
||||
*/
|
||||
|
||||
static GPtrArray* wanted_fields = NULL;
|
||||
|
||||
/*
|
||||
* field extractor registartion is tricky, In order to allow
|
||||
* the user to define them in the body of the script we will
|
||||
* populate the Field value with a pointer of the abbrev of it
|
||||
* to later replace it with the hfi.
|
||||
*
|
||||
* This will be added to the wanted_fields array that will
|
||||
* exists only while they can be defined, and be cleared right
|
||||
* after the fields are primed.
|
||||
*/
|
||||
|
||||
void lua_prime_all_fields(proto_tree* tree _U_) {
|
||||
GString* fake_tap_filter = g_string_new("frame");
|
||||
guint i;
|
||||
static gboolean fake_tap = FALSE;
|
||||
|
||||
for(i=0; i < wanted_fields->len; i++) {
|
||||
Field f = g_ptr_array_index(wanted_fields,i);
|
||||
gchar* name = *((gchar**)f);
|
||||
|
||||
*f = proto_registrar_get_byname(name);
|
||||
|
||||
if (!*f) {
|
||||
report_failure("Could not find field `%s'",name);
|
||||
*f = NULL;
|
||||
g_free(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
g_free(name);
|
||||
|
||||
g_string_sprintfa(fake_tap_filter," || %s",(*f)->abbrev);
|
||||
fake_tap = TRUE;
|
||||
}
|
||||
|
||||
g_ptr_array_free(wanted_fields,TRUE);
|
||||
wanted_fields = NULL;
|
||||
|
||||
if (fake_tap) {
|
||||
/* a boring tap :-) */
|
||||
GString* error = register_tap_listener("frame",
|
||||
&fake_tap,
|
||||
fake_tap_filter->str,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (error) {
|
||||
report_failure("while registering lua_fake_tap:\n%s",error->str);
|
||||
g_string_free(error,TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WSLUA_CONSTRUCTOR Field_new(lua_State *L) {
|
||||
/*
|
||||
Create a Field extractor
|
||||
*/
|
||||
#define WSLUA_ARG_Field_new_FIELDNAME 1 /* The filter name of the field (e.g. ip.addr) */
|
||||
const gchar* name = luaL_checkstring(L,WSLUA_ARG_Field_new_FIELDNAME);
|
||||
Field f;
|
||||
|
||||
if (!name) return 0;
|
||||
|
||||
if (!proto_registrar_get_byname(name))
|
||||
WSLUA_ARG_ERROR(Field_new,FIELDNAME,"a field with this name must exist");
|
||||
|
||||
if (!wanted_fields)
|
||||
WSLUA_ERROR(Field_get,"a Field extractor must be defined before Taps or Dissectors get called");
|
||||
|
||||
f = g_malloc(sizeof(void*));
|
||||
*f = (header_field_info*)g_strdup(name); /* cheating */
|
||||
|
||||
g_ptr_array_add(wanted_fields,f);
|
||||
|
||||
pushField(L,f);
|
||||
WSLUA_RETURN(1); /* The field extractor */
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD Field__call (lua_State* L) {
|
||||
Field f = checkField(L,1);
|
||||
header_field_info* in = *f;
|
||||
int items_found = 0;
|
||||
|
||||
if (! in) {
|
||||
luaL_error(L,"invalid field");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! lua_pinfo ) {
|
||||
WSLUA_ERROR(Field__call,"fields cannot be used outside dissectors or taps");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (;in;in = in->same_name_next) {
|
||||
GPtrArray* found = proto_get_finfo_ptr_array(lua_tree->tree, in->id);
|
||||
guint i;
|
||||
if (found) {
|
||||
for (i=0; i<found->len; i++) {
|
||||
pushFieldInfo(L,g_ptr_array_index(found,i));
|
||||
items_found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_RETURN(items_found); /* All the values of this field */
|
||||
}
|
||||
|
||||
static int Field_tostring(lua_State* L) {
|
||||
Field f = checkField(L,1);
|
||||
|
||||
if ( !(f && *f) ) {
|
||||
luaL_error(L,"invalid Field");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wanted_fields) {
|
||||
lua_pushstring(L,*((gchar**)f));
|
||||
} else {
|
||||
lua_pushstring(L,(*f)->abbrev);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_reg Field_methods[] = {
|
||||
{"new", Field_new},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static const luaL_reg Field_meta[] = {
|
||||
{"__tostring", Field_tostring},
|
||||
{"__call", Field__call},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int Field_register(lua_State* L) {
|
||||
|
||||
wanted_fields = g_ptr_array_new();
|
||||
|
||||
WSLUA_REGISTER_CLASS(Field);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,508 @@
|
|||
/*
|
||||
* lua_gui.c
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua_gui.c 18611 2006-06-29 13:49:56Z lego $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
|
||||
static const funnel_ops_t* ops = NULL;
|
||||
|
||||
struct _lua_menu_data {
|
||||
lua_State* L;
|
||||
int cb_ref;
|
||||
int data_ref;
|
||||
};
|
||||
|
||||
static int menu_cb_error_handler(lua_State* L) {
|
||||
const gchar* error = lua_tostring(L,1);
|
||||
report_failure("Lua: Error During execution of Menu Callback:\n %s",error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_FUNCTION wslua_gui_enabled(lua_State* L) { /* Checks whether the GUI facility is enabled. */
|
||||
lua_pushboolean(L,GPOINTER_TO_INT(ops));
|
||||
WSLUA_RETURN(1); /* A boolean: true if it is enabled, false if it isn't. */
|
||||
}
|
||||
|
||||
void lua_menu_callback(gpointer data) {
|
||||
struct _lua_menu_data* md = data;
|
||||
|
||||
lua_pushcfunction(md->L,menu_cb_error_handler);
|
||||
lua_rawgeti(md->L, LUA_REGISTRYINDEX, md->cb_ref);
|
||||
lua_rawgeti(md->L, LUA_REGISTRYINDEX, md->data_ref);
|
||||
|
||||
lua_pcall(md->L,1,0,1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
WSLUA_FUNCTION wslua_register_menu(lua_State* L) { /* Register a menu item in the Statistics menu. */
|
||||
#define WSLUA_ARG_register_menu_NAME 1 /* The name of the menu item. */
|
||||
#define WSLUA_ARG_register_menu_ACTION 2 /* The function to be called when the menu item is invoked. */
|
||||
#define WSLUA_OPTARG_register_menu_USERDATA 3 /* To be passed to the action. */
|
||||
|
||||
const gchar* name = luaL_checkstring(L,WSLUA_ARG_register_menu_NAME);
|
||||
struct _lua_menu_data* md;
|
||||
gboolean retap = FALSE;
|
||||
|
||||
if(!name)
|
||||
WSLUA_ARG_ERROR(register_menu,NAME,"must be a string");
|
||||
|
||||
if (!lua_isfunction(L,WSLUA_ARG_register_menu_ACTION))
|
||||
WSLUA_ARG_ERROR(register_menu,ACTION,"must be a function");
|
||||
|
||||
md = g_malloc(sizeof(struct _lua_menu_data));
|
||||
md->L = L;
|
||||
|
||||
lua_pushvalue(L, 2);
|
||||
md->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
if ( lua_gettop(L) > 2) {
|
||||
lua_pushvalue(L, WSLUA_OPTARG_register_menu_USERDATA);
|
||||
md->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
} else {
|
||||
md->data_ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
funnel_register_menu(name,
|
||||
REGISTER_STAT_GROUP_GENERIC,
|
||||
lua_menu_callback,
|
||||
md,
|
||||
retap);
|
||||
|
||||
WSLUA_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct _dlg_cb_data {
|
||||
lua_State* L;
|
||||
int func_ref;
|
||||
int data_ref;
|
||||
};
|
||||
|
||||
static int dlg_cb_error_handler(lua_State* L) {
|
||||
const gchar* error = lua_tostring(L,1);
|
||||
report_failure("Lua: Error During execution of dialog callback:\n %s",error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lua_dialog_cb(gchar** user_input, void* data) {
|
||||
struct _dlg_cb_data* dcbd = data;
|
||||
int i = 0;
|
||||
gchar* input;
|
||||
lua_State* L = dcbd->L;
|
||||
|
||||
lua_settop(L,0);
|
||||
lua_pushcfunction(L,dlg_cb_error_handler);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, dcbd->func_ref);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, dcbd->data_ref);
|
||||
|
||||
for (i = 0; (input = user_input[i]) ; i++) {
|
||||
lua_pushstring(L,input);
|
||||
g_free(input);
|
||||
}
|
||||
|
||||
g_free(user_input);
|
||||
|
||||
switch ( lua_pcall(L,i+1,0,1) ) {
|
||||
case 0:
|
||||
break;
|
||||
case LUA_ERRRUN:
|
||||
g_warning("Runtime error while calling dialog callback");
|
||||
break;
|
||||
case LUA_ERRMEM:
|
||||
g_warning("Memory alloc error while calling dialog callback");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WSLUA_FUNCTION wslua_new_dialog(lua_State* L) { /* Pops up a new dialog */
|
||||
#define WSLUA_ARG_new_dialog_TITLE 1 /* Title of the dialog's window. */
|
||||
#define WSLUA_ARG_new_dialog_ACTION 2 /* Action to be performed when OKd. */
|
||||
/* WSLUA_MOREARGS new_dialog A series of strings to be used as labels of the dialog's fields */
|
||||
|
||||
const gchar* title;
|
||||
int top = lua_gettop(L);
|
||||
int i;
|
||||
GPtrArray* labels;
|
||||
struct _dlg_cb_data* dcbd;
|
||||
|
||||
if (! ops) {
|
||||
luaL_error(L,"the GUI facility has to be enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! (title = luaL_checkstring(L,WSLUA_ARG_new_dialog_TITLE)) ) {
|
||||
WSLUA_ARG_ERROR(new_dialog,TITLE,"must be a string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! lua_isfunction(L,WSLUA_ARG_new_dialog_ACTION)) {
|
||||
WSLUA_ARG_ERROR(new_dialog,ACTION,"must be a function");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (top < 3) {
|
||||
WSLUA_ERROR(new_dialog,"at least one field required");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
dcbd = g_malloc(sizeof(struct _dlg_cb_data));
|
||||
dcbd->L = L;
|
||||
|
||||
lua_remove(L,1);
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
dcbd->func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_remove(L,1);
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
dcbd->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_remove(L,1);
|
||||
|
||||
labels = g_ptr_array_new();
|
||||
|
||||
top -= 3;
|
||||
|
||||
for (i = 1; i <= top; i++) {
|
||||
gchar* label = (void*)luaL_checkstring(L,i);
|
||||
|
||||
/* XXX leaks labels on error */
|
||||
if (! label)
|
||||
WSLUA_ERROR(new_dialog,"all fields must be strings");
|
||||
|
||||
g_ptr_array_add(labels,label);
|
||||
}
|
||||
|
||||
g_ptr_array_add(labels,NULL);
|
||||
|
||||
ops->new_dialog(title, (const gchar**)labels->pdata, lua_dialog_cb, dcbd);
|
||||
|
||||
g_ptr_array_free(labels,TRUE);
|
||||
|
||||
WSLUA_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
WSLUA_CLASS_DEFINE(TextWindow,NOP,NOP); /* Manages a text window. */
|
||||
|
||||
WSLUA_CONSTRUCTOR TextWindow_new(lua_State* L) { /* Creates a new TextWindow. */
|
||||
#define WSLUA_OPTARG_TextWindow_new_TITLE 1 /* Title of the new window. */
|
||||
|
||||
const gchar* title;
|
||||
TextWindow tw;
|
||||
|
||||
title = luaL_optstring(L,WSLUA_OPTARG_TextWindow_new_TITLE,"Untitled Window");
|
||||
tw = ops->new_text_window(title);
|
||||
pushTextWindow(L,tw);
|
||||
|
||||
WSLUA_RETURN(1); /* The newly created TextWindow object. */
|
||||
}
|
||||
|
||||
struct _close_cb_data {
|
||||
lua_State* L;
|
||||
int func_ref;
|
||||
int data_ref;
|
||||
};
|
||||
|
||||
int text_win_close_cb_error_handler(lua_State* L) {
|
||||
const gchar* error = lua_tostring(L,1);
|
||||
report_failure("Lua: Error During execution of TextWindow close callback:\n %s",error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void text_win_close_cb(void* data) {
|
||||
struct _close_cb_data* cbd = data;
|
||||
lua_State* L = cbd->L;
|
||||
|
||||
lua_pushcfunction(L,text_win_close_cb_error_handler);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, cbd->func_ref);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, cbd->data_ref);
|
||||
|
||||
switch ( lua_pcall(L,1,0,1) ) {
|
||||
case 0:
|
||||
break;
|
||||
case LUA_ERRRUN:
|
||||
g_warning("Runtime error during execution of TextWindow close callback");
|
||||
break;
|
||||
case LUA_ERRMEM:
|
||||
g_warning("Memory alloc error during execution of TextWindow close callback");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_METHOD TextWindow_set_atclose(lua_State* L) { /* Set the function that will be called when the window closes */
|
||||
#define WSLUA_ARG_TextWindow_at_close_ACTION 2 /* A function to be executed when the user closes the window */
|
||||
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
struct _close_cb_data* cbd;
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_at_close,"cannot be called for something not a TextWindow");
|
||||
|
||||
lua_settop(L,3);
|
||||
|
||||
if (! lua_isfunction(L,2))
|
||||
WSLUA_ARG_ERROR(TextWindow_at_close,ACTION,"must be a function");
|
||||
|
||||
cbd = g_malloc(sizeof(struct _close_cb_data));
|
||||
|
||||
cbd->L = L;
|
||||
cbd->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
cbd->func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
ops->set_close_cb(tw,text_win_close_cb,cbd);
|
||||
|
||||
pushTextWindow(L,tw);
|
||||
WSLUA_RETURN(1); /* The TextWindow object. */
|
||||
}
|
||||
|
||||
WSLUA_METHOD TextWindow_set(lua_State* L) { /* Sets the text. */
|
||||
#define WSLUA_ARG_TextWindow_set_TEXT 2 /* The text to be used. */
|
||||
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
const gchar* text = luaL_checkstring(L,2);
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_set,"cannot be called for something not a TextWindow");
|
||||
|
||||
if (!text)
|
||||
WSLUA_ARG_ERROR(TextWindow_set,TEXT,"must be a string");
|
||||
|
||||
ops->set_text(tw,text);
|
||||
|
||||
pushTextWindow(L,tw);
|
||||
WSLUA_RETURN(1); /* The TextWindow object. */
|
||||
}
|
||||
|
||||
WSLUA_METHOD TextWindow_append(lua_State* L) { /* Appends text */
|
||||
#define WSLUA_ARG_TextWindow_append_TEXT 2 /* The text to be appended */
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
const gchar* text = luaL_checkstring(L,2);
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_append,"cannot be called for something not a TextWindow");
|
||||
|
||||
if (!text)
|
||||
WSLUA_ARG_ERROR(TextWindow_append,TEXT,"must be a string");
|
||||
|
||||
ops->append_text(tw,text);
|
||||
|
||||
pushTextWindow(L,tw);
|
||||
WSLUA_RETURN(1); /* The TextWindow object. */
|
||||
}
|
||||
|
||||
WSLUA_METHOD TextWindow_prepend(lua_State* L) { /* Prepends text */
|
||||
#define WSLUA_ARG_TextWindow_prepend_TEXT 2 /* The text to be appended */
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
const gchar* text = luaL_checkstring(L,2);
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_prepend,"cannot be called for something not a TextWindow");
|
||||
|
||||
if (!text)
|
||||
WSLUA_ARG_ERROR(TextWindow_prepend,TEXT,"must be a string");
|
||||
|
||||
ops->prepend_text(tw,text);
|
||||
|
||||
pushTextWindow(L,tw);
|
||||
WSLUA_RETURN(1); /* The TextWindow object. */
|
||||
}
|
||||
|
||||
WSLUA_METHOD TextWindow_clear(lua_State* L) { /* Errases all text in the window. */
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_clear,"cannot be called for something not a TextWindow");
|
||||
|
||||
ops->clear_text(tw);
|
||||
|
||||
pushTextWindow(L,tw);
|
||||
WSLUA_RETURN(1); /* The TextWindow object. */
|
||||
}
|
||||
|
||||
WSLUA_METHOD TextWindow_get_text(lua_State* L) { /* Get the text of the window */
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
const gchar* text;
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_get_text,"cannot be called for something not a TextWindow");
|
||||
|
||||
text = ops->get_text(tw);
|
||||
|
||||
lua_pushstring(L,text);
|
||||
WSLUA_RETURN(1); /* The TextWindow's text. */
|
||||
}
|
||||
|
||||
static int TextWindow__gc(lua_State* L) {
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_gc,"cannot be called for something not a TextWindow");
|
||||
|
||||
ops->destroy_text_window(tw);
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METHOD TextWindow_set_editable(lua_State* L) { /* Set the function that will be called when the window closes */
|
||||
#define WSLUA_OPTARG_TextWindow_at_close_EDITABLE 2 /* A boolean flag, defaults to true */
|
||||
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
gboolean editable = luaL_optint(L,2,1);
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_at_close,"cannot be called for something not a TextWindow");
|
||||
|
||||
if (ops->set_editable)
|
||||
ops->set_editable(tw,editable);
|
||||
|
||||
pushTextWindow(L,tw);
|
||||
WSLUA_RETURN(1); /* The TextWindow object. */
|
||||
}
|
||||
|
||||
typedef struct _wslua_bt_cb_t {
|
||||
lua_State* L;
|
||||
int func_ref;
|
||||
int data_ref;
|
||||
} wslua_bt_cb_t;
|
||||
|
||||
static gboolean wslua_button_callback(funnel_text_window_t* tw, void* data) {
|
||||
wslua_bt_cb_t* cbd = data;
|
||||
lua_State* L = cbd->L;
|
||||
|
||||
lua_settop(L,0);
|
||||
lua_pushcfunction(L,dlg_cb_error_handler);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, cbd->func_ref);
|
||||
pushTextWindow(L,tw);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, cbd->data_ref);
|
||||
|
||||
switch ( lua_pcall(L,2,0,1) ) {
|
||||
case 0:
|
||||
break;
|
||||
case LUA_ERRRUN:
|
||||
g_warning("Runtime error while calling button callback");
|
||||
break;
|
||||
case LUA_ERRMEM:
|
||||
g_warning("Memory alloc error while calling button callback");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WSLUA_METHOD TextWindow_add_button(lua_State* L) {
|
||||
#define WSLUA_ARG_TextWindow_add_button_LABEL 2 /* The label of the button */
|
||||
#define WSLUA_ARG_TextWindow_add_button_FUNCTION 3 /* The function to be called when clicked */
|
||||
#define WSLUA_ARG_TextWindow_add_button_DATA 4 /* The data to be passed to the function (other than the window) */
|
||||
TextWindow tw = checkTextWindow(L,1);
|
||||
const gchar* label = luaL_checkstring(L,WSLUA_ARG_TextWindow_add_button_LABEL);
|
||||
|
||||
funnel_bt_t* fbt;
|
||||
wslua_bt_cb_t* cbd;
|
||||
|
||||
if (!tw)
|
||||
WSLUA_ERROR(TextWindow_at_close,"cannot be called for something not a TextWindow");
|
||||
|
||||
if (! lua_isfunction(L,WSLUA_ARG_TextWindow_add_button_FUNCTION) )
|
||||
WSLUA_ARG_ERROR(TextWindow_add_button,FUNCTION,"must be a function");
|
||||
|
||||
lua_settop(L,4);
|
||||
|
||||
if (ops->add_button) {
|
||||
fbt = ep_alloc(sizeof(funnel_bt_t));
|
||||
cbd = ep_alloc(sizeof(wslua_bt_cb_t));
|
||||
|
||||
fbt->tw = tw;
|
||||
fbt->func = wslua_button_callback;
|
||||
fbt->data = cbd;
|
||||
|
||||
cbd->L = L;
|
||||
cbd->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
cbd->func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
ops->add_button(tw,fbt,label);
|
||||
}
|
||||
|
||||
pushTextWindow(L,tw);
|
||||
WSLUA_RETURN(1); /* The TextWindow object. */
|
||||
}
|
||||
|
||||
WSLUA_METHODS TextWindow_methods[] = {
|
||||
WSLUA_CLASS_FNREG(TextWindow,new),
|
||||
WSLUA_CLASS_FNREG(TextWindow,set),
|
||||
WSLUA_CLASS_FNREG(TextWindow,new),
|
||||
WSLUA_CLASS_FNREG(TextWindow,append),
|
||||
WSLUA_CLASS_FNREG(TextWindow,prepend),
|
||||
WSLUA_CLASS_FNREG(TextWindow,clear),
|
||||
WSLUA_CLASS_FNREG(TextWindow,set_atclose),
|
||||
WSLUA_CLASS_FNREG(TextWindow,set_editable),
|
||||
WSLUA_CLASS_FNREG(TextWindow,get_text),
|
||||
WSLUA_CLASS_FNREG(TextWindow,add_button),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
WSLUA_META TextWindow_meta[] = {
|
||||
{"__tostring", TextWindow_get_text},
|
||||
{"__gc", TextWindow__gc},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int TextWindow_register(lua_State* L) {
|
||||
|
||||
ops = funnel_get_funnel_ops();
|
||||
|
||||
WSLUA_REGISTER_CLASS(TextWindow);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_FUNCTION wslua_retap_packets(lua_State* L) {
|
||||
/*
|
||||
Rescan all packets and just run taps - don't reconstruct the display.
|
||||
*/
|
||||
if ( ops->retap_packets ) {
|
||||
ops->retap_packets();
|
||||
} else {
|
||||
WSLUA_ERROR(wslua_retap_packets, "does not work on TShark");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* wslua_tap.c
|
||||
*
|
||||
* Wireshark's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua_tap.c 18268 2006-05-31 17:38:42Z gerald $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
|
||||
/* generated file gets included */
|
||||
#include "taps.c-inc"
|
||||
|
||||
WSLUA_CLASS_DEFINE(Listener,NOP,NOP);
|
||||
/*
|
||||
A Listener, is called once for every packet that matches a certain filter or has a certain tap.
|
||||
It can read the tree, the packet's Tvb eventually the tapped data but it cannot
|
||||
add elements to the tree.
|
||||
*/
|
||||
struct _wslua_tap {
|
||||
gchar* name;
|
||||
gchar* filter;
|
||||
tap_extractor_t extractor;
|
||||
lua_State* L;
|
||||
int packet_ref;
|
||||
int draw_ref;
|
||||
int init_ref;
|
||||
};
|
||||
|
||||
tap_extractor_t get_extractor(const gchar* name) {
|
||||
tappable_t* t;
|
||||
for(t = tappables; t->name; t++ ) {
|
||||
if (g_str_equal(t->name,name)) return t->extractor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int tap_packet_cb_error_handler(lua_State* L) {
|
||||
const gchar* error = lua_tostring(L,1);
|
||||
static gchar* last_error = NULL;
|
||||
static int repeated = 0;
|
||||
static int next = 2;
|
||||
const gchar* where = (lua_pinfo) ?
|
||||
ep_strdup_printf("Lua: on packet %i Error During execution of Listener Packet Callback",lua_pinfo->fd->num) :
|
||||
ep_strdup_printf("Lua: Error During execution of Listener Packet Callback") ;
|
||||
|
||||
/* show the error the 1st, 3rd, 5th, 9th, 17th, 33th... time it appears to avoid window flooding */
|
||||
/* XXX the last series of identical errors won't be shown (the user however gets at least one message) */
|
||||
|
||||
if (! last_error) {
|
||||
report_failure("%s:\n%s",where,error);
|
||||
last_error = g_strdup(error);
|
||||
repeated = 0;
|
||||
next = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_str_equal(last_error,error) ) {
|
||||
repeated++;
|
||||
if ( repeated == next ) {
|
||||
report_failure("%s happened %i times:\n %s",where,repeated,error);
|
||||
next *= 2;
|
||||
}
|
||||
} else {
|
||||
report_failure("%s happened %i times:\n %s",where,repeated,last_error);
|
||||
g_free(last_error);
|
||||
last_error = g_strdup(error);
|
||||
repeated = 0;
|
||||
next = 2;
|
||||
report_failure("%s:\n %s",where,error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int lua_tap_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data) {
|
||||
Listener tap = tapdata;
|
||||
int retval = 0;
|
||||
|
||||
if (tap->packet_ref == LUA_NOREF) return 0;
|
||||
|
||||
lua_settop(tap->L,0);
|
||||
|
||||
lua_pushcfunction(tap->L,tap_packet_cb_error_handler);
|
||||
lua_rawgeti(tap->L, LUA_REGISTRYINDEX, tap->packet_ref);
|
||||
|
||||
push_Pinfo(tap->L, pinfo);
|
||||
push_Tvb(tap->L, edt->tvb);
|
||||
|
||||
if (tap->extractor) {
|
||||
tap->extractor(tap->L,data);
|
||||
} else {
|
||||
lua_pushnil(tap->L);
|
||||
}
|
||||
|
||||
lua_pinfo = pinfo;
|
||||
lua_tvb = edt->tvb;
|
||||
lua_tree = ep_alloc(sizeof(struct _wslua_treeitem));
|
||||
lua_tree->tree = edt->tree;
|
||||
lua_tree->item = NULL;
|
||||
|
||||
switch ( lua_pcall(tap->L,3,1,1) ) {
|
||||
case 0:
|
||||
|
||||
if (lua_gettop(tap->L) == 1)
|
||||
retval = luaL_checkint(tap->L,1);
|
||||
else
|
||||
retval = 1;
|
||||
|
||||
break;
|
||||
case LUA_ERRRUN:
|
||||
break;
|
||||
case LUA_ERRMEM:
|
||||
g_warning("Memory alloc error while calling listenet tap callback packet");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
clear_outstanding_pinfos();
|
||||
clear_outstanding_tvbs();
|
||||
|
||||
lua_pinfo = NULL;
|
||||
lua_tvb = NULL;
|
||||
lua_tree = NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int tap_reset_cb_error_handler(lua_State* L) {
|
||||
const gchar* error = lua_tostring(L,1);
|
||||
report_failure("Lua: Error During execution of Listener init Callback:\n %s",error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void lua_tap_reset(void *tapdata) {
|
||||
Listener tap = tapdata;
|
||||
|
||||
if (tap->init_ref == LUA_NOREF) return;
|
||||
|
||||
lua_pushcfunction(tap->L,tap_reset_cb_error_handler);
|
||||
lua_rawgeti(tap->L, LUA_REGISTRYINDEX, tap->init_ref);
|
||||
|
||||
switch ( lua_pcall(tap->L,0,0,1) ) {
|
||||
case 0:
|
||||
break;
|
||||
case LUA_ERRRUN:
|
||||
g_warning("Runtime error while calling a listener's init()");
|
||||
break;
|
||||
case LUA_ERRMEM:
|
||||
g_warning("Memory alloc error while calling a listener's init()");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int tap_draw_cb_error_handler(lua_State* L) {
|
||||
const gchar* error = lua_tostring(L,1);
|
||||
report_failure("Lua: Error During execution of Listener Draw Callback:\n %s",error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void lua_tap_draw(void *tapdata) {
|
||||
Listener tap = tapdata;
|
||||
const gchar* error;
|
||||
if (tap->draw_ref == LUA_NOREF) return;
|
||||
|
||||
lua_pushcfunction(tap->L,tap_reset_cb_error_handler);
|
||||
lua_rawgeti(tap->L, LUA_REGISTRYINDEX, tap->draw_ref);
|
||||
|
||||
switch ( lua_pcall(tap->L,0,0,1) ) {
|
||||
case 0:
|
||||
/* OK */
|
||||
break;
|
||||
case LUA_ERRRUN:
|
||||
error = lua_tostring(tap->L,-1);
|
||||
g_warning("Runtime error while calling a listener's draw(): %s",error);
|
||||
break;
|
||||
case LUA_ERRMEM:
|
||||
g_warning("Memory alloc error while calling a listener's draw()");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_CONSTRUCTOR Listener_new(lua_State* L) {
|
||||
/* Creates a new Listener listener */
|
||||
#define WSLUA_OPTARG_Listener_new_TAP 1 /* the name of this tap */
|
||||
#define WSLUA_OPTARG_Listener_new_FILTER 2 /* a filter that when matches the tap.packet function gets called (use nil to be called for every packet) */
|
||||
|
||||
const gchar* tap_type = luaL_optstring(L,WSLUA_OPTARG_Listener_new_TAP,"frame");
|
||||
const gchar* filter = luaL_optstring(L,WSLUA_OPTARG_Listener_new_FILTER,NULL);
|
||||
Listener tap;
|
||||
GString* error;
|
||||
|
||||
tap = g_malloc(sizeof(struct _wslua_tap));
|
||||
|
||||
tap->name = g_strdup(tap_type);
|
||||
tap->filter = filter ? g_strdup(filter) : NULL;
|
||||
tap->extractor = get_extractor(tap_type);
|
||||
tap->L = L;
|
||||
tap->packet_ref = LUA_NOREF;
|
||||
tap->draw_ref = LUA_NOREF;
|
||||
tap->init_ref = LUA_NOREF;
|
||||
|
||||
error = register_tap_listener(tap_type, tap, tap->filter, lua_tap_reset, lua_tap_packet, lua_tap_draw);
|
||||
|
||||
if (error) {
|
||||
if (tap->filter) g_free(tap->filter);
|
||||
g_free(tap->name);
|
||||
g_free(tap);
|
||||
/* WSLUA_ERROR(new_tap,"tap registration error"); */
|
||||
luaL_error(L,"Error while registering tap:\n%s",error->str);
|
||||
g_string_free(error,TRUE); /* XXX LEAK? */
|
||||
}
|
||||
|
||||
pushListener(L,tap);
|
||||
WSLUA_RETURN(1); /* The newly created Listener listener object */
|
||||
}
|
||||
|
||||
WSLUA_METHOD Listener_remove(lua_State* L) {
|
||||
/* Removes a tap listener */
|
||||
Listener tap = checkListener(L,1);
|
||||
|
||||
if (!tap) return 0;
|
||||
|
||||
remove_tap_listener(tap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Listener_tostring(lua_State* L) {
|
||||
Listener tap = checkListener(L,1);
|
||||
gchar* str;
|
||||
|
||||
if (!tap) return 0;
|
||||
|
||||
str = g_strdup_printf("Listener(%s) filter: %s",tap->name, tap->filter ? tap->filter : "NONE");
|
||||
lua_pushstring(L,str);
|
||||
g_free(str);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int Listener_newindex(lua_State* L) {
|
||||
/* WSLUA_ATTRIBUTE Listener_packet WO A function that will be called once every packet matches the Listener listener filter.
|
||||
|
||||
function tap.packet(pinfo,tvb,userdata) ... end
|
||||
*/
|
||||
/* WSLUA_ATTRIBUTE Listener_draw WO A function that will be called once every few seconds to redraw the gui objects
|
||||
in tshark this funtion is called oly at the very end of the capture file.
|
||||
|
||||
function tap.draw(userdata) ... end
|
||||
*/
|
||||
/* WSLUA_ATTRIBUTE Listener_reset WO A function that will be called at the end of the capture run.
|
||||
|
||||
function tap.reset(userdata) ... end
|
||||
*/
|
||||
Listener tap = shiftListener(L,1);
|
||||
const gchar* index = lua_shiftstring(L,1);
|
||||
int* refp = NULL;
|
||||
|
||||
if (!index) return 0;
|
||||
|
||||
if (g_str_equal(index,"packet")) {
|
||||
refp = &(tap->packet_ref);
|
||||
} else if (g_str_equal(index,"draw")) {
|
||||
refp = &(tap->draw_ref);
|
||||
} else if (g_str_equal(index,"reset")) {
|
||||
refp = &(tap->init_ref);
|
||||
} else {
|
||||
luaL_error(L,"No such attribute `%s' for a tap",index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! lua_isfunction(L,1)) {
|
||||
luaL_error(L,"Listener's attribute `%s' must be a function");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
*refp = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const luaL_reg Listener_methods[] = {
|
||||
{"new", Listener_new},
|
||||
{"remove", Listener_remove},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static const luaL_reg Listener_meta[] = {
|
||||
{"__tostring", Listener_tostring},
|
||||
{"__newindex", Listener_newindex},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int Listener_register(lua_State* L) {
|
||||
WSLUA_REGISTER_CLASS(Listener);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,888 @@
|
|||
/*
|
||||
* wslua_pinfo.c
|
||||
*
|
||||
* Wireshark's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua_pinfo.c 18231 2006-05-28 16:32:49Z etxrab $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
|
||||
#include <epan/addr_resolv.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* NULLify lua userdata to avoid crashing when trying to
|
||||
* access saved copies of invalid stuff.
|
||||
*
|
||||
* see comment on lua_tvb.c
|
||||
*/
|
||||
|
||||
static GPtrArray* outstanding_stuff = NULL;
|
||||
|
||||
void clear_outstanding_pinfos(void) {
|
||||
while (outstanding_stuff->len) {
|
||||
void** p = (void**)g_ptr_array_remove_index_fast(outstanding_stuff,0);
|
||||
*p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void* push_Pinfo(lua_State* L, Pinfo pinfo) {
|
||||
void** p = (void**)pushPinfo(L,pinfo);
|
||||
g_ptr_array_add(outstanding_stuff,p);
|
||||
return p;
|
||||
}
|
||||
|
||||
#define PUSH_COLUMN(L,c) g_ptr_array_add(outstanding_stuff,pushColumn(L,c))
|
||||
#define PUSH_COLUMNS(L,c) g_ptr_array_add(outstanding_stuff,pushColumns(L,c))
|
||||
|
||||
WSLUA_CLASS_DEFINE(Address,NOP,NOP);
|
||||
|
||||
WSLUA_CONSTRUCTOR Address_ip(lua_State* L) { /* Creates an Address Object representing an IP address. */
|
||||
#define WSLUA_ARG_Address_ip_HOSTNAME 1 /* The address or name of the IP host. */
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
guint32* ip_addr = g_malloc(sizeof(guint32));
|
||||
const gchar* name = luaL_checkstring(L,WSLUA_ARG_Address_ip_HOSTNAME);
|
||||
|
||||
if (! get_host_ipaddr(name, (guint32*)ip_addr)) {
|
||||
*ip_addr = 0;
|
||||
}
|
||||
|
||||
SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
|
||||
pushAddress(L,addr);
|
||||
WSLUA_RETURN(1); /* the Address object */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* TODO */
|
||||
static int Address_ipv6(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_ss7(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_eth(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_sna(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_atalk(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_vines(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_osi(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_arcnet(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_fc(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_string(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_eui64(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_uri(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
static int Address_tipc(lua_State* L) {
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
WSLUA_METHODS Address_methods[] = {
|
||||
{"ip", Address_ip },
|
||||
{"ipv4", Address_ip },
|
||||
#if 0
|
||||
{"ipv6", Address_ipv6 },
|
||||
{"ss7pc", Address_ss7 },
|
||||
{"eth", Address_eth },
|
||||
{"sna", Address_sna },
|
||||
{"atalk", Address_atalk },
|
||||
{"vines", Address_vines },
|
||||
{"osi", Address_osi },
|
||||
{"arcnet", Address_arcnet },
|
||||
{"fc", Address_fc },
|
||||
{"string", Address_string },
|
||||
{"eui64", Address_eui64 },
|
||||
{"uri", Address_uri },
|
||||
{"tipc", Address_tipc },
|
||||
#endif
|
||||
{0,0}
|
||||
};
|
||||
|
||||
WSLUA_METAMETHOD Address__tostring(lua_State* L) {
|
||||
Address addr = checkAddress(L,1);
|
||||
|
||||
lua_pushstring(L,get_addr_name(addr));
|
||||
|
||||
WSLUA_RETURN(1); /* The string representing the address. */
|
||||
}
|
||||
|
||||
static int Address__gc(lua_State* L) {
|
||||
Address addr = checkAddress(L,1);
|
||||
|
||||
if (addr) {
|
||||
if (addr->data) g_free((void*)addr->data);
|
||||
g_free((void*)addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD Address__eq(lua_State* L) { /* compares two Addresses */
|
||||
Address addr1 = checkAddress(L,1);
|
||||
Address addr2 = checkAddress(L,2);
|
||||
gboolean result = FALSE;
|
||||
|
||||
if (ADDRESSES_EQUAL(addr1, addr2))
|
||||
result = TRUE;
|
||||
|
||||
lua_pushboolean(L,result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD Address__le(lua_State* L) { /* compares two Addresses */
|
||||
Address addr1 = checkAddress(L,1);
|
||||
Address addr2 = checkAddress(L,2);
|
||||
gboolean result = FALSE;
|
||||
|
||||
if (CMP_ADDRESS(addr1, addr2) <= 0)
|
||||
result = TRUE;
|
||||
|
||||
lua_pushboolean(L,result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD Address__lt(lua_State* L) { /* compares two Addresses */
|
||||
Address addr1 = checkAddress(L,1);
|
||||
Address addr2 = checkAddress(L,2);
|
||||
gboolean result = FALSE;
|
||||
|
||||
if (CMP_ADDRESS(addr1, addr2) < 0)
|
||||
result = TRUE;
|
||||
|
||||
lua_pushboolean(L,result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_META Address_meta[] = {
|
||||
{"__gc", Address__gc },
|
||||
{"__tostring", Address__tostring },
|
||||
{"__eq",Address__eq},
|
||||
{"__le",Address__le},
|
||||
{"__lt",Address__lt},
|
||||
{0,0}
|
||||
};
|
||||
|
||||
|
||||
int Address_register(lua_State *L) {
|
||||
WSLUA_REGISTER_CLASS(Address);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_CLASS_DEFINE(Column,FAIL_ON_NULL("expired column"),NOP); /* A Column in the packet list */
|
||||
|
||||
struct col_names_t {
|
||||
const gchar* name;
|
||||
int id;
|
||||
};
|
||||
|
||||
static const struct col_names_t colnames[] = {
|
||||
{"number",COL_NUMBER},
|
||||
{"abs_time",COL_ABS_TIME},
|
||||
{"cls_time",COL_CLS_TIME},
|
||||
{"rel_time",COL_REL_TIME},
|
||||
{"date",COL_ABS_DATE_TIME},
|
||||
{"delta_time",COL_DELTA_TIME},
|
||||
{"src",COL_DEF_SRC},
|
||||
{"src_res",COL_RES_SRC},
|
||||
{"src_unres",COL_UNRES_SRC},
|
||||
{"dl_src",COL_DEF_DL_SRC},
|
||||
{"dl_src_res",COL_RES_DL_SRC},
|
||||
{"dl_src_unres",COL_UNRES_DL_SRC},
|
||||
{"net_src",COL_DEF_NET_SRC},
|
||||
{"net_src_res",COL_RES_NET_SRC},
|
||||
{"net_src_unres",COL_UNRES_NET_SRC},
|
||||
{"dst",COL_DEF_DST},
|
||||
{"dst_res",COL_RES_DST},
|
||||
{"dst_unres",COL_UNRES_DST},
|
||||
{"dl_dst",COL_DEF_DL_DST},
|
||||
{"dl_dst_res",COL_RES_DL_DST},
|
||||
{"dl_dst_unres",COL_UNRES_DL_DST},
|
||||
{"net_dst",COL_DEF_NET_DST},
|
||||
{"net_dst_res",COL_RES_NET_DST},
|
||||
{"net_dst_unres",COL_UNRES_NET_DST},
|
||||
{"src_port",COL_DEF_SRC_PORT},
|
||||
{"src_port_res",COL_RES_SRC_PORT},
|
||||
{"src_port_unres",COL_UNRES_SRC_PORT},
|
||||
{"dst_port",COL_DEF_DST_PORT},
|
||||
{"dst_port_res",COL_RES_DST_PORT},
|
||||
{"dst_port_unres",COL_UNRES_DST_PORT},
|
||||
{"protocol",COL_PROTOCOL},
|
||||
{"info",COL_INFO},
|
||||
{"packet_len",COL_PACKET_LENGTH},
|
||||
{"cumulative_bytes",COL_CUMULATIVE_BYTES},
|
||||
{"oxid",COL_OXID},
|
||||
{"rxid",COL_RXID},
|
||||
{"direction",COL_IF_DIR},
|
||||
{"circuit_id",COL_CIRCUIT_ID},
|
||||
{"src_idx",COL_SRCIDX},
|
||||
{"dst_idx",COL_DSTIDX},
|
||||
{"vsan",COL_VSAN},
|
||||
{"tx_rate",COL_TX_RATE},
|
||||
{"rssi",COL_RSSI},
|
||||
{"hpux_subsys",COL_HPUX_SUBSYS},
|
||||
{"hpux_devid",COL_HPUX_DEVID},
|
||||
{"dce_call",COL_DCE_CALL},
|
||||
{NULL,0}
|
||||
};
|
||||
|
||||
static gint col_name_to_id(const gchar* name) {
|
||||
const struct col_names_t* cn;
|
||||
for(cn = colnames; cn->name; cn++) {
|
||||
if (g_str_equal(cn->name,name)) {
|
||||
return cn->id;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const gchar* col_id_to_name(gint id) {
|
||||
const struct col_names_t* cn;
|
||||
for(cn = colnames; cn->name; cn++) {
|
||||
if ( cn->id == id ) {
|
||||
return cn->name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_METAMETHOD Column__tostring(lua_State *L) {
|
||||
Column c = checkColumn(L,1);
|
||||
const gchar* name;
|
||||
|
||||
if (!(c)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX: should return the column's text ! */
|
||||
name = col_id_to_name(c->col);
|
||||
lua_pushstring(L,name ? name : "Unknown Column");
|
||||
|
||||
WSLUA_RETURN(1); /* A string representing the column */
|
||||
}
|
||||
|
||||
WSLUA_METHOD Column_clear(lua_State *L) {
|
||||
/* Clears a Column */
|
||||
Column c = checkColumn(L,1);
|
||||
|
||||
if (!(c && c->cinfo)) return 0;
|
||||
|
||||
if (check_col(c->cinfo, c->col))
|
||||
col_clear(c->cinfo, c->col);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD Column_set(lua_State *L) {
|
||||
/* Sets the text of a Column */
|
||||
#define WSLUA_ARG_Column_set_TEXT 2 /* The text to which to set the Column */
|
||||
Column c = checkColumn(L,1);
|
||||
const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_set_TEXT);
|
||||
|
||||
if (!(c && c->cinfo))
|
||||
return 0;
|
||||
|
||||
if (!s) WSLUA_ARG_ERROR(Column_set,TEXT,"must be a string");
|
||||
|
||||
if (check_col(c->cinfo, c->col))
|
||||
col_set_str(c->cinfo, c->col, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD Column_append(lua_State *L) {
|
||||
/* Appends text to a Column */
|
||||
#define WSLUA_ARG_Column_append_TEXT 2 /* The text to append to the Column */
|
||||
Column c = checkColumn(L,1);
|
||||
const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_append_TEXT);
|
||||
|
||||
if (!(c && c->cinfo))
|
||||
return 0;
|
||||
|
||||
if (!s) WSLUA_ARG_ERROR(Column_append,TEXT,"must be a string");
|
||||
|
||||
|
||||
if (check_col(c->cinfo, c->col))
|
||||
col_append_str(c->cinfo, c->col, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD Column_preppend(lua_State *L) {
|
||||
/* Prepends text to a Column */
|
||||
#define WSLUA_ARG_Column_prepend_TEXT 2 /* The text to prepend to the Column */
|
||||
Column c = checkColumn(L,1);
|
||||
const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_prepend_TEXT);
|
||||
|
||||
if (!(c && c->cinfo))
|
||||
return 0;
|
||||
|
||||
if (!s) WSLUA_ARG_ERROR(Column_prepend,TEXT,"must be a string");
|
||||
|
||||
if (check_col(c->cinfo, c->col))
|
||||
col_prepend_fstr(c->cinfo, c->col, "%s",s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHODS Column_methods[] = {
|
||||
{"clear", Column_clear },
|
||||
{"set", Column_set },
|
||||
{"append", Column_append },
|
||||
{"preppend", Column_preppend },
|
||||
{0,0}
|
||||
};
|
||||
|
||||
|
||||
WSLUA_META Column_meta[] = {
|
||||
{"__tostring", Column__tostring },
|
||||
{0,0}
|
||||
};
|
||||
|
||||
|
||||
int Column_register(lua_State *L) {
|
||||
WSLUA_REGISTER_CLASS(Column);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WSLUA_CLASS_DEFINE(Columns,NOP,NOP);
|
||||
/* The Columns of the packet list. */
|
||||
|
||||
WSLUA_METAMETHOD Columns__tostring(lua_State *L) {
|
||||
lua_pushstring(L,"Columns");
|
||||
WSLUA_RETURN(1);
|
||||
/* The string "Columns", no real use, just for debugging purposes. */
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD Columns__newindex(lua_State *L) {
|
||||
/* Sets the text of a specific column */
|
||||
#define WSLUA_ARG_Columns__newindex_COLUMN 2 /* the name of the column to set */
|
||||
#define WSLUA_ARG_Columns__newindex_TEXT 3 /* the text for the column */
|
||||
Columns cols = checkColumns(L,1);
|
||||
const struct col_names_t* cn;
|
||||
const char* colname;
|
||||
const char* text;
|
||||
|
||||
if (!cols) return 0;
|
||||
|
||||
colname = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_COLUMN);
|
||||
text = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_TEXT);
|
||||
|
||||
for(cn = colnames; cn->name; cn++) {
|
||||
if( g_str_equal(cn->name,colname) ) {
|
||||
if (check_col(cols, cn->id))
|
||||
col_set_str(cols, cn->id, text);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_ARG_ERROR(Columns__newindex,COLUMN,"the column name must be a valid column");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD Columns_index(lua_State *L) {
|
||||
Columns cols = checkColumns(L,1);
|
||||
const struct col_names_t* cn;
|
||||
const char* colname = luaL_checkstring(L,2);
|
||||
|
||||
if (!cols) {
|
||||
Column c = ep_alloc(sizeof(struct _wslua_col_info));
|
||||
c->cinfo = NULL;
|
||||
c->col = col_name_to_id(colname);
|
||||
|
||||
PUSH_COLUMN(L,c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!colname) return 0;
|
||||
|
||||
for(cn = colnames; cn->name; cn++) {
|
||||
if( g_str_equal(cn->name,colname) ) {
|
||||
Column c = ep_alloc(sizeof(struct _wslua_col_info));
|
||||
c->cinfo = cols;
|
||||
c->col = col_name_to_id(colname);
|
||||
|
||||
PUSH_COLUMN(L,c);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const luaL_reg Columns_meta[] = {
|
||||
{"__tostring", Columns__tostring },
|
||||
{"__newindex", Columns__newindex },
|
||||
{"__index", Columns_index},
|
||||
{0,0}
|
||||
};
|
||||
|
||||
|
||||
int Columns_register(lua_State *L) {
|
||||
WSLUA_REGISTER_META(Columns);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_CLASS_DEFINE(Pinfo,FAIL_ON_NULL("expired pinfo"),NOP);
|
||||
/* Packet information */
|
||||
|
||||
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); \
|
||||
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); \
|
||||
const gchar* value; \
|
||||
if (!pinfo) return 0; \
|
||||
value = val; \
|
||||
if (value) lua_pushstring(L,(const char*)(value)); else lua_pushnil(L); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define PINFO_GET_ADDRESS(name,role) static int name(lua_State *L) { \
|
||||
Pinfo pinfo = checkPinfo(L,1); \
|
||||
Address addr = g_malloc(sizeof(address)); \
|
||||
if (!pinfo) return 0; \
|
||||
COPY_ADDRESS(addr, &(pinfo->role)); \
|
||||
pushAddress(L,addr); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
PINFO_GET_NUMBER(Pinfo_number,pinfo->fd->num)
|
||||
PINFO_GET_NUMBER(Pinfo_len,pinfo->fd->pkt_len)
|
||||
PINFO_GET_NUMBER(Pinfo_caplen,pinfo->fd->cap_len)
|
||||
PINFO_GET_NUMBER(Pinfo_abs_ts,(((double)pinfo->fd->abs_ts.secs) + (((double)pinfo->fd->abs_ts.nsecs) / 1000000000.0) ))
|
||||
PINFO_GET_NUMBER(Pinfo_rel_ts,(((double)pinfo->fd->rel_ts.secs) + (((double)pinfo->fd->rel_ts.nsecs) / 1000000000.0) ))
|
||||
PINFO_GET_NUMBER(Pinfo_delta_ts,(((double)pinfo->fd->del_ts.secs) + (((double)pinfo->fd->del_ts.nsecs) / 1000000000.0) ))
|
||||
PINFO_GET_NUMBER(Pinfo_ipproto,pinfo->ipproto)
|
||||
PINFO_GET_NUMBER(Pinfo_circuit_id,pinfo->circuit_id)
|
||||
PINFO_GET_NUMBER(Pinfo_ptype,pinfo->ptype)
|
||||
PINFO_GET_NUMBER(Pinfo_src_port,pinfo->srcport)
|
||||
PINFO_GET_NUMBER(Pinfo_dst_port,pinfo->destport)
|
||||
|
||||
PINFO_GET_STRING(Pinfo_curr_proto,pinfo->current_proto)
|
||||
|
||||
PINFO_GET_ADDRESS(Pinfo_net_src,net_src)
|
||||
PINFO_GET_ADDRESS(Pinfo_net_dst,net_dst)
|
||||
PINFO_GET_ADDRESS(Pinfo_dl_src,dl_src)
|
||||
PINFO_GET_ADDRESS(Pinfo_dl_dst,dl_dst)
|
||||
PINFO_GET_ADDRESS(Pinfo_src,src)
|
||||
PINFO_GET_ADDRESS(Pinfo_dst,dst)
|
||||
|
||||
static int Pinfo_visited(lua_State *L) {
|
||||
Pinfo pinfo = checkPinfo(L,1);
|
||||
if (!pinfo) return 0;
|
||||
lua_pushboolean(L,pinfo->fd->flags.visited);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int Pinfo_match(lua_State *L) {
|
||||
Pinfo pinfo = checkPinfo(L,1);
|
||||
|
||||
if (!pinfo) return 0;
|
||||
|
||||
if (pinfo->match_string) {
|
||||
lua_pushstring(L,pinfo->match_string);
|
||||
} else {
|
||||
lua_pushnumber(L,(lua_Number)(pinfo->match_port));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Pinfo_columns(lua_State *L) {
|
||||
Pinfo pinfo = checkPinfo(L,1);
|
||||
const gchar* colname = luaL_optstring(L,2,NULL);
|
||||
|
||||
if (!colname) {
|
||||
PUSH_COLUMNS(L,pinfo->cinfo);
|
||||
} else {
|
||||
lua_settop(L,0);
|
||||
PUSH_COLUMNS(L,pinfo->cinfo);
|
||||
lua_pushstring(L,colname);
|
||||
return Columns_index(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
typedef enum {
|
||||
PARAM_NONE,
|
||||
PARAM_ADDR_SRC,
|
||||
PARAM_ADDR_DST,
|
||||
PARAM_ADDR_DL_SRC,
|
||||
PARAM_ADDR_DL_DST,
|
||||
PARAM_ADDR_NET_SRC,
|
||||
PARAM_ADDR_NET_DST,
|
||||
PARAM_PORT_SRC,
|
||||
PARAM_PORT_DST,
|
||||
PARAM_CIRCUIT_ID,
|
||||
PARAM_PORT_TYPE,
|
||||
} pinfo_param_type_t;
|
||||
|
||||
static int pushnil_param(lua_State* L, packet_info* pinfo _U_, pinfo_param_type_t pt _U_ ) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Pinfo_set_addr(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
|
||||
const address* from = checkAddress(L,1);
|
||||
address* to;
|
||||
|
||||
if (! from ) {
|
||||
luaL_error(L,"Not an OK address");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(pt) {
|
||||
case PARAM_ADDR_SRC:
|
||||
to = &(pinfo->src);
|
||||
break;
|
||||
case PARAM_ADDR_DST:
|
||||
to = &(pinfo->dst);
|
||||
break;
|
||||
case PARAM_ADDR_DL_SRC:
|
||||
to = &(pinfo->dl_src);
|
||||
break;
|
||||
case PARAM_ADDR_DL_DST:
|
||||
to = &(pinfo->dl_dst);
|
||||
break;
|
||||
case PARAM_ADDR_NET_SRC:
|
||||
to = &(pinfo->net_src);
|
||||
break;
|
||||
case PARAM_ADDR_NET_DST:
|
||||
to = &(pinfo->net_dst);
|
||||
break;
|
||||
default:
|
||||
g_assert(!"BUG: A bad parameter");
|
||||
}
|
||||
|
||||
COPY_ADDRESS(to,from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Pinfo_set_int(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
|
||||
guint v = luaL_checkint(L,1);
|
||||
|
||||
switch(pt) {
|
||||
case PARAM_PORT_SRC:
|
||||
pinfo->srcport = v;
|
||||
return 0;
|
||||
case PARAM_PORT_DST:
|
||||
pinfo->destport = v;
|
||||
return 0;
|
||||
case PARAM_CIRCUIT_ID:
|
||||
pinfo->circuit_id = v;
|
||||
return 0;
|
||||
default:
|
||||
g_assert(!"BUG: A bad parameter");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _pinfo_method_t {
|
||||
const gchar* name;
|
||||
lua_CFunction get;
|
||||
int (*set)(lua_State*, packet_info*, pinfo_param_type_t);
|
||||
pinfo_param_type_t param;
|
||||
} pinfo_method_t;
|
||||
|
||||
static int Pinfo_hi(lua_State *L) {
|
||||
Pinfo pinfo = checkPinfo(L,1);
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
if (!pinfo) return 0;
|
||||
|
||||
if (CMP_ADDRESS(&(pinfo->src), &(pinfo->dst) ) >= 0) {
|
||||
COPY_ADDRESS(addr, &(pinfo->src));
|
||||
} else {
|
||||
COPY_ADDRESS(addr, &(pinfo->dst));
|
||||
}
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Pinfo_lo(lua_State *L) {
|
||||
Pinfo pinfo = checkPinfo(L,1);
|
||||
Address addr = g_malloc(sizeof(address));
|
||||
|
||||
if (!pinfo) return 0;
|
||||
|
||||
if (CMP_ADDRESS(&(pinfo->src), &(pinfo->dst) ) < 0) {
|
||||
COPY_ADDRESS(addr, &(pinfo->src));
|
||||
} else {
|
||||
COPY_ADDRESS(addr, &(pinfo->dst));
|
||||
}
|
||||
|
||||
pushAddress(L,addr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const pinfo_method_t Pinfo_methods[] = {
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_number RO The number of this packet in the current file */
|
||||
{"number", Pinfo_number, pushnil_param, PARAM_NONE},
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_len RO The length of the frame */
|
||||
{"len", Pinfo_len, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_caplen RO The captured length of the frame */
|
||||
{"caplen", Pinfo_caplen, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_abs_ts RO When the packet was captured */
|
||||
{"abs_ts",Pinfo_abs_ts, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_rel_ts RO Number of seconds passed since beginning of capture */
|
||||
{"rel_ts",Pinfo_rel_ts, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_delta_ts RO Number of seconds passed since the last packet */
|
||||
{"delta_ts",Pinfo_delta_ts, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_visited RO Whether this packet hass been already visited */
|
||||
{"visited",Pinfo_visited, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_src RW Source Address of this Packet */
|
||||
{"src", Pinfo_src, Pinfo_set_addr, PARAM_ADDR_SRC },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_dst RW Destination Address of this Packet */
|
||||
{"dst", Pinfo_dst, Pinfo_set_addr, PARAM_ADDR_DST },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_lo RO lower Address of this Packet */
|
||||
{"lo", Pinfo_lo, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_hi RW higher Address of this Packet */
|
||||
{"hi", Pinfo_hi, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_dl_src RW Data Link Source Address of this Packet */
|
||||
{"dl_src", Pinfo_dl_src, Pinfo_set_addr, PARAM_ADDR_DL_SRC },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_dl_dst RW Data Link Destination Address of this Packet */
|
||||
{"dl_dst", Pinfo_dl_dst, Pinfo_set_addr, PARAM_ADDR_DL_DST },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_net_src RW Network Layer Source Address of this Packet */
|
||||
{"net_src", Pinfo_net_src, Pinfo_set_addr, PARAM_ADDR_NET_SRC },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_net_dst RW Network Layer Destination Address of this Packet */
|
||||
{"net_dst", Pinfo_net_dst, Pinfo_set_addr, PARAM_ADDR_NET_DST },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_ptype RW Type of Port of .src_port and .dst_port */
|
||||
{"port_type", Pinfo_ptype, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_src_port RW Source Port of this Packet */
|
||||
{"src_port", Pinfo_src_port, Pinfo_set_int, PARAM_PORT_SRC },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_dst_port RW Source Address of this Packet */
|
||||
{"dst_port", Pinfo_dst_port, Pinfo_set_int, PARAM_PORT_SRC },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_ipproto RO IP Protocol id */
|
||||
{"ipproto", Pinfo_ipproto, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_circuit_id RO For circuit based protocols */
|
||||
{"circuit_id", Pinfo_circuit_id, Pinfo_set_int, PARAM_CIRCUIT_ID },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_match RO Port/Data we are matching */
|
||||
{"match", Pinfo_match, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_match RO Which Protocol are we dissecting */
|
||||
{"curr_proto", Pinfo_curr_proto, pushnil_param, PARAM_NONE },
|
||||
|
||||
/* WSLUA_ATTRIBUTE Pinfo_columns RO Accesss to the packet list columns */
|
||||
{"cols", Pinfo_columns, pushnil_param, PARAM_NONE },
|
||||
|
||||
{NULL,NULL,NULL,PARAM_NONE}
|
||||
};
|
||||
|
||||
|
||||
static int pushnil(lua_State* L) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Pinfo_index(lua_State* L) {
|
||||
Pinfo pinfo = checkPinfo(L,1);
|
||||
const gchar* name = luaL_checkstring(L,2);
|
||||
lua_CFunction method = pushnil;
|
||||
const pinfo_method_t* curr;
|
||||
|
||||
if (! (pinfo && name) ) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (curr = Pinfo_methods ; curr->name ; curr++) {
|
||||
if (g_str_equal(curr->name,name)) {
|
||||
method = curr->get;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lua_settop(L,1);
|
||||
return method(L);
|
||||
}
|
||||
|
||||
static int Pinfo_setindex(lua_State* L) {
|
||||
Pinfo pinfo = checkPinfo(L,1);
|
||||
const gchar* name = luaL_checkstring(L,2);
|
||||
int (*method)(lua_State*, packet_info* pinfo, pinfo_param_type_t) = pushnil_param;
|
||||
const pinfo_method_t* curr;
|
||||
pinfo_param_type_t param_type = PARAM_NONE;
|
||||
|
||||
if (! (pinfo && name) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (curr = Pinfo_methods ; curr->name ; curr++) {
|
||||
if (g_str_equal(curr->name,name)) {
|
||||
method = curr->set;
|
||||
param_type = curr->param;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lua_remove(L,1);
|
||||
lua_remove(L,1);
|
||||
return method(L,pinfo,param_type);
|
||||
}
|
||||
|
||||
static const luaL_reg Pinfo_meta[] = {
|
||||
{"__index", Pinfo_index},
|
||||
{"__newindex",Pinfo_setindex},
|
||||
{"__tostring", Pinfo_tostring},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int Pinfo_register(lua_State* L) {
|
||||
WSLUA_REGISTER_META(Pinfo);
|
||||
outstanding_stuff = g_ptr_array_new();
|
||||
return 1;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* wslua_tree.c
|
||||
*
|
||||
* Wireshark's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua_tree.c 18231 2006-05-28 16:32:49Z etxrab $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
#include <epan/expert.h>
|
||||
|
||||
static gint wslua_ett = -1;
|
||||
|
||||
static GPtrArray* outstanding_stuff = NULL;
|
||||
|
||||
#define PUSH_TREEITEM(L,i) g_ptr_array_add(outstanding_stuff,push_TreeItem(L,i))
|
||||
|
||||
void* push_TreeItem(lua_State*L, TreeItem t) {
|
||||
void** p = (void**)pushTreeItem(L,t);
|
||||
g_ptr_array_add(outstanding_stuff,p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void clear_outstanding_trees(void) {
|
||||
while (outstanding_stuff->len) {
|
||||
void** p = (void**)g_ptr_array_remove_index_fast(outstanding_stuff,0);
|
||||
*p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_CLASS_DEFINE(TreeItem,NOP,NOP);
|
||||
|
||||
/* ProtoTree class */
|
||||
static int TreeItem_add_item_any(lua_State *L, gboolean little_endian) {
|
||||
TvbRange tvbr;
|
||||
Proto proto;
|
||||
ProtoField field;
|
||||
int hfid = -1;
|
||||
int ett = -1;
|
||||
ftenum_t type = FT_NONE;
|
||||
TreeItem tree_item = shiftTreeItem(L,1);
|
||||
proto_item* item = NULL;
|
||||
|
||||
if (!tree_item) {
|
||||
return luaL_error(L,"not a TreeItem!");
|
||||
}
|
||||
if (! ( field = shiftProtoField(L,1) ) ) {
|
||||
if (( proto = shiftProto(L,1) )) {
|
||||
hfid = proto->hfid;
|
||||
type = FT_PROTOCOL;
|
||||
ett = proto->ett;
|
||||
}
|
||||
} else {
|
||||
hfid = field->hfid;
|
||||
type = field->type;
|
||||
ett = field->ett;
|
||||
}
|
||||
|
||||
tvbr = shiftTvbRange(L,1);
|
||||
|
||||
if (!tvbr) {
|
||||
tvbr = ep_alloc(sizeof(struct _wslua_tvbrange));
|
||||
tvbr->tvb = lua_tvb;
|
||||
tvbr->offset = 0;
|
||||
tvbr->len = 0;
|
||||
}
|
||||
|
||||
if (hfid > 0 ) {
|
||||
if (lua_gettop(L)) {
|
||||
switch(type) {
|
||||
case FT_PROTOCOL:
|
||||
item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,FALSE);
|
||||
lua_pushnumber(L,0);
|
||||
lua_insert(L,1);
|
||||
break;
|
||||
case FT_UINT8:
|
||||
case FT_UINT16:
|
||||
case FT_UINT24:
|
||||
case FT_UINT32:
|
||||
case FT_FRAMENUM:
|
||||
item = proto_tree_add_uint(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(guint32)luaL_checknumber(L,1));
|
||||
break;
|
||||
case FT_INT8:
|
||||
case FT_INT16:
|
||||
case FT_INT24:
|
||||
case FT_INT32:
|
||||
item = proto_tree_add_int(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(gint32)luaL_checknumber(L,1));
|
||||
break;
|
||||
case FT_FLOAT:
|
||||
item = proto_tree_add_float(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(float)luaL_checknumber(L,1));
|
||||
break;
|
||||
case FT_DOUBLE:
|
||||
item = proto_tree_add_double(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,(double)luaL_checknumber(L,1));
|
||||
break;
|
||||
case FT_STRING:
|
||||
case FT_STRINGZ:
|
||||
item = proto_tree_add_string(tree_item->tree,hfid,tvbr->tvb,tvbr->offset,tvbr->len,luaL_checkstring(L,1));
|
||||
break;
|
||||
case FT_UINT64:
|
||||
case FT_INT64:
|
||||
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:
|
||||
default:
|
||||
luaL_error(L,"FT_ not yet supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_remove(L,1);
|
||||
|
||||
} else {
|
||||
item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb, tvbr->offset, tvbr->len, little_endian);
|
||||
}
|
||||
|
||||
if ( lua_gettop(L) ) {
|
||||
const gchar* s = lua_tostring(L,1);
|
||||
|
||||
if (s) proto_item_set_text(item,"%s",s);
|
||||
|
||||
lua_remove(L,1);
|
||||
|
||||
}
|
||||
|
||||
} else if (tvbr) {
|
||||
if (lua_gettop(L)) {
|
||||
const gchar* s = lua_tostring(L,1);
|
||||
|
||||
item = proto_tree_add_text(tree_item->tree, tvbr->tvb, tvbr->offset, tvbr->len,"%s",s);
|
||||
lua_remove(L,1);
|
||||
}
|
||||
} else {
|
||||
if (lua_gettop(L)) {
|
||||
const gchar* s = lua_tostring(L,1);
|
||||
item = proto_tree_add_text(tree_item->tree, lua_tvb, 0, 0,"%s",s);
|
||||
lua_remove(L,1);
|
||||
}
|
||||
}
|
||||
|
||||
while(lua_gettop(L)) {
|
||||
const gchar* s = lua_tostring(L,1);
|
||||
|
||||
if (s) proto_item_append_text(item, " %s", s);
|
||||
|
||||
lua_remove(L,1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
tree_item = ep_alloc(sizeof(struct _wslua_treeitem));
|
||||
tree_item->item = item;
|
||||
tree_item->tree = proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett);
|
||||
|
||||
PUSH_TREEITEM(L,tree_item);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_METHOD TreeItem_add(lua_State *L) { return TreeItem_add_item_any(L,FALSE); }
|
||||
WSLUA_METHOD TreeItem_add_le(lua_State *L) { return TreeItem_add_item_any(L,TRUE); }
|
||||
|
||||
WSLUA_METHOD TreeItem_set_text(lua_State *L) {
|
||||
TreeItem ti = checkTreeItem(L,1);
|
||||
|
||||
if (ti) {
|
||||
const gchar* s = luaL_checkstring(L,2);
|
||||
proto_item_set_text(ti->item,"%s",s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD TreeItem_append_text(lua_State *L) {
|
||||
TreeItem ti = checkTreeItem(L,1);
|
||||
const gchar* s;
|
||||
|
||||
if (ti) {
|
||||
s = luaL_checkstring(L,2);
|
||||
proto_item_append_text(ti->item,"%s",s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD TreeItem_set_len(lua_State *L) {
|
||||
TreeItem ti = checkTreeItem(L,1);
|
||||
int len;
|
||||
|
||||
if (ti) {
|
||||
len = luaL_checkint(L,2);
|
||||
proto_item_set_len(ti->item,len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD TreeItem_set_expert_flags(lua_State *L) {
|
||||
TreeItem ti = checkTreeItem(L,1);
|
||||
int group = luaL_checkint(L,2);
|
||||
int severity = luaL_checkint(L,3);
|
||||
|
||||
if ( ti && ti->item ) {
|
||||
proto_item_set_expert_flags(ti->item,group,severity);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD TreeItem_add_expert_info(lua_State *L) {
|
||||
TreeItem ti = checkTreeItem(L,1);
|
||||
int group = luaL_checkint(L,2);
|
||||
int severity = luaL_checkint(L,3);
|
||||
const gchar* str = luaL_optstring(L,4,"Expert Info");
|
||||
|
||||
if ( ti && ti->item ) {
|
||||
expert_add_info_format(lua_pinfo, ti->item, group, severity, "%s", str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METHOD TreeItem_set_generated(lua_State *L) {
|
||||
TreeItem ti = checkTreeItem(L,1);
|
||||
if (ti) {
|
||||
PROTO_ITEM_SET_GENERATED(ti->item);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_METHOD TreeItem_set_hidden(lua_State *L) {
|
||||
TreeItem ti = checkTreeItem(L,1);
|
||||
if (ti) {
|
||||
PROTO_ITEM_SET_HIDDEN(ti->item);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_reg TreeItem_methods[] = {
|
||||
{"add", TreeItem_add},
|
||||
{"add_le", TreeItem_add_le},
|
||||
{"set_text", TreeItem_set_text},
|
||||
{"append_text", TreeItem_append_text},
|
||||
{"set_len", TreeItem_set_len},
|
||||
{"set_expert_flags", TreeItem_set_expert_flags},
|
||||
{"add_expert_info", TreeItem_add_expert_info},
|
||||
{"set_generated", TreeItem_set_generated},
|
||||
{"set_hidden", TreeItem_set_hidden},
|
||||
{0, 0}
|
||||
};
|
||||
static const luaL_reg TreeItem_meta[] = {
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
|
||||
int TreeItem_register(lua_State *L) {
|
||||
gint* etts[] = { &wslua_ett };
|
||||
|
||||
WSLUA_REGISTER_CLASS(TreeItem);
|
||||
outstanding_stuff = g_ptr_array_new();
|
||||
|
||||
proto_register_subtree_array(etts,1);
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,738 @@
|
|||
/*
|
||||
* wslua_tvb.c
|
||||
*
|
||||
* Wireshark's interface to the Lua Programming Language
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua_tvb.c 18231 2006-05-28 16:32:49Z etxrab $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
|
||||
WSLUA_CLASS_DEFINE(ByteArray,FAIL_ON_NULL("null bytearray"),NOP);
|
||||
|
||||
WSLUA_CONSTRUCTOR ByteArray_new(lua_State* L) { /* creates a ByteArray Object */
|
||||
#define WSLUA_OPTARG_ByteArray_new_HEXBYTES 1 /* A string consisting of hexadecimal bytes like "00 B1 A2" or "1a2b3c4d" */
|
||||
GByteArray* ba = g_byte_array_new();
|
||||
const gchar* s;
|
||||
int nibble[2];
|
||||
int i = 0;
|
||||
gchar c;
|
||||
|
||||
if (lua_gettop(L) == 1) {
|
||||
s = luaL_checkstring(L,WSLUA_OPTARG_ByteArray_new_HEXBYTES);
|
||||
|
||||
if (!s) {
|
||||
WSLUA_OPTARG_ERROR(ByteArray_new,HEXBYTES,"must be a string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX: slow! */
|
||||
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);
|
||||
|
||||
WSLUA_RETURN(1); /* The new ByteArray object. */
|
||||
}
|
||||
|
||||
static int ByteArray_gc(lua_State* L) {
|
||||
ByteArray ba = checkByteArray(L,1);
|
||||
|
||||
if (!ba) return 0;
|
||||
|
||||
g_byte_array_free(ba,TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_METAMETHOD ByteArray__concat(lua_State* L) {
|
||||
#define WSLUA_ARG_ByteArray__cat_FIRST 1
|
||||
#define WSLUA_ARG_ByteArray__cat_SECOND 1
|
||||
|
||||
ByteArray ba = checkByteArray(L,1);
|
||||
ByteArray ba2 = checkByteArray(L,2);
|
||||
|
||||
if (! (ba && ba2) )
|
||||
WSLUA_ERROR(ByteArray__cat,"both arguments must be ByteArrays");
|
||||
|
||||
g_byte_array_append(ba,ba2->data,ba2->len);
|
||||
|
||||
pushByteArray(L,ba);
|
||||
WSLUA_RETURN(1); /* The new composite ByteArray. */
|
||||
}
|
||||
|
||||
WSLUA_METHOD ByteArray_prepend(lua_State* L) {
|
||||
#define WSLUA_ARG_ByteArray_prepend_BYTES 1
|
||||
ByteArray ba = checkByteArray(L,1);
|
||||
ByteArray ba2 = checkByteArray(L,2);
|
||||
|
||||
if (! (ba && ba2) )
|
||||
WSLUA_ERROR(ByteArray_prepend,"both arguments must be ByteArrays");
|
||||
|
||||
g_byte_array_prepend(ba,ba2->data,ba2->len);
|
||||
|
||||
pushByteArray(L,ba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METHOD ByteArray_append(lua_State* L) {
|
||||
ByteArray ba = checkByteArray(L,1);
|
||||
ByteArray ba2 = checkByteArray(L,2);
|
||||
|
||||
if (! (ba && ba2) )
|
||||
WSLUA_ERROR(ByteArray_prepend,"both arguments must be ByteArrays");
|
||||
|
||||
g_byte_array_prepend(ba,ba2->data,ba2->len);
|
||||
|
||||
pushByteArray(L,ba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METHOD 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;
|
||||
}
|
||||
|
||||
WSLUA_METHOD 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 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
|
||||
luaL_argerror(L,2,"bad index");
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
WSLUA_METHOD ByteArray_get_index(lua_State* L) {
|
||||
ByteArray ba = checkByteArray(L,1);
|
||||
int idx = luaL_checkint(L,2);
|
||||
|
||||
if (!ba) return 0;
|
||||
|
||||
if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
|
||||
luaL_argerror(L,2,"bad index");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (idx < 0 || (guint)idx >= ba->len) {
|
||||
luaL_argerror(L,2,"index out of range");
|
||||
return 0;
|
||||
}
|
||||
lua_pushnumber(L,ba->data[idx]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METHOD ByteArray_len(lua_State* L) {
|
||||
ByteArray ba = checkByteArray(L,1);
|
||||
|
||||
if (!ba) return 0;
|
||||
|
||||
lua_pushnumber(L,(lua_Number)ba->len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSLUA_METHOD ByteArray_subset(lua_State* L) {
|
||||
ByteArray ba = checkByteArray(L,1);
|
||||
int offset = luaL_checkint(L,2);
|
||||
int len = luaL_checkint(L,3);
|
||||
ByteArray sub;
|
||||
|
||||
if (!ba) return 0;
|
||||
|
||||
if ((offset + len) > (int)ba->len || offset < 0 || len < 1) {
|
||||
luaL_error(L,"Out Of Bounds");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub = g_byte_array_new();
|
||||
g_byte_array_append(sub,ba->data + offset,len);
|
||||
|
||||
pushByteArray(L,sub);
|
||||
|
||||
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("");
|
||||
|
||||
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 int Tvb_new_real (lua_State *L);
|
||||
|
||||
static const luaL_reg ByteArray_methods[] = {
|
||||
{"new", ByteArray_new},
|
||||
{"len", ByteArray_len},
|
||||
{"prepend", ByteArray_prepend},
|
||||
{"append", ByteArray_append},
|
||||
{"subset", ByteArray_subset},
|
||||
{"set_size", ByteArray_set_size},
|
||||
{"tvb", Tvb_new_real},
|
||||
{"get_index", ByteArray_get_index},
|
||||
{"set_index", ByteArray_set_index},
|
||||
{0,0}
|
||||
};
|
||||
|
||||
static const luaL_reg ByteArray_meta[] = {
|
||||
{"__tostring", ByteArray_tostring},
|
||||
{"__gc", ByteArray_gc},
|
||||
{"__concat", ByteArray__concat},
|
||||
{"__call",ByteArray_subset},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int ByteArray_register(lua_State* L) {
|
||||
WSLUA_REGISTER_CLASS(ByteArray);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tvb & TvbRange
|
||||
*
|
||||
* a Tvb represents a tvbuff_t in Lua.
|
||||
* a TvbRange represents a range in a tvb (tvb,offset,lenght) it's main purpose is to do bounds checking,
|
||||
* it helps too simplifing argument passing to Tree. In wireshark terms this is worthless nothing
|
||||
* not already done by the TVB itself. In lua's terms is necessary to avoid abusing TRY{}CATCH(){}
|
||||
* via preemptive bounds checking.
|
||||
*
|
||||
* These lua objects have to be "NULLified after use", that is, we cannot leave pointers in the
|
||||
* lua machine to a tvb or a tvbr that might exist anymore.
|
||||
*
|
||||
* To do so we are going to keep a pointer to every "box" in which lua has placed a pointer to our object
|
||||
* and then NULLify the object lua points to.
|
||||
*
|
||||
* Other than that we are going to check every instance of a potentialy NULLified object before using it
|
||||
* and report an error to the lua machine if it happens to be NULLified.
|
||||
*/
|
||||
|
||||
WSLUA_CLASS_DEFINE(Tvb,FAIL_ON_NULL("expired tvb"),NOP);
|
||||
|
||||
static GPtrArray* outstanding_stuff = NULL;
|
||||
|
||||
#define PUSH_TVB(L,t) g_ptr_array_add(outstanding_stuff,pushTvb(L,t))
|
||||
#define PUSH_TVBRANGE(L,t) g_ptr_array_add(outstanding_stuff,pushTvbRange(L,t))
|
||||
|
||||
void clear_outstanding_tvbs(void) {
|
||||
while (outstanding_stuff->len) {
|
||||
void** p = (void**)g_ptr_array_remove_index_fast(outstanding_stuff,0);
|
||||
*p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void* push_Tvb(lua_State* L, Tvb tvb) {
|
||||
void** p = (void**)pushTvb(L,tvb);
|
||||
g_ptr_array_add(outstanding_stuff,p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Tvb_new_real(bytearray,name)
|
||||
* Creates a new Tvb from a bytearray (adds it to the frame too)
|
||||
*/
|
||||
static int Tvb_new_real (lua_State *L) {
|
||||
ByteArray ba = checkByteArray(L,1);
|
||||
const gchar* name = luaL_optstring(L,2,"Unnamed") ;
|
||||
guint8* data;
|
||||
Tvb tvb;
|
||||
|
||||
if (!ba) return 0;
|
||||
|
||||
if (!lua_tvb) {
|
||||
luaL_error(L,"Tvbs can only be created and used in dissectors");
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = g_memdup(ba->data, ba->len);
|
||||
|
||||
tvb = tvb_new_real_data(data, ba->len,ba->len);
|
||||
tvb_set_free_cb(tvb, g_free);
|
||||
|
||||
add_new_data_source(lua_pinfo, tvb, name);
|
||||
PUSH_TVB(L,tvb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* creates a subtvb from a tvbrange
|
||||
*
|
||||
*/
|
||||
static int Tvb_new_subset (lua_State *L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
|
||||
if (! tvbr) return 0;
|
||||
|
||||
if (tvb_offset_exists(tvbr->tvb, tvbr->offset + tvbr->len -1 )) {
|
||||
PUSH_TVB(L, tvb_new_subset(tvbr->tvb,tvbr->offset,tvbr->len, tvbr->len) );
|
||||
return 1;
|
||||
} else {
|
||||
luaL_error(L,"Out Of Bounds");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* convert the bytes to string, mainly for debugging purposes (mind the ...)
|
||||
*/
|
||||
static int Tvb_tostring(lua_State* L) {
|
||||
Tvb tvb = checkTvb(L,1);
|
||||
int len;
|
||||
gchar* str;
|
||||
|
||||
if (!tvb) return 0;
|
||||
|
||||
len = tvb_length(tvb);
|
||||
str = ep_strdup_printf("TVB(%i) : %s",len,tvb_bytes_to_str(tvb,0,len));
|
||||
lua_pushstring(L,str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns the length of a TVB
|
||||
*/
|
||||
static int Tvb_len(lua_State* L) {
|
||||
Tvb tvb = checkTvb(L,1);
|
||||
|
||||
if (!tvb) return 0;
|
||||
|
||||
lua_pushnumber(L,tvb_length(tvb));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the raw offset of a sub TVB
|
||||
*/
|
||||
static int Tvb_offset(lua_State* L) {
|
||||
Tvb tvb = checkTvb(L,1);
|
||||
|
||||
if (!tvb) return 0;
|
||||
|
||||
lua_pushnumber(L,TVB_RAW_OFFSET(tvb));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const luaL_reg Tvb_methods[] = {
|
||||
{"len", Tvb_len},
|
||||
{"offset", Tvb_offset},
|
||||
{0,0}
|
||||
};
|
||||
|
||||
static int Tvb_range(lua_State* L);
|
||||
|
||||
static const luaL_reg Tvb_meta[] = {
|
||||
{"__call", Tvb_range},
|
||||
{"__tostring", Tvb_tostring},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int Tvb_register(lua_State* L) {
|
||||
WSLUA_REGISTER_CLASS(Tvb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* TVB RAnge helper class
|
||||
*
|
||||
*/
|
||||
|
||||
TvbRange new_TvbRange(lua_State* L, tvbuff_t* tvb, int offset, int len) {
|
||||
TvbRange tvbr;
|
||||
|
||||
if (len == -1) {
|
||||
len = tvb_length_remaining(tvb,offset);
|
||||
if (len < 0) {
|
||||
luaL_error(L,"out of bounds");
|
||||
return 0;
|
||||
}
|
||||
} else if ( (guint)(len + offset) > tvb_length(tvb)) {
|
||||
luaL_error(L,"Range is out of bounds");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tvbr = ep_alloc(sizeof(struct _wslua_tvbrange));
|
||||
tvbr->tvb = tvb;
|
||||
tvbr->offset = offset;
|
||||
tvbr->len = len;
|
||||
|
||||
return tvbr;
|
||||
}
|
||||
|
||||
/*
|
||||
* creates a tvbr given the triplet (tvb,offset,len)
|
||||
*/
|
||||
static int Tvb_range(lua_State* L) {
|
||||
Tvb tvb = checkTvb(L,1);
|
||||
int offset = luaL_optint(L,2,0);
|
||||
int len = luaL_optint(L,3,-1);
|
||||
TvbRange tvbr;
|
||||
|
||||
if (!tvb) return 0;
|
||||
|
||||
if ((tvbr = new_TvbRange(L,tvb,offset,len))) {
|
||||
PUSH_TVBRANGE(L,tvbr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
WSLUA_CLASS_DEFINE(TvbRange,FAIL_ON_NULL("expired tvbrange"),NOP);
|
||||
|
||||
/*
|
||||
* read access to tvbr's data
|
||||
*/
|
||||
static int TvbRange_get_index(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
const gchar* index = luaL_checkstring(L,2);
|
||||
|
||||
if (!(tvbr && index)) return 0;
|
||||
|
||||
if (g_str_equal(index,"offset")) {
|
||||
lua_pushnumber(L,(lua_Number)tvbr->offset);
|
||||
return 1;
|
||||
} else if (g_str_equal(index,"len")) {
|
||||
lua_pushnumber(L,(lua_Number)tvbr->len);
|
||||
return 1;
|
||||
} else if (g_str_equal(index,"tvb")) {
|
||||
PUSH_TVB(L,tvbr->tvb);
|
||||
return 1;
|
||||
} else {
|
||||
luaL_error(L,"TvbRange has no `%s' attribute",index);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* write access to tvbr's data
|
||||
*/
|
||||
static int TvbRange_set_index(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
const gchar* index = luaL_checkstring(L,2);
|
||||
|
||||
if (!tvbr) return 0;
|
||||
|
||||
if (g_str_equal(index,"offset")) {
|
||||
int offset = (int)lua_tonumber(L,3);
|
||||
|
||||
if ( (guint)(tvbr->len + offset) > tvb_length(tvbr->tvb)) {
|
||||
luaL_error(L,"out of bounds");
|
||||
return 0;
|
||||
} else {
|
||||
tvbr->offset = offset;
|
||||
PUSH_TVBRANGE(L,tvbr);
|
||||
return 1;
|
||||
}
|
||||
} else if (g_str_equal(index,"len")) {
|
||||
int len = (int)lua_tonumber(L,3);
|
||||
|
||||
if ( (guint)(tvbr->offset + len) > tvb_length(tvbr->tvb)) {
|
||||
luaL_error(L,"out of bounds");
|
||||
return 0;
|
||||
} else {
|
||||
tvbr->len = len;
|
||||
PUSH_TVBRANGE(L,tvbr);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
luaL_error(L,"cannot set `%s' attribute on TvbRange",index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get a Blefuscuoan unsigned integer from a tvb
|
||||
*/
|
||||
static int TvbRange_get_uint(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
if (!tvbr) return 0;
|
||||
|
||||
switch (tvbr->len) {
|
||||
case 1:
|
||||
lua_pushnumber(L,tvb_get_guint8(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
case 2:
|
||||
lua_pushnumber(L,tvb_get_ntohs(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
case 3:
|
||||
lua_pushnumber(L,tvb_get_ntoh24(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
case 4:
|
||||
lua_pushnumber(L,tvb_get_ntohl(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
/*
|
||||
* XXX:
|
||||
* lua uses double so we have 52 bits to play with
|
||||
* we are missing 5 and 6 byte integers within lua's range
|
||||
* and 64 bit integers are not supported (there's a lib for
|
||||
* lua that does).
|
||||
*/
|
||||
default:
|
||||
luaL_error(L,"TvbRange:get_uint() does not handle %d byte integers",tvbr->len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get a Lilliputian unsigned integer from a tvb
|
||||
*/
|
||||
static int TvbRange_get_le_uint(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
if (!tvbr) return 0;
|
||||
|
||||
switch (tvbr->len) {
|
||||
case 1:
|
||||
/* XXX unsigned anyway */
|
||||
lua_pushnumber(L,(lua_Number)tvb_get_guint8(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
case 2:
|
||||
lua_pushnumber(L,tvb_get_letohs(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
case 3:
|
||||
lua_pushnumber(L,tvb_get_letoh24(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
case 4:
|
||||
lua_pushnumber(L,tvb_get_letohl(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
default:
|
||||
luaL_error(L,"TvbRange:get_le_uint() does not handle %d byte integers",tvbr->len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get a Blefuscuoan float
|
||||
*/
|
||||
static int TvbRange_get_float(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
if (!tvbr) return 0;
|
||||
|
||||
switch (tvbr->len) {
|
||||
case 4:
|
||||
lua_pushnumber(L,(double)tvb_get_ntohieee_float(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
case 8:
|
||||
lua_pushnumber(L,tvb_get_ntohieee_double(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
default:
|
||||
luaL_error(L,"TvbRange:get_float() does not handle %d byte floating numbers",tvbr->len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get a Lilliputian float
|
||||
*/
|
||||
static int TvbRange_get_le_float(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
if (!tvbr) return 0;
|
||||
|
||||
switch (tvbr->len) {
|
||||
case 4:
|
||||
lua_pushnumber(L,tvb_get_letohieee_float(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
case 8:
|
||||
lua_pushnumber(L,tvb_get_letohieee_double(tvbr->tvb,tvbr->offset));
|
||||
return 1;
|
||||
default:
|
||||
luaL_error(L,"TvbRange:get_float() does not handle %d byte floating numbers",tvbr->len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int TvbRange_get_ipv4(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
Address addr;
|
||||
guint32* ip_addr;
|
||||
|
||||
if ( !tvbr ) return 0;
|
||||
|
||||
addr = g_malloc(sizeof(address));
|
||||
|
||||
ip_addr = g_malloc(sizeof(guint32));
|
||||
*ip_addr = tvb_get_ntohl(tvbr->tvb,tvbr->offset);
|
||||
|
||||
SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
|
||||
pushAddress(L,addr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int TvbRange_get_ether(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
Address addr;
|
||||
guint8* buff;
|
||||
|
||||
if ( !tvbr ) return 0;
|
||||
|
||||
addr = g_malloc(sizeof(address));
|
||||
|
||||
buff = tvb_memdup(tvbr->tvb,tvbr->offset,tvbr->len);
|
||||
|
||||
SET_ADDRESS(addr, AT_ETHER, 6, buff);
|
||||
pushAddress(L,addr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int TvbRange_get_string(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
|
||||
if ( !tvbr ) return 0;
|
||||
|
||||
lua_pushstring(L, (gchar*)tvb_get_ephemeral_string(tvbr->tvb,tvbr->offset,tvbr->len) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int TvbRange_get_bytes(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
GByteArray* ba;
|
||||
|
||||
if ( !tvbr ) return 0;
|
||||
|
||||
ba = g_byte_array_new();
|
||||
g_byte_array_append(ba,ep_tvb_memdup(tvbr->tvb,tvbr->offset,tvbr->len),tvbr->len);
|
||||
|
||||
pushByteArray(L,ba);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int TvbRange_tostring(lua_State* L) {
|
||||
TvbRange tvbr = checkTvbRange(L,1);
|
||||
|
||||
if (!tvbr) return 0;
|
||||
|
||||
lua_pushstring(L,tvb_bytes_to_str(tvbr->tvb,tvbr->offset,tvbr->len));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_reg TvbRange_methods[] = {
|
||||
{"uint", TvbRange_get_uint},
|
||||
{"le_uint", TvbRange_get_le_uint},
|
||||
{"float", TvbRange_get_float},
|
||||
{"le_float", TvbRange_get_le_float},
|
||||
{"ether", TvbRange_get_ether},
|
||||
{"ipv4", TvbRange_get_ipv4},
|
||||
{"string", TvbRange_get_string},
|
||||
{"bytes", TvbRange_get_bytes},
|
||||
{"tvb", Tvb_new_subset},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static const luaL_reg TvbRange_meta[] = {
|
||||
{"__index", TvbRange_get_index},
|
||||
{"__newindex", TvbRange_set_index},
|
||||
{"__tostring", TvbRange_tostring},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int TvbRange_register(lua_State* L) {
|
||||
outstanding_stuff = g_ptr_array_new();
|
||||
WSLUA_REGISTER_CLASS(TvbRange);
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* wslua_util.c
|
||||
*
|
||||
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
|
||||
*
|
||||
* $Id: wslua_util.c 18197 2006-05-21 05:12:17Z sahlberg $
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "wslua.h"
|
||||
#include <math.h>
|
||||
|
||||
WSLUA_API const gchar* lua_shiftstring(lua_State* L, int i) {
|
||||
const gchar* p = luaL_checkstring(L, i);
|
||||
|
||||
if (p) {
|
||||
lua_remove(L,i);
|
||||
return p;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
WSLUA_FUNCTION wslua_format_date(lua_State* LS) { /* Formats an absolute timestamp into a human readable date */
|
||||
#define WSLUA_ARG_format_date_TIMESTAMP 1 /* A timestamp value to convert. */
|
||||
lua_Number time = luaL_checknumber(LS,WSLUA_ARG_format_date_TIMESTAMP);
|
||||
nstime_t then;
|
||||
gchar* str;
|
||||
|
||||
then.secs = (guint32)floor(time);
|
||||
then.nsecs = (guint32) ( (time-(double)(then.secs))*1000000000);
|
||||
str = abs_time_to_str(&then);
|
||||
lua_pushstring(LS,str);
|
||||
|
||||
WSLUA_RETURN(1); /* a string with the formated date */
|
||||
}
|
||||
|
||||
WSLUA_FUNCTION wslua_format_time(lua_State* LS) { /* Formats an absolute timestamp in a human readable form */
|
||||
#define WSLUA_ARG_format_time_TIMESTAMP 1 /* a timestamp value to convert */
|
||||
lua_Number time = luaL_checknumber(LS,WSLUA_ARG_format_time_TIMESTAMP);
|
||||
nstime_t then;
|
||||
gchar* str;
|
||||
|
||||
then.secs = (guint32)floor(time);
|
||||
then.nsecs = (guint32) ( (time-(double)(then.secs))*1000000000);
|
||||
str = rel_time_to_str(&then);
|
||||
lua_pushstring(LS,str);
|
||||
|
||||
WSLUA_RETURN(1); /* a string with the formated time */
|
||||
}
|
||||
|
||||
WSLUA_FUNCTION wslua_report_failure(lua_State* LS) { /* reports a failure to the user */
|
||||
#define WSLUA_ARG_report_failure_TEXT 1 /* message */
|
||||
const gchar* s = luaL_checkstring(LS,WSLUA_ARG_report_failure_TEXT);
|
||||
report_failure("%s",s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wslua_log(lua_State* L, GLogLevelFlags log_level) {
|
||||
GString* str = g_string_new("");
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
int i;
|
||||
|
||||
lua_getglobal(L, "tostring");
|
||||
for (i=1; i<=n; i++) {
|
||||
const char *s;
|
||||
lua_pushvalue(L, -1); /* function to be called */
|
||||
lua_pushvalue(L, i); /* value to print */
|
||||
lua_call(L, 1, 1);
|
||||
s = lua_tostring(L, -1); /* get result */
|
||||
if (s == NULL)
|
||||
return luaL_error(L, "`tostring' must return a string");
|
||||
|
||||
if (i>1) g_string_append(str,"\t");
|
||||
g_string_append(str,s);
|
||||
|
||||
lua_pop(L, 1); /* pop result */
|
||||
}
|
||||
|
||||
g_log(LOG_DOMAIN_LUA, log_level, "%s\n", str->str);
|
||||
g_string_free(str,TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSLUA_FUNCTION wslua_critical( lua_State* L ) { /* Will add a log entry with critical severity*/
|
||||
/* WSLUA_MOREARGS critical objects to be printed */
|
||||
wslua_log(L,G_LOG_LEVEL_CRITICAL);
|
||||
return 0;
|
||||
}
|
||||
WSLUA_FUNCTION wslua_warn( lua_State* L ) { /* Will add a log entry with warn severity */
|
||||
/* WSLUA_MOREARGS warn objects to be printed */
|
||||
wslua_log(L,G_LOG_LEVEL_WARNING);
|
||||
return 0;
|
||||
}
|
||||
WSLUA_FUNCTION wslua_message( lua_State* L ) { /* Will add a log entry with message severity */
|
||||
/* WSLUA_MOREARGS message objects to be printed */
|
||||
wslua_log(L,G_LOG_LEVEL_MESSAGE);
|
||||
return 0;
|
||||
}
|
||||
WSLUA_FUNCTION wslua_info( lua_State* L ) { /* Will add a log entry with info severity */
|
||||
/* WSLUA_MOREARGS info objects to be printed */
|
||||
wslua_log(L,G_LOG_LEVEL_INFO);
|
||||
return 0;
|
||||
}
|
||||
WSLUA_FUNCTION wslua_debug( lua_State* L ) { /* Will add a log entry with debug severity */
|
||||
/* WSLUA_MOREARGS debug objects to be printed */
|
||||
wslua_log(L,G_LOG_LEVEL_DEBUG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -21,13 +21,6 @@
|
|||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
if HAVE_LIBLUA
|
||||
lua_dir = \
|
||||
lua
|
||||
else # HAVE_LIBLUA
|
||||
lua_dir =
|
||||
endif # HAVE_LIBLUA
|
||||
|
||||
SUBDIRS = \
|
||||
acn \
|
||||
agentx \
|
||||
|
@ -40,7 +33,6 @@ SUBDIRS = \
|
|||
gryphon \
|
||||
h223 \
|
||||
irda \
|
||||
$(lua_dir) \
|
||||
lwres \
|
||||
mate \
|
||||
megaco \
|
||||
|
|
Loading…
Reference in New Issue