Skip to content

v0.2.0: DNP3 Implementation

Choose a tag to compare

@MatrixEditor MatrixEditor released this 29 Aug 21:48
· 25 commits to master since this release

This release includes an almost complete implementation of the DNP3.0 object standard library and a sample implementation of a Master realized more or less as a client. Its interface is designed to be simple, yet effective:

from icspacket.proto.dnp3.master import DNP3_Master
from icspacket.proto.dnp3.const import FunctionCode
from icspacket.proto.dnp3.objects.util import new_class_data_request
from icspacket.proto.dnp3.objects.coding import unpack_objects

# 1. Create a new master (client) - must include the local link address
master = DNP3_Master(link_addr=0x0001)

# 2. Associate (connect) with the remote peer - must provide the remote link address
remote_link_addr = 1024
master.associate((remote_link_addr, "127.0.0.1", 20000))

# 3. Create a READ request and block until a response is received
objects = new_class_data_request(1, 2, 3)
apdu = master.request(FunctionCode.READ, objects)

# 4. decode objects using standard library - the result will be a mapping
#    of DNP3Objects[group][variation] -> DNP3ObjectVariations
objects = unpack_objects(apdu.objects)

This release also includes a new script dnp3dump.py that can display object data within DNP3 packets:

$ dnp3dump.py -apdu "c68100001e01000000010000000028030000000100000000"
 [I] Parsed RESPONSE (129) APDU (FIR, FIN), SEQ: 6
 [I] No Internal Indications (IIN)
 Data Objects:
 ├── Object(s): Analog input (Obj: 30, Var: 1) [Range: 0-1]
 │   └── 32-bit with flag [0]:
 │       ├── comm_lost: False
 │       ├── local_forced: False
 │       ├── online: True
 │       ├── over_range: False
 │       ├── reference_err: False
 │       ├── remote_forced: False
 │       ├── reserved0: False
 │       ├── restart: False
 │       └── value: 0
 └── Object(s): Analog output status (Obj: 40, Var: 3) [Range: 0-1]
     └── single-precision, floating-point with flag [0]:
         ├── comm_lost: False
         ├── local_forced: False
         ├── online: True
         ├── over_range: False
         ├── reference_err: False
         ├── remote_forced: False
         ├── reserved0: False
         ├── restart: False
         └── value: 0.0

Some Fixes

  • hexdump() now respects the width for all parts
  • Add IEC61850 ASN.1 sources to package and enable compilation

Full Changelog: v0.1.0...v0.2.0