Root Protocol#

pcapkit.protocols.protocol contains Protocol only, which is an abstract base class for all protocol family, with pre-defined utility arguments and methods of specified protocols.

class pcapkit.protocols.protocol.Protocol(file=None, length=None, **kwargs)[source]#

Bases: ProtocolBase, Generic[_PT, _ST]

Abstract base class for all protocol family.

abstract property name: str#

Name of current protocol.

property alias: str#

Acronym of current protocol.

property info_name: str#

Key name of the info dict.

property info: _PT#

Info dict of current instance.

property data: bytes#

Binary packet data of current instance.

abstract property length: int#

Header length of current protocol.

property payload: ProtocolBase#

Payload of current instance.

property protocol: str | None#

Name of next layer protocol (if any).

property protochain: ProtoChain#

Protocol chain of current instance.

property packet: Packet#

Data_Packet data of the protocol.

property schema: _ST#

Schema data of the protocol.

classmethod id()#

Index ID of the protocol.

Return type:

tuple[str, ...]

Returns:

By default, it returns the name of the protocol. In certain cases, the method may return multiple values.

classmethod register(code, protocol)#

Register a new protocol class.

Notes

The full qualified class name of the new protocol class should be as {protocol.module}.{protocol.name}.

Parameters:
Return type:

None

classmethod analyze(proto, payload, **kwargs)#

Analyse packet payload.

Parameters:
  • proto (int) – Protocol registry number.

  • payload (bytes) – Packet payload.

  • **kwargs (Any) – Arbitrary keyword arguments.

Return type:

ProtocolBase

Returns:

Parsed payload as a Protocol instance.

classmethod from_schema(schema)#

Create protocol instance from schema.

Parameters:

schema (Union[TypeVar(_ST, bound= Schema), dict[str, Any]]) – Protocol schema.

Return type:

Self

Returns:

Protocol instance.

classmethod from_data(data)#

Create protocol instance from data.

Parameters:

data (Union[TypeVar(_PT, bound= Data), dict[str, Any]]) – Protocol data.

Return type:

Self

Returns:

Protocol instance.

abstract read(length=None, **kwargs)#

Read (parse) packet data.

Parameters:
  • length (Optional[int]) – Length of packet data.

  • **kwargs (Any) – Arbitrary keyword arguments.

Return type:

TypeVar(_PT, bound= Data)

Returns:

Parsed packet data.

abstract make(**kwargs)#

Make (construct) packet data.

Parameters:

**kwargs (Any) – Arbitrary keyword arguments.

Return type:

TypeVar(_ST, bound= Schema)

Returns:

Curated protocol schema data.

unpack(length=None, **kwargs)#

Unpack (parse) packet data.

Parameters:
  • length (Optional[int]) – Length of packet data.

  • **kwargs (Any) – Arbitrary keyword arguments.

Return type:

TypeVar(_PT, bound= Data)

Returns:

Parsed packet data.

Notes

We used a special keyword argument __packet__ to pass the global packet data to underlying methods. This is useful when the packet data is not available in the current instance.

pack(**kwargs)#

Pack (construct) packet data.

Parameters:

**kwargs (Any) – Arbitrary keyword arguments.

Return type:

bytes

Returns:

Constructed packet data.

Notes

We used a special keyword argument __packet__ to pass the global packet data to underlying methods. This is useful when the packet data is not available in the current instance.

static decode(byte, *, encoding=None, errors='strict')#

Decode bytes into str.

Should decoding failed using encoding, the method will try again decoding the bytes as 'unicode_escape' with 'replace' for error handling.

See also

The method is a wrapping function for bytes.decode().

Parameters:
  • byte (bytes) – Source bytestring.

  • encoding (Optional[str]) – The encoding with which to decode the bytes. If not provided, pcapkit will first try detecting its encoding using chardet. The fallback encoding would is UTF-8.

  • errors (Literal['strict', 'ignore', 'replace']) – The error handling scheme to use for the handling of decoding errors. The default is 'strict' meaning that decoding errors raise a UnicodeDecodeError. Other possible values are 'ignore' and 'replace' as well as any other name registered with codecs.register_error() that can handle UnicodeDecodeError.

Return type:

str

static unquote(url, *, encoding='utf-8', errors='replace')#

Unquote URLs into readable format.

Should decoding failed , the method will try again replacing '%' with '\x' then decoding the url as 'unicode_escape' with 'replace' for error handling.

