Coverage Report

Created: 2025-07-11 07:47

/src/PcapPlusPlus/Packet++/header/StpLayer.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include "Layer.h"
4
#include "MacAddress.h"
5
#include <cstring>
6
7
/// @file
8
9
/// @namespace pcpp
10
/// @brief The main namespace for the PcapPlusPlus lib
11
namespace pcpp
12
{
13
  /// @struct stp_tcn_bpdu
14
  /// Represents payload of network changes announcements of BPDU
15
#pragma pack(push, 1)
16
  struct stp_tcn_bpdu
17
  {
18
    /// Protocol ID. Fixed at 0x0, which represents IEEE 802.1d
19
    uint16_t protoId;
20
    /// Protocol version. 0x0 for STP, 0x2 for RSTP, 0x3 for MSTP
21
    uint8_t version;
22
    /// Type of the BPDU. 0x0 for configuration, 0x2 for RSTP/MSTP, 0x80 for TCN
23
    uint8_t type;
24
  };
25
#pragma pack(pop)
26
  static_assert(sizeof(stp_tcn_bpdu) == 4, "stp_tcn_bpdu size is not 4 bytes");
27
28
  /// Spanning Tree protocol common header
29
  typedef stp_tcn_bpdu stp_header;
30
  static_assert(sizeof(stp_header) == 4, "stp_header size is not 4 bytes");
31
32
  /// @struct stp_conf_bpdu
33
  /// Represents payload configuration of BPDU for STP
34
#pragma pack(push, 1)
35
  struct stp_conf_bpdu : stp_tcn_bpdu
36
  {
37
    /// Flag for indicate purpose of BPDU
38
    uint8_t flag;
39
    /// Root bridge ID
40
    uint64_t rootId;
41
    /// Cost of path
42
    uint32_t pathCost;
43
    /// Bridge ID
44
    uint64_t bridgeId;
45
    /// Port ID
46
    uint16_t portId;
47
    /// Age of the BPDU
48
    uint16_t msgAge;
49
    /// Maximum age of the BPDU
50
    uint16_t maxAge;
51
    /// BPDU transmission interval
52
    uint16_t helloTime;
53
    /// Delay for STP
54
    uint16_t forwardDelay;
55
  };
56
#pragma pack(pop)
57
  static_assert(sizeof(stp_conf_bpdu) == 35, "stp_conf_bpdu size is not 35 bytes");
58
59
  /// @struct rstp_conf_bpdu
60
  /// Represents payload configuration of BPDU for Rapid STP (RSTP)
61
#pragma pack(push, 1)
62
  struct rstp_conf_bpdu : stp_conf_bpdu
63
  {
64
    /// Version1 length. The value is 0x0
65
    uint8_t version1Len;
66
  };
67
#pragma pack(pop)
68
  static_assert(sizeof(rstp_conf_bpdu) == 36, "rstp_conf_bpdu size is not 36 bytes");
69
70
  /// @struct mstp_conf_bpdu
71
  /// Represents payload configuration of BPDU for Multiple STP (MSTP)
72
#pragma pack(push, 1)
73
  struct mstp_conf_bpdu : rstp_conf_bpdu
74
  {
75
    /// Version3 length.
76
    uint16_t version3Len;
77
    /// Configuration id format selector
78
    uint8_t mstConfigFormatSelector;
79
    /// Configuration id name
80
    uint8_t mstConfigName[32];
81
    /// Configuration id revision
82
    uint16_t mstConfigRevision;
83
    /// Configuration id digest
84
    uint8_t mstConfigDigest[16];
85
    /// CIST internal root path cost
86
    uint32_t irpc;
87
    /// CIST bridge id
88
    uint64_t cistBridgeId;
89
    /// CIST remaining hop count
90
    uint8_t remainId;
91
  };
92
#pragma pack(pop)
93
  static_assert(sizeof(mstp_conf_bpdu) == 102, "mstp_conf_bpdu size is not 102 bytes");
94
95
  /// @struct msti_conf_msg
96
  /// Represents MSTI configuration messages. Each message contains 16 bytes and MSTP can contain 0 to 64 MSTI
97
  /// messages.
98
#pragma pack(push, 1)
99
  struct msti_conf_msg
100
  {
101
    /// MSTI flags
102
    uint8_t flags;
103
    /// Regional root switching id (Priority (4 bits) + ID (12 bits) + Regional root (48 bits - MAC address))
104
    uint64_t regionalRootId;
105
    /// Total path cost from local port to regional port
106
    uint32_t pathCost;
107
    /// Priority value of switching device
108
    uint8_t bridgePriority;
109
    /// Priority value of port
110
    uint8_t portPriority;
111
    /// Remaining hops of BPDU
112
    uint8_t remainingHops;
113
  };
114
#pragma pack(pop)
115
  static_assert(sizeof(msti_conf_msg) == 16, "msti_conf_msg size is not 16 bytes");
116
117
  /// @class StpLayer
118
  /// Represents an Spanning Tree Protocol Layer
119
  class StpLayer : public Layer
120
  {
121
  protected:
122
    StpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
123
0
        : Layer(data, dataLen, prevLayer, packet, STP)
124
0
    {}
125
126
    explicit StpLayer(size_t dataLen)
127
0
    {
128
0
      m_DataLen = dataLen;
129
0
      m_Data = new uint8_t[dataLen];
130
0
      memset(m_Data, 0, dataLen);
131
0
      m_Protocol = STP;
132
0
    }
133
134
    static pcpp::MacAddress IDtoMacAddress(uint64_t id);
135
    static uint64_t macAddressToID(const pcpp::MacAddress& addr);
136
137
  public:
138
    /// STP protocol uses "01:80:C2:00:00:00" multicast address as destination MAC
139
    static pcpp::MacAddress StpMulticastDstMAC;
140
    /// STP Uplink Fast protocol uses "01:00:0C:CD:CD:CD" as destination MAC
141
    static pcpp::MacAddress StpUplinkFastMulticastDstMAC;
142
143
    /// Get a pointer to base Spanning tree header
144
    /// @return A pointer to spanning tree header
145
    stp_header* getStpHeader() const
146
0
    {
147
0
      return reinterpret_cast<stp_header*>(m_Data);
148
0
    }
149
150
    /// Returns the protocol id. Fixed at 0x0 for STP messages which represents IEEE 802.1d
151
    /// @return ID of the protocol
152
    uint16_t getProtoId() const
153
0
    {
154
0
      return getStpHeader()->protoId;
155
0
    }
156
157
    /// Sets the protocol id
158
    /// @param[in] value ID of the protocol
159
160
    void setProtoId(uint16_t value)
161
0
    {
162
0
      getStpHeader()->protoId = value;
163
0
    }
164
165
    /// Returns the version. Fixed at 0x0 for STP messages
166
    /// @return Version number
167
    uint8_t getVersion() const
168
0
    {
169
0
      return getStpHeader()->version;
170
0
    }
171
172
    /// Sets the version
173
    /// @param[in] value Version number
174
    void setVersion(uint8_t value)
175
0
    {
176
0
      getStpHeader()->version = value;
177
0
    }
178
179
    /// Returns the type of configuration message.
180
    /// @return Type of configuration message
181
    uint8_t getType() const
182
0
    {
183
0
      return getStpHeader()->type;
184
0
    }
185
186
    /// Sets the type of configuration message
187
    /// @param[in] value Type of configuration message
188
    void setType(uint8_t value)
189
0
    {
190
0
      getStpHeader()->type = value;
191
0
    }
192
193
    // overridden methods
194
195
    /// @return The size of STP packet
196
    size_t getHeaderLen() const override
197
0
    {
198
0
      return m_DataLen;
199
0
    }
200
201
    /// Does nothing for this layer
202
    void computeCalculateFields() override
203
0
    {}
204
205
    /// @return The OSI layer level of STP (Data Link Layer).
206
    OsiModelLayer getOsiModelLayer() const override
207
0
    {
208
0
      return OsiModelDataLinkLayer;
209
0
    }
210
211
    /// A static method that validates the input data
212
    /// @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree packet
213
    /// @param[in] dataLen The length of the byte stream
214
    /// @return True if the data is valid and can represent an Spanning Tree packet
215
    static bool isDataValid(const uint8_t* data, size_t dataLen);
216
217
    /// A method to create STP layer from existing packet
218
    /// @param[in] data A pointer to the raw data
219
    /// @param[in] dataLen Size of the data in bytes
220
    /// @param[in] prevLayer A pointer to the previous layer
221
    /// @param[in] packet A pointer to the Packet instance where layer will be stored
222
    /// @return A newly allocated STP layer of one of the following types (according to the message type):
223
    /// StpConfigurationBPDULayer, StpTopologyChangeBPDULayer, RapidStpLayer, MultipleStpLayer
224
    static StpLayer* parseStpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
225
  };
226
227
  /// @class StpTopologyChangeBPDULayer
228
  /// Represents network topology change BPDU message of Spanning Tree Protocol
229
  class StpTopologyChangeBPDULayer : public StpLayer
230
  {
231
  protected:
232
0
    explicit StpTopologyChangeBPDULayer(size_t dataLen) : StpLayer(dataLen)
233
0
    {}
234
235
  public:
236
    /// A constructor that creates the layer from an existing packet raw data
237
    /// @param[in] data A pointer to the raw data
238
    /// @param[in] dataLen Size of the data in bytes
239
    /// @param[in] prevLayer A pointer to the previous layer
240
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
241
    StpTopologyChangeBPDULayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
242
0
        : StpLayer(data, dataLen, prevLayer, packet)
243
0
    {}
244
245
    /// Empty c'tor to create a new network topology change (TCN) BPDU layer.
246
    /// Initializes the protocol identifier, version and STP type fields with correct values
247
    StpTopologyChangeBPDULayer();
248
249
    /// Get a pointer to network topology change (TCN) BPDU message
250
    /// @return A pointer to TCN BPDU message
251
    stp_tcn_bpdu* getStpTcnHeader()
252
0
    {
253
0
      return getStpHeader();
254
0
    }
255
256
    // overridden methods
257
258
    /// @return The size of STP TCN message
259
    size_t getHeaderLen() const override
260
0
    {
261
0
      return sizeof(stp_tcn_bpdu);
262
0
    }
263
264
    /// Parses next layer
265
    void parseNextLayer() override;
266
267
    /// @return Returns the protocol info as readable string
268
    std::string toString() const override
269
0
    {
270
0
      return "Spanning Tree Topology Change Notification";
271
0
    }
272
273
    /// A static method that validates the input data
274
    /// @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree Topology Change BPDU
275
    /// packet
276
    /// @param[in] dataLen The length of the byte stream
277
    /// @return True if the data is valid and can represent an Spanning Tree packet
278
    static bool isDataValid(const uint8_t* data, size_t dataLen)
279
0
    {
280
0
      return canReinterpretAs<stp_tcn_bpdu>(data, dataLen);
281
0
    }
282
  };
283
284
  /// @class StpConfigurationBPDULayer
285
  /// Represents configuration BPDU message of Spanning Tree Protocol
286
  class StpConfigurationBPDULayer : public StpTopologyChangeBPDULayer
287
  {
288
  protected:
289
0
    explicit StpConfigurationBPDULayer(size_t dataLen) : StpTopologyChangeBPDULayer(dataLen)
290
0
    {}
291
292
  public:
293
    /// A constructor that creates the layer from an existing packet raw data
294
    /// @param[in] data A pointer to the raw data
295
    /// @param[in] dataLen Size of the data in bytes
296
    /// @param[in] prevLayer A pointer to the previous layer
297
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
298
    StpConfigurationBPDULayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
299
0
        : StpTopologyChangeBPDULayer(data, dataLen, prevLayer, packet)
300
0
    {}
301
302
    /// Empty c'tor to create a new configuration BPDU layer.
303
    /// Initializes the protocol identifier, version and STP type fields with correct values
304
    StpConfigurationBPDULayer();
305
306
    /// Get a pointer to configuration BPDU message
307
    /// @return A pointer to configuration BPDU message
308
    stp_conf_bpdu* getStpConfHeader() const
309
0
    {
310
0
      return reinterpret_cast<stp_conf_bpdu*>(m_Data);
311
0
    }
312
313
    /// Returns the flags of configuration message which indicates purpose of BPDU
314
    /// @return Flags of the configuration message
315
    uint8_t getFlag() const
316
0
    {
317
0
      return getStpConfHeader()->flag;
318
0
    }
319
320
    /// Returns the flags of configuration message which indicates purpose of BPDU
321
    /// @param[in] value Flags of the configuration message
322
    void setFlag(uint8_t value)
323
0
    {
324
0
      getStpConfHeader()->flag = value;
325
0
    }
326
327
    /// Returns the root bridge identifier
328
    /// @return Root bridge identifier
329
    uint64_t getRootId() const;
330
331
    /// Sets the root bridge identifier
332
    /// @param[in] value Root bridge identifier
333
    void setRootId(uint64_t value);
334
335
    /// Returns the priority of root bridge
336
    /// @return Priority of root bridge
337
    uint16_t getRootPriority() const;
338
339
    /// Sets the priority of root bridge
340
    /// @param[in] value Priority of root bridge
341
    void setRootPriority(uint16_t value);
342
343
    /// Returns the system identifier extension of root bridge
344
    /// @return System extension of root bridge
345
    uint16_t getRootSystemIDExtension() const;
346
347
    /// Sets the system identifier extension of root bridge
348
    /// @param[in] value System extension of root bridge
349
    void setRootSystemIDExtension(uint16_t value);
350
351
    /// Returns the system identifier of root bridge
352
    /// @return System identifier of root bridge
353
    pcpp::MacAddress getRootSystemID() const
354
0
    {
355
0
      return IDtoMacAddress(getRootId());
356
0
    }
357
358
    /// Sets the system identifier of root bridge
359
    /// @param[in] value System identifier of root bridge
360
    void setRootSystemID(const pcpp::MacAddress& value);
361
362
    /// Returns the value of the cost of path
363
    /// @return Cost of path
364
    uint32_t getPathCost() const;
365
366
    /// Sets the value of the cost of path
367
    /// @param[in] value Cost of path
368
    void setPathCost(uint32_t value);
369
370
    /// Returns the bridge identifier
371
    /// @return Bridge identifier
372
    uint64_t getBridgeId() const;
373
374
    /// Sets the bridge identifier
375
    /// @param[in] value Bridge identifier
376
    void setBridgeId(uint64_t value);
377
378
    /// Returns the priority of bridge
379
    /// @return Priority of bridge
380
    uint16_t getBridgePriority() const;
381
382
    /// Sets the priority of bridge
383
    /// @param[in] value Priority of bridge
384
    void setBridgePriority(uint16_t value);
385
386
    /// Returns the system identifier extension of bridge
387
    /// @return System extension of bridge
388
    uint16_t getBridgeSystemIDExtension() const;
389
390
    /// Sets the system identifier extension of bridge
391
    /// @param[in] value System extension of bridge
392
    void setBridgeSystemIDExtension(uint16_t value);
393
394
    /// Returns the system identifier of bridge
395
    /// @return System identifier of bridge
396
    pcpp::MacAddress getBridgeSystemID() const
397
0
    {
398
0
      return IDtoMacAddress(getBridgeId());
399
0
    }
400
401
    /// Sets the system identifier of bridge
402
    /// @param[in] value System identifier of bridge
403
    void setBridgeSystemID(const pcpp::MacAddress& value);
404
405
    /// Returns the port identifier
406
    /// @return Port identifier
407
    uint16_t getPortId() const;
408
409
    /// Sets the port identifier
410
    /// @param[in] value Port identifier
411
    void setPortId(uint16_t value);
412
413
    /// Returns age of the BPDU message
414
    /// @return Age of BPDU in seconds
415
    double getMessageAge() const;
416
417
    /// Sets age of the BPDU message
418
    /// @param[in] value Age of BPDU in seconds
419
    void setMessageAge(double value);
420
421
    /// Returns maximum age of the BPDU message
422
    /// @return Maximum age of BPDU in seconds
423
    double getMaximumAge() const;
424
425
    /// Sets maximum age of the BPDU message
426
    /// @param[in] value Maximum age of BPDU in seconds
427
    void setMaximumAge(double value);
428
429
    /// Returns the BPDU transmission interval
430
    /// @return Value of the transmission interval in seconds
431
    double getTransmissionInterval() const;
432
433
    /// Sets the BPDU transmission interval
434
    /// @param[in] value Value of the transmission interval in seconds
435
    void setTransmissionInterval(double value);
436
437
    /// Returns the delay for STP message
438
    /// @return Value of the forward delay in seconds
439
    double getForwardDelay() const;
440
441
    /// Sets the delay for STP message
442
    /// @param[in] value Value of the forward delay in seconds
443
    void setForwardDelay(double value);
444
445
    // overridden methods
446
447
    /// @return The size of STP configuration BPDU message
448
    size_t getHeaderLen() const override
449
0
    {
450
0
      return sizeof(stp_conf_bpdu);
451
0
    }
452
453
    /// Parses next layer
454
    void parseNextLayer() override;
455
456
    /// @return Returns the protocol info as readable string
457
    std::string toString() const override
458
0
    {
459
0
      return "Spanning Tree Configuration";
460
0
    }
461
462
    /// A static method that validates the input data
463
    /// @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree Configuration BPDU packet
464
    /// @param[in] dataLen The length of the byte stream
465
    /// @return True if the data is valid and can represent an Spanning Tree packet
466
    static bool isDataValid(const uint8_t* data, size_t dataLen)
467
0
    {
468
0
      return canReinterpretAs<stp_conf_bpdu>(data, dataLen);
469
0
    }
470
  };
471
472
  /// @class RapidStpLayer
473
  /// Represents Rapid Spanning Tree Protocol (RSTP)
474
  class RapidStpLayer : public StpConfigurationBPDULayer
475
  {
476
  protected:
477
0
    explicit RapidStpLayer(size_t dataLen) : StpConfigurationBPDULayer(dataLen)
478
0
    {}
479
480
  public:
481
    /// A constructor that creates the layer from an existing packet raw data
482
    /// @param[in] data A pointer to the raw data
483
    /// @param[in] dataLen Size of the data in bytes
484
    /// @param[in] prevLayer A pointer to the previous layer
485
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
486
    RapidStpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
487
0
        : StpConfigurationBPDULayer(data, dataLen, prevLayer, packet)
488
0
    {}
489
490
    /// Empty c'tor to create a new Rapid STP layer.
491
    /// Initializes the protocol identifier, version and STP type fields with correct values
492
    RapidStpLayer();
493
494
    /// Get a pointer to Rapid STP header
495
    /// @return A pointer to Rapid STP header
496
    rstp_conf_bpdu* getRstpConfHeader() const
497
0
    {
498
0
      return reinterpret_cast<rstp_conf_bpdu*>(m_Data);
499
0
    }
500
501
    /// Returns the length of version1 field. Fixed at 0x0 for Rapid STP
502
    /// @return Length of the version1 field
503
    uint8_t getVersion1Len() const
504
0
    {
505
0
      return getRstpConfHeader()->version1Len;
506
0
    }
507
508
    /// Returns the length of version1 field
509
    /// @param[in] value Length of the version1 field
510
    void setVersion1Len(uint8_t value)
511
0
    {
512
0
      getRstpConfHeader()->version1Len = value;
513
0
    }
514
515
    // overridden methods
516
517
    /// @return The size of Rapid STP message
518
    size_t getHeaderLen() const override
519
0
    {
520
0
      return sizeof(rstp_conf_bpdu);
521
0
    }
522
523
    /// Parses next layer
524
    void parseNextLayer() override;
525
526
    /// @return Returns the protocol info as readable string
527
    std::string toString() const override
528
0
    {
529
0
      return "Rapid Spanning Tree";
530
0
    }
531
532
    /// A static method that validates the input data
533
    /// @param[in] data The pointer to the beginning of a byte stream of an Rapid STP packet
534
    /// @param[in] dataLen The length of the byte stream
535
    /// @return True if the data is valid and can represent an Spanning Tree packet
536
    static bool isDataValid(const uint8_t* data, size_t dataLen)
537
0
    {
538
0
      return canReinterpretAs<rstp_conf_bpdu>(data, dataLen);
539
0
    }
540
  };
541
542
  /// @class MultipleStpLayer
543
  /// Represents Multiple Spanning Tree Protocol (MSTP). It has limited capabilities (no crafting / limited editing)
544
  /// over MSTI configuration
545
  class MultipleStpLayer : public RapidStpLayer
546
  {
547
  public:
548
    /// A constructor that creates the layer from an existing packet raw data
549
    /// @param[in] data A pointer to the raw data
550
    /// @param[in] dataLen Size of the data in bytes
551
    /// @param[in] prevLayer A pointer to the previous layer
552
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
553
    MultipleStpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
554
0
        : RapidStpLayer(data, dataLen, prevLayer, packet)
555
0
    {}
556
557
    /// Empty c'tor to create a new Multiple STP layer.
558
    /// Initializes the protocol identifier, version and STP type fields with correct values
559
    MultipleStpLayer();
560
561
    /// Get a pointer to Multiple STP header
562
    /// @return A pointer to Multiple STP header
563
    mstp_conf_bpdu* getMstpHeader() const
564
0
    {
565
0
      return reinterpret_cast<mstp_conf_bpdu*>(m_Data);
566
0
    }
567
568
    /// @return Length of version3 field
569
    uint16_t getVersion3Len() const;
570
571
    /// Sets the length of version3 field
572
    /// @param[in] value Length of version3 field
573
    void setVersion3Len(uint16_t value);
574
575
    /// Returns the configuration ID format selector
576
    /// @return Configuration ID of format selector
577
    uint8_t getMstConfigurationFormatSelector() const
578
0
    {
579
0
      return getMstpHeader()->mstConfigFormatSelector;
580
0
    }
581
582
    /// Sets the configuration ID format selector
583
    /// @param[in] value Configuration ID of format selector
584
    void setMstConfigurationFormatSelector(uint8_t value)
585
0
    {
586
0
      getMstpHeader()->mstConfigFormatSelector = value;
587
0
    }
588
589
    /// Returns the pointer to configuration name field
590
    /// @return Configuration name
591
    std::string getMstConfigurationName() const;
592
593
    /// Sets the configuration name field
594
    /// @param[in] value Configuration name. Length should be less than 32, if longer value provided first 32
595
    /// characters are used
596
    void setMstConfigurationName(const std::string& value);
597
598
    /// Returns the revision of configuration ID
599
    /// @return Revision of configuration ID
600
    uint16_t getMstConfigRevision() const;
601
602
    /// Sets the revision of configuration ID
603
    /// @param[in] value Revision of configuration ID
604
    void setMstConfigRevision(uint16_t value);
605
606
    /// Returns the pointer to configuration message digest. The field itself always 16 bytes long.
607
    /// @return A pointer to configuration digest
608
    uint8_t* getMstConfigDigest() const
609
0
    {
610
0
      return getMstpHeader()->mstConfigDigest;
611
0
    }
612
613
    /// Sets the pointer to configuration message digest. The field itself always 16 bytes long.
614
    /// @param[in] value Pointer to digest
615
    /// @param[in] len Length of the digest, should be less than 16. If longer first 16 bytes are used
616
    void setMstConfigDigest(const uint8_t* value, uint8_t len);
617
618
    /// Returns CIST internal root path cost
619
    /// @return Value of the internal root path cost
620
    uint32_t getCISTIrpc() const;
621
622
    /// Sets CIST internal root path cost
623
    /// @param[in] value Value of the internal root path cost
624
    void setCISTIrpc(uint32_t value);
625
626
    /// Returns CIST bridge identifier
627
    /// @return Value of the bridge identifier
628
    uint64_t getCISTBridgeId() const;
629
630
    /// Sets CIST bridge identifier
631
    /// @param[in] value Value of the bridge identifier
632
    void setCISTBridgeId(uint64_t value);
633
634
    /// Returns the priority of CIST bridge
635
    /// @return Priority of CIST bridge
636
    uint16_t getCISTBridgePriority() const;
637
638
    /// Sets the priority of CIST bridge
639
    /// @param[in] value Priority of CIST bridge
640
    void setCISTBridgePriority(uint16_t value);
641
642
    /// Returns the system identifier extension of CIST bridge
643
    /// @return System extension of CIST bridge
644
    uint16_t getCISTBridgeSystemIDExtension() const;
645
646
    /// Sets the system identifier extension of CIST bridge
647
    /// @param[in] value System extension of CIST bridge
648
    void setCISTBridgeSystemIDExtension(uint16_t value);
649
650
    /// Returns the system identifier of CIST bridge
651
    /// @return System identifier of CIST bridge
652
    pcpp::MacAddress getCISTBridgeSystemID() const
653
0
    {
654
0
      return IDtoMacAddress(getCISTBridgeId());
655
0
    }
656
657
    /// Sets the system identifier of CIST bridge
658
    /// @param[in] value System identifier of CIST bridge
659
    void setCISTBridgeSystemID(const pcpp::MacAddress& value);
660
661
    /// Returns the remaining hop count
662
    /// @return Value of remaining hop count
663
    uint8_t getRemainingHopCount() const
664
0
    {
665
0
      return getMstpHeader()->remainId;
666
0
    }
667
668
    /// Returns the remaining hop count
669
    /// @param[in] value Value of remaining hop count
670
    void setRemainingHopCount(uint8_t value)
671
0
    {
672
0
      getMstpHeader()->remainId = value;
673
0
    }
674
675
    /// Returns the total number of MSTI configuration messages
676
    /// @return Number of MSTI configuration messages. Can be between 0 and 64.
677
    uint8_t getNumberOfMSTIConfMessages() const
678
0
    {
679
0
      return (getVersion3Len() - (sizeof(mstp_conf_bpdu) - sizeof(rstp_conf_bpdu) - sizeof(uint16_t))) /
680
0
             sizeof(msti_conf_msg);
681
0
    }
682
683
    /// Returns a reference to MSTI configuration messages. An MSTP packet can contain between 0 to 64 MSTI
684
    /// messages. The number of messages can be obtained by using getNumberOfMSTIConfMessages()
685
    /// @return An array pointer to MSTI configuration messages. Returns nullptr if there is no MSTI message.
686
    msti_conf_msg* getMstiConfMessages() const;
687
688
    // overridden methods
689
690
    /// Parses next layer
691
    void parseNextLayer() override
692
0
    {}
693
694
    /// @return Returns the protocol info as readable string
695
    std::string toString() const override
696
0
    {
697
0
      return "Multiple Spanning Tree";
698
0
    }
699
700
    /// A static method that validates the input data
701
    /// @param[in] data The pointer to the beginning of a byte stream of an Multiple STP packet
702
    /// @param[in] dataLen The length of the byte stream
703
    /// @return True if the data is valid and can represent an Spanning Tree packet
704
    static bool isDataValid(const uint8_t* data, size_t dataLen)
705
0
    {
706
0
      return canReinterpretAs<mstp_conf_bpdu>(data, dataLen);
707
0
    }
708
  };
709
}  // namespace pcpp