You are browsing as a guest. Sign up (or log in) to start making projects!

arnabm

@arnabm

Joined June 8th, 2026

  • 14Devlogs
  • 1Projects
  • 0Ships
  • 0Votes
noob coder, wanna be ee
Open comments for this post

2h 33m 52s logged

Manual Packet Creation and More!

Just finished adding the ability to create a packet based on parameters rather than requiring a premade packet.

Manual Packets

Basicly, instead of needing something like ,

uint8_t input[] = { 
    0x05, 0x64, ...
};

dnp3p_st packet_s = mkPacket(input);

You can now just use a function and pass in parameters. Then, since this is just a fancy memory structure, a simple memcpy into an appropriately sized array will give you both! (The raw packet, and the structure)

uint8_t packet[30] = {0};

 // did some renaming, uses dnp3Lib for library funcs now
dnp3p_st packet_s = dnp3Lib_mkPacket_manual(1, 0, 30, 2, 0, 10);
// params are: destination, source, group, variation, startIndex, and stopIndex

memcpy(&packet, &packet_s, 30);

This will give you basicly the same thing as the first example, meaning you can create a packet based on a discription, rather than a discription based on a packet.

This will be very useful when creating responses from to the client from the server, or vice versa.

Should be noted that this is technically not very complete, but it is just an example for now.

Pre-made Packets

On the topic of creating a packet based on a discription, I also created some functions to create packets for common messages, including;

  • Reset Link
    • Required when creating a new connection
  • Acknowledgement
  • Negative Acknowledgment

These will be useful when making connections, and sending responses to requests and replies.

Wrap Up

Still got a ways to go in terms of completion, but I’m hoping to ramp up my speed, been a little busy the past couple weeks.

0
0
2
Open comments for this post

3h 11m 20s logged

Dev log 11?

I just pushed some changes and merged main and dev. This update I basically just made some fixes that should make the parser more accurate overall, but there are still a few lingering bugs.

The main change I made was adding a system to clean the packet of any CRC bytes from within. Normally, a packet contains 2 bytes of CRC spread around it, with 2 after the end of the header, and after that 2 after every 16 bytes.

This change will allow my data handler to not accidentally ingest CRC bytes, which would mess up the spacing of each data segment, and result in randomness.

I also added a function to calculate the size of a packet based on the length information stored within it, rather than the physical memory size of it. This is better, as I can call it from any function and not have to pass in the size as a param.

Overall, I am around 90% done with the backend, and just have a couple bugs to fix.

I have attached a screen shot of some of the new features.

0
0
1
Open comments for this post

1h 26m 14s logged

Added parsing for more Objects

Has not been very long but I am back with an update. I just finished adding in parsing for more object types, including

  • Group 1
    • Varriation 1
    • Varriation 2
  • Group 30
    • Varriation 1
    • Varriation 2

I’ll also try and make more frequent posts here!

0
0
3
Open comments for this post

9h 43m 5s logged

DNP3 Parser Update - Understanding a DNP3 Packet

This week I finished parsing DNP3 Group 1 Variation 1, the first object type supported by the parser. That means the parser can now decode binary input status values from real DNP3 traffic instead of just stopping at the object header.

I also got some practice using GDB to debug my programs! Super useful as I ran into some segmentation faults that would have been impossible to fix without it!

How a DNP3 Packet Works

DNP3 (Distributed Network Protocol 3) is an industrial control protocol used by electric utilities, water systems, and other critical infrastructure. Communication happens between a Master (SCADA server) and one or more Outstations (RTUs, relays, PLCs, etc.).

A packet is made up of several layers:

  1. Data Link Layer
  2. Transport Layer
  3. Application Header
  4. Object Header(s)
  5. Object Data

Data Link Layer

The packet always begins with the start bytes:

0x05 0x64

These identify the frame as DNP3.

The rest of the link header contains:

  • Length
  • Control byte
  • Destination address
  • Source address
  • CRC

This layer is responsible for moving frames between devices and detecting transmission errors.

Transport Layer

The transport header is only one byte long, but it’s important because it:

  • Marks the start and end of fragmented messages
  • Provides a sequence number so fragments can be reassembled

Application Layer

The application header tells the receiver what operation is being requested.

Examples include:

  • Read
  • Write
  • Response
  • Confirm

It also contains application control flags and an application sequence number.

Object Headers

After the application header come one or more object headers. These tell the parser what type of data follows.

An object header contains:

  • Group number
  • Variation number
  • Qualifier

For example:

Group 1 Variation 1

represents packed binary input values.

The qualifier then specifies how many objects are present and how they are indexed.

Object Data

Finally comes the actual payload.

For Group 1 Variation 1, each bit represents the current state of a binary input:

  • 1 = ON
  • 0 = OFF

The parser reads these bytes and expands them into individual points that can be displayed or analyzed.

Completed Sections

  • Data Link Layer parsing
  • Transport Header parsing
  • Application Header parsing
  • Object Header parsing
  • Group 1 Variation 1 object parsing

Next up is adding support for additional object groups and variations so the parser can decode more real-world DNP3 traffic.

0
0
1
Open comments for this post

