Expand description
LLDP (IEEE 802.1AB) server — NetGet as a switch on somebody else’s link.
LLDP is a one-way announcement protocol: every agent periodically transmits a description of
itself to the nearest-bridge group address 01:80:C2:00:00:0E under EtherType 0x88CC, and
every agent records what it hears in a table an operator reads. There is no request, no
response and no acknowledgement. What makes it worth driving from a model is that the
identity is authored, not derived: chassis ID, system description and capability set are
choices, and they are exactly what network reconnaissance reads off a link.
§Two transports, one codec
The frame format lives in codec and is a pure function over plain values. This module is
the thin layer that moves those bytes:
transport: "raw"(the default) — libpcap capture and injection on a real interface, filtered toether proto 0x88cc. Needs root,/dev/bpf*access on macOS/BSD, orCAP_NET_RAWon Linux. This code has never been executed; seeCLAUDE.md.transport: "udp"— a testing transport that carries complete Ethernet frames as UDP datagram payloads, so the whole event → handler/LLM → frame path runs unprivileged. No real neighbour speaks it. This is the same accommodationospfmakes for its raw socket, made explicit as a declared parameter rather than left to the test file.
§Failure is silence, and the log is where the difference lives
LLDP is in the deliberately-silent class the root CLAUDE.md describes. Every frame the
protocol defines is a positive assertion that a device with a given identity exists on this
link, and a neighbour writes it straight into its topology table. There is no error frame to
send, and fabricating an advertisement to signal “netget is broken” would put a device on the
network map that does not exist. So an LLM failure transmits nothing, and no WireFailure
text ever reaches the wire.
On the wire all four outcomes are identical, so they are separated in the log by a
decision= tag, the way src/server/radius/ separates its cases:
| Tag | Meaning |
|---|---|
decision=no_policy | No instruction and no handler — nothing is advertised and no LLM call is made |
decision=model_reject | The model answered no_advertisement — a real decision |
decision=model_silent | The model returned nothing usable |
decision=fail_closed_overloaded | The call failed and the backend is saturated (retryable) |
decision=fail_closed_llm_error | The call failed otherwise |