/src/PcapPlusPlus/Packet++/header/S7CommLayer.h
Line | Count | Source |
1 | | #pragma once |
2 | | |
3 | | #include <memory> |
4 | | #include "EthLayer.h" |
5 | | #include "Layer.h" |
6 | | |
7 | | /// @namespace pcpp |
8 | | /// @brief The main namespace for the PcapPlusPlus lib |
9 | | namespace pcpp |
10 | | { |
11 | | /// @struct s7commhdr |
12 | | /// Represents a S7COMM protocol header |
13 | | #pragma pack(push, 1) |
14 | | typedef struct |
15 | | { |
16 | | /// protocol id |
17 | | uint8_t protocolId; |
18 | | /// message type |
19 | | uint8_t msgType; |
20 | | /// redundancy identification (reserved) |
21 | | uint16_t reserved; |
22 | | /// protocol data unit reference |
23 | | uint16_t pduRef; |
24 | | /// parameter length |
25 | | uint16_t paramLength; |
26 | | /// data length |
27 | | uint16_t dataLength; |
28 | | } s7commhdr; |
29 | | #pragma pack(pop) |
30 | | static_assert(sizeof(s7commhdr) == 10, "s7commhdr size is not 10 bytes"); |
31 | | |
32 | | /// @struct s7comm_ack_data_hdr |
33 | | /// Represents a S7COMM protocol header with Ack-Data header |
34 | | #pragma pack(push, 1) |
35 | | struct s7comm_ack_data_hdr : s7commhdr |
36 | | { |
37 | | /// error class |
38 | | uint8_t errorClass; |
39 | | /// error code |
40 | | uint8_t errorCode; |
41 | | }; |
42 | | #pragma pack(pop) |
43 | | static_assert(sizeof(s7comm_ack_data_hdr) == 12, "s7comm_ack_data_hdr size is not 12 bytes"); |
44 | | |
45 | | /// @class S7CommParameter |
46 | | /// Represents a S7COMM (S7 Communication) protocol Parameter |
47 | | class S7CommParameter |
48 | | { |
49 | | friend class S7CommLayer; |
50 | | |
51 | | public: |
52 | | S7CommParameter() |
53 | 0 | {} |
54 | | |
55 | 0 | virtual ~S7CommParameter() = default; |
56 | | |
57 | | /// @return The data of the Parameter |
58 | | uint8_t* getData() const |
59 | 0 | { |
60 | 0 | return m_Data; |
61 | 0 | } |
62 | | /// @return The length of the Parameter data |
63 | | size_t getDataLength() const |
64 | 0 | { |
65 | 0 | return m_DataLen; |
66 | 0 | } |
67 | | |
68 | | private: |
69 | 0 | S7CommParameter(uint8_t* data, size_t dataLen) : m_Data(data), m_DataLen(dataLen) |
70 | 0 | {} |
71 | | uint8_t* m_Data; |
72 | | size_t m_DataLen; |
73 | | }; |
74 | | /// @class S7CommLayer |
75 | | /// Represents a S7COMM (S7 Communication) protocol |
76 | | class S7CommLayer : public Layer |
77 | | { |
78 | | public: |
79 | | /// A constructor that allocates a new S7comm header |
80 | | /// @param[in] msgType The general type of the message |
81 | | /// @param[in] pduRef Link responses to their requests |
82 | | /// @param[in] paramLength The length of the parameter field |
83 | | /// @param[in] dataLength The length of the data field |
84 | | /// @param[in] errorClass The value of the error class |
85 | | /// @param[in] errorCode The value of the error code |
86 | | S7CommLayer(uint8_t msgType, uint16_t pduRef, uint16_t paramLength, uint16_t dataLength, uint8_t errorClass = 0, |
87 | | uint8_t errorCode = 0); |
88 | | |
89 | | /// A constructor that creates the layer from an existing packet raw data |
90 | | /// @param[in] data A pointer to the raw data (will be casted to @ref s7commhdr) |
91 | | /// @param[in] dataLen Size of the data in bytes |
92 | | /// @param[in] prevLayer A pointer to the previous layer |
93 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
94 | | S7CommLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
95 | 9.42k | : Layer(data, dataLen, prevLayer, packet, S7COMM) |
96 | 9.42k | {} |
97 | | |
98 | 9.42k | ~S7CommLayer() override = default; |
99 | | |
100 | | /// @return S7comm protocol id |
101 | | uint8_t getProtocolId() const; |
102 | | |
103 | | /// @return S7comm message type |
104 | | uint8_t getMsgType() const; |
105 | | |
106 | | /// @return S7comm PDU ref |
107 | | uint16_t getPduRef() const; |
108 | | |
109 | | /// @return S7comm parameter length |
110 | | uint16_t getParamLength() const; |
111 | | |
112 | | /// @return S7comm data length |
113 | | uint16_t getDataLength() const; |
114 | | |
115 | | /// @return S7comm error code |
116 | | uint8_t getErrorCode() const; |
117 | | |
118 | | /// @return S7comm error class |
119 | | uint8_t getErrorClass() const; |
120 | | |
121 | | /// @return S7comm parameter |
122 | | const S7CommParameter* getParameter(); |
123 | | |
124 | | /// Set the value of the message type |
125 | | /// @param[in] msgType The value of the message type |
126 | | void setMsgType(uint8_t msgType) const; |
127 | | |
128 | | /// Set the value of the PDU ref |
129 | | /// @param[in] pduRef The value of the PDU ref |
130 | | void setPduRef(uint16_t pduRef) const; |
131 | | |
132 | | /// Set the value of the error code |
133 | | /// @param[in] errorCode The value of the error code |
134 | | void setErrorCode(uint8_t errorCode) const; |
135 | | /// Set the value of the error class |
136 | | /// @param[in] errorClass The value of the error class |
137 | | void setErrorClass(uint8_t errorClass) const; |
138 | | |
139 | | /// @return Size of S7CommLayer |
140 | | size_t getHeaderLen() const override |
141 | 1.29k | { |
142 | 1.29k | return m_DataLen; |
143 | 1.29k | } |
144 | | |
145 | | /// Does nothing for this layer (S7CommLayer is always last) |
146 | | void computeCalculateFields() override |
147 | 1.29k | {} |
148 | | |
149 | | /// Does nothing for this layer (S7CommLayer is always last) |
150 | | void parseNextLayer() override |
151 | 9.42k | {} |
152 | | |
153 | | /// A static method that takes a byte array and detects whether it is a S7COMM |
154 | | /// @param[in] data A byte array |
155 | | /// @param[in] dataSize The byte array size (in bytes) |
156 | | /// @return True if the data looks like a valid S7COMM layer |
157 | | static bool isDataValid(const uint8_t* data, size_t dataSize); |
158 | | |
159 | | std::string toString() const override; |
160 | | |
161 | | OsiModelLayer getOsiModelLayer() const override |
162 | 1.29k | { |
163 | 1.29k | return OsiModelApplicationLayer; |
164 | 1.29k | } |
165 | | |
166 | | private: |
167 | | s7commhdr* getS7commHeader() const |
168 | 2.58k | { |
169 | 2.58k | return reinterpret_cast<s7commhdr*>(m_Data); |
170 | 2.58k | } |
171 | | |
172 | | s7comm_ack_data_hdr* getS7commAckDataHeader() const |
173 | 0 | { |
174 | 0 | if (getS7commHeader()->msgType == 0x03) |
175 | 0 | { |
176 | 0 | return reinterpret_cast<s7comm_ack_data_hdr*>(m_Data); |
177 | 0 | } |
178 | 0 | return nullptr; |
179 | 0 | } |
180 | | |
181 | | size_t getS7commHeaderLength() const; |
182 | | |
183 | | std::unique_ptr<S7CommParameter> m_Parameter; |
184 | | }; |
185 | | |
186 | | } // namespace pcpp |