Coverage Report

Created: 2024-02-25 06:29

/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
{
8
/**
9
 * @struct s7commhdr
10
 * Represents a S7COMM protocol header
11
 */
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
30
/**
31
 * @struct s7comm_ack_data_hdr
32
 * Represents a S7COMM protocol header with Ack-Data header
33
 */
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
44
  /**
45
   * @class S7CommParameter
46
   * Represents a S7COMM (S7 Communication) protocol Parameter
47
   */
48
  class S7CommParameter
49
  {
50
    friend class S7CommLayer;
51
52
    public:
53
0
    S7CommParameter() {}
54
55
0
    virtual ~S7CommParameter() {}
56
57
    /**
58
     * @return The data of the Parameter
59
     */
60
0
    uint8_t *getData() const { return m_Data; }
61
    /**
62
     * @return The length of the Parameter data
63
     */
64
0
    size_t getDataLength() const { return m_DataLen; }
65
66
    private:
67
0
    S7CommParameter(uint8_t *data, size_t dataLen) : m_Data(data), m_DataLen(dataLen) {}
68
    uint8_t *m_Data;
69
    size_t m_DataLen;
70
  };
71
  /**
72
   * @class S7CommLayer
73
   * Represents a S7COMM (S7 Communication) protocol
74
   */
75
  class S7CommLayer : public Layer
76
  {
77
  public:
78
    /**
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
     */
87
    S7CommLayer(uint8_t msgType, uint16_t pduRef, uint16_t paramLength, uint16_t dataLength, uint8_t errorClass = 0,
88
          uint8_t errorCode = 0);
89
90
    /**
91
     * A constructor that creates the layer from an existing packet raw data
92
     * @param[in] data A pointer to the raw data (will be casted to @ref s7commhdr)
93
     * @param[in] dataLen Size of the data in bytes
94
     * @param[in] prevLayer A pointer to the previous layer
95
     * @param[in] packet A pointer to the Packet instance where layer will be stored in
96
     */
97
    S7CommLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
98
      : Layer(data, dataLen, prevLayer, packet)
99
0
    {
100
0
      m_Protocol = S7COMM;
101
0
      m_Parameter = nullptr;
102
0
    }
103
104
    virtual ~S7CommLayer()
105
0
    {
106
0
      if (m_Parameter)
107
0
        delete m_Parameter;
108
0
    }
109
110
    /**
111
     * @return S7comm protocol id
112
     */
113
    uint8_t getProtocolId() const;
114
115
    /**
116
     * @return S7comm message type
117
     */
118
    uint8_t getMsgType() const;
119
120
    /**
121
     * @return S7comm PDU ref
122
     */
123
    uint16_t getPduRef() const;
124
125
    /**
126
     * @return S7comm parameter length
127
     */
128
    uint16_t getParamLength() const;
129
130
    /**
131
     * @return S7comm data length
132
     */
133
    uint16_t getDataLength() const;
134
135
    /**
136
     * @return S7comm error code
137
     */
138
    uint8_t getErrorCode() const;
139
140
    /**
141
     * @return S7comm error class
142
     */
143
    uint8_t getErrorClass() const;
144
145
    /**
146
     * @return S7comm parameter
147
     */
148
    const S7CommParameter *getParameter();
149
150
    /**
151
     * Set the value of the message type
152
     * @param[in] msgType The value of the message type
153
     */
154
    void setMsgType(uint8_t msgType) const;
155
156
    /**
157
     * Set the value of the PDU ref
158
     * @param[in] pduRef The value of the PDU ref
159
     */
160
    void setPduRef(uint16_t pduRef) const;
161
162
    /**
163
     * Set the value of the error code
164
     * @param[in] errorCode The value of the error code
165
     */
166
    void setErrorCode(uint8_t errorCode) const;
167
    /**
168
     * Set the value of the error class
169
     * @param[in] errorClass The value of the error class
170
     */
171
    void setErrorClass(uint8_t errorClass) const;
172
173
    /**
174
     * @return Size of S7CommLayer
175
     */
176
0
    size_t getHeaderLen() const override { return m_DataLen; }
177
178
    /**
179
     * Does nothing for this layer (S7CommLayer is always last)
180
     */
181
0
    void computeCalculateFields() override {}
182
183
    /**
184
     * Does nothing for this layer (S7CommLayer is always last)
185
     */
186
0
    void parseNextLayer() override {}
187
188
    /**
189
     * A static method that takes a byte array and detects whether it is a S7COMM
190
     * @param[in] data A byte array
191
     * @param[in] dataSize The byte array size (in bytes)
192
     * @return True if the data looks like a valid S7COMM layer
193
     */
194
    static bool isDataValid(const uint8_t *data, size_t dataSize);
195
196
    std::string toString() const override;
197
198
0
    OsiModelLayer getOsiModelLayer() const override { return OsiModelApplicationLayer; }
199
200
  private:
201
0
    s7commhdr *getS7commHeader() const { return (s7commhdr *)m_Data; }
202
203
    s7comm_ack_data_hdr *getS7commAckDataHeader() const
204
0
    {
205
0
      if (getS7commHeader()->msgType == 0x03)
206
0
      {
207
0
        return (s7comm_ack_data_hdr *)m_Data;
208
0
      }
209
0
      return nullptr;
210
0
    }
211
212
    size_t getS7commHeaderLength() const;
213
214
    S7CommParameter *m_Parameter;
215
  };
216
217
} // namespace pcpp