LinuxSLL - Linux “Cooked” Capture Encapsulation Family

pcapkit.protocols.link.linux_sll contains LinuxSLL only, the base class of the Linux “cooked” capture encapsulation family:

LinkType

Class

LINUX_SLL (113)

LinuxSLL1

LINUX_SLL2 (276)

LinuxSLL2

The versions differ in field order and width, so each parses its own header. The base holds what they share: the next-layer dispatch, and link-layer address validation. It has no registry index, so its __index__ raises. Constructing the base gives the version its version keyword names, from octets or from fields, and is refused without it, since the link type rather than the header names the version. Its from_data() gives the version whose data model it is handed (#2574).

class pcapkit.protocols.link.linux_sll.LinuxSLL[_PT: Data, _ST: Schema](file=None, length=None, **kwargs)[source]

Bases: Link[_PT, _ST], Generic[_PT, _ST]

Base class of the Linux “cooked” capture encapsulation family.

The versions differ in field order and width, so this base holds only the next-layer dispatch they share. See Selecting a Version for the labels that select a version.

This class supports parsing of the following protocols, which are registered in the self.__proto__ attribute, keyed by arphrd_type:

Every other arphrd_type reads protocol_type as an EtherType and dispatches it through Link.__proto__, as an Ethernet frame does.

It dispatches where the version is known, never giving an instance of this class (#2574). version names the member, from octets or from fields, and nothing else does: the header carries no version of its own, and no field picks a member, so either is refused without it. from_data() gives the member whose data model it is handed, and refuses a dict. See __new__().

classmethod id()[source]

Index ID of the protocol.

Returns:

the direct members, each by its own name.

Return type:

tuple[Literal['LinuxSLL1'], Literal['LinuxSLL2']]

classmethod register(code, protocol)[source]

Register a new protocol class for an arphrd_type.

Notes

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

Parameters:

Important

This overrides Link.register because self.__proto__ is keyed by arphrd_type rather than by EtherType. A registered arphrd_type dispatches through it, and its protocol_type is not read as an EtherType.

Raises:

pcapkit.utilities.exceptions.RegistryError – If protocol is not a class, or not a ProtocolBase subclass.

Warns:

pcapkit.utilities.warnings.RegistryWarning – If this arphrd_type is already registered and the incumbent differs from the replacement; see Protocol.register for the guard, and for the shipped descriptor a restore puts back (#1504).

classmethod from_data(data, **kwargs)[source]

Create protocol instance from data.

Parameters:
Return type:

Self

Returns:

Protocol instance; on this class, an instance of the member whose data model data is.

Raises:

ProtocolError – If data is neither member’s data model, on this class. A dict is refused: it carries no version, and no key picks a member.

classmethod __index__()[source]

Numeral registry index of the protocol.

Raises:

UnsupportedCall – The family base has no registry entry; nothing dispatches to it, only to its members.

Return type:

NoReturn

__init__(file=None, length=None, *, version=None, **kwargs)[source]

Initialisation.

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

  • length (int | None) – Length of packet data.

  • version (Literal[1, 2] | None) – Version of the header, 1 or 2: the member __new__() picks. Building from fields, it must be this class’s own. Parsing, it is handed on unread.

  • **kwargs (Any) – As Protocol.__init__.

Raises:

ProtocolError – If, building from fields, version names neither member, or is not this class’s own version: that of the member it is or derives from, which a subclass outside the members does not have.

static __new__(cls, file=None, length=None, **kwargs)[source]

Create the member a construction of this class describes.

The version keyword names the member, on either path, and nothing else does: the header carries no version of its own, and no field picks a member. That member’s __init__ then runs with the same arguments. A subclass of this class is created as itself.

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

  • length (int | None) – Length of packet data.

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

Return type:

LinuxSLL

Returns:

An uninitialised instance of the member.

Raises:

ProtocolError – If version is missing, or names neither member. Without it, octets are refused as fields are: the link type names the version, LINUX_SLL (113) or LINUX_SLL2 (276).

_import_next_layer(proto, length=None, *, packet=None)[source]

Import next layer extractor.

Parameters:
Returns:

the class self.__proto__ registers for arphrd_type when it has a key for it, and otherwise the class Link.__proto__ registers for proto as an EtherType. Where parsing stops at this layer, either path keeps the payload Raw, and a Raw records proto either way.

Return type:

ProtocolBase

Note

self.__proto__ holds the arphrd_type keys, so the EtherType path names Link.__proto__ itself rather than reaching it through super(), as FRAD._import_next_layer does for a SNAP EtherType.

static _member_of_version(version)[source]

The member a version of 1 or 2 names.

Parameters:

version (Any) – Version of the header.

Return type:

Type[LinuxSLL]

Returns:

LinuxSLL1 or LinuxSLL2.

Raises:

ProtocolError – If version is neither, or is no int: a bool or a float is refused even where it equals one.

__proto__: DefaultDict[int | ARPHRD, ModuleDescriptor[ProtocolBase] | Type[ProtocolBase]]

Protocol index mapping for decoding next layer, keyed by the arphrd_type values whose protocol_type is not an EtherType, per tcpdump.org’s LINUX_SLL and LINUX_SLL2 pages.

__proto_key__: ClassVar[tuple[Type[EnumRegistry], bool]]

What __proto__ is keyed by, declared as Link.__proto_key__ is.

Auxiliary Functions

pcapkit.protocols.link.linux_sll._resolve_next_layer_proto(registry, arphrd_type, protocol_type)[source]

Resolve the next-layer dispatch key of either version.

Parameters:
  • registry (DefaultDict[int, Any]) – The arphrd_type registry, i.e. LinuxSLL.__proto__.

  • arphrd_type (int) – ARP hardware type of the interface the packet was seen on.

  • protocol_type (int) – Protocol (internet layer), as parsed off the wire.

Return type:

EtherType | int

Returns:

protocol_type itself if arphrd_type is a key of registry; otherwise the value Ethernet stores for the same type.

Validate and pad the link-layer address for make() of either version.

Parameters:
  • alias (str) – Acronym of the calling protocol, for the error message.

  • link_addr (bytes | bytearray) – Link-layer address, at most 8 octets.

  • link_addr_length (int | None) – Length in use, by default len(link_addr); may exceed 8, e.g. 20 for InfiniBand, of which the header keeps 8.

  • max_length (int) – Maximum of the wire field holding the length.

Return type:

tuple[bytes, int]

Returns:

link_addr padded with NUL octets to 8, and the length.

Raises:

ProtocolError – If link_addr exceeds 8 octets, or the length is outside 0 to max_length.

Auxiliary Constants

pcapkit.protocols.link.linux_sll._ETHERTYPE_FIELD

Resolves protocol_type exactly as Ethernet resolves its type.

Hardware Types

The arphrd_type keys of LinuxSLL.__proto__ are named by ARPHRD.

Selecting a Version

The family name selects either version, and each version’s own name selects that version only, as IPv4 and IPv6 do under IP. 'LinuxSLL' is in both versions; 'LinuxSLL1' in a v2 layer is False. String == does not expand a key, so v1 == 'LinuxSLL' is False while 'LinuxSLL' in v1 is True.