Lua: add ability for scripts loaded from command-line to be passed arguments

This change adds the ability to pass on to lua scripts loaded from the
command-line (tshark or wireshark) additional arguments supplied by the
command-line.  This will help us in our testsuites, but also might be
useful for user-created scripts.  The additional arguments are passed in
using the '-X' eXtension switch.

Change-Id: Ib94cdf1ffd194ca84692fee7816665e4ff95efbd
Reviewed-on: https://code.wireshark.org/review/156
Reviewed-by: Evan Huus <eapache@gmail.com>
Tested-by: Evan Huus <eapache@gmail.com>
This commit is contained in:
Hadriel Kaplan 2014-02-09 14:27:51 -05:00 committed by Evan Huus
parent 1eeb33a7b0
commit 58fe488822
6 changed files with 126 additions and 6 deletions

View File

@ -788,6 +788,13 @@ is in the form I<extension_key>B<:>I<value>, where I<extension_key> can be:
B<lua_script>:I<lua_script_filename> tells B<Wireshark> to load the given script in addition to the
default Lua scripts.
B<lua_script>I<num>:I<argument> tells B<Wireshark> to pass the given argument
to the lua script identified by 'num', which is the number indexed order of the 'lua_script' command.
For example, if only one script was loaded with '-X lua_script:my.lua', then '-X lua_script1:foo'
will pass the string 'foo' to the 'my.lua' script. If two scripts were loaded, such as '-X lua_script:my.lua'
and '-X lua_script:other.lua' in that order, then a '-X lua_script2:bar' would pass the string 'bar' to the second lua
script, namely 'other.lua'.
=item -y E<lt>capture link typeE<gt>
Set the data link type to use while capturing packets. The values

View File

@ -604,6 +604,13 @@ is in the form I<extension_key>B<:>I<value>, where I<extension_key> can be:
B<lua_script>:I<lua_script_filename> tells B<Wireshark> to load the given script in addition to the
default Lua scripts.
B<lua_script>I<num>:I<argument> tells B<Wireshark> to pass the given argument
to the lua script identified by 'num', which is the number indexed order of the 'lua_script' command.
For example, if only one script was loaded with '-X lua_script:my.lua', then '-X lua_script1:foo'
will pass the string 'foo' to the 'my.lua' script. If two scripts were loaded, such as '-X lua_script:my.lua'
and '-X lua_script:other.lua' in that order, then a '-X lua_script2:bar' would pass the string 'bar' to the second lua
script, namely 'other.lua'.
B<stdin_descr>:I<description> tells B<Wireshark> to use the given description when
capturing from standard input (B<-i ->).

View File

@ -585,6 +585,14 @@ standard libpcap format.
<para>
<command>lua_script</command>:lua_script_filename; Tells Wireshark to load the given script in addition to the default Lua scripts.
</para>
<para>
<command>lua_script[num]</command>:argument; Tells Wireshark to pass the given argument
to the lua script identified by 'num', which is the number indexed order of the 'lua_script' command.
For example, if only one script was loaded with '-X lua_script:my.lua', then '-X lua_script1:foo'
will pass the string 'foo' to the 'my.lua' script. If two scripts were loaded, such as '-X lua_script:my.lua' and
'-X lua_script:other.lua' in that order, then a '-X lua_script2:bar' would pass the string 'bar' to the second lua
script, namely 'other.lua'.
</para>
</listitem>
</varlistentry>
<varlistentry><term><command>-z &lt;statistics-string></command></term>

View File

