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