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
2 changes: 1 addition & 1 deletion pcapkit/protocols/link/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# Base Class for Link Layer
from pcapkit.protocols.link.link import Link

# Utility Classes for Protocols
# Link Layer Protocols
from pcapkit.protocols.link.arp import ARP, InARP
from pcapkit.protocols.link.ethernet import Ethernet

Expand Down
9 changes: 5 additions & 4 deletions pcapkit/protocols/link/arp.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
.. module:: pcapkit.protocols.link.arp

:mod:`pcapkit.protocols.link.arp` contains
:class:`~pcapkit.protocols.link.arp.ARP` only,
which implements extractor for (Inverse) Address Resolution
:class:`~pcapkit.protocols.link.arp.ARP` and
:class:`~pcapkit.protocols.link.arp.InARP`,
which implement extractors for (Inverse) Address Resolution
Protocol (ARP/InARP) [*]_, whose structure is described as
below:

Expand Down Expand Up @@ -323,7 +324,7 @@ def _make_data(cls, data: 'Data_ARP') -> 'dict[str, Any]': # type: ignore[overr
}

def _read_addr_resolve(self, addr: 'bytes', htype: 'int') -> 'str':
"""Resolve headware address according to protocol.
"""Resolve hardware address according to protocol.

Arguments:
addr: Hardware address.
Expand Down Expand Up @@ -364,7 +365,7 @@ def _read_proto_resolve(self, addr: 'bytes', ptype: 'int') -> 'str | IPv4Address
return addr.hex()

def _make_addr_resolve(self, addr: 'str | bytes', htype: 'int') -> 'bytes':
"""Resolve headware address according to protocol.
"""Resolve hardware address according to protocol.

Arguments:
addr: Hardware address.
Expand Down
7 changes: 4 additions & 3 deletions pcapkit/protocols/link/c_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ def id(cls) -> 'tuple[Literal["C_Tag"], Literal["VLAN"]]': # type: ignore[overr

Returns:
Index ID of the protocol. ``VLAN`` is retained alongside the class's
own name so that selecting the protocol by that name -- as
``pcapkit.extract(..., protocol='VLAN')`` did when this class *was*
``VLAN`` -- keeps matching.
own name so that selecting VLAN tags by that name, e.g.
``pcapkit.extract(..., protocol='VLAN')``, matches the customer
tag; :class:`~pcapkit.protocols.link.s_tag.S_Tag` carries the same
alias.

"""
return ('C_Tag', 'VLAN')
Expand Down
4 changes: 2 additions & 2 deletions pcapkit/protocols/link/ethernet.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
====== ===== ============ =========================
0 0 ``eth.dst`` Destination MAC Address
------ ----- ------------ -------------------------
1 8 ``eth.src`` Source MAC Address
6 48 ``eth.src`` Source MAC Address
------ ----- ------------ -------------------------
2 16 ``eth.type`` Protocol (Internet Layer)
12 96 ``eth.type`` Protocol (Internet Layer)
====== ===== ============ =========================

.. [*] https://en.wikipedia.org/wiki/Ethernet
Expand Down
6 changes: 3 additions & 3 deletions pcapkit/protocols/link/l2tp.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
everything after it differs, so a base that parsed further would be assuming one
version's layout for all of them.

What the family still wants
---------------------------
Unimplemented Members
---------------------

**L2TPv3** [:rfc:`3931`] has a different session header and a different control
message header from v2, and is reachable two ways -- over UDP port 1701 like v2
Expand Down Expand Up @@ -65,7 +65,7 @@
version-flavoured alias is spelled: canonical name first, alias second, since
callers take element zero as canonical.

Selecting a version
Selecting a Version
-------------------

Nothing *dispatches* on the version nibble, because only one version exists
Expand Down
12 changes: 6 additions & 6 deletions pcapkit/protocols/link/l2tpv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ def version(self) -> 'Literal[2]':
datagram whose nibble is not ``2``, so this hard-coded answer cannot
disagree with
:attr:`info.version <pcapkit.protocols.data.link.l2tp.L2TP.version>`
on the same octets. It did before that guard landed, reporting ``2``
here and ``3`` there.
on the same octets.

"""
return 2
Expand Down Expand Up @@ -234,9 +233,9 @@ def read(self, length: 'Optional[int]' = None, **kwargs: 'Any') -> 'Data_L2TP':
# L2TP carries no next-protocol field -- the payload is a PPP frame,
# which pcapkit does not dissect -- so dispatch on the -1 sentinel, as
# ARP does, rather than on a code read off the wire. Passing the
# remaining length here (as this did) dispatched on it as if it were an
# EtherType, which resolved to Raw only because a length rarely collides
# with a registered one.
# remaining length here would dispatch on it as if it were an EtherType,
# resolving to Raw only because a length rarely collides with a
# registered one.
return self._decode_next_layer(l2tp, -1, length - hdr_len)

