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
8 changes: 5 additions & 3 deletions docs/source/pcapkit/protocols/link/ieee802_11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ IEEE 802.11 - Wireless LAN MAC Header
:mod:`pcapkit.protocols.link.ieee802_11` contains
:class:`~pcapkit.protocols.link.ieee802_11.IEEE802_11` only, which implements
the extractor for the IEEE 802.11 MAC header [*]_ of a protocol version 0
frame, as :class:`~pcapkit.protocols.link.radiotap.Radiotap` hands it on. Its
fields, in the order they appear, numeric ones little-endian:
frame, as a ``LINKTYPE_IEEE802_11`` capture carries it or
:class:`~pcapkit.protocols.link.radiotap.Radiotap` hands it on. Its fields, in
the order they appear, numeric ones little-endian:

.. table::

Expand Down Expand Up @@ -41,7 +42,8 @@ Scope
* **The frame body** (§9.2.4.7) is kept as
:class:`~pcapkit.protocols.misc.raw.Raw`, protected or not.
* **The FCS** (§9.2.4.8), where one was captured, stays at the end of the
body: whether a capture carries it is a radiotap Flags bit, which
body: this class does not decide whether a capture carries one, which
behind radiotap is a Flags bit
:class:`~pcapkit.protocols.link.radiotap.Radiotap` does not decode.
* **Pad octets** that radiotap's data-pad flag says follow the header stay
at the start of the body, for the same reason.
Expand Down
1 change: 1 addition & 0 deletions docs/source/pcapkit/protocols/link/radiotap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Radiotap - IEEE 802.11 Radiotap Header
:class:`~pcapkit.protocols.link.radiotap.Radiotap`
only, which implements the extractor for the radiotap header [*]_ capture
tools prepend to an 802.11 frame, as seen on a
``LINKTYPE_IEEE802_11_RADIOTAP`` capture, or on a
``LINKTYPE_LINUX_SLL``/``LINKTYPE_LINUX_SLL2`` capture whose ``arphrd_type``
is ``ARPHRD_IEEE80211_RADIOTAP``. Radiotap is not part of the 802.11
standard itself -- it is a prefix written by the capturing tool, in front of
Expand Down
20 changes: 20 additions & 0 deletions examples/generators/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,18 @@ def _linux_sll2(payload: 'bytes') -> 'bytes':
return bytes(LinuxSLL2(payload=payload))


def _wlan_ack() -> 'bytes':
"""An 802.11 Ack frame, which carries no body."""
from pcapkit.protocols.link.ieee802_11 import IEEE802_11
return bytes(IEEE802_11(type='Control', subtype='ACK', addr1='02:00:00:00:00:01'))


def _radiotap(payload: 'bytes') -> 'bytes':
"""A minimal radiotap header carrying ``payload``."""
from pcapkit.protocols.link.radiotap import Radiotap
return bytes(Radiotap(payload=payload))


###############################################################################
# Link -- EtherType.
###############################################################################
Expand Down Expand Up @@ -580,6 +592,10 @@ def _linktype_payload(code: 'Any') -> 'tuple[bytes, bool]':
return _linux_sll(_ip4(6, _tcp(9999))), False
if code == LinkType.LINUX_SLL2:
return _linux_sll2(_ip4(6, _tcp(9999))), False
if code == LinkType.IEEE802_11:
return _wlan_ack(), False
if code == LinkType.IEEE802_11_RADIOTAP:
return _radiotap(_wlan_ack()), False
raise LookupError(f'linktype: no payload builder for {code!r}') # pragma: no cover


Expand Down Expand Up @@ -811,6 +827,8 @@ def _link_enum() -> 'Any':
'pcap-frame/IPV6': ('pcapkit.protocols.internet', 'IPv6'),
'pcap-frame/LINUX_SLL': ('pcapkit.protocols.link', 'LinuxSLL1'),
'pcap-frame/LINUX_SLL2': ('pcapkit.protocols.link', 'LinuxSLL2'),
'pcap-frame/IEEE802_11': ('pcapkit.protocols.link', 'IEEE802_11'),
'pcap-frame/IEEE802_11_RADIOTAP': ('pcapkit.protocols.link', 'Radiotap'),

