/src/PcapPlusPlus/Packet++/src/ModbusLayer.cpp
Line | Count | Source |
1 | | #include "ModbusLayer.h" |
2 | | #include "EndianPortable.h" |
3 | | #include <iostream> |
4 | | #include <iomanip> |
5 | | #include <cstring> |
6 | | #include "Logger.h" |
7 | | |
8 | | namespace pcpp |
9 | | { |
10 | | ModbusLayer::ModbusLayer(uint16_t transactionId, uint8_t unitId) |
11 | 0 | { |
12 | 0 | constexpr int16_t pduSize = sizeof(ModbusReadInputRegisters); // Currently only supporting Read Input Registers |
13 | 0 | constexpr size_t headerLen = sizeof(modbus_header); |
14 | |
|
15 | 0 | allocData(headerLen + pduSize); |
16 | | |
17 | | // Initialize the header fields to default values |
18 | 0 | modbus_header* header = getModbusHeader(); |
19 | 0 | header->transactionId = htobe16(transactionId); |
20 | 0 | header->protocolId = 0; // 0 for Modbus/TCP |
21 | 0 | header->length = htobe16(pduSize + 2); // Length includes unitId and functionCode |
22 | 0 | header->unitId = unitId; |
23 | 0 | header->functionCode = static_cast<uint8_t>(ModbusFunctionCode::ReadInputRegisters); |
24 | 0 | } |
25 | | |
26 | | modbus_header* ModbusLayer::getModbusHeader() const |
27 | 3.52k | { |
28 | 3.52k | return reinterpret_cast<modbus_header*>(m_Data); |
29 | 3.52k | } |
30 | | |
31 | | uint16_t ModbusLayer::getTransactionId() const |
32 | 704 | { |
33 | 704 | return be16toh(getModbusHeader()->transactionId); |
34 | 704 | } |
35 | | |
36 | | uint16_t ModbusLayer::getProtocolId() const |
37 | 704 | { |
38 | 704 | return be16toh(getModbusHeader()->protocolId); |
39 | 704 | } |
40 | | |
41 | | uint16_t ModbusLayer::getLength() const |
42 | 704 | { |
43 | 704 | return be16toh(getModbusHeader()->length); |
44 | 704 | } |
45 | | |
46 | | uint8_t ModbusLayer::getUnitId() const |
47 | 704 | { |
48 | 704 | return getModbusHeader()->unitId; |
49 | 704 | } |
50 | | |
51 | | ModbusLayer::ModbusFunctionCode ModbusLayer::getFunctionCode() const |
52 | 704 | { |
53 | 704 | switch (getModbusHeader()->functionCode) |
54 | 704 | { |
55 | 104 | case 1: |
56 | 104 | return ModbusFunctionCode::ReadCoils; |
57 | 0 | case 2: |
58 | 0 | return ModbusFunctionCode::ReadDiscreteInputs; |
59 | 290 | case 3: |
60 | 290 | return ModbusFunctionCode::ReadHoldingRegisters; |
61 | 0 | case 4: |
62 | 0 | return ModbusFunctionCode::ReadInputRegisters; |
63 | 0 | case 5: |
64 | 0 | return ModbusFunctionCode::WriteSingleCoil; |
65 | 50 | case 6: |
66 | 50 | return ModbusFunctionCode::WriteSingleHoldingRegister; |
67 | 0 | case 15: |
68 | 0 | return ModbusFunctionCode::WriteMultipleCoils; |
69 | 0 | case 16: |
70 | 0 | return ModbusFunctionCode::WriteMultipleHoldingRegisters; |
71 | 0 | case 17: |
72 | 0 | return ModbusFunctionCode::ReadSlaveId; |
73 | 260 | default: |
74 | 260 | return ModbusFunctionCode::UnknownFunction; |
75 | 704 | } |
76 | 704 | } |
77 | | |
78 | | void ModbusLayer::setTransactionId(uint16_t transactionId) |
79 | 0 | { |
80 | 0 | getModbusHeader()->transactionId = htobe16(transactionId); |
81 | 0 | } |
82 | | |
83 | | void ModbusLayer::setUnitId(uint8_t unitId) |
84 | 0 | { |
85 | 0 | getModbusHeader()->unitId = unitId; |
86 | 0 | } |
87 | | |
88 | | void ModbusLayer::setFunctionCode(ModbusLayer::ModbusFunctionCode functionCode) |
89 | 0 | { |
90 | 0 | getModbusHeader()->functionCode = static_cast<uint8_t>(functionCode); |
91 | 0 | } |
92 | | |
93 | | std::string ModbusLayer::toString() const |
94 | 704 | { |
95 | 704 | return "Modbus Layer, Transaction ID: " + std::to_string(getTransactionId()) + |
96 | 704 | ", Protocol ID: " + std::to_string(getProtocolId()) + ", Length: " + std::to_string(getLength()) + |
97 | 704 | ", Unit ID: " + std::to_string(getUnitId()) + |
98 | 704 | ", Function Code: " + std::to_string(static_cast<uint8_t>(getFunctionCode())); |
99 | 704 | } |
100 | | } // namespace pcpp |