I'm writing a chained dissector in Lua for the Ethercat protocol. I named my chained dissector littlecat.
For what I have so far, littlecat correctly dissects the fields I want it to. However, instead of executing after the built in ecat dissector, littlecat takes it over completely.
This is what the registration at the end of my Lua code looks like.
-- Initialize Protocol
function littlecat.init()
end
-- Register Chained Dissector Ethercat Port
local ethercat_dissector_table = DissectorTable.get("ecatf.type")
dissector = ethercat_dissector_table:get_dissector(1)
-- Dissector can be called from littlecat.dissector
-- So the previous dissector gets called
ethercat_dissector_table:add(1, littlecat)
How can I have my dissector execute after ecat has been executed?
I found a solution.
To ensure that the default dissector is called, and then the custom dissector:
Define the dissector table and original dissector before the dissection function.
Call original dissector within the dissection function.
Example
-- Initialize Protocol
-- Initialize Protocol Fields
-- Define dissector table and default dissector here
-- so they can be called within the dissection func.
local dissector_table = DissectorTable.get("shortname")
dissector = dissector_table:get_dissector(PORT)
-- Dissection Function
function dissectorname.dissector (tvbuf, pktinfo, root)
-- Call default dissector.
dissector(tvbuf, pktinfo, root)
-- Continue dissection....
end
-- Initialize Protocol
function dissectorname.init()
end
-- Dissector can be called from dissectorname.dissector
-- So the previous dissector gets called
dissector_table:add(PORT, dissectorname)
Related
In Lua, calling a function with excess arguments will simply discard those. Is there a possibility with the debug library to access these discarded arguments? (I'm not looking for variadic functions)
function test()
local info = debug.getinfo(1, "u")
print(info.nparams) -- just 0 :(
-- how to access the discarded arguments?
end
test(42, "Hello World!", 3.14)
Edit: As Luiz-Henrique informed me in the comments, this is not possible in standard Lua. He also asked for more context, so I'm going to repeat the problem that I was trying to solve to answer another question. In this other question the OP wanted to access the name that module has inside package.preload from within the loader function but without taking it as an argument as it is passed by require. I don't know why but this led me to the question whether it is possible to access discarded arguments.
package.preload["test"] = function()
local info = debug.getinfo(1, "u")
print(info.nparams) -- just 0 :(
-- how to access the name without taking it as an argument
return {}
end
require("test")
I have a Lua Wireshark dissector that is structured like so:
-- Initialize Protocol
-- Initialize Protocol Fields
-- Register Protocol Fields
-- DissectionFunction(tvbuf, pktinfo, root)
-- Initialize Protocol
-- Function definitions.
I have a function written that I'd like to use to calculate some values, and then use those values in the dissector. So I wrote my function outside the dissection function and in the function definitions section.
But the function call also works within the dissector function, if called outside the dissector function Wireshark does not recognize it. Calling it in the dissection function is very inefficient, as it only needs to be executed once and will be executed for every frame instead.
Is there a way to call it once outside the dissection function?
I'm not quite sure of what the question is, but you can do the following in Lua
local function calculate_constant_value()
return a * b + c
end
local my_constant_value = calculate_constant_value()
function proto.dissector()
-- use my_constant_value here
end
I wrote a lua function write_json which translates lua table into json text.
Is it possible to bind the function with the io library, so that I can use it like this:
mytable = {name="Jack", age="22", score=[12,33,55,66]}
f = io.open("score.json", "wb")
f:write_json(mytable) -- call my function here.
f:close()
You need access to the __index table of the metatable for file objects and put your new methods there:
local metatable = getmetatable( io.stdout )
local indextable = metatable.__index
indextable.write_json = function( file, tab )
-- ...
end
There is another way: The C API function luaL_newmetatable stores the metatable for file objects in the registry under the key "FILE*", so the following will also work (but requires the debug library):
local metatable = debug.getregistry()["FILE*"]
local indextable = metatable.__index
-- ...
There is yet another (more hackish) way: All Lua versions I tested (PUC-Rio Lua 5.1, 5.2, 5.3, and LuaJIT) set the __index field of the metatable to the metatable itself, so you can get at the __index table like that:
local indextable = io.stdout.__index
The best way is probably the first one.
The type of the object returned by io.open is userdata, which I believe cannot be monkey-patched due to its unique nature.
I found very useful example of heuristic tables usage in Lua.
a link
But it doesn't not cover my case.
I've written custom dissector in lua. Described custom protocol has many subprotos. So I create new subdissectors table DissectorTable.new() and register new subprotos.
But some of subprotocols doesn't have identification sign and their types must be found out dynamically.
I hoped to register heuristic dissector with proto:register_heuristic() method, but there is no my new table in DissectorTable.heuristic_list() list.
Creating new dissector table does not create heuristic dissectors table.
Is there a way to create new own heuristic dissectors table?
There is no way to create a real heuristic dissector table for your protocol in the current Lua API, but I'm not sure it makes a lot of sense to have such a thing. The purpose of having a protocol create a heuristic dissector table for itself is so that other protocols can register their heuristic dissectors into it - for example the UDP protocol creates a heuristic dissector table named "udp", so that other protocols like RTP, STUN, Skype, etc., can all register their heuristic dissectors into it, and UDP can try them all without knowing about them before-hand.
But when you create a new protocol in a Lua plugin, no other code is going to know about your new protocol or any heuristic dissector table you create. Only your own Lua code will know about it. Obviously your new protocol might have subprotocols that need to be tried heuristically, as you appear to need, but you don't need a heuristic dissector table to do that - just call your subprotocols's heuristic dissector functions directly in Lua.
For example:
local myProto = Proto("myproto", "My Main Protocol")
local mySubproto1 = Proto("mysubproto1", "My First Sub-Protocol")
local mySubproto2 = Proto("mysubproto2", "My Second Sub-Protocol")
-- the sub-prpotocol's heuristic function
-- returns true if the packet is its protocol and it dissected it
-- otherwise returns false
function heur_dissect_mySubproto1(tvbuf, pktinfo, root)
-- see if the passed in tvb is Subproto1 protocol
-- and if so then add tree items and such or
-- call mySubproto1's normal dissector function to do that stuff
return is_Subproto1
end
function heur_dissect_mySubproto2(tvbuf, pktinfo, root)
-- see if the passed in tvb is Subproto2 protocol
return is_Subproto2
end
function myProto.dissector(tvbuf, pktinfo, root)
-- do stuff for my main protocol
-- create a new sub-tvb of what has not been processed by the main protocol
local newTvb = tvbuf(bytes_parsed_by_myproto):tvb()
-- call the heuristic dissector functions of my sub protocols
-- with the portion of the tvb that belongs to them
if heur_dissect_mySubproto1(newTvb, pktinfo, root) then
-- do here anything you need to afterwards
elseif heur_dissect_mySubproto2(newTvb, pktinfo, root) then
-- do here anything you need to afterwards
end
end
or if you want to be fancier, use a table of your own...
local myProto = Proto("myproto", "My Main Protocol")
local mySubproto1 = Proto("mysubproto1", "My First Sub-Protocol")
local mySubproto2 = Proto("mysubproto2", "My Second Sub-Protocol")
-- a heuristic dissector table for myProto
local myProto_heuristic_table = {}
-- a function to register into myProto's heuristic table
local function register_heuristic(func)
myProto_heuristic_table[#myProto_heuristic_table + 1] = func
end
function heur_dissect_mySubproto1(tvbuf, pktinfo, root)
-- do stuff
return is_Subproto1
end
-- "register" the above function
register_heuristic(heur_dissect_mySubproto1)
function heur_dissect_mySubproto2(tvbuf, pktinfo, root)
-- do stuff
return is_Subproto2
end
register_heuristic(heur_dissect_mySubproto2)
function myProto.dissector(tvbuf, pktinfo, root)
-- do stuff for my main protocol
local newTvb = tvbuf(bytes_parsed_by_myproto):tvb()
-- call the heuristic dissector functions of my sub protocols
-- with the portion of the tvb that belongs to them
for _, func in ipairs(myProto_heuristic_table) do
-- call the heuristic
if func(newTvb, pktinfo, root) then
-- do here anything you need to afterwards
return
end
end
end
How do I call a function that needs to be called from above its creation? I read something about forward declarations, but Google isn't being helpful in this case. What is the correct syntax for this?
Lua is a dynamic language and functions are just a kind of value that can be called with the () operator. So you don't really need to forward declare the function so much as make sure that the variable in scope when you call it is the variable you think it is.
This is not an issue at all for global variables containing functions, since the global environment is the default place to look to resolve a variable name. For local functions, however, you need to make sure the local variable is already in scope at the lexical point where you need to call the value it stores, and also make sure that at run time it is really holding a value that can be called.
For example, here is a pair of mutually recursive local functions:
local a,b
a = function() return b() end
b = function() return a() end
Of course, that is also an example of using tail calls to allow infinite recursion that does nothing, but the point here is the declarations. By declaring the variables with local before either has a function stored in it, those names are known to be local variables in lexical scope of the rest of the example. Then the two functions are stored, each referring to the other variable.
You can forward declare a function by declaring its name before declaring the actual function body:
local func1
local func2 = function()
func1()
end
func1 = function()
--do something
end
However forward declarations are only necessary when declaring functions with local scope. That is generally what you want to do, but Lua also supports a syntax more like C, in which case forward declaration is not necessary:
function func2()
func1()
end
function func1()
--do something
end
Testing under the embedded lua in Freeswitch, forward declaration does not work:
fmsg("CRIT", "It worked.")
function fmsg(infotype, msg)
freeswitch.consoleLog(infotype, msg .. "\n")
end
result:
[ERR] mod_lua.cpp:203 /usr/local/freeswitch/scripts/foo.lua:1: attempt to call global 'fmsg' (a nil value)
Reversing the order does (duh) work.
To comprehend how forward referencing in Lua works compared to C, you must understand the a fundamental difference between C compilation and the Lua execution.
In C, forward referencing is a compile time mechanism. Hence if you include a forward declaration template in a C module then any of your code following will employ this template in compiling the call. You may or may not include the function implementation in the same module, in which case both declarations must be semantically identical or the compiler will error. Since this is a compile time construct, the compiled code can be executed in any order.
In Lua, forward referencing is runtime mechanism, in that the compiled function generates a function prototype internally within the code, but this is only accessible as a runtime Lua variable or value after the execution has
passed over the declaration creating a Lua closure. Here the declaration order within the source is immaterial. It is the execution order that is important: if the closure hasn't been bound to the variable yet, then the execution will throw a "nil value" exception.If you are using a local variable to hold the function value, then normal local scoping rules still apply: the local declaration must precede its use in the source and must be within scope, otherwise the compiler will compile in the wrong global or outer local reference. So forward referencing using locals as discussed in other answer will work, but only if the Protos are bound to closures before the first call is executed.
Doesn't work for me if I try to call the function before definition. I am using this Lua script in nginx conf.
lua entry thread aborted: runtime error: lua_redirect.lua:109: attempt to call global 'throwErrorIfAny' (a nil value)
Code snippet -
...
throwErrorIfAny()
...
function throwErrorIfAny()
ngx.say("request not allowed")
ngx.exit(ngx.HTTP_OK)
end
Given some other answers have also pointed out that it didn't work for them either, it is possible that forward declaration of Lua doesn't work with other tools.
PS : It works fine if I put the function definition before and then call it after wards.
If you use OOP you can call any function member prior its "definition".
local myClass = {}
local myClass_mt = { __index = myClass }
local function f1 (self)
print("f1")
self:later() --not yet "delared" local function
end
local function f2 (self)
print("f2")
self:later() --not yet "declared" local function
end
--...
--later in your source declare the "later" function:
local function later (self)
print("later")
end
function myClass.new() -- constructor
local this = {}
this = {
f1 = f1,
f2 = f2,
later = later, --you can access the "later" function through "self"
}
setmetatable(this, myClass_mt)
return this
end
local instance = myClass.new()
instance:f1()
instance:f2()
Program output:
f1
later
f2
later