Coverage Report

Created: 2024-02-25 06:29

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