/src/PcapPlusPlus/Packet++/header/IgmpLayer.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 | | /// @namespace pcpp |
10 | | /// @brief The main namespace for the PcapPlusPlus lib |
11 | | namespace pcpp |
12 | | { |
13 | | /// @struct igmp_header |
14 | | /// IGMPv1 and IGMPv2 basic protocol header |
15 | | struct igmp_header |
16 | | { |
17 | | /// Indicates the message type. The enum for message type is pcpp::IgmpType |
18 | | uint8_t type; |
19 | | /// Specifies the time limit for the corresponding report. The field has a resolution of 100 milliseconds |
20 | | uint8_t maxResponseTime; |
21 | | /// This is the 16-bit one's complement of the one's complement sum of the entire IGMP message |
22 | | uint16_t checksum; |
23 | | /// This is the multicast address being queried when sending a Group-Specific or Group-and-Source-Specific Query |
24 | | uint32_t groupAddress; |
25 | | }; |
26 | | static_assert(sizeof(igmp_header) == 8, "igmp_header size is not 8 bytes"); |
27 | | |
28 | | /// @struct igmpv3_query_header |
29 | | /// IGMPv3 membership query basic header |
30 | | struct igmpv3_query_header |
31 | | { |
32 | | /// IGMP message type. Should always have value of membership query (::IgmpType_MembershipQuery) |
33 | | uint8_t type; |
34 | | /// This field specifies the maximum time (in 1/10 second) allowed before sending a responding report |
35 | | uint8_t maxResponseTime; |
36 | | /// This is the 16-bit one's complement of the one's complement sum of the entire IGMP message |
37 | | uint16_t checksum; |
38 | | /// This is the multicast address being queried when sending a Group-Specific or Group-and-Source-Specific Query |
39 | | uint32_t groupAddress; |
40 | | /// Suppress Router-side Processing Flag + Querier's Robustness Variable |
41 | | uint8_t s_qrv; |
42 | | /// Querier's Query Interval Code |
43 | | uint8_t qqic; |
44 | | /// This field specifies the number of source addresses present in the Query |
45 | | uint16_t numOfSources; |
46 | | }; |
47 | | static_assert(sizeof(igmpv3_query_header) == 12, "igmpv3_query_header size is not 12 bytes"); |
48 | | |
49 | | /// @struct igmpv3_report_header |
50 | | /// IGMPv3 membership report basic header |
51 | | struct igmpv3_report_header |
52 | | { |
53 | | /// IGMP message type. Should always have value of IGMPv3 membership report (::IgmpType_MembershipReportV3) |
54 | | uint8_t type; |
55 | | /// Unused byte |
56 | | uint8_t reserved1; |
57 | | /// This is the 16-bit one's complement of the one's complement sum of the entire IGMP message |
58 | | uint16_t checksum; |
59 | | /// Unused bytes |
60 | | uint16_t reserved2; |
61 | | /// This field specifies the number of group records present in the Report |
62 | | uint16_t numOfGroupRecords; |
63 | | }; |
64 | | static_assert(sizeof(igmpv3_report_header) == 8, "igmpv3_report_header size is not 8 bytes"); |
65 | | |
66 | | /// @struct igmpv3_group_record |
67 | | /// A block of fields containing information pertaining to the sender's membership in a single multicast group on |
68 | | /// the interface from which the Report is sent. Relevant only for IGMPv3 membership report messages |
69 | | struct igmpv3_group_record |
70 | | { |
71 | | /// Group record type |
72 | | uint8_t recordType; |
73 | | /// Contains the length of the Auxiliary Data field in this Group Record. A value other than 0 isn't supported |
74 | | uint8_t auxDataLen; |
75 | | /// Specifies how many source addresses are present in this Group Record |
76 | | uint16_t numOfSources; |
77 | | /// Contains the IP multicast address to which this Group Record pertains |
78 | | uint32_t multicastAddress; |
79 | | /// A vector of n IP unicast addresses, where n is the value in this record's Number of Sources field |
80 | | uint8_t sourceAddresses[]; |
81 | | |
82 | | /// @return The multicast address in igmpv3_group_record#multicastAddress as IPv4Address instance |
83 | | IPv4Address getMulticastAddress() const |
84 | 0 | { |
85 | 0 | return multicastAddress; |
86 | 0 | } |
87 | | |
88 | | /// @return The number of source addresses in this group record |
89 | | uint16_t getSourceAddressCount() const; |
90 | | |
91 | | /// Get the source address at a certain index |
92 | | /// @param[in] index The index of the source address in the group record |
93 | | /// @return The source address in the requested index. If index is negative or higher than the number of source |
94 | | /// addresses in this group record the value if IPv4Address#Zero is returned |
95 | | IPv4Address getSourceAddressAtIndex(int index) const; |
96 | | |
97 | | /// @return The total size in bytes of the group record |
98 | | size_t getRecordLen() const; |
99 | | }; |
100 | | |
101 | | /// IGMP message types |
102 | | enum IgmpType |
103 | | { |
104 | | /// Unknown message type |
105 | | IgmpType_Unknown = 0, |
106 | | /// IGMP Membership Query |
107 | | IgmpType_MembershipQuery = 0x11, |
108 | | /// IGMPv1 Membership Report |
109 | | IgmpType_MembershipReportV1 = 0x12, |
110 | | /// DVMRP |
111 | | IgmpType_DVMRP = 0x13, |
112 | | /// PIM version 1 |
113 | | IgmpType_P1Mv1 = 0x14, |
114 | | /// Cisco Trace Messages |
115 | | IgmpType_CiscoTrace = 0x15, |
116 | | /// IGMPv2 Membership Report |
117 | | IgmpType_MembershipReportV2 = 0x16, |
118 | | /// IGMPv2 Leave Group |
119 | | IgmpType_LeaveGroup = 0x17, |
120 | | /// Multicast Traceroute Response |
121 | | IgmpType_MulticastTracerouteResponse = 0x1e, |
122 | | /// Multicast Traceroute |
123 | | IgmpType_MulticastTraceroute = 0x1f, |
124 | | /// IGMPv3 Membership Report |
125 | | IgmpType_MembershipReportV3 = 0x22, |
126 | | /// MRD, Multicast Router Advertisement |
127 | | IgmpType_MulticastRouterAdvertisement = 0x30, |
128 | | /// MRD, Multicast Router Solicitation |
129 | | IgmpType_MulticastRouterSolicitation = 0x31, |
130 | | /// MRD, Multicast Router Termination |
131 | | IgmpType_MulticastRouterTermination = 0x32, |
132 | | }; |
133 | | |
134 | | /// @class IgmpLayer |
135 | | /// A base class for all IGMP (Internet Group Management Protocol) protocol classes. This is an abstract class and |
136 | | /// cannot be instantiated, only its child classes can be instantiated. The inherited classes represent the |
137 | | /// different versions of the protocol: IGMPv1, IGMPv2 and IGMPv3 |
138 | | class IgmpLayer : public Layer |
139 | | { |
140 | | protected: |
141 | | IgmpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, ProtocolType igmpVer) |
142 | 7.90k | : Layer(data, dataLen, prevLayer, packet, igmpVer) |
143 | 7.90k | {} |
144 | | |
145 | | IgmpLayer(IgmpType type, const IPv4Address& groupAddr, uint8_t maxResponseTime, ProtocolType igmpVer); |
146 | | |
147 | | uint16_t calculateChecksum(); |
148 | | |
149 | | size_t getHeaderSizeByVerAndType(ProtocolType igmpVer, IgmpType igmpType) const; |
150 | | |
151 | | public: |
152 | | ~IgmpLayer() override = default; |
153 | | |
154 | | /// Get a pointer to the raw IGMPv1/IGMPv2 header. Notice this points directly to the data, so every change will |
155 | | /// change the actual packet data |
156 | | /// @return A pointer to the @ref igmp_header |
157 | | igmp_header* getIgmpHeader() const |
158 | 5.92k | { |
159 | 5.92k | return reinterpret_cast<igmp_header*>(m_Data); |
160 | 5.92k | } |
161 | | |
162 | | /// @return The IPv4 multicast address stored igmp_header#groupAddress |
163 | | IPv4Address getGroupAddress() const |
164 | 0 | { |
165 | 0 | return getIgmpHeader()->groupAddress; |
166 | 0 | } |
167 | | |
168 | | /// Set the IPv4 multicast address |
169 | | /// @param[in] groupAddr The IPv4 address to set |
170 | | void setGroupAddress(const IPv4Address& groupAddr); |
171 | | |
172 | | /// @return IGMP type set in igmp_header#type as ::IgmpType enum. Notice that if igmp_header#type contains a |
173 | | /// value that doesn't appear in the ::IgmpType enum, ::IgmpType_Unknown will be returned |
174 | | IgmpType getType() const; |
175 | | |
176 | | /// Set IGMP type (will be written to igmp_header#type field) |
177 | | /// @param[in] type The type to set |
178 | | void setType(IgmpType type); |
179 | | |
180 | | /// A static method that gets raw IGMP data (byte stream) and returns the IGMP version of this IGMP message |
181 | | /// @param[in] data The IGMP raw data (byte stream) |
182 | | /// @param[in] dataLen Raw data length |
183 | | /// @param[out] isQuery Return true if IGMP message type is ::IgmpType_MembershipQuery and false otherwise |
184 | | /// @return One of the values ::IGMPv1, ::IGMPv2, ::IGMPv3 according to detected IGMP version or |
185 | | /// ::UnknownProtocol if couldn't detect IGMP version |
186 | | static ProtocolType getIGMPVerFromData(uint8_t* data, size_t dataLen, bool& isQuery); |
187 | | |
188 | | // implement abstract methods |
189 | | |
190 | | /// Does nothing for this layer (IGMP layer is always last) |
191 | | void parseNextLayer() override |
192 | 7.90k | {} |
193 | | |
194 | | /// @return Size of IGMP header = 8B |
195 | | size_t getHeaderLen() const override |
196 | 1.85k | { |
197 | 1.85k | return sizeof(igmp_header); |
198 | 1.85k | } |
199 | | |
200 | | std::string toString() const override; |
201 | | |
202 | | OsiModelLayer getOsiModelLayer() const override |
203 | 1.66k | { |
204 | 1.66k | return OsiModelNetworkLayer; |
205 | 1.66k | } |
206 | | }; |
207 | | |
208 | | /// @class IgmpV1Layer |
209 | | /// Represents IGMPv1 (Internet Group Management Protocol ver 1) layer. This class represents all the different |
210 | | /// messages of IGMPv1 |
211 | | class IgmpV1Layer : public IgmpLayer |
212 | | { |
213 | | public: |
214 | | /// A constructor that creates the layer from an existing packet raw data |
215 | | /// @param[in] data A pointer to the raw data |
216 | | /// @param[in] dataLen Size of the data in bytes |
217 | | /// @param[in] prevLayer A pointer to the previous layer |
218 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
219 | | IgmpV1Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
220 | 1.58k | : IgmpLayer(data, dataLen, prevLayer, packet, IGMPv1) |
221 | 1.58k | {} |
222 | | |
223 | | /// A constructor that allocates a new IGMPv1 header |
224 | | /// @param[in] type The message type to set |
225 | | /// @param[in] groupAddr The multicast address to set. This is an optional parameter and has a default value of |
226 | | /// IPv4Address#Zero if not provided |
227 | | explicit IgmpV1Layer(IgmpType type, const IPv4Address& groupAddr = IPv4Address()) |
228 | | : IgmpLayer(type, groupAddr, 0, IGMPv1) |
229 | 0 | {} |
230 | | |
231 | | /// A destructor for this layer (does nothing) |
232 | | ~IgmpV1Layer() override = default; |
233 | | |
234 | | // implement abstract methods |
235 | | |
236 | | /// Calculate the IGMP checksum and set igmp_header#maxResponseTime to 0 (this field is unused in IGMPv1) |
237 | | void computeCalculateFields() override; |
238 | | |
239 | | /// A static method that validates the input data |
240 | | /// @param[in] data The pointer to the beginning of a byte stream of an IGMPv1 layer |
241 | | /// @param[in] dataLen The length of the byte stream |
242 | | /// @return True if the data is valid and can represent an IGMPv1 layer |
243 | | static bool isDataValid(uint8_t const* data, size_t dataLen) |
244 | 1.58k | { |
245 | 1.58k | return canReinterpretAs<igmp_header>(data, dataLen); |
246 | 1.58k | } |
247 | | }; |
248 | | |
249 | | /// @class IgmpV2Layer |
250 | | /// Represents IGMPv2 (Internet Group Management Protocol ver 2) layer. This class represents all the different |
251 | | /// messages of IGMPv2 |
252 | | class IgmpV2Layer : public IgmpLayer |
253 | | { |
254 | | public: |
255 | | /// A constructor that creates the layer from an existing packet raw data |
256 | | /// @param[in] data A pointer to the raw data |
257 | | /// @param[in] dataLen Size of the data in bytes |
258 | | /// @param[in] prevLayer A pointer to the previous layer |
259 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
260 | | IgmpV2Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
261 | 3.03k | : IgmpLayer(data, dataLen, prevLayer, packet, IGMPv2) |
262 | 3.03k | {} |
263 | | |
264 | | /// A constructor that allocates a new IGMPv2 header |
265 | | /// @param[in] type The message type to set |
266 | | /// @param[in] groupAddr The multicast address to set. This is an optional parameter and has a default value of |
267 | | /// unspecified/zero IPv4 address |
268 | | /// @param[in] maxResponseTime The max response time to set. This is an optional parameter and has a default |
269 | | /// value of 0 if not provided |
270 | | explicit IgmpV2Layer(IgmpType type, const IPv4Address& groupAddr = IPv4Address(), uint8_t maxResponseTime = 0) |
271 | | : IgmpLayer(type, groupAddr, maxResponseTime, IGMPv2) |
272 | 0 | {} |
273 | | |
274 | | /// A destructor for this layer (does nothing) |
275 | | ~IgmpV2Layer() override = default; |
276 | | |
277 | | // implement abstract methods |
278 | | |
279 | | /// Calculate the IGMP checksum |
280 | | void computeCalculateFields() override; |
281 | | |
282 | | /// A static method that validates the input data |
283 | | /// @param[in] data The pointer to the beginning of a byte stream of an IGMPv2 layer |
284 | | /// @param[in] dataLen The length of the byte stream |
285 | | /// @return True if the data is valid and can represent an IGMPv2 layer |
286 | | static bool isDataValid(uint8_t const* data, size_t dataLen) |
287 | 3.03k | { |
288 | 3.03k | return canReinterpretAs<igmp_header>(data, dataLen); |
289 | 3.03k | } |
290 | | }; |
291 | | |
292 | | /// @class IgmpV3QueryLayer |
293 | | /// Represents an IGMPv3 (Internet Group Management Protocol ver 3) membership query message |
294 | | class IgmpV3QueryLayer : public IgmpLayer |
295 | | { |
296 | | public: |
297 | | /// A constructor that creates the layer from an existing packet raw data |
298 | | /// @param[in] data A pointer to the raw data |
299 | | /// @param[in] dataLen Size of the data in bytes |
300 | | /// @param[in] prevLayer A pointer to the previous layer |
301 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
302 | | IgmpV3QueryLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); |
303 | | |
304 | | /// A constructor that allocates a new IGMPv3 membership query |
305 | | /// @param[in] multicastAddr The multicast address to set. This is an optional parameter and has a default value |
306 | | /// of unspecified/zero IPv4 address if not provided |
307 | | /// @param[in] maxResponseTime The max response time to set. This is an optional parameter and has a default |
308 | | /// value of 0 if not provided |
309 | | /// @param[in] s_qrv A 1-byte value representing the value in Suppress Router-side Processing Flag + Querier's |
310 | | /// Robustness Variable (igmpv3_query_header#s_qrv field). This is an optional parameter and has a default value |
311 | | /// of 0 if not provided |
312 | | explicit IgmpV3QueryLayer(const IPv4Address& multicastAddr = IPv4Address(), uint8_t maxResponseTime = 0, |
313 | | uint8_t s_qrv = 0); |
314 | | |
315 | | /// Get a pointer to the raw IGMPv3 membership query header. Notice this points directly to the data, so every |
316 | | /// change will change the actual packet data |
317 | | /// @return A pointer to the @ref igmpv3_query_header |
318 | | igmpv3_query_header* getIgmpV3QueryHeader() const |
319 | 1.18k | { |
320 | 1.18k | return reinterpret_cast<igmpv3_query_header*>(m_Data); |
321 | 1.18k | } |
322 | | |
323 | | /// @return The number of source addresses in this message (as extracted from the |
324 | | /// igmpv3_query_header#numOfSources field) |
325 | | uint16_t getSourceAddressCount() const; |
326 | | |
327 | | /// Get the IPV4 source address in a certain index |
328 | | /// @param[in] index The requested index of the source address |
329 | | /// @return The IPv4 source address, or IPv4Address#Zero if index is out of bounds (of the message or of the |
330 | | /// layer) |
331 | | IPv4Address getSourceAddressAtIndex(int index) const; |
332 | | |
333 | | /// Add a new source address at the end of the source address list. The igmpv3_query_header#numOfSources field |
334 | | /// will be incremented accordingly |
335 | | /// @param[in] addr The IPv4 source address to add |
336 | | /// @return True if source address was added successfully or false otherwise. If false is returned an |
337 | | /// appropriate error message will be printed to log |
338 | | bool addSourceAddress(const IPv4Address& addr); |
339 | | |
340 | | /// Add a new source address at a certain index of the source address list. The igmpv3_query_header#numOfSources |
341 | | /// field will be incremented accordingly |
342 | | /// @param[in] addr The IPv4 source address to add |
343 | | /// @param[in] index The index to add the new source address at |
344 | | /// @return True if source address was added successfully or false otherwise. If false is returned an |
345 | | /// appropriate error message will be printed to log |
346 | | bool addSourceAddressAtIndex(const IPv4Address& addr, int index); |
347 | | |
348 | | /// Remove a source address at a certain index. The igmpv3_query_header#numOfSources field will be decremented |
349 | | /// accordingly |
350 | | /// @param[in] index The index of the source address to be removed |
351 | | /// @return True if source address was removed successfully or false otherwise. If false is returned an |
352 | | /// appropriate error message will be printed to log |
353 | | bool removeSourceAddressAtIndex(int index); |
354 | | |
355 | | /// Remove all source addresses in the message. The igmpv3_query_header#numOfSources field will be set to 0 |
356 | | /// @return True if all source addresses were cleared successfully or false otherwise. If false is returned an |
357 | | /// appropriate error message will be printed to log |
358 | | bool removeAllSourceAddresses(); |
359 | | |
360 | | // implement abstract methods |
361 | | |
362 | | /// Calculate the IGMP checksum |
363 | | void computeCalculateFields() override; |
364 | | |
365 | | /// @return The message size in bytes which include the size of the basic header + the size of the source |
366 | | /// address list |
367 | | size_t getHeaderLen() const override; |
368 | | |
369 | | /// A static method that validates the input data |
370 | | /// @param[in] data The pointer to the beginning of a byte stream of an IGMPv3 Query layer |
371 | | /// @param[in] dataLen The length of the byte stream |
372 | | /// @return True if the data is valid and can represent an IGMPv3 Query layer |
373 | | static bool isDataValid(uint8_t const* data, size_t dataLen) |
374 | 1.58k | { |
375 | 1.58k | return canReinterpretAs<igmpv3_query_header>(data, dataLen); |
376 | 1.58k | } |
377 | | }; |
378 | | |
379 | | /// @class IgmpV3ReportLayer |
380 | | /// Represents an IGMPv3 (Internet Group Management Protocol ver 3) membership report message |
381 | | class IgmpV3ReportLayer : public IgmpLayer |
382 | | { |
383 | | private: |
384 | | igmpv3_group_record* addGroupRecordAt(uint8_t recordType, const IPv4Address& multicastAddress, |
385 | | const std::vector<IPv4Address>& sourceAddresses, int offset); |
386 | | |
387 | | public: |
388 | | /// A constructor that creates the layer from an existing packet raw data |
389 | | /// @param[in] data A pointer to the raw data |
390 | | /// @param[in] dataLen Size of the data in bytes |
391 | | /// @param[in] prevLayer A pointer to the previous layer |
392 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
393 | | IgmpV3ReportLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
394 | 1.71k | : IgmpLayer(data, dataLen, prevLayer, packet, IGMPv3) |
395 | 1.71k | {} |
396 | | |
397 | | /// A constructor that allocates a new IGMPv3 membership report with 0 group addresses |
398 | | IgmpV3ReportLayer() : IgmpLayer(IgmpType_MembershipReportV3, IPv4Address(), 0, IGMPv3) |
399 | 0 | {} |
400 | | |
401 | | /// Get a pointer to the raw IGMPv3 membership report header. Notice this points directly to the data, so every |
402 | | /// change will change the actual packet data |
403 | | /// @return A pointer to the @ref igmpv3_report_header |
404 | | igmpv3_report_header* getReportHeader() const |
405 | 345 | { |
406 | 345 | return reinterpret_cast<igmpv3_report_header*>(m_Data); |
407 | 345 | } |
408 | | |
409 | | /// @return The number of group records in this message (as extracted from the |
410 | | /// igmpv3_report_header#numOfGroupRecords field) |
411 | | uint16_t getGroupRecordCount() const; |
412 | | |
413 | | /// @return A pointer to the first group record or nullptr if no group records exist. Notice the return value is |
414 | | /// a pointer to the real data, so changes in the return value will affect the packet data |
415 | | igmpv3_group_record* getFirstGroupRecord() const; |
416 | | |
417 | | /// Get the group record that comes next to a given group record. If "groupRecord" is nullptr then nullptr will |
418 | | /// be returned. If "groupRecord" is the last group record or if it is out of layer bounds nullptr will be |
419 | | /// returned also. Notice the return value is a pointer to the real data casted to igmpv3_group_record type (as |
420 | | /// opposed to a copy of the option data). So changes in the return value will affect the packet data |
421 | | /// @param[in] groupRecord The group record to start searching from |
422 | | /// @return The next group record or nullptr if "groupRecord" is nullptr, last or out of layer bounds |
423 | | igmpv3_group_record* getNextGroupRecord(igmpv3_group_record* groupRecord) const; |
424 | | |
425 | | /// Add a new group record at a the end of the group record list. The igmpv3_report_header#numOfGroupRecords |
426 | | /// field will be incremented accordingly |
427 | | /// @param[in] recordType The type of the new group record |
428 | | /// @param[in] multicastAddress The multicast address of the new group record |
429 | | /// @param[in] sourceAddresses A vector containing all the source addresses of the new group record |
430 | | /// @return The method constructs a new group record, adds it to the end of the group record list of IGMPv3 |
431 | | /// report message and returns a pointer to the new message. If something went wrong in creating or adding the |
432 | | /// new group record a nullptr value is returned and an appropriate error message is printed to log |
433 | | igmpv3_group_record* addGroupRecord(uint8_t recordType, const IPv4Address& multicastAddress, |
434 | | const std::vector<IPv4Address>& sourceAddresses); |
435 | | |
436 | | /// Add a new group record at a certain index of the group record list. The |
437 | | /// igmpv3_report_header#numOfGroupRecords field will be incremented accordingly |
438 | | /// @param[in] recordType The type of the new group record |
439 | | /// @param[in] multicastAddress The multicast address of the new group record |
440 | | /// @param[in] sourceAddresses A vector containing all the source addresses of the new group record |
441 | | /// @param[in] index The index to add the new group address at |
442 | | /// @return The method constructs a new group record, adds it to the IGMPv3 report message and returns a pointer |
443 | | /// to the new message. If something went wrong in creating or adding the new group record a nullptr value is |
444 | | /// returned and an appropriate error message is printed to log |
445 | | igmpv3_group_record* addGroupRecordAtIndex(uint8_t recordType, const IPv4Address& multicastAddress, |
446 | | const std::vector<IPv4Address>& sourceAddresses, int index); |
447 | | |
448 | | /// Remove a group record at a certain index. The igmpv3_report_header#numOfGroupRecords field will be |
449 | | /// decremented accordingly |
450 | | /// @param[in] index The index of the group record to be removed |
451 | | /// @return True if group record was removed successfully or false otherwise. If false is returned an |
452 | | /// appropriate error message will be printed to log |
453 | | bool removeGroupRecordAtIndex(int index); |
454 | | |
455 | | /// Remove all group records in the message. The igmpv3_report_header#numOfGroupRecords field will be set to 0 |
456 | | /// @return True if all group records were cleared successfully or false otherwise. If false is returned an |
457 | | /// appropriate error message will be printed to log |
458 | | bool removeAllGroupRecords(); |
459 | | |
460 | | // implement abstract methods |
461 | | |
462 | | /// Calculate the IGMP checksum |
463 | | void computeCalculateFields() override; |
464 | | |
465 | | /// @return The message size in bytes which include the size of the basic header + the size of the group record |
466 | | /// list |
467 | | size_t getHeaderLen() const override |
468 | 690 | { |
469 | 690 | return m_DataLen; |
470 | 690 | } |
471 | | |
472 | | /// A static method that validates the input data |
473 | | /// @param[in] data The pointer to the beginning of a byte stream of an IGMPv3 Report layer |
474 | | /// @param[in] dataLen The length of the byte stream |
475 | | /// @return True if the data is valid and can represent an IGMPv3 Report layer |
476 | | static bool isDataValid(uint8_t const* data, size_t dataLen) |
477 | 1.71k | { |
478 | 1.71k | return canReinterpretAs<igmpv3_report_header>(data, dataLen); |
479 | 1.71k | } |
480 | | }; |
481 | | |
482 | | } // namespace pcpp |