Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions docs/source/contributing/pep.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1100,11 +1100,15 @@ through a shared method body. The two are distinguished by whether they carry ps
checksums (ICMPv6 does; ICMPv4 does not) and parse without checksum computation or verification
(:issue:`2470`).

**IGMP v1/v2 — done within wave 2** (:issue:`2439`).
The versioned classes :class:`IGMPv1 <pcapkit.protocols.internet.igmpv1.IGMP>` and
:class:`IGMPv2 <pcapkit.protocols.internet.igmpv2.IGMP>` share one read path on the
abstract :class:`~pcapkit.protocols.internet.igmp.IGMP` base.
:rfc:`3376` IGMPv3 is :issue:`2448`.
**IGMP — done within wave 2** (:issue:`2439`, :issue:`2448`).
The three concrete classes :class:`IGMPv1 <pcapkit.protocols.internet.igmpv1.IGMP>`,
:class:`IGMPv2 <pcapkit.protocols.internet.igmpv2.IGMP>` and
:class:`IGMPv3 <pcapkit.protocols.internet.igmpv3.IGMP>` share one read path on
the abstract :class:`~pcapkit.protocols.internet.igmp.IGMP` base, which
:meth:`~pcapkit.protocols.internet.igmp.IGMP._classify` dispatches to the right
one. IGMPv1/v2 share one 8-octet message shape; IGMPv3 (:rfc:`3376`) adds the
Membership Query's source-list extension and the Membership Report's
group-record list, each a shape of its own.

**Done within wave 2 — TLS/SSL with DTLS.** The `DTLS`_ section above lists
what is decoded: the shared :class:`~pcapkit.protocols.application.ssl.SSL`
Expand Down Expand Up @@ -1148,8 +1152,7 @@ sequenced *after* wave 2 rather than by preference: the multicast options embed
rides in **ICMPv6**, and :rfc:`3376` **IGMPv3** group records. ICMPv6 and
IGMPv1/v2 are both wave 2 deliverables, now done; MLD itself remains a
follow-up to ICMPv6 (see `More Protocols, More!!!`_ above), and IGMPv3 is
:issue:`2448` -- neither is part of wave 2's own scope. Landing the
registry first would give a dispatch table with nothing but
:issue:`2448`. Landing the registry first would give a dispatch table with
:class:`~pcapkit.protocols.misc.raw.Raw` to register. The
counter-argument is real though, and worth weighing rather than dismissing: changing the
parsed shape from :obj:`bytes` to :class:`~pcapkit.protocols.misc.raw.Raw` is the
Expand Down
17 changes: 17 additions & 0 deletions docs/source/pcapkit/const/igmp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ enumerations include:

* - :class:`IGMP_Type <pcapkit.const.igmp.type.Type>`
- IGMP Type Numbers [*]_
* - :class:`IGMP_RecordType <pcapkit.const.igmp.record_type.RecordType>`
- IGMP Group Record Types [*]_

IGMP Type Numbers
=================
Expand All @@ -26,6 +28,21 @@ which is automatically generated from :class:`pcapkit.vendor.igmp.type.Type`.
:undoc-members:
:show-inheritance:

IGMP Group Record Types
========================

.. module:: pcapkit.const.igmp.record_type

This module contains the constant enumeration for **IGMP Group Record
Types**, which is automatically generated from
:class:`pcapkit.vendor.igmp.record_type.RecordType`.

.. autoclass:: pcapkit.const.igmp.record_type.RecordType
:members:
:undoc-members:
:show-inheritance:

.. rubric:: Footnotes

.. [*] https://www.iana.org/assignments/igmp-type-numbers/igmp-type-numbers.xhtml
.. [*] https://www.rfc-editor.org/rfc/rfc3376#section-4.2.12
12 changes: 8 additions & 4 deletions docs/source/pcapkit/protocols/internet/igmp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ IGMP - Internet Group Management Protocol

:mod:`pcapkit.protocols.internet.igmp` contains
:class:`~pcapkit.protocols.internet.igmp.IGMP`, the abstract base of the
Internet Group Management Protocol (IGMP) [*]_ versions 1 and 2. Both share
the 8-octet structure below. :class:`IGMPv1 <pcapkit.protocols.internet.igmpv1.IGMP>`
and :class:`IGMPv2 <pcapkit.protocols.internet.igmpv2.IGMP>` set :attr:`version`,
and :attr:`alias` names the version of each message.
Internet Group Management Protocol (IGMP) [*]_ versions 1, 2 and 3. IGMPv1
and IGMPv2 share the 8-octet structure below.
:class:`IGMPv1 <pcapkit.protocols.internet.igmpv1.IGMP>` and
:class:`IGMPv2 <pcapkit.protocols.internet.igmpv2.IGMP>` set :attr:`version`
and reuse this schema and data model as-is; IGMPv3's wire format differs
materially by message, so :class:`IGMPv3 <pcapkit.protocols.internet.igmpv3.IGMP>`
carries its own instead -- see :doc:`igmpv3`. :attr:`alias` names the version
of each message read.

