Skip to content

Commit 41b5735

Browse files
committed
feat(internet): implement IGMP v1/v2 as an Internet subclass
Closes #2439 - Add pcapkit/protocols/internet/igmp.py, with its data and schema modules, covering IGMPv1 (RFC 1112 appendix I) and IGMPv2 (RFC 2236 sec. 2) from one 8-octet schema/data/protocol triple, per discussion #251. Type codes cross-checked against RFC 1112 appendix I, RFC 2236 sec. 2.1, and IANA's IGMP Type Numbers registry: Membership Query 0x11, v1 Report 0x12, v2 Report 0x16, Leave Group 0x17. A type outside those four -- an IGMPv3 Membership Report, DVMRP, and so on -- raises ProtocolError in read() so the dispatch machinery's beholder falls back to Raw instead of mis-decoding it through the v1/v2 layout. - Add pcapkit/const/igmp/type.py and pcapkit/vendor/igmp/type.py, a new const registry/vendor crawler pair generated from IANA's IGMP Type Numbers CSV, formalising the raw hex values pcapkit/protocols/internet/mh.py already referenced opaquely. - Register IGMP onto Internet.__proto__ at TransType.IGMP (protocol number 2), and wire it into every protocols/const/vendor aggregator's __all__. IGMPv3 (RFC 3376)'s group-record-list body is out of scope, left to a follow-up. - Update tests/protocols/test_dispatch_registry_unit.py and four tests/const sweep tests for the new dispatch entry and const enum; add a dispatch-probe builder for TransType.IGMP in examples/generators/dispatch.py. - Add tests/protocols/internet/test_igmp_unit.py: byte fixtures for every v1/v2 message type, a checksum-validation test, parse/make round trips, and a regression pair proving an IGMPv3 Membership Report raises ProtocolError directly and falls back to Raw under IPv4 dispatch. - Open docs/source/changelog/1.6.0.rst with this PR's bullet, add the wave-2 index entry to docs/source/changelog.rst, and regenerate CHANGELOG.md to match. Build: mypy and isort clean on every changed pcapkit/ file (pylint's redefined-builtin/unused-argument noise matches AH/IPX precedent). tests/protocols/internet/test_igmp_unit.py, tests/project/test_issue_refs_in_comments.py, tests/project/test_changelog_md.py and tests/protocols/test_dispatch_registry_unit.py all pass.
1 parent 37053f0 commit 41b5735

35 files changed

Lines changed: 1073 additions & 546 deletions

‎CHANGELOG.md‎

Lines changed: 3 additions & 517 deletions
Large diffs are not rendered by default.

‎docs/source/changelog.rst‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ All notable changes to PyPCAPKit are recorded here.
4444
Releases are listed newest first. The repository root's :file:`CHANGELOG.md`
4545
carries only the version being released; this page is the whole recorded history.
4646

47+
* **1.6.0** (unreleased) -- Wave 2 of the roadmap: the protocol pairs that
48+
wanted a shared abstract base, and the two that had no dissector at all.
49+
:doc:`Full changelog <changelog/1.6.0>`.
4750
* **1.5.0** (2026-10-29) -- The largest release since 1.0, and the first
4851
recorded here as it happened rather than reconstructed: more extraction
4952
engines, ESP with payload decryption, SCTP and NGAP over SCTP,
@@ -174,6 +177,7 @@ carries only the version being released; this page is the whole recorded history
174177
:hidden:
175178
:maxdepth: 1
176179

180+
changelog/1.6.0
177181
changelog/1.5.0
178182
changelog/1.4.1
179183
changelog/1.4.0

‎docs/source/changelog/1.6.0.rst‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
1.6.0 -- unreleased
2+
===================
3+
4+
Wave 2 of the roadmap, per the contributing docs' enhancement-proposal page: the
5+
protocol pairs that wanted a shared abstract base, and the two that simply had
6+
no dissector at all.
7+
8+
pcapkit.protocols
9+
-----------------
10+
11+
Added
12+
~~~~~
13+
14+
* IGMPv1 [:rfc:`1112`] and IGMPv2 [:rfc:`2236`] as an
15+
:class:`~pcapkit.protocols.internet.internet.Internet` subclass
16+
(:mod:`pcapkit.protocols.internet.igmp`), one schema/data/protocol triple
17+
covering both versions since they share the same 8-octet message shape
18+
(:discussion:`251`, :issue:`2439`, :pr:`2444`). A new
19+
:class:`~pcapkit.const.igmp.type.Type` registry, generated from IANA's
20+
*IGMP Type Numbers*, formalises the raw type octets
21+
:mod:`pcapkit.protocols.internet.mh` already referenced opaquely. A
22+
message whose type is not one of the four IGMPv1/v2 types falls back to
23+
:class:`~pcapkit.protocols.misc.raw.Raw` rather than being mis-decoded
24+
through the v1/v2 layout. IGMPv3 [:rfc:`3376`]'s group-record-list body is
25+
a materially different shape and is left to a follow-up.

