diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /test/lua/proto.lua | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/lua/proto.lua')
-rw-r--r-- | test/lua/proto.lua | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/test/lua/proto.lua b/test/lua/proto.lua new file mode 100644 index 00000000..cc038989 --- /dev/null +++ b/test/lua/proto.lua @@ -0,0 +1,211 @@ +---------------------------------------- +-- script-name: proto.lua +-- Test the Proto/ProtoField API +---------------------------------------- + +------------- general test helper funcs ------------ +local testlib = require("testlib") + +local OTHER = "other" + +-- expected number of runs per type +local taptests = { + [OTHER]=48 +} +testlib.init(taptests) + +--------- +-- the following are so we can use pcall (which needs a function to call) +local function callFunc(func,...) + func(...) +end + +local function callObjFuncGetter(vart,varn,tobj,name,...) + vart[varn] = tobj[name](...) +end + +local function setValue(tobj,name,value) + tobj[name] = value +end + +local function getValue(tobj,name) + local foo = tobj[name] +end + +------------- test script ------------ + +---------------------------------------- +-- creates a Proto object, but doesn't register it yet +testlib.testing(OTHER,"Proto creation") + +testlib.test(OTHER,"Proto.__call", pcall(callFunc,Proto,"foo","Foo Protocol")) +testlib.test(OTHER,"Proto.__call", pcall(callFunc,Proto,"foo1","Foo1 Protocol")) +testlib.test(OTHER,"Proto.__call", not pcall(callFunc,Proto,"","Bar Protocol")) +testlib.test(OTHER,"Proto.__call", not pcall(callFunc,Proto,nil,"Bar Protocol")) +testlib.test(OTHER,"Proto.__call", not pcall(callFunc,Proto,"bar","")) +testlib.test(OTHER,"Proto.__call", not pcall(callFunc,Proto,"bar",nil)) + + +local dns = Proto("mydns","MyDNS Protocol") + +testlib.test(OTHER,"Proto.__tostring", tostring(dns) == "Proto: MYDNS") + +---------------------------------------- +-- multiple ways to do the same thing: create a protocol field (but not register it yet) +-- the abbreviation should always have "<myproto>." before the specific abbreviation, to avoid collisions +testlib.testing(OTHER,"ProtoField creation") + +local pfields = {} -- a table to hold fields, so we can pass them back/forth through pcall() +--- variable -- what dissector.lua did, so we almost match it +local pf_trasaction_id = 1 -- ProtoField.new("Transaction ID", "mydns.trans_id", ftypes.UINT16) +local pf_flags = 2 -- ProtoField.new("Flags", "mydns.flags", ftypes.UINT16, nil, base.HEX) +local pf_num_questions = 3 -- ProtoField.uint16("mydns.num_questions", "Number of Questions") +local pf_num_answers = 4 -- ProtoField.uint16("mydns.num_answers", "Number of Answer RRs") +local pf_num_authority_rr = 5 -- ProtoField.uint16("mydns.num_authority_rr", "Number of Authority RRs") +local pf_num_additional_rr = 6 -- ProtoField.uint16("mydns.num_additional_rr", "Number of Additional RRs") + +testlib.test(OTHER,"ProtoField.new",pcall(callObjFuncGetter, pfields,pf_trasaction_id, ProtoField,"new", "Transaction ID", "mydns.trans_id", ftypes.INT16,nil,"base.DEC")) +testlib.test(OTHER,"ProtoField.new",pcall(callObjFuncGetter, pfields,pf_flags, ProtoField,"new", "Flags", "mydns.flags", ftypes.UINT16, nil, "base.HEX")) + +-- tries to register a field that already exists (from the real dns proto dissector) but with incompatible type +testlib.test(OTHER,"ProtoField.new_duplicate_bad",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "Flags", "dns.flags", ftypes.INT16, nil, "base.HEX")) +testlib.test(OTHER,"ProtoField.int16_duplicate_bad",not pcall(callObjFuncGetter, pfields,10, ProtoField,"int16", "dns.id","Transaction ID")) +-- now compatible (but different type) +testlib.test(OTHER,"ProtoField.new_duplicate_ok",pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "Flags", "dns.flags", ftypes.UINT32, nil, "base.HEX")) +testlib.test(OTHER,"ProtoField.uint16_duplicate_ok",pcall(callObjFuncGetter, pfields,10, ProtoField,"uint16", "dns.id","Transaction ID")) + +-- invalid valuestring arg +testlib.test(OTHER,"ProtoField.new_invalid_valuestring",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "Transaction ID", "mydns.trans_id", ftypes.INT16,"howdy","base.DEC")) +-- invalid ftype +testlib.test(OTHER,"ProtoField.new_invalid_ftype",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "Transaction ID", "mydns.trans_id", 9999)) +-- invalid description +--testlib.test(OTHER,"ProtoField.new_invalid_description",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "", "mydns.trans_id", ftypes.INT16)) +testlib.test(OTHER,"ProtoField.new_invalid_description",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", nil, "mydns.trans_id", ftypes.INT16)) + +testlib.test(OTHER,"ProtoField.new_invalid_abbr",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "trans id", "", ftypes.INT16)) +testlib.test(OTHER,"ProtoField.new_invalid_abbr",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "trans id", nil, ftypes.INT16)) + +testlib.test(OTHER,"ProtoField.int16",pcall(callObjFuncGetter, pfields,pf_num_questions, ProtoField,"int16", "mydns.num_questions", "Number of Questions")) +testlib.test(OTHER,"ProtoField.int16",pcall(callObjFuncGetter, pfields,pf_num_answers, ProtoField,"int16", "mydns.num_answers", "Number of Answer RRs",base.DEC)) +testlib.test(OTHER,"ProtoField.int16",pcall(callObjFuncGetter, pfields,pf_num_authority_rr, ProtoField,"int16", "mydns.num_authority_rr", "Number of Authority RRs",base.DEC)) +testlib.test(OTHER,"ProtoField.int16",pcall(callObjFuncGetter, pfields,pf_num_additional_rr, ProtoField,"int16", "mydns.num_additional_rr", "Number of Additional RRs")) + +-- now undo the table thingy +pf_trasaction_id = pfields[pf_trasaction_id] +pf_flags = pfields[pf_flags] +pf_num_questions = pfields[pf_num_questions] +pf_num_answers = pfields[pf_num_answers] +pf_num_authority_rr = pfields[pf_num_authority_rr] +pf_num_additional_rr = pfields[pf_num_additional_rr] + +-- within the flags field, we want to parse/show the bits separately +-- note the "base" argument becomes the size of the bitmask'ed field when ftypes.BOOLEAN is used +-- the "mask" argument is which bits we want to use for this field (e.g., base=16 and mask=0x8000 means we want the top bit of a 16-bit field) +-- again the following shows different ways of doing the same thing basically +local pf_flag_response = ProtoField.new("Response", "mydns.flags.response", ftypes.BOOLEAN, {"this is a response","this is a query"}, 16, 0x8000, "is the message a response?") +local pf_flag_opcode = ProtoField.new("Opcode", "mydns.flags.opcode", ftypes.UINT16, nil, base.DEC, 0x7800, "operation code") +local pf_flag_authoritative = ProtoField.new("Authoritative", "mydns.flags.authoritative", ftypes.BOOLEAN, nil, 16, 0x0400, "is the response authoritative?") +local pf_flag_truncated = ProtoField.bool("mydns.flags.truncated", "Truncated", 16, nil, 0x0200, "is the message truncated?") +local pf_flag_recursion_desired = ProtoField.bool("mydns.flags.recursion_desired", "Recursion desired", 16, {"yes","no"}, 0x0100, "do the query recursivley?") +local pf_flag_recursion_available = ProtoField.bool("mydns.flags.recursion_available", "Recursion available", 16, nil, 0x0080, "does the server support recursion?") +local pf_flag_z = ProtoField.uint16("mydns.flags.z", "World War Z - Reserved for future use", base.HEX, nil, 0x0040, "when is it the future?") +local pf_flag_authenticated = ProtoField.bool("mydns.flags.authenticated", "Authenticated", 16, {"yes","no"}, 0x0020, "did the server DNSSEC authenticate?") +local pf_flag_checking_disabled = ProtoField.bool("mydns.flags.checking_disabled", "Checking disabled", 16, nil, 0x0010) + +-- no, these aren't all the DNS response codes - this is just an example +local rcodes = { + [0] = "No Error", + [1] = "Format Error", + [2] = "Server Failure", + [3] = "Non-Existent Domain", + [9] = "Server Not Authoritative for zone" +} +-- the above rcodes table is used in this next ProtoField +local pf_flag_rcode = ProtoField.uint16("mydns.flags.rcode", "Response code", base.DEC, rcodes, 0x000F) +local pf_query = ProtoField.new("Query", "mydns.query", ftypes.BYTES) +local pf_query_name = ProtoField.new("Name", "mydns.query.name", ftypes.STRING) +local pf_query_name_len = ProtoField.new("Name Length", "mydns.query.name.len", ftypes.UINT8) +local pf_query_label_count = ProtoField.new("Label Count", "mydns.query.label.count", ftypes.UINT8) +local rrtypes = { [1] = "A (IPv4 host address)", [2] = "NS (authoritative name server)", [28] = "AAAA (for geeks only)" } +local pf_query_type = ProtoField.uint16("mydns.query.type", "Type", base.DEC, rrtypes) +-- again, not all class types are listed here +local classes = { + [0] = "Reserved", + [1] = "IN (Internet)", + [2] = "The 1%", + [5] = "First class", + [6] = "Business class", + [65535] = "Cattle class" +} +local pf_query_class = ProtoField.uint16("mydns.query.class", "Class", base.DEC, classes, nil, "keep it classy folks") + + +testlib.testing(OTHER,"Proto functions") + +---------------------------------------- +-- this actually registers the ProtoFields above, into our new Protocol +-- in a real script I wouldn't do it this way; I'd build a table of fields programaticaly +-- and then set dns.fields to it, so as to avoid forgetting a field +local myfields = { pf_trasaction_id, pf_flags, + pf_num_questions, pf_num_answers, pf_num_authority_rr, pf_num_additional_rr, + pf_flag_response, pf_flag_opcode, pf_flag_authoritative, + pf_flag_truncated, pf_flag_recursion_desired, pf_flag_recursion_available, + pf_flag_z, pf_flag_authenticated, pf_flag_checking_disabled, pf_flag_rcode, + pf_query, pf_query_name, pf_query_name_len, pf_query_label_count, pf_query_type, pf_query_class } + +--dns.fields = myfields +testlib.test(OTHER,"Proto.fields-set", pcall(setValue,dns,"fields",myfields)) +testlib.test(OTHER,"Proto.fields-get", pcall(getValue,dns,"fields")) +testlib.test(OTHER,"Proto.fields-get", #dns.fields == #myfields) + +local pf_foo = ProtoField.uint16("myfoo.com", "Fooishly", base.DEC, rcodes, 0x000F) + +local foo = Proto("myfoo","MyFOO Protocol") +local bar = Proto("mybar","MyBAR Protocol") + +testlib.test(OTHER,"Proto.fields-set", pcall(setValue,foo,"fields",pf_foo)) +testlib.test(OTHER,"Proto.fields-get", #foo.fields == 1) +testlib.test(OTHER,"Proto.fields-get", foo.fields[1] == pf_foo) + +testlib.test(OTHER,"Proto.fields-set", not pcall(setValue,bar,"fields","howdy")) +testlib.test(OTHER,"Proto.fields-set", not pcall(setValue,bar,"fields",nil)) +testlib.test(OTHER,"Proto.fields-get", #bar.fields == 0) + +testlib.test(OTHER,"Proto.name-get", foo.name == "MYFOO") +testlib.test(OTHER,"Proto.name-set", not pcall(setValue,foo,"name","howdy")) + +testlib.test(OTHER,"Proto.description-get", foo.description == "MyFOO Protocol") +testlib.test(OTHER,"Proto.description-set", not pcall(setValue,foo,"description","howdy")) + +testlib.test(OTHER,"Proto.prefs-get", typeof(foo.prefs) == "Prefs") +testlib.test(OTHER,"Proto.prefs-set", not pcall(setValue,foo,"prefs","howdy")) + +local function dummy() + setFailed(OTHER) + error("dummy function called!") + return +end + +-- can't get this because we haven't set it yet +testlib.test(OTHER,"Proto.dissector-get", not pcall(getValue,foo,"dissector")) +-- now set it +testlib.test(OTHER,"Proto.dissector-set", pcall(setValue,foo,"dissector",dummy)) +testlib.test(OTHER,"Proto.dissector-set", not pcall(setValue,foo,"dissector","howdy")) +testlib.test(OTHER,"Proto.dissector-get", pcall(getValue,foo,"dissector")) + +testlib.test(OTHER,"Proto.prefs_changed-set", pcall(setValue,foo,"prefs_changed",dummy)) +testlib.test(OTHER,"Proto.prefs_changed-get", not pcall(getValue,foo,"prefs_changed")) +testlib.test(OTHER,"Proto.prefs_changed-set", not pcall(setValue,foo,"prefs_changed","howdy")) + +local function dummy_init() + testlib.test(OTHER,"Proto.init-called",true) +end + +testlib.test(OTHER,"Proto.init-set", pcall(setValue,foo,"init",dummy_init)) +testlib.test(OTHER,"Proto.init-set", pcall(setValue,bar,"init",dummy_init)) + +testlib.test(OTHER,"Proto.init-get", not pcall(getValue,foo,"init")) +testlib.test(OTHER,"Proto.init-set", not pcall(setValue,foo,"init","howdy")) + +testlib.getResults() + |