DNP3
December 17, 2025 ยท View on GitHub
The DNP3 plugin for Caldera provides adversary emulation abilities specific to the DNP3 control systems protocol.
v2.0 released 05 Dec 2024
Overview
The DNP3 plugin provides 11 unique abilities specific to the DNP3 protocol offered for both serial and TCP connections (22 total abilities). This is accomplished not through exploitation, but rather by leveraging native functionality within the protocol.
The following table outlines MITRE ATT&CK for ICS coverage provided by the DNP3 plugin.
| Collection | Inhibit Response Function | Impair Process Control |
|---|---|---|
| Automated Collection | Device Restart/Shutdown | Unauthorized Command Message |
| Point & Tag Identification | Block Reporting Message | Modify Parameter |
| Denial of Service |
Ability Overview Tables
The following table(s) list each plugin ability by their corresponding tactic.
Collection Abilities
| Ability | Technique | Technique Id |
|---|---|---|
| DNP3 - Read | Point & Tag Identification | T0861 |
| DNP3 - Read All | Point & Tag Identification | T0861 |
| DNP3 - Integrity Poll | Automated Collection | T0802 |
| DNP3 - Enable Unsolicited Messages | Automated Collection | T0802 |
Inhibit Response Function Abilities
| Ability | Technique | Technique Id |
|---|---|---|
| DNP3 - Cold Restart | Device Restart/Shutdown | T0816 |
| DNP3 - Warm Restart | Device Restart/Shutdown | T0816 |
| DNP3 - Disable Unsolicited Messages | Block Reporting Message | T0804 |
Impair Process Control Abilities
| Ability | Technique | Technique Id |
|---|---|---|
| DNP3 - Operate | Unauthorized Command Message | T0855 |
| DNP3 - Toggle (Two-Output Model) | Unauthorized Command Message | T0855 |
| DNP3 - Toggle (Activation Model) | Unauthorized Command Message | T0855 |
| DNP3 - Set Analog | Modify Parameter | T0836 |
Architecture
This section describes the main components of the plugin and how they interface.
Block Diagram