See also

This method is a wrapper function for urllib.parse.unquote().

Parameters:
  • url (str) – URL string.

  • encoding (str) – The encoding with which to decode the bytes.

  • errors (Literal['strict', 'ignore', 'replace']) – The error handling scheme to use for the handling of decoding errors. The default is 'strict' meaning that decoding errors raise a UnicodeDecodeError. Other possible values are 'ignore' and 'replace' as well as any other name registered with codecs.register_error() that can handle UnicodeDecodeError.

Return type:

str

static expand_comp(value)#

Expand protocol class to protocol name.

The method is used to expand protocol class to protocol name, in the following manner:

  1. If value is a protocol instance, the method will return the protocol class, and the protocol names in upper case obtained from Protocol.id.

  2. If value is a protocol class, the method will return the protocol class itself, and the protocols names in upper case obtained from Protocol.id.

  3. If value is str, the method will attempt to search for the existing registered protocol class from pcapkit.protocols.__proto__ and follow step 2; otherwise, return the value itself.

Parameters:

value (Union[str, ProtocolBase, Type[ProtocolBase]]) – Protocol class or name.

Return type:

tuple

__layer__: Optional[Literal['Link', 'Internet', 'Transport', 'Application']]#

Layer of protocol, can be one of Link, Internet, Transport and Application. For example, the layer of Ethernet is Link. However, certain protocols are not in any layer, such as Raw, and thus its layer is None.

__proto__: DefaultDict[int, Union[ModuleDescriptor[ProtocolBase], Type[ProtocolBase]]]#

Protocol index mapping for decoding next layer, c.f. self._decode_next_layer & self._import_next_layer. The values should be a tuple representing the module name and class name, or a Protocol subclass.

__schema__(dict_=None, **kwargs): Type[TypeVar(_ST, bound= Schema)]#

Protocol header schema definition.

__header__: TypeVar(_ST, bound= Schema)#

Protocol header schema instance.

_read_packet(length=None, *, header=None, payload=None, discard=False)#

Read raw packet data.

Parameters:
  • length (Optional[int]) – length of the packet

  • header (Optional[int]) – length of the packet header

  • payload (Optional[int]) – length of the packet payload

  • discard (bool) – flag if discard header data

Return type:

bytes | Packet

  • If header omits, returns the whole packet data in bytes.

  • If discard is set as True, returns the packet body (in bytes) only.

  • Otherwise, returns the header and payload data as Packet object.

_get_payload()#

Get payload from self.__header__.

Return type:

bytes

Returns:

Payload of self.__header__ as bytes.

See also

This is a wrapper function for pcapkit.protocols.schema.schema.Schema.get_payload().

classmethod _make_data(data)#

Create key-value pairs from data for protocol construction.

Parameters:

data (Data) – protocol data

Return type:

dict[str, Any]

Returns:

Key-value pairs for protocol construction.

classmethod _make_index(name, default=None, *, namespace=None, reversed=False, pack=False, size=4, signed=False, lilendian=False)#

Return first index of name from a dict or enumeration.

Parameters:
Return type:

int | bytes

Returns:

Index of name from a dict or enumeration. If pack is True, returns bytes; otherwise, returns int.

Raises:

ProtocolNotImplemented – If name is NOT in namespace and default is None.

classmethod _make_payload(data)#

Create payload from data for protocol construction.

This method uses __next_type__ and __next_name__ to determine the payload type and name. If either of them is None, a NoPayload instance will be returned. Otherwise, the payload will be constructed by Protocol.from_data.

Parameters:

data (Data) – protocol data

Return type:

ProtocolBase

Returns:

Payload for protocol construction.

_decode_next_layer(dict_, proto, length=None, *, packet=None)#

Decode next layer protocol.

Parameters:
Return type:

TypeVar(_PT, bound= Data)

Returns:

Current protocol with next layer extracted.

Notes

We added a new key __next_type__ to dict_ to store the next layer protocol type, and a new key __next_name__ to store the next layer protocol name. These two keys will NOT be included when Info.to_dict is called.

_import_next_layer(proto, length=None, *, packet=None)#

Import next layer extractor.

Parameters:
Return type:

ProtocolBase

Returns:

Instance of next layer.

_file: IO[bytes]#

Source packet stream.

_info: TypeVar(_PT, bound= Data)#