@ -241,9 +241,27 @@ static void wslua_add_plugin(gchar *name, gchar *version, gchar *filename)
new_plug->next = NULL;
}
static gboolean lua_load_script(const gchar* filename) {
static int lua_script_push_args(const int script_num) {
gchar* argname = g_strdup_printf("lua_script%d", script_num);
const gchar* argvalue = NULL;
int count = 0;
while((argvalue = ex_opt_get_next(argname))) {
lua_pushstring(L,argvalue);
count++;
}
g_free(argname);
return count;
}
/* If file_count > 0 then it's a command-line-added user script, and the count
* represents which user script it is (first=1, second=2, etc.).
*/
static gboolean lua_load_script(const gchar* filename, const int file_count) {
FILE* file;
int error;
int numargs = 0;
if (! ( file = ws_fopen(filename,"r")) ) {
report_open_failure(filename,errno,FALSE);
@ -261,7 +279,10 @@ static gboolean lua_load_script(const gchar* filename) {
#endif
switch (error) {
case 0:
lua_pcall(L,0,0,1);
if (file_count > 0) {
numargs = lua_script_push_args(file_count);
}
lua_pcall(L,numargs,0,1);
fclose(file);
lua_pop(L,1); /* pop the error handler */
return TRUE;
@ -332,7 +353,7 @@ static int lua_load_plugins(const char *dirname, register_cb cb, gpointer client
if (!count_only) {
if (cb)
(*cb)(RA_LUA_PLUGINS, name, client_data);
if (lua_load_script(filename)) {
if (lua_load_script(filename,0)) {
wslua_add_plugin(g_strdup(name), g_strdup(""), g_strdup(filename));
}
}
@ -401,6 +422,7 @@ int wslua_init(register_cb cb, gpointer client_data) {
const funnel_ops_t* ops = funnel_get_funnel_ops();
gboolean run_anyway = FALSE;
expert_module_t* expert_lua;
int file_count = 1;
static ei_register_info ei[] = {
{ &ei_lua_error, { "_ws.lua.error", PI_UNDECODED, PI_ERROR ,"Lua Error", EXPFILL }},
@ -456,7 +478,7 @@ int wslua_init(register_cb cb, gpointer client_data) {
}
if (( file_exists(filename))) {
lua_load_script(filename);
lua_load_script(filename,0);
}
g_free(filename);
@ -491,7 +513,7 @@ int wslua_init(register_cb cb, gpointer client_data) {
if ((file_exists(filename))) {
if (cb)
(*cb)(RA_LUA_PLUGINS, get_basename(filename), client_data);
lua_load_script(filename);
lua_load_script(filename,0);
}
g_free(filename);
@ -504,7 +526,8 @@ int wslua_init(register_cb cb, gpointer client_data) {
while((script_filename = ex_opt_get_next("lua_script"))) {
if (cb)
(*cb)(RA_LUA_PLUGINS, get_basename(script_filename), client_data);
lua_load_script(script_filename);
lua_load_script(script_filename,file_count);
file_count++;
}
}

36
test/lua/script_args.lua Executable file
View File

@ -0,0 +1,36 @@
----------------------------------------
-- This just verifies the number of args it got is what it expected.
-- The first arg should be a number, for how many total args to expect,
-- including itself.
local function testing(...)
print("---- Testing "..tostring(...).." ----")
end
local function test(name, result)
io.stdout:write("test "..name.."...")
if result == true then
io.stdout:write("passed\n")
else
io.stdout:write("failed!\n")
error(name.." test failed!")
end
end
-----------------------------
testing("Command-line args")
local arg={...} -- get passed-in args
test("arg1", arg ~= nil and #arg > 0)
local numargs = tonumber(arg[1])
test("arg2", numargs ~= nil)
test("arg3", #arg == numargs)
print("\n-----------------------------\n")
print("All tests passed!\n\n")

View File

@ -114,6 +114,44 @@ unittests_step_lua_int64_test() {
fi
}
unittests_step_lua_args_test() {
if [ $HAVE_LUA -ne 0 ]; then
test_step_skipped
return
fi
# Tshark catches lua script failures, so we have to parse the output.
$TSHARK -r $CAPTURE_DIR/dhcp.pcap -X lua_script:$TESTS_DIR/lua/script_args.lua -X lua_script1:1 > testout.txt 2>&1
grep -q "All tests passed!" testout.txt
if [ $? -ne 0 ]; then
cat testout.txt
test_step_failed "lua_args_test test 1 failed"
fi
$TSHARK -r $CAPTURE_DIR/dhcp.pcap -X lua_script:$TESTS_DIR/lua/script_args.lua -X lua_script1:3 -X lua_script1:foo -X lua_script1:bar > testout.txt 2>&1
grep -q "All tests passed!" testout.txt
if [ $? -ne 0 ]; then
cat testout.txt
test_step_failed "lua_args_test test 2 failed"
fi
$TSHARK -r $CAPTURE_DIR/dhcp.pcap -X lua_script:$TESTS_DIR/lua/script_args.lua -X lua_script:$TESTS_DIR/lua/script_args.lua -X lua_script1:3 -X lua_script2:1 -X lua_script1:foo -X lua_script1:bar > testout.txt 2>&1
grep -q "All tests passed!" testout.txt
if [ $? -ne 0 ]; then
cat testout.txt
test_step_failed "lua_args_test test 3 failed"
fi
$TSHARK -r $CAPTURE_DIR/dhcp.pcap -X lua_script:$TESTS_DIR/lua/script_args.lua > testout.txt 2>&1
if grep -q "All tests passed!" testout.txt; then
cat testout.txt
test_step_failed "lua_args_test negative test 4 failed"
fi
$TSHARK -r $CAPTURE_DIR/dhcp.pcap -X lua_script:$TESTS_DIR/lua/script_args.lua -X lua_script1:3 > testout.txt 2>&1
if grep -q "All tests passed!" testout.txt; then
cat testout.txt
test_step_failed "lua_args_test negative test 5 failed"
fi
test_step_ok
}
unittests_step_oids_test() {
DUT=$SOURCE_DIR/epan/oids_test
ARGS=
@ -149,6 +187,7 @@ unittests_suite() {
test_step_add "exntest" unittests_step_exntest
test_step_add "lua dissector" unittests_step_lua_dissector_test
test_step_add "lua int64" unittests_step_lua_int64_test
test_step_add "lua script arguments" unittests_step_lua_args_test
test_step_add "oids_test" unittests_step_oids_test
test_step_add "reassemble_test" unittests_step_reassemble_test
test_step_add "tvbtest" unittests_step_tvbtest