Coverage Report

Created: 2024-02-25 06:29

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