Lua: allow a Dissector object to be passed in for register_heuristic
Bug: 10695 Change-Id: I81181b2d00fcb5f0c25ab89bbe4968897f47a3a6 Reviewed-on: https://code.wireshark.org/review/6131 Petri-Dish: Hadriel Kaplan <hadrielk@yahoo.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
parent
11212887a1
commit
f7b6dcc58c
|
@ -283,6 +283,8 @@ gboolean heur_dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, v
|
|||
} else {
|
||||
if (lua_isboolean(L, -1) || lua_isnil(L, -1)) {
|
||||
result = lua_toboolean(L, -1);
|
||||
} else if (lua_type(L, -1) == LUA_TNUMBER) {
|
||||
result = lua_tointeger(L,-1) != 0 ? TRUE : FALSE;
|
||||
} else {
|
||||
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0,
|
||||
"Lua Error: invalid return value from Lua %s heuristic dissector", pinfo->current_proto);
|
||||
|
|
|
@ -1635,6 +1635,13 @@ WSLUA_METHOD Proto_register_heuristic(lua_State* L) {
|
|||
and dissect the packet (including setting TreeItem info and such) only if the payload is for it,
|
||||
before returning true or false.
|
||||
|
||||
Since version 1.99.1, this function also accepts a Dissector object as the second argument,
|
||||
to allow re-using the same Lua code as the `function proto.dissector(...)`. In this case,
|
||||
the Dissector must return a Lua number of the number of bytes consumed/parsed: if 0 is returned,
|
||||
it will be treated the same as a `false` return for the heuristic; if a positive or negative
|
||||
number is returned, then the it will be treated the same as a `true` return for the heuristic,
|
||||
meaning the packet is for this protocol and no other heuristic will be tried.
|
||||
|
||||
@since 1.11.3
|
||||
*/
|
||||
#define WSLUA_ARG_Proto_register_heuristic_LISTNAME 2 /* The heuristic list name this function
|
||||
|
@ -1659,6 +1666,29 @@ WSLUA_METHOD Proto_register_heuristic(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* we'll check if the second form of this function was called: when the second arg is
|
||||
a Dissector obejct. The truth is we don't need the Dissector object to do this
|
||||
form of registration, but someday we might... so we're using it as a boolean arg
|
||||
right now and in the future might use it for other things in this registration.
|
||||
*/
|
||||
if (isDissector(L, WSLUA_ARG_Proto_register_heuristic_FUNC)) {
|
||||
/* retrieve the Dissector's Lua function... first get the table of all dissector funcs */
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref);
|
||||
/* then get the one for this Proto */
|
||||
lua_getfield(L, -1, proto_name);
|
||||
|
||||
if (!lua_isfunction(L,-1)) {
|
||||
/* this shouldn't be possible */
|
||||
luaL_error(L,"Proto_register_heuristic: could not get lua function from lua_dissectors_table");
|
||||
return 0;
|
||||
}
|
||||
/* replace the Dissector with the function */
|
||||
lua_replace(L, WSLUA_ARG_Proto_register_heuristic_FUNC);
|
||||
/* pop the lua_dissectors_table */
|
||||
lua_pop(L, 1);
|
||||
g_assert(top == lua_gettop(L));
|
||||
}
|
||||
|
||||
/* heuristic functions are stored in a table in the registry; the registry has a
|
||||
* table at reference lua_heur_dissectors_table_ref, and that table has keys for
|
||||
* the heuristic listname (e.g., "udp", "tcp", etc.), and that key's value is a
|
||||
|
|
|
@ -66,6 +66,7 @@ local default_settings =
|
|||
debug_level = DEBUG,
|
||||
port = 65333,
|
||||
heur_enabled = true,
|
||||
heur_regmode = 1,
|
||||
}
|
||||
|
||||
-- for testing purposes, we want to be able to pass in changes to the defaults
|
||||
|
@ -584,7 +585,16 @@ local function heur_dissect_dns(tvbuf,pktinfo,root)
|
|||
end
|
||||
|
||||
-- now register that heuristic dissector into the udp heuristic list
|
||||
dns:register_heuristic("udp",heur_dissect_dns)
|
||||
if default_settings.heur_regmode == 1 then
|
||||
-- this is the "normal" way to register a heuristic: using a lua function
|
||||
dns:register_heuristic("udp",heur_dissect_dns)
|
||||
elseif default_settings.heur_regmode == 2 then
|
||||
-- this is to test the fix for bug 10695:
|
||||
dns:register_heuristic("udp",dns.dissector)
|
||||
elseif default_settings.heur_regmode == 3 then
|
||||
-- and this too is to test the fix for bug 10695:
|
||||
dns:register_heuristic("udp", function (...) return dns.dissector(...); end )
|
||||
end
|
||||
|
||||
-- We're done!
|
||||
-- our protocol (Proto) gets automatically registered after this script finishes loading
|
||||
|
|
|
@ -135,6 +135,19 @@ local lines = {
|
|||
-- dissector, then the first one by the heuristic, then the second one by
|
||||
-- a conversation match
|
||||
local numtests = 1 + #lines[1] + #lines[2] + #lines[3] + #lines[4]
|
||||
|
||||
local hasHeuristic = true
|
||||
|
||||
-- grab passed-in arguments
|
||||
local args = { ... }
|
||||
if #args > 0 then
|
||||
for _, arg in ipairs(args) do
|
||||
if arg == "no_heur" then
|
||||
numtests = numtests - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
print("going to run "..numtests.." tests")
|
||||
|
||||
-- for an example of what we're reading through to verify, look at end of this file
|
||||
|
|
|
@ -48,12 +48,50 @@ wslua_step_dissector_test() {
|
|||
if [ ! $RETURNVALUE -eq $EXIT_OK ]; then
|
||||
echo
|
||||
cat ./testin.txt
|
||||
test_step_failed "exit status of $DUT: $RETURNVALUE"
|
||||
test_step_failed "subtest-1 exit status of $DUT: $RETURNVALUE"
|
||||
return
|
||||
fi
|
||||
|
||||
# then run tshark again with the verification script. (it internally reads in testin.txt)
|
||||
$TSHARK -r $CAPTURE_DIR/empty.pcap -X lua_script:$TESTS_DIR/lua/verify_dissector.lua > testout.txt 2>&1
|
||||
grep -q "All tests passed!" testout.txt
|
||||
if [ $? -ne 0 ]; then
|
||||
cat ./testin.txt
|
||||
cat ./testout.txt
|
||||
test_step_failed "subtest-1 didn't find pass marker"
|
||||
fi
|
||||
|
||||
# run tshark with the dissector script again, but in mode 2.
|
||||
$TSHARK -r $CAPTURE_DIR/dns_port.pcap -V -X lua_script:$TESTS_DIR/lua/dissector.lua -X lua_script1:heur_regmode=2 > testin.txt 2>&1
|
||||
RETURNVALUE=$?
|
||||
if [ ! $RETURNVALUE -eq $EXIT_OK ]; then
|
||||
echo
|
||||
cat ./testin.txt
|
||||
test_step_failed "subtest-1 exit status of $DUT: $RETURNVALUE"
|
||||
return
|
||||
fi
|
||||
|
||||
# then run tshark again with the verification script. (it internally reads in testin.txt)
|
||||
$TSHARK -r $CAPTURE_DIR/empty.pcap -X lua_script:$TESTS_DIR/lua/verify_dissector.lua -X lua_script1:no_heur > testout.txt 2>&1
|
||||
grep -q "All tests passed!" testout.txt
|
||||
if [ $? -ne 0 ]; then
|
||||
cat ./testin.txt
|
||||
cat ./testout.txt
|
||||
test_step_failed "subtest-1 didn't find pass marker"
|
||||
fi
|
||||
|
||||
# run tshark with the dissector script again, but in mode 3.
|
||||
$TSHARK -r $CAPTURE_DIR/dns_port.pcap -V -X lua_script:$TESTS_DIR/lua/dissector.lua -X lua_script1:heur_regmode=3 > testin.txt 2>&1
|
||||
RETURNVALUE=$?
|
||||
if [ ! $RETURNVALUE -eq $EXIT_OK ]; then
|
||||
echo
|
||||
cat ./testin.txt
|
||||
test_step_failed "subtest-1 exit status of $DUT: $RETURNVALUE"
|
||||
return
|
||||
fi
|
||||
|
||||
# then run tshark again with the verification script. (it internally reads in testin.txt)
|
||||
$TSHARK -r $CAPTURE_DIR/empty.pcap -X lua_script:$TESTS_DIR/lua/verify_dissector.lua -X lua_script1:no_heur > testout.txt 2>&1
|
||||
if grep -q "All tests passed!" testout.txt; then
|
||||
test_step_ok
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue