Table of Contents
Lua
Currently, the lua API allows the creation of scripted pom-ng output.
Quick link : List of plugins.
Tutorial
Register an output
To create a new output, you simply call output.new(name, parameters). Each parameter is declared the following way : {name, ptype, default_value, description}. The output will be registered in the system automatically.
When the output is started, the function open() will be called. Similarily, the function close() will be called when the output is stopped.
Here is an example of a basic output which prints the value of parameter 1 on startup and parameter 2 when stopped :
my_output = pom.output.new("my_output_name", { { "param1_name", "string", "default_value", "Parameter description" }, { "param2_name", "uint64", "1234567", "Parameter 2 is an integer" } }) function my_output:open() local param1_value = self:param_get("param1_name") print("My output started. Param 1 value is " .. param1_value) end function my_output:close() local param2_value = self:param_get("param2_name") print("My output started. Param 2 value is " .. param2_value) end
Listening to events
Listening to events is very easy. To start listening to a particular event, call self:event_listen_start(event_name, process_begin_function, process_end_function).
The event_name is the event you want to listen to. The process_begin_function and process_end_function will be called when the event being listened to starts and ends. The process function prototype should be process_function(event). You can specify nil for either functions if you don't need to process the begining, the end of an event or both.
It is important that you stop listening to events using self:event_listen_stop(event_name) when you don't need it anymore.
For more informations about events, see the event API documentation.
Here is an example that prints the name of an event when ends :
function my_output:event_process(evt) print("Event " .. evt.name .. " just finished !") end function my_output:open() self:event_listen_start("my_event", nil, self.event_process) end function my_output:close() self:event_listen_stop("my_event") end
Listening to payloads
Similar to the events, you can listen to payloads using self:pload_listen_start(open_function, write_function, close_function).
The open_function will be called when a new payload is found. Its prototype is function open_function(payload_priv, payload). The variable payload_priv is a table where you can store data related to that payload. You will receive the same payload_priv table in the write and close function. The payload_priv table is an easy way to store different data for each payload. The variable payload holds all the information known about the payload.
The prototype of the write_function is function write_function(payload_priv, payload_data). The first argument is the same table as the one passed to the open_function. The second argument is the data of the payload. You can get the number of bytes using payload_data.len and the actual data using payload_data.data.
The close function only receives the payload_prive table : function close_function(payload_priv). It will be called each time a payload is complete.
Here is an example :
function my_output:pload_open(priv, pload) print("New payload of class " .. pload.type["class"]) priv.tot_len = 0 return true end function my_output:pload_write(priv, pdata) priv.tot_len += pdata.len return true end function my_output:pload_close(priv) print("The payload was " .. priv.tot_len .. " bytes") end function my_output:open() self:pload_listen_start(self.pload_open, self.pload_write, self.pload_close) end function my_output:close() self:pload_listen_stop() end
Using plugins
The plugins are piece of C code, usually from existing outputs, that perform useful functions. For example, the plugin log_xml logs all the data about a particular event into an XML file. To use plugins, you first create an instance of the plugin you need using pom.plugin.new(plugin_name). Afterwards, set the plugin parameter to the desired value using plugin:param_set(param_name, param_value) and open the plugin using plugin:open().
The plugin is now ready to receive events or payloads depending on the type of the plugin. For event plugins, you can either send the event directly to the plugin by calling plugin:event_process(event) or have it listen to events by itself using plugin:event_listen_start(event_name) and plugin:event_listen_stop(event_name).
You can have payload plugins process the payload by calling plugin:pload_process(pload, parameters). The parameters are specific payload parameters. For example the plugin file takes the parameter filename. The parameters are a simple array with the key being the parameter name and the value the parameter value.
Once you are done with the plugin, you must call the plugin:close() function to release associated ressources.
function my_output:pload_open(pload_priv, pload) -- Log the event associated with the payload self.log:event_process(pload.event) -- Process the payload local fname = "/tmp/" .. self.file_count .. ".bin" self.file_count++; -- Send the payload to the plugin, it will take care of it from now on self.file:pload_process(pload, { filename = fname }) -- Return false because there is nothing more to do return false end function my_output:open() -- Setup the logging plugin self.log = pom.plugin.new("log_xml") self.log:param_set("filename", "/tmp/my_output_logs.xml") self.log:open() -- Setup the file plugin self.file = pom.plugin.new("file") self.file:open() -- File counter self.file_count = 0 -- Listen to the http_request event in order have the payload generated out of it self:even_listen_start("http_request", nil, nil) -- Listen to payloads -- self:pload_listen_start(self.payload_open, nil, nil) end function my_output:close() self:pload_listen_stop() self:event_listen_stop("http_request") self.file:close() self.log:close() end
The API
pom library
pom.data.iterator(data)
Parameters:
- data: a data object.
Returns:
An iterator function that iterates over the data object values. The iterator returns the next pair of key/values each time its called.
Example:
local data_iter = pom.data.iterator(data) while true do local key, value key, value = data_iter() if not key then break end local value_type = type(value) if value_type == "userdata" then print("Data has key " .. key .. " which value is a data_item object") elseif value_type == "nil" then print("Data has key " .. key .. " with no value associated") else print("Data has key " .. key .. " with value \"" .. value .. "\"") end end
pom.data.item_iterator(data_item)
The pom.data.item_iterator() works the same way as the pom.data.iterator() but with data_item object instead of data objects.
Parameters:
- data_item: A data_item object from a data object.
pom.dns.forward_lookup(name)
Perform a forward lookup for a hostname using the offline DNS database.
Parameters:
- name: A name to lookup
pom.dns.reverse_lookup(name)
Perform a reverse lookup for a hostname or IP using the offline DNS database. It will try to find out what was the original query that points to the provided name.
Parameters:
- name: A name or IP to lookup
pom.log(level, message)
Log a line into pom-ng. The function print() is actually a overriden by this function and logs messages at the INFO level.
Parameters:
- level: Log level. You can use the global variables POMLOG_ERR, POMLOG_WARN, POMLOG_INFO, POMLOG_DEBUG for the appropriate logging level.
- message: The message to log.
pom.output.new(name, parameters)
Creates a new output class. It will return an array which can be used with pom.output.register(). You must implement the open() and the close() function.
Parameters:
- nameName: of the parameter that will appear in pom-ng as the output type.
- parameters: An array of parameters. Each parameter should be in the form {name, ptype, default_value, description} where name is the parameter name, ptype is the type of value (e.g. string, uint64, timestamps), default_value is the default value of the parameter and description a short description.
Returns:
An output class.
pom.plugin.new(plugin_name)
Creates a new plugin instance.
Parameters:
- plugin_name: Name of the plugin. See plugins for a list of plugins.
data
The data objects are a collections of data about an even or a payload. It is basically a table containing key/values. The values are either nil if they are not set, a single value such as a string or an integer, or a data_item object containing a list of key/values.
Example:
-- Accessing a data entry print(data["url"]) -> "/index.html" -- Accessing a data_item object local query_headers = data["query_headers"] print(query_headers["Host"]) -> "www.packet-o-matic.org"
event
Events object contain the event name and the data associated with that event.
event.name
Returns:
Returns a string containing the name of the event.
event.data
Returns:
Returns a data object containing all the information related to this event.
event.timestsamp
Returns:
Returns the timestamp when the event started in micro seconds since epoch.
output
Outputs are the main object that you will create. You need to use pom.output.new() to create a new output class and you must implement the open and close function.
output:close()
Called when an instance of the output is stopped. This function must be implemented by addon.
output:event_listen_start(event_name, process_begin_function, process_end_function, filter)
Call this function to start listening to a particular event. You must call output:event_listen_stop(event_name) when you are done listening to that particular event.
Parameters:
- event_name: Name of the event you want to listen to. For a list of available events, see here.
- process_begin_function: Function that will be called when an event starts. Its prototype is process_function(event).
- process_end_function: Function that will be called when an event stops. Its prototype is process_function(event).
- filter: String containing an event filter, optional.
output:event_listen_stop(event_name)
Call this function to stop listening to an event.
Parameters:
- event_name: Name of the event you want to stop listening to.
output:open()
Called when an instance of the output is started. This function must be implemented by addon.
output:pload_listen_start(open_function, write_function, close_function, filter)
Start listening to payloads. Every payload will be processed. It's up to the output to filter them. If you don't need a specific function, you can specify nil instead.
Parameters:
- open_function: Function that will be called when a new payload is open. Its prototype is open_function(payload_priv, payload). It must return true if it want to continue processing the payload, otherwise false.
- write_function: Function that will be called when new data from a payload are available. Its prototype is write_function(payload_priv, payload_data). It must return true to continue processing the payload, other false.
- close_function: Function that will be called once a payload has been fully processed. Its prototype is close_function(payload_priv).
- filter: Pload filter to use, optional.
Parameters of the above functions:
- payload: It's a pload object that contains informations about the payload.
- payload_priv: Table unique per payload. Used to store output specific variables which will be tied to a specific payload.
- payload_data: It's a pload_data object containing both the actual data and the len.
output:pload_listen_stop()
Stops listening to payloads.
output:param_get(param_name)
Get the current value of the output parameter.
Parameters:
- param_name: The name of the parameter to get the value from.
pload
pload.data
Returns:
Returns the data related to this payload. It contains the data that the analyzer identified. For example, images will contain 'height' and 'width'.
pload.event
Returns:
Returns the event related to this payload.
pload.filename
Returns:
Returns the pload filename if it has been set, nil otherwise.
pload.parent
Returns:
Returns the pload that was the parent of the present pload if any.
pload.type
Returns:
Provide a table describing the payload type :
name | Type name (e.g. jpeg, pdf, …) |
description | Short description of this payload type. |
extension | Default file extension for this payload type. |
class | Class fo the payload. Classes are : unknown, application, audio, image, video, document. |
See payload_types.xml for a list of payload types.
pload_data
pload_data.data
Returns:
Returns a string containing the actual payload data.
pload_data.len
Returns:
Returns the lenght of the payload data in bytes.
plugin
Plugins are a piece of C code, usually from existing outputs, that perform useful functions. There are two types of plugins : event plugins and payload plugins. As you can guess, event plugins will process events and payload plugins will process payloads.
Here is a list of plugins.
plugin:close()
Close the plugin and releases all the associated data.
plugin:event_listen_start(event_name, filter)
Have the plugin listens to a specific event and process it.
Parameters:
- event_name: Name of the event to listen to.
- filter: String containing an event filter, optional.
plugin:event_listen_stop(event_name)
Have the plugin stop listening for a specific event.
Parameters:
- event_name: Name of the event to stop listening to.
plugin:event_process(event)
Process a specific event.
Parameters:
- event: Event object to process.
plugin:open()
Opens a plugin so it is ready for processing.
plugin:param_get(param_name)
Retrieve the value of a plugin parameter.
Parameters:
- param_name: Name of the parameter.
Returns:
Returns the value of the given parameter.
plugin:param_set(param_name, param_value)
Sets the value of the given plugin parameter.
Parameters:
- param_name: Name of the parameters.
- param_value: Value to set to the parameter.
plugin:pload_process(pload, parameters)
Process a specific payload. It should only be used in the pload_open callback function of the output !
Parameters:
- pload: A pload object to process.
- parameters: Parameters for this pload. A simple table with the key being the parameter name and the value being the parameter value.