aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/wslua/wslua_tree.c32
-rw-r--r--test/lua/protofield.lua16
-rwxr-xr-xtest/suite-wslua.sh27
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() {