IGMPv3 - Internet Group Management Protocol Version 3¶
pcapkit.protocols.internet.igmpv3 contains
IGMPv3, which implements an
extractor for Internet Group Management Protocol version 3 (IGMPv3)
[RFC 3376]. Unlike IGMPv1
and IGMPv2, which reuse the
abstract base’s own 8-octet schema and data model (see
igmp), IGMPv3 defines two message shapes
of its own:
An IGMPv3 Membership Query (type 0x11, shared with v1/v2) reuses the
8-octet layout IGMPv1/v2 share and, when at least 12 octets long overall,
appends a source-list extension:
Octets |
Bits |
Name |
Description |
|---|---|---|---|
0 |
0 |
|
Type |
1 |
8 |
|
Max Response Code |
2 |
16 |
|
Checksum |
4 |
32 |
|
Group Address |
8 |
64 |
|
Reserved (Resv) |
8 |
68 |
|
Suppress Router-Side Processing (S) |
8 |
69 |
|
Querier’s Robustness Variable (QRV) |
9 |
72 |
|
Querier’s Query Interval Code |
10 |
80 |
Number of Sources (N) |
|
12 |
96 |
|
Source Address [1..N] |
An IGMPv3 Membership Report (type 0x22) has an unrelated, materially
different shape of its own:
Octets |
Bits |
Name |
Description |
|---|---|---|---|
0 |
0 |
|
Type |
1 |
8 |
|
Reserved |
2 |
16 |
|
Checksum |
4 |
32 |
|
Reserved |
6 |
48 |
|
Number of Group Records (M) |
8 |
64 |
|
Group Record [1..M] |
- class pcapkit.protocols.internet.igmpv3.IGMPv3(file=None, length=None, **kwargs)[source]¶
-
This class implements Internet Group Management Protocol version 3.
Unlike
IGMPv1andIGMPv2, which share the base’s own 8-octet schema and data model, IGMPv3’s wire format differs materially by message – a Query’s source-list extension, a Report’s group-record list – so this class carries its own (#2439, #2448).- property name: Literal['Internet Group Management Protocol version 3']¶
Name of corresponding protocol.
- property length: int¶
Header length of current protocol.
Every message starts with an 8-octet header. A Query may carry the source-list extension, and a Report’s group-record list has no fixed size, so this is taken during
read()from the octets consumed (seelength) rather than returned as a constant, unlike the base’s ownlength.
- classmethod id()[source]¶
Index ID of the protocol.
RFC 3376 names the protocol
IGMPv3, carrying its own version.
- read(length=None, **kwargs)[source]¶
Read Internet Group Management Protocol version 3.
- Parameters:
- Return type:
- Returns:
Parsed packet data.
- Raises:
ProtocolError – If
_classify()does not place the message inversion3 – an IGMPv1/v2-shaped Query, or a type neither version of IGMP defines.
Note
A message the data ends inside records the cut on its
body, with or without an enclosing length, sofrom_data(info)rebuilds it as captured.
- make(type=Type.IGMP_Membership_Query, max_resp_code=None, max_resp_time=0, checksum=None, group='0.0.0.0', resv=0, s_flag=False, qrv=0, qqic=None, qqi=None, sources=None, reserved_1=0, reserved_2=b'\x00\x00', num_group_records=None, records=None, payload=b'', **kwargs)[source]¶
Make (construct) packet data.
Building a Query (the default) always writes the source-list extension: this class is specifically IGMPv3, unlike the base’s own
make(), which writes the extension only when asked, since there a plain 8-octet message is the more natural default.- Parameters:
max_resp_code (
int|None) – Max response code, as transmitted on the wire. When not given, derived frommax_resp_timevia_encode_resp_code(); only meaningful for a Query.max_resp_time (
int) – Max response time, in units of 1/10 second: anintfrom 0 to 255 (not abool), elseProtocolError. Ignored whenmax_resp_codeis given.checksum (
bytes|None) – Checksum; the one’s complement of the one’s complement sum of the message, with this field taken as zero and no pseudo-header – the whole IP payload (RFC 3376 Section 4.1.2, RFC 3376 Section 4.2.2). IfNone, computed so, overpayloadas well, whenCHECKSUM_COMPUTEis on, zero when it is off.group (
IPv4Address|str|bytes|int) – Group address;0.0.0.0for a General Query; only meaningful for a Query.resv (
int) – The 4 reserved high-order bits of the flags octet (RFC 3376 Section 4.1.4);0on a standards-conformant sender; only meaningful for a Query.s_flag (
bool) – Suppress Router-Side Processing flag (RFC 3376 Section 4.1.5); only meaningful for a Query.qrv (
int) – Querier’s Robustness Variable (RFC 3376 Section 4.1.6); only meaningful for a Query.qqic (
int|None) – Querier’s Query Interval Code, as transmitted on the wire; derived fromqqivia_encode_resp_code()when not given; only meaningful for a Query.qqi (
int|None) – Querier’s Query Interval, in seconds; ignored whenqqicis given; only meaningful for a Query.sources (
Iterable[IPv4Address|str|bytes|int] |None) – Source addresses being queried (RFC 3376 Section 4.1.9); only meaningful for a Query.reserved_1 (
int) – The reserved octet followingtype(RFC 3376 Section 4.2.1); only meaningful for a Report.reserved_2 (
bytes) – The reserved 16 bits before the group-record count (RFC 3376 Section 4.2.1); only meaningful for a Report.num_group_records (
int|None) – Number of group records, as transmitted on the wire; the length ofrecordswhen not given, so a capture cut inside its record list rebuilds as captured; only meaningful for a Report. A count above the length ofrecordsis written as given, as on a Report the capture cut short.records (
Iterable[dict[str,Any] |GroupRecord] |None) – Group records (RFC 3376 Section 4.2.4), each either aGroupRecordor adictof the keyword arguments_make_group_record()takes; only meaningful for a Report.payload (
bytes|ProtocolBase|Schema) – Payload of current instance.**kwargs (
Any) – Arbitrary keyword arguments.
- Return type:
- Returns:
Constructed packet data.
- Raises:
ProtocolError – If
typeis a name, abool, or a member or code outside 0 to 255, or is neither a Query nor a Report; ifmax_resp_timeis not anintfrom 0 to 255; ifnum_group_recordsis not anintfrom the length ofrecordsto 65535; ifchecksumorreserved_2is not two octets; or if a record’srecord_typeis refused, see_make_group_record().
- _make_group_record(record=None, *, record_type=RecordType.MODE_IS_INCLUDE, aux_data_len=None, num_sources=None, multicast_address='0.0.0.0', sources=None, aux_data=b'', **kwargs)[source]¶
Make an IGMPv3 group record (RFC 3376 Section 4.2.4).
- Parameters:
record (
GroupRecord|None) – An already-built group record, taking precedence over the keyword arguments below (mirrorsHIP._make_param_locator_set’sparam/keyword split).record_type (
RecordType|int) – Record type.aux_data_len (
int|None) – Auxiliary data length, in 32-bit words; derived fromaux_datawhen not given.num_sources (
int|None) – Number of source addresses; derived fromsourceswhen not given.multicast_address (
IPv4Address|str|bytes|int) – Multicast address.sources (
Iterable[IPv4Address|str|bytes|int] |None) – Source addresses.aux_data (
bytes) – Auxiliary data; RFC 3376 Section 4.2.10 requires an IGMPv3 sender to leave this empty.**kwargs (
Any) – Arbitrary keyword arguments.
- Return type:
- Returns:
Group record schema.
- Raises:
ProtocolError – If
record_typeis a name, abool, or a member or code outside 0 to 255.
- classmethod _make_data(data)[source]¶
Create key-value pairs from
datafor protocol construction.- Parameters:
data (
IGMPv3) – protocol data- Return type:
- Returns:
Key-value pairs for protocol construction.
Note
Dispatches on
data.typerather than onisinstance(data, Data_Report), so that a hand-builtdictcarrying the righttypebut not actually one of the two concrete data classes – as a test double legitimately might – still rebuilds correctly, the same waymake()itself dispatches on thetypeit is given rather than requiring a particular input class.
Header Schemas¶
- class pcapkit.protocols.schema.internet.igmpv3.IGMPv3(type=NO_VALUE, body=NO_VALUE, *, __packet__=None, **kwargs)[source]¶
Bases:
SchemaHeader schema for an IGMPv3 packet.
typeis common to both shapes IGMPv3 defines; everything past it is switched, byigmpv3_body_selector(), betweenQueryandReport(#2439, #2448).Note
No
PayloadFieldhere: IGMP has no header field bounding the message, sobodygets the whole length and keeps its trailing octets itself – inQuery.payload(orQueryExtension.payloadwhenQuery.extis present), orReport.payload.get_payload()delegates there.
- class pcapkit.protocols.schema.internet.igmpv3.Query(max_resp_code=NO_VALUE, checksum=NO_VALUE, group=NO_VALUE, ext=NO_VALUE, payload=NO_VALUE, *, __packet__=None, **kwargs)[source]¶
Bases:
SchemaHeader schema for an IGMPv3 Membership Query (RFC 3376 Section 4.1).
The first 8 octets are the same shape IGMPv1/v2 share (
IGMP); the extension is present only on a Query of 12 or more octets overall – seequery_extension_present(). An 8-octet Query, which this schema unpacks too (withextNone), is not actually IGMPv3;IGMPv3.readis what refuses it.- max_resp_code: int = <UInt8Field max_resp_code>¶
Max response code; the raw octet
IGMPv3.readdecodes per RFC 3376 Section 4.1.1.
- checksum: bytes = <BytesField checksum>¶
Checksum. The 16-bit one’s complement of the one’s complement sum of the message, with the checksum field itself taken as zero and no pseudo-header involved – the whole IP payload (RFC 3376 Section 4.1.2).
- group: IPv4Address = <IPv4AddressField group>¶
Group address.
- ext: QueryExtension | None = <ConditionalField ext>¶
Source-list extension (RFC 3376 Section 4.1), present only on a Query at least 12 octets long overall;
Noneotherwise – seequery_extension_present().
- payload: bytes = <PayloadField payload>¶
Payload, empty for a well-formed IGMPv3 Query. Only ever actually holds anything when
extisNone: when it is not,extwas handed the whole remaining length, so this field’s own share of it is always empty, andget_payload()readsQueryExtension.payloadinstead – see there.
- class pcapkit.protocols.schema.internet.igmpv3.QueryExtension(flags=NO_VALUE, qqic=NO_VALUE, num_sources=NO_VALUE, sources=NO_VALUE, payload=NO_VALUE, *, __packet__=None, **kwargs)[source]¶
Bases:
SchemaHeader schema for the IGMPv3 Query’s source-list extension.
Follows the 8-octet header every IGMP Query shares with IGMPv1/v2 (RFC 3376 Section 4.1).
- flags: QueryFlags = <BitField flags>¶
Resv/S Flag/QRV.
- qqic: int = <UInt8Field qqic>¶
Querier’s Query Interval Code, as received on the wire; decoded into seconds by
IGMPv3.readper RFC 3376 Section 4.1.7.
- sources: list[IPv4Address] = <ListField sources>¶
Source addresses (RFC 3376 Section 4.1.9).
- payload: bytes = <PayloadField payload>¶
Additional data (RFC 3376 Section 4.1.10) – octets past the source list that a received Query may carry and that must be kept (to verify the checksum) but not otherwise acted on. Empty for a standards-conformant Query, since
IGMPv3.makenever writes any.
- class pcapkit.protocols.schema.internet.igmpv3.Report(reserved_1=NO_VALUE, checksum=NO_VALUE, reserved_2=NO_VALUE, num_group_records=NO_VALUE, records=NO_VALUE, payload=NO_VALUE, *, __packet__=None, **kwargs)[source]¶
Bases:
SchemaHeader schema for an IGMPv3 Membership Report’s body (RFC 3376 Section 4.2).
Note
recordsis first read with the whole remaining length, since the declared count cannot size it in octets (cf.LocatorSetParameter).post_process()keeps only the firstnum_group_recordsrecords and gives the rest topayload, which is RFC 3376 Section 4.2.11’s “Additional Data”. Where the data ends before the records counted, seereport_record_count().- num_group_records: int = <UInt16Field num_group_records>¶
Number of group records, as received on the wire.
- records: list[GroupRecord] = <ListField records>¶
Group records; see
post_process()for how this is kept to exactlynum_group_recordsentries.
- payload: bytes = <PayloadField payload>¶
Payload; empty for a standards-conformant message with
num_group_recordsmatching the octets actually present.
- class pcapkit.protocols.schema.internet.igmpv3.GroupRecord(record_type=NO_VALUE, aux_data_len=NO_VALUE, num_sources=NO_VALUE, multicast_address=NO_VALUE, sources=NO_VALUE, aux_data=NO_VALUE, *, __packet__=None, **kwargs)[source]¶
Bases:
SchemaHeader schema for an IGMPv3 group record (RFC 3376 Section 4.2.4).
- record_type: RecordType = <EnumField record_type>¶
Record type.
- multicast_address: IPv4Address = <IPv4AddressField multicast_address>¶
Multicast address.
- sources: list[IPv4Address] = <ListField sources>¶
Source addresses (RFC 3376 Section 4.2.9).
- aux_data: bytes = <BytesField aux_data>¶
Auxiliary data (RFC 3376 Section 4.2.10).
Data Models¶
- class pcapkit.protocols.data.internet.igmpv3.IGMPv3(*args, **kwargs)[source]¶
Bases:
ProtocolData model for Internet Group Management Protocol version 3.
This is the common ancestor of the two message shapes IGMPv3 defines:
Query, its Membership Query, extending the 8-octet group-address header IGMPv1/v2 also use with a source-list extension; andReport, its Membership Report, whose body is a list of group records instead (#2439, #2448).- version: Literal[3]¶
Version of IGMP, always
3. It is on no octet; it names the class that read or built the message, as on the IGMPv1/v2 data model, andIGMP.from_datadispatches on it (#2574).
- length: int¶
Header length, in octets. IGMP has no header field of its own that states this – unlike
AH, it is computed from whatIGMPv3.readactually consumed, the same waylengthis.
- checksum_status: ChecksumStatus¶
Outcome of verifying the message’s
checksum, present only whenCHECKSUM_VERIFYis on.
- class pcapkit.protocols.data.internet.igmpv3.Query(version, type, length, max_resp_code, max_resp_time, checksum, group, resv, s_flag, qrv, qqic, qqi, sources)[source]¶
Bases:
IGMPv3Data model for an IGMPv3 Membership Query (RFC 3376 Section 4.1).
Reached only once
IGMPv3.readhas confirmed the message classifies as IGMPv3 (at least 12 octets), so the source-list extension fields below are always populated – neverNone, unlike the single-class design IGMPv1/v2 predate this one with.- max_resp_code: int¶
Max response code, as received on the wire; the raw octet
max_resp_timeis decoded from (RFC 3376 Section 4.1.1).
- max_resp_time: int¶
Max response time, in units of 1/10 second, decoded from
max_resp_code: literal if below 128, else floating-point,(mant | 0x10) << (exp + 3)(RFC 3376 Section 4.1.1).
- group: IPv4Address¶
Group address – the IPv4 multicast group being queried, or
0.0.0.0on a General Query.
- resv: int¶
Resv, the 4 reserved high-order bits of the flags octet (RFC 3376 Section 4.1.4), kept as read rather than assumed zero so a round trip reproduces a non-conformant sender’s octet exactly.
- s_flag: bool¶
Suppress Router-Side Processing flag (RFC 3376 Section 4.1.5).
- qrv: int¶
Querier’s Robustness Variable (RFC 3376 Section 4.1.6).
- qqi: int¶
Querier’s Query Interval, in seconds, decoded from
qqicby the same formula asmax_resp_time(RFC 3376 Section 4.1.7).
- sources: tuple[IPv4Address, ...]¶
Source addresses being queried (RFC 3376 Section 4.1.9); an empty
tuplefor a General or Group-Specific Query.
- class pcapkit.protocols.data.internet.igmpv3.Report(version, type, length, reserved_1, checksum, reserved_2, num_group_records, records)[source]¶
Bases:
IGMPv3Data model for an IGMPv3 Membership Report (RFC 3376 Section 4.2).
- reserved_1: int¶
Reserved octet after
type(RFC 3376 Section 4.2.1), kept as read rather than assumed zero so a round trip reproduces a non-conformant sender’s octet exactly.
- reserved_2: bytes¶
Reserved 16 bits before
num_group_records(RFC 3376 Section 4.2.1); seereserved_1.
- records: tuple[GroupRecord, ...]¶
Group records (RFC 3376 Section 4.2.4).
- class pcapkit.protocols.data.internet.igmpv3.GroupRecord(record_type, aux_data_len, num_sources, multicast_address, sources, aux_data)[source]¶
Bases:
DataData model for an IGMPv3 group record (RFC 3376 Section 4.2.4).
- record_type: RecordType¶
Record type.
- multicast_address: IPv4Address¶
Multicast address this record pertains to.
- sources: tuple[IPv4Address, ...]¶
Source addresses (RFC 3376 Section 4.2.9).
- aux_data: bytes¶
Auxiliary data (RFC 3376 Section 4.2.10); always empty for a standards-conformant IGMPv3 sender, but kept as read for a receiver.