/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 |