# -- PCAPNG.__proto__ (LinkType) --------------------------------------------
'pcapng-frame/NULL': ('pcapkit.protocols.link', 'Loopback'),
Expand All @@ -820,6 +838,8 @@ def _link_enum() -> 'Any':
'pcapng-frame/IPV6': ('pcapkit.protocols.internet', 'IPv6'),
'pcapng-frame/LINUX_SLL': ('pcapkit.protocols.link', 'LinuxSLL1'),
'pcapng-frame/LINUX_SLL2': ('pcapkit.protocols.link', 'LinuxSLL2'),
'pcapng-frame/IEEE802_11': ('pcapkit.protocols.link', 'IEEE802_11'),
'pcapng-frame/IEEE802_11_RADIOTAP': ('pcapkit.protocols.link', 'Radiotap'),

# -- Loopback.__proto__ (address family) ------------------------------------
'loopback/2': ('pcapkit.protocols.internet.ipv4', 'IPv4'),
Expand Down
37 changes: 21 additions & 16 deletions pcapkit/protocols/link/ieee802_11.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
:mod:`pcapkit.protocols.link.ieee802_11` contains
:class:`~pcapkit.protocols.link.ieee802_11.IEEE802_11` only, which implements
the extractor for the IEEE 802.11 MAC header [*]_ of a protocol version 0
frame, as :class:`~pcapkit.protocols.link.radiotap.Radiotap` hands it on. Its
fields, in the order they appear, numeric ones little-endian:
frame, as a ``LINKTYPE_IEEE802_11`` capture carries it or
:class:`~pcapkit.protocols.link.radiotap.Radiotap` hands it on. Its fields, in
the order they appear, numeric ones little-endian:

.. table::

Expand Down Expand Up @@ -37,12 +38,12 @@
:class:`~pcapkit.protocols.data.link.ieee802_11.FrameControl`.

The frame body (§9.2.4.7) follows the header and is kept as
:class:`~pcapkit.protocols.misc.raw.Raw`, protected or not. So is the FCS
(§9.2.4.8) where one was captured: whether a capture carries it is a
radiotap Flags bit, which :class:`~pcapkit.protocols.link.radiotap.Radiotap`
does not decode, so the FCS stays at the end of the body. For the same reason,
the pad octets that radiotap's data-pad flag says follow the header stay at the
start of the body.
:class:`~pcapkit.protocols.misc.raw.Raw`, protected or not. The FCS
(§9.2.4.8), where one was captured, stays at the end of the body: this class
does not decide whether a capture carries one, which behind radiotap is a
Flags bit :class:`~pcapkit.protocols.link.radiotap.Radiotap` does not decode.
For the same reason, the pad octets that radiotap's data-pad flag says follow
the header stay at the start of the body.

A frame of any protocol version but 0 is refused: version 1 is the PV1 frame
format of §9.8, whose Frame Control field is laid out differently, and
Expand All @@ -62,6 +63,7 @@
from pcapkit.const.ieee802_11.extension_subtype import ExtensionSubtype as Enum_ExtensionSubtype
from pcapkit.const.ieee802_11.management_subtype import ManagementSubtype as Enum_ManagementSubtype
from pcapkit.const.ieee802_11.type import Type as Enum_Type
from pcapkit.const.reg.linktype import LinkType as Enum_LinkType
from pcapkit.protocols.data.link.ieee802_11 import IEEE802_11 as Data_IEEE802_11
from pcapkit.protocols.data.link.ieee802_11 import FrameControl as Data_FrameControl
from pcapkit.protocols.data.link.ieee802_11 import HTControl as Data_HTControl
Expand All @@ -71,11 +73,11 @@
from pcapkit.protocols.link.link import Link
from pcapkit.protocols.schema.link.ieee802_11 import IEEE802_11 as Schema_IEEE802_11
from pcapkit.protocols.schema.link.ieee802_11 import Layout, layout
from pcapkit.utilities.exceptions import ProtocolError, UnsupportedCall
from pcapkit.utilities.exceptions import ProtocolError

