diff options
-rw-r--r-- | epan/wslua/wslua_tree.c | 32 | ||||
-rw-r--r-- | test/lua/protofield.lua | 16 | ||||
-rwxr-xr-x | test/suite-wslua.sh | 27 |
3 files changed, 66 insertions, 9 deletions
diff --git a/epan/wslua/wslua_tree.c b/epan/wslua/wslua_tree.c index bb78a19af8..09392d8f12 100644 --- a/epan/wslua/wslua_tree.c +++ b/epan/wslua/wslua_tree.c @@ -866,6 +866,37 @@ WSLUA_METHOD TreeItem_set_len(lua_State *L) { WSLUA_RETURN(1); /* The same TreeItem. */ } +WSLUA_METHOD TreeItem_referenced(lua_State *L) { + /* Checks if a ProtoField or Dissector is referenced by a filter/tap/UI. + + If this function returns FALSE, it means that the field (or dissector) does not need to be dissected + and can be safely skipped. By skipping a field rather than dissecting it, the dissector will + usually run faster since Wireshark will not do extra dissection work when it doesn't need the field. + + You can use this in conjunction with the TreeItem.visible attribute. This function will always return + TRUE when the TreeItem is visible. When it is not visible and the field is not referenced, you can + speed up the dissection by not dissecting the field as it is not needed for display or filtering. + + This function takes one parameter that can be a ProtoField or a Dissector. The Dissector form is + usefull when you need to decide whether to call a sub-dissector. + + @since 2.4 + */ +#define WSLUA_ARG_TreeItem_referenced_PROTOFIELD 2 /* The ProtoField or Dissector to check if referenced. */ + TreeItem ti = checkTreeItem(L, 1); + if (!ti) return 0; + ProtoField f = shiftProtoField(L, WSLUA_ARG_TreeItem_referenced_PROTOFIELD); + if (f) { + lua_pushboolean(L, proto_field_is_referenced(ti->tree, f->hfid)); + } + else { + Dissector d = checkDissector(L, WSLUA_ARG_TreeItem_referenced_PROTOFIELD); + if (!d) return 0; + lua_pushboolean(L, proto_field_is_referenced(ti->tree, dissector_handle_get_protocol_index(d))); + } + WSLUA_RETURN(1); /* A boolean indicating if the ProtoField/Dissector is referenced */ +} + WSLUA_METAMETHOD TreeItem__tostring(lua_State* L) { /* Returns string debug information about the `TreeItem`. @@ -921,6 +952,7 @@ WSLUA_METHODS TreeItem_methods[] = { WSLUA_CLASS_FNREG(TreeItem,set_generated), WSLUA_CLASS_FNREG(TreeItem,set_hidden), WSLUA_CLASS_FNREG(TreeItem,set_len), + WSLUA_CLASS_FNREG(TreeItem,referenced), { NULL, NULL } }; diff --git a/test/lua/protofield.lua b/test/lua/protofield.lua index c4026e5cf8..6b6110ddff 100644 --- a/test/lua/protofield.lua +++ b/test/lua/protofield.lua @@ -30,7 +30,7 @@ local function setFailed(name) end -- expected number of runs -local taptests = { [OTHER]=28 } +local taptests = { [OTHER]=32 } local function getResults() print("\n-----------------------------\n") for k,v in pairs(taptests) do @@ -70,6 +70,7 @@ end local test_proto = Proto.new("test", "Test Proto") test_proto.fields.time_field = ProtoField.uint16("test.time", "Time", base.UNIT_STRING, {" sec", " secs"}) test_proto.fields.dist_field = ProtoField.uint16("test.dist", "Distance", base.UNIT_STRING, {" km"}) +test_proto.fields.filtered_field = ProtoField.uint16("test.filtered", "Filtered Field", base.DEC) -- Field name: empty, illegal, incompatible success = pcall(ProtoField.int8, nil, "empty field name 1") @@ -155,6 +156,19 @@ function test_proto.dissector(tvb, pinfo, tree) test("Time: 65535 secs", ti.text == "Time: 65535 secs") ti = tree:add(test_proto.fields.dist_field, tvb3()) test("Distance: 65535 km", ti.text == "Distance: 65535 km") + + ti = tree:add(test_proto.fields.filtered_field, tvb2()) + -- Note that this file should be loaded in tshark twice. Once with a visible + -- tree (-V) and once without a visible tree. + if tree.visible then + -- Tree is visible so both fields should be referenced + test("Visible tree: Time is referenced", tree:referenced(test_proto.fields.time_field) == true) + test("Visible tree: Filtered field is referenced", tree:referenced(test_proto.fields.filtered_field) == true) + else + -- Tree is not visible so only the field that appears in a filter should be referenced + test("Invisible tree: Time is NOT referenced", tree:referenced(test_proto.fields.time_field) == false) + test("Invisible tree: Filtered field is referenced", tree:referenced(test_proto.fields.filtered_field) == true) + end end DissectorTable.get("udp.port"):add(65333, test_proto) diff --git a/test/suite-wslua.sh b/test/suite-wslua.sh index c788a7d81c..20745f449a 100755 --- a/test/suite-wslua.sh +++ b/test/suite-wslua.sh @@ -340,14 +340,25 @@ wslua_step_protofield_test() { return fi - # Tshark catches lua script failures, so we have to parse the output. - $TSHARK -r $CAPTURE_DIR/dns_port.pcap -X lua_script:$TESTS_DIR/lua/protofield.lua -V > testout.txt 2>&1 - if grep -q "All tests passed!" testout.txt; then - test_step_ok - else - cat testout.txt - test_step_failed "didn't find pass marker" - fi + # Tshark catches lua script failures, so we have to parse the output. + # Perform this twice: once with a tree, once without + + # Pass 1 (visible tree) + $TSHARK -r $CAPTURE_DIR/dns_port.pcap -X lua_script:$TESTS_DIR/lua/protofield.lua -V -Y "test.filtered==1" > testout.txt 2>&1 + grep -q "All tests passed!" testout.txt + if [ $? -ne 0 ]; then + cat testout.txt + test_step_failed "protofield_test: didn't find pass marker (pass 1)" + fi + + # Pass 2 (invisible tree) + $TSHARK -r $CAPTURE_DIR/dns_port.pcap -X lua_script:$TESTS_DIR/lua/protofield.lua -Y "test.filtered==1" > testout.txt 2>&1 + if grep -q "All tests passed!" testout.txt; then + test_step_ok + else + cat testout.txt + test_step_failed "protofield_test: didn't find pass marker (pass 2)" + fi } wslua_step_int64_test() { |