diff options
-rw-r--r-- | epan/wslua/init_wslua.c | 2 | ||||
-rw-r--r-- | epan/wslua/wslua_proto.c | 30 | ||||
-rw-r--r-- | test/lua/dissector.lua | 12 | ||||
-rw-r--r-- | test/lua/verify_dissector.lua | 13 | ||||
-rwxr-xr-x | test/suite-wslua.sh | 40 |
5 files changed, 95 insertions, 2 deletions
diff --git a/epan/wslua/init_wslua.c b/epan/wslua/init_wslua.c index 40f03a276a..bee9fb6d3d 100644 --- a/epan/wslua/init_wslua.c +++ b/epan/wslua/init_wslua.c @@ -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); diff --git a/epan/wslua/wslua_proto.c b/epan/wslua/wslua_proto.c index 069ab373ff..afa4526bbe 100644 --- a/epan/wslua/wslua_proto.c +++ b/epan/wslua/wslua_proto.c @@ -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 diff --git a/test/lua/dissector.lua b/test/lua/dissector.lua index 4685006aed..8d7b4a84e4 100644 --- a/test/lua/dissector.lua +++ b/test/lua/dissector.lua @@ -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 diff --git a/test/lua/verify_dissector.lua b/test/lua/verify_dissector.lua index 46ec704e40..99003a0ee7 100644 --- a/test/lua/verify_dissector.lua +++ b/test/lua/verify_dissector.lua @@ -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 diff --git a/test/suite-wslua.sh b/test/suite-wslua.sh index 04e7a70ca3..9b18de4072 100755 --- a/test/suite-wslua.sh +++ b/test/suite-wslua.sh @@ -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 |