L2TP - Layer Two Tunnelling Protocol¶
pcapkit.protocols.link.l2tp contains
L2TP only, an abstract base class for the
Layer Two Tunnelling Protocol family [*]. The concrete versions live in modules
of their own:
Only L2TPv2 is implemented.
The base deliberately parses no header, as
IP does for its family, because the
versions do not share one. Only the first 16-bit word, with a version nibble at
bits 12-15, is common to all of them; a base that parsed further would assume one
version’s layout for every version.
- class pcapkit.protocols.link.l2tp.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 the class cannot be instantiated. Bind a version, never this class.Changed in version 1.5.0: Became an abstract base for the family; its version-2 parsing moved to
L2TPv2.- 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. That is also the project’s rule for module layout – a distinct
__index__means a distinct module, and a base carrying none claims no module of its own beyond holding the family together.
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. It would also be
the first member of this family with a real
__index__(), and so the first that
needs a module of its own under the project’s one-module-per-index rule.
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() – the relationship HTTP/3 has to
QUIC. See HTTPv1.id for
how a version-flavoured alias is spelled: canonical name first, alias second,
since callers take element zero as canonical.
Version Dispatch¶
Nothing dispatches on the version nibble, because L2TPv2 is the only version
implemented. Another would follow the precedent of
HTTP, which reads a version and
delegates to a per-version class. L2TP is the easier case:
HTTP._guess_version
has to infer the version – recognising the HTTP/2 preface or an HTTP/1 start
line, else trial-parsing each candidate – because HTTP’s wire format carries no
version field, whereas L2TP states its version explicitly in those four bits. A
deterministic switch on Ver is enough, and no new registry is needed.
Footnotes