Sees what the server cannot.

docsis_monitor watches a DOCSIS plant's provisioning traffic on the wire, and says something when it stops looking like a working plant. The provisioning server logs everything it answers, and the console reads those tables. What neither can see is a request that never arrived: a CMTS with a broken relay, a VLAN that stopped trunking, a firewall rule somebody added on Friday. In every one of those the server's tables look quiet and healthy, because nothing reached the server to be logged. The only place it is visible is the wire.

View on GitHub Get started
docsis_monitor — project data MMQR-04 Rev A Sheet 04 of 06
01 Language Rust Statically linked against musl, for hosts whose libc nobody has checked
02 Licence GPL v2+ GNU General Public License, version 2 or later
03 Capture AF_PACKET Through pnet_datalink: no libpcap, no C library, filtering in-process
04 Needs CAP_NET_RAW setcap on the binary, or root; --check says whether a host can capture at all
05 Alerts Trap · Mail An SNMPv2c trap to every receiver and mail to every recipient, on a change of state
06 Writes Nothing Never transmits on the interface it watches, never touches a plant's database

Repository: github.com/mmqr-developer/docsis_monitor · The four DOCSIS projects also have a site of their own at docsis-admin.com.

02 · States

Quiet, unanswered, working

It counts the DHCP and TFTP packets crossing one interface, in both directions, per conversation and per CMTS. Every report_every seconds it writes what it saw to the log and judges each interface. The plant's state is the worst of them: one CMTS out of twelve gone quiet is an outage for everybody behind it, and a threshold over the whole plant averages that away.

Quiet

Nothing has arrived from that CMTS for longer than it is allowed to be silent. The relay is broken, the VLAN is not trunking, or something between the plant and the server has changed.

Unanswered

Requests are arriving and fewer than min_answered of them are being answered. A server that is up, listening, and refusing or failing every request — which, from a modem's side, is a server that is down.

Working

Neither. With no trap receiver and no mail recipient configured it says nothing at all: the state is already on the report line, and a monitor that logs its own inaction every window is a monitor whose log nobody reads.

03 · How it judges

Per CMTS, and both directions

01 Per CMTS, not per plant One interface carries several thousand modems and should never be silent for five minutes; another carries forty and is properly silent for an hour. One number is wrong for both — set for the busy one it cries wolf about the quiet one every night, set for the quiet one it says nothing for an hour after the busy one falls over. So each relaying interface gets its own.
02 Times the answers Counting replies is not knowing requests were answered: two thousand of each in a window is a plant answering everything in four milliseconds, or one answering half of them twice, four seconds late. Both sides cross the interface, so a request and its reply are matched on transaction id and the gap between them is the server's response time as the CMTS experiences it.
03 TFTP counted, not alarmed on It is far quieter than DHCP by nature — the equipment behind a modem never touches it, so a plant fetches a config when a modem boots and not again.
04 Tells somebody once A change of state sends a trap and a mail. The same trouble is not repeated for resend_after seconds, and a change always goes out, including the recovery. The subject carries the whole finding — which host, which state, and the counts behind it — because that is all a phone shows, and "DOCSIS alert" makes somebody open the mail to find out whether to get up.
05 Names the one to look at The per-destination counts are what make an alarm actionable: on a plant with four relays, three still talking and one silent names the one to go and look at. Each trap carries the host, the interface, the state, the counts, the window length and the busiest destination, so an alert says where to look without anybody logging in.
06 Thresholds are measured Do not guess them. --adaptation 60 watches for an hour, raises no alarms, and writes into the log what every relaying interface did with a suggested idle_seconds and the arithmetic behind it, ending in a per_relay block to paste into the configuration. Where it saw too little to say anything honest, it says so rather than writing today's outage into the configuration as tomorrow's normal.
07 Mail is plain SMTP No STARTTLS: adding it means a TLS stack to keep patched on hosts nobody logs in to, in a program whose point is to run unattended. This is for a relay on a network you trust, which is the ordinary shape for alerting. Nothing is queued and nothing is retried; a failed send is logged with its subject, so the finding survives even though the message did not.
04 · Traps

Three, under one enterprise

1.3.6.1.4.1.99999
.1quietNothing is arriving
.2unansweredArriving, and not being answered
.3recoveredWorking again
05 · Get started

Build, grant the capture, watch first

A capture socket belongs to root or to a binary holding CAP_NET_RAW. The capture is opened before the fork, so a permission problem is answered on the terminal rather than in a log file belonging to a process that has already exited.

./build.sh                                  # checks, then a static build with the time compiled in
sudo setcap cap_net_raw,cap_net_admin=eip /path/to/docsis_monitor

docsis_monitor --check                      # reads the config, opens the capture, exits
docsis_monitor --adaptation 60              # watches for an hour and suggests the thresholds
docsis_monitor                              # detaches, logs to ~/logs/docsis_monitor.log
docsis_monitor --nofork                     # stays on the terminal

Everything is in ~/config/docsis_monitor.json, or /etc/docsis_monitor.json for a system service. The example file in the repository is checked by the test suite against the code that reads it. A key the program does not know is printed at startup rather than refused — on a monitor, a setting that silently does nothing is an alarm that never fires, and that looks exactly like a plant that is working.