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