aboutsummaryrefslogtreecommitdiffstats
path: root/test/lua
diff options
context:
space:
mode:
authorJonathan Landis <jkl@calibersecurity.com>2022-03-31 09:39:40 -0700
committerAndersBroman <a.broman58@gmail.com>2023-08-08 21:37:28 +0000
commitec17ee15bd9c1b81d596fb0a9d182c64db5d2c5c (patch)
tree1910e48f4b75313283d1cb98fbccc22f41985414 /test/lua
parent6659f4494d1dd313ef4d9f69f7e0b6194cc3e6b2 (diff)
test suite for lua add_packet_field
Diffstat (limited to 'test/lua')
-rw-r--r--test/lua/add_packet_field.lua930
-rw-r--r--test/lua/field_setup.lua108
2 files changed, 1038 insertions, 0 deletions
diff --git a/test/lua/add_packet_field.lua b/test/lua/add_packet_field.lua
new file mode 100644
index 0000000000..bd78be3143
--- /dev/null
+++ b/test/lua/add_packet_field.lua
@@ -0,0 +1,930 @@
+--[[
+ The tree:add_packet_field() method returns a value and offset in addition to a tree item.
+ This file tests whether the value and offset are correct. As for the value,
+ its correctness is tested in several ways for a given input.
+
+ 1. The returned value should match a precomputed value
+
+ 2. The returned value should match the value obtained from a Field object
+ right after tree:add_packet_field() is called
+
+ 3. The returned value should match the value obtained from a Field object
+ right after tree:add() is called with the same input
+
+ 4. The returned value should match the value obtained from the corresponding value function
+ called on the input tvbrange
+
+ There are some incompatibilties and limitations due to handling of encodings.
+ Incompatibilities are noted with the text INCOMPATIBILITY in a nearby comment
+ Skipped tests because of partially implementations are marked with SKIP comments
+]]
+
+local field_setup = require "field_setup"
+
+--[[
+ This dissector expects a capture with at least one packet on UDP 65333.
+ All the actual test data is synthetic.
+]]--
+local myproto = Proto("test", "Test")
+
+field_data = field_setup(myproto, "test")
+
+function hexlify_string(s)
+ local sep = ""
+ local hx = ""
+ for i=1,#s do
+ hx = hx .. sep .. string.format("%02x", s:byte(i))
+ sep = " "
+ end
+ return hx
+end
+
+--[[
+ Ensure the value is represented in a way that shows up when printed.
+ It is assumed the string representation is relatively short.
+
+ The test suite will report an error if we print invalid utf8 for any reason.
+ We work around this by passing a substitution string used when the real
+ string has invalid utf8. We also print the output bytes in hex after the string,
+ and those bytes are always faithful to the real output.
+]]--
+function format_value_for_print(v, substitution)
+ local t = type(v)
+ local s
+ if t == "string" then
+ local hx = hexlify_string(v)
+ if substitution ~= nil then
+ s = string.format("(invalid utf8) \"%s\" [%s]", substitution, hx)
+ else
+ s = string.format("\"%s\" [%s]", v, hx)
+ end
+
+ else
+ s = tostring(v)
+ end
+ return string.format("(%s) %s", type(v), s)
+end
+
+function format_encoding_for_print(enc)
+
+ local char_enc = "ASCII"
+ if bit.band(enc, ENC_UTF_16) ~= 0 then
+ char_enc = "UTF-16"
+ end
+
+ local enc_enc = "BE"
+ if bit.band(enc, ENC_LITTLE_ENDIAN) ~= 0 then
+ end_enc = "LE"
+ end
+
+ if enc == ENC_ISO_8601_DATE_TIME then
+ char_enc = "ISO_8601"
+ end_enc = "-"
+ end
+
+ return string.format("%s %s", char_enc, end_enc)
+end
+
+function print_test_data(test_data)
+ print(string.format("TEST: using field type: %s", test_data.field_type))
+ if test_data.hexlify then
+ print(string.format("TEST: input was hexlified from: \"%s\"", test_data.original_input))
+ end
+ print(string.format("TEST: using data: [%s]", test_data.input))
+ print(string.format("TEST: using offset: %d", test_data.input_offset))
+ print(string.format("TEST: using encoding: %s", format_encoding_for_print(test_data.encoding)))
+ print()
+end
+
+function general_equality_test(a, b)
+ return a == b
+end
+
+--equal or both nan
+function float_equality_test(a, b)
+ return a == b or (a ~= a and b ~= b)
+end
+
+function recent_field_value(t)
+ local values = {field_data[t].value_field()}
+ return values[#values].value
+end
+
+function add_packet_field_returns_precomputed_value(test_data)
+
+ print(string.format(" EXPECT: precomputed return value: %s", format_value_for_print(test_data.expect_precomputed)))
+ print(string.format(" OUTPUT: add_packet_field returned value: %s", format_value_for_print(test_data.returned_value)))
+
+ if test_data.equality_function(test_data.returned_value, test_data.expect_precomputed) then
+ print(" PASS: the return value is correct")
+ print()
+ return true
+ end
+
+ print(" FAIL: the returned value is incorrect")
+ print()
+ return false
+end
+
+function add_packet_field_then_value_field_returns_expected_value(test_data)
+
+ print(string.format(" EXPECT: value field value %s", format_value_for_print(test_data.expect_add_pf_field_value)))
+ print(string.format(" OUTPUT: value field after tree:add_packet_field() returned: %s",
+ format_value_for_print(test_data.returned_add_pf_field_value)))
+
+ local incompatible = test_data.expect_add_pf_field_value ~= test_data.expect_precomputed
+ if incompatible then
+ print(" WARNING: the value field does not return the same value as the other implementations")
+ end
+ if test_data.equality_function(test_data.returned_add_pf_field_value, test_data.expect_add_pf_field_value) then
+ print(" PASS: the value field is correct")
+ print()
+ return true
+ end
+
+ print(" FAIL: the value field is incorrect")
+ print()
+ return false
+end
+
+function tree_add_then_value_field_returns_expected_value(test_data)
+
+ if test_data.skip_tree_add_test then
+ print(" SKIP: " .. test_data.skip_tree_add_test_message)
+ print()
+ return true
+ end
+
+ print(string.format(" EXPECT: value field value %s", format_value_for_print(test_data.expect_add_field_value)))
+ print(string.format(" OUTPUT: value field after tree:add() returned: %s",
+ format_value_for_print(test_data.returned_add_field_value)))
+
+ local incompatible = test_data.expect_add_field_value ~= test_data.expect_precomputed
+ if incompatible then
+ print(" WARNING: the value field does not return the same value as the other implementations")
+ end
+ if test_data.equality_function(test_data.returned_add_field_value, test_data.expect_add_field_value) then
+ print(" PASS: the value field is correct")
+ print()
+ return true
+ end
+
+ print(" FAIL: the value field is incorrect")
+ print()
+ return false
+
+end
+
+--[[
+ The tvbrange:string() function can return invalid utf8 even when the input is valid.
+]]
+function tvbrange_returns_expected_value(test_data)
+
+ if test_data.tvbr_fn == nil then
+ print(" SKIP: no tvbrange function for this field type")
+ print()
+ return true
+ end
+
+ local tvbr_value, tvbr_fn_printable = test_data.tvbr_fn(test_data.input_tvbrange, test_data.encoding)
+ local pass = test_data.equality_function(tvbr_value, test_data.expect_tvbrange_value)
+ local incompatible = test_data.expect_tvbrange_value ~= test_data.expect_precomputed
+ local tvbr_value_printable = format_value_for_print(tvbr_value)
+ local expect_value_printable = format_value_for_print(test_data.expect_tvbrange_value, test_data.expect_tvbrange_value_printable)
+ if pass then
+ --if the outputs are equal, then the substitute is useable for both
+ tvbr_value_printable = format_value_for_print(tvbr_value, test_data.expect_tvbrange_value_printable)
+ end
+
+ print(string.format(" TEST: using tvbrange function %s", tvbr_fn_printable))
+ print(string.format(" EXPECT: tvbrange value %s", expect_value_printable))
+ print(string.format(" OUTPUT: tvbrange returned %s", tvbr_value_printable))
+ if incompatible then
+ print(" WARNING: the tvbr function is not compatible with the other implementations")
+ end
+
+ if pass then
+ print(" PASS: the the tvbr function works as expected")
+ print()
+ return true
+ end
+
+ print(" FAIL: the the tvbr function works as expected")
+ print()
+ return false
+end
+
+function add_packet_field_returns_correct_offset(test_data)
+
+ print(string.format(" EXPECT: offset %d", test_data.expect_offset))
+ print(string.format(" OUTPUT: add_packet_field returned offset %d", test_data.returned_offset))
+
+ if test_data.returned_offset == test_data.expect_offset then
+ print(" PASS: the returned offset is correct")
+ print()
+ return true
+ end
+
+ print(" FAIL: the returned offset is incorrect")
+ print()
+ return false
+end
+
+function add_packet_field_all_tests(tree, test_data)
+ print_test_data(test_data)
+ local ret = true
+ and add_packet_field_returns_precomputed_value(test_data)
+ and add_packet_field_then_value_field_returns_expected_value(test_data)
+ and tree_add_then_value_field_returns_expected_value(test_data)
+ and tvbrange_returns_expected_value(test_data)
+ and add_packet_field_returns_correct_offset(test_data)
+ return ret
+end
+
+function generate_test_data_for_case(tree, field_type, case, tvbr_fn, equality_function, use_offset)
+
+ local input = case.input
+ if case.hexlify then
+ input = hexlify_string(case.input)
+ end
+
+ local input_byte_length = string.len(input:gsub(" ", "")) / 2
+ local input_offset = 0
+ if use_offset then
+ input = "77 " .. input
+ input_offset = 1
+ end
+
+ local input_tvb = ByteArray.new(input):tvb()
+ local input_tvbrange
+
+ if case.fake_input_length == nil then
+ input_tvbrange = input_tvb(input_offset, input_byte_length)
+ else
+ input_tvbrange = input_tvb(input_offset, case.fake_input_length)
+ end
+
+ local t = field_data[field_type]
+ local add_pf_leaf, returned_value, returned_offset = tree:add_packet_field(t.packet_field, input_tvbrange, case.encoding)
+ local add_pf_field_value = recent_field_value(field_type)
+
+ local add_leaf = nil
+ local add_field_value = nil
+ local skip_tree_add_test_message = nil
+ local skip_tree_add_test = false
+
+ if case.encoding == ENC_ASCII + ENC_BIG_ENDIAN then
+ add_leaf = tree:add(t.packet_field, input_tvbrange)
+ add_field_value = recent_field_value(field_type)
+ elseif case.encoding == ENC_ASCII + ENC_LITTLE_ENDIAN then
+ add_leaf = tree:add_le(t.packet_field, input_tvbrange)
+ add_field_value = recent_field_value(field_type)
+ else
+ skip_tree_add_test = true
+ skip_tree_add_test_message = "tree:add() only uses ASCII encoding"
+ end
+
+ local expect_add_pf_field_value = case.output
+ if case.incompatible_add_pf_field then
+ expect_add_pf_field_value = case.expect_add_pf_field_value
+ end
+
+ local expect_add_field_value = case.output
+ if case.incompatible_add_field then
+ expect_add_field_value = case.expect_add_field_value
+ end
+
+ local expect_tvbrange_value = case.output
+ if case.incompatible_tvbrange then
+ expect_tvbrange_value = case.expect_tvbrange_value
+ end
+
+ local expect_offset = input_byte_length + input_offset
+ if case.variable_input_length then
+ expect_offset = case.input_length + input_offset
+ end
+
+ return {
+ field_type = field_type,
+ hexlify = case.hexlify,
+ original_input = case.input,
+ input = input,
+ input_offset = input_offset,
+ input_tvbrange = input_tvbrange,
+ encoding = case.encoding,
+
+ returned_value = returned_value,
+ returned_offset = returned_offset,
+ returned_add_pf_field_value = add_pf_field_value,
+ returned_add_field_value = add_field_value,
+
+ tvbr_fn = tvbr_fn,
+ equality_function = equality_function,
+ expect_precomputed = case.output,
+ expect_add_pf_field_value = expect_add_pf_field_value,
+
+ expect_add_field_value = expect_add_field_value,
+ skip_tree_add_test = skip_tree_add_test,
+ skip_tree_add_test_message = skip_tree_add_test_message,
+
+ expect_tvbrange_value = expect_tvbrange_value,
+ expect_tvbrange_value_printable = case.expect_tvbrange_value_printable,
+ expect_offset = expect_offset
+ }
+end
+
+function run_test_cases_all_tests(tree, field_type, test_cases, tvbr_fn, equality_function)
+ local test_data
+ for _ , case in ipairs(test_cases) do
+ test_data = generate_test_data_for_case(tree, field_type, case, tvbr_fn, equality_function, true)
+ if not add_packet_field_all_tests(tree, test_data) then
+ return false
+ end
+
+ test_data = generate_test_data_for_case(tree, field_type, case, tvbr_fn, equality_function, false)
+ if not add_packet_field_all_tests(tree, test_data) then
+ return false
+ end
+ end
+
+ return true
+end
+
+function simple_integer_tests(tree)
+ local uint8_test_cases = {
+ {input = "ff", encoding = ENC_LITTLE_ENDIAN, output = 0xff},
+ {input = "00", encoding = ENC_LITTLE_ENDIAN, output = 0x00},
+ {input = "ff", encoding = ENC_BIG_ENDIAN, output = 0xff},
+ {input = "00", encoding = ENC_BIG_ENDIAN, output = 0x00},
+ }
+
+ local uint16_test_cases = {
+ {input = "ff 00", encoding = ENC_LITTLE_ENDIAN, output = 0x00ff},
+ {input = "00 ff", encoding = ENC_LITTLE_ENDIAN, output = 0xff00},
+ {input = "ff 00", encoding = ENC_BIG_ENDIAN, output = 0xff00},
+ {input = "00 ff", encoding = ENC_BIG_ENDIAN, output = 0x00ff},
+ }
+
+ local uint24_test_cases = {
+ {input = "ff 00 00", encoding = ENC_LITTLE_ENDIAN, output = 0x0000ff},
+ {input = "00 ff 00", encoding = ENC_LITTLE_ENDIAN, output = 0x00ff00},
+ {input = "00 00 ff", encoding = ENC_LITTLE_ENDIAN, output = 0xff0000},
+ {input = "ff 00 00", encoding = ENC_BIG_ENDIAN, output = 0xff0000},
+ {input = "00 ff 00", encoding = ENC_BIG_ENDIAN, output = 0x00ff00},
+ {input = "00 00 ff", encoding = ENC_BIG_ENDIAN, output = 0x0000ff},
+ }
+
+ local uint32_test_cases = {
+ {input = "ff 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = 0x000000ff},
+ {input = "00 ff 00 00", encoding = ENC_LITTLE_ENDIAN, output = 0x0000ff00},
+ {input = "00 00 ff 00", encoding = ENC_LITTLE_ENDIAN, output = 0x00ff0000},
+ {input = "00 00 00 ff", encoding = ENC_LITTLE_ENDIAN, output = 0xff000000},
+ {input = "ff 00 00 00", encoding = ENC_BIG_ENDIAN, output = 0xff000000},
+ {input = "00 ff 00 00", encoding = ENC_BIG_ENDIAN, output = 0x00ff0000},
+ {input = "00 00 ff 00", encoding = ENC_BIG_ENDIAN, output = 0x0000ff00},
+ {input = "00 00 00 ff", encoding = ENC_BIG_ENDIAN, output = 0x000000ff},
+ }
+
+ function tvbr_uint (tvbr, encoding)
+ if encoding == ENC_LITTLE_ENDIAN then
+ return tvbr:le_uint(), "le_uint()"
+ else
+ return tvbr:uint(), "uint()"
+ end
+ end
+
+ local int8_test_cases = {
+ {input = "ff", encoding = ENC_LITTLE_ENDIAN, output = -0x01},
+ {input = "00", encoding = ENC_LITTLE_ENDIAN, output = 0x00},
+ {input = "ff", encoding = ENC_BIG_ENDIAN, output = -0x01},
+ {input = "00", encoding = ENC_BIG_ENDIAN, output = 0x00},
+ }
+
+ local int16_test_cases = {
+ {input = "ff 00", encoding = ENC_LITTLE_ENDIAN, output = 0x00ff},
+ {input = "00 ff", encoding = ENC_LITTLE_ENDIAN, output = -0x0100},
+ {input = "ff 00", encoding = ENC_BIG_ENDIAN, output = -0x0100},
+ {input = "00 ff", encoding = ENC_BIG_ENDIAN, output = 0x00ff},
+ }
+
+ local int24_test_cases = {
+ {input = "ff 00 00", encoding = ENC_LITTLE_ENDIAN, output = 0x0000ff},
+ {input = "00 ff 00", encoding = ENC_LITTLE_ENDIAN, output = 0x00ff00},
+ {input = "00 00 ff", encoding = ENC_LITTLE_ENDIAN, output = -0x010000},
+ {input = "ff 00 00", encoding = ENC_BIG_ENDIAN, output = -0x010000},
+ {input = "00 ff 00", encoding = ENC_BIG_ENDIAN, output = 0x00ff00},
+ {input = "00 00 ff", encoding = ENC_BIG_ENDIAN, output = 0x0000ff},
+ }
+
+ local int32_test_cases = {
+ {input = "ff 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = 0x000000ff},
+ {input = "00 ff 00 00", encoding = ENC_LITTLE_ENDIAN, output = 0x0000ff00},
+ {input = "00 00 ff 00", encoding = ENC_LITTLE_ENDIAN, output = 0x00ff0000},
+ {input = "00 00 00 ff", encoding = ENC_LITTLE_ENDIAN, output = -0x01000000},
+ {input = "ff 00 00 00", encoding = ENC_BIG_ENDIAN, output = -0x01000000},
+ {input = "00 ff 00 00", encoding = ENC_BIG_ENDIAN, output = 0x00ff0000},
+ {input = "00 00 ff 00", encoding = ENC_BIG_ENDIAN, output = 0x0000ff00},
+ {input = "00 00 00 ff", encoding = ENC_BIG_ENDIAN, output = 0x000000ff},
+ }
+
+ function tvbr_int(tvbr, encoding)
+ if encoding == ENC_LITTLE_ENDIAN then
+ return tvbr:le_int(), "le_int()"
+ else
+ return tvbr:int(), "int()"
+ end
+ end
+
+ return true
+ and run_test_cases_all_tests(tree, "uint8", uint8_test_cases, tvbr_uint, general_equality_test)
+ and run_test_cases_all_tests(tree, "uint16", uint16_test_cases, tvbr_uint, general_equality_test)
+ and run_test_cases_all_tests(tree, "uint24", uint24_test_cases, tvbr_uint, general_equality_test)
+ and run_test_cases_all_tests(tree, "uint32", uint32_test_cases, tvbr_uint, general_equality_test)
+
+ and run_test_cases_all_tests(tree, "int8", int8_test_cases, tvbr_int, general_equality_test)
+ and run_test_cases_all_tests(tree, "int16", int16_test_cases, tvbr_int, general_equality_test)
+ and run_test_cases_all_tests(tree, "int24", int24_test_cases, tvbr_int, general_equality_test)
+ and run_test_cases_all_tests(tree, "int32", int32_test_cases, tvbr_int, general_equality_test)
+end
+
+function integer64_tests(tree)
+
+ local uint64_test_cases = {
+ {input = "ff 00 00 00 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = UInt64(0x000000ff, 0x00000000)},
+ {input = "00 ff 00 00 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = UInt64(0x0000ff00, 0x00000000)},
+ {input = "00 00 ff 00 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = UInt64(0x00ff0000, 0x00000000)},
+ {input = "00 00 00 ff 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = UInt64(0xff000000, 0x00000000)},
+ {input = "00 00 00 00 ff 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = UInt64(0x00000000, 0x000000ff)},
+ {input = "00 00 00 00 00 ff 00 00", encoding = ENC_LITTLE_ENDIAN, output = UInt64(0x00000000, 0x0000ff00)},
+ {input = "00 00 00 00 00 00 ff 00", encoding = ENC_LITTLE_ENDIAN, output = UInt64(0x00000000, 0x00ff0000)},
+ {input = "00 00 00 00 00 00 00 ff", encoding = ENC_LITTLE_ENDIAN, output = UInt64(0x00000000, 0xff000000)},
+ {input = "ff 00 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = UInt64(0x00000000, 0xff000000)},
+ {input = "00 ff 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = UInt64(0x00000000, 0x00ff0000)},
+ {input = "00 00 ff 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = UInt64(0x00000000, 0x0000ff00)},
+ {input = "00 00 00 ff 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = UInt64(0x00000000, 0x000000ff)},
+ {input = "00 00 00 00 ff 00 00 00", encoding = ENC_BIG_ENDIAN, output = UInt64(0xff000000, 0x00000000)},
+ {input = "00 00 00 00 00 ff 00 00", encoding = ENC_BIG_ENDIAN, output = UInt64(0x00ff0000, 0x00000000)},
+ {input = "00 00 00 00 00 00 ff 00", encoding = ENC_BIG_ENDIAN, output = UInt64(0x0000ff00, 0x00000000)},
+ {input = "00 00 00 00 00 00 00 ff", encoding = ENC_BIG_ENDIAN, output = UInt64(0x000000ff, 0x00000000)},
+ }
+
+ function tvbr_uint(tvbr, encoding)
+ if encoding == ENC_LITTLE_ENDIAN then
+ return tvbr:le_uint64(), "le_uint64()"
+ else
+ return tvbr:uint64(), "uint64()"
+ end
+ end
+
+ local int64_test_cases = {
+ {input = "ff 00 00 00 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = Int64(0x000000ff, 0x00000000)},
+ {input = "00 ff 00 00 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = Int64(0x0000ff00, 0x00000000)},
+ {input = "00 00 ff 00 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = Int64(0x00ff0000, 0x00000000)},
+ {input = "00 00 00 ff 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = Int64(0xff000000, 0x00000000)},
+ {input = "00 00 00 00 ff 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = Int64(0x00000000, 0x000000ff)},
+ {input = "00 00 00 00 00 ff 00 00", encoding = ENC_LITTLE_ENDIAN, output = Int64(0x00000000, 0x0000ff00)},
+ {input = "00 00 00 00 00 00 ff 00", encoding = ENC_LITTLE_ENDIAN, output = Int64(0x00000000, 0x00ff0000)},
+ {input = "00 00 00 00 00 00 00 ff", encoding = ENC_LITTLE_ENDIAN, output = Int64(0x00000000, 0xff000000)},
+ {input = "ff 00 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = Int64(0x00000000, 0xff000000)},
+ {input = "00 ff 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = Int64(0x00000000, 0x00ff0000)},
+ {input = "00 00 ff 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = Int64(0x00000000, 0x0000ff00)},
+ {input = "00 00 00 ff 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = Int64(0x00000000, 0x000000ff)},
+ {input = "00 00 00 00 ff 00 00 00", encoding = ENC_BIG_ENDIAN, output = Int64(0xff000000, 0x00000000)},
+ {input = "00 00 00 00 00 ff 00 00", encoding = ENC_BIG_ENDIAN, output = Int64(0x00ff0000, 0x00000000)},
+ {input = "00 00 00 00 00 00 ff 00", encoding = ENC_BIG_ENDIAN, output = Int64(0x0000ff00, 0x00000000)},
+ {input = "00 00 00 00 00 00 00 ff", encoding = ENC_BIG_ENDIAN, output = Int64(0x000000ff, 0x00000000)},
+ }
+
+ function tvbr_int(tvbr, encoding)
+ if encoding == ENC_LITTLE_ENDIAN then
+ return tvbr:le_int64(), "le_int64()"
+ else
+ return tvbr:int64(), "int64()"
+ end
+ end
+
+ return true
+ and run_test_cases_all_tests(tree, "uint64", uint64_test_cases, tvbr_uint, general_equality_test)
+ and run_test_cases_all_tests(tree, "int64", int64_test_cases, tvbr_int, general_equality_test)
+end
+
+function string_tests(tree)
+
+ local ABC_ascii = "41 42 43"
+ local ABCzD_ascii = "41 42 43 00 44"
+
+ local SHARK_16_little = "b5 30 e1 30"
+ local SHARKzSA_16_little = "b5 30 e1 30 00 00 b5 30"
+
+ local SHARK_16_big = "30 b5 30 e1"
+ local SHARKzSA_16_big = "30 b5 30 e1 00 00 30 b5"
+
+ local string_test_cases = {
+ {input = ABC_ascii, encoding = ENC_ASCII, output = "ABC"},
+
+ --INCOMPATIBILITY: tvbrange:string() preserves embedded nulls
+ {input = ABCzD_ascii, encoding = ENC_ASCII, output = "ABC",
+ incompatible_tvbrange = true, expect_tvbrange_value = "ABC\000D",
+ },
+
+ --INCOMPATIBILITY: tvbrange:string() truncates the output
+ {input = SHARK_16_little, encoding = ENC_ASCII, output = "�0�0",
+ incompatible_tvbrange = true, expect_tvbrange_value = "�0",
+ },
+
+ --INCOMPATIBILITY: tvbrange:string() truncates the output, producing invalid utf-8
+ {input = SHARK_16_little, encoding = ENC_UTF_16 + ENC_LITTLE_ENDIAN, output = "サメ",
+ incompatible_tvbrange = true, expect_tvbrange_value = "サ\227",
+ expect_tvbrange_value_printable = "サ�",
+ },
+
+ --INCOMPATIBILITY: tvbrange:string() preserves embedded nulls and truncates, producing invalid utf-8
+ {input = SHARKzSA_16_little, encoding = ENC_UTF_16 + ENC_LITTLE_ENDIAN, output = "サメ",
+ incompatible_tvbrange = true, expect_tvbrange_value = "サメ\000\227",
+ expect_tvbrange_value_printable = "サメ\\000�",
+ },
+
+ --INCOMPATIBILITY: tvbrange:string() truncates the output, producing invalid utf-8
+ {input = SHARK_16_big, encoding = ENC_UTF_16 + ENC_BIG_ENDIAN, output = "サメ",
+ incompatible_tvbrange = true, expect_tvbrange_value = "サ\227",
+ expect_tvbrange_value_printable = "サ�",
+ },
+
+ --INCOMPATIBILITY: tvbrange:string() preserves embedded nulls and truncates, producing invalid utf-8
+ {input = SHARKzSA_16_big, encoding = ENC_UTF_16 + ENC_BIG_ENDIAN, output = "サメ",
+ incompatible_tvbrange = true, expect_tvbrange_value = "サメ\000\227",
+ expect_tvbrange_value_printable = "サメ\\000�",
+ },
+ }
+
+ function tvbr_string(tvbr, encoding)
+ return tvbr:string(encoding), string.format("string(%s)", format_encoding_for_print(encoding))
+ end
+
+ --[[
+ stringz computes its own input length by looking for null
+ the input length includes the null, which is 2 bytes for utf16
+ ]]--
+ local stringz_tests = {
+
+ {input = ABCzD_ascii, encoding = ENC_ASCII, output = "ABC",
+ variable_input_length = true, input_length = 4
+ },
+
+ {input = SHARKzSA_16_little, encoding = ENC_UTF_16 + ENC_LITTLE_ENDIAN, output = "サメ",
+ variable_input_length = true, input_length = 6,
+ },
+
+ {input = SHARKzSA_16_big, encoding = ENC_UTF_16 + ENC_BIG_ENDIAN, output = "サメ",
+ variable_input_length = true, input_length = 6,
+ },
+ }
+
+ function tvbr_stringz(tvbr, encoding)
+ return tvbr:stringz(encoding), string.format("stringz(%s)", format_encoding_for_print(encoding))
+ end
+
+ local ustring_tests = {
+ {input = SHARK_16_big, encoding = ENC_UTF_16 + ENC_BIG_ENDIAN, output = "サメ"},
+ {input = SHARKzSA_16_big, encoding = ENC_UTF_16 + ENC_BIG_ENDIAN, output = "サメ"},
+ }
+
+ function tvbr_ustring(tvbr, encoding)
+ return tvbr:ustring(), "ustring()"
+ end
+
+ local le_ustring_tests = {
+ {input = SHARK_16_little, encoding = ENC_UTF_16 + ENC_LITTLE_ENDIAN, output = "サメ"},
+ {input = SHARKzSA_16_little, encoding = ENC_UTF_16 + ENC_LITTLE_ENDIAN, output = "サメ"},
+ }
+
+ function tvbr_le_ustring(tvbr, encoding)
+ return tvbr:le_ustring(), "le_ustring()"
+ end
+
+ local ustringz_tests = {
+ {input = SHARKzSA_16_big, encoding = ENC_UTF_16 + ENC_BIG_ENDIAN, output = "サメ",
+ variable_input_length = true, input_length = 6
+ },
+ }
+
+ function tvbr_ustringz(tvbr, encoding)
+ return tvbr:ustringz(), "ustringz()"
+ end
+
+ local le_ustringz_tests = {
+ {input = SHARKzSA_16_little, encoding = ENC_UTF_16 + ENC_LITTLE_ENDIAN, output = "サメ",
+ variable_input_length = true, input_length = 6
+ },
+ }
+
+ function tvbr_le_ustringz(tvbr, encoding)
+ return tvbr:le_ustringz(), "le_ustringz()"
+ end
+
+ return true
+ and run_test_cases_all_tests(tree, "string", string_test_cases, tvbr_string, general_equality_test)
+ and run_test_cases_all_tests(tree, "stringz", stringz_tests, tvbr_stringz, general_equality_test)
+ and run_test_cases_all_tests(tree, "string", ustring_tests, tvbr_ustring, general_equality_test)
+ and run_test_cases_all_tests(tree, "string", le_ustring_tests, tvbr_le_ustring, general_equality_test)
+ and run_test_cases_all_tests(tree, "stringz", ustringz_tests, tvbr_ustringz, general_equality_test)
+ and run_test_cases_all_tests(tree, "stringz", le_ustringz_tests, tvbr_le_ustringz, general_equality_test)
+end
+
+function bool_char_tests(tree)
+
+ local bool_tests = {
+ {input = "ff", encoding = ENC_BIG_ENDIAN, output = true},
+ {input = "00", encoding = ENC_BIG_ENDIAN, output = false},
+ {input = "01", encoding = ENC_BIG_ENDIAN, output = true},
+ {input = "ff", encoding = ENC_LITTLE_ENDIAN, output = true},
+ {input = "00", encoding = ENC_LITTLE_ENDIAN, output = false},
+ {input = "01", encoding = ENC_LITTLE_ENDIAN, output = true},
+ }
+
+ local char_tests = {
+ {input = "ff", encoding = ENC_BIG_ENDIAN, output = 0xff},
+ {input = "00", encoding = ENC_BIG_ENDIAN, output = 0x00},
+ {input = "30", encoding = ENC_BIG_ENDIAN, output = 0x30},
+ {input = "ff", encoding = ENC_LITTLE_ENDIAN, output = 0xff},
+ {input = "00", encoding = ENC_LITTLE_ENDIAN, output = 0x00},
+ {input = "30", encoding = ENC_LITTLE_ENDIAN, output = 0x30},
+ }
+
+ return true
+ and run_test_cases_all_tests(tree, "boolean", bool_tests, nil, general_equality_test)
+ and run_test_cases_all_tests(tree, "char", char_tests, nil, general_equality_test)
+end
+
+function float_tests(tree)
+
+ local be_float = {
+ {input = "3c 00 00 00", encoding = ENC_BIG_ENDIAN, output = 0.0078125},
+ {input = "bd a0 00 00", encoding = ENC_BIG_ENDIAN, output = -0.078125},
+ {input = "3f 48 00 00", encoding = ENC_BIG_ENDIAN, output = 0.78125},
+ {input = "c0 fa 00 00", encoding = ENC_BIG_ENDIAN, output = -7.8125},
+ {input = "42 9c 40 00", encoding = ENC_BIG_ENDIAN, output = 78.125},
+ {input = "c4 43 50 00", encoding = ENC_BIG_ENDIAN, output = -781.25},
+ {input = "45 f4 24 00", encoding = ENC_BIG_ENDIAN, output = 7812.5},
+ {input = "c7 98 96 80", encoding = ENC_BIG_ENDIAN, output = -78125.0},
+ {input = "49 3e bc 20", encoding = ENC_BIG_ENDIAN, output = 781250.0},
+ {input = "ca ee 6b 28", encoding = ENC_BIG_ENDIAN, output = -7812500.0},
+ {input = "00 00 00 00", encoding = ENC_BIG_ENDIAN, output = 0.0},
+ {input = "80 00 00 00", encoding = ENC_BIG_ENDIAN, output = -0.0},
+ {input = "7f c0 00 00", encoding = ENC_BIG_ENDIAN, output = 0/0},
+ {input = "7f 80 00 00", encoding = ENC_BIG_ENDIAN, output = 1/0},
+ {input = "ff 80 00 00", encoding = ENC_BIG_ENDIAN, output = -1/0},
+ }
+
+ local le_float = {
+ {input = "00 00 00 3c", encoding = ENC_LITTLE_ENDIAN, output = 0.0078125},
+ {input = "00 00 a0 bd", encoding = ENC_LITTLE_ENDIAN, output = -0.078125},
+ {input = "00 00 48 3f", encoding = ENC_LITTLE_ENDIAN, output = 0.78125},
+ {input = "00 00 fa c0", encoding = ENC_LITTLE_ENDIAN, output = -7.8125},
+ {input = "00 40 9c 42", encoding = ENC_LITTLE_ENDIAN, output = 78.125},
+ {input = "00 50 43 c4", encoding = ENC_LITTLE_ENDIAN, output = -781.25},
+ {input = "00 24 f4 45", encoding = ENC_LITTLE_ENDIAN, output = 7812.5},
+ {input = "80 96 98 c7", encoding = ENC_LITTLE_ENDIAN, output = -78125.0},
+ {input = "20 bc 3e 49", encoding = ENC_LITTLE_ENDIAN, output = 781250.0},
+ {input = "28 6b ee ca", encoding = ENC_LITTLE_ENDIAN, output = -7812500.0},
+ {input = "00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = 0.0},
+ {input = "00 00 00 80", encoding = ENC_LITTLE_ENDIAN, output = -0.0},
+ {input = "00 00 c0 7f", encoding = ENC_LITTLE_ENDIAN, output = 0/0},
+ {input = "00 00 80 7f", encoding = ENC_LITTLE_ENDIAN, output = 1/0},
+ {input = "00 00 80 ff", encoding = ENC_LITTLE_ENDIAN, output = -1/0},
+ }
+
+ local be_double = {
+ {input = "3f 80 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = 0.0078125},
+ {input = "bf e9 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = -0.78125},
+ {input = "40 88 6a 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = 781.25},
+ {input = "c0 f3 12 d0 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = -78125.0},
+ {input = "41 92 a0 5f 20 00 00 00", encoding = ENC_BIG_ENDIAN, output = 78125000.0},
+ {input = "c1 fd 1a 94 a2 00 00 00", encoding = ENC_BIG_ENDIAN, output = -7812500000.0},
+ {input = "42 9c 6b f5 26 34 00 00", encoding = ENC_BIG_ENDIAN, output = 7812500000000.0},
+ {input = "c3 06 34 57 85 d8 a0 00", encoding = ENC_BIG_ENDIAN, output = -781250000000000.0},
+ {input = "43 a5 af 1d 78 b5 8c 40", encoding = ENC_BIG_ENDIAN, output = 7.8125e+17},
+ {input = "c4 10 f0 cf 06 4d d5 92", encoding = ENC_BIG_ENDIAN, output = -7.8125e+19},
+ {input = "00 00 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = 0.0},
+ {input = "80 00 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = -0.0},
+ {input = "7f f8 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = 0/0},
+ {input = "7f f0 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = 1/0},
+ {input = "ff f0 00 00 00 00 00 00", encoding = ENC_BIG_ENDIAN, output = -1/0},
+ }
+
+ local le_double = {
+ {input = "00 00 00 00 00 00 80 3f", encoding = ENC_LITTLE_ENDIAN, output = 0.0078125},
+ {input = "00 00 00 00 00 00 e9 bf", encoding = ENC_LITTLE_ENDIAN, output = -0.78125},
+ {input = "00 00 00 00 00 6a 88 40", encoding = ENC_LITTLE_ENDIAN, output = 781.25},
+ {input = "00 00 00 00 d0 12 f3 c0", encoding = ENC_LITTLE_ENDIAN, output = -78125.0},
+ {input = "00 00 00 20 5f a0 92 41", encoding = ENC_LITTLE_ENDIAN, output = 78125000.0},
+ {input = "00 00 00 a2 94 1a fd c1", encoding = ENC_LITTLE_ENDIAN, output = -7812500000.0},
+ {input = "00 00 34 26 f5 6b 9c 42", encoding = ENC_LITTLE_ENDIAN, output = 7812500000000.0},
+ {input = "00 a0 d8 85 57 34 06 c3", encoding = ENC_LITTLE_ENDIAN, output = -781250000000000.0},
+ {input = "40 8c b5 78 1d af a5 43", encoding = ENC_LITTLE_ENDIAN, output = 7.8125e+17},
+ {input = "92 d5 4d 06 cf f0 10 c4", encoding = ENC_LITTLE_ENDIAN, output = -7.8125e+19},
+ {input = "00 00 00 00 00 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = 0.0},
+ {input = "00 00 00 00 00 00 00 80", encoding = ENC_LITTLE_ENDIAN, output = -0.0},
+ {input = "00 00 00 00 00 00 f8 7f", encoding = ENC_LITTLE_ENDIAN, output = 0/0},
+ {input = "00 00 00 00 00 00 f0 7f", encoding = ENC_LITTLE_ENDIAN, output = 1/0},
+ {input = "00 00 00 00 00 00 f0 ff", encoding = ENC_LITTLE_ENDIAN, output = -1/0},
+ }
+
+ function tvbr_float(tvbr, encoding)
+ return tvbr:float(), "float()"
+ end
+
+ function tvbr_le_float(tvbr, encoding)
+ return tvbr:le_float(), "le_float()"
+ end
+
+ return true
+ and run_test_cases_all_tests(tree, "float", be_float, tvbr_float, float_equality_test)
+ and run_test_cases_all_tests(tree, "double", be_double, tvbr_float, float_equality_test)
+ and run_test_cases_all_tests(tree, "float", le_float, tvbr_le_float, float_equality_test)
+ and run_test_cases_all_tests(tree, "double", le_double, tvbr_le_float, float_equality_test)
+end
+
+function address_tests(tree)
+
+ --INCOMPATIBILITY: value fields always assume big-endian encoding for IPv4 addresses
+ local ipv4_test_cases = {
+ {input = "01 00 00 00", encoding = ENC_LITTLE_ENDIAN, output = Address.ip("0.0.0.1"),
+ incompatible_add_pf_field = true, expect_add_pf_field_value = Address.ip("1.0.0.0"),
+ incompatible_add_field = true, expect_add_field_value = Address.ip("1.0.0.0")
+ },
+ {input = "00 02 00 00", encoding = ENC_LITTLE_ENDIAN, output = Address.ip("0.0.2.0"),
+ incompatible_add_pf_field = true, expect_add_pf_field_value = Address.ip("0.2.0.0"),
+ incompatible_add_field = true, expect_add_field_value = Address.ip("0.2.0.0")
+ },
+ {input = "00 00 03 00", encoding = ENC_LITTLE_ENDIAN, output = Address.ip("0.3.0.0"),
+ incompatible_add_pf_field = true, expect_add_pf_field_value = Address.ip("0.0.3.0"),
+ incompatible_add_field = true, expect_add_field_value = Address.ip("0.0.3.0")
+ },
+ {input = "00 00 00 04", encoding = ENC_LITTLE_ENDIAN, output = Address.ip("4.0.0.0"),
+ incompatible_add_pf_field = true, expect_add_pf_field_value = Address.ip("0.0.0.4"),
+ incompatible_add_field = true, expect_add_field_value = Address.ip("0.0.0.4")
+ },
+ {input = "01 00 00 00", encoding = ENC_BIG_ENDIAN, output = Address.ip("1.0.0.0")},
+ {input = "00 02 00 00", encoding = ENC_BIG_ENDIAN, output = Address.ip("0.2.0.0")},
+ {input = "00 00 03 00", encoding = ENC_BIG_ENDIAN, output = Address.ip("0.0.3.0")},
+ {input = "00 00 00 04", encoding = ENC_BIG_ENDIAN, output = Address.ip("0.0.0.4")},
+ }
+
+ function tvbr_ipv4 (tvbr, encoding)
+ if encoding == ENC_LITTLE_ENDIAN then
+ return tvbr:le_ipv4(), "le_ipv4()"
+ else
+ return tvbr:ipv4(), "ipv4()"
+ end
+ end
+
+ local ipv6_test_cases = {
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 0000 0000 0000 0000 00ff",
+ output = Address.ipv6("0000:0000:0000:0000:0000:0000:0000:00ff")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 0000 0000 0000 0000 ff00",
+ output = Address.ipv6("0000:0000:0000:0000:0000:0000:0000:ff00")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 0000 0000 0000 00ff 0000",
+ output = Address.ipv6("0000:0000:0000:0000:0000:0000:00ff:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 0000 0000 0000 ff00 0000",
+ output = Address.ipv6("0000:0000:0000:0000:0000:0000:ff00:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 0000 0000 00ff 0000 0000",
+ output = Address.ipv6("0000:0000:0000:0000:0000:00ff:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 0000 0000 ff00 0000 0000",
+ output = Address.ipv6("0000:0000:0000:0000:0000:ff00:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 0000 00ff 0000 0000 0000",
+ output = Address.ipv6("0000:0000:0000:0000:00ff:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 0000 ff00 0000 0000 0000",
+ output = Address.ipv6("0000:0000:0000:0000:ff00:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 00ff 0000 0000 0000 0000",
+ output = Address.ipv6("0000:0000:0000:00ff:0000:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 0000 ff00 0000 0000 0000 0000",
+ output = Address.ipv6("0000:0000:0000:ff00:0000:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 00ff 0000 0000 0000 0000 0000",
+ output = Address.ipv6("0000:0000:00ff:0000:0000:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 0000 ff00 0000 0000 0000 0000 0000",
+ output = Address.ipv6("0000:0000:ff00:0000:0000:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 00ff 0000 0000 0000 0000 0000 0000",
+ output = Address.ipv6("0000:00ff:0000:0000:0000:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "0000 ff00 0000 0000 0000 0000 0000 0000",
+ output = Address.ipv6("0000:ff00:0000:0000:0000:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "00ff 0000 0000 0000 0000 0000 0000 0000",
+ output = Address.ipv6("00ff:0000:0000:0000:0000:0000:0000:0000")},
+ {encoding = ENC_BIG_ENDIAN, input = "ff00 0000 0000 0000 0000 0000 0000 0000",
+ output = Address.ipv6("ff00:0000:0000:0000:0000:0000:0000:0000")},
+ }
+
+ function tvbr_ipv6 (tvbr, encoding)
+ return tvbr:ipv6(), "ipv6()"
+ end
+
+ local ether_test_cases = {
+ {input = "ff 00 00 00 00 00", encoding = 0, output = Address.ether("ff:00:00:00:00:00")},
+ {input = "00 ff 00 00 00 00", encoding = 0, output = Address.ether("00:ff:00:00:00:00")},
+ {input = "00 00 ff 00 00 00", encoding = 0, output = Address.ether("00:00:ff:00:00:00")},
+ {input = "00 00 00 ff 00 00", encoding = 0, output = Address.ether("00:00:00:ff:00:00")},
+ {input = "00 00 00 00 ff 00", encoding = 0, output = Address.ether("00:00:00:00:ff:00")},
+ {input = "00 00 00 00 00 ff", encoding = 0, output = Address.ether("00:00:00:00:00:ff")},
+ }
+
+ function tvbr_ether (tvbr, encoding)
+ return tvbr:ether(), "ether()"
+ end
+
+ return true
+ and run_test_cases_all_tests(tree, "ipv4", ipv4_test_cases, tvbr_ipv4, general_equality_test)
+ and run_test_cases_all_tests(tree, "ipv6", ipv6_test_cases, tvbr_ipv6, general_equality_test)
+ and run_test_cases_all_tests(tree, "ether", ether_test_cases, tvbr_ether, general_equality_test)
+end
+
+function time_tests(tree)
+
+ local time_cases = {
+ {input ="00 01 02 03", encoding = ENC_BIG_ENDIAN, output = NSTime(0x00010203,0)},
+ {input ="03 02 01 00", encoding = ENC_LITTLE_ENDIAN, output = NSTime(0x00010203,0)},
+ {input ="00 01 02 03 04 05 06 07", encoding = ENC_BIG_ENDIAN, output = NSTime(0x00010203, 0x04050607)},
+ {input ="03 02 01 00 07 06 05 04", encoding = ENC_LITTLE_ENDIAN, output = NSTime(0x00010203, 0x04050607)},
+ }
+
+ local string_cases = {
+ {input = "1994-11-05T13:15:30Z", encoding = ENC_ISO_8601_DATE_TIME, output = NSTime(784041330, 0),
+ hexlify=true},
+ {input = "1994-11-05T13:15:30Z12345", encoding = ENC_ISO_8601_DATE_TIME, output = NSTime(784041330, 0),
+ hexlify=true, variable_input_length = true, input_length = 20},
+ }
+
+ function tvbr_nstime(tvbr, encoding)
+ if encoding == ENC_LITTLE_ENDIAN then
+ return tvbr:le_nstime(), "le_nstime()"
+ else
+ return tvbr:nstime(encoding), string.format("nstime(%s)", format_encoding_for_print(encoding))
+ end
+ end
+
+ return true
+ and run_test_cases_all_tests(tree, "relative_time", time_cases, tvbr_nstime, general_equality_test)
+ and run_test_cases_all_tests(tree, "absolute_time", time_cases, tvbr_nstime, general_equality_test)
+ and run_test_cases_all_tests(tree, "absolute_time", string_cases, tvbr_nstime, general_equality_test)
+end
+
+function bytearray_tests(tree)
+
+ local bytes_tests = {
+ {input = "00 01 02 03 ff", encoding = 0, output = ByteArray.new("00 01 02 03 ff")}
+ }
+
+ function tvbr_bytes(tvbr, encoding)
+ return tvbr:bytes(), "bytes()"
+ end
+
+ local varbytes_tests = {
+ {input = "04 00 01 02 ff", encoding = ENC_BIG_ENDIAN,
+ output = ByteArray.new("00 01 02 ff"), fake_input_length = 1},
+ {input = "00 04 00 01 02 ff", encoding = ENC_BIG_ENDIAN,
+ output = ByteArray.new("00 01 02 ff"), fake_input_length = 2},
+ {input = "00 00 00 04 00 01 02 ff", encoding = ENC_BIG_ENDIAN,
+ output = ByteArray.new("00 01 02 ff"), fake_input_length = 4},
+ }
+
+ return true
+ and run_test_cases_all_tests(tree, "bytes", bytes_tests, tvbr_bytes, general_equality_test)
+ and run_test_cases_all_tests(tree, "oid", bytes_tests, tvbr_bytes, general_equality_test)
+ and run_test_cases_all_tests(tree, "rel_oid", bytes_tests, tvbr_bytes, general_equality_test)
+ and run_test_cases_all_tests(tree, "system_id", bytes_tests, tvbr_bytes, general_equality_test)
+ and run_test_cases_all_tests(tree, "uint_bytes", varbytes_tests, nil, general_equality_test)
+end
+
+--[[
+ TODO
+"ipxnet",
+"framenum",
+"guid",
+"eui64",
+]]--
+
+function run_all_tests(tree)
+ return true
+ and simple_integer_tests(tree)
+ and integer64_tests(tree)
+ and string_tests(tree)
+ and bool_char_tests(tree)
+ and float_tests(tree)
+ and address_tests(tree)
+ and time_tests(tree)
+ and bytearray_tests(tree)
+end
+
+local has_run = false
+function myproto.dissector(tvb, pkt, root)
+ if has_run then
+ return
+ end
+ has_run = true
+ local tree = root:add(myproto, tvb(0))
+ if run_all_tests(tree) then
+ print("All tests passed!")
+ print()
+ end
+end
+
+DissectorTable.get("udp.port"):add(65333, myproto)
diff --git a/test/lua/field_setup.lua b/test/lua/field_setup.lua
new file mode 100644
index 0000000000..d73b13a0cc
--- /dev/null
+++ b/test/lua/field_setup.lua
@@ -0,0 +1,108 @@
+function field_setup(proto, prefix)
+
+ local pf_boolean = ProtoField.new("Boolean", prefix..".boolean", ftypes.BOOLEAN)
+ local pf_char = ProtoField.new("Char", prefix..".char", ftypes.CHAR)
+ local pf_uint8 = ProtoField.new("Uint8", prefix..".uint8", ftypes.UINT8)
+ local pf_uint16 = ProtoField.new("Uint16", prefix..".uint16", ftypes.UINT16)
+ local pf_uint24 = ProtoField.new("Uint24", prefix..".uint24", ftypes.UINT24)
+ local pf_uint32 = ProtoField.new("Uint32", prefix..".uint32", ftypes.UINT32)
+ local pf_uint64 = ProtoField.new("Uint64", prefix..".uint64", ftypes.UINT64)
+ local pf_int8 = ProtoField.new("Int8", prefix..".int8", ftypes.INT8)
+ local pf_int16 = ProtoField.new("Int16", prefix..".int16", ftypes.INT16)
+ local pf_int24 = ProtoField.new("Int24", prefix..".int24", ftypes.INT24)
+ local pf_int32 = ProtoField.new("Int32", prefix..".int32", ftypes.INT32)
+ local pf_int64 = ProtoField.new("Int64", prefix..".int64", ftypes.INT64)
+ local pf_float = ProtoField.new("Float", prefix..".float", ftypes.FLOAT)
+ local pf_double = ProtoField.new("Double", prefix..".double", ftypes.DOUBLE)
+ local pf_absolute_time = ProtoField.new("Absolute_Time", prefix..".absolute_time", ftypes.ABSOLUTE_TIME)
+ local pf_relative_time = ProtoField.new("Relative_Time", prefix..".relative_time", ftypes.RELATIVE_TIME)
+ local pf_string = ProtoField.new("String", prefix..".string", ftypes.STRING)
+ local pf_stringz = ProtoField.new("Stringz", prefix..".stringz", ftypes.STRINGZ)
+ local pf_ether = ProtoField.new("Ether", prefix..".ether", ftypes.ETHER)
+ local pf_bytes = ProtoField.new("Bytes", prefix..".bytes", ftypes.BYTES)
+ local pf_uint_bytes = ProtoField.new("Uint_Bytes", prefix..".uint_bytes", ftypes.UINT_BYTES)
+ local pf_ipv4 = ProtoField.new("Ipv4", prefix..".ipv4", ftypes.IPv4)
+ local pf_ipv6 = ProtoField.new("Ipv6", prefix..".ipv6", ftypes.IPv6)
+ local pf_ipxnet = ProtoField.new("Ipxnet", prefix..".ipxnet", ftypes.IPXNET)
+ local pf_framenum = ProtoField.new("Framenum", prefix..".framenum", ftypes.FRAMENUM)
+ local pf_guid = ProtoField.new("Guid", prefix..".guid", ftypes.GUID)
+ local pf_oid = ProtoField.new("Oid", prefix..".oid", ftypes.OID)
+ local pf_rel_oid = ProtoField.new("Rel_Oid", prefix..".rel_oid", ftypes.REL_OID)
+ local pf_system_id = ProtoField.new("System_Id", prefix..".system_id", ftypes.SYSTEM_ID)
+ local pf_eui64 = ProtoField.new("Eui64", prefix..".eui64", ftypes.EUI64)
+
+ proto.fields = {
+ pf_boolean, pf_char, pf_uint8, pf_uint16, pf_uint24, pf_uint32, pf_uint64, pf_int8,
+ pf_int16, pf_int24, pf_int32, pf_int64, pf_float, pf_double, pf_absolute_time, pf_relative_time,
+ pf_string, pf_stringz, pf_ether, pf_bytes, pf_uint_bytes, pf_ipv4, pf_ipv6, pf_ipxnet,
+ pf_framenum, pf_guid, pf_oid, pf_rel_oid, pf_system_id, pf_eui64,
+ }
+
+ local vf_boolean = Field.new(prefix..".boolean")
+ local vf_char = Field.new(prefix..".char")
+ local vf_uint8 = Field.new(prefix..".uint8")
+ local vf_uint16 = Field.new(prefix..".uint16")
+ local vf_uint24 = Field.new(prefix..".uint24")
+ local vf_uint32 = Field.new(prefix..".uint32")
+ local vf_uint64 = Field.new(prefix..".uint64")
+ local vf_int8 = Field.new(prefix..".int8")
+ local vf_int16 = Field.new(prefix..".int16")
+ local vf_int24 = Field.new(prefix..".int24")
+ local vf_int32 = Field.new(prefix..".int32")
+ local vf_int64 = Field.new(prefix..".int64")
+ local vf_float = Field.new(prefix..".float")
+ local vf_double = Field.new(prefix..".double")
+ local vf_absolute_time = Field.new(prefix..".absolute_time")
+ local vf_relative_time = Field.new(prefix..".relative_time")
+ local vf_string = Field.new(prefix..".string")
+ local vf_stringz = Field.new(prefix..".stringz")
+ local vf_ether = Field.new(prefix..".ether")
+ local vf_bytes = Field.new(prefix..".bytes")
+ local vf_uint_bytes = Field.new(prefix..".uint_bytes")
+ local vf_ipv4 = Field.new(prefix..".ipv4")
+ local vf_ipv6 = Field.new(prefix..".ipv6")
+ local vf_ipxnet = Field.new(prefix..".ipxnet")
+ local vf_framenum = Field.new(prefix..".framenum")
+ local vf_guid = Field.new(prefix..".guid")
+ local vf_oid = Field.new(prefix..".oid")
+ local vf_rel_oid = Field.new(prefix..".rel_oid")
+ local vf_system_id = Field.new(prefix..".system_id")
+ local vf_eui64 = Field.new(prefix..".eui64")
+
+ local fieldmap = {
+ ["boolean"] = {packet_field = pf_boolean, value_field = vf_boolean},
+ ["char"] = {packet_field = pf_char, value_field = vf_char},
+ ["uint8"] = {packet_field = pf_uint8, value_field = vf_uint8},
+ ["uint16"] = {packet_field = pf_uint16, value_field = vf_uint16},
+ ["uint24"] = {packet_field = pf_uint24, value_field = vf_uint24},
+ ["uint32"] = {packet_field = pf_uint32, value_field = vf_uint32},
+ ["uint64"] = {packet_field = pf_uint64, value_field = vf_uint64},
+ ["int8"] = {packet_field = pf_int8, value_field = vf_int8},
+ ["int16"] = {packet_field = pf_int16, value_field = vf_int16},
+ ["int24"] = {packet_field = pf_int24, value_field = vf_int24},
+ ["int32"] = {packet_field = pf_int32, value_field = vf_int32},
+ ["int64"] = {packet_field = pf_int64, value_field = vf_int64},
+ ["float"] = {packet_field = pf_float, value_field = vf_float},
+ ["double"] = {packet_field = pf_double, value_field = vf_double},
+ ["absolute_time"] = {packet_field = pf_absolute_time, value_field = vf_absolute_time},
+ ["relative_time"] = {packet_field = pf_relative_time, value_field = vf_relative_time},
+ ["string"] = {packet_field = pf_string, value_field = vf_string},
+ ["stringz"] = {packet_field = pf_stringz, value_field = vf_stringz},
+ ["ether"] = {packet_field = pf_ether, value_field = vf_ether},
+ ["bytes"] = {packet_field = pf_bytes, value_field = vf_bytes},
+ ["uint_bytes"] = {packet_field = pf_uint_bytes, value_field = vf_uint_bytes},
+ ["ipv4"] = {packet_field = pf_ipv4, value_field = vf_ipv4},
+ ["ipv6"] = {packet_field = pf_ipv6, value_field = vf_ipv6},
+ ["ipxnet"] = {packet_field = pf_ipxnet, value_field = vf_ipxnet},
+ ["framenum"] = {packet_field = pf_framenum, value_field = vf_framenum},
+ ["guid"] = {packet_field = pf_guid, value_field = vf_guid},
+ ["oid"] = {packet_field = pf_oid, value_field = vf_oid},
+ ["rel_oid"] = {packet_field = pf_rel_oid, value_field = vf_rel_oid},
+ ["system_id"] = {packet_field = pf_system_id, value_field = vf_system_id},
+ ["eui64"] = {packet_field = pf_eui64, value_field = vf_eui64},
+ }
+
+ return fieldmap
+end
+
+return field_setup