Skip to content

Conversation

yahyayozo
Copy link
Contributor

  • Add ModbusLayer first implementation with header parsing only (no test included)

@yahyayozo yahyayozo requested a review from seladb as a code owner May 18, 2025 18:15
@yahyayozo yahyayozo marked this pull request as draft May 18, 2025 18:16
Copy link

codecov bot commented May 18, 2025

Codecov Report

❌ Patch coverage is 91.86992% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.47%. Comparing base (699f7b0) to head (e3461d0).
⚠️ Report is 6 commits behind head on dev.

Files with missing lines Patch % Lines
Packet++/src/ModbusLayer.cpp 88.05% 8 Missing ⚠️
Packet++/header/ModbusLayer.h 90.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1823      +/-   ##
==========================================
- Coverage   83.47%   83.47%   -0.01%     
==========================================
  Files         298      304       +6     
  Lines       53945    54152     +207     
  Branches    11705    12013     +308     
==========================================
+ Hits        45029    45201     +172     
- Misses       7709     7735      +26     
- Partials     1207     1216       +9     
Flag Coverage Δ
alpine320 75.45% <93.33%> (+0.02%) ⬆️
fedora42 75.60% <93.44%> (+0.06%) ⬆️
macos-13 81.67% <89.10%> (+<0.01%) ⬆️
macos-14 81.67% <89.10%> (+<0.01%) ⬆️
macos-15 81.67% <89.10%> (+<0.01%) ⬆️
mingw32 70.29% <78.72%> (-0.01%) ⬇️
mingw64 70.27% <78.72%> (-0.02%) ⬇️
rhel94 75.30% <93.44%> (+0.02%) ⬆️
ubuntu2004 59.24% <76.56%> (+0.03%) ⬆️
ubuntu2004-zstd 59.36% <76.56%> (+0.05%) ⬆️
ubuntu2204 75.23% <93.44%> (-0.01%) ⬇️
ubuntu2204-icpx 60.93% <70.58%> (+0.04%) ⬆️
ubuntu2404 75.50% <93.44%> (+0.03%) ⬆️
ubuntu2404-arm64 75.47% <93.44%> (+0.02%) ⬆️
unittest 83.47% <91.86%> (-0.01%) ⬇️
windows-2022 85.49% <86.95%> (+0.01%) ⬆️
windows-2025 85.51% <86.95%> (+0.01%) ⬆️
winpcap 85.51% <86.95%> (+0.01%) ⬆️
xdp 53.09% <93.44%> (+0.12%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Dimi1010 Dimi1010 linked an issue May 19, 2025 that may be closed by this pull request
@yahyayozo yahyayozo marked this pull request as ready for review May 21, 2025 20:13
@yahyayozo
Copy link
Contributor Author

yahyayozo commented May 21, 2025

@seladb I've prepared only 1 constructor which initiates the layer with default fields values
Can you please mention what are the other constructors I need to implement? also please mention if I need to follow on other protocols layers?

@seladb
Copy link
Owner

seladb commented May 22, 2025

@yahyayozo we usually have at least 2 c'tors, sometimes more:

  1. As part of the packet parsing flow. For example:
    MplsLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
    which is used here (and in some other places also):
    m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet);
  2. When the user wants to create a new layer of this type. This is the c'tor you already implemented, but usually we don't implement (only) c'tors with zero arguments. We tend to implement c'tors that allow the user to build the layer. In your case, I'd add arguments like transactionId, unitId and functionCode

@yahyayozo
Copy link
Contributor Author

Hi @seladb can you please guide me briefly on how to add tests for my ModbusLayer for parsing/crafting headers? As I want to pass to function types request/response after testing the header part.

@seladb
Copy link
Owner

seladb commented May 25, 2025

@yahyayozo sure! You can learn about tests here: https://pcapplusplus.github.io/docs/tests