if TYPE_CHECKING:
from enum import IntEnum as StdlibEnum
from typing import Any, Mapping, NoReturn, Optional, Type, Union
from typing import Any, Mapping, Optional, Type, Union

from aenum import IntEnum as AenumEnum
from typing_extensions import Literal
Expand Down Expand Up @@ -330,16 +332,19 @@ def __length_hint__(self) -> 'Literal[36]':
return 36

@classmethod
def __index__(cls) -> 'NoReturn': # pylint: disable=invalid-index-returned
def __index__(cls) -> 'Enum_LinkType': # pylint: disable=invalid-index-returned
"""Numeral registry index of the protocol.

Raises:
UnsupportedCall: This protocol is reached only through
:class:`~pcapkit.protocols.link.radiotap.Radiotap`'s payload
dispatch, not through a link-layer header type of its own.
Returns:
Numeral registry index of the protocol in `tcpdump`_ link-layer
header types, which
:attr:`Radiotap.__proto__ <pcapkit.protocols.link.radiotap.Radiotap.__proto__>`
is keyed by too.

.. _tcpdump: https://www.tcpdump.org/linktypes.html

"""
raise UnsupportedCall(f'{cls.__name__!r} object cannot be interpreted as an integer')
return Enum_LinkType.IEEE802_11 # type: ignore[return-value]