======= ========= ========================= ===================================
Octets Bits Name Description
Expand Down
105 changes: 105 additions & 0 deletions docs/source/pcapkit/protocols/internet/igmpv3.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
IGMPv3 - Internet Group Management Protocol version 3
==============================================================

.. module:: pcapkit.protocols.internet.igmpv3

:mod:`pcapkit.protocols.internet.igmpv3` contains
:class:`~pcapkit.protocols.internet.igmpv3.IGMP`, which implements an
extractor for Internet Group Management Protocol version 3 (IGMPv3)
[:rfc:`3376`]. Unlike :class:`IGMPv1 <pcapkit.protocols.internet.igmpv1.IGMP>`
and :class:`IGMPv2 <pcapkit.protocols.internet.igmpv2.IGMP>`, which reuse the
abstract base's own 8-octet schema and data model (see
:mod:`~pcapkit.protocols.internet.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 ``igmp.type`` Type
1 8 ``igmp.body.max_resp_code`` Max Response Code
2 16 ``igmp.body.checksum`` Checksum
4 32 ``igmp.body.group`` Group Address
8 64 ``igmp.body.ext.flags`` Resv / S Flag / QRV
9 72 ``igmp.body.ext.qqic`` Querier's Query Interval Code
10 80 ``igmp.body.ext.num_sources`` Number of Sources (N)
12 96 ``igmp.body.ext.sources`` 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 ``igmp.type`` Type
1 8 ``igmp.body.reserved_1`` Reserved
2 16 ``igmp.body.checksum`` Checksum
4 32 ``igmp.body.reserved_2`` Reserved
6 48 ``igmp.body.num_group_records`` Number of Group Records (M)
8 64 ``igmp.body.records`` Group Record [1..M]
======= ========= ================================== ===================================

.. autoclass:: pcapkit.protocols.internet.igmpv3.IGMP
:no-members:
:show-inheritance:

.. autoproperty:: version
.. autoproperty:: length

.. automethod:: id

.. automethod:: read
.. automethod:: make

.. automethod:: _make_group_record
.. automethod:: _make_data

Header Schemas
--------------

.. module:: pcapkit.protocols.schema.internet.igmpv3

.. autoclass:: pcapkit.protocols.schema.internet.igmpv3.IGMP
:members:
:show-inheritance:

.. autoclass:: pcapkit.protocols.schema.internet.igmpv3.Query
:members:
:show-inheritance:

.. autoclass:: pcapkit.protocols.schema.internet.igmpv3.QueryExtension
:members:
:show-inheritance:

.. autoclass:: pcapkit.protocols.schema.internet.igmpv3.Report
:members:
:show-inheritance:

.. autoclass:: pcapkit.protocols.schema.internet.igmpv3.GroupRecord
:members:
:show-inheritance:

Data Models
-----------

.. module:: pcapkit.protocols.data.internet.igmpv3

.. autoclass:: pcapkit.protocols.data.internet.igmpv3.IGMP
:members:
:show-inheritance:

.. autoclass:: pcapkit.protocols.data.internet.igmpv3.Query
:members:
:show-inheritance:

.. autoclass:: pcapkit.protocols.data.internet.igmpv3.Report
:members:
:show-inheritance:

.. autoclass:: pcapkit.protocols.data.internet.igmpv3.GroupRecord
:members:
:show-inheritance:
1 change: 1 addition & 0 deletions docs/source/pcapkit/protocols/internet/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ internet layer, with detailed implementation and methods.
igmp
igmpv1
igmpv2
igmpv3
ipx

.. todo::
Expand Down
19 changes: 19 additions & 0 deletions docs/source/pcapkit/vendor/igmp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ vendor crawlers include:

* - :class:`IGMP_Type <pcapkit.vendor.igmp.type.Type>`
- IGMP Type Numbers [*]_
* - :class:`IGMP_RecordType <pcapkit.vendor.igmp.record_type.RecordType>`
- IGMP Group Record Types [*]_

IGMP Type Numbers
=================
Expand All @@ -25,6 +27,23 @@ which is automatically generating :class:`pcapkit.const.igmp.type.Type`.
:members: FLAG, LINK
:show-inheritance:

IGMP Group Record Types
========================

.. module:: pcapkit.vendor.igmp.record_type

This module contains the vendor crawler for **IGMP Group Record Types**,
which is automatically generating
:class:`pcapkit.const.igmp.record_type.RecordType`. Unlike the type-number
crawler above, this is not an IANA-maintained registry -- the six values are
fixed in :rfc:`3376#section-4.2.12` itself -- so :meth:`~pcapkit.vendor.igmp.record_type.RecordType.request`
returns the table directly rather than fetching :attr:`LINK`.

