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