Expand description
CDP (Cisco Discovery Protocol) server — NetGet impersonating a Cisco device to its neighbours.
CDP is the classic Layer-2 reconnaissance leak: a switch announces its hostname, hardware model, IOS version, port name and native VLAN to anyone on the wire, unsolicited, every 60 seconds. Here the model authors all of it, so what a neighbour records about “the switch it is plugged into” is whatever the LLM decides to claim.
§Structure
codecis a pure module: TLVs, the 802.3 + LLC/SNAP header and the CDP checksum, with no I/O of any kind. That is where the protocol can actually be wrong, and it is exhaustively tested against literal specification bytes and real captures.- This file is the transport, and it is deliberately thin. It has two implementations:
- raw — libpcap capture and injection on a named interface. Needs packet-capture
privilege (root,
/dev/bpf*access on macOS/BSD, orCAP_NET_RAWon Linux). Never executed by any test. - udp — one complete 802.3 frame per datagram, replying to the datagram’s sender.
Needs no privilege, and exists so the whole event → LLM → action → frame path runs in the
test suite. Selected with the
transportstartup parameter, the same wayospfis driven over UDP in tests.
- raw — libpcap capture and injection on a named interface. Needs packet-capture
privilege (root,
§Silence on failure
CDP is in the deliberately-silent class (root CLAUDE.md). Every frame the protocol
defines is a positive assertion — “a device with this identity exists on this link” — which
the neighbour caches and an operator reads back. There is no CDP error or NAK frame, so on an
LLM failure a fabricated advertisement would be strictly worse than nothing: it poisons a
neighbour table with a device that does not exist. The wire therefore carries nothing, no
WireFailure text is ever interpolated into a frame, and the distinction survives only in the
log, in the same shape src/server/radius/ uses. The six tokens this file actually emits,
and the whole set — grep them, do not guess, because a token that does not exist is worse
than none:
decision=passive_no_policy · model_reject · model_silent · model_invalid_action ·
fail_closed_llm_error_overloaded · fail_closed_llm_error_unavailable
Note the last two: there is no bare fail_closed_llm_error. The WireFailure category is
folded into the token so that “the backend is saturated, retry” and “the backend is broken”
stay greppable apart, which is the one thing an operator wants from a log line that says
nothing went on the wire.
Modules§
- actions
- CDP protocol actions, events and metadata.
- codec
- Pure CDP frame codec — 802.3 + LLC/SNAP framing, the CDP header, and the TLV body.