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:
Luis Ontanon 2006-09-25 01:09:00 +00:00
parent 299469d48d
commit 6462d05044
24 changed files with 6860 additions and 27 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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

121
epan/wslua/Makefile.am Normal file
View File

@ -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

69
epan/wslua/Makefile.nmake Normal file
View File

@ -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

323
epan/wslua/init_wslua.c Normal file
View File

@ -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; }

385
epan/wslua/make-doc.pl Executable file
View File

@ -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};
}
}

121
epan/wslua/make-init-lua.pl Executable file
View File

@ -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;

62
epan/wslua/make-reg.pl Executable file
View File

@ -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";

206
epan/wslua/make-taps.pl Normal file
View File

@ -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;

81
epan/wslua/taps Normal file
View File

@ -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

View File

@ -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%

338
epan/wslua/wslua.h Normal file
View File

@ -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

389
epan/wslua/wslua_dumper.c Normal file
View File

@ -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;
}

445
epan/wslua/wslua_field.c Normal file
View File

@ -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;
}

508
epan/wslua/wslua_gui.c Normal file
View File

@ -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;
}

332
epan/wslua/wslua_listener.c Normal file
View File

@ -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;
}

888
epan/wslua/wslua_pinfo.c Normal file
View File

@ -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;
}

1350
epan/wslua/wslua_proto.c Normal file

File diff suppressed because it is too large Load Diff

290
epan/wslua/wslua_tree.c Normal file
View File

@ -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;
}

738
epan/wslua/wslua_tvb.c Normal file
View File

@ -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;
}

129
epan/wslua/wslua_util.c Normal file
View File

@ -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;
}

View File

@ -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 \