pcapplusplus-sys 0.1.0

Compile PcapPlusPlus and make its library and header files available. See also https://github.com/seladb/PcapPlusPlus
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
#ifndef PACKETPP_STP_LAYER
#define PACKETPP_STP_LAYER

#include "Layer.h"
#include "MacAddress.h"

/// @file

/**
 * \namespace pcpp
 * \brief The main namespace for the PcapPlusPlus lib
 */
namespace pcpp
{

/**
 * @struct stp_tcn_bpdu
 * Represents payload of network changes announcements of BPDU
 */
#pragma pack(push, 1)
	struct stp_tcn_bpdu
	{
		/// Protocol ID. Fixed at 0x0, which represents IEEE 802.1d
		uint16_t protoId;
		/// Protocol version. 0x0 for STP, 0x2 for RSTP, 0x3 for MSTP
		uint8_t version;
		/// Type of the BPDU. 0x0 for configuration, 0x2 for RSTP/MSTP, 0x80 for TCN
		uint8_t type;
	};
#pragma pack(pop)

/// Spanning Tree protocol common header
typedef stp_tcn_bpdu stp_header;

/**
 * @struct stp_conf_bpdu
 * Represents payload configuration of BPDU for STP
 */
#pragma pack(push, 1)
	struct stp_conf_bpdu : stp_tcn_bpdu
	{
		/// Flag for indicate purpose of BPDU
		uint8_t flag;
		/// Root bridge ID
		uint64_t rootId;
		/// Cost of path
		uint32_t pathCost;
		/// Bridge ID
		uint64_t bridgeId;
		/// Port ID
		uint16_t portId;
		/// Age of the BPDU
		uint16_t msgAge;
		/// Maximum age of the BPDU
		uint16_t maxAge;
		/// BPDU transmission interval
		uint16_t helloTime;
		/// Delay for STP
		uint16_t forwardDelay;
	};
#pragma pack(pop)

/**
 * @struct rstp_conf_bpdu
 * Represents payload configuration of BPDU for Rapid STP (RSTP)
 */
#pragma pack(push, 1)
	struct rstp_conf_bpdu : stp_conf_bpdu
	{
		/// Version1 length. The value is 0x0
		uint8_t version1Len;
	};
#pragma pack(pop)

/**
 * @struct mstp_conf_bpdu
 * Represents payload configuration of BPDU for Multiple STP (MSTP)
 */
#pragma pack(push, 1)
	struct mstp_conf_bpdu : rstp_conf_bpdu
	{
		/// Version3 length.
		uint16_t version3Len;
		/// Configuration id format selector
		uint8_t mstConfigFormatSelector;
		/// Configuration id name
		uint8_t mstConfigName[32];
		/// Configuration id revision
		uint16_t mstConfigRevision;
		/// Configuration id digest
		uint8_t mstConfigDigest[16];
		/// CIST internal root path cost
		uint32_t irpc;
		/// CIST bridge id
		uint64_t cistBridgeId;
		/// CIST remaining hop count
		uint8_t remainId;
	};
#pragma pack(pop)

/**
 * @struct msti_conf_msg
 * Represents MSTI configuration messages. Each message contains 16 bytes and MSTP can contain 0 to 64 MSTI messages.
 */
#pragma pack(push, 1)
	struct msti_conf_msg
	{
		/// MSTI flags
		uint8_t flags;
		/// Regional root switching id (Priority (4 bits) + ID (12 bits) + Regional root (48 bits - MAC address))
		uint64_t regionalRootId;
		/// Total path cost from local port to regional port
		uint32_t pathCost;
		/// Priority value of switching device
		uint8_t bridgePriority;
		/// Priority value of port
		uint8_t portPriority;
		/// Remaining hops of BPDU
		uint8_t remainingHops;
	};
#pragma pack(pop)

	/**
	 * @class StpLayer
	 * Represents an Spanning Tree Protocol Layer
	 */
	class StpLayer : public Layer
	{
	  protected:
		StpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
			: Layer(data, dataLen, prevLayer, packet)
		{
			m_Protocol = STP;
		}

