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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

Wave 2 of the roadmap, per the contributing docs' enhancement-proposal page: the protocol pairs that wanted a shared abstract base, and the two that simply had no dissector at all.

- **Added** -- `GRE`, a dissector for the Generic Routing Encapsulation base header ([RFC 2784](https://datatracker.ietf.org/doc/html/rfc2784)) plus the optional Key and Sequence Number extensions ([RFC 2890](https://datatracker.ietf.org/doc/html/rfc2890)). `LinuxSLL`/ `LinuxSLL1`/ `LinuxSLL2` dispatch to it for both the `ARPHRD_IPGRE` and `ARPHRD_IP6GRE` cases -- the same GRE framing either way, the "IP"/"IP6" distinction being only which outer IP version the tunnel carries -- instead of falling back to `Raw`. The Protocol Type field dispatches onward as an EtherType, through the same family registry (`Link.__proto__`) Ethernet, VLAN and LinuxSLL already share. One of [#2460](https://github.com/JarryShaw/PyPCAPKit/issues/2460)'s five `arphrd_type` follow-ups to get a dissector (`NETLINK` and `FRAD` are tracked separately on [#2507](https://github.com/JarryShaw/PyPCAPKit/pull/2507) and [#2499](https://github.com/JarryShaw/PyPCAPKit/pull/2499)); `IEEE80211_RADIOTAP` remains `Raw`.

- **Added** -- `Netlink`, a dissector for the fixed 16-octet `nlmsghdr` framing of Linux's own kernel/userspace IPC transport (the kernel's own `netlink(7)` man page; [RFC 3549 Section 2.3.2](https://datatracker.ietf.org/doc/html/rfc3549#section-2.3.2)). `LinuxSLL`/ `LinuxSLL1`/ `LinuxSLL2` dispatch to it for the `ARPHRD_NETLINK` case instead of falling back to `Raw`. The byte order the header was written in is ambiguous -- Netlink is kernel/userspace IPC, not wire format -- and is guessed the way Wireshark's own netlink dissector does, by `nlmsg_byteorder()`. Per-family message payloads (routing table entries and the like) and multiple messages packed into one capture are out of scope for this first cut; every message's payload is kept as `Raw`, unconditionally. One of [#2460](https://github.com/JarryShaw/PyPCAPKit/issues/2460)'s five `arphrd_type` follow-ups to get a dissector (`FRAD` is tracked separately on [#2499](https://github.com/JarryShaw/PyPCAPKit/pull/2499)); `IPGRE`/`IP6GRE` and `IEEE80211_RADIOTAP` remain `Raw`.

- **Added** -- `FRAD`, a dissector for Frame Relay's multiprotocol encapsulation ([RFC 2427](https://datatracker.ietf.org/doc/html/rfc2427), obsoleting [RFC 1490](https://datatracker.ietf.org/doc/html/rfc1490)). `LinuxSLL`/ `LinuxSLL1`/ `LinuxSLL2` dispatch to it for the `ARPHRD_FRAD` case instead of falling back to `Raw`; the direct NLPID and SNAP-encapsulated forms both dispatch onward, to IPv4/IPv6 and (via the EtherType registry every Ethernet/VLAN/LinuxSLL frame shares) ARP among others. The first of [#2460](https://github.com/JarryShaw/PyPCAPKit/issues/2460)'s five `arphrd_type` follow-ups to get a dissector; the other four (`NETLINK`, `IPGRE`/`IP6GRE`, `IEEE80211_RADIOTAP`) remain `Raw`.

---
Expand Down
18 changes: 18 additions & 0 deletions docs/source/changelog/1.6.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ Wave 2 of the roadmap, per the contributing docs' enhancement-proposal page: the
protocol pairs that wanted a shared abstract base, and the two that simply had
no dissector at all.

* **Added** -- :class:`~pcapkit.protocols.link.gre.GRE`, a dissector for the
Generic Routing Encapsulation base header (:rfc:`2784`) plus the optional Key
and Sequence Number extensions (:rfc:`2890`).
:class:`~pcapkit.protocols.link.linux_sll.LinuxSLL`/
:class:`~pcapkit.protocols.link.linux_sll1.LinuxSLL1`/
:class:`~pcapkit.protocols.link.linux_sll2.LinuxSLL2` dispatch to it for both
the ``ARPHRD_IPGRE`` and ``ARPHRD_IP6GRE`` cases -- the same GRE framing either
way, the "IP"/"IP6" distinction being only which outer IP version the tunnel
carries -- instead of falling back to
:class:`~pcapkit.protocols.misc.raw.Raw`. The Protocol Type field dispatches
onward as an EtherType, through the same family registry
(:attr:`Link.__proto__ <pcapkit.protocols.link.link.Link.__proto__>`)
Ethernet, VLAN and LinuxSLL already share. One of :issue:`2460`'s five
``arphrd_type`` follow-ups to get a dissector (``NETLINK`` and ``FRAD`` are
tracked separately on :pr:`2507` and :pr:`2499`); ``IEEE80211_RADIOTAP``
remains :class:`~pcapkit.protocols.misc.raw.Raw`.

* **Added** -- :class:`~pcapkit.protocols.link.netlink.Netlink`, a dissector for
the fixed 16-octet ``nlmsghdr`` framing of Linux's own kernel/userspace IPC
transport (the kernel's own ``netlink(7)`` man page; :rfc:`3549#section-2.3.2`).
Expand All @@ -22,6 +39,7 @@ no dissector at all.
:issue:`2460`'s five ``arphrd_type`` follow-ups to get a dissector (``FRAD`` is
tracked separately on :pr:`2499`); ``IPGRE``/``IP6GRE`` and
``IEEE80211_RADIOTAP`` remain :class:`~pcapkit.protocols.misc.raw.Raw`.

* **Added** -- :class:`~pcapkit.protocols.link.frad.FRAD`, a dissector for Frame
Relay's multiprotocol encapsulation (:rfc:`2427`, obsoleting :rfc:`1490`).
:class:`~pcapkit.protocols.link.linux_sll.LinuxSLL`/
Expand Down
90 changes: 90 additions & 0 deletions docs/source/pcapkit/protocols/link/gre.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
GRE - Generic Routing Encapsulation
====================================

.. module:: pcapkit.protocols.link.gre

:mod:`pcapkit.protocols.link.gre` contains
:class:`~pcapkit.protocols.link.gre.GRE`
only, which implements the extractor for the Generic Routing Encapsulation
base header [*]_ plus the optional Key and Sequence Number extensions [*]_, as
seen on a ``LINKTYPE_LINUX_SLL``/``LINKTYPE_LINUX_SLL2`` capture whose
``arphrd_type`` is ``ARPHRD_IPGRE`` or ``ARPHRD_IP6GRE`` -- both land on this
one class, the "IP"/"IP6" distinction being only which outer IP version the
tunnel carries. Its structure, with every optional field present, is
described as below:

.. table::

====== ==== ========================= ====================================
Octets Bits Name Description
====== ==== ========================= ====================================
0 0 ``gre.checksum_present`` Checksum Present (``C``)
------ ---- ------------------------- ------------------------------------
0 2 ``gre.key_present`` Key Present (``K``), :rfc:`2890`
------ ---- ------------------------- ------------------------------------
0 3 ``gre.sequence_present`` Sequence Number Present (``S``), :rfc:`2890`
------ ---- ------------------------- ------------------------------------
0 13 ``gre.version`` Version Number (``0``)
------ ---- ------------------------- ------------------------------------
2 16 ``gre.protocol_type`` Protocol Type (EtherType)
------ ---- ------------------------- ------------------------------------
4 32 ``gre.checksum`` Checksum, present only if ``C``
------ ---- ------------------------- ------------------------------------
6 48 ``gre.reserved1`` Reserved1, present only if ``C``
------ ---- ------------------------- ------------------------------------
8/4 64 ``gre.key`` Key, present only if ``K``, :rfc:`2890`
------ ---- ------------------------- ------------------------------------
12/8/4 96 ``gre.sequence_number`` Sequence Number, present only if ``S``, :rfc:`2890`
====== ==== ========================= ====================================

``C``, ``K`` and ``S`` each gate their own field independently, so the header
is 4, 8, 12 or 16 octets depending on which are set. The Protocol Type field
is an EtherType, dispatched onward through
:attr:`Link.__proto__ <pcapkit.protocols.link.link.Link.__proto__>`, the same
family registry Ethernet, VLAN and LinuxSLL already share -- unlike
:class:`~pcapkit.protocols.link.frad.FRAD`, this class keeps no registry of
its own. A nonzero Version Number (RFC 2637's "Enhanced GRE"/PPTP, version 1)
is a different, incompatible protocol and is refused rather than misread; see
the module docstring's *Scope* section.

.. autoclass:: pcapkit.protocols.link.gre.GRE
:no-members:
:show-inheritance:

.. autoproperty:: name
.. autoproperty:: alias
.. autoproperty:: length
.. autoproperty:: protocol

.. automethod:: id

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

.. automethod:: __length_hint__
.. automethod:: __index__

.. automethod:: _make_data

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

.. module:: pcapkit.protocols.schema.link.gre

.. autoclass:: pcapkit.protocols.schema.link.gre.GRE
:members:
:show-inheritance:

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

.. module:: pcapkit.protocols.data.link.gre

.. autoclass:: pcapkit.protocols.data.link.gre.GRE
:members:
:show-inheritance:

.. rubric:: Footnotes

.. [*] :rfc:`2784`
.. [*] :rfc:`2890`
1 change: 1 addition & 0 deletions docs/source/pcapkit/protocols/link/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ link layer, with detailed implementation and methods.
ethernet
arp
frad
gre
l2tp
l2tpv2
linux_sll
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
'NoPayload', # No Payload
'Raw', # Raw Packet

'ARP', 'C_Tag', 'Ethernet', 'FRAD', 'InARP', 'L2TP', # Link Layer
'ARP', 'C_Tag', 'Ethernet', 'FRAD', 'GRE', 'InARP', 'L2TP', # Link Layer
'L2TPv2', 'LinuxSLL', 'LinuxSLL1', 'LinuxSLL2', 'Loopback', 'Netlink', 'S_Tag', 'VLAN',

'AH', 'ESP', 'ICMP', 'ICMPv4', 'ICMPv6', # Internet Layer
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
'PCAPNG', # PCAPNG Format
'NoPayload', # No Payload
'Raw', # Raw Packet
'ARP', 'C_Tag', 'Ethernet', 'FRAD', 'InARP', 'L2TP', 'L2TPv2', 'LinuxSLL', 'LinuxSLL1',
'ARP', 'C_Tag', 'Ethernet', 'FRAD', 'GRE', 'InARP', 'L2TP', 'L2TPv2', 'LinuxSLL', 'LinuxSLL1',
'LinuxSLL2', 'Loopback', 'Netlink', 'S_Tag', 'VLAN', # Link Layer
'AH', 'ESP', 'ICMP', 'ICMPv4', 'ICMPv6', 'IGMP', 'IGMPv1', 'IGMPv2', 'IGMPv3',
'IP', 'IPsec', 'IPv4', 'IPv6', 'IPX', # Internet Layer
Expand Down
3 changes: 1 addition & 2 deletions pcapkit/protocols/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@
'Raw',

# Link Layer
'ARP', 'C_Tag', 'Ethernet', 'FRAD', 'InARP', 'L2TP', 'L2TPv2', 'LinuxSLL', 'LinuxSLL1',
'ARP', 'C_Tag', 'Ethernet', 'FRAD', 'GRE', 'InARP', 'L2TP', 'L2TPv2', 'LinuxSLL', 'LinuxSLL1',
'LinuxSLL2', 'Loopback', 'Netlink', 'S_Tag', 'VLAN',


# Internet Layer
'AH', 'ESP', 'ICMP', 'ICMPv4', 'ICMPv6', 'IGMP', 'IGMPv1', 'IGMPv2', 'IGMPv3',
'IP', 'IPsec', 'IPv4', 'IPv6', 'IPX',
Expand Down
3 changes: 3 additions & 0 deletions pcapkit/protocols/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
# Frame Relay Access Device
'FRAD',

# Generic Routing Encapsulation
'GRE',

# Layer Two Tunnelling Protocol
'L2TP', 'L2TP_Flags',

Expand Down
6 changes: 6 additions & 0 deletions pcapkit/protocols/data/link/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
# Frame Relay Access Device
from pcapkit.protocols.data.link.frad import FRAD

# Generic Routing Encapsulation
from pcapkit.protocols.data.link.gre import GRE

# Layer Two Tunnelling Protocol
from pcapkit.protocols.data.link.l2tp import L2TP
from pcapkit.protocols.data.link.l2tp import Flags as L2TP_Flags
Expand Down Expand Up @@ -40,6 +43,9 @@
# Frame Relay Access Device
'FRAD',

# Generic Routing Encapsulation
'GRE',

# Layer Two Tunnelling Protocol
'L2TP', 'L2TP_Flags',

Expand Down
57 changes: 57 additions & 0 deletions pcapkit/protocols/data/link/gre.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
"""data models for Generic Routing Encapsulation (GRE) frames"""

from typing import TYPE_CHECKING

from pcapkit.corekit.infoclass import info_final
from pcapkit.protocols.data.protocol import Protocol

if TYPE_CHECKING:
from typing import Optional

from pcapkit.const.reg.ethertype import EtherType

__all__ = ['GRE']


@info_final
class GRE(Protocol):
"""Data model for a Generic Routing Encapsulation (GRE) frame."""

#: Checksum Present bit (``C``), :rfc:`2784`.
checksum_present: 'bool'
#: Key Present bit (``K``), :rfc:`2890`.
key_present: 'bool'
#: Sequence Number Present bit (``S``), :rfc:`2890`.
sequence_present: 'bool'
#: Reserved bits of the flags word outside ``C``/``K``/``S``/``Ver``, in
#: their on-wire positions (i.e. masked by ``0x4FF8``). :rfc:`2784` calls
#: the whole 12-bit span (before :rfc:`2890` carved ``K``/``S`` out of it)
#: ``Reserved0`` and requires it sent as zero; carried verbatim so a
#: rebuild reproduces the word as it arrived.
reserved: 'int'
#: Version Number; :rfc:`2784` requires this to be ``0``.
version: 'int'
#: Protocol Type: the EtherType of the encapsulated payload.
protocol_type: 'EtherType'
#: Checksum, present only when :attr:`checksum_present` is set.
checksum: 'Optional[int]'
#: Reserved1, present only when :attr:`checksum_present` is set;
#: :rfc:`2784` requires it sent as zero, carried verbatim.
reserved1: 'Optional[int]'
#: Key, present only when :attr:`key_present` is set, :rfc:`2890`.
key: 'Optional[int]'
#: Sequence Number, present only when :attr:`sequence_present` is set,
#: :rfc:`2890`.
sequence_number: 'Optional[int]'
#: Header length, in octets -- ``4``, plus ``4`` more for each of
#: :attr:`checksum_present`, :attr:`key_present` and
#: :attr:`sequence_present` that is set.
len: 'int'

if TYPE_CHECKING:
def __init__(self, checksum_present: 'bool', key_present: 'bool', # pylint: disable=unused-argument,super-init-not-called,multiple-statements
sequence_present: 'bool', reserved: 'int', version: 'int', # pylint: disable=unused-argument
protocol_type: 'EtherType', checksum: 'Optional[int]', # pylint: disable=unused-argument
reserved1: 'Optional[int]', key: 'Optional[int]', # pylint: disable=unused-argument
sequence_number: 'Optional[int]', len: 'int') -> 'None': ... # pylint: disable=unused-argument,redefined-builtin
4 changes: 2 additions & 2 deletions pcapkit/protocols/link/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from pcapkit.protocols.link.arp import ARP, InARP
from pcapkit.protocols.link.ethernet import Ethernet
from pcapkit.protocols.link.frad import FRAD
from pcapkit.protocols.link.gre import GRE
from pcapkit.protocols.link.loopback import Loopback
from pcapkit.protocols.link.netlink import Netlink

Expand All @@ -43,7 +44,6 @@
'LINKTYPE',

# Link Layer Protocols
'ARP', 'C_Tag', 'Ethernet', 'FRAD', 'InARP', 'L2TP', 'L2TPv2', 'LinuxSLL', 'LinuxSLL1',
'ARP', 'C_Tag', 'Ethernet', 'FRAD', 'GRE', 'InARP', 'L2TP', 'L2TPv2', 'LinuxSLL', 'LinuxSLL1',
'LinuxSLL2', 'Loopback', 'Netlink', 'S_Tag', 'VLAN',

]
Loading
Loading