decryption works, but addid doesn't because of unique pointer layers
[wireshark-sm.git] / test / lua / proto.lua
blobb4306c6983c1b3baa1c09ef97e1aafa0a2d96855
1 ----------------------------------------
2 -- script-name: proto.lua
3 -- Test the Proto/ProtoField API
4 ----------------------------------------
6 ------------- general test helper funcs ------------
7 local testlib = require("testlib")
9 local OTHER = "other"
11 -- expected number of runs per type
12 -- # of fields test doesn't work on Lua 5.4
13 local taptests = {
14 [OTHER]=47
16 testlib.init(taptests)
18 ---------
19 -- the following are so we can use pcall (which needs a function to call)
20 local function callFunc(func,...)
21 func(...)
22 end
24 local function callObjFuncGetter(vart,varn,tobj,name,...)
25 vart[varn] = tobj[name](...)
26 end
28 local function setValue(tobj,name,value)
29 tobj[name] = value
30 end
32 local function getValue(tobj,name)
33 local foo = tobj[name]
34 end
36 ------------- test script ------------
38 ----------------------------------------
39 -- creates a Proto object, but doesn't register it yet
40 testlib.testing(OTHER,"Proto creation")
42 testlib.test(OTHER,"Proto.__call", pcall(callFunc,Proto,"foo","Foo Protocol"))
43 testlib.test(OTHER,"Proto.__call", pcall(callFunc,Proto,"foo1","Foo1 Protocol"))
44 testlib.test(OTHER,"Proto.__call", not pcall(callFunc,Proto,"","Bar Protocol"))
45 testlib.test(OTHER,"Proto.__call", not pcall(callFunc,Proto,nil,"Bar Protocol"))
46 testlib.test(OTHER,"Proto.__call", not pcall(callFunc,Proto,"bar",""))
47 testlib.test(OTHER,"Proto.__call", not pcall(callFunc,Proto,"bar",nil))
50 local dns = Proto("mydns","MyDNS Protocol")
52 testlib.test(OTHER,"Proto.__tostring", tostring(dns) == "Proto: MYDNS")
54 ----------------------------------------
55 -- multiple ways to do the same thing: create a protocol field (but not register it yet)
56 -- the abbreviation should always have "<myproto>." before the specific abbreviation, to avoid collisions
57 testlib.testing(OTHER,"ProtoField creation")
59 local pfields = {} -- a table to hold fields, so we can pass them back/forth through pcall()
60 --- variable -- what dissector.lua did, so we almost match it
61 local pf_trasaction_id = 1 -- ProtoField.new("Transaction ID", "mydns.trans_id", ftypes.UINT16)
62 local pf_flags = 2 -- ProtoField.new("Flags", "mydns.flags", ftypes.UINT16, nil, base.HEX)
63 local pf_num_questions = 3 -- ProtoField.uint16("mydns.num_questions", "Number of Questions")
64 local pf_num_answers = 4 -- ProtoField.uint16("mydns.num_answers", "Number of Answer RRs")
65 local pf_num_authority_rr = 5 -- ProtoField.uint16("mydns.num_authority_rr", "Number of Authority RRs")
66 local pf_num_additional_rr = 6 -- ProtoField.uint16("mydns.num_additional_rr", "Number of Additional RRs")
68 testlib.test(OTHER,"ProtoField.new",pcall(callObjFuncGetter, pfields,pf_trasaction_id, ProtoField,"new", "Transaction ID", "mydns.trans_id", ftypes.INT16,nil,"base.DEC"))
69 testlib.test(OTHER,"ProtoField.new",pcall(callObjFuncGetter, pfields,pf_flags, ProtoField,"new", "Flags", "mydns.flags", ftypes.UINT16, nil, "base.HEX"))
71 -- tries to register a field that already exists (from the real dns proto dissector) but with incompatible type
72 testlib.test(OTHER,"ProtoField.new_duplicate_bad",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "Flags", "dns.flags", ftypes.INT16, nil, "base.HEX"))
73 testlib.test(OTHER,"ProtoField.int16_duplicate_bad",not pcall(callObjFuncGetter, pfields,10, ProtoField,"int16", "dns.id","Transaction ID"))
74 -- now compatible (but different type)
75 testlib.test(OTHER,"ProtoField.new_duplicate_ok",pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "Flags", "dns.flags", ftypes.UINT32, nil, "base.HEX"))
76 testlib.test(OTHER,"ProtoField.uint16_duplicate_ok",pcall(callObjFuncGetter, pfields,10, ProtoField,"uint16", "dns.id","Transaction ID"))
78 -- invalid valuestring arg
79 testlib.test(OTHER,"ProtoField.new_invalid_valuestring",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "Transaction ID", "mydns.trans_id", ftypes.INT16,"howdy","base.DEC"))
80 -- invalid ftype
81 testlib.test(OTHER,"ProtoField.new_invalid_ftype",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "Transaction ID", "mydns.trans_id", 9999))
82 -- invalid description
83 --testlib.test(OTHER,"ProtoField.new_invalid_description",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "", "mydns.trans_id", ftypes.INT16))
84 testlib.test(OTHER,"ProtoField.new_invalid_description",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", nil, "mydns.trans_id", ftypes.INT16))
86 testlib.test(OTHER,"ProtoField.new_invalid_abbr",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "trans id", "", ftypes.INT16))
87 testlib.test(OTHER,"ProtoField.new_invalid_abbr",not pcall(callObjFuncGetter, pfields,10, ProtoField,"new", "trans id", nil, ftypes.INT16))
89 testlib.test(OTHER,"ProtoField.int16",pcall(callObjFuncGetter, pfields,pf_num_questions, ProtoField,"int16", "mydns.num_questions", "Number of Questions"))
90 testlib.test(OTHER,"ProtoField.int16",pcall(callObjFuncGetter, pfields,pf_num_answers, ProtoField,"int16", "mydns.num_answers", "Number of Answer RRs",base.DEC))
91 testlib.test(OTHER,"ProtoField.int16",pcall(callObjFuncGetter, pfields,pf_num_authority_rr, ProtoField,"int16", "mydns.num_authority_rr", "Number of Authority RRs",base.DEC))
92 testlib.test(OTHER,"ProtoField.int16",pcall(callObjFuncGetter, pfields,pf_num_additional_rr, ProtoField,"int16", "mydns.num_additional_rr", "Number of Additional RRs"))
94 -- now undo the table thingy
95 pf_trasaction_id = pfields[pf_trasaction_id]
96 pf_flags = pfields[pf_flags]
97 pf_num_questions = pfields[pf_num_questions]
98 pf_num_answers = pfields[pf_num_answers]
99 pf_num_authority_rr = pfields[pf_num_authority_rr]
100 pf_num_additional_rr = pfields[pf_num_additional_rr]
102 -- within the flags field, we want to parse/show the bits separately
103 -- note the "base" argument becomes the size of the bitmask'ed field when ftypes.BOOLEAN is used
104 -- 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)
105 -- again the following shows different ways of doing the same thing basically
106 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?")
107 local pf_flag_opcode = ProtoField.new("Opcode", "mydns.flags.opcode", ftypes.UINT16, nil, base.DEC, 0x7800, "operation code")
108 local pf_flag_authoritative = ProtoField.new("Authoritative", "mydns.flags.authoritative", ftypes.BOOLEAN, nil, 16, 0x0400, "is the response authoritative?")
109 local pf_flag_truncated = ProtoField.bool("mydns.flags.truncated", "Truncated", 16, nil, 0x0200, "is the message truncated?")
110 local pf_flag_recursion_desired = ProtoField.bool("mydns.flags.recursion_desired", "Recursion desired", 16, {"yes","no"}, 0x0100, "do the query recursivley?")
111 local pf_flag_recursion_available = ProtoField.bool("mydns.flags.recursion_available", "Recursion available", 16, nil, 0x0080, "does the server support recursion?")
112 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?")
113 local pf_flag_authenticated = ProtoField.bool("mydns.flags.authenticated", "Authenticated", 16, {"yes","no"}, 0x0020, "did the server DNSSEC authenticate?")
114 local pf_flag_checking_disabled = ProtoField.bool("mydns.flags.checking_disabled", "Checking disabled", 16, nil, 0x0010)
116 -- no, these aren't all the DNS response codes - this is just an example
117 local rcodes = {
118 [0] = "No Error",
119 [1] = "Format Error",
120 [2] = "Server Failure",
121 [3] = "Non-Existent Domain",
122 [9] = "Server Not Authoritative for zone"
124 -- the above rcodes table is used in this next ProtoField
125 local pf_flag_rcode = ProtoField.uint16("mydns.flags.rcode", "Response code", base.DEC, rcodes, 0x000F)
126 local pf_query = ProtoField.new("Query", "mydns.query", ftypes.BYTES)
127 local pf_query_name = ProtoField.new("Name", "mydns.query.name", ftypes.STRING)
128 local pf_query_name_len = ProtoField.new("Name Length", "mydns.query.name.len", ftypes.UINT8)
129 local pf_query_label_count = ProtoField.new("Label Count", "mydns.query.label.count", ftypes.UINT8)
130 local rrtypes = { [1] = "A (IPv4 host address)", [2] = "NS (authoritative name server)", [28] = "AAAA (for geeks only)" }
131 local pf_query_type = ProtoField.uint16("mydns.query.type", "Type", base.DEC, rrtypes)
132 -- again, not all class types are listed here
133 local classes = {
134 [0] = "Reserved",
135 [1] = "IN (Internet)",
136 [2] = "The 1%",
137 [5] = "First class",
138 [6] = "Business class",
139 [65535] = "Cattle class"
141 local pf_query_class = ProtoField.uint16("mydns.query.class", "Class", base.DEC, classes, nil, "keep it classy folks")
144 testlib.testing(OTHER,"Proto functions")
146 ----------------------------------------
147 -- this actually registers the ProtoFields above, into our new Protocol
148 -- in a real script I wouldn't do it this way; I'd build a table of fields programaticaly
149 -- and then set dns.fields to it, so as to avoid forgetting a field
150 local myfields = { pf_trasaction_id, pf_flags,
151 pf_num_questions, pf_num_answers, pf_num_authority_rr, pf_num_additional_rr,
152 pf_flag_response, pf_flag_opcode, pf_flag_authoritative,
153 pf_flag_truncated, pf_flag_recursion_desired, pf_flag_recursion_available,
154 pf_flag_z, pf_flag_authenticated, pf_flag_checking_disabled, pf_flag_rcode,
155 pf_query, pf_query_name, pf_query_name_len, pf_query_label_count, pf_query_type, pf_query_class }
157 --dns.fields = myfields
158 testlib.test(OTHER,"Proto.fields-set", pcall(setValue,dns,"fields",myfields))
159 testlib.test(OTHER,"Proto.fields-get", pcall(getValue,dns,"fields"))
160 -- This test doesn't work on Lua 5.4 because the # operator includes the
161 -- reference(s) that are the linked list of allocated and free keys,
162 -- starting with LUA_RIDX_LAST + 1 == 3.
163 -- testlib.test(OTHER,"Proto.fields-get", #dns.fields == #myfields)
165 local pf_foo = ProtoField.uint16("myfoo.com", "Fooishly", base.DEC, rcodes, 0x000F)
167 local foo = Proto("myfoo","MyFOO Protocol")
168 local bar = Proto("mybar","MyBAR Protocol")
170 testlib.test(OTHER,"Proto.fields-set", pcall(setValue,foo,"fields",pf_foo))
171 testlib.test(OTHER,"Proto.fields-get", #foo.fields == 1)
172 testlib.test(OTHER,"Proto.fields-get", foo.fields[1] == pf_foo)
174 testlib.test(OTHER,"Proto.fields-set", not pcall(setValue,bar,"fields","howdy"))
175 testlib.test(OTHER,"Proto.fields-set", not pcall(setValue,bar,"fields",nil))
176 testlib.test(OTHER,"Proto.fields-get", #bar.fields == 0)
178 testlib.test(OTHER,"Proto.name-get", foo.name == "MYFOO")
179 testlib.test(OTHER,"Proto.name-set", not pcall(setValue,foo,"name","howdy"))
181 testlib.test(OTHER,"Proto.description-get", foo.description == "MyFOO Protocol")
182 testlib.test(OTHER,"Proto.description-set", not pcall(setValue,foo,"description","howdy"))
184 testlib.test(OTHER,"Proto.prefs-get", typeof(foo.prefs) == "Prefs")
185 testlib.test(OTHER,"Proto.prefs-set", not pcall(setValue,foo,"prefs","howdy"))
187 local function dummy()
188 setFailed(OTHER)
189 error("dummy function called!")
190 return
193 -- can't get this because we haven't set it yet
194 testlib.test(OTHER,"Proto.dissector-get", not pcall(getValue,foo,"dissector"))
195 -- now set it
196 testlib.test(OTHER,"Proto.dissector-set", pcall(setValue,foo,"dissector",dummy))
197 testlib.test(OTHER,"Proto.dissector-set", not pcall(setValue,foo,"dissector","howdy"))
198 testlib.test(OTHER,"Proto.dissector-get", pcall(getValue,foo,"dissector"))
200 testlib.test(OTHER,"Proto.prefs_changed-set", pcall(setValue,foo,"prefs_changed",dummy))
201 testlib.test(OTHER,"Proto.prefs_changed-get", not pcall(getValue,foo,"prefs_changed"))
202 testlib.test(OTHER,"Proto.prefs_changed-set", not pcall(setValue,foo,"prefs_changed","howdy"))
204 local function dummy_init()
205 testlib.test(OTHER,"Proto.init-called",true)
208 testlib.test(OTHER,"Proto.init-set", pcall(setValue,foo,"init",dummy_init))
209 testlib.test(OTHER,"Proto.init-set", pcall(setValue,bar,"init",dummy_init))
211 testlib.test(OTHER,"Proto.init-get", not pcall(getValue,foo,"init"))
212 testlib.test(OTHER,"Proto.init-set", not pcall(setValue,foo,"init","howdy"))
214 testlib.getResults()