Coverage Report

Created: 2023-01-17 06:15

/src/PcapPlusPlus/Packet++/header/IPSecLayer.h
Line
Count
Source (jump to first uncovered line)
1
#ifndef PACKETPP_IPSEC_LAYER
2
#define PACKETPP_IPSEC_LAYER
3
4
/// @file
5
6
#include "Layer.h"
7
8
/**
9
 * \namespace pcpp
10
 * \brief The main namespace for the PcapPlusPlus lib
11
 */
12
namespace pcpp
13
{
14
  /**
15
   * @struct ipsec_authentication_header
16
   * Represents IPSec AuthenticationHeader (AH) structure
17
   */
18
#pragma pack(push, 1)
19
  struct ipsec_authentication_header
20
  {
21
    /** Type of the next header */
22
    uint8_t nextHeader;
23
    /** The length of the Authentication Header in 4-octet units, minus 2 */
24
    uint8_t payloadLen;
25
    /** Reserved */
26
    uint16_t reserved;
27
    /** Security Parameters Index */
28
    uint32_t spi;
29
    /** Sequence Number */
30
    uint32_t sequenceNumber;
31
  };
32
#pragma pack(pop)
33
34
  /**
35
   * @struct ipsec_esp
36
   * Represents IPSec Encapsulating Security Payload (ESP) structure
37
   */
38
#pragma pack(push, 1)
39
  struct ipsec_esp
40
  {
41
    /** Security Parameters Index */
42
    uint32_t spi;
43
    /** Sequence Number */
44
    uint32_t sequenceNumber;
45
  };
46
#pragma pack(pop)
47
48
  /**
49
   * @class AuthenticationHeaderLayer
50
   * Represents an IPSec AuthenticationHeader (AH) layer
51
   */
52
  class AuthenticationHeaderLayer : public Layer
53
  {
54
  public:
55
     /** A constructor that creates the layer from an existing packet raw data
56
     * @param[in] data A pointer to the raw data
57
     * @param[in] dataLen Size of the data in bytes
58
     * @param[in] prevLayer A pointer to the previous layer
59
     * @param[in] packet A pointer to the Packet instance where layer will be stored in
60
     */
61
7.24k
    AuthenticationHeaderLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = AuthenticationHeader; }
62
63
    /**
64
     * Get a pointer to the raw AH header. Notice this points directly to the data, so every change will change the actual packet data
65
     * @return A pointer to the ipsec_authentication_header
66
     */
67
14.2k
    ipsec_authentication_header* getAHHeader() const { return (ipsec_authentication_header*)m_Data; }
68
69
    /**
70
     * @return The Security Parameters Index (SPI) field value
71
     */
72
    uint32_t getSPI() const;
73
74
    /**
75
     * @return The sequence number value
76
     */
77
    uint32_t getSequenceNumber() const;
78
79
    /**
80
     * @return The size of the Integrity Check Value (ICV)
81
     */
82
    size_t getICVLength() const;
83
84
    /**
85
     * @return A pointer to the raw data of the Integrity Check Value (ICV)
86
     */
87
    uint8_t* getICVBytes() const;
88
89
    /**
90
     * @return The value of the Integrity Check Value (ICV) as a hex string
91
     */
92
    std::string getICVHexStream() const;
93
94
    /**
95
     * A static method that validates the input data
96
     * @param[in] data The pointer to the beginning of a byte stream of a AuthenticationHeader layer
97
     * @param[in] dataLen The length of byte stream
98
     * @return True if the data is valid and can represent an AuthenticationHeader layer
99
     */
100
    static inline bool isDataValid(const uint8_t* data, size_t dataLen);
101
102
    // implement abstract methods
103
104
    /**
105
     * @return The size of the AH header
106
     */
107
7.24k
    size_t getHeaderLen() const { return 4*(getAHHeader()->payloadLen + 2); }
108
109
    /**
110
     * Currently identifies the following next layers: UdpLayer, TcpLayer, IPv4Layer, IPv6Layer and ESPLayer. Otherwise sets PayloadLayer
111
     */
112
    void parseNextLayer();
113
114
    /**
115
     * Does nothing for this layer
116
     */
117
0
    void computeCalculateFields() {}
118
119
    std::string toString() const;
120
121
7.24k
    OsiModelLayer getOsiModelLayer() const { return OsiModelNetworkLayer; }
122
123
  private:
124
    // this layer supports parsing only
125
0
    AuthenticationHeaderLayer() {}
126
  };
127
128
129
130
  /**
131
   * @class ESPLayer
132
   * Represents an IPSec Encapsulating Security Payload (ESP) layer
133
   */
134
  class ESPLayer : public Layer
135
  {
136
  public:
137
     /** A constructor that creates the layer from an existing packet raw data
138
     * @param[in] data A pointer to the raw data
139
     * @param[in] dataLen Size of the data in bytes
140
     * @param[in] prevLayer A pointer to the previous layer
141
     * @param[in] packet A pointer to the Packet instance where layer will be stored in
142
     */
143
1.38k
    ESPLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = ESP; }
144
145
0
    ipsec_esp* getESPHeader() const { return (ipsec_esp*)m_Data; }
146
147
    /**
148
     * @return The Security Parameters Index (SPI) field value
149
     */
150
    uint32_t getSPI() const;
151
152
    /**
153
     * @return The sequence number value
154
     */
155
    uint32_t getSequenceNumber() const;
156
157
    /**
158
     * A static method that validates the input data
159
     * @param[in] data The pointer to the beginning of a byte stream of a ESP layer
160
     * @param[in] dataLen The length of byte stream
161
     * @return True if the data is valid and can represent an ESP layer
162
     */
163
    static inline bool isDataValid(const uint8_t* data, size_t dataLen);
164
165
    // implement abstract methods
166
167
    /**
168
     * @return The size of the ESP header (8 bytes)
169
     */
170
1.38k
    size_t getHeaderLen() const { return sizeof(ipsec_esp); }
171
172
    /**
173
     * The payload of an ESP layer is encrypted, hence the next layer is always a generic payload (PayloadLayer)
174
     */
175
    void parseNextLayer();
176
177
    /**
178
     * Does nothing for this layer
179
     */
180
0
    void computeCalculateFields() {}
181
182
    std::string toString() const;
183
184
1.38k
    OsiModelLayer getOsiModelLayer() const { return OsiModelTransportLayer; }
185
186
  private:
187
    // this layer supports parsing only
188
0
    ESPLayer() {}
189
  };
190
191
192
  // implementation of inline methods
193
194
  bool AuthenticationHeaderLayer::isDataValid(const uint8_t* data, size_t dataLen)
195
9.54k
  {
196
9.54k
    if (dataLen < sizeof(ipsec_authentication_header))
197
674
      return false;
198
199
8.87k
    size_t payloadLen = 4 * (data[1] + 2);
200
8.87k
    if (payloadLen < sizeof(ipsec_authentication_header) || payloadLen > dataLen)
201
1.62k
      return false;
202
203
7.24k
    return true;
204
8.87k
  }
205
206
  bool ESPLayer::isDataValid(const uint8_t* data, size_t dataLen)
207
1.94k
  {
208
1.94k
    return dataLen >= sizeof(ipsec_esp);
209
1.94k
  }
210
}
211
212
#endif // PACKETPP_IPSEC_LAYER