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
5 changes: 4 additions & 1 deletion docs/source/ext.rst
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,10 @@ The available engines and the file formats they read:
matters is that the gap is *announced* -- each engine warns, or raises, for the
capability it cannot provide, rather than silently producing an empty result,
save that `PyPCAPFile`_ leaves TCP behind a VLAN tag, in a tunnel or behind an
extension header (an IPv6 one, or AH in IPv4) out without a warning. See
extension header (an IPv6 one, or AH in IPv4) out without a warning, and the
`Scapy`_ engine reads IPv6 only as far as `Scapy`_ dissects it, which leaves
IPv6 behind some BSD loopback headers, and TCP and IPv6 fragments behind some
IPv6 extension headers, out without one. See
:doc:`pcapkit/foundation/engines/index` for the full table.

.. note::
Expand Down
5 changes: 4 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ so IPv6 reassembly is unavailable. Each gap is announced with a warning or an
exception rather than silently returning nothing, save that
:class:`~pcapkit.foundation.engines.pypcapfile.PyPCAPFile` leaves TCP behind a
VLAN tag, in a tunnel or behind an extension header (an IPv6 one, or AH in IPv4)
out without one; :doc:`pcapkit/foundation/engines/index` tabulates them.
out without one, and :class:`~pcapkit.foundation.engines.scapy.Scapy` reads IPv6
only as far as `Scapy`_ dissects it, which leaves IPv6 behind some BSD loopback
headers, and TCP and IPv6 fragments behind some IPv6 extension headers, out
without one; :doc:`pcapkit/foundation/engines/index` tabulates them.

Every engine also answers a preflight check --
:meth:`~pcapkit.foundation.engines.engine.EngineBase.unsupported_reason`, which
Expand Down
5 changes: 5 additions & 0 deletions docs/source/pcapkit/foundation/engines/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ their row says otherwise:
| | PCAP savefiles only, otherwise |
| | :exc:`~pcapkit.utilities.exceptions.FormatError` |
+-----------------------------------------------------------------+---------------------------------------------------------------+
| :class:`~pcapkit.foundation.engines.scapy.Scapy` | reads IPv6 only as far as `Scapy`_ dissects it, without a |
| | warning: behind a BSD loopback header only at the family |
| | Scapy binds it to on the host it runs on, and no TCP or |
| | Fragment header behind an AH, Mobility, HIP or Shim6 header |
+-----------------------------------------------------------------+---------------------------------------------------------------+
| :class:`~pcapkit.foundation.engines.dpkt.DPKT`, | no PCAP output, since each frame reaches the writer as a |
| :class:`~pcapkit.foundation.engines.scapy.Scapy`, | plain :obj:`dict` -- ``json`` is written instead, with a |
| :class:`~pcapkit.foundation.engines.pyshark.PyShark`, | :class:`~pcapkit.utilities.warnings.FormatWarning` |
Expand Down
10 changes: 6 additions & 4 deletions docs/source/pcapkit/protocols/internet/internet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ A chain of IPv6 extension headers is dissected to at most
a row, whether it follows IPv6 or another layer such as IPv4. What follows is
kept as :class:`~pcapkit.protocols.misc.raw.Raw`, with one
:exc:`~pcapkit.utilities.warnings.ProtocolWarning` (:issue:`1604`). The
``dpkt`` and ``scapy`` toolkits stop at the same depth. The ``pyshark`` engine
leaves the walk to its own parser, which does not stop there, so it may still
find the upper layer past it (:issue:`1609`). The ``pypcapfile`` toolkit walks
no extension header chain, so it finds no upper layer behind one.
``dpkt`` toolkit stops at the same depth. The ``pyshark`` engine leaves the walk
to its own parser, which does not stop there, so it may still find the upper
layer past it (:issue:`1609`). So does the ``scapy`` engine behind IPv6, where
Scapy dissects each extension header itself; behind IPv4, its toolkit steps over
them in the octets to find TCP, and stops at the same depth. The ``pypcapfile``
toolkit walks no extension header chain, so it finds no upper layer behind one.

.. autodata:: pcapkit.protocols.internet.internet.EXTENSION_HEADER_LIMIT
7 changes: 4 additions & 3 deletions docs/source/pcapkit/protocols/protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ there back out, as they do one the TCP parser rejected (:issue:`1518`). A
protocol constructed from its own octets is not counted itself, so the count
starts at the first layer it dissects. One chain of extension headers is also bounded on
its own, by :data:`~pcapkit.protocols.internet.internet.EXTENSION_HEADER_LIMIT`.
The ``pyshark`` and ``pypcapfile`` engines dissect with their own parsers,
which do not apply this bound (:issue:`1609`). The ``dpkt`` and ``scapy``
toolkits count the layers they walk as the default engine does, and stop at it.
The ``pyshark``, ``scapy`` and ``pypcapfile`` engines dissect with their own
parsers, which do not apply the frame's layer bound (:issue:`1609`). The
``dpkt`` toolkit counts the layers it walks as the default engine does, and
stops at it.

.. autodata:: pcapkit.protocols.protocol.FRAME_LAYER_LIMIT

Expand Down
6 changes: 3 additions & 3 deletions pcapkit/foundation/engines/scapy.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def _reader_type() -> 'Type[PcapReader]':
to one table across Section Header Blocks, so a later section's interface 0
resolved to the first section's, with its link type and resolution (#1522).

And it dates two kinds of packet as the default engine does. A Simple Packet
And it dates two kinds of packet that `Scapy`_ misdates. A Simple Packet
Block has no timestamp, and `Scapy`_ leaves its packet with the time it was
built, so it is set to 0 (#1503). `Scapy`_ ignores an interface's
``if_tsoffset``, the seconds to add to each of its timestamps, so the
Expand Down Expand Up @@ -210,8 +210,8 @@ def read_packet(self, *args: 'Any', **kwargs: 'Any') -> 'ScapyPacket':
attach_resolution(packet, self._resolution)
attach_linktype(packet, self._linktype)
if not self._timed:
# no timestamp at all, which the default engine reads as 0, where
# Scapy leaves the time the packet was built (#1503)
# no timestamp at all, so 0, where Scapy leaves the time the
# packet was built (#1503)
packet.time = EDecimal(0)
elif self._offset:
packet.time += self._offset # if_tsoffset (#1549)
Expand Down
6 changes: 3 additions & 3 deletions pcapkit/foundation/extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1186,9 +1186,9 @@ def __init__(self,

# NOTE: the third-party engines' adapters hand the output writer each
# frame as a plain :obj:`dict` built by ``packet2dict``, which carries
# neither the frame's octets nor its record header, so there is nothing
# for the PCAP writer to write. The flow tracer has the same limitation,
# and is given the same replacement below.
# no record header, so there is nothing for the PCAP writer to write.
# The flow tracer has the same limitation where an engine's adapters
# build no frame record, and is given the same replacement below.
if (self._exnam in ('dpkt', 'scapy', 'pyshark', 'pypcap', 'pcap_ct', 'pypcapfile')
and format in ('pcap', 'cap')):
warn(f"'Extractor(engine={self._exnam})' does not support 'format={format}'; "
Expand Down
Loading
Loading