		explicit StpLayer(size_t dataLen)
		{
			m_DataLen = dataLen;
			m_Data = new uint8_t[dataLen];
			memset(m_Data, 0, dataLen);
			m_Protocol = STP;
		}

		static pcpp::MacAddress IDtoMacAddress(uint64_t id);
		static uint64_t macAddressToID(const pcpp::MacAddress &addr);

	  public:
		/// STP protocol uses "01:80:C2:00:00:00" multicast address as destination MAC
		static pcpp::MacAddress StpMulticastDstMAC;
		/// STP Uplink Fast protocol uses "01:00:0C:CD:CD:CD" as destination MAC
		static pcpp::MacAddress StpUplinkFastMulticastDstMAC;

		/**
		 * Get a pointer to base Spanning tree header
		 * @return A pointer to spanning tree header
		 */
		stp_header *getStpHeader() const { return (stp_header *)(m_Data); }

		/**
		 * Returns the protocol id. Fixed at 0x0 for STP messages which represents IEEE 802.1d
		 * @return ID of the protocol
		 */
		uint16_t getProtoId() const { return getStpHeader()->protoId; }

		/**
		 * Sets the protocol id
		 * @param[in] value ID of the protocol
		 */
		void setProtoId(uint16_t value) { getStpHeader()->protoId = value; }

		/**
		 * Returns the version. Fixed at 0x0 for STP messages
		 * @return Version number
		 */
		uint8_t getVersion() const { return getStpHeader()->version; }

		/**
		 * Sets the version
		 * @param[in] value Version number
		 */
		void setVersion(uint8_t value) { getStpHeader()->version = value; }

		/**
		 * Returns the type of configuration message.
		 * @return Type of configuration message
		 */
		uint8_t getType() const { return getStpHeader()->type; }

		/**
		 * Sets the type of configuration message
		 * @param[in] value Type of configuration message
		 */
		void setType(uint8_t value) { getStpHeader()->type = value; }

		// overridden methods

		/**
		 * @return The size of STP packet
		 */
		size_t getHeaderLen() const { return m_DataLen; }

		/// Does nothing for this layer
		void computeCalculateFields() {}

		/**
		 * @return The OSI layer level of STP (Data Link Layer).
		 */
		OsiModelLayer getOsiModelLayer() const { return OsiModelDataLinkLayer; }

		/**
		 * A static method that validates the input data
		 * @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree packet
		 * @param[in] dataLen The length of the byte stream
		 * @return True if the data is valid and can represent an Spanning Tree packet
		 */
		static bool isDataValid(const uint8_t *data, size_t dataLen);

