FRAD - Frame Relay Access Device

pcapkit.protocols.link.frad contains FRAD only, which implements the extractor for Frame Relay’s multiprotocol encapsulation [*], as seen on a LINKTYPE_FRELAY capture, or on a LINKTYPE_LINUX_SLL/LINKTYPE_LINUX_SLL2 capture whose arphrd_type is ARPHRD_FRAD. Its structure, the Q.922 LAPF address onward with no trailing FCS, is described as below:

Octets

Bits

Name

Description

0

0

frad.addr

Q.922 Address (2-octet form)

2

16

frad.control

Control (0x03, UI, for data traffic)

3

24

frad.nlpid

NLPID, or the 0x00 pad ahead of one

When nlpid is the 0x00 pad, the NLPID follows it as frad.ext_nlpid. An NLPID of 0x80, with or without the pad, is followed by a SNAP header, a 3-octet OUI and a 2-octet PID, kept as frad.oui and frad.pid.

class pcapkit.protocols.link.frad.FRAD(file=None, length=None, **kwargs)[source]

Bases: Link[FRAD, FRAD]

This class implements Frame Relay Access Device (FRAD) frames.

A frame whose NLPID (after resolving any 0x00 pad ahead of it) is 0xCC or 0x8E dispatches to IPv4 or IPv6 respectively, registered in the self.__proto__ attribute. A SNAP header whose OUI is 00-00-00 carries an EtherType in its PID, resolved instead through the family registry every Ethernet/VLAN/LinuxSLL frame shares, Link.__proto__ – which is how an ARP frame (PID 0x0806) over Frame Relay is reached. Every other NLPID (Q.933 signalling, ISO CLNP/ES-IS/IS-IS, FRF.9/FRF.12 compression and fragmentation, PPP-in-Frame-Relay, and a SNAP header whose OUI names a bridged medium rather than an EtherType) is kept as Raw, exactly as every arphrd_type this module’s docstring lists already was before this class existed. A frame whose Q.922 address is not the 2-octet form is refused: read() raises ProtocolError. It becomes Raw only behind a caller that catches the error, such as LinuxSLL or a LINKTYPE_FRELAY capture.

property name: Literal['Frame Relay Access Device']

Name of current protocol.

property alias: Literal['FRAD']

Acronym of corresponding protocol.

property length: int

Header length of current protocol.

property protocol: int

NLPID of next layer protocol.

classmethod id()[source]

Index ID of the protocol.

Return type:

tuple[Literal['FRAD']]

read(length=None, **kwargs)[source]

Read Frame Relay Access Device (FRAD) frame.

Structure of a direct-NLPID FRAD frame, the common case:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      DLCI (high)     |C/R|EA0|  DLCI (low)   |FECN|BECN|DE|EA1|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Control            |             NLPID             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

A SNAP-encapsulated frame inserts a 0x00 pad and a 0x80 NLPID in place of the single NLPID octet above, followed by a 3-octet OUI and a 2-octet PID (RFC 2427 Section 4.1). The pad may precede any NLPID, or be left out ahead of 0x80 (RFC 2427 Section 3), and pad records whether it is there.

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

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

Return type:

FRAD

Returns:

Parsed packet data.

Raises:

ProtocolError – If the address is not the 2-octet Q.922 form, the only one the schema reads (RFC 2427 Section 3): an EA bit other than 0 then 1. An EA bit the capture cut off is not checked.

make(dlci=0, cr=0, fecn=0, becn=0, de=0, control=0x03, nlpid=0xCC, pad=None, snap_oui=None, snap_pid=None, payload=b'', **kwargs)[source]

Make (construct) packet data.

Parameters:
  • dlci (int) – Data Link Connection Identifier, 10 bits (0 to 1023).

  • cr (int) – Command/response indication bit.

  • fecn (int) – Forward explicit congestion notification bit.

  • becn (int) – Backward explicit congestion notification bit.

  • de (int) – Discard eligibility bit.

  • control (int) – Control field; 0x03 (UI) for ordinary data traffic.

  • nlpid (int) – NLPID selecting the encapsulated protocol; 0xCC for IPv4, 0x8E for IPv6, 0x80 for a SNAP header.

  • pad (bool | None) – Whether a 0x00 pad octet precedes nlpid (RFC 2427 Section 3). When None, there is one ahead of a SNAP header alone, as RFC 2427 Section 4.1 writes it, and ahead of an nlpid of 0, which reads as the pad.

  • snap_oui (bytes | None) – SNAP OUI; required, and only meaningful, when nlpid is 0x80.

  • snap_pid (int | None) – SNAP PID; required, and only meaningful, when nlpid is 0x80.

  • payload (bytes | ProtocolBase | Schema) – Payload data.

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

Return type:

FRAD

Returns:

Constructed packet data.

Raises:

ProtocolError – If dlci does not fit in 10 bits; if cr, fecn, becn or de is not 0 or 1; if control or nlpid does not fit in 8 bits; if nlpid is 0x80 and snap_oui is not exactly 3 octets or snap_pid does not fit in 16 bits; if either snap_oui or snap_pid is given while nlpid is not 0x80; or if pad is False with an nlpid of 0.