##########################################################################
# Utilities.
Expand Down
20 changes: 13 additions & 7 deletions pcapkit/protocols/misc/pcap/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,14 @@ class Frame(ProtocolBase[Data_Frame, Schema_Frame],
- :class:`pcapkit.protocols.link.loopback.Loopback`
* - :attr:`pcapkit.const.reg.linktype.LinkType.ETHERNET`
- :class:`pcapkit.protocols.link.ethernet.Ethernet`
* - :attr:`pcapkit.const.reg.linktype.LinkType.IEEE802_11`
- :class:`pcapkit.protocols.link.ieee802_11.IEEE802_11`
* - :attr:`pcapkit.const.reg.linktype.LinkType.LOOP`
- :class:`pcapkit.protocols.link.loopback.Loopback`
* - :attr:`pcapkit.const.reg.linktype.LinkType.LINUX_SLL`
- :class:`pcapkit.protocols.link.linux_sll1.LinuxSLL1`
* - :attr:`pcapkit.const.reg.linktype.LinkType.IEEE802_11_RADIOTAP`
- :class:`pcapkit.protocols.link.radiotap.Radiotap`
* - :attr:`pcapkit.const.reg.linktype.LinkType.IPV4`
- :class:`pcapkit.protocols.internet.ipv4.IPv4`
* - :attr:`pcapkit.const.reg.linktype.LinkType.IPV6`
Expand All @@ -112,13 +116,15 @@ class Frame(ProtocolBase[Data_Frame, Schema_Frame],
__proto__ = collections.defaultdict(
lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
{
Enum_LinkType.NULL: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
Enum_LinkType.ETHERNET: ModuleDescriptor('pcapkit.protocols.link', 'Ethernet'),
Enum_LinkType.LOOP: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
Enum_LinkType.LINUX_SLL: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL1'),
Enum_LinkType.IPV4: ModuleDescriptor('pcapkit.protocols.internet', 'IPv4'),
Enum_LinkType.IPV6: ModuleDescriptor('pcapkit.protocols.internet', 'IPv6'),
Enum_LinkType.LINUX_SLL2: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL2'),
Enum_LinkType.NULL: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
Enum_LinkType.ETHERNET: ModuleDescriptor('pcapkit.protocols.link', 'Ethernet'),
Enum_LinkType.IEEE802_11: ModuleDescriptor('pcapkit.protocols.link', 'IEEE802_11'),
Enum_LinkType.LOOP: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
Enum_LinkType.LINUX_SLL: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL1'),
Enum_LinkType.IEEE802_11_RADIOTAP: ModuleDescriptor('pcapkit.protocols.link', 'Radiotap'),
Enum_LinkType.IPV4: ModuleDescriptor('pcapkit.protocols.internet', 'IPv4'),
Enum_LinkType.IPV6: ModuleDescriptor('pcapkit.protocols.internet', 'IPv6'),
Enum_LinkType.LINUX_SLL2: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL2'),
},
) # type: DefaultDict[Enum_LinkType | int, ModuleDescriptor[ProtocolBase] | Type[ProtocolBase]]

Expand Down
20 changes: 13 additions & 7 deletions pcapkit/protocols/misc/pcapng.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,14 @@ class PCAPNG(ProtocolBase[Data_PCAPNG, Schema_PCAPNG],
- :class:`pcapkit.protocols.link.loopback.Loopback`
* - :attr:`pcapkit.const.reg.linktype.LinkType.ETHERNET`
- :class:`pcapkit.protocols.link.ethernet.Ethernet`
* - :attr:`pcapkit.const.reg.linktype.LinkType.IEEE802_11`
- :class:`pcapkit.protocols.link.ieee802_11.IEEE802_11`
* - :attr:`pcapkit.const.reg.linktype.LinkType.LOOP`
- :class:`pcapkit.protocols.link.loopback.Loopback`
* - :attr:`pcapkit.const.reg.linktype.LinkType.LINUX_SLL`
- :class:`pcapkit.protocols.link.linux_sll1.LinuxSLL1`
* - :attr:`pcapkit.const.reg.linktype.LinkType.IEEE802_11_RADIOTAP`
- :class:`pcapkit.protocols.link.radiotap.Radiotap`
* - :attr:`pcapkit.const.reg.linktype.LinkType.IPV4`
- :class:`pcapkit.protocols.internet.ipv4.IPv4`
* - :attr:`pcapkit.const.reg.linktype.LinkType.IPV6`
Expand Down Expand Up @@ -771,13 +775,15 @@ class PCAPNG(ProtocolBase[Data_PCAPNG, Schema_PCAPNG],
__proto__ = collections.defaultdict(
lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
{
Enum_LinkType.NULL: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
Enum_LinkType.ETHERNET: ModuleDescriptor('pcapkit.protocols.link', 'Ethernet'),
Enum_LinkType.LOOP: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
Enum_LinkType.LINUX_SLL: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL1'),
Enum_LinkType.IPV4: ModuleDescriptor('pcapkit.protocols.internet', 'IPv4'),
Enum_LinkType.IPV6: ModuleDescriptor('pcapkit.protocols.internet', 'IPv6'),
Enum_LinkType.LINUX_SLL2: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL2'),
Enum_LinkType.NULL: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
Enum_LinkType.ETHERNET: ModuleDescriptor('pcapkit.protocols.link', 'Ethernet'),
Enum_LinkType.IEEE802_11: ModuleDescriptor('pcapkit.protocols.link', 'IEEE802_11'),
Enum_LinkType.LOOP: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
Enum_LinkType.LINUX_SLL: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL1'),
Enum_LinkType.IEEE802_11_RADIOTAP: ModuleDescriptor('pcapkit.protocols.link', 'Radiotap'),
Enum_LinkType.IPV4: ModuleDescriptor('pcapkit.protocols.internet', 'IPv4'),
Enum_LinkType.IPV6: ModuleDescriptor('pcapkit.protocols.internet', 'IPv6'),
Enum_LinkType.LINUX_SLL2: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL2'),
},
) # type: DefaultDict[Enum_LinkType | int, ModuleDescriptor[ProtocolBase] | Type[ProtocolBase]]

Expand Down
Loading
Loading