Skip to content

Commit 65a2b41

Browse files
authored
feat(protocols): bind FRAD's and GRE's standard registry values (#2649) (#2667)
- Frame.__proto__ and PCAPNG.__proto__ bind LinkType.FRELAY to FRAD, so a LINKTYPE_FRELAY capture parses through FRAD rather than as Raw. - Internet.__proto__ binds TransType.GRE to GRE, so IPv4 and IPv6 hand protocol 47 to GRE, whose checksum is verified behind either. - The reachability test's UNBOUND table drops both entries; the internet, pcap-frame and pcapng-frame dispatch families probe the bound keys. - ProtocolCodeEndToEndTests registers under the RFC 3692 experimental TransType 254 in place of TransType.GRE. - FRAD's and GRE's pages, module and schema docstrings, GRE.__index__ and the roadmap name both carriers; gre.rst says analysis follows the tunnel. Tests: test_frad_gre_binding_2649_unit, reachability and dispatch registry fail without the fix and pass with it; the dispatch report and a capture differential against main change only the 107 and 47 cases.
1 parent 1ea04cc commit 65a2b41

16 files changed

Lines changed: 375 additions & 38 deletions

File tree

‎docs/source/contributing/pep.rst‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,8 @@ small part of each is bound to a dissector; everything else resolves to
298298
complaint and yields nothing useful.
299299

300300
* :class:`~pcapkit.const.reg.linktype.LinkType` --
301-
``NULL``, ``ETHERNET``, ``LOOP``, ``LINUX_SLL``, ``IPV4``, ``IPV6`` and
302-
``LINUX_SLL2``, declared identically
301+
``NULL``, ``ETHERNET``, ``IEEE802_11``, ``FRELAY``, ``LOOP``, ``LINUX_SLL``,
302+
``IEEE802_11_RADIOTAP``, ``IPV4``, ``IPV6`` and ``LINUX_SLL2``, declared identically
303303
in :class:`~pcapkit.protocols.misc.pcap.frame.Frame` and
304304
:class:`~pcapkit.protocols.misc.pcapng.PCAPNG`, which also read ``RAW`` as
305305
``IPV4`` or ``IPV6`` by its version nibble.
@@ -961,9 +961,11 @@ offload heuristic on :issue:`2470`.
961961
clear is :attr:`~pcapkit.corekit.checksum.internet.ChecksumStatus.NOT_COMPUTED`,
962962
and ``make()`` computes one when ``checksum_present`` asks without giving it.
963963
Neither GRE nor the Linux cooked-capture header carries a length, so a GRE frame
964-
the capture cut short is
965-
:attr:`~pcapkit.corekit.checksum.internet.ChecksumStatus.INVALID`. Settled at
966-
implementation (:issue:`2618`).
964+
the capture cut short there is
965+
:attr:`~pcapkit.corekit.checksum.internet.ChecksumStatus.INVALID`, settled at
966+
implementation (:issue:`2618`); behind IPv4 or IPv6, which state the payload
967+
length, it is :attr:`~pcapkit.corekit.checksum.internet.ChecksumStatus.TRUNCATED`
968+
(:issue:`2649`).
967969
* **DCCP covers what its Checksum Coverage gives** (:rfc:`4340#section-9.2`), over
968970
a pseudo-header that carries the whole packet's length, as TCP's does, so a
969971
fragment is

‎docs/source/pcapkit/protocols/link/frad.rst‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ FRAD - Frame Relay Access Device
66
:mod:`pcapkit.protocols.link.frad` contains
77
:class:`~pcapkit.protocols.link.frad.FRAD`
88
only, which implements the extractor for Frame Relay's multiprotocol
9-
encapsulation [*]_, as seen on a ``LINKTYPE_LINUX_SLL``/``LINKTYPE_LINUX_SLL2``
10-
capture whose ``arphrd_type`` is ``ARPHRD_FRAD``. Its structure, the Q.922
9+
encapsulation [*]_, as seen on a ``LINKTYPE_FRELAY`` capture, or on a
10+
``LINKTYPE_LINUX_SLL``/``LINKTYPE_LINUX_SLL2`` capture whose ``arphrd_type`` is
11+
``ARPHRD_FRAD``. Its structure, the Q.922
1112
LAPF address onward with no trailing FCS, is described as below:
1213

1314
.. table::

‎docs/source/pcapkit/protocols/link/gre.rst‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ GRE - Generic Routing Encapsulation
77
:class:`~pcapkit.protocols.link.gre.GRE`
88
only, which implements the extractor for the Generic Routing Encapsulation
99
base header [*]_ plus the optional Key and Sequence Number extensions [*]_, as
10-
seen on a ``LINKTYPE_LINUX_SLL``/``LINKTYPE_LINUX_SLL2`` capture whose
11-
``arphrd_type`` is ``ARPHRD_IPGRE`` or ``ARPHRD_IP6GRE`` -- both land on this
12-
one class, the "IP"/"IP6" distinction being only which outer IP version the
13-
tunnel carries. Its structure, with every optional field present, is
14-
described as below:
10+
reached through IP protocol number 47 behind any layer sharing
11+
:attr:`Internet.__proto__ <pcapkit.protocols.internet.internet.Internet.__proto__>`,
12+
IPv4 and IPv6 among them, or as seen on a
13+
``LINKTYPE_LINUX_SLL``/``LINKTYPE_LINUX_SLL2`` capture whose
14+
``arphrd_type`` is ``ARPHRD_IPGRE`` or ``ARPHRD_IP6GRE`` -- ``ARPHRD_IPGRE``
15+
and ``ARPHRD_IP6GRE`` both land on this one class, the "IP"/"IP6" distinction
16+
being only which outer IP version the tunnel carries. Its structure, with
17+
every optional field present, is described as below:
1518

1619
.. table::
1720

@@ -47,6 +50,11 @@ its own. A nonzero Version Number (RFC 2637's "Enhanced GRE"/PPTP, version 1)
4750
is a different, incompatible protocol and is refused rather than misread; see
4851
the module docstring's *Scope* section.
4952

53+
Flow tracing and TCP reassembly follow the tunnel's inner flow, keyed by the
54+
IP header nearest the TCP segment as for any tunnel (:issue:`1581`), and IPv4
55+
reassembly of an outer datagram fragmented in transit yields a parsed GRE
56+
layer.
57+
5058
.. autoclass:: pcapkit.protocols.link.gre.GRE
5159
:no-members:
5260
:show-inheritance:

‎examples/generators/dispatch_families/internet.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
4, # IPv4
2828
6, # TCP
2929
17, # UDP
30+
47, # GRE
3031
50, # ESP
3132
51, # AH
3233
89, # OSPFIGP
@@ -79,6 +80,9 @@ def _payload(code: 'int') -> 'bytes':
7980
if code == TransType.IPv6_Frag:
8081
from pcapkit.protocols.internet.ipv6_frag import IPv6_Frag
8182
return bytes(IPv6_Frag(next=17, id=1, offset=0, mf=False, payload=_udp(9999)))
83+
if code == TransType.GRE:
84+
from pcapkit.protocols.link.gre import GRE
85+
return bytes(GRE(protocol_type=0x0800, payload=_ip4(6, _tcp(9999))))
8286
if code == TransType.ESP:
8387
from pcapkit.protocols.internet.esp import ESP
8488
return bytes(ESP(spi=0x1234, seq=1, payload=b'\x01\x02\x03\x04'))
@@ -164,6 +168,7 @@ def _build(code: 'int') -> 'Any':
164168
'internet/IPv6_ICMP': ('pcapkit.protocols.internet.icmpv6', 'ICMPv6'),
165169
'internet/IPv6_Route': ('pcapkit.protocols.internet.ipv6_route', 'IPv6_Route'),
166170
'internet/IPv6_Frag': ('pcapkit.protocols.internet.ipv6_frag', 'IPv6_Frag'),
171+
'internet/GRE': ('pcapkit.protocols.link.gre', 'GRE'),
167172
'internet/ESP': ('pcapkit.protocols.internet.esp', 'ESP'),
168173
'internet/AH': ('pcapkit.protocols.internet.ah', 'AH'),
169174
'internet/IGMP': ('pcapkit.protocols.internet.igmp', 'IGMP'),

‎examples/generators/dispatch_families/linktype.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ def _payload(code: 'Any') -> 'tuple[bytes, bool]':
5959
return _wlan_ack(), False
6060
if code == LinkType.IEEE802_11_RADIOTAP:
6161
return _radiotap(_wlan_ack()), False
62+
if code == LinkType.FRELAY: # direct NLPID 0xCC, IPv4
63+
from pcapkit.protocols.link.frad import FRAD
64+
return bytes(FRAD(nlpid=0xCC, payload=_ip4(6, _tcp(9999)))), False
6265
raise LookupError(f'linktype: no payload builder for {code!r}') # pragma: no cover
6366

6467

@@ -110,6 +113,7 @@ def _pcapng_build(code: 'Any') -> 'Any':
110113
'pcap-frame/LINUX_SLL2': ('pcapkit.protocols.link', 'LinuxSLL2'),
111114
'pcap-frame/IEEE802_11': ('pcapkit.protocols.link', 'IEEE802_11'),
112115
'pcap-frame/IEEE802_11_RADIOTAP': ('pcapkit.protocols.link', 'Radiotap'),
116+
'pcap-frame/FRELAY': ('pcapkit.protocols.link', 'FRAD'),
113117

114118
# -- PCAPNG.__proto__ (LinkType) --------------------------------------------
115119
'pcapng-frame/NULL': ('pcapkit.protocols.link', 'Loopback'),
@@ -121,4 +125,5 @@ def _pcapng_build(code: 'Any') -> 'Any':
121125
'pcapng-frame/LINUX_SLL2': ('pcapkit.protocols.link', 'LinuxSLL2'),
122126
'pcapng-frame/IEEE802_11': ('pcapkit.protocols.link', 'IEEE802_11'),
123127
'pcapng-frame/IEEE802_11_RADIOTAP': ('pcapkit.protocols.link', 'Radiotap'),
128+
'pcapng-frame/FRELAY': ('pcapkit.protocols.link', 'FRAD'),
124129
}

‎pcapkit/protocols/internet/internet.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ class Internet(ProtocolBase[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=ab
7777
- :class:`pcapkit.protocols.internet.ipv6_route.IPv6_Route`
7878
* - :attr:`~pcapkit.const.reg.transtype.TransType.IPv6_Frag`
7979
- :class:`pcapkit.protocols.internet.ipv6_frag.IPv6_Frag`
80+
* - :attr:`~pcapkit.const.reg.transtype.TransType.GRE`
81+
- :class:`pcapkit.protocols.link.gre.GRE`
8082
* - :attr:`~pcapkit.const.reg.transtype.TransType.ESP`
8183
- :class:`pcapkit.protocols.internet.esp.ESP`
8284
* - :attr:`~pcapkit.const.reg.transtype.TransType.AH`
@@ -134,6 +136,9 @@ class Internet(ProtocolBase[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=ab
134136
Enum_TransType.IPv6_ICMP: ModuleDescriptor('pcapkit.protocols.internet.icmpv6', 'ICMPv6'),
135137
Enum_TransType.IPv6_Route: ModuleDescriptor('pcapkit.protocols.internet.ipv6_route', 'IPv6_Route'),
136138
Enum_TransType.IPv6_Frag: ModuleDescriptor('pcapkit.protocols.internet.ipv6_frag', 'IPv6_Frag'),
139+
# NOTE: a tunnel is placed by its payload, so GRE lives under ``protocols.link``;
140+
# see :doc:`/contributing/conventions/protocol-layer-placement`.
141+
Enum_TransType.GRE: ModuleDescriptor('pcapkit.protocols.link.gre', 'GRE'),
137142
Enum_TransType.ESP: ModuleDescriptor('pcapkit.protocols.internet.esp', 'ESP'),
138143
Enum_TransType.AH: ModuleDescriptor('pcapkit.protocols.internet.ah', 'AH'),
139144
Enum_TransType.IGMP: ModuleDescriptor('pcapkit.protocols.internet.igmp', 'IGMP'),

‎pcapkit/protocols/link/frad.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
:mod:`pcapkit.protocols.link.frad` contains
88
:class:`~pcapkit.protocols.link.frad.FRAD` only, which implements the
99
extractor for Frame Relay's multiprotocol encapsulation [*]_, as seen on a
10+
``LINKTYPE_FRELAY`` capture, or on a
1011
``LINKTYPE_LINUX_SLL``/``LINKTYPE_LINUX_SLL2`` capture whose ``arphrd_type``
1112
is ``ARPHRD_FRAD`` -- :class:`~pcapkit.protocols.link.linux_sll.LinuxSLL`
1213
dispatches here instead of falling back to

‎pcapkit/protocols/link/gre.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
:mod:`pcapkit.protocols.link.gre` contains
88
:class:`~pcapkit.protocols.link.gre.GRE` only, which implements the extractor
99
for the Generic Routing Encapsulation base header [:rfc:`2784`] plus the
10-
optional Key and Sequence Number extensions [:rfc:`2890`], as seen on a
10+
optional Key and Sequence Number extensions [:rfc:`2890`]. It is reached
11+
through IP protocol number 47 behind any layer sharing
12+
:attr:`Internet.__proto__ <pcapkit.protocols.internet.internet.Internet.__proto__>`,
13+
IPv4 and IPv6 among them, and on a
1114
``LINKTYPE_LINUX_SLL``/``LINKTYPE_LINUX_SLL2`` capture whose ``arphrd_type``
12-
is ``ARPHRD_IPGRE`` or ``ARPHRD_IP6GRE`` -- both land on this one class:
15+
is ``ARPHRD_IPGRE`` or ``ARPHRD_IP6GRE`` -- ``ARPHRD_IPGRE`` and
16+
``ARPHRD_IP6GRE`` both land on this one class:
1317
:class:`~pcapkit.protocols.link.linux_sll.LinuxSLL` dispatches here instead
1418
of falling back to :class:`~pcapkit.protocols.misc.raw.Raw` for either case;
1519
see :attr:`LinuxSLL.__proto__ <pcapkit.protocols.link.linux_sll.LinuxSLL.__proto__>`. The
@@ -359,7 +363,9 @@ def __index__(cls) -> 'Enum_TransType': # pylint: disable=invalid-index-returne
359363
360364
Returns:
361365
Numeral registry index of the protocol in `IANA`_ protocol
362-
numbers.
366+
numbers, which
367+
:attr:`Internet.__proto__ <pcapkit.protocols.internet.internet.Internet.__proto__>`
368+
is keyed by.
363369
:attr:`LinuxSLL.__proto__ <pcapkit.protocols.link.linux_sll.LinuxSLL.__proto__>`
364370
names its own keys for this class,
365371
:attr:`~pcapkit.const.linux.arphrd.ARPHRD.IPGRE` and

‎pcapkit/protocols/misc/pcap/frame.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class Frame(ProtocolBase[Data_Frame, Schema_Frame],
8585
- :class:`pcapkit.protocols.link.ethernet.Ethernet`
8686
* - :attr:`pcapkit.const.reg.linktype.LinkType.IEEE802_11`
8787
- :class:`pcapkit.protocols.link.ieee802_11.IEEE802_11`
88+
* - :attr:`pcapkit.const.reg.linktype.LinkType.FRELAY`
89+
- :class:`pcapkit.protocols.link.frad.FRAD`
8890
* - :attr:`pcapkit.const.reg.linktype.LinkType.LOOP`
8991
- :class:`pcapkit.protocols.link.loopback.Loopback`
9092
* - :attr:`pcapkit.const.reg.linktype.LinkType.LINUX_SLL`
@@ -119,6 +121,7 @@ class Frame(ProtocolBase[Data_Frame, Schema_Frame],
119121
Enum_LinkType.NULL: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
120122
Enum_LinkType.ETHERNET: ModuleDescriptor('pcapkit.protocols.link', 'Ethernet'),
121123
Enum_LinkType.IEEE802_11: ModuleDescriptor('pcapkit.protocols.link', 'IEEE802_11'),
124+
Enum_LinkType.FRELAY: ModuleDescriptor('pcapkit.protocols.link', 'FRAD'),
122125
Enum_LinkType.LOOP: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
123126
Enum_LinkType.LINUX_SLL: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL1'),
124127
Enum_LinkType.IEEE802_11_RADIOTAP: ModuleDescriptor('pcapkit.protocols.link', 'Radiotap'),

‎pcapkit/protocols/misc/pcapng.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,8 @@ class PCAPNG(ProtocolBase[Data_PCAPNG, Schema_PCAPNG],
482482
- :class:`pcapkit.protocols.link.ethernet.Ethernet`
483483
* - :attr:`pcapkit.const.reg.linktype.LinkType.IEEE802_11`
484484
- :class:`pcapkit.protocols.link.ieee802_11.IEEE802_11`
485+
* - :attr:`pcapkit.const.reg.linktype.LinkType.FRELAY`
486+
- :class:`pcapkit.protocols.link.frad.FRAD`
485487
* - :attr:`pcapkit.const.reg.linktype.LinkType.LOOP`
486488
- :class:`pcapkit.protocols.link.loopback.Loopback`
487489
* - :attr:`pcapkit.const.reg.linktype.LinkType.LINUX_SLL`
@@ -776,6 +778,7 @@ class PCAPNG(ProtocolBase[Data_PCAPNG, Schema_PCAPNG],
776778
Enum_LinkType.NULL: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
777779
Enum_LinkType.ETHERNET: ModuleDescriptor('pcapkit.protocols.link', 'Ethernet'),
778780
Enum_LinkType.IEEE802_11: ModuleDescriptor('pcapkit.protocols.link', 'IEEE802_11'),
781+
Enum_LinkType.FRELAY: ModuleDescriptor('pcapkit.protocols.link', 'FRAD'),
779782
Enum_LinkType.LOOP: ModuleDescriptor('pcapkit.protocols.link', 'Loopback'),
780783
Enum_LinkType.LINUX_SLL: ModuleDescriptor('pcapkit.protocols.link', 'LinuxSLL1'),
781784
Enum_LinkType.IEEE802_11_RADIOTAP: ModuleDescriptor('pcapkit.protocols.link', 'Radiotap'),

0 commit comments

Comments
 (0)