@arnabm
on
dnp3 Parser and Simulator
What did you make?
I built a partial implementation of DNP3 in C, along with a TCP client/server simulator and an interactive packet parser.
DNP3 is a communication protocol used in SCADA systems, including power utilities and water management. It lets equipment at remote sites send measurements and status information to control centers.
The protocol is decades old and widely used, but finding detailed, freely available documentation was surprisingly difficult. My project implements a small subset of it so you can generate data, exchange packets between programs, and inspect what those packets contain.
Why was it challenging?
The hardest part was turning the protocolās packet layouts into working C code. DNP3 originated in serial communication, and carrying its frames over TCP meant handling the fact that one network read doesnāt necessarily equal one complete packet.
This was also my first big C project. Coming from Java, I had to get comfortable with pointers, manual memory handling, sockets, and the difference between a structās layout in memory and the bytes a protocol expects. Struct padding caused a lot more trouble than I expected š.
I also took a roughly two-month break. Returning to code Iād written while still learning C was a challenge of its own, especially where I hadnāt used consistent conventions or documented my decisions.
What are you proud of?
Mostly, that I stuck with it.
This project pushed me through problems that initially felt impossible and taught me how to break them down, investigate them, and keep going. I understand memory layout, byte order, networking, and C much better now than when I started.
Seeing the client request data, the server build a response, and the parser turn those bytes into readable fields made that work feel worth it.
What should people know before using it?
Read the README first! It explains how to build the programs, configure connections, and use the supported packet formats. This is a partial implementation, so it wonāt interpret every DNP3 packet.
For a quick demo:
- Start the server. Its default port is 48188.
- Choose Group 1, Variation 2 for binary values with flags, or Group 30, Variation 1 for analog values with flags. Use a small point range, such as 0ā7.
- Start the client, enter port 48188, and enter 0 as the address to use localhost.
- Copy a complete reply from the clientās output into the parser. Join the hex bytes into one line and leave out the surrounding log messages. (certain consoles will do this automatically hint hint vscode
- 23 devlogs
- 104h