def make(self,
Expand Down Expand Up @@ -335,7 +334,8 @@ def __index__(cls) -> 'NoReturn': # pylint: disable=invalid-index-returned
``__index__`` value anywhere in this package -- every non-raising
``__index__`` returns a :class:`~pcapkit.const.reg.transtype.TransType`,
:class:`~pcapkit.const.reg.ethertype.EtherType` or
:class:`~pcapkit.const.reg.linktype.LinkType`, and
:class:`~pcapkit.const.reg.linktype.LinkType`, bar the PCAP frame and
PCAP-NG block instances that return their own index number, and
:meth:`Application.__index__
<pcapkit.protocols.application.application.Application.__index__>`
raises for exactly this reason. So there is no index to return here.
Expand Down
10 changes: 5 additions & 5 deletions pcapkit/protocols/link/vlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
======= ========= ====================== =============================
Octets Bits Name Description
======= ========= ====================== =============================
1 0 ``vlan.tci`` Tag Control Information
1 0 ``vlan.tci.pcp`` Priority Code Point
1 3 ``vlan.tci.dei`` Drop Eligible Indicator
1 4 ``vlan.tci.vid`` VLAN Identifier
3 24 ``vlan.type`` Protocol (Internet Layer)
0 0 ``vlan.tci`` Tag Control Information
0 0 ``vlan.tci.pcp`` Priority Code Point
0 3 ``vlan.tci.dei`` Drop Eligible Indicator
0 4 ``vlan.tci.vid`` VLAN Identifier
2 16 ``vlan.type`` Protocol (Internet Layer)
======= ========= ====================== =============================

The two tags carry an **identical** tag control information layout -- the same
Expand Down
9 changes: 3 additions & 6 deletions pcapkit/protocols/misc/pcap/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ class Frame(ProtocolBase[Data_Frame, Schema_Frame],
#: DefaultDict[Enum_LinkType, ModuleDescriptor[ProtocolBase] | ~typing.Type[ProtocolBase]]: Protocol index mapping for
#: decoding next layer, c.f. :meth:`self._decode_next_layer <pcapkit.protocols.protocol.Protocol._decode_next_layer>`
#: & :meth:`self._import_next_layer <pcapkit.protocols.protocol.Protocol._import_next_layer>`.
#: The values should be a tuple representing the module name and class name, or
#: a :class:`~pcapkit.protocols.protocol.Protocol` subclass.
#: Each value is a :class:`~pcapkit.corekit.module.ModuleDescriptor` naming the
#: module and class, or a :class:`~pcapkit.protocols.protocol.Protocol` subclass.
__proto__ = collections.defaultdict(
lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
{
Expand Down Expand Up @@ -282,10 +282,7 @@ def read(self, length: 'Optional[int]' = None, *, _read: 'bool' = True,
# as "Frame length stored into the capture file", and raises
# ``frame.len_lt_caplen`` (``PI_MALFORMED``) on ``frame_len <
# cap_len``, which could not be malformed if ``len`` were the smaller,
# captured one. Age does not settle it: this reader's older
# convention (c43892af, 2022-01-11) was the swapped one, and the
# PCAP-NG reader's later one (25f216f4, 2023-04-27) matches the names,
# so this reader was brought into line with it.
# captured one. The PCAP-NG reader uses the same convention.
len=_olen,
cap_len=_ilen,
)
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/protocols/misc/pcap/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
.. module:: pcapkit.protocols.misc.pcap.header

:mod:`pcapkit.protocols.misc.pcap.header` contains
:class:`~pcapkit.protocols.misc.pcap.Header` only,
:class:`~pcapkit.protocols.misc.pcap.header.Header` only,
which implements extractor for global headers [*]_
of PCAP, whose structure is described as below:

Expand Down
20 changes: 10 additions & 10 deletions pcapkit/protocols/misc/pcapng.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,11 +498,11 @@ class PCAPNG(ProtocolBase[Data_PCAPNG, Schema_PCAPNG],
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._read_option_isb_usrdeliv`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._make_option_isb_usrdeliv`
* - :attr:`~pcapkit.const.pcapng.option_type.OptionType.pack_flags`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._read_option_epb_flags`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._make_option_epb_flags`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._read_option_pack_flags`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._make_option_pack_flags`
* - :attr:`~pcapkit.const.pcapng.option_type.OptionType.pack_hash`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._read_option_epb_hash`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._make_option_epb_hash`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._read_option_pack_hash`
- :meth:`~pcapkit.protocols.misc.pcapng.PCAPNG._make_option_pack_hash`

The class currently supports parsing of the following name resolution
record types, which are registered in the :attr:`self.__record__ <pcapkit.protocols.misc.pcapng.PCAPNG.__record__>`
Expand Down Expand Up @@ -580,8 +580,8 @@ class PCAPNG(ProtocolBase[Data_PCAPNG, Schema_PCAPNG],
#: DefaultDict[Enum_LinkType, ModuleDescriptor[ProtocolBase] | ~typing.Type[ProtocolBase]]: Protocol index mapping for
#: decoding next layer, c.f. :meth:`self._decode_next_layer <pcapkit.protocols.protocol.Protocol._decode_next_layer>`
#: & :meth:`self._import_next_layer <pcapkit.protocols.protocol.Protocol._import_next_layer>`.
#: The values should be a tuple representing the module name and class name,
#: or a :class:`~pcapkit.protocols.protocol.Protocol` subclass.
#: Each value is a :class:`~pcapkit.corekit.module.ModuleDescriptor` naming the
#: module and class, or a :class:`~pcapkit.protocols.protocol.Protocol` subclass.
__proto__ = collections.defaultdict(
lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
{
Expand Down Expand Up @@ -1307,8 +1307,8 @@ def _check_block_floor(self, length: 'Optional[int]') -> 'None':
which has no catch point above it and would abort the whole extraction --
this costs no frame that was actually in the file. It is the same signal
:func:`~pcapkit.utilities.decorators.prepare` raises for a *derived*
remainder of exactly zero; only one, two or three stray octets fell
through it.
remainder of exactly zero; a remainder of one, two or three octets
passes that check and is caught here instead.

Note:
This runs on the parsing path only, since :meth:`unpack` reaches it
Expand Down Expand Up @@ -3523,7 +3523,7 @@ def _read_secrets_zigbee_nwk(self, schema: 'Schema_ZigBeeNWKKey', *,
12 | Secrets Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 | AES-128 |
| NKW Key |
| NWK Key |
| (16 octets) |
| (128 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Expand Down Expand Up @@ -5394,7 +5394,7 @@ def _make_option_isb_usrdeliv(self, type: 'Enum_OptionType', option: 'Optional[D
Args:
type: Option type.
option: Option data model.
packets: Number of dropped packets.
packets: Number of packets delivered to the user.
**kwargs: Arbitrary keyword arguments.

Returns:
Expand Down
31 changes: 16 additions & 15 deletions pcapkit/protocols/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,8 @@ class ProtocolBase(Generic[_PT, _ST], metaclass=ProtocolMeta):
#: Protocol index mapping for decoding next layer, c.f.
#: :meth:`self._decode_next_layer <pcapkit.protocols.protocol.Protocol._decode_next_layer>`
#: & :meth:`self._import_next_layer <pcapkit.protocols.protocol.Protocol._import_next_layer>`.
#: The values should be a tuple representing the module name and class name,
#: or a :class:`Protocol` subclass.
#: Each value is a :class:`~pcapkit.corekit.module.ModuleDescriptor` naming the
#: module and class, or a :class:`Protocol` subclass.
__proto__: 'DefaultDict[int, ModuleDescriptor[ProtocolBase] | Type[ProtocolBase]]' = collections.defaultdict(
lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
)
Expand Down Expand Up @@ -603,7 +603,7 @@ def decode(byte: bytes, *, encoding: 'Optional[str]' = None,
byte: Source bytestring.
encoding: The encoding with which to decode the :obj:`bytes`.
If not provided, :mod:`pcapkit` will first try detecting its encoding
using |chardet|_. The fallback encoding would is **UTF-8**.
using |chardet|_. The fallback encoding is **UTF-8**.
errors: The error handling scheme to use for the handling of decoding errors.
The default is ``'strict'`` meaning that decoding errors raise a
:exc:`UnicodeDecodeError`. Other possible values are ``'ignore'`` and ``'replace'``
Expand Down Expand Up @@ -635,8 +635,9 @@ def unquote(url: str, *, encoding: 'str' = 'utf-8',
url: URL string.
encoding: The encoding with which to decode the :obj:`bytes`.
errors: The error handling scheme to use for the handling of decoding errors.
The default is ``'strict'`` meaning that decoding errors raise a
:exc:`UnicodeDecodeError`. Other possible values are ``'ignore'`` and ``'replace'``
The default is ``'replace'``, which substitutes a replacement marker for
each undecodable sequence. Other possible values are ``'strict'``, under
which decoding errors raise a :exc:`UnicodeDecodeError`, and ``'ignore'``,
as well as any other name registered with :func:`codecs.register_error` that
can handle :exc:`UnicodeDecodeError`.

Expand Down Expand Up @@ -1127,7 +1128,7 @@ def __repr__(self) -> 'str':

Example:
>>> protocol
<Frame alias='...' frame=(..., packet=b'...', sethernet=..., protocols='Ethernet:IPv6:Raw')>
<Frame frame=<Frame ..., ethernet=Ethernet(...), protocols='Ethernet:IPv6:Raw', packet=b'...'>>

"""
if (cached := self.__cached__.get('__repr__')) is not None:
Expand All @@ -1144,7 +1145,7 @@ def __str__(self) -> 'str':

Example:
>>> protocol
Frame(..., packet=b"...", sethernet=..., protocols='Ethernet:IPv6:Raw')
<Frame frame=<Frame ..., ethernet=Ethernet(...), protocols='Ethernet:IPv6:Raw', packet=b'...'>>
>>> print(protocol)
00 00 00 00 00 00 00 a6 87 f9 27 93 16 ee fe 80 00 00 00 ..........'........
00 00 00 1c cd 7c 77 ba c7 46 b7 87 00 0e aa 00 00 00 00 .....|w..F.........
Expand Down Expand Up @@ -1277,7 +1278,7 @@ def __eq__(cls, other: 'object') -> 'bool':
"""Returns if ``other`` is of the same protocol as the current object.

Args:
other: Comparision against the object.
other: Comparison against the object.

"""
if isinstance(other, type) and issubclass(other, ProtocolBase):
Expand Down Expand Up @@ -1375,7 +1376,7 @@ def _read_unpack(self, size: 'int' = 1, *, signed: 'bool' = False,
Unpacked data upon success

Raises:
StructError: If unpack (:func:`struct.pack`) failed, and :exc:`struct.error` raised.
StructError: If unpack (:func:`struct.unpack`) failed, and :exc:`struct.error` raised.

"""
endian = '<' if lilendian else '>'
Expand All @@ -1387,7 +1388,7 @@ def _read_unpack(self, size: 'int' = 1, *, signed: 'bool' = False,
kind = 'h' if signed else 'H'
elif size == 1: # unpack to 1-byte integer (char)
kind = 'b' if signed else 'B'
else: # do not unpack
else: # no struct format, see int.from_bytes below
kind = None

mem = self._file.read(size)
Expand Down Expand Up @@ -1480,15 +1481,15 @@ def _make_pack(cls, integer: 'int', *, size: 'int' = 1,

"""
endian = '<' if lilendian else '>'
if size == 8: # unpack to 8-byte integer (long long)
if size == 8: # pack from 8-byte integer (long long)
kind = 'q' if signed else 'Q'
elif size == 4: # unpack to 4-byte integer (int / long)
elif size == 4: # pack from 4-byte integer (int / long)
kind = 'i' if signed else 'I'
elif size == 2: # unpack to 2-byte integer (short)
elif size == 2: # pack from 2-byte integer (short)
kind = 'h' if signed else 'H'
elif size == 1: # unpack to 1-byte integer (char)
elif size == 1: # pack from 1-byte integer (char)
kind = 'b' if signed else 'B'
else: # do not unpack
else: # no struct format, see int.to_bytes below
kind = None

if kind is None:
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/protocols/transport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# Base Class for Transport Layer
from pcapkit.protocols.transport.transport import Transport

# Utility Classes for Protocols
# Transport Layer Protocols
from pcapkit.protocols.transport.sctp import SCTP
from pcapkit.protocols.transport.tcp import TCP
from pcapkit.protocols.transport.udp import UDP
Expand Down
8 changes: 4 additions & 4 deletions pcapkit/protocols/transport/tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
8 64 ``tcp.ack`` Acknowledgement Number (if ACK set)
12 96 ``tcp.hdr_len`` Data Offset
12 100 Reserved (must be ``\\x00``)
12 103 ``tcp.flags.ns`` ECN Concealment Protection (NS)
12 103 ECN Concealment Protection (NS), not parsed
13 104 ``tcp.flags.cwr`` Congestion Window Reduced (CWR)
13 105 ``tcp.flags.ece`` ECN-Echo (ECE)
13 106 ``tcp.flags.urg`` Urgent (URG)
Expand Down Expand Up @@ -1565,7 +1565,7 @@ def _read_mptcp_join(self, schema: 'Schema_MPTCPJoin', *, options: 'Option') ->
Parsed option data.

Raises:
ProtocolError: If the option is not given on a valid SYN/ACK packet.
ProtocolError: If the segment carries neither SYN nor ACK.

"""
if Enum_Flags.SYN in self._flags and Enum_Flags.ACK not in self._flags: # MP_JOIN-SYN
Expand Down Expand Up @@ -1771,7 +1771,7 @@ def _read_mptcp_addaddr(self, schema: 'Schema_MPTCPAddAddress', *, options: 'Opt
+---------------+---------------+-------+-------+---------------+
| Kind | Length |Subtype| IPVer | Address ID |
+---------------+---------------+-------+-------+---------------+
| Address (TCP - 4 octets / IPv6 - 16 octets) |
| Address (IPv4 - 4 octets / IPv6 - 16 octets) |
+-------------------------------+-------------------------------+
| Port (2 octets, optional) |
+-------------------------------+
Expand Down Expand Up @@ -2755,7 +2755,7 @@ def _make_mptcp_capable(self, subtype: 'Enum_MPTCPOption', opt: 'Optional[Data_M
opt: option data
version: MPTCP version
flag_req: checksum required flag
flag_ext: extensability flag
flag_ext: extensibility flag
flag_hsa: use of HMAC-SHA1 flag
skey: option sender's key
rkey: option receiver's key
Expand Down
Loading
Loading