mirror of https://github.com/OISF/suricata
parent
3b7b908fe2
commit
eaef74af05
@ -0,0 +1,184 @@
|
||||
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
|
||||
Loading…
Reference in New Issue