.. autoclass:: pcapkit.vendor.igmp.record_type.RecordType
:members: FLAG
:show-inheritance:

.. rubric:: Footnotes

.. [*] https://www.iana.org/assignments/igmp-type-numbers/igmp-type-numbers.xhtml
.. [*] https://www.rfc-editor.org/rfc/rfc3376#section-4.2.12
3 changes: 2 additions & 1 deletion pcapkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@
'L2TPv2', 'LinuxSLL', 'LinuxSLL1', 'LinuxSLL2', 'Loopback', 'S_Tag', 'VLAN',

'AH', 'ESP', 'ICMP', 'ICMPv4', 'ICMPv6', # Internet Layer
'IGMP', 'IGMPv1', 'IGMPv2', 'IP', 'IPsec', 'IPv4', 'IPv6', 'IPX',
'IGMP', 'IGMPv1', 'IGMPv2', 'IGMPv3', 'IP', 'IPsec', 'IPv4', 'IPv6', 'IPX',

'HIP', 'HOPOPT', 'IPv6_Frag', 'IPv6_Ext', 'IPv6_Opts', 'IPv6_Route', 'MH',
# IPv6 Extension Header

Expand Down
3 changes: 2 additions & 1 deletion pcapkit/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@
'Raw', # Raw Packet
'ARP', 'C_Tag', 'Ethernet', 'InARP', 'L2TP', 'L2TPv2', 'LinuxSLL', 'LinuxSLL1',
'LinuxSLL2', 'Loopback', 'S_Tag', 'VLAN', # Link Layer
'AH', 'ESP', 'ICMP', 'ICMPv4', 'ICMPv6', 'IGMP', 'IGMPv1', 'IGMPv2',
'AH', 'ESP', 'ICMP', 'ICMPv4', 'ICMPv6', 'IGMP', 'IGMPv1', 'IGMPv2', 'IGMPv3',
'IP', 'IPsec', 'IPv4', 'IPv6', 'IPX', # Internet Layer

'HIP', 'HOPOPT', 'IPv6_Ext', 'IPv6_Frag', 'IPv6_Opts', 'IPv6_Route', 'MH',
# IPv6 Extension Header
'TCP', 'UDP', 'SCTP', # Transport Layer
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/const/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
'ICMPv6_Type', 'ICMPv6_DestinationUnreachableCode', 'ICMPv6_TimeExceededCode',
'ICMPv6_ParameterProblemCode',
# IGMP
'IGMP_Type',
'IGMP_Type', 'IGMP_RecordType',
# IPv4
'IPv4_ClassificationLevel', 'IPv4_OptionClass', 'IPv4_OptionNumber', 'IPv4_ProtectionAuthority',
'IPv4_QSFunction', 'IPv4_RouterAlert', 'IPv4_ToSDelay', 'IPv4_ToSECN', 'IPv4_ToSPrecedence',
Expand Down
6 changes: 5 additions & 1 deletion pcapkit/const/igmp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@

* - :class:`IGMP_Type <pcapkit.const.igmp.type.Type>`
- IGMP Type Numbers [*]_
* - :class:`IGMP_RecordType <pcapkit.const.igmp.record_type.RecordType>`
- IGMP Group Record Types [*]_

.. [*] https://www.iana.org/assignments/igmp-type-numbers/igmp-type-numbers.xhtml
.. [*] https://www.rfc-editor.org/rfc/rfc3376#section-4.2.12

"""

from pcapkit.const.igmp.record_type import RecordType as IGMP_RecordType
from pcapkit.const.igmp.type import Type as IGMP_Type

__all__ = ['IGMP_Type']
__all__ = ['IGMP_Type', 'IGMP_RecordType']
73 changes: 73 additions & 0 deletions pcapkit/const/igmp/record_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# pylint: disable=line-too-long,consider-using-f-string
"""IGMP Group Record Types
=============================

.. module:: pcapkit.const.igmp.record_type

