Coverage Report

Created: 2025-07-11 07:47

/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