‎docs/source/contributing/pep.rst‎

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ one. Grouped by each TCP/IP layer and ordered by protocol name alphabetically,
4141
the ones outstanding are,
4242

4343
* Link Layer: DSL, EAPOL, FDDI, ISDN, LINUX_SLL, LINUX_SLL2, NDP, PPP
44-
* Internet Layer: ECN, ICMP, ICMPv6, IGMP, Shim6
44+
* Internet Layer: ECN, ICMP, ICMPv6, Shim6
4545
* Transport Layer: DCCP, RSVP
4646
* Application Layer: BGP, DHCP, DHCPv6, DNS, DTLS, IMAP, LDAP, MQTT, NNTP,
4747
NTP, ONC/RPC, POP, QUIC, RIP, RTP, SIP, SMTP, SNMP, SSH, Telnet, TLS/SSL,
@@ -349,8 +349,8 @@ Follow-ups to the bindings above:
349349
port number. That depends on the proxy identifying the version positively
350350
instead of guessing, since a guess path is wrong on non-HTTP input.
351351

352-
Beyond those, the gaps most likely to be met in a real capture are ICMP (1),
353-
ICMPv6 (58) and IGMP (2) on the internet layer, each of which has a stub;
352+
Beyond those, the gaps most likely to be met in a real capture are ICMP (1)
353+
and ICMPv6 (58) on the internet layer, each of which has a stub;
354354
and ``LINUX_SLL`` and ``LINUX_SLL2`` at the link layer, which every
355355
``tcpdump -i any`` capture uses and which have no stub.
356356

