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