TransType.L2TP is 115, and nothing in the tree dispatches it. A capture carrying IP protocol 115 falls through to Raw.
Found while answering a design question on #514. The owner's recollection there was that "L2TP, iirc we added it to Internet's registry despite it being a Link subclass" — hedged, and it turns out the situation is different and worth recording precisely, because the fix differs from the one that recollection implies.
Measured on main at 691f12ab5, repo venv, PYTHONSAFEPATH=1, pcapkit.__file__ asserted to be the repository tree:
TransType.L2TP = 115
Internet.__proto__ owns 16 entries; 115 present: False
Link.__proto__ owns 7 entries; 115 present: False
classes owning their own __proto__: Frame, PCAPNG, SCTP, TCP, UDP
-- none of them holds key 115
So L2TP is not misfiled into Internet's registry. It is registered nowhere at all under its IP protocol number.
What is registered, and why that masks the gap
UDP.__proto__ holds key 1701 → pcapkit.protocols.link.l2tpv2.L2TPv2. That is the UDP-encapsulated form on its well-known port, and it works. L2TPv2 subclasses L2TP, which subclasses Link.
So the UDP path is covered and the IP-protocol path is not. Anyone testing L2TP through a UDP capture sees it dissect correctly and would not notice that a capture with IP protocol 115 in the header does not.
Why 115 is the right key to expect
IANA assigns protocol number 115 to L2TP, and pcapkit/const/reg/transtype.py already carries the TransType.L2TP = 115 member — so the constant exists and is correct; only the dispatch entry is missing. pcapkit/protocols/link/l2tp.py exists and implements the protocol.
The design question this sits inside
L2TP is awkward precisely because it is an L2 protocol carried over IP, so "which registry owns key 115" is a real question rather than an oversight to paper over:
Internet.__proto__ is keyed by TransType, which is where 115 belongs by key type.
- But
L2TP is a Link subclass, so registering it there means an Internet registry entry resolving to a Link class.
That tension is the same one #514 is working through — the owner's Q3 there proposes either inferring the destination registry from the Enum class, or taking an explicit destination argument. This issue should probably be fixed as part of whichever mechanism #514 lands, rather than by hand-adding an entry that the new scheme would then have to special-case. Recording it separately so it is not lost if #514's scope narrows.
Coverage
No test asserts that every TransType member with an implementing class is reachable through dispatch, which is why this survived. Such a test would be broadly useful — it would catch the next missing registration rather than just this one — and it belongs with whatever fix lands. Note a related dispatch-registry test already exists at tests/protocols/test_dispatch_registry_unit.py and enumerates 38 __proto__ entries, so the harness for this is already in place.
Not fixed here, and deliberately: pcapkit/protocols/internet/internet.py and the registry machinery are contended by PR #547 (#514's PR (a)) as I write this.
TransType.L2TPis 115, and nothing in the tree dispatches it. A capture carrying IP protocol 115 falls through toRaw.Found while answering a design question on #514. The owner's recollection there was that "L2TP, iirc we added it to Internet's registry despite it being a Link subclass" — hedged, and it turns out the situation is different and worth recording precisely, because the fix differs from the one that recollection implies.
Measured on
mainat691f12ab5, repo venv,PYTHONSAFEPATH=1,pcapkit.__file__asserted to be the repository tree:So L2TP is not misfiled into
Internet's registry. It is registered nowhere at all under its IP protocol number.What is registered, and why that masks the gap
UDP.__proto__holds key 1701 →pcapkit.protocols.link.l2tpv2.L2TPv2. That is the UDP-encapsulated form on its well-known port, and it works.L2TPv2subclassesL2TP, which subclassesLink.So the UDP path is covered and the IP-protocol path is not. Anyone testing L2TP through a UDP capture sees it dissect correctly and would not notice that a capture with IP protocol 115 in the header does not.
Why 115 is the right key to expect
IANA assigns protocol number 115 to L2TP, and
pcapkit/const/reg/transtype.pyalready carries theTransType.L2TP = 115member — so the constant exists and is correct; only the dispatch entry is missing.pcapkit/protocols/link/l2tp.pyexists and implements the protocol.The design question this sits inside
L2TP is awkward precisely because it is an L2 protocol carried over IP, so "which registry owns key 115" is a real question rather than an oversight to paper over:
Internet.__proto__is keyed byTransType, which is where 115 belongs by key type.L2TPis aLinksubclass, so registering it there means anInternetregistry entry resolving to aLinkclass.That tension is the same one #514 is working through — the owner's Q3 there proposes either inferring the destination registry from the Enum class, or taking an explicit destination argument. This issue should probably be fixed as part of whichever mechanism #514 lands, rather than by hand-adding an entry that the new scheme would then have to special-case. Recording it separately so it is not lost if #514's scope narrows.
Coverage
No test asserts that every
TransTypemember with an implementing class is reachable through dispatch, which is why this survived. Such a test would be broadly useful — it would catch the next missing registration rather than just this one — and it belongs with whatever fix lands. Note a related dispatch-registry test already exists attests/protocols/test_dispatch_registry_unit.pyand enumerates 38__proto__entries, so the harness for this is already in place.Not fixed here, and deliberately:
pcapkit/protocols/internet/internet.pyand the registry machinery are contended by PR #547 (#514's PR (a)) as I write this.