L2TP - Layer Two Tunnelling Protocol¶
pcapkit.protocols.link.l2tp.protocol contains
L2TP only, an abstract base class for the
Layer Two Tunnelling Protocol family [*]. The concrete versions live in modules
of their own:
The base parses no header, as IP
does for its family: only the first 16-bit word, with the version nibble at bits
12-15, is common to every version, so parsing further would impose one version’s
layout on all.
- class pcapkit.protocols.link.l2tp.protocol.L2TP[_PT: Data, _ST: Schema](file=None, length=None, **kwargs)[source]¶
Bases:
Link[_PT,_ST],Generic[_PT,_ST]This class implements all protocols in L2TP family.
It is abstract for the same mechanical reason
IPis:nameandread()are both declared abstract byProtocolBaseand neither is defined here, so no instance of it exists. Bind a version, never this class.It dispatches on both paths, never giving an instance of this class (#2574). The
versionfield names the member; without it, octets give the one their version nibble names, and fields are refused.from_data()reads theversionof its data. See__new__().Changed in version 1.5.0: Became an abstract base for the family; its version-2 parsing moved to
L2TPv2.Changed in version 1.6.0: Constructing it and
from_data()giveL2TPv2, where they raisedTypeError. Theversionfield names the member; without it, octets give the one their version nibble names, and fields are refused (#2574).- classmethod from_data(data, **kwargs)[source]¶
Create protocol instance from data.
- Parameters:
**kwargs (
Any) – AsProtocol.from_data.
- Return type:
- Returns:
Protocol instance; on this class, an instance of the member the
versionofdatanames.- Raises:
ProtocolError – If no member reads that
version, on this class.
- classmethod __index__()[source]¶
Numeral registry index of the protocol.
- Raises:
UnsupportedCall – This protocol has no registry entry.
- Return type:
Note
An abstract base is reached by nothing, so it has no index of its own.
- static __new__(cls, file=None, length=None, **kwargs)[source]¶
Create the member a construction of this class describes.
The
versionfield names the member, on either path. Without it, parsing octets gives the member the version nibble, bits 12 to 15 of their first word, names, and building from fields is refused, since 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:
- Return type:
- Returns:
An uninitialised instance of the member.
- Raises:
ProtocolError – If no member reads
version; or, without it, if building from fields, or if the octets are shorter than the first word or no member reads their version.
Versions Not Implemented¶
L2TPv3 [RFC 3931] has a different session header and control message
header from v2, and is reachable two ways: over UDP port 1701 like v2, and
directly over IP as protocol number 115. That second route is why
Internet.__proto__
leaves 115 unbound: the binding waits on an L2TPv3 class. Protocol 115 names v3
alone: v2’s __index__() is its UDP
port.
L2F [RFC 2341] is reached when the version nibble reads 1. It is not
an earlier version of L2TP: RFC 2661 §3.1 requires Ver to be 2 and reserves
the value 1 “to permit detection of L2F packets should they arrive intermixed with
L2TP packets”. L2F is a separate protocol with its own header, so it is to be
implemented as L2F, the canonical name, with L2TPv1 only as an alias in its
id(). See
L2TPv2.id for
how a version-flavoured alias is spelled: canonical name first, alias second,
since callers take element zero as canonical.
Version Dispatch¶
Constructing the base gives the member its version field names, from octets or
from fields; without it, octets give the one their version nibble names, and fields
are refused, since no field picks a member (#2574).
_member_of_version() maps 2 to
L2TPv2 and refuses any other version, for
that field, for the nibble and for the data
from_data() is handed. UDP port 1701 binds
L2TPv2 itself. A further member goes in that switch, and binding the port to the
base through a hook making the same switch, as
IGMP._dispatch does for
IP protocol 2, needs no new registry. Unlike
HTTP, whose
_guess_version() has to infer
the version, L2TP states it in the version nibble.
Footnotes