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: 4 additions & 4 deletions pcapkit/protocols/application/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

.. module:: pcapkit.protocols.application

:mod:`pcapkit.protocols.application` is collection of all protocols in
application layer, with detailed implementation and methods.
:mod:`pcapkit.protocols.application` is a collection of all protocols in
application layer.

"""
# TODO: Implements BGP, DHCP, DHCPv6, DNS, IMAP, LDAP, MQTT,
Expand All @@ -17,7 +17,7 @@
# dependency, c.f. pcapkit.protocols.application.ngap. Importing the module
# is free -- ``pycrate`` is imported inside the parse path, not here.

# Base Class for Internet Layer
# Base Class for Application Layer
from pcapkit.protocols.application.application import Application

# Utility Classes for Protocols
Expand All @@ -31,7 +31,7 @@
# Base Classes
from pcapkit.protocols.application.http import HTTP

# Transport Layer Protocol Numbers
# Application Layer Protocol Numbers
from pcapkit.const.reg.apptype import AppType as APPTYPE

__all__ = [
Expand Down
9 changes: 4 additions & 5 deletions pcapkit/protocols/application/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@

:mod:`pcapkit.protocols.application.application` contains only
:class:`~pcapkit.protocols.application.application.Application`,
which is a base class for application layer protocols, eg.
:class:`HTTP/1.* <pcapkit.protocols.application.httpv1.HTTP>`,
:class:`HTTP/2 <pcapkit.protocols.application.httpv2.HTTP>`
and etc.
which is a base class for application layer protocols, e.g.
:class:`HTTP/1.* <pcapkit.protocols.application.httpv1.HTTP>` and
:class:`HTTP/2 <pcapkit.protocols.application.httpv2.HTTP>`.

"""
from typing import TYPE_CHECKING, Generic, overload
Expand Down Expand Up @@ -87,7 +86,7 @@ def __post_init__(self, file: 'Optional[IO[bytes] | bytes]' = None,
# ``_decode_next_layer``, which already set the payload and the chain
# (basis included); only a protocol that did not gets the empty default
if getattr(self, '_next', None) is None:
#: pcapkit.protocols.null.NoPayload: Payload of current instance.
#: pcapkit.protocols.misc.null.NoPayload: Payload of current instance.
self._next = NoPayload()
#: pcapkit.corekit.protochain.ProtoChain: Protocol chain of current instance.
self._protos = ProtoChain(self.__class__, self.alias)
Expand Down
9 changes: 6 additions & 3 deletions pcapkit/protocols/application/ftp.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# -*- coding: utf-8 -*-
"""file transfer protocol
"""FTP - File Transfer Protocol
================================

.. module:: pcapkit.protocols.application.ftp

:mod:`pcapkit.protocols.application.ftp` contains
:class:`~pcapkit.protocols.application.ftp.FTP` only,
:class:`~pcapkit.protocols.application.ftp.FTP`,
which implements extractor for File Transfer Protocol
(FTP) [*]_.
(FTP) [*]_, and
:class:`~pcapkit.protocols.application.ftp.FTP_DATA`
for its data channel.

.. [*] https://en.wikipedia.org/wiki/File_Transfer_Protocol

Expand Down
9 changes: 5 additions & 4 deletions pcapkit/protocols/application/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,11 @@ def _guess_version(self, length: 'int', **kwargs: 'Any') -> 'HTTP':

Raises:
ProtocolError: If no version in the family accepts the payload, or if
an identified version's own parser refuses it. This is the
*only* exception this method raises for an unparseable payload --
a candidate failing in any other way, on a version that was not
positively identified, is a fall-through and not an answer.
an identified version's own parser refuses it. Only a
``ProtocolError`` from a trial parse falls through to the next
version, and the final HTTP/2 trial also absorbs
:exc:`struct.error`; any other exception from either HTTP/1
arm, or from that HTTP/2 trial, propagates unconverted.

Note:
Two things this deliberately does **not** decide, because one payload
Expand Down
17 changes: 8 additions & 9 deletions pcapkit/protocols/application/httpv1.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@
# Regular expression to match HTTP status code. Anchored for the same reason as
# ``_RE_METHOD``, and it matters more here: this pattern is only a guard, and the
# value is taken from ``int(para2)`` on the raw token, so an unanchored prefix
# match let ``200x`` and ``2000`` past the guard and then out of ``int()`` as a
# bare ``ValueError`` -- where ``_read_http_header`` documents ``ProtocolError``.
# match would let ``200x`` and ``2000`` past the guard and then out of ``int()``
# as a bare ``ValueError`` -- where ``_read_http_header`` documents
# ``ProtocolError``.
# :rfc:`9112#section-4` gives ``status-code = 3DIGIT``, exactly three -- the
# grammar is in HTTP/1.1 because ``status-code`` is part of its ``status-line``
# production; :rfc:`9110#section-15` covers the code semantics and registry, not
Expand Down Expand Up @@ -404,9 +405,7 @@ def _read_http_header(self, header: 'bytes') -> 'tuple[Data_Header, OrderedMulti
# unfolded here -- the RFC's own remedy -- rather than treated as a field
# line of its own. Deprecated, but present in real captures. Treating a
# continuation as a field line of its own goes wrong twice: one carrying
# no colon leaves the split below one element long, so ``item[1]`` raises
# :exc:`IndexError`, which is neither a :exc:`ValueError` nor a
# ``ProtocolError`` and escapes ``HTTP._guess_version``'s suppression;
# no colon fails the colon check below, so a valid message is refused;
# one that happens to contain a colon parses silently into a spurious
# extra field (``X-Long: a`` plus ``b: c``, for a folded ``X-Long: a b``).
# Unfolded, a folded message parses to the field it actually carries.
Expand All @@ -421,10 +420,10 @@ def _read_http_header(self, header: 'bytes') -> 'tuple[Data_Header, OrderedMulti
# continuation, because the production is ``obs-fold = OWS CRLF
# RWS`` and it is the *whole* obs-fold that is replaced by a
# single space -- the OWS before the CRLF belongs to the fold,
# not to the value. Stripping only the continuation left that OWS
# in place, so ``X: a \t\r\n\tb`` unfolded to ``'a \t b'``
# rather than ``'a b'``: four of five folded/literal pairs
# disagreed, and a HTAB survived where the RFC prescribes SP.
# not to the value. Stripping only the continuation would leave
# that OWS in place, so ``X: a \t\r\n\tb`` would unfold to
# ``'a \t b'`` rather than ``'a b'``, keeping a HTAB where the
# RFC prescribes SP.
fields[-1] = fields[-1].rstrip() + b' ' + line.strip()
continue
fields.append(line)
Expand Down
14 changes: 10 additions & 4 deletions pcapkit/protocols/application/httpv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ class HTTP(HTTPBase[Data_HTTP, Schema_HTTP],
##########################################################################

#: DefaultDict[Enum_Frame, str | tuple[FrameParser, FrameConstructor]]: Frame
#: code to method mapping. Method names are expected to be referred to
#: the class by ``_read_http_${name}`` and/or ``_make_http_${name}``, and if
#: such name not found, the value should then be a method that can parse the
#: frame by itself.
#: code to method mapping. A :obj:`str` value names the
#: ``_read_http_${name}`` and ``_make_http_${name}`` methods, which fall back
#: to ``_read_http_none`` and ``_make_http_none`` when not defined, as an
#: unregistered code does; any other value is a ``(parser, constructor)``
#: pair of callables.
__frame__ = collections.defaultdict(
lambda: 'none',
{
Expand Down Expand Up @@ -1009,6 +1010,7 @@ def _make_http_data(self, frame: 'Optional[Data_DataFrame]' = None, *,
Args:
frame: Frame data model.
end_stream: End of stream flag.
pad_len: Padding length.
data: Frame data.
**kwargs: Arbitrary keyword arguments.

Expand Down Expand Up @@ -1048,6 +1050,7 @@ def _make_http_headers(self, frame: 'Optional[Data_HeadersFrame]' = None, *,
frame: Frame data model.
end_stream: End of stream flag.
end_headers: End of headers flag.
pad_len: Padding length.
excl_dep: Exclusive dependency flag.
sid_dep: Dependency stream identifier.
weight: Priority weight value.
Expand Down Expand Up @@ -1134,6 +1137,9 @@ def _make_http_rst_stream(self, frame: 'Optional[Data_RSTStreamFrame]' = None, *
Args:
frame: Frame data model.
error: Error code.
error_default: Default value of error code.
error_namespace: Namespace of error code.
error_reversed: Reversed namespace of error code.
**kwargs: Arbitrary keyword arguments.

Returns:
Expand Down
5 changes: 3 additions & 2 deletions pcapkit/protocols/application/ngap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
.. module:: pcapkit.protocols.application.ngap

:mod:`pcapkit.protocols.application.ngap` contains
:class:`~pcapkit.protocols.application.ngap.NGAP` only,
:class:`~pcapkit.protocols.application.ngap.NGAP`,
which implements extractor for the NG Application Protocol
(NGAP) [*]_, as specified in 3GPP TS 38.413.
(NGAP) [*]_, as specified in 3GPP TS 38.413, and the enumerations its
decoded fields resolve to.

NGAP is the control plane between a 5G RAN node (gNB or ng-eNB) and an AMF.
It runs over SCTP and is named by the DATA chunk's *payload protocol
Expand Down
20 changes: 9 additions & 11 deletions pcapkit/protocols/application/ospf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
====== ===== ================== ===============================
0 0 ``ospf.version`` Version Number
------ ----- ------------------ -------------------------------
0 0 ``ospf.type`` Type
1 8 ``ospf.type`` Type
------ ----- ------------------ -------------------------------
0 1 ``ospf.len`` Packet Length (header included)
2 16 ``ospf.len`` Packet Length (header included)
------ ----- ------------------ -------------------------------
0 2 ``ospf.router_id`` Router ID
4 32 ``ospf.router_id`` Router ID
------ ----- ------------------ -------------------------------
0 4 ``ospf.area_id`` Area ID
8 64 ``ospf.area_id`` Area ID
------ ----- ------------------ -------------------------------
0 6 ``ospf.chksum`` Checksum
12 96 ``ospf.chksum`` Checksum
------ ----- ------------------ -------------------------------
0 7 ``ospf.autype`` Authentication Type
14 112 ``ospf.autype`` Authentication Type
------ ----- ------------------ -------------------------------
1 8 ``ospf.auth`` Authentication
16 128 ``ospf.auth`` Authentication
====== ===== ================== ===============================

.. [*] https://en.wikipedia.org/wiki/Open_Shortest_Path_First
Expand Down Expand Up @@ -187,10 +187,8 @@ def read(self, length: 'Optional[int]' = None, **kwargs: 'Any') -> 'Data_OSPF':
])
# OSPF carries no next-protocol field -- the body is LSAs and packet-type
# specific fields, 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.
# -1 sentinel, as ARP does, rather than on a code read off the wire;
# ``Application._decode_next_layer`` refuses any other value.
return self._decode_next_layer(ospf, -1, length - self.length)

def make(self,
Expand Down
5 changes: 3 additions & 2 deletions pcapkit/protocols/application/rarp.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
.. module:: pcapkit.protocols.application.rarp

:mod:`pcapkit.protocols.application.rarp` contains
:class:`~pcapkit.protocols.application.rarp.RARP` only,
which implements extractor for (Dynamic) Reverse
:class:`~pcapkit.protocols.application.rarp.RARP` and
:class:`~pcapkit.protocols.application.rarp.DRARP`,
which implement extractors for (Dynamic) Reverse
Address Resolution Protocol (RARP/DRARP) [*]_,
whose structure is described as below:

Expand Down
Loading