Note

nlpid is not refused for being 0 – the value of the one pad octet RFC 2427 Section 3 allows, if present, ahead of any NLPID, never an NLPID of its own – even though no caller building a frame from scratch should pass it: from_data replays a capture that ended inside the header through this same method, and a capture cut short of the nlpid octet reads as 0 (zero rather than missing). Rejecting it here would make a short capture fail to rebuild, the one invariant every protocol in this package keeps (#1458). It is written as the pad and an NLPID of 0, the octets that read back as it, and the schema’s own short read cuts them back to those captured (#2710).

classmethod register(code, protocol)[source]

Register a new protocol class for an NLPID.

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 NLPID rather than by EtherType.

Raises:

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

Warns:

pcapkit.utilities.warnings.RegistryWarning – If this NLPID 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).

__length_hint__()[source]

Return an estimated length for the object.

The longest form – a SNAP-encapsulated header, 10 octets – per the reason L2TPv2.__length_hint__ gives for a variable-length header: the shortest form would reject a fully captured longer header as too short.

Return type:

Literal[10]

classmethod __index__()[source]

Numeral registry index of the protocol.

Return type:

LinkType

Returns:

Numeral registry index of the protocol in tcpdump link-layer header types, LINKTYPE_FRELAY: a Q.922 LAPF frame from the address field on, with no FCS. LinuxSLL.__proto__ names its own key for this class, ARPHRD_FRAD (The Registry Index).

classmethod _make_data(data)[source]

Create key-value pairs from data for protocol construction.

Parameters:

data (FRAD) – protocol data

Return type:

dict[str, Any]

Returns:

Key-value pairs for protocol construction.

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

Import next layer extractor.

Parameters:
  • proto (int) – next layer protocol index – the resolved NLPID, unused when a SNAP EtherType was recorded by read().

  • length (int | None) – valid (non-padding) length

  • packet (dict[str, Any] | None) – packet info (passed from self.unpack)

Return type:

ProtocolBase

Returns:

Instance of next layer. A SNAP header whose OUI is 00-00-00 is dispatched through Link.__proto__ instead of self.__proto__, keyed by the PID as an EtherType – see read(), which records it as self._snap_ethertype.

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

Protocol index mapping for decoding next layer, keyed by the resolved NLPID rather than by EtherType, so this class keeps a registry of its own instead of sharing Link.__proto__ – the same reason Loopback keeps one of its own.

Header Schemas

class pcapkit.protocols.schema.link.frad.FRAD(addr=NO_VALUE, control=NO_VALUE, nlpid=NO_VALUE, ext_nlpid=NO_VALUE, oui=NO_VALUE, pid=NO_VALUE, payload=NO_VALUE, *, __packet__=None, **kwargs)[source]

Bases: Schema

Header schema for a Frame Relay Access Device (FRAD) frame.

The frame is Frame Relay’s multiprotocol encapsulation [RFC 2427, obsoleting RFC 1490] as presented to a LINKTYPE_FRELAY capture, or to a LINKTYPE_LINUX_SLL/LINKTYPE_LINUX_SLL2 capture whose arphrd_type is ARPHRD_FRAD: the Q.922 LAPF address onward, with no trailing FCS.

addr: AddressType = <BitField addr>

Q.922 address field (2-octet form only; see RFC 2427 Section 3).

control: int = <UInt8Field control>

Control field; 0x03 (UI) for ordinary data traffic.

nlpid: int = <UInt8Field nlpid>

NLPID, or the 0x00 pad octet ahead of one.

ext_nlpid: int | None = <ConditionalField ext_nlpid>

NLPID proper, present only when nlpid is the pad.

oui: bytes | None = <ConditionalField oui>

SNAP OUI, present only when the frame is SNAP-encapsulated.

pid: int | None = <ConditionalField pid>

SNAP PID, present only when the frame is SNAP-encapsulated.

payload: bytes = <PayloadField payload>

Payload.

Data Models

class pcapkit.protocols.data.link.frad.FRAD(dlci, cr, fecn, becn, de, control, nlpid, pad, snap_oui, snap_pid, len)[source]

Bases: Protocol

Data model for a Frame Relay Access Device (FRAD) frame.

dlci: int

Data Link Connection Identifier, from the Q.922 address field.

cr: int

Command/response indication bit.

fecn: int

Forward explicit congestion notification.

becn: int

Backward explicit congestion notification.

de: int

Discard eligibility.

control: int

Control field; 0x03 (UI) for ordinary data traffic.

nlpid: int

NLPID selecting the encapsulated protocol, with any 0x00 pad already resolved to the real value that followed it.

pad: bool

Whether a 0x00 pad octet precedes the NLPID (RFC 2427 Section 3).

snap_oui: bytes | None

SNAP OUI, present only when nlpid is 0x80.

snap_pid: int | None

SNAP PID, present only when nlpid is 0x80.

len: int

Header length, in octets – 4 for a direct NLPID, one more with the pad octet, and 5 more with a SNAP header.

Footnotes