/src/PcapPlusPlus/Packet++/header/VrrpLayer.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include "Layer.h" |
4 | | #include "IpAddress.h" |
5 | | #include <vector> |
6 | | |
7 | | /// @file |
8 | | |
9 | | /** |
10 | | * \namespace pcpp |
11 | | * \brief The main namespace for the PcapPlusPlus lib |
12 | | */ |
13 | | namespace pcpp |
14 | | { |
15 | | /** |
16 | | For more info see: |
17 | | https://datatracker.ietf.org/doc/html/rfc2338 |
18 | | https://datatracker.ietf.org/doc/html/rfc3768 |
19 | | https://datatracker.ietf.org/doc/html/rfc5798 |
20 | | */ |
21 | | |
22 | | /* VRRPv2 Packet Format |
23 | | 0 1 2 3 |
24 | | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
25 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
26 | | |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| |
27 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
28 | | | Auth Type | Adver Int | Checksum | |
29 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
30 | | | IP Address (1) | |
31 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
32 | | | . | |
33 | | | . | |
34 | | | . | |
35 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
36 | | | IP Address (n) | |
37 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
38 | | | Authentication Data (1) | |
39 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
40 | | | Authentication Data (2) | |
41 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
42 | | */ |
43 | | |
44 | | /* VRRPv3 Packet Format |
45 | | 0 1 2 3 |
46 | | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
47 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
48 | | | IPv4 Fields or IPv6 Fields | |
49 | | ... ... |
50 | | | | |
51 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
52 | | |Version| Type | Virtual Rtr ID| Priority |Count IPvX Addr| |
53 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
54 | | |(rsvd) | Max Adver Int | Checksum | |
55 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
56 | | | | |
57 | | + + |
58 | | | IPvX Address(es) | |
59 | | + + |
60 | | + + |
61 | | + + |
62 | | + + |
63 | | | | |
64 | | + + |
65 | | | | |
66 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
67 | | */ |
68 | | |
69 | | /** |
70 | | * @struct vrrp_header |
71 | | * VRRP generic header |
72 | | */ |
73 | | struct vrrp_header |
74 | | { |
75 | | #if (BYTE_ORDER == LITTLE_ENDIAN) |
76 | | /** Type */ |
77 | | uint8_t type: 4, |
78 | | |
79 | | /** Version bits */ |
80 | | version: 4; |
81 | | #else |
82 | | /** Version bits */ |
83 | | uint8_t version:4, |
84 | | |
85 | | /** Type */ |
86 | | type: 4; |
87 | | #endif |
88 | | /** The Virtual Router Identifier (VRID) field identifies the virtual router this packet is reporting status for*/ |
89 | | uint8_t vrId; |
90 | | |
91 | | /** This specifies the sending VRRP router's priority for the virtual router */ |
92 | | uint8_t priority; |
93 | | |
94 | | /** Specifies how many IPvX addresses are present in this Packet */ |
95 | | uint8_t ipAddrCount; |
96 | | |
97 | | /** This specifies authentication type(v2) or (Max) Advertisement interval (in seconds(v2) or centi-seconds(v3)). */ |
98 | | uint16_t authTypeAdvInt; |
99 | | |
100 | | /** This specifies checksum field that is used to detect data corruption in the VRRP message. |
101 | | * VRRPv2 uses normal checksum algorithm, while VRRPv3 uses "pseudo-header" checksum algorithm. */ |
102 | | uint16_t checksum; |
103 | | |
104 | | /** This specifies one or more IPvX addresses that are associated with the virtual router. */ |
105 | | uint8_t *ipAddresses[]; |
106 | | }; |
107 | | |
108 | | /** |
109 | | * @class VrrpLayer |
110 | | * A base class for all VRRP (Virtual Router Redundancy Protocol) protocol classes. This is an abstract class and cannot be instantiated, |
111 | | * only its child classes can be instantiated. The inherited classes represent the different versions of the protocol: |
112 | | * VRRPv2 and VRRPv3 |
113 | | */ |
114 | | class VrrpLayer : public Layer |
115 | | { |
116 | | private: |
117 | | bool addIPAddressesAt(const std::vector<IPAddress> &ipAddresses, int offset); |
118 | | |
119 | | uint8_t getIPAddressLen() const; |
120 | | |
121 | | bool isIPAddressValid(IPAddress &ipAddress) const; |
122 | | |
123 | | uint8_t* getFirstIPAddressPtr() const; |
124 | | |
125 | | uint8_t* getNextIPAddressPtr(uint8_t* ipAddressPtr) const; |
126 | | |
127 | | IPAddress getIPAddressFromData(uint8_t *data) const; |
128 | | |
129 | | void copyIPAddressToData(uint8_t *data, const IPAddress &ipAddress) const; |
130 | | |
131 | | IPAddress::AddressType m_AddressType; |
132 | | |
133 | | protected: |
134 | | VrrpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet, ProtocolType vrrpVer, |
135 | | IPAddress::AddressType addressType) |
136 | | : Layer(data, dataLen, prevLayer, packet), m_AddressType(addressType) |
137 | 13.4k | { |
138 | 13.4k | m_Protocol = vrrpVer; |
139 | 13.4k | } |
140 | | |
141 | | explicit VrrpLayer(ProtocolType subProtocol, uint8_t virtualRouterId, uint8_t priority); |
142 | | |
143 | 48.3k | vrrp_header *getVrrpHeader() const { return (vrrp_header *) m_Data; } |
144 | | |
145 | | void setAddressType(IPAddress::AddressType addressType); |
146 | | |
147 | | public: |
148 | | /** |
149 | | * VRRP message types |
150 | | */ |
151 | | enum VrrpType |
152 | | { |
153 | | /** Unknown VRRP message */ |
154 | | VrrpType_Unknown = 0, |
155 | | |
156 | | /** VRRP advertisement message */ |
157 | | VrrpType_Advertisement = 1 |
158 | | }; |
159 | | |
160 | | /** |
161 | | * An enum describing VRRP special priority values |
162 | | */ |
163 | | enum VrrpPriority |
164 | | { |
165 | | /** Default priority for a backup VRRP router (value of 100) */ |
166 | | Default, |
167 | | /** Current Master has stopped participating in VRRP (value of 0) */ |
168 | | Stop, |
169 | | /** This VRRP router owns the virtual router's IP address(es) (value of 255) */ |
170 | | Owner, |
171 | | /** Other priority */ |
172 | | Other |
173 | | }; |
174 | | |
175 | 0 | virtual ~VrrpLayer() {} |
176 | | |
177 | | /** |
178 | | * @return The VRRP IP Address type |
179 | | */ |
180 | | IPAddress::AddressType getAddressType() const; |
181 | | |
182 | | /** |
183 | | * A static method that validates the input data |
184 | | * @param[in] data VRRP raw data (byte stream) |
185 | | * @param[in] dataLen The length of the byte stream |
186 | | * @return One of the values ::VRRPv2, ::VRRPv3 according to detected VRRP version or ::UnknownProtocol if couldn't detect |
187 | | * VRRP version |
188 | | */ |
189 | | static ProtocolType getVersionFromData(uint8_t *data, size_t dataLen); |
190 | | |
191 | | /** |
192 | | * @return VRRP version of this message |
193 | | */ |
194 | | uint8_t getVersion() const; |
195 | | |
196 | | /** |
197 | | * @return VRRP type set in vrrp_header#type as VrrpLayer::VrrpType enum. |
198 | | */ |
199 | | VrrpType getType() const; |
200 | | |
201 | | /** |
202 | | * @return The virtual router id (vrId) in this message |
203 | | */ |
204 | | uint8_t getVirtualRouterID() const; |
205 | | |
206 | | /** |
207 | | * Set the virtual router ID |
208 | | * @param virtualRouterID new ID to set |
209 | | */ |
210 | | void setVirtualRouterID(uint8_t virtualRouterID); |
211 | | |
212 | | /** |
213 | | * @return The priority in this message |
214 | | */ |
215 | | uint8_t getPriority() const; |
216 | | |
217 | | /** |
218 | | * @return An enum describing VRRP priority |
219 | | */ |
220 | | VrrpPriority getPriorityAsEnum() const; |
221 | | |
222 | | /** |
223 | | * Set the priority |
224 | | * @param priority new priority to set |
225 | | */ |
226 | | void setPriority(uint8_t priority); |
227 | | |
228 | | /** |
229 | | * @return VRRP checksum of this message |
230 | | */ |
231 | | uint16_t getChecksum() const; |
232 | | |
233 | | /** |
234 | | * Fill the checksum from header and data and write the result to @ref vrrp_header#checksum |
235 | | */ |
236 | | void calculateAndSetChecksum(); |
237 | | |
238 | | /** |
239 | | * Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum |
240 | | * @return The checksum result |
241 | | */ |
242 | | virtual uint16_t calculateChecksum() const = 0; |
243 | | |
244 | | /** |
245 | | * @return True if VRRP checksum is correct |
246 | | */ |
247 | | bool isChecksumCorrect() const; |
248 | | |
249 | | /** |
250 | | * @return The count of VRRP virtual IP addresses in this message |
251 | | */ |
252 | | uint8_t getIPAddressesCount() const; |
253 | | |
254 | | /** |
255 | | * @return A list of the virtual IP addresses in this message |
256 | | */ |
257 | | std::vector<IPAddress> getIPAddresses() const; |
258 | | |
259 | | /** |
260 | | * Add a list of virtual IP addresses at a the end of the virtual IP address list. The vrrp_header#ipAddressCount field will be |
261 | | * incremented accordingly |
262 | | * @param[in] ipAddresses A vector containing all the virtual IP address |
263 | | * @return true if added successfully, false otherwise |
264 | | */ |
265 | | bool addIPAddresses(const std::vector<IPAddress> &ipAddresses); |
266 | | |
267 | | /** |
268 | | * Add a virtual IP address at a the end of the virtual IP address list. The vrrp_header#ipAddressCount field will be |
269 | | * incremented accordingly |
270 | | * @param[in] ipAddress Virtual IP address to add |
271 | | * @return true if add successfully, false otherwise |
272 | | */ |
273 | | bool addIPAddress(const IPAddress &ipAddress); |
274 | | |
275 | | /** |
276 | | * Remove a virtual IP address at a certain index. The vrrp_header#ipAddressCount field will be decremented accordingly |
277 | | * @param[in] index The index of the virtual IP address to be removed |
278 | | * @return True if virtual IP address was removed successfully or false otherwise. If false is returned an appropriate error message |
279 | | * will be printed to log |
280 | | */ |
281 | | bool removeIPAddressAtIndex(int index); |
282 | | |
283 | | /** |
284 | | * Remove all virtual IP addresses in the message. The vrrp_header#ipAddressCount field will be set to 0 |
285 | | * @return True if virtual IP addresses were cleared successfully or false otherwise. If false is returned an appropriate error message |
286 | | * will be printed to log |
287 | | */ |
288 | | bool removeAllIPAddresses(); |
289 | | |
290 | | // implement abstract methods |
291 | | |
292 | | /** |
293 | | * Does nothing for this layer (VRRP layer is always last) |
294 | | */ |
295 | 13.4k | void parseNextLayer() override {} |
296 | | |
297 | | /** |
298 | | * Calculate the VRRP checksum |
299 | | */ |
300 | | void computeCalculateFields() override; |
301 | | |
302 | | /** |
303 | | * @return The message size in bytes which include the size of the basic header + the size of the IP address(es) |
304 | | */ |
305 | 14.7k | size_t getHeaderLen() const override { return m_DataLen; } |
306 | | |
307 | | std::string toString() const override; |
308 | | |
309 | 3.16k | OsiModelLayer getOsiModelLayer() const override { return OsiModelNetworkLayer; } |
310 | | }; |
311 | | |
312 | | /** |
313 | | * @class VrrpV2Layer |
314 | | * Represents VRRPv2 (Virtual Router Redundancy Protocol ver 2) layer. This class represents all the different messages of VRRPv2 |
315 | | */ |
316 | | class VrrpV2Layer : public VrrpLayer |
317 | | { |
318 | | private: |
319 | | struct vrrpv2_auth_adv |
320 | | { |
321 | | uint8_t authType; |
322 | | uint8_t advInt; |
323 | | }; |
324 | | |
325 | | public: |
326 | | /** |
327 | | * VRRP v2 authentication types |
328 | | */ |
329 | | enum class VrrpAuthType : uint8_t |
330 | | { |
331 | | /** No Authentication */ |
332 | | NoAuthentication = 0, |
333 | | /** Simple Text Password */ |
334 | | SimpleTextPassword = 1, |
335 | | /** IP Authentication Header */ |
336 | | IPAuthenticationHeader = 2, |
337 | | /** Cisco VRRP MD5 Authentication */ |
338 | | MD5 = 3, |
339 | | /** Other/Unknown Authentication Type */ |
340 | | Other = 4 |
341 | | }; |
342 | | |
343 | | /** A constructor that creates the layer from an existing packet raw data |
344 | | * @param[in] data A pointer to the raw data |
345 | | * @param[in] dataLen Size of the data in bytes |
346 | | * @param[in] prevLayer A pointer to the previous layer |
347 | | * @param[in] packet A pointer to the Packet instance where layer will be stored in |
348 | | */ |
349 | | VrrpV2Layer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet) |
350 | 3.28k | : VrrpLayer(data, dataLen, prevLayer, packet, VRRPv2, IPAddress::IPv4AddressType) {} |
351 | | |
352 | | /** |
353 | | * A constructor that allocates a new VRRP v2 layer |
354 | | * @param virtualRouterId Virtual router ID |
355 | | * @param priority Priority |
356 | | * @param advInt Advertisement interval |
357 | | * @param authType Authentication type (default value is 0) |
358 | | */ |
359 | | explicit VrrpV2Layer(uint8_t virtualRouterId, uint8_t priority, uint8_t advInt, uint8_t authType = 0); |
360 | | |
361 | | /** |
362 | | * A destructor for this layer (does nothing) |
363 | | */ |
364 | 0 | ~VrrpV2Layer() {} |
365 | | |
366 | | /** |
367 | | * @return The VRRP advertisement interval in this message |
368 | | */ |
369 | | uint8_t getAdvInt() const; |
370 | | |
371 | | /** |
372 | | * Set advertisement interval value in this message |
373 | | * @param advInt value to set |
374 | | */ |
375 | | void setAdvInt(uint8_t advInt); |
376 | | |
377 | | /** |
378 | | * @return The authentication type in this message |
379 | | */ |
380 | | uint8_t getAuthType() const; |
381 | | |
382 | | /** |
383 | | * @return The VRRP authentication type as enum |
384 | | */ |
385 | | VrrpAuthType getAuthTypeAsEnum() const; |
386 | | |
387 | | /** |
388 | | * Set VRRP authentication type |
389 | | * @param authType value to set |
390 | | */ |
391 | | void setAuthType(uint8_t authType); |
392 | | |
393 | | // implement abstract methods |
394 | | |
395 | | /** |
396 | | * Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum |
397 | | * @return The checksum result |
398 | | */ |
399 | | uint16_t calculateChecksum() const override; |
400 | | }; |
401 | | |
402 | | /** |
403 | | * @class VrrpV3Layer |
404 | | * Represents VRRPv3 (Virtual Router Redundancy Protocol ver 3) layer. This class represents all the different messages of VRRP |
405 | | */ |
406 | | class VrrpV3Layer : public VrrpLayer |
407 | | { |
408 | | private: |
409 | | struct vrrpv3_rsvd_adv |
410 | | { |
411 | | uint16_t maxAdvInt; |
412 | | }; |
413 | | |
414 | | public: |
415 | | /** A constructor that creates the layer from an existing packet raw data |
416 | | * @param[in] data A pointer to the raw data |
417 | | * @param[in] dataLen Size of the data in bytes |
418 | | * @param[in] prevLayer A pointer to the previous layer |
419 | | * @param[in] packet A pointer to the Packet instance where layer will be stored in |
420 | | * @param[in] addressType The IP address type to set for this layer |
421 | | */ |
422 | | VrrpV3Layer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet, IPAddress::AddressType addressType) |
423 | 10.2k | : VrrpLayer(data, dataLen, prevLayer, packet, VRRPv3, addressType) {} |
424 | | |
425 | | /** |
426 | | * A constructor that allocates a new VRRPv3 |
427 | | * @param addressType The IP address type to set for this layer |
428 | | * @param virtualRouterId Virtual router ID |
429 | | * @param priority Priority |
430 | | * @param maxAdvInt Max advertisement interval |
431 | | */ |
432 | | explicit VrrpV3Layer(IPAddress::AddressType addressType, uint8_t virtualRouterId, uint8_t priority, uint16_t maxAdvInt); |
433 | | |
434 | | /** |
435 | | * A destructor for this layer (does nothing) |
436 | | */ |
437 | 0 | ~VrrpV3Layer() {} |
438 | | |
439 | | /** |
440 | | * @return The maximum advertisement interval in this message |
441 | | */ |
442 | | uint16_t getMaxAdvInt() const; |
443 | | |
444 | | /** |
445 | | * Set the maximum advertisement interval value |
446 | | * @param maxAdvInt Value to set |
447 | | */ |
448 | | void setMaxAdvInt(uint16_t maxAdvInt); |
449 | | |
450 | | // implement abstract methods |
451 | | |
452 | | /** |
453 | | * Calculate the checksum from header and data and write the result to @ref vrrp_header#checksum |
454 | | * @return The checksum result |
455 | | */ |
456 | | uint16_t calculateChecksum() const override; |
457 | | }; |
458 | | } |