e03a7b61b4499b25a3aadebe4a8bd47891219354
[metze/wireshark/wip.git] / test / lua / tvb.lua
1 ----------------------------------------
2 -- script-name: tvb.lua
3 -- This tests the Tvb/TvbRange and proto_add_XXX_item API.
4 ----------------------------------------
5
6 ------------- general test helper funcs ------------
7 local FRAME = "frame"
8 local OTHER = "other"
9
10 local total_tests = 0
11 local function getTotal()
12     return total_tests
13 end
14
15
16 local packet_counts = {}
17 local function incPktCount(name)
18     if not packet_counts[name] then
19         packet_counts[name] = 1
20     else
21         packet_counts[name] = packet_counts[name] + 1
22     end
23 end
24 local function getPktCount(name)
25     return packet_counts[name] or 0
26 end
27
28 local passed = {}
29 local function setPassed(name)
30     if not passed[name] then
31         passed[name] = 1
32     else
33         passed[name] = passed[name] + 1
34     end
35     total_tests = total_tests + 1
36 end
37
38 local fail_count = 0
39 local function setFailed(name)
40     fail_count = fail_count + 1
41     total_tests = total_tests + 1
42 end
43
44 -- expected number of runs per type
45 --
46 -- CHANGE THIS TO MATCH HOW MANY TESTS THERE ARE
47 --
48 -- The number of tests in a specific category (other than FRAME) is the
49 -- number of times execute() is called by any function below testing().
50 -- From the user's perspective, it can be calculated with the following
51 -- formula:
52 --
53 -- N = number of execute() you call +
54 --     number of verifyFields() * (1 + number of fields) +
55 --     number of verifyResults() * (1 + 2 * number of values)
56 --
57 local taptests = { [FRAME]=4, [OTHER]=330 }
58
59 local function getResults()
60     print("\n-----------------------------\n")
61     for k,v in pairs(taptests) do
62         -- each frame run executes the same test again, so multiply by #frames
63         if k ~= "frame" and v ~= 0 then v = (v * taptests.frame) end
64
65         if v ~= 0 and passed[k] ~= v then
66             print("Something didn't run or ran too much... tests failed!")
67             print("Dissector type " .. k ..
68                   " expected: " .. v ..
69                   " (" .. ( v / taptests.frame) .. ")" ..
70                   ", but got: " .. tostring(passed[k]) ..
71                   " (" .. (tonumber(passed[k] or 0) / taptests.frame) .. ")" )
72             return false
73         end
74     end
75     print("All tests passed!\n\n")
76     return true
77 end
78
79
80 local function testing(type,...)
81     print("\n-------- Testing " .. tostring(...) ..
82           " ---- for packet # " .. getPktCount(type) ..
83           " --------\n")
84 end
85
86 local function execute(type,name, ...)
87     io.stdout:write("test --> "..name.."-"..getTotal().."-"..getPktCount(type).."...")
88     local results = { ... }
89     if #results > 0 and results[1] == true then
90         setPassed(type)
91         io.stdout:write("passed\n")
92         return true
93     else
94         setFailed(type)
95         io.stdout:write("failed!\n")
96         if #results > 1 then
97             print("Got the following error: '" .. tostring(results[2]) .. "'")
98         end
99         error(name.." test failed!")
100     end
101 end
102
103 ---------
104 -- the following are so we can use pcall (which needs a function to call)
105 local function callFunc(func,...)
106     func(...)
107 end
108
109 local function callObjFuncGetter(vart,varn,tobj,name,...)
110     vart[varn] = tobj[name](...)
111 end
112
113 local function setValue(tobj,name,value)
114     tobj[name] = value
115 end
116
117 local function getValue(tobj,name)
118     local foo = tobj[name]
119 end
120
121 ------------- test script ------------
122
123 ----------------------------------
124 -- modify original test function for now, kinda sorta
125 local orig_execute = execute
126 execute = function (...)
127     return orig_execute(OTHER,...)
128 end
129
130 ----------------------------------------
131 -- creates a Proto object for our testing
132 local test_proto = Proto("test","Test Protocol")
133
134 local numinits = 0
135 function test_proto.init()
136     numinits = numinits + 1
137     if numinits == 2 then
138         getResults()
139     end
140 end
141
142
143 ----------------------------------------
144 -- a table of all of our Protocol's fields
145 local testfield =
146 {
147     basic =
148     {
149         STRING         = ProtoField.string ("test.basic.string",  "Basic string"),
150         BOOLEAN        = ProtoField.bool   ("test.basic.boolean", "Basic boolean", 16, {"yes","no"}, 0x0001),
151         UINT16         = ProtoField.uint16 ("test.basic.uint16",  "Basic uint16"),
152         INT24          = ProtoField.int24  ("test.basic.uint24",  "Basic uint24"),
153         BYTES          = ProtoField.bytes  ("test.basic.bytes",   "Basic Bytes"),
154         UINT_BYTES     = ProtoField.ubytes ("test.basic.ubytes",  "Basic Uint Bytes"),
155         OID            = ProtoField.oid    ("test.basic.oid",     "Basic OID"),
156         REL_OID        = ProtoField.rel_oid("test.basic.rel_oid", "Basic Relative OID"),
157         ABSOLUTE_LOCAL = ProtoField.absolute_time("test.basic.absolute.local","Basic absolute local"),
158         ABSOLUTE_UTC   = ProtoField.absolute_time("test.basic.absolute.utc",  "Basic absolute utc", base.UTC),
159         IPv4           = ProtoField.ipv4   ("test.basic.ipv4",    "Basic ipv4 address"),
160         IPv6           = ProtoField.ipv6   ("test.basic.ipv6",    "Basic ipv6 address"),
161         -- GUID           = ProtoField.guid   ("test.basic.guid",    "Basic GUID"),
162     },
163
164     time =
165     {
166         ABSOLUTE_LOCAL = ProtoField.absolute_time("test.time.absolute.local","Time absolute local"),
167         ABSOLUTE_UTC   = ProtoField.absolute_time("test.time.absolute.utc",  "Time absolute utc", base.UTC),
168     },
169
170     bytes =
171     {
172         BYTES      = ProtoField.bytes  ("test.bytes.bytes",   "Bytes"),
173         UINT_BYTES = ProtoField.ubytes ("test.bytes.ubytes",  "Uint Bytes"),
174         OID        = ProtoField.oid    ("test.bytes.oid",     "OID"),
175         REL_OID    = ProtoField.rel_oid("test.bytes.rel_oid", "Relative OID"),
176         -- GUID       = ProtoField.guid   ("test.bytes.guid",    "GUID"),
177     },
178 }
179
180 -- create a flat array table of the above that can be registered
181 local pfields = {}
182 for _,t in pairs(testfield) do
183     for k,v in pairs(t) do
184         pfields[#pfields+1] = v
185     end
186 end
187
188 -- register them
189 test_proto.fields = pfields
190
191 print("test_proto ProtoFields registered")
192
193
194 local getfield =
195 {
196     basic =
197     {
198         STRING         = Field.new ("test.basic.string"),
199         BOOLEAN        = Field.new ("test.basic.boolean"),
200         UINT16         = Field.new ("test.basic.uint16"),
201         INT24          = Field.new ("test.basic.uint24"),
202         BYTES          = Field.new ("test.basic.bytes"),
203         UINT_BYTES     = Field.new ("test.basic.ubytes"),
204         OID            = Field.new ("test.basic.oid"),
205         REL_OID        = Field.new ("test.basic.rel_oid"),
206         ABSOLUTE_LOCAL = Field.new ("test.basic.absolute.local"),
207         ABSOLUTE_UTC   = Field.new ("test.basic.absolute.utc"),
208         IPv4           = Field.new ("test.basic.ipv4"),
209         IPv6           = Field.new ("test.basic.ipv6"),
210         -- GUID           = Field.new ("test.basic.guid"),
211     },
212
213     time =
214     {
215         ABSOLUTE_LOCAL = Field.new ("test.time.absolute.local"),
216         ABSOLUTE_UTC   = Field.new ("test.time.absolute.utc"),
217     },
218
219     bytes =
220     {
221         BYTES      = Field.new ("test.bytes.bytes"),
222         UINT_BYTES = Field.new ("test.bytes.ubytes"),
223         OID        = Field.new ("test.bytes.oid"),
224         REL_OID    = Field.new ("test.bytes.rel_oid"),
225         -- GUID       = Field.new ("test.bytes.guid"),
226     },
227 }
228
229 print("test_proto Fields created")
230
231 local function addMatchFields(match_fields, ... )
232     match_fields[#match_fields + 1] = { ... }
233 end
234
235 local function getFieldInfos(name)
236     local base, field = name:match("([^.]+)%.(.+)")
237     if not base or not field then
238         error("failed to get base.field from '" .. name .. "'")
239     end
240     local t = { getfield[base][field]() }
241     return t
242 end
243
244 local function verifyFields(name, match_fields)
245     local finfos = getFieldInfos(name)
246
247     execute ("verify-fields-size-" .. name, #finfos == #match_fields,
248              "#finfos=" .. #finfos .. ", #match_fields=" .. #match_fields)
249
250     for i, t in ipairs(match_fields) do
251         if type(t) ~= 'table' then
252             error("verifyFields didn't get a table inside the matches table")
253         end
254         if #t ~= 1 then
255             error("verifyFields matches table's table is not size 1")
256         end
257         local result = finfos[i]()
258         local value  = t[1]
259         print(
260                 name .. " got:",
261                 "\n\tfinfos [" .. i .. "]='" .. tostring( result ) .. "'",
262                 "\n\tmatches[" .. i .. "]='" .. tostring( value  ) .. "'"
263              )
264         execute ( "verify-fields-value-" .. name .. "-" .. i, result == value )
265     end
266 end
267
268
269 local function addMatchValues(match_values, ... )
270     match_values[#match_values + 1] = { ... }
271 end
272
273 local function addMatchFieldValues(match_fields, match_values, match_both, ...)
274     addMatchFields(match_fields, match_both)
275     addMatchValues(match_values, match_both, ...)
276 end
277
278 local result_values = {}
279 local function resetResults()
280     result_values = {}
281 end
282
283 local function treeAddPField(...)
284     local t = { pcall ( TreeItem.add_packet_field, ... ) }
285     if t[1] == nil then
286         return nil, t[2]
287     end
288     -- it gives back a TreeItem, then the results
289     if typeof(t[2]) ~= 'TreeItem' then
290         return nil, "did not get a TreeItem returned from TreeItem.add_packet_field, "..
291                     "got a '" .. typeof(t[2]) .."'"
292     end
293
294     if #t ~= 4 then
295         return nil, "did not get 3 return values from TreeItem.add_packet_field"
296     end
297
298     result_values[#result_values + 1] = { t[3], t[4] }
299
300     return true
301 end
302
303 local function verifyResults(name, match_values)
304     execute ("verify-results-size-" .. name, #result_values == #match_values,
305              "#result_values=" .. #result_values ..
306              ", #match_values=" .. #match_values)
307
308     for j, t in ipairs(match_values) do
309         if type(t) ~= 'table' then
310             error("verifyResults didn't get a table inside the matches table")
311         end
312         for i, match in ipairs(t) do
313             local r = result_values[j][i]
314             print(
315                     name .. " got:",
316                     "\n\tresults[" .. j .. "][" .. i .. "]='" .. tostring( r ) .. "'",
317                     "\n\tmatches[" .. j .. "][" .. i .. "]='" .. tostring( match ) .. "'"
318                  )
319             local result_type, match_type
320             if type(match) == 'userdata' then
321                 match_type = typeof(match)
322             else
323                 match_type = type(match)
324             end
325             if type(r) == 'userdata' then
326                 result_type = typeof(r)
327             else
328                 result_type = type(r)
329             end
330             execute ( "verify-results-type-" .. name .. "-" .. i, result_type == match_type )
331             execute ( "verify-results-value-" .. name .. "-" .. i, r == match )
332         end
333     end
334 end
335
336 -- Compute the difference in seconds between local time and UTC
337 -- from http://lua-users.org/wiki/TimeZone
338 local function get_timezone()
339   local now = os.time()
340   return os.difftime(now, os.time(os.date("!*t", now)))
341 end
342 local timezone = get_timezone()
343 print ("timezone = " .. timezone)
344
345 ----------------------------------------
346 -- The following creates the callback function for the dissector.
347 -- The 'tvbuf' is a Tvb object, 'pktinfo' is a Pinfo object, and 'root' is a TreeItem object.
348 function test_proto.dissector(tvbuf,pktinfo,root)
349
350     incPktCount(FRAME)
351     incPktCount(OTHER)
352
353     testing(OTHER, "Basic string")
354
355     local tree = root:add(test_proto, tvbuf:range(0,tvbuf:len()))
356
357     -- create a fake Tvb to use for testing
358     local teststring = "this is the string for the first test"
359     local bytearray  = ByteArray.new(teststring, true)
360     local tvb_string = bytearray:tvb("Basic string")
361
362     local function callTreeAdd(tree,...)
363         tree:add(...)
364     end
365
366     local string_match_fields = {}
367
368     execute ("basic-tvb_get_string", tvb_string:range():string() == teststring )
369
370     execute ("basic-string", tree:add(testfield.basic.STRING, tvb_string:range(0,tvb_string:len())) ~= nil )
371     addMatchFields(string_match_fields, teststring)
372
373     execute ("basic-string", pcall (callTreeAdd, tree, testfield.basic.STRING, tvb_string:range() ) )
374     addMatchFields(string_match_fields, teststring)
375
376     verifyFields("basic.STRING", string_match_fields)
377
378 ----------------------------------------
379     testing(OTHER, "Basic boolean")
380
381     local barray_bytes_hex  = "00FF00018000"
382     local barray_bytes      = ByteArray.new(barray_bytes_hex)
383     local tvb_bytes         = barray_bytes:tvb("Basic bytes")
384     local bool_match_fields = {}
385
386     execute ("basic-boolean", pcall (callTreeAdd, tree, testfield.basic.BOOLEAN, tvb_bytes:range(0,2)) )
387     addMatchFields(bool_match_fields, true)
388
389     execute ("basic-boolean", pcall (callTreeAdd, tree, testfield.basic.BOOLEAN, tvb_bytes:range(2,2)) )
390     addMatchFields(bool_match_fields, true)
391
392     execute ("basic-boolean", pcall (callTreeAdd, tree, testfield.basic.BOOLEAN, tvb_bytes:range(4,2)) )
393     addMatchFields(bool_match_fields, false)
394
395     verifyFields("basic.BOOLEAN", bool_match_fields )
396
397 ----------------------------------------
398     testing(OTHER, "Basic uint16")
399
400     local uint16_match_fields = {}
401
402     execute ("basic-uint16", pcall (callTreeAdd, tree, testfield.basic.UINT16, tvb_bytes:range(0,2)) )
403     addMatchFields(uint16_match_fields, 255)
404
405     execute ("basic-uint16", pcall (callTreeAdd, tree, testfield.basic.UINT16, tvb_bytes:range(2,2)) )
406     addMatchFields(uint16_match_fields, 1)
407
408     execute ("basic-uint16", pcall (callTreeAdd, tree, testfield.basic.UINT16, tvb_bytes:range(4,2)) )
409     addMatchFields(uint16_match_fields, 32768)
410
411     verifyFields("basic.UINT16", uint16_match_fields)
412
413 ----------------------------------------
414     testing(OTHER, "Basic uint16-le")
415
416     local function callTreeAddLE(tree,...)
417         tree:add_le(...)
418     end
419
420     execute ("basic-uint16-le", pcall (callTreeAddLE, tree, testfield.basic.UINT16, tvb_bytes:range(0,2)) )
421     addMatchFields(uint16_match_fields, 65280)
422
423     execute ("basic-uint16-le", pcall (callTreeAddLE, tree, testfield.basic.UINT16, tvb_bytes:range(2,2)) )
424     addMatchFields(uint16_match_fields, 256)
425
426     execute ("basic-uint16-le", pcall (callTreeAddLE, tree, testfield.basic.UINT16, tvb_bytes:range(4,2)) )
427     addMatchFields(uint16_match_fields, 128)
428
429     verifyFields("basic.UINT16", uint16_match_fields)
430
431 ----------------------------------------
432     testing(OTHER, "Basic int24")
433
434     local int24_match_fields = {}
435
436     execute ("basic-int24", pcall (callTreeAdd, tree, testfield.basic.INT24, tvb_bytes:range(0,3)) )
437     addMatchFields(int24_match_fields, 65280)
438
439     execute ("basic-int24", pcall (callTreeAdd, tree, testfield.basic.INT24, tvb_bytes:range(3,3)) )
440     addMatchFields(int24_match_fields, 98304)
441
442     verifyFields("basic.INT24", int24_match_fields)
443
444 ----------------------------------------
445     testing(OTHER, "Basic int24-le")
446
447     execute ("basic-int24", pcall (callTreeAddLE, tree, testfield.basic.INT24, tvb_bytes:range(0,3)) )
448     addMatchFields(int24_match_fields, 65280)
449
450     execute ("basic-int24", pcall (callTreeAddLE, tree, testfield.basic.INT24, tvb_bytes:range(3,3)) )
451     addMatchFields(int24_match_fields, 32769)
452
453     verifyFields("basic.INT24", int24_match_fields)
454
455 ----------------------------------------
456     testing(OTHER, "Basic bytes")
457
458     local bytes_match_fields = {}
459
460     execute ("basic-tvb_get_string_bytes",
461              string.lower(tostring(tvb_bytes:range():bytes())) == string.lower(barray_bytes_hex))
462
463     execute ("basic-bytes", pcall (callTreeAdd, tree, testfield.basic.BYTES, tvb_bytes:range()) )
464     addMatchFields(bytes_match_fields, barray_bytes)
465
466     -- TODO: it's silly that tree:add_packet_field() requires an encoding argument
467     --  need to fix that separately in a bug fix
468     execute ("add_pfield-bytes", treeAddPField(tree, testfield.basic.BYTES,
469                                                tvb_bytes:range(), ENC_BIG_ENDIAN))
470     addMatchFields(bytes_match_fields, barray_bytes)
471
472     verifyFields("basic.BYTES", bytes_match_fields)
473
474 ----------------------------------------
475     testing(OTHER, "Basic uint bytes")
476
477     local len_string        = string.format("%02x", barray_bytes:len())
478     local barray_uint_bytes = ByteArray.new(len_string) .. barray_bytes
479     local tvb_uint_bytes    = barray_uint_bytes:tvb("Basic UINT_BYTES")
480     local uint_bytes_match_fields = {}
481
482     execute ("basic-uint-bytes", pcall (callTreeAdd, tree, testfield.basic.UINT_BYTES,
483                                         tvb_uint_bytes:range(0,1)) )
484     addMatchFields(uint_bytes_match_fields, barray_bytes)
485
486     execute ("add_pfield-uint-bytes", treeAddPField(tree, testfield.basic.UINT_BYTES,
487                                                     tvb_uint_bytes:range(0,1), ENC_BIG_ENDIAN) )
488     addMatchFields(uint_bytes_match_fields, barray_bytes)
489
490     verifyFields("basic.UINT_BYTES", uint_bytes_match_fields)
491
492 ----------------------------------------
493     testing(OTHER, "Basic OID")
494
495     -- note: the tvb being dissected and compared isn't actually a valid OID.
496     -- tree:add() and tree:add_packet-field() don't care about its validity right now.
497
498     local oid_match_fields = {}
499
500     execute ("basic-oid", pcall(callTreeAdd, tree, testfield.basic.OID, tvb_bytes:range()) )
501     addMatchFields(oid_match_fields, barray_bytes)
502
503     execute ("add_pfield-oid", treeAddPField(tree, testfield.basic.OID,
504                                              tvb_bytes:range(), ENC_BIG_ENDIAN) )
505     addMatchFields(oid_match_fields, barray_bytes)
506
507     verifyFields("basic.OID", oid_match_fields)
508
509 ----------------------------------------
510     testing(OTHER, "Basic REL_OID")
511
512     -- note: the tvb being dissected and compared isn't actually a valid OID.
513     -- tree:add() and tree:add_packet-field() don't care about its validity right now.
514
515     local rel_oid_match_fields = {}
516
517     execute ("basic-rel-oid", pcall(callTreeAdd, tree, testfield.basic.REL_OID, tvb_bytes:range()))
518     addMatchFields(rel_oid_match_fields, barray_bytes)
519
520     execute ("add_pfield-rel_oid", treeAddPField(tree, testfield.basic.REL_OID,
521                                                  tvb_bytes:range(), ENC_BIG_ENDIAN) )
522     addMatchFields(rel_oid_match_fields, barray_bytes)
523
524     verifyFields("basic.REL_OID", rel_oid_match_fields)
525
526     -- TODO: a FT_GUID is not really a ByteArray, so we can't simply treat it as one
527     -- local barray_guid       = ByteArray.new("00FF0001 80001234 567890AB CDEF00FF")
528     -- local tvb_guid          = barray_guid:tvb("Basic GUID")
529     -- local guid_match_fields = {}
530
531     -- execute ("basic-guid", pcall(callTreeAdd, tree, testfield.basic.GUID, tvb_guid:range()) )
532     -- addMatchFields(guid_match_fields, barray_guid)
533
534     -- execute ("add_pfield-guid", treeAddPField(tree, testfield.basic.GUID,
535     --                                          tvb_guid:range(), ENC_BIG_ENDIAN) )
536     -- addMatchFields(guid_match_fields, barray_guid)
537
538     -- verifyFields("basic.GUID", guid_match_fields)
539
540 ----------------------------------------
541     testing(OTHER, "tree:add ipv6")
542
543     local tvb = ByteArray.new("20010db8 00000000 0000ff00 00428329"):tvb("IPv6")
544     local IPv6 = testfield.basic.IPv6
545     local ipv6_match_fields = {}
546
547     execute ("ipv6", pcall (callTreeAdd, tree, IPv6, tvb:range(0,16)))
548     addMatchFields(ipv6_match_fields, Address.ipv6('2001:0db8:0000:0000:0000:ff00:0042:8329'))
549
550     verifyFields("basic.IPv6", ipv6_match_fields)
551
552 ----------------------------------------
553     testing(OTHER, "tree:add ipv4")
554
555     local tvb = ByteArray.new("7f000001"):tvb("IPv4")
556     local IPv4 = testfield.basic.IPv4
557     local ipv4_match_fields = {}
558
559     execute ("ipv4", pcall (callTreeAdd, tree, IPv4, tvb:range(0,4)))
560     addMatchFields(ipv4_match_fields, Address.ip('127.0.0.1'))
561
562     -- TODO: currently, tree:add_le only works for numeric values, not IPv4
563     -- addresses. Test this in the future.
564
565     -- execute ("ipv4", pcall (callTreeAddLE, tree, IPv4, tvb:range(0,4)))
566     -- addMatchFields(ipv4_match_fields, Address.ip('1.0.0.127'))
567
568     verifyFields("basic.IPv4", ipv4_match_fields)
569
570 ----------------------------------------
571     testing(OTHER, "tree:add_packet_field Bytes")
572
573     resetResults()
574     bytes_match_fields = {}
575     local bytes_match_values = {}
576
577     -- something to make this easier to read
578     local function addMatch(...)
579         addMatchFieldValues(bytes_match_fields, bytes_match_values, ...)
580     end
581
582     local bytesstring1 =   "deadbeef0123456789DEADBEEFabcdef"
583     local bytesstring = ByteArray.new(bytesstring1) -- the binary version of above, for comparing
584     local bytestvb1 = ByteArray.new(bytesstring1, true):tvb("Bytes hex-string 1")
585     local bytesstring2 = "  de:ad:be:ef:01:23:45:67:89:DE:AD:BE:EF:ab:cd:ef"
586     local bytestvb2 = ByteArray.new(bytesstring2 .. "-f0-00 foobar", true):tvb("Bytes hex-string 2")
587
588     local bytestvb1_decode = bytestvb1:range():bytes(ENC_STR_HEX + ENC_SEP_NONE + ENC_SEP_COLON + ENC_SEP_DASH)
589     execute ("tvb_get_string_bytes", string.lower(tostring(bytestvb1_decode)) == string.lower(tostring(bytesstring1)))
590
591     execute ("add_pfield-bytes1", treeAddPField(tree, testfield.bytes.BYTES,
592                                                bytestvb1:range(),
593                                                ENC_STR_HEX + ENC_SEP_NONE +
594                                                ENC_SEP_COLON + ENC_SEP_DASH))
595     addMatch(bytesstring, string.len(bytesstring1))
596
597     execute ("add_pfield-bytes2", treeAddPField(tree, testfield.bytes.BYTES,
598                                                bytestvb2:range(),
599                                                ENC_STR_HEX + ENC_SEP_NONE +
600                                                ENC_SEP_COLON + ENC_SEP_DASH))
601     addMatch(bytesstring, string.len(bytesstring2))
602
603     verifyResults("add_pfield-bytes", bytes_match_values)
604     verifyFields("bytes.BYTES", bytes_match_fields)
605
606
607 ----------------------------------------
608     testing(OTHER, "tree:add_packet_field OID")
609
610     resetResults()
611     bytes_match_fields = {}
612     bytes_match_values = {}
613
614     execute ("add_pfield-oid1", treeAddPField(tree, testfield.bytes.OID,
615                                                bytestvb1:range(),
616                                                ENC_STR_HEX + ENC_SEP_NONE +
617                                                ENC_SEP_COLON + ENC_SEP_DASH))
618     addMatch(bytesstring, string.len(bytesstring1))
619
620     execute ("add_pfield-oid2", treeAddPField(tree, testfield.bytes.OID,
621                                                bytestvb2:range(),
622                                                ENC_STR_HEX + ENC_SEP_NONE +
623                                                ENC_SEP_COLON + ENC_SEP_DASH))
624     addMatch(bytesstring, string.len(bytesstring2))
625
626     verifyResults("add_pfield-oid", bytes_match_values)
627     verifyFields("bytes.OID", bytes_match_fields)
628
629
630 ----------------------------------------
631     testing(OTHER, "tree:add_packet_field REL_OID")
632
633     resetResults()
634     bytes_match_fields = {}
635     bytes_match_values = {}
636
637     execute ("add_pfield-rel_oid1", treeAddPField(tree, testfield.bytes.REL_OID,
638                                                bytestvb1:range(),
639                                                ENC_STR_HEX + ENC_SEP_NONE +
640                                                ENC_SEP_COLON + ENC_SEP_DASH))
641     addMatch(bytesstring, string.len(bytesstring1))
642
643     execute ("add_pfield-rel_oid2", treeAddPField(tree, testfield.bytes.REL_OID,
644                                                bytestvb2:range(),
645                                                ENC_STR_HEX + ENC_SEP_NONE +
646                                                ENC_SEP_COLON + ENC_SEP_DASH))
647     addMatch(bytesstring, string.len(bytesstring2))
648
649     verifyResults("add_pfield-rel_oid", bytes_match_values)
650     verifyFields("bytes.REL_OID", bytes_match_fields)
651
652
653 ----------------------------------------
654     testing(OTHER, "tree:add Time")
655
656     local tvb = ByteArray.new("00000000 00000000 0000FF0F 00FF000F"):tvb("Time")
657     local ALOCAL = testfield.time.ABSOLUTE_LOCAL
658     local alocal_match_fields = {}
659
660     execute ("time-local",    pcall (callTreeAdd,   tree, ALOCAL, tvb:range(0,8)) )
661     addMatchFields(alocal_match_fields, NSTime())
662
663     execute ("time-local",    pcall (callTreeAdd,   tree, ALOCAL, tvb:range(8,8)) )
664     addMatchFields(alocal_match_fields, NSTime( 0x0000FF0F, 0x00FF000F) )
665
666     execute ("time-local-le", pcall (callTreeAddLE, tree, ALOCAL, tvb:range(0,8)) )
667     addMatchFields(alocal_match_fields, NSTime())
668
669     execute ("time-local-le", pcall (callTreeAddLE, tree, ALOCAL, tvb:range(8,8)) )
670     addMatchFields(alocal_match_fields, NSTime( 0x0FFF0000, 0x0F00FF00 ) )
671
672     verifyFields("time.ABSOLUTE_LOCAL", alocal_match_fields)
673
674     local AUTC = testfield.time.ABSOLUTE_UTC
675     local autc_match_fields = {}
676
677     execute ("time-utc",    pcall (callTreeAdd,   tree, AUTC, tvb:range(0,8)) )
678     addMatchFields(autc_match_fields, NSTime())
679
680     execute ("time-utc",    pcall (callTreeAdd,   tree, AUTC, tvb:range(8,8)) )
681     addMatchFields(autc_match_fields, NSTime( 0x0000FF0F, 0x00FF000F) )
682
683     execute ("time-utc-le", pcall (callTreeAddLE, tree, AUTC, tvb:range(0,8)) )
684     addMatchFields(autc_match_fields, NSTime())
685
686     execute ("time-utc-le", pcall (callTreeAddLE, tree, AUTC, tvb:range(8,8)) )
687     addMatchFields(autc_match_fields, NSTime( 0x0FFF0000, 0x0F00FF00 ) )
688
689     verifyFields("time.ABSOLUTE_UTC", autc_match_fields )
690
691 ----------------------------------------
692     testing(OTHER, "tree:add_packet_field Time bytes")
693
694     resetResults()
695     local autc_match_values = {}
696
697     -- something to make this easier to read
698     addMatch = function(...)
699         addMatchFieldValues(autc_match_fields, autc_match_values, ...)
700     end
701
702     -- tree:add_packet_field(ALOCAL, tvb:range(0,8), ENC_BIG_ENDIAN)
703     execute ("add_pfield-time-bytes-local",    treeAddPField ( tree, AUTC, tvb:range(0,8), ENC_BIG_ENDIAN) )
704     addMatch( NSTime(), 8)
705
706     execute ("add_pfield-time-bytes-local",    treeAddPField ( tree, AUTC, tvb:range(8,8), ENC_BIG_ENDIAN) )
707     addMatch( NSTime( 0x0000FF0F, 0x00FF000F), 8)
708
709     execute ("add_pfield-time-bytes-local-le", treeAddPField ( tree, AUTC, tvb:range(0,8), ENC_LITTLE_ENDIAN) )
710     addMatch( NSTime(), 8)
711
712     execute ("add_pfield-time-bytes-local-le", treeAddPField ( tree, AUTC, tvb:range(8,8), ENC_LITTLE_ENDIAN) )
713     addMatch( NSTime( 0x0FFF0000, 0x0F00FF00 ), 8)
714
715     verifyFields("time.ABSOLUTE_UTC", autc_match_fields)
716
717     verifyResults("add_pfield-time-bytes-local", autc_match_values)
718
719 ----------------------------------------
720     testing(OTHER, "tree:add_packet_field Time string ENC_ISO_8601_DATE_TIME")
721
722     resetResults()
723     autc_match_values = {}
724
725     local datetimestring1 =   "2013-03-01T22:14:48+00:00" -- this is 1362176088 seconds epoch time
726     local tvb1 = ByteArray.new(datetimestring1, true):tvb("Date_Time string 1")
727     local datetimestring2 = "  2013-03-01T17:14:48+05:00" -- this is 1362176088 seconds epoch time
728     local tvb2 = ByteArray.new(datetimestring2 .. "  foobar", true):tvb("Date_Time string 2")
729     local datetimestring3 = "  2013-03-01T16:44+05:30"    -- this is 1362176040 seconds epoch time
730     local tvb3 = ByteArray.new(datetimestring3, true):tvb("Date_Time string 3")
731     local datetimestring4 =   "2013-03-02T01:44:00-03:30" -- this is 1362176040 seconds epoch time
732     local tvb4 = ByteArray.new(datetimestring4, true):tvb("Date_Time string 4")
733     local datetimestring5 =   "2013-03-01T22:14:48Z"      -- this is 1362176088 seconds epoch time
734     local tvb5 = ByteArray.new(datetimestring5, true):tvb("Date_Time string 5")
735     local datetimestring6 =   "2013-03-01T22:14Z"         -- this is 1362176040 seconds epoch time
736     local tvb6 = ByteArray.new(datetimestring6, true):tvb("Date_Time string 6")
737
738     execute ("add_pfield-datetime-local", treeAddPField ( tree, AUTC, tvb1:range(), ENC_ISO_8601_DATE_TIME) )
739     addMatch( NSTime( 1362176088, 0), string.len(datetimestring1))
740
741     execute ("add_pfield-datetime-local", treeAddPField ( tree, AUTC, tvb2:range(), ENC_ISO_8601_DATE_TIME) )
742     addMatch( NSTime( 1362176088, 0), string.len(datetimestring2))
743
744     execute ("add_pfield-datetime-local", treeAddPField ( tree, AUTC, tvb3:range(), ENC_ISO_8601_DATE_TIME) )
745     addMatch( NSTime( 1362176040, 0), string.len(datetimestring3))
746
747     execute ("add_pfield-datetime-local", treeAddPField ( tree, AUTC, tvb4:range(), ENC_ISO_8601_DATE_TIME) )
748     addMatch( NSTime( 1362176040, 0), string.len(datetimestring4))
749
750     execute ("add_pfield-datetime-local", treeAddPField ( tree, AUTC, tvb5:range(), ENC_ISO_8601_DATE_TIME) )
751     addMatch( NSTime( 1362176088, 0), string.len(datetimestring5))
752
753     execute ("add_pfield-datetime-local", treeAddPField ( tree, AUTC, tvb6:range(), ENC_ISO_8601_DATE_TIME) )
754     addMatch( NSTime( 1362176040, 0), string.len(datetimestring6))
755
756     verifyFields("time.ABSOLUTE_UTC", autc_match_fields)
757
758     verifyResults("add_pfield-datetime-local", autc_match_values)
759
760 ----------------------------------------
761     testing(OTHER, "tree:add_packet_field Time string ENC_ISO_8601_DATE")
762
763     resetResults()
764     autc_match_values = {}
765
766     local datestring1 =   "2013-03-01"  -- this is 1362096000 seconds epoch time
767     local d_tvb1 = ByteArray.new(datestring1, true):tvb("Date string 1")
768     local datestring2 = "  2013-03-01"  -- this is 1362096000 seconds epoch time
769     local d_tvb2 = ByteArray.new(datestring2 .. "  foobar", true):tvb("Date string 2")
770
771     execute ("add_pfield-date-local", treeAddPField ( tree, AUTC, d_tvb1:range(), ENC_ISO_8601_DATE) )
772     addMatch( NSTime( 1362096000, 0), string.len(datestring1))
773
774     execute ("add_pfield-date-local", treeAddPField ( tree, AUTC, d_tvb2:range(), ENC_ISO_8601_DATE) )
775     addMatch( NSTime( 1362096000, 0), string.len(datestring2))
776
777     verifyFields("time.ABSOLUTE_UTC", autc_match_fields)
778
779     verifyResults("add_pfield-date-local", autc_match_values)
780
781 ----------------------------------------
782     testing(OTHER, "tree:add_packet_field Time string ENC_ISO_8601_TIME")
783
784     resetResults()
785     autc_match_values = {}
786
787     local timestring1 =   "22:14:48"  -- this is 80088 seconds
788     local t_tvb1 = ByteArray.new(timestring1, true):tvb("Time string 1")
789     local timestring2 = "  22:14:48"  -- this is 80088 seconds
790     local t_tvb2 = ByteArray.new(timestring2 .. "  foobar", true):tvb("Time string 2")
791
792     local now = os.date("!*t")
793     now.hour = 22
794     now.min  = 14
795     now.sec  = 48
796     local timebase = os.time( now )
797     timebase = timebase + timezone
798     print ("timebase = " .. tostring(timebase) .. ", timezone=" .. timezone)
799
800     execute ("add_pfield-time-local", treeAddPField ( tree, AUTC, t_tvb1:range(), ENC_ISO_8601_TIME) )
801     addMatch( NSTime( timebase, 0), string.len(timestring1))
802
803     execute ("add_pfield-time-local", treeAddPField ( tree, AUTC, t_tvb2:range(), ENC_ISO_8601_TIME) )
804     addMatch( NSTime( timebase, 0), string.len(timestring2))
805
806     verifyFields("time.ABSOLUTE_UTC", autc_match_fields)
807
808     verifyResults("add_pfield-time-local", autc_match_values)
809
810 ----------------------------------------
811     testing(OTHER, "tree:add_packet_field Time string ENC_RFC_822")
812
813     resetResults()
814     autc_match_values = {}
815
816     local rfc822string1 =   "Fri, 01 Mar 13 22:14:48 GMT"  -- this is 1362176088 seconds epoch time
817     local rfc822_tvb1 = ByteArray.new(rfc822string1, true):tvb("RFC 822 Time string 1")
818     local rfc822string2 = "  Fri, 01 Mar 13 22:14:48 GMT"  -- this is 1362176088 seconds epoch time
819     local rfc822_tvb2 = ByteArray.new(rfc822string2 .. "  foobar", true):tvb("RFC 822 Time string 2")
820
821     execute ("add_pfield-time-local", treeAddPField ( tree, AUTC, rfc822_tvb1:range(), ENC_RFC_822) )
822     addMatch( NSTime( 1362176088, 0), string.len(rfc822string1))
823
824     execute ("add_pfield-time-local", treeAddPField ( tree, AUTC, rfc822_tvb2:range(), ENC_RFC_822) )
825     addMatch( NSTime( 1362176088, 0), string.len(rfc822string2))
826
827     verifyFields("time.ABSOLUTE_UTC", autc_match_fields)
828
829     verifyResults("add_pfield-rfc822-local", autc_match_values)
830
831 ----------------------------------------
832     testing(OTHER, "tree:add_packet_field Time string ENC_RFC_1123")
833
834     resetResults()
835     autc_match_values = {}
836
837     local rfc1123string1 =   "Fri, 01 Mar 2013 22:14:48 GMT"  -- this is 1362176088 seconds epoch time
838     local rfc1123_tvb1 = ByteArray.new(rfc1123string1, true):tvb("RFC 1123 Time string 1")
839     local rfc1123string2 = "  Fri, 01 Mar 2013 22:14:48 GMT"  -- this is 1362176088 seconds epoch time
840     local rfc1123_tvb2 = ByteArray.new(rfc1123string2 .. "  foobar", true):tvb("RFC 1123 Time string 2")
841
842     execute ("add_pfield-time-local", treeAddPField ( tree, AUTC, rfc1123_tvb1:range(), ENC_RFC_1123) )
843     addMatch( NSTime( 1362176088, 0), string.len(rfc1123string1))
844
845     execute ("add_pfield-time-local", treeAddPField ( tree, AUTC, rfc1123_tvb2:range(), ENC_RFC_1123) )
846     addMatch( NSTime( 1362176088, 0), string.len(rfc1123string2))
847
848     verifyFields("time.ABSOLUTE_UTC", autc_match_fields)
849
850     verifyResults("add_pfield-rfc1123-local", autc_match_values)
851
852 ----------------------------------------
853
854     setPassed(FRAME)
855 end
856
857 ----------------------------------------
858 -- we want to have our protocol dissection invoked for a specific UDP port,
859 -- so get the udp dissector table and add our protocol to it
860 DissectorTable.get("udp.port"):add(65333, test_proto)
861 DissectorTable.get("udp.port"):add(65346, test_proto)
862
863 print("test_proto dissector registered")