mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.1 KiB
ReStructuredText
185 lines
4.1 KiB
ReStructuredText
DNP3
|
|
####
|
|
|
|
The ``suricata.dnp3`` module provides access to DNP3 (Distributed
|
|
Network Protocol 3) transaction data in Suricata Lua rules.
|
|
|
|
It is only available in Suricata Lua rules, not output scripts.
|
|
|
|
Setup
|
|
*****
|
|
|
|
::
|
|
|
|
local dnp3 = require("suricata.dnp3")
|
|
|
|
Module Functions
|
|
****************
|
|
|
|
.. function:: dnp3.get_tx()
|
|
|
|
Returns the current DNP3 transaction object containing request or response data.
|
|
|
|
:returns: A table containing the DNP3 transaction data, or nil on error
|
|
:raises error: If the protocol is not DNP3
|
|
:raises error: If no transaction is available
|
|
|
|
Example:
|
|
|
|
::
|
|
|
|
function match(args)
|
|
local tx = dnp3.get_tx()
|
|
if tx and tx.is_request then
|
|
-- Process DNP3 request
|
|
end
|
|
end
|
|
|
|
Transaction Object Structure
|
|
****************************
|
|
|
|
The transaction object returned by ``get_tx()`` contains the following fields:
|
|
|
|
.. attribute:: tx_num
|
|
|
|
Transaction number (integer)
|
|
|
|
.. attribute:: is_request
|
|
|
|
Boolean indicating if this is a request (true) or response (false)
|
|
|
|
.. attribute:: request
|
|
|
|
Table containing request data (only present when ``is_request`` is true)
|
|
|
|
.. attribute:: response
|
|
|
|
Table containing response data (only present when ``is_request`` is false)
|
|
|
|
Request/Response Structure
|
|
**************************
|
|
|
|
Both request and response tables contain:
|
|
|
|
.. attribute:: done
|
|
|
|
Boolean indicating if the transaction is complete
|
|
|
|
.. attribute:: complete
|
|
|
|
Boolean indicating if all data has been received
|
|
|
|
.. attribute:: link_header
|
|
|
|
Table containing DNP3 link layer header fields:
|
|
|
|
- ``len``: Frame length
|
|
- ``control``: Control byte
|
|
- ``dst``: Destination address
|
|
- ``src``: Source address
|
|
- ``crc``: CRC value
|
|
|
|
.. attribute:: transport_header
|
|
|
|
Transport layer header byte (integer)
|
|
|
|
.. attribute:: application_header
|
|
|
|
Table containing DNP3 application layer header fields:
|
|
|
|
- ``control``: Application control byte
|
|
- ``function_code``: DNP3 function code
|
|
|
|
.. attribute:: objects
|
|
|
|
Array of DNP3 objects in the message
|
|
|
|
Additionally, response tables contain:
|
|
|
|
.. attribute:: indicators
|
|
|
|
Internal Indication (IIN) field as a 16-bit integer combining IIN1 and IIN2
|
|
|
|
Objects Structure
|
|
*****************
|
|
|
|
Each object in the ``objects`` array contains:
|
|
|
|
.. attribute:: group
|
|
|
|
DNP3 object group number (integer)
|
|
|
|
.. attribute:: variation
|
|
|
|
DNP3 object variation number (integer)
|
|
|
|
.. attribute:: points
|
|
|
|
Array of data points for this object
|
|
|
|
Points Structure
|
|
****************
|
|
|
|
Each point in the ``points`` array contains:
|
|
|
|
.. attribute:: index
|
|
|
|
Point index (integer)
|
|
|
|
Additional point fields depend on the object group and variation. Common fields include:
|
|
|
|
- ``state``: Binary state value
|
|
- ``online``: Online status flag
|
|
- ``restart``: Restart flag
|
|
- ``comm_lost``: Communication lost flag
|
|
- ``remote_forced``: Remote forced flag
|
|
- ``local_forced``: Local forced flag
|
|
- ``chatter_filter``: Chatter filter flag
|
|
- ``reserved``: Reserved bits
|
|
- ``value``: Analog value (for analog objects)
|
|
- ``timestamp``: Timestamp value (for time-tagged objects)
|
|
|
|
For all available fields, see ``app-layer-dnp3-objects.h`` in the
|
|
Suricata source code.
|
|
|
|
Example Usage
|
|
*************
|
|
|
|
Complete example checking for specific DNP3 function codes:
|
|
|
|
::
|
|
|
|
local dnp3 = require("suricata.dnp3")
|
|
|
|
function init(args)
|
|
return {}
|
|
end
|
|
|
|
function match(args)
|
|
local tx = dnp3.get_tx()
|
|
|
|
if not tx then
|
|
return 0
|
|
end
|
|
|
|
-- Check for write function code in request
|
|
if tx.is_request and tx.request then
|
|
local func_code = tx.request.application_header.function_code
|
|
if func_code == 2 then -- WRITE function
|
|
return 1
|
|
end
|
|
end
|
|
|
|
-- Check for specific object types
|
|
if tx.request and tx.request.objects then
|
|
for _, obj in ipairs(tx.request.objects) do
|
|
if obj.group == 12 and obj.variation == 1 then
|
|
-- Control Relay Output Block
|
|
return 1
|
|
end
|
|
end
|
|
end
|
|
|
|
return 0
|
|
end
|