Parsed packet data.

__data__: Type[TypeVar(_PT, bound= Data)] = <class 'pcapkit.protocols.data.misc.raw.Raw'>#

Protocol packet data definition.

__init__(file=None, length=None, **kwargs)#

Initialisation.

Parameters:
  • file (Union[IO[bytes], bytes, None]) – Source packet stream.

  • length (Optional[int]) – Length of packet data.

  • _layer (str) – Parse packet until _layer (self._exlayer).

  • _protocol (Union[str, Protocol, Type[Protocol]]) – Parse packet until _protocol (self._exproto).

  • **kwargs (Any) – Arbitrary keyword arguments.

__post_init__(file=None, length=None, **kwargs)#

Post initialisation hook.

Parameters:
Return type:

None

See also

For construction arguments, please refer to self.make.

classmethod __init_subclass__(schema=None, data=None, *args, **kwargs)[source]#

Initialisation for subclasses.

Parameters:
  • schema (Optional[Type[TypeVar(_ST, bound= Schema)]]) – Schema class.

  • data (Optional[Type[TypeVar(_PT, bound= Data)]]) – Data class.

  • *args (Any) – Arbitrary positional arguments.

  • **kwargs (Any) – Arbitrary keyword arguments.

Return type:

None

This method is called when a subclass of Protocol is defined. It is used to set the self.__schema__ attribute of the subclass.

Notes

When schema and/or data is not specified, the method will first try to find the corresponding class in the schema and data modules respectively. If the class is not found, the default Schema_Raw and Data_Raw classes will be used.

This method also registers the subclass to the protocol registry, i.e., pcapkit.protocols.__proto__.

See also

For more information on the registry, please refer to pcapkit.foundation.registry.protocols.register_protocol().

__repr__()#

Returns representation of parsed protocol data. :rtype: str

Example

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

Returns formatted hex representation of source data stream. :rtype: str

Example

>>> protocol
Frame(..., packet=b"...", sethernet=..., protocols='Ethernet:IPv6:Raw')
>>> 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.........
fe 80 00 00 00 00 00 00 1c cd 7c 77 ba c7 46 b7 01 01 a4     ..........|w..F....
5e 60 d9 6b 97                                               ^`.k.
__getitem__(key)#

Subscription (getitem) support.

  • If key is a Protocol object, the method will fetch its indexes (self.id).

  • Later, search the packet’s chain of protocols with the calculated key.

  • If no matches, then raises ProtocolNotFound.

Parameters:

key (Union[str, Protocol, Type[Protocol]]) – Indexing key.

Return type:

ProtocolBase

Returns:

The sub-packet from the current packet of indexed protocol.

Raises:

ProtocolNotFound – If key is not in the current packet.

See also

The method calls self.expand_comp to handle the key and expand it for robust searching.

__contains__(name)#

Returns if certain protocol is in the instance.

Parameters:

name (Union[str, Protocol, Type[Protocol]]) – Name to search

Return type:

bool

See also

The method calls self.expand_comp to handle the name and expand it for robust searching.

abstract classmethod __index__()#

Numeral registry index of the protocol.

Return type:

IntEnum | IntEnum

_exlayer: Optional[str]#

Parse packet until such layer.

Type:

str

_exproto: Union[str, ProtocolBase, Type[ProtocolBase], None]#

Parse packet until such protocol.

Type:

str

Data Models#

class pcapkit.protocols.data.protocol.Packet(*args: VT, **kwargs: VT)[source]#

Bases: Data

Header and payload data.

header: bytes#

packet header

payload: bytes#

packet payload

Internal Definitions#

class pcapkit.protocols.protocol.ProtocolBase(file=None, length=None, **kwargs)[source]#

Bases: Generic[_PT, _ST]

Abstract base class for all protocol family.

Note

This class is for internal use only. For customisation, please use Protocol instead.

class pcapkit.protocols.protocol.ProtocolMeta(name, bases, namespace, /, **kwargs)[source]#

Bases: ABCMeta

Meta class to add dynamic support to Protocol.

This meta class is used to generate necessary attributes for the Protocol class. It can be useful to reduce unnecessary registry calls and simplify the customisation process.

Type Variables#

pcapkit.protocols.protocol._PT: pcapkit.protocols.data.data.Data#
pcapkit.protocols.protocol._ST: pcapkit.protocols.schema.schema.Schema#