		/**
		 * A method to create STP layer from existing packet
		 * @param[in] data A pointer to the raw data
		 * @param[in] dataLen Size of the data in bytes
		 * @param[in] prevLayer A pointer to the previous layer
		 * @param[in] packet A pointer to the Packet instance where layer will be stored
		 * @return A newly allocated STP layer of one of the following types (according to the message type):
		 * StpConfigurationBPDULayer, StpTopologyChangeBPDULayer, RapidStpLayer, MultipleStpLayer
		 */
		static StpLayer *parseStpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet);
	};

	/**
	 * @class StpTopologyChangeBPDULayer
	 * Represents network topology change BPDU message of Spanning Tree Protocol
	 */
	class StpTopologyChangeBPDULayer : public StpLayer
	{
	  protected:
		explicit StpTopologyChangeBPDULayer(size_t dataLen) : StpLayer(dataLen) {}

	  public:
		/**
		 * A constructor that creates the layer from an existing packet raw data
		 * @param[in] data A pointer to the raw data
		 * @param[in] dataLen Size of the data in bytes
		 * @param[in] prevLayer A pointer to the previous layer
		 * @param[in] packet A pointer to the Packet instance where layer will be stored in
		 */
		StpTopologyChangeBPDULayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
			: StpLayer(data, dataLen, prevLayer, packet)
		{
		}

		/**
		 * Empty c'tor to create a new network topology change (TCN) BPDU layer.
		 * Initializes the protocol identifier, version and STP type fields with correct values
		 */
		StpTopologyChangeBPDULayer();

		/**
		 * Get a pointer to network topology change (TCN) BPDU message
		 * @return A pointer to TCN BPDU message
		 */
		stp_tcn_bpdu* getStpTcnHeader() { return getStpHeader(); }

		// overridden methods

		/**
		 * @return The size of STP TCN message
		 */
		size_t getHeaderLen() const { return sizeof(stp_tcn_bpdu); }

		/// Parses next layer
		void parseNextLayer();

		/**
		 * @return Returns the protocol info as readable string
		 */
		std::string toString() const { return "Spanning Tree Topology Change Notification"; }

		/**
		 * A static method that validates the input data
		 * @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree Topology Change BPDU packet
		 * @param[in] dataLen The length of the byte stream
		 * @return True if the data is valid and can represent an Spanning Tree packet
		 */
		static bool isDataValid(const uint8_t *data, size_t dataLen) { return data && dataLen >= sizeof(stp_tcn_bpdu); }
	};

	/**
	 * @class StpConfigurationBPDULayer
	 * Represents configuration BPDU message of Spanning Tree Protocol
	 */
	class StpConfigurationBPDULayer : public StpTopologyChangeBPDULayer
	{
	  protected:
		explicit StpConfigurationBPDULayer(size_t dataLen) : StpTopologyChangeBPDULayer(dataLen) {}

	  public:
		/**
		 * A constructor that creates the layer from an existing packet raw data
		 * @param[in] data A pointer to the raw data
		 * @param[in] dataLen Size of the data in bytes
		 * @param[in] prevLayer A pointer to the previous layer
		 * @param[in] packet A pointer to the Packet instance where layer will be stored in
		 */
		StpConfigurationBPDULayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
			: StpTopologyChangeBPDULayer(data, dataLen, prevLayer, packet)
		{
		}

		/**
		 * Empty c'tor to create a new configuration BPDU layer.
		 * Initializes the protocol identifier, version and STP type fields with correct values
		 */
		StpConfigurationBPDULayer();

		/**
		 * Get a pointer to configuration BPDU message
		 * @return A pointer to configuration BPDU message
		 */
		stp_conf_bpdu *getStpConfHeader() const { return (stp_conf_bpdu *)(m_Data); }

		/**
		 * Returns the flags of configuration message which indicates purpose of BPDU
		 * @return Flags of the configuration message
		 */
		uint8_t getFlag() const { return getStpConfHeader()->flag; }

		/**
		 * Returns the flags of configuration message which indicates purpose of BPDU
		 * @param[in] value Flags of the configuration message
		 */
		void setFlag(uint8_t value) { getStpConfHeader()->flag = value; }

		/**
		 * Returns the root bridge identifier
		 * @return Root bridge identifier
		 */
		uint64_t getRootId() const;

		/**
		 * Sets the root bridge identifier
		 * @param[in] value Root bridge identifier
		 */
		void setRootId(uint64_t value);

		/**
		 * Returns the priority of root bridge
		 * @return Priority of root bridge
		 */
		uint16_t getRootPriority() const;

		/**
		 * Sets the priority of root bridge
		 * @param[in] value Priority of root bridge
		 */
		void setRootPriority(uint16_t value);

		/**
		 * Returns the system identifier extension of root bridge
		 * @return System extension of root bridge
		 */
		uint16_t getRootSystemIDExtension() const;

		/**
		 * Sets the system identifier extension of root bridge
		 * @param[in] value System extension of root bridge
		 */
		void setRootSystemIDExtension(uint16_t value);

		/**
		 * Returns the system identifier of root bridge
		 * @return System identifier of root bridge
		 */
		pcpp::MacAddress getRootSystemID() const { return IDtoMacAddress(getRootId()); }

		/**
		 * Sets the system identifier of root bridge
		 * @param[in] value System identifier of root bridge
		 */
		void setRootSystemID(const pcpp::MacAddress &value);

		/**
		 * Returns the value of the cost of path
		 * @return Cost of path
		 */
		uint32_t getPathCost() const;

		/**
		 * Sets the value of the cost of path
		 * @param[in] value Cost of path
		 */
		void setPathCost(uint32_t value);

		/**
		 * Returns the bridge identifier
		 * @return Bridge identifier
		 */
		uint64_t getBridgeId() const;

		/**
		 * Sets the bridge identifier
		 * @param[in] value Bridge identifier
		 */
		void setBridgeId(uint64_t value);

		/**
		 * Returns the priority of bridge
		 * @return Priority of bridge
		 */
		uint16_t getBridgePriority() const;

		/**
		 * Sets the priority of bridge
		 * @param[in] value Priority of bridge
		 */
		void setBridgePriority(uint16_t value);

		/**
		 * Returns the system identifier extension of bridge
		 * @return System extension of bridge
		 */
		uint16_t getBridgeSystemIDExtension() const;

		/**
		 * Sets the system identifier extension of bridge
		 * @param[in] value System extension of bridge
		 */
		void setBridgeSystemIDExtension(uint16_t value);

		/**
		 * Returns the system identifier of bridge
		 * @return System identifier of bridge
		 */
		pcpp::MacAddress getBridgeSystemID() const { return IDtoMacAddress(getBridgeId()); }

		/**
		 * Sets the system identifier of bridge
		 * @param[in] value System identifier of bridge
		 */
		void setBridgeSystemID(const pcpp::MacAddress &value);

		/**
		 * Returns the port identifier
		 * @return Port identifier
		 */
		uint16_t getPortId() const;

		/**
		 * Sets the port identifier
		 * @param[in] value Port identifier
		 */
		void setPortId(uint16_t value);

		/**
		 * Returns age of the BPDU message
		 * @return Age of BPDU in seconds
		 */
		double getMessageAge() const;

		/**
		 * Sets age of the BPDU message
		 * @param[in] value Age of BPDU in seconds
		 */
		void setMessageAge(double value);

		/**
		 * Returns maximum age of the BPDU message
		 * @return Maximum age of BPDU in seconds
		 */
		double getMaximumAge() const;

		/**
		 * Sets maximum age of the BPDU message
		 * @param[in] value Maximum age of BPDU in seconds
		 */
		void setMaximumAge(double value);

		/**
		 * Returns the BPDU transmission interval
		 * @return Value of the transmission interval in seconds
		 */
		double getTransmissionInterval() const;

		/**
		 * Sets the BPDU transmission interval
		 * @param[in] value Value of the transmission interval in seconds
		 */
		void setTransmissionInterval(double value);

		/**
		 * Returns the delay for STP message
		 * @return Value of the forward delay in seconds
		 */
		double getForwardDelay() const;

		/**
		 * Sets the delay for STP message
		 * @param[in] value Value of the forward delay in seconds
		 */
		void setForwardDelay(double value);

		// overridden methods

		/**
		 * @return The size of STP configuration BPDU message
		 */
		size_t getHeaderLen() const { return sizeof(stp_conf_bpdu); }

		/// Parses next layer
		void parseNextLayer();

		/**
		 * @return Returns the protocol info as readable string
		 */
		std::string toString() const { return "Spanning Tree Configuration"; }

		/**
		 * A static method that validates the input data
		 * @param[in] data The pointer to the beginning of a byte stream of an Spanning Tree Configuration BPDU packet
		 * @param[in] dataLen The length of the byte stream
		 * @return True if the data is valid and can represent an Spanning Tree packet
		 */
		static bool isDataValid(const uint8_t *data, size_t dataLen)
		{
			return data && dataLen >= sizeof(stp_conf_bpdu);
		}
	};

	/**
	 * @class RapidStpLayer
	 * Represents Rapid Spanning Tree Protocol (RSTP)
	 */
	class RapidStpLayer : public StpConfigurationBPDULayer
	{
	  protected:
		explicit RapidStpLayer(size_t dataLen) : StpConfigurationBPDULayer(dataLen) {}

	  public:
		/**
		 * A constructor that creates the layer from an existing packet raw data
		 * @param[in] data A pointer to the raw data
		 * @param[in] dataLen Size of the data in bytes
		 * @param[in] prevLayer A pointer to the previous layer
		 * @param[in] packet A pointer to the Packet instance where layer will be stored in
		 */
		RapidStpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
			: StpConfigurationBPDULayer(data, dataLen, prevLayer, packet)
		{
		}

		/**
		 * Empty c'tor to create a new Rapid STP layer.
		 * Initializes the protocol identifier, version and STP type fields with correct values
		 */
		RapidStpLayer();

		/**
		 * Get a pointer to Rapid STP header
		 * @return A pointer to Rapid STP header
		 */
		rstp_conf_bpdu *getRstpConfHeader() const { return (rstp_conf_bpdu *)(m_Data); }

		/**
		 * Returns the length of version1 field. Fixed at 0x0 for Rapid STP
		 * @return Length of the version1 field
		 */
		uint8_t getVersion1Len() const { return getRstpConfHeader()->version1Len; }

		/**
		 * Returns the length of version1 field
		 * @param[in] value Length of the version1 field
		 */
		void setVersion1Len(uint8_t value) { getRstpConfHeader()->version1Len = value; }

		// overridden methods

		/**
		 * @return The size of Rapid STP message
		 */
		size_t getHeaderLen() const { return sizeof(rstp_conf_bpdu); }

		/// Parses next layer
		void parseNextLayer();

		/**
		 * @return Returns the protocol info as readable string
		 */
		std::string toString() const { return "Rapid Spanning Tree"; }

		/**
		 * A static method that validates the input data
		 * @param[in] data The pointer to the beginning of a byte stream of an Rapid STP packet
		 * @param[in] dataLen The length of the byte stream
		 * @return True if the data is valid and can represent an Spanning Tree packet
		 */
		static bool isDataValid(const uint8_t *data, size_t dataLen)
		{
			return data && dataLen >= sizeof(rstp_conf_bpdu);
		}
	};

	/**
	 * @class MultipleStpLayer
	 * Represents Multiple Spanning Tree Protocol (MSTP). It has limited capabilities (no crafting / limited editing) over MSTI configuration
	 */
	class MultipleStpLayer : public RapidStpLayer
	{
	  public:
		/**
		 * A constructor that creates the layer from an existing packet raw data
		 * @param[in] data A pointer to the raw data
		 * @param[in] dataLen Size of the data in bytes
		 * @param[in] prevLayer A pointer to the previous layer
		 * @param[in] packet A pointer to the Packet instance where layer will be stored in
		 */
		MultipleStpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
			: RapidStpLayer(data, dataLen, prevLayer, packet)
		{
		}

		/**
		 * Empty c'tor to create a new Multiple STP layer.
		 * Initializes the protocol identifier, version and STP type fields with correct values
		 */
		MultipleStpLayer();

		/**
		 * Get a pointer to Multiple STP header
		 * @return A pointer to Multiple STP header
		 */
		mstp_conf_bpdu *getMstpHeader() const { return (mstp_conf_bpdu *)(m_Data); }

		/**
		 * @return Length of version3 field
		 */
		uint16_t getVersion3Len() const;

		/**
		 * Sets the length of version3 field
		 * @param[in] value Length of version3 field
		 */
		void setVersion3Len(uint16_t value);

		/**
		 * Returns the configuration ID format selector
		 * @return Configuration ID of format selector
		 */
		uint8_t getMstConfigurationFormatSelector() const { return getMstpHeader()->mstConfigFormatSelector; }

		/**
		 * Sets the configuration ID format selector
		 * @param[in] value Configuration ID of format selector
		 */
		void setMstConfigurationFormatSelector(uint8_t value) { getMstpHeader()->mstConfigFormatSelector = value; }

		/**
		 * Returns the pointer to configuration name field
		 * @return Configuration name
		 */
		std::string getMstConfigurationName() const;

		/**
		 * Sets the configuration name field
		 * @param[in] value Configuration name. Length should be less than 32, if longer value provided first 32
		 * characters are used
		 */
		void setMstConfigurationName(const std::string &value);

		/**
		 * Returns the revision of configuration ID
		 * @return Revision of configuration ID
		 */
		uint16_t getMstConfigRevision() const;

		/**
		 * Sets the revision of configuration ID
		 * @param[in] value Revision of configuration ID
		 */
		void setMstConfigRevision(uint16_t value);

		/**
		 * Returns the pointer to configuration message digest. The field itself always 16 bytes long.
		 * @return A pointer to configuration digest
		 */
		uint8_t *getMstConfigDigest() const { return getMstpHeader()->mstConfigDigest; }

		/**
		 * Sets the pointer to configuration message digest. The field itself always 16 bytes long.
		 * @param[in] value Pointer to digest
		 * @param[in] len Length of the digest, should be less than 16. If longer first 16 bytes are used
		 */
		void setMstConfigDigest(const uint8_t *value, uint8_t len);

		/**
		 * Returns CIST internal root path cost
		 * @return Value of the internal root path cost
		 */
		uint32_t getCISTIrpc() const;

		/**
		 * Sets CIST internal root path cost
		 * @param[in] value Value of the internal root path cost
		 */
		void setCISTIrpc(uint32_t value);

		/**
		 * Returns CIST bridge identifier
		 * @return Value of the bridge identifier
		 */
		uint64_t getCISTBridgeId() const;

		/**
		 * Sets CIST bridge identifier
		 * @param[in] value Value of the bridge identifier
		 */
		void setCISTBridgeId(uint64_t value);

		/**
		 * Returns the priority of CIST bridge
		 * @return Priority of CIST bridge
		 */
		uint16_t getCISTBridgePriority() const;

		/**
		 * Sets the priority of CIST bridge
		 * @param[in] value Priority of CIST bridge
		 */
		void setCISTBridgePriority(uint16_t value);

		/**
		 * Returns the system identifier extension of CIST bridge
		 * @return System extension of CIST bridge
		 */
		uint16_t getCISTBridgeSystemIDExtension() const;

		/**
		 * Sets the system identifier extension of CIST bridge
		 * @param[in] value System extension of CIST bridge
		 */
		void setCISTBridgeSystemIDExtension(uint16_t value);

		/**
		 * Returns the system identifier of CIST bridge
		 * @return System identifier of CIST bridge
		 */
		pcpp::MacAddress getCISTBridgeSystemID() const { return IDtoMacAddress(getCISTBridgeId()); }

		/**
		 * Sets the system identifier of CIST bridge
		 * @param[in] value System identifier of CIST bridge
		 */
		void setCISTBridgeSystemID(const pcpp::MacAddress &value);

		/**
		 * Returns the remaining hop count
		 * @return Value of remaining hop count
		 */
		uint8_t getRemainingHopCount() const { return getMstpHeader()->remainId; }

		/**
		 * Returns the remaining hop count
		 * @param[in] value Value of remaining hop count
		 */
		void setRemainingHopCount(uint8_t value) { getMstpHeader()->remainId = value; }

		/**
		 * Returns the total number of MSTI configuration messages
		 * @return Number of MSTI configuration messages. Can be between 0 and 64.
		 */
		uint8_t getNumberOfMSTIConfMessages() const { return (getVersion3Len() - (sizeof(mstp_conf_bpdu) - sizeof(rstp_conf_bpdu) - sizeof(uint16_t))) / sizeof(msti_conf_msg); }

		/**
		 * Returns a reference to MSTI configuration messages. An MSTP packet can contain between 0 to 64 MSTI messages.
		 * The number of messages can be obtained by using getNumberOfMSTIConfMessages()
		 * @return An array pointer to MSTI configuration messages. Returns nullptr if there is no MSTI message.
		 */
		msti_conf_msg *getMstiConfMessages() const;

		// overridden methods

		/// Parses next layer
		void parseNextLayer() {}

		/**
		 * @return Returns the protocol info as readable string
		 */
		std::string toString() const { return "Multiple Spanning Tree"; }

		/**
		 * A static method that validates the input data
		 * @param[in] data The pointer to the beginning of a byte stream of an Multiple STP packet
		 * @param[in] dataLen The length of the byte stream
		 * @return True if the data is valid and can represent an Spanning Tree packet
		 */
		static bool isDataValid(const uint8_t *data, size_t dataLen)
		{
			return data && dataLen >= sizeof(mstp_conf_bpdu);
		}
	};
} // namespace pcpp

#endif /* PACKETPP_STP_LAYER */