Coverage Report

Created: 2025-07-11 07:47

/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