This module contains the constant enumeration for **IGMP Group Record Types**,
which is automatically generated from :class:`pcapkit.vendor.igmp.record_type.RecordType`.

"""

from typing import TYPE_CHECKING

from aenum import IntEnum

from pcapkit.corekit.enum import EnumRegistry
from pcapkit.utilities.exceptions import EnumValueError

if TYPE_CHECKING:
from typing import Any

__all__ = ['RecordType']


class RecordType(EnumRegistry, IntEnum):
"""[RecordType] IGMP Group Record Types"""

MODE_IS_INCLUDE = 1

MODE_IS_EXCLUDE = 2

CHANGE_TO_INCLUDE_MODE = 3

CHANGE_TO_EXCLUDE_MODE = 4

ALLOW_NEW_SOURCES = 5

BLOCK_OLD_SOURCES = 6

@classmethod
def _validate_value(cls, value: 'Any') -> 'None':
"""Reject ``value`` unless it passes the range check :meth:`_missing_` makes.

Overrides :meth:`~pcapkit.corekit.enum.EnumLookup._validate_value`
with that check and the message it raises, so
:meth:`~pcapkit.corekit.enum.EnumRegistry.register` refuses exactly the
values :meth:`~pcapkit.corekit.enum.EnumLookup.get` refuses, in the
same words (:issue:`1816`).

Args:
value: Value about to be looked up or minted.

Raises:
EnumValueError: If ``value`` fails that check. A
:exc:`ValueError`, so an ``except ValueError`` caller is
unaffected.

"""
if not (isinstance(value, int) and 0 <= value <= 255):
raise EnumValueError('%r is not a valid %s' % (value, cls.__name__))

@classmethod
def _missing_(cls, value: 'int') -> 'RecordType':
"""Lookup function used when value is not found.

Args:
value: Value to get enum item.

"""
if not (isinstance(value, int) and 0 <= value <= 255):
raise ValueError('%r is not a valid %s' % (value, cls.__name__))
return cls._unregistered_member(value, 'Unassigned')
2 changes: 1 addition & 1 deletion pcapkit/protocols/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
'LinuxSLL2', 'Loopback', 'S_Tag', 'VLAN',

# Internet Layer
'AH', 'ESP', 'ICMP', 'ICMPv4', 'ICMPv6', 'IGMP', 'IGMPv1', 'IGMPv2',
'AH', 'ESP', 'ICMP', 'ICMPv4', 'ICMPv6', 'IGMP', 'IGMPv1', 'IGMPv2', 'IGMPv3',
'IP', 'IPsec', 'IPv4', 'IPv6', 'IPX',

# IPv6 Extension Header
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/protocols/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
'IPv6_Route_UnknownType', 'IPv6_Route_SourceRoute', 'IPv6_Route_Type2', 'IPv6_Route_RPL',

# Internet Group Management Protocol
'IGMP',
'IGMP', 'IGMPv3', 'IGMPv3_Query', 'IGMPv3_Report', 'IGMPv3_GroupRecord',

# Internet Protocol version 6
'IPv6',
Expand Down
6 changes: 5 additions & 1 deletion pcapkit/protocols/data/internet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@

# Internet Group Management Protocol
from pcapkit.protocols.data.internet.igmp import IGMP
from pcapkit.protocols.data.internet.igmpv3 import GroupRecord as IGMPv3_GroupRecord
from pcapkit.protocols.data.internet.igmpv3 import IGMP as IGMPv3
from pcapkit.protocols.data.internet.igmpv3 import Query as IGMPv3_Query
from pcapkit.protocols.data.internet.igmpv3 import Report as IGMPv3_Report

# Internet Protocol version 4
from pcapkit.protocols.data.internet.ipv4 import EOOLOption as IPv4_EOOLOption
Expand Down Expand Up @@ -446,7 +450,7 @@
'ICMPv6_ParameterProblem', 'ICMPv6_Echo',

# Internet Group Management Protocol
'IGMP',
'IGMP', 'IGMPv3', 'IGMPv3_Query', 'IGMPv3_Report', 'IGMPv3_GroupRecord',

# Internet Protocol version 4
'IPv4',
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/protocols/data/internet/igmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class IGMP(Protocol):
v2's, with ``max_resp_time`` reserved at zero and fewer :attr:`type`
values defined (:issue:`2439`). IGMPv3 (:rfc:`3376`) adds a
group-record-list body of a materially different shape and is out of
scope here.
scope here -- see :mod:`pcapkit.protocols.data.internet.igmpv3`.

"""

Expand Down
Loading
Loading