At a high level:

  • You should add your tests under Tests/Packet++Test/Tests (don't forget to add your .cpp file to CMakeFiles.txt)
  • The tests use a homegrown testing framework. A test case is PTF_TEST_CASE. You can write 3 of those: for parsing, crafting, and editing
  • You can find the possible assertions here, the most common one is PTF_ASSERT_EQUAL(actual, expected)
  • You need to add your test cases to https://github.com/seladb/PcapPlusPlus/blob/master/Tests/Packet%2B%2BTest/main.cpp and add a PTF_RUN_TEST for each test case
  • When you build the tests, you should run them from the Tests/Packet++Test directory, like this: Bin/Packet++Test -t <YOUR_TEST_CASE>

Please look at similar tests that were written for other layers and follow the same patterns.

Please let me know if you have any questions.

@yahyayozo
Copy link
Contributor Author

@seladb I'll add tests for the headers crafting/parsing implementation and then you can a review before we move to adding the different PDU types

@yahyayozo yahyayozo marked this pull request as draft May 28, 2025 22:00
@yahyayozo
Copy link
Contributor Author

@seladb @Dimi1010 I've started adding some tests, but I have a question regarding the ".dat" files; how can I generate examples for some Modbus frames?

@seladb
Copy link
Owner

seladb commented Jun 2, 2025

@seladb @Dimi1010 I've started adding some tests, but I have a question regarding the ".dat" files; how can I generate examples for some Modbus frames?

If you open the file in Wireshark, you can choose a packet and right click -> Copy -> ... as a Hex Stream:

image

@seladb
Copy link
Owner

seladb commented Aug 12, 2025

@yahyayozo the tests fail in CI...

@yahyayozo
Copy link
Contributor Author

@seladb should be fixed now

{
ModbusLayer::ModbusLayer(uint16_t transactionId, uint8_t unitId, ModbusLayer::ModbusFunctionCode functionCode)
{
const int16_t pduSize = getFunctionDataSize(functionCode);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see that getFunctionDataSize() currently supports only one function code, which is ModbusFunctionCode::READ_INPUT_REGISTERS. In that case, maybe we can remove the functionCode parameter, remove the getFunctionDataSize() method, and set the function code in this constructor to be ModbusFunctionCode::READ_INPUT_REGISTERS

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment wasn't addressed

Comment on lines +80 to +86
/// @struct ModbusReadInputRegisters
/// Represents a Modbus request to read input registers.
struct ModbusReadInputRegisters
{
uint16_t startingAddress; ///< Starting address of the input registers to read
uint16_t quantity; ///< Number of input registers to read
};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This struct is only used in getFunctionDataSize(). If we remove it we can remove this struct as well

{
ModbusLayer::ModbusLayer(uint16_t transactionId, uint8_t unitId, ModbusLayer::ModbusFunctionCode functionCode)
{
const int16_t pduSize = getFunctionDataSize(functionCode);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment wasn't addressed

@seladb
Copy link
Owner

seladb commented Aug 20, 2025

@seladb
Copy link
Owner

seladb commented Aug 23, 2025

@yahyayozo I think the only comments left are:

Once you address those I think we can merge this PR

@yahyayozo
Copy link
Contributor Author

@seladb all the comments shall be addressed now
I kept the ModbusReadInputRegisters struct because I use in the constructor and also to keep it as an example for the future implementation of other functions Codes

@yahyayozo
Copy link
Contributor Author

@seladb can you please check why it shows forbid submodules in the failed pre-commit?

@Dimi1010
Copy link
Collaborator

@seladb can you please check why it shows forbid submodules in the failed pre-commit?

a7b926d this commit adds deps/benchmark-src to the repo. I think this is a mistake.

@yahyayozo
Copy link
Contributor Author

@seladb @Dimi1010 I removed it
I don't know how it was added as a submodule!!

@seladb seladb merged commit 8e44878 into seladb:dev Aug 26, 2025
42 checks passed
@seladb
Copy link
Owner

seladb commented Aug 26, 2025

@yahyayozo thank you so much for working on this and contributing to PcapPlusPlus, it is much appreciated! 🙏

@yahyayozo
Copy link
Contributor Author

@seladb so, the other PDUs types will added in another PR?

@Dimi1010
Copy link
Collaborator

Yes, it's easier to review that way as it results in smaller differential changes in PRs.

@seladb
Copy link
Owner

seladb commented Aug 26, 2025

Yes, it's easier to review that way as it results in smaller differential changes in PRs.

Yes I agree. Smaller PRs are always better and easier to review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Modbus Protocol Support
3 participants