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