The DNP3 plugin exposes several new protocol specific abilities to your Caldera instance. The abilities are executed from a host running a Caldera agent via the corresponding payload. Abilities must target devices that support the DNP3 protocol to achieve described effects.
Payloads
The DNP3 plugin includes one payload that implements the abilities, compiled for three different host architectures:
dnp3-actions.exe(Windows)dnp3-actions(Linux)dnp3-actions_darwin(Mac)
Libraries
The following libraries were used to build the DNP3 payloads:
| Library | Version | License |
|---|---|---|
| OpenDNP3 | v3.1.2 | Apache 2.0 |
| CLI11 | v2.4.2 | License |
Usage
This section describes how to initially deploy and execute the abilities present within the DNP3 Plugin.
Deployment
- Identify the target system you would like to communicate with via the DNP3 protocol.
- Identify a viable host for the Caldera agent that will be sending DNP3 messages to the target system. A viable host has a network connection to the target system and has an architecture that is compatible with one of the plugin's payloads.
- Deploy the Caldera agent to the viable host.
- Run a combination of the DNP3 plugin abilities to achieve the desired effect.
If you don't know where to begin, try using DNP3 - Integrity Poll to read all of the data on a device.
Reference the Caldera training plugin for a step-by-step tutorial on how to deploy an agent and run abilities via an operation.
Test Server (Outstation) Usage
This plugin includes a test server (known in DNP3 parlance as an outstation) in the plugins/ directory that can be used to create a test environment for the plugin.
- Start the Caldera server and deploy a Caldera agent.
- On the device where the agent is running, start the DNP3 server using the following commands:
Windows (psh)
.\dnp3-outstation.exe --tui
Linux (sh)
./dnp3-outstation --tui
Darwin (sh)
./dnp3-outstation_darwin --tui
- Execute a DNP3 ability from your agent using the Caldera server. "DNP3 (TCP) - Integrity Poll" is a good first test. To target the DNP3 test server, ensure you select the following facts:
dnp3.server.ip: 127.0.0.1dnp3.link.local: 1dnp3.link.remote: 1024
- The outstation is designed to demonstrate the different features and concepts in the DNP3 protocol and is not intended to be an authentic replica of any specific device. Try discovering data on the device, reading and writing analog values, and operating points with different operation types and trip control codes.
Network Connection
This plugin allows the agent to send DNP3 messages using a IP/TCP or serial connection. The first argument to the dnp3-actions payload selects the connection type. This must be followed by several additional arguments to establish the connection.
IP/TCP
Positional arguments (required):
| Name | Description | Type |
|---|---|---|
dnp3.server.ip | IP address of the outstation | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
Flags (optional):
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
Serial
Positional arguments (required):
| Name | Description | Type |
|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
Flags (optional):
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
Abilities
DNP3 - Read
Read the specified values from the outstation.
For more information, see the [Data Model](#data-model) section.
TCP
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group} --start #{dnp3.data.start} --end #{dnp3.data.end}
Linux (sh)
./dnp3-actions tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group} --start #{dnp3.data.start} --end #{dnp3.data.end}
Darwin (sh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group} --start #{dnp3.data.start} --end #{dnp3.data.end}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.ip | IP address of the outstation | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.data.group | DNP3 datatype | int |
dnp3.data.start | First index to read (inclusive) | int |
dnp3.data.end | Final index to read (inclusive) | int |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
--variation | variation (format) to read the data | int | None |
Serial
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group} --start #{dnp3.data.start} --end #{dnp3.data.end}
Linux (sh)
./dnp3-actions serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group} --start #{dnp3.data.start} --end #{dnp3.data.end}
Darwin (sh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group} --start #{dnp3.data.start} --end #{dnp3.data.end}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.data.group | DNP3 datatype | int |
dnp3.data.start | First index to read (inclusive) | int |
dnp3.data.end | Final index to read (inclusive) | int |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
--variation | variation (format) to read the data | int | None |
DNP3 - Read All
Read the specified values from a certain group of the outstation.
For more information, see the [Data Model](#data-model) section.
TCP
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group}
Linux (sh)
./dnp3-actions tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group}
Darwin (sh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.ip | IP address of the outstation | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.data.group | DNP3 datatype | int |
dnp3.data.variation | Variation of the DNP3 datatype (group) | int |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
--variation | variation (format) to read the data | int | None |
Serial
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group}
Linux (sh)
./dnp3-actions serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group}
Darwin (sh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} read #{dnp3.data.group}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.data.group | DNP3 datatype | int |
dnp3.data.variation | Variation of the DNP3 datatype (group) | int |
dnp3.data.start | First index to read (inclusive) | int |
dnp3.data.end | Final index to read (inclusive) | int |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
--variation | variation (format) to read the data | int | None |
DNP3 - Integrity Poll
Read all data groups present on the outstation.
TCP
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} integrity-poll
Linux (sh)
./dnp3-actions tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} integrity-poll
Darwin (sh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} integrity-poll
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.ip | IP address of the outstation | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
Serial
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} integrity-poll
Linux (sh)
./dnp3-actions serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} integrity-poll
Darwin (sh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} integrity-poll
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
DNP3 - Operate
Operate specified points utilizing SELECT_BEFORE_OPERATE (SBO) or DIRECT_OPERATE (DO)
For more information on operating points in DNP3 see the [Control Models](#control-models) section.
TCP
Ability Command:
Windows (cmd/psh)
./dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} #{dnp3.op.mode} --indices #{dnp3.operate.indices} --op-type #{dnp3.operate.type} --tcc #{dnp3.operate.tcc}
Linux (sh)
./dnp3-actions tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} #{dnp3.op.mode} --indices #{dnp3.operate.indices} --op-type #{dnp3.operate.type} --tcc #{dnp3.operate.tcc}
Darwin (sh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} #{dnp3.op.mode} --indices #{dnp3.operate.indices} --op-type #{dnp3.operate.type} --tcc #{dnp3.operate.tcc}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.ip | IP address of the outstation | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.operate.mode | Choose either SBO or DO Mode | string |
dnp3.operate.indices | Indices to send the CROB to (operate) | comma separated list of int |
dnp3.operate.type | One of 'NUL', 'PULSE_ON', 'PULSE_OFF', 'LATCH_ON', 'LATCH_OFF' | string |
dnp3.operate.tcc | One of 'NUL', 'CLOSE', 'TRIP' | string |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
--on | signal on-time value in ms | int | 100 |
--off | signal off-time value in ms | int | 100 |
--count | times to repeat signal | int | 1 |
--clear | set the control code clear bit | string |
Serial
Ability Command:
Windows (cmd/psh)
./dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} #{dnp3.op.mode} --indices #{dnp3.operate.indices} --op-type #{dnp3.operate.type} --tcc #{dnp3.operate.tcc}
Linux (sh)
./dnp3-actions serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} #{dnp3.op.mode} --indices #{dnp3.operate.indices} --op-type #{dnp3.operate.type} --tcc #{dnp3.operate.tcc}
Darwin (sh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} #{dnp3.op.mode} --indices #{dnp3.operate.indices} --op-type #{dnp3.operate.type} --tcc #{dnp3.operate.tcc}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.operate.mode | Choose either SBO or DO Mode | string |
dnp3.operate.indices | Indices to send the CROB to (operate) | comma separated list of int |
dnp3.operate.type | One of 'NUL', 'PULSE_ON', 'PULSE_OFF', 'LATCH_ON', 'LATCH_OFF' | string |
dnp3.operate.tcc | One of 'NUL', 'CLOSE', 'TRIP' | string |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
--on | signal on-time value in ms | int | 100 |
--off | signal off-time value in ms | int | 100 |
--count | times to repeat signal | int | 1 |
--clear | set the control code clear bit | string |
DNP3 - Toggle (Activation Model)
Toggle breakers using the activation model (Utilizing trip-indices and close-indices)
For more information on operating points in DNP3 see the [Control Models](#control-models) section.
TCP
Ability Command:
Windows (cmd/psh)
./dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} toggle-activation #{dnp3.op.mode} --trip-indices #{dnp3.trip.indices} --close-indices #{dnp3.close.indices}
Linux (psh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} toggle-activation #{dnp3.op.mode} --trip-indices #{dnp3.trip.indices} --close-indices #{dnp3.close.indices}
Darwin (psh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} toggle-activation #{dnp3.op.mode} --trip-indices #{dnp3.trip.indices} --close-indices #{dnp3.close.indices}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.ip | IP address of the outstation | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.operate.mode | Choose either SBO or DO Mode | string |
dnp3.trip.indices | Trip-indices to send the CROB to (operate) | comma separated list of int |
dnp3.close.indices | Close-indices to send the CROB to (operate) | comma separated list of int |
dnp3.operate.type | One of 'NUL', 'PULSE_ON', 'PULSE_OFF', 'LATCH_ON', 'LATCH_OFF' | string |
dnp3.operate.tcc | One of 'NUL', 'CLOSE', 'TRIP' | string |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
--on | signal on-time value in ms | int | 100 |
--off | signal off-time value in ms | int | 100 |
--iterations | times to repeat signal | int | 1 |
--delay | delay between trip and close operations in ms | int | 30000 |
Serial
Ability Command:
Windows (cmd/psh)
./dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} toggle-activation #{dnp3.op.mode} --trip-indices #{dnp3.trip.indices} --close-indices #{dnp3.close.indices}
Linux (psh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} toggle-activation #{dnp3.op.mode} --trip-indices #{dnp3.trip.indices} --close-indices #{dnp3.close.indices}
Darwin (psh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} toggle-activation #{dnp3.op.mode} --trip-indices #{dnp3.trip.indices} --close-indices #{dnp3.close.indices}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.operate.mode | Choose either SBO or DO Mode | string |
dnp3.trip.indices | Trip-indices to send the CROB to (operate) | comma separated list of int |
dnp3.close.indices | Close-indices to send the CROB to (operate) | comma separated list of int |
dnp3.operate.type | One of 'NUL', 'PULSE_ON', 'PULSE_OFF', 'LATCH_ON', 'LATCH_OFF' | string |
dnp3.operate.tcc | One of 'NUL', 'CLOSE', 'TRIP' | string |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
--on | signal on-time value in ms | int | 100 |
--off | signal off-time value in ms | int | 100 |
--iterations | times to repeat signal | int | 1 |
--delay | delay between trip and close operations in ms | int | 30000 |
DNP3 - Toggle (Two Output Model)
Toggle breakers using the complementary two-output model (Utilizing TRIP/CLOSE on the same index)
For more information on operating points in DNP3 see the [Control Models](#control-models) section.
TCP
Ability Command:
Windows (cmd/psh)
./dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} toggle-two-output #{dnp3.op.mode} --indices #{dnp3.operate.indices}
Linux (psh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} toggle-two-output #{dnp3.op.mode} --indices #{dnp3.operate.indices}
Darwin (psh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} toggle-two-output #{dnp3.op.mode} --indices #{dnp3.operate.indices}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.ip | IP address of the outstation | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.operate.mode | Choose either SBO or DO Mode | string |
dnp3.operate.indices | Indices to send the CROB to (operate) | comma separated list of int |
dnp3.operate.type | One of 'NUL', 'PULSE_ON', 'PULSE_OFF', 'LATCH_ON', 'LATCH_OFF' | string |
dnp3.operate.tcc | One of 'NUL', 'CLOSE', 'TRIP' | string |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
--on | signal on-time value in ms | int | 100 |
--off | signal off-time value in ms | int | 100 |
--iterations | times to repeat signal | int | 1 |
--delay | delay between trip and close operations in ms | int | 30000 |
Serial
Ability Command:
Windows (cmd/psh)
./dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} toggle-two-output #{dnp3.op.mode} --indices #{dnp3.operate.indices}
Linux (psh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} toggle-two-output #{dnp3.op.mode} --indices #{dnp3.operate.indices}
Darwin (psh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} toggle-two-output #{dnp3.op.mode} --indices #{dnp3.operate.indices}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.operate.mode | Choose either SBO or DO Mode | string |
dnp3.operate.indices | Indices to send the CROB to (operate) | comma separated list of int |
dnp3.operate.type | One of 'NUL', 'PULSE_ON', 'PULSE_OFF', 'LATCH_ON', 'LATCH_OFF' | string |
dnp3.operate.tcc | One of 'NUL', 'CLOSE', 'TRIP' | string |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
--on | signal on-time value in ms | int | 100 |
--off | signal off-time value in ms | int | 100 |
--iterations | times to repeat signal | int | 1 |
--delay | delay between trip and close operations in ms | int | 30000 |
DNP3 - Set Analog
Change the values of specified points
TCP
Ability Command:
Windows (cmd/psh)
./dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} set-analog --indices #{dnp3.operate.indices} --values {dnp3.set.values}
Linux (psh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} set-analog --indices #{dnp3.operate.indices} --values {dnp3.set.values}
Darwin (psh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} set-analog --indices #{dnp3.operate.indices} --values {dnp3.set.values}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.ip | IP address of the outstation | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.set.analog | Set analog output values command | string |
dnp3.operate.indices | Indices to send the CROB to (operate) | comma separated list of int |
dnp3.set.values | Set values to output on specified point | comma separated list of int |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | Port number of the outstation | int | 20000 |
--dtype | Datatype of values | string | 'DOUBLE64' |
Serial
Ability Command:
Windows (cmd/psh)
./dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} set-analog --indices #{dnp3.operate.indices} --values {dnp3.set.values}
Linux (psh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} set-analog --indices #{dnp3.operate.indices} --values {dnp3.set.values}
Darwin (psh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} set-analog --indices #{dnp3.operate.indices} --values {dnp3.set.values}
Facts:
| Name | Description | Type |
|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string |
dnp3.local.link | DNP3 link layer address of the local device | int |
dnp3.remote.link | DNP3 link layer address of the remote device | int |
dnp3.set.analog | Set analog output values command | string |
dnp3.operate.indices | Indices to send the CROB to (operate) | comma separated list of int |
dnp3.set.values | Set values to output on specified point | comma separated list of int |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
--dtype | Datatype of values | string | 'DOUBLE64' |
DNP3 - Cold Restart
Perform a full restart (cold restart) of the outstation.
May leave the outstation in an unknown or invalid state
TCP
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} cold-restart
Linux (sh)
./dnp3-actions tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} cold-restart
Darwin (sh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} cold-restart
Facts:
| Name | Description | Type | Default |
|---|---|---|---|
dnp3.server.ip | IP address of the outstation | string | None |
dnp3.local.link | DNP3 link layer address of the local device | int | None |
dnp3.remote.link | DNP3 link layer address of the remote device | int | None |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
Serial
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} cold-restart
Linux (sh)
./dnp3-actions serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} cold-restart
Darwin (sh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} cold-restart
Facts:
| Name | Description | Type | Default |
|---|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string | |
dnp3.local.link | DNP3 link layer address of the local device | int | None |
dnp3.remote.link | DNP3 link layer address of the remote device | int | None |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
DNP3 - Warm Restart
Perform a partial restart (warm restart) of the outstation. DNP3 applications will be reset but not affect other processes. Sometimes, this may revert values to defaults or reset to a known configuration.
May leave the outstation in an unknown or invalid state
TCP
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} warm-restart
Linux (sh)
./dnp3-actions tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} warm-restart
Darwin (sh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} warm-restart
Facts:
| Name | Description | Type | Default |
|---|---|---|---|
dnp3.server.ip | IP address of the outstation | string | None |
dnp3.local.link | DNP3 link layer address of the local device | int | None |
dnp3.remote.link | DNP3 link layer address of the remote device | int | None |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
Serial
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} warm-restart
Linux (sh)
./dnp3-actions serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} warm-restart
Darwin (sh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} warm-restart
Facts:
| Name | Description | Type | Default |
|---|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string | |
dnp3.local.link | DNP3 link layer address of the local device | int | None |
dnp3.remote.link | DNP3 link layer address of the remote device | int | None |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
DNP3 - Disable Unsolicited Messages
Disable unsolicited messages on the outstation. May prevent clients connected to the outstation from receiving event data that would otherwise be self-reported by the outstation.
[Enable Unsolicited Messages](#dnp3---enable-unsolicited-messages) Ability
TCP
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} disable-unsolicited
Linux (sh)
./dnp3-actions tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} disable-unsolicited
Darwin (sh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} disable-unsolicited
Facts:
| Name | Description | Type | Default |
|---|---|---|---|
dnp3.server.ip | IP address of the outstation | string | None |
dnp3.local.link | DNP3 link layer address of the local device | int | None |
dnp3.remote.link | DNP3 link layer address of the remote device | int | None |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
--classes | space separated list of classes to disable | string | '1,2,3' |
Serial
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} disable-unsolicited
Linux (sh)
./dnp3-actions serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} disable-unsolicited
Darwin (sh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} disable-unsolicited
Facts:
| Name | Description | Type | Default |
|---|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string | |
dnp3.local.link | DNP3 link layer address of the local device | int | None |
dnp3.remote.link | DNP3 link layer address of the remote device | int | None |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
--classes | space separated list of classes to disable | string | '1,2,3' |
DNP3 - Enable Unsolicited Messages
Enable unsolicited messages on the outstation.
[Disable Unsolicited Messages](#dnp3---disable-unsolicited-messages) Ability
TCP
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} enable-unsolicited
Linux (sh)
./dnp3-actions tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} enable-unsolicited
Darwin (sh)
./dnp3-actions_darwin tcp #{dnp3.server.ip} #{dnp3.local.link} #{dnp3.remote.link} enable-unsolicited
Facts:
| Name | Description | Type | Default |
|---|---|---|---|
dnp3.server.ip | IP address of the outstation | string | None |
dnp3.local.link | DNP3 link layer address of the local device | int | None |
dnp3.remote.link | DNP3 link layer address of the remote device | int | None |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-p, --port | port number of the outstation | int | 20000 |
--classes | space separated list of classes to disable | string | '1,2,3' |
Serial
Ability Command:
Windows (cmd/psh)
.\dnp3-actions.exe serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} enable-unsolicited
Linux (sh)
./dnp3-actions serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} enable-unsolicited
Darwin (sh)
./dnp3-actions_darwin serial #{dnp3.server.serial_device} #{dnp3.local.link} #{dnp3.remote.link} enable-unsolicited
Facts:
| Name | Description | Type | Default |
|---|---|---|---|
dnp3.server.serial_device | Serial device name (e.g. COM1, /dev/ttyS0) | string | |
dnp3.local.link | DNP3 link layer address of the local device | int | None |
dnp3.remote.link | DNP3 link layer address of the remote device | int | None |
Optional Flags:
| Flag | Description | Type | Default |
|---|---|---|---|
-b,--baud | baud rate of the serial device | int | 9600 |
--databits | data bits | int | 8 |
--stopbits | stop bits, one of: 'One', 'OnePointFive', 'Two', 'None' | string | 'One' |
--parity | parity, one of: 'Even', 'Odd', 'None' | string | 'None' |
--flowtype | flow control setting, one of 'Hardware', 'XONXOFF', 'None' | string | 'None' |
--delay | delay time in milliseconds before first tx | int | 500 |
--classes | space separated list of classes to disable | string | '1,2,3' |
DNP3 Protocol Notes
Data Model
When reading data from a DNP3 outstation, the user must specify the 'Group' and
'Variation' to read. The 'Group' can be thought of as similar to a datatype (see
the table below for examples). Each Group has several 'Variations', which are
different ways in which a Group can be read. For example, Group 2 is 'Binary
Input Events', Variation 1 reads the data without a time value, while Variation
1 reads the data with absolute time. By default, this plugin requests all reads
with variation 0, indicating no preference of read type. The optional --variation
flag can be used to specify a particular variation.
| Group | Name |
|---|---|
| 1 | Binary Input |
| 2 | Binary Input Event |
| 3 | Double-bit Binary Input |
| 4 | Double-bit Binary Input Event |
| 10 | Binary Output |
| 11 | Binary Output Event |
| 12 | Binary Command |
| 13 | Binary Command Event |
| 20 | Counter |
| 21 | Frozen Counter |
| 22 | Counter Event |
| 23 | Frozen Counter Event |
| 30 | Analog Input |
| 32 | Analog Input Event |
| 40 | Analog Output Status |
| 41 | Analog Output |
| 42 | Analog Output Event |
| 43 | Analog Command Event |
| 50 | Time and Date |
| 51 | Time and Date CTO |
| 52 | Time Delay |
| 60 | Class Data |
| 70 | File-control |
| 80 | Internal Indications |
| 110 | Octet String |
| 111 | Octet String Event |
| 112 | Virtual Terminal Output Block |
| 113 | Virtual Terminal Event Data |
Control Models
There are two control philosophies in DNP3 (and this plugin): select-before-operate and direct operate. Using the select-before-operate procedure, the controlling station (the Caldera payload) must first send a SELECT message, indicating the intention to operate a point. This is followed by an OPERATE message to actually execute the operation. If the outstation is set for select-before-operate mode and receives an unexpected OPERATE message (one not preceded by a SELECT message), it will ignore the command. In the direct operate mode, the preceding SELECT message is not required.
The action of an OPERATE command is defined by its control relay output block (CROB). Control abilities in this plugin contain the necessary fact templates (arguments) to build a CROB. There are three control models that a outstation may implement and the CROB must be constructed according to the appropriate model. The models are:
- Activation model
- Complementary latch model
- Complementary two-output model
The activation model functions like a push-button, where a single virtual or physical output is linked to a specific event, such as "trip breaker" or "acknowledge alarm." Pressing the button triggers the associated event. These outputs are usually configured in pairs, with separate indices for actions like "trip breaker" and "close breaker." In this model, Control Relay Output Blocks (CROBs) typically use the 'PULSE_ON' operation type and the 'NUL' trip close code. Using the push-button analogy, 'PULSE_ON' represents the act of pressing the button, not the action itself. To trip a breaker, the operator sends a (NUL, PULSE_ON) CROB to the trip breaker index, and to close the breaker, a (NUL, PULSE_ON) CROB is sent to the close breaker index.
The complementary latch model operates like a light switch, where a single virtual or physical output remains in the on (active) or off (inactive) state based on the command it receives. This allows a single index to manage both on-off or enable-disable functions. This model is configured for the 'NUL' trip close code and uses 'LATCH_ON' and 'LATCH_OFF' operation types to activate or deactivate the output, respectively. It is generally used for simple controls, such as turning an indicator light on or off, rather than for controlling breakers.
The complementary two-output model consists of two virtual or physical outputs: a close and a trip output. Depending on the command received, one of these outputs is momentarily activated, allowing a breaker to be controlled from a single index. This model is configured for the 'TRIP' and 'CLOSE' trip close codes and uses the 'PULSE_ON' operation type. To trip a breaker, the operator sends a (TRIP, PULSE_ON) CROB to the breaker index, and to close the breaker, a (CLOSE, PULSE_ON) CROB is sent to the breaker index.
The CROB also contains on-time and off-time fields to set the time durations of the signal. These values are suggestions and may be overridden by the outstation.
Copyright Notice
As of September 2nd, 2022, the OpenDNP3 project was archived by the project owner. The latest and final release is 3.1.2 on April 22nd, 2022. The source may still be found on GitHub.
OpenDNP3 is (c) to Green Energy Corp (2010, 2011), Step Function I/O LLC (2013-2022, 2020-2022), and various contributors (2010-2022). Note that Automatak rebranded as Step Function I/O.
It is licensed under the terms of the Apache License 2.0, whose main condition requires "preservation of copyright and license notices."
The Caldera plugin is named "DNP3" as that is a short identifier of is purpose/scope. The plugin is not produced by Step Function I/O LLC.