6h 58m 5s logged

Transport Header, Printing Updates, and Bug Fixes!

Its once again that time. This week I worked on the object header, updated the printing on the DLC parsing, as well as fixing a couple big bugs.

Transport Header

The transport header consists of 5 parts, and its main job is to explains the format, and ordering of the data in the packet. Note that there are multiple object and data blocks in a single packet, but currently I can only parse 1 at most.

Bugs Fixed

Ran into a couple bugs, but I’ll just mention 2.

  1. When filling the range (part of the object header) I ran into some errors.

    • It turns out that I had forgoten to initilize the space with 0s, and that ment that if less than 8 bytes were assigned, there was garbage memory sitting in the space.
    • Fix was pretty easy, just zeroed out the space and then assigned the data
  2. Incorrect DLC data being printed.

    • Another strange bug, not really sure what was causing it
    • Fix was pretty simple, just rewrote the print statements (attached a picture)

Wrap Up

Thanks for enduring that yap fest. Next update will probably be when I add in data parsing, unless I make some major change.Hope you enjoyed it.
Check out the GitHub:

https://github.com/arnabmondal-eg/dnp3

And have a safe, fun, and patriotic Fourth of July!

0
0
3
Open comments for this post

6h 59m 16s logged

DNP3 Parser

I genuinely dont know how its been 7 hours. I feel like the majority of my time is fixing bugs and trying to get my code to compile.

Where I’ve Been

It’s been a while since my last devlog, and I have spent the past 7 hours adding a good bit. Main thing is that almost the entire packet is now being parsed, or atleast the hard part.

The entire header, dlc byte, transport header, and application header are parsed, so the only thing left is the Object headers and the data itself.

I also created a new struct to hold all of these functions, so you can just pass in a hex and get all this data out, no need to call each portions functionality anymore.

Whats Next

Moving forward, I have a couple goals/milestones I have to hit before I can ship this project:

  1. Parse the rest of the packet
  2. Check validity on entire packet (using CRC bytes)
  3. Finish Parser UI (almost done, but still some more to be done)
  4. Create Control/Main Station UI
  5. Create RTU/Secondary Station UI
  6. Link backend and frontend using network sockets
  7. Create systems for creating packets (I believe this will be much more difficult than parsing them)
  8. Simulate “Conversations” between the main and outstations
  9. Create binaries for Windows, Mac, and Linux
1
0
12
Open comments for this post

1h 17m 56s logged

Just did a little rework to move all header files to the inc/ folder. This should make it less cluttered, but we will see how this holds up.

Next things on the chopping block are:

  1. Implement Transport Header Parsing
  2. Implement Application Header Parsing
  3. Check all CRC bytes in entire packet

Check out the GitHub! https://github.com/arnabmondal-eg/dnp3

0
0
1
Open comments for this post

5h 38m 14s logged

Its been a while…

Hello! I have been working on the parser for a while. This post will be an explanation of where I am in the project so far.

I wouldn’t go as far as to say that I am close to done yet, but I’m definitely nearing the halfway point.

The past 2 days I have reworked how packets are interpreted, as well as adding some new helper utilities/functions to make future decoding easier. I also implemented a full bit-by-bit decomposition of the DLC byte in a header!

This was super fun and rewarding as I learned a lot about bit-wise operations in C, as well as strengthening my understand of memory and how it is transferred through a program.

I also learned I can’t spell! Wrote valid as “vaild” over 10 times! I also learned that C doesn’t pass the size of an array automatically! Super fun bugs! \s

Feel free to critique my code on the GitHub! https://github.com/arnabmondal-eg/dnp3

0
0
1
Open comments for this post

1h 20m 17s logged

Finished reworking the Parser UI. It uses a split pane so you can get as much or as little space as you need. Features a text input area on the left with a parse button on the bottom, and a tree view on the right (to see the parsed packet contents) with a valid indicator on the bottom.
Nothing is hooked up yet to logic, so that is coming up soon on the list!
Swing is definitely kind of tedious to write though!

Check out the github: https://github.com/arnabmondal-eg/dnp3

0
0
7
Open comments for this post

2h 32m 9s logged

Just finished writing the final portion of the header validity checker, which uses a brand new CRC byte calculator!

Very Fun to make, as I really got to dig deep into bit-wise operations for the first time, but definitely challenging!

In terms of the backend, there is still much to do, but I am getting close to completion. The frontend still is in rough shape however.

Making Good Progress!

0
0
10
Open comments for this post

1h 11m 40s logged

Improved project structure, worked on README, added tasks to make compiling easier.

Really want this to be usable, so I am putting in the work to make it simple to understand and use.

Also I hated writing this project tree. Leme know if there is some tool i can use to do this automatically in the future

0
0
9
Open comments for this post

1h 16m 12s logged

Working on the parser backend.
Currently planning for all the backend to be in C, while I handle the frontend in Java using Swing.

While this may seem like an ancient technology, most production SCADA applications use Swing for its long term support. And Java and C are obvious choices aswell.

Heres a pic of the header part of the interpreter, and some work in progress ui. Much more work to come!

0
0
9

Followers

Loading…