@@ -1072,11 +1072,16 @@ Steps`_ above.
10721072

10731073
**Wave 2 — the protocol pairs that want a shared abstract base**, per `More
10741074
Protocols, More!!!`_ above: **ICMP with ICMPv6**, **TLS/SSL with DTLS**, and
1075-
``LINUX_SLL`` with ``LINUX_SLL2``, plus **IGMP** on its own. These are grouped
1076-
because the shared-base question is the design work and doing either half of a
1077-
pair alone would answer it twice. ``LINUX_SLL`` matters out of proportion to its
1078-
size: every ``tcpdump -i any`` capture uses it, and neither variant has even a
1079-
stub.
1075+
``LINUX_SLL`` with ``LINUX_SLL2``. These are grouped because the shared-base
1076+
question is the design work and doing either half of a pair alone would
1077+
answer it twice. ``LINUX_SLL`` matters out of proportion to its size: every
1078+
``tcpdump -i any`` capture uses it, and neither variant has even a stub.
1079+
1080+
**IGMP v1/v2 — done ahead of wave 2**, as the one item of the three that
1081+
needed no shared base: :rfc:`1112` and :rfc:`2236` share one 8-octet message
1082+
shape, so one schema/data/protocol triple covers both (:issue:`2439`).
1083+
:rfc:`3376` IGMPv3's group-record-list body is a different enough shape to
1084+
be its own follow-up rather than part of this work.
10801085

10811086
**Done ahead of wave 2 — handlers for the** ``DLT_NULL`` **and** ``DLT_RAW``
10821087
**link types.** Both are genuine DLTs that a capture can legitimately be rooted
@@ -1104,8 +1109,10 @@ above, which describes the payloads in question and why a registry of their own
11041109
is wanted instead of
11051110
:meth:`~pcapkit.protocols.protocol.Protocol._decode_next_layer`. It is
11061111
sequenced *after* wave 2 rather than by preference: the multicast options embed
1107-
:rfc:`3810` MLD, which rides in **ICMPv6**, and :rfc:`3376` **IGMP** records —
1108-
both wave 2 deliverables. Landing the registry first would give a dispatch table
1112+
:rfc:`3810` MLD, which rides in **ICMPv6**, and :rfc:`3376` **IGMPv3** group
1113+
records — ICMPv6 a wave 2 deliverable, IGMPv3's group-record-list body the
1114+
follow-up :issue:`2439` left outstanding when it landed IGMP v1/v2 ahead of
1115+
wave 2. Landing the registry first would give a dispatch table
11091116
with nothing but :class:`~pcapkit.protocols.misc.raw.Raw` to register. The
11101117
counter-argument is real though, and worth weighing rather than dismissing: changing the
11111118
parsed shape from :obj:`bytes` to :class:`~pcapkit.protocols.misc.raw.Raw` is the

‎docs/source/pcapkit/const/igmp.rst‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
====================================================================
2+
:class:`~pcapkit.protocols.internet.igmp.IGMP` Constant Enumerations
3+
====================================================================
4+
5+
.. module:: pcapkit.const.igmp
6+
7+
This module contains all constant enumerations of
8+
:class:`~pcapkit.protocols.internet.igmp.IGMP` implementations. Available
9+
enumerations include:
10+
11+
.. list-table::
12+
13+
* - :class:`IGMP_Type <pcapkit.const.igmp.type.Type>`
14+
- IGMP Type Numbers [*]_
15+
16+
IGMP Type Numbers
17+
=================
18+
19+
.. module:: pcapkit.const.igmp.type
20+
21+
This module contains the constant enumeration for **IGMP Type Numbers**,
22+
which is automatically generated from :class:`pcapkit.vendor.igmp.type.Type`.
23+
24+
.. autoclass:: pcapkit.const.igmp.type.Type
25+
:members:
26+
:undoc-members:
27+
:show-inheritance:
28+
29+
.. rubric:: Footnotes
30+
31+
.. [*] https://www.iana.org/assignments/igmp-type-numbers/igmp-type-numbers.xhtml

‎docs/source/pcapkit/const/index.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Internet Layer
8080

8181
esp
8282
hip
83+
igmp
8384
ipv4
8485
ipv6
8586
ipx
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
IGMP - Internet Group Management Protocol
2+
==========================================
3+
4+
.. module:: pcapkit.protocols.internet.igmp
5+
6+
:mod:`pcapkit.protocols.internet.igmp` contains
7+
:class:`~pcapkit.protocols.internet.igmp.IGMP` only,
8+
which implements the extractor for Internet Group
9+
Management Protocol (IGMP) [*]_ versions 1 and 2, whose
10+
8-octet structure is described as below:
11+
12+
======= ========= ========================= ===================================
13+
Octets Bits Name Description
14+
======= ========= ========================= ===================================
15+
0 0 ``igmp.type`` Type
16+
1 8 ``igmp.max_resp_time`` Max Response Time
17+
2 16 ``igmp.checksum`` Checksum
18+
4 32 ``igmp.group`` Group Address
19+
======= ========= ========================= ===================================
20+
21+
.. autoclass:: pcapkit.protocols.internet.igmp.IGMP
22+
:no-members:
23+
:show-inheritance:
24+
25+
.. autoproperty:: name
26+
.. autoproperty:: alias
27+
.. autoproperty:: length
28+
29+
.. automethod:: read
30+
.. automethod:: make
31+
32+
.. automethod:: _make_data
33+
34+
.. automethod:: __index__
35+
36+
Header Schemas
37+
--------------
38+
39+
.. module:: pcapkit.protocols.schema.internet.igmp
40+
41+
.. autoclass:: pcapkit.protocols.schema.internet.igmp.IGMP
42+
:members:
43+
:show-inheritance:
44+
45+
Data Models
46+
-----------
47+
48+
.. module:: pcapkit.protocols.data.internet.igmp
49+
50+
.. autoclass:: pcapkit.protocols.data.internet.igmp.IGMP
51+
:members:
52+
:show-inheritance:
53+
54+
.. rubric:: Footnotes
55+
56+
.. [*] https://en.wikipedia.org/wiki/Internet_Group_Management_Protocol

‎docs/source/pcapkit/protocols/internet/index.rst‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ internet layer, with detailed implementation and methods.
2626
ah
2727
esp
2828
hip
29+
igmp
2930
ipx
3031

3132
.. todo::
3233

33-
Implement ECN, ICMP, ICMPv6, IGMP, Shim6.
34+
Implement ECN, ICMP, ICMPv6, Shim6.
3435

3536
Protocol Registry
3637
-----------------
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
==============================================================
2+
:class:`~pcapkit.protocols.internet.igmp.IGMP` Vendor Crawlers
3+
==============================================================
4+
5+
.. module:: pcapkit.vendor.igmp
6+
7+
This module contains all vendor crawlers of
8+
:class:`~pcapkit.protocols.internet.igmp.IGMP` implementations. Available
9+
vendor crawlers include:
10+
11+
.. list-table::
12+
13+
* - :class:`IGMP_Type <pcapkit.vendor.igmp.type.Type>`
14+
- IGMP Type Numbers [*]_
15+
16+
IGMP Type Numbers
17+
=================
18+
19+
.. module:: pcapkit.vendor.igmp.type
20+
21+
This module contains the vendor crawler for **IGMP Type Numbers**,
22+
which is automatically generating :class:`pcapkit.const.igmp.type.Type`.
23+
24+
.. autoclass:: pcapkit.vendor.igmp.type.Type
25+
:members: FLAG, LINK
26+
:show-inheritance:
27+
28+
.. rubric:: Footnotes
29+
30+
.. [*] https://www.iana.org/assignments/igmp-type-numbers/igmp-type-numbers.xhtml

‎docs/source/pcapkit/vendor/index.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Internet Layer
5555

5656
esp
5757
hip
58+
igmp
5859
ipv4
5960
ipv6
6061
ipx

0 